// Copyright (c) 2017 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "net/http/http_cache_writers.h"

#include <limits>
#include <memory>
#include <string>
#include <utility>
#include <vector>

#include "base/bind.h"
#include "base/run_loop.h"
#include "net/http/http_cache.h"
#include "net/http/http_cache_transaction.h"
#include "net/http/http_response_info.h"
#include "net/http/http_transaction.h"
#include "net/http/http_transaction_test_util.h"
#include "net/http/mock_http_cache.h"
#include "net/http/partial_data.h"
#include "net/test/gtest_util.h"
#include "net/test/test_with_task_environment.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"

using net::test::IsError;
using net::test::IsOk;

namespace net {

class WritersTest;

class TestHttpCacheTransaction : public HttpCache::Transaction {
  typedef WebSocketHandshakeStreamBase::CreateHelper CreateHelper;

 public:
  TestHttpCacheTransaction(RequestPriority priority, HttpCache* cache)
      : HttpCache::Transaction(priority, cache) {}
  ~TestHttpCacheTransaction() override = default;

  Transaction::Mode mode() const override { return Transaction::READ_WRITE; }
};

class TestHttpCache : public HttpCache {
 public:
  TestHttpCache(std::unique_ptr<HttpTransactionFactory> network_layer,
                std::unique_ptr<BackendFactory> backend_factory)
      : HttpCache(std::move(network_layer), std::move(backend_factory), false) {
  }

  void WritersDoneWritingToEntry(ActiveEntry* entry,
                                 bool success,
                                 bool should_keep_entry,
                                 TransactionSet make_readers) override {
    done_writing_to_entry_count_ += 1;
    make_readers_size_ = make_readers.size();
  }

  void WritersDoomEntryRestartTransactions(ActiveEntry* entry) override {}

  int WritersDoneWritingToEntryCount() const {
    return done_writing_to_entry_count_;
  }

  size_t MakeReadersSize() const { return make_readers_size_; }

 private:
  int done_writing_to_entry_count_ = 0;
  size_t make_readers_size_ = 0u;
};

class WritersTest : public TestWithTaskEnvironment {
 public:
  enum class DeleteTransactionType { NONE, ACTIVE, WAITING, IDLE };
  WritersTest()
      : scoped_transaction_(kSimpleGET_Transaction),
        disk_entry_(nullptr),
        test_cache_(std::make_unique<MockNetworkLayer>(),
                    std::make_unique<MockBackendFactory>()),
        request_(kSimpleGET_Transaction) {
    scoped_transaction_.response_headers =
        "Last-Modified: Wed, 28 Nov 2007 00:40:09 GMT\n"
        "Content-Length: 22\n"
        "Etag: \"foopy\"\n";
    request_ = MockHttpRequest(scoped_transaction_);
  }

  ~WritersTest() override {
    if (disk_entry_)
      disk_entry_->Close();
  }

  void CreateWriters(const std::string& url) {
    cache_.CreateBackendEntry(kSimpleGET_Transaction.url, &disk_entry_,
                              nullptr);
    entry_ = std::make_unique<HttpCache::ActiveEntry>(disk_entry_, false);
    (static_cast<MockDiskEntry*>(disk_entry_))->AddRef();
    writers_ = std::make_unique<HttpCache::Writers>(&test_cache_, entry_.get());
  }

  std::unique_ptr<HttpTransaction> CreateNetworkTransaction() {
    std::unique_ptr<HttpTransaction> transaction;
    MockNetworkLayer* network_layer = cache_.network_layer();
    network_layer->CreateTransaction(DEFAULT_PRIORITY, &transaction);
    return transaction;
  }

  void CreateWritersAddTransaction(
      HttpCache::ParallelWritingPattern parallel_writing_pattern_ =
          HttpCache::PARALLEL_WRITING_JOIN,
      bool content_encoding_present = false) {
    TestCompletionCallback callback;

    // Create and Start a mock network transaction.
    std::unique_ptr<HttpTransaction> network_transaction;
    network_transaction = CreateNetworkTransaction();
    network_transaction->Start(&request_, callback.callback(),
                               NetLogWithSource());
    base::RunLoop().RunUntilIdle();
    response_info_ = *(network_transaction->GetResponseInfo());
    if (content_encoding_present)
      response_info_.headers->AddHeader("Content-Encoding: gzip");

    // Create a mock cache transaction.
    std::unique_ptr<TestHttpCacheTransaction> transaction =
        std::make_unique<TestHttpCacheTransaction>(DEFAULT_PRIORITY,
                                                   cache_.http_cache());

    CreateWriters(kSimpleGET_Transaction.url);
    EXPECT_TRUE(writers_->IsEmpty());
    HttpCache::Writers::TransactionInfo info(
        transaction->partial(), transaction->is_truncated(), response_info_);

    writers_->AddTransaction(transaction.get(), parallel_writing_pattern_,
                             transaction->priority(), info);
    writers_->SetNetworkTransaction(transaction.get(),
                                    std::move(network_transaction));
    EXPECT_TRUE(writers_->HasTransaction(transaction.get()));
    transactions_.push_back(std::move(transaction));
  }

  void CreateWritersAddTransactionPriority(
      net::RequestPriority priority,
      HttpCache::ParallelWritingPattern parallel_writing_pattern_ =
          HttpCache::PARALLEL_WRITING_JOIN) {
    CreateWritersAddTransaction(parallel_writing_pattern_);
    TestHttpCacheTransaction* transaction = transactions_.begin()->get();
    transaction->SetPriority(priority);
  }

  void AddTransactionToExistingWriters() {
    EXPECT_TRUE(writers_);

    // Create a mock cache transaction.
    std::unique_ptr<TestHttpCacheTransaction> transaction =
        std::make_unique<TestHttpCacheTransaction>(DEFAULT_PRIORITY,
                                                   cache_.http_cache());

    HttpCache::Writers::TransactionInfo info(transaction->partial(),
                                             transaction->is_truncated(),
                                             *(transaction->GetResponseInfo()));
    info.response_info = response_info_;
    writers_->AddTransaction(transaction.get(),
                             HttpCache::PARALLEL_WRITING_JOIN,
                             transaction->priority(), info);
    transactions_.push_back(std::move(transaction));
  }

  int Read(std::string* result) {
    EXPECT_TRUE(transactions_.size() >= (size_t)1);
    TestHttpCacheTransaction* transaction = transactions_.begin()->get();
    TestCompletionCallback callback;

    std::string content;
    int rv = 0;
    do {
      scoped_refptr<IOBuffer> buf =
          base::MakeRefCounted<IOBuffer>(kDefaultBufferSize);
      rv = writers_->Read(buf.get(), kDefaultBufferSize, callback.callback(),
                          transaction);
      if (rv == ERR_IO_PENDING) {
        rv = callback.WaitForResult();
        base::RunLoop().RunUntilIdle();
      }

      if (rv > 0)
        content.append(buf->data(), rv);
      else if (rv < 0)
        return rv;
    } while (rv > 0);

    result->swap(content);
    return OK;
  }

  int ReadFewBytes(std::string* result) {
    EXPECT_TRUE(transactions_.size() >= (size_t)1);
    TestHttpCacheTransaction* transaction = transactions_.begin()->get();
    TestCompletionCallback callback;

    std::string content;
    int rv = 0;
    scoped_refptr<IOBuffer> buf = base::MakeRefCounted<IOBuffer>(5);
    rv = writers_->Read(buf.get(), 5, callback.callback(), transaction);
    if (rv == ERR_IO_PENDING) {
      rv = callback.WaitForResult();
      base::RunLoop().RunUntilIdle();
    }

    if (rv > 0)
      result->append(buf->data(), rv);
    else if (rv < 0)
      return rv;

    return OK;
  }

  void ReadVerifyTwoDifferentBufferLengths(
      const std::vector<int>& buffer_lengths) {
    EXPECT_EQ(2u, buffer_lengths.size());
    EXPECT_EQ(2u, transactions_.size());

    std::vector<std::string> results(buffer_lengths.size());

    // Check only the 1st Read and not the complete response because the smaller
    // buffer transaction will need to read the remaining response from the
    // cache which will be tested when integrated with TestHttpCacheTransaction
    // layer.

    int rv = 0;

    std::vector<scoped_refptr<IOBuffer>> bufs;
    for (auto buffer_length : buffer_lengths)
      bufs.push_back(base::MakeRefCounted<IOBuffer>(buffer_length));

    std::vector<TestCompletionCallback> callbacks(buffer_lengths.size());

    // Multiple transactions should be able to read with different sized
    // buffers.
    for (size_t i = 0; i < transactions_.size(); i++) {
      rv = writers_->Read(bufs[i].get(), buffer_lengths[i],
                          callbacks[i].callback(), transactions_[i].get());
      EXPECT_EQ(ERR_IO_PENDING, rv);  // Since the default is asynchronous.
    }

    // If first buffer is smaller, then the second one will only read the
    // smaller length as well.
    std::vector<int> expected_lengths = {buffer_lengths[0],
                                         buffer_lengths[0] < buffer_lengths[1]
                                             ? buffer_lengths[0]
                                             : buffer_lengths[1]};

    for (size_t i = 0; i < callbacks.size(); i++) {
      rv = callbacks[i].WaitForResult();
      EXPECT_EQ(expected_lengths[i], rv);
      results[i].append(bufs[i]->data(), expected_lengths[i]);
    }

    EXPECT_EQ(results[0].substr(0, expected_lengths[1]), results[1]);

    std::string expected(kSimpleGET_Transaction.data);
    EXPECT_EQ(expected.substr(0, expected_lengths[1]), results[1]);
  }

  // Each transaction invokes Read simultaneously. If |deleteType| is not NONE,
  // then it deletes the transaction of given type during the read process.
  void ReadAllDeleteTransaction(DeleteTransactionType deleteType) {
    EXPECT_LE(3u, transactions_.size());

    unsigned int delete_index = std::numeric_limits<unsigned int>::max();
    switch (deleteType) {
      case DeleteTransactionType::NONE:
        break;
      case DeleteTransactionType::ACTIVE:
        delete_index = 0;
        break;
      case DeleteTransactionType::WAITING:
        delete_index = 1;
        break;
      case DeleteTransactionType::IDLE:
        delete_index = 2;
        break;
    }

    std::vector<std::string> results(transactions_.size());
    int rv = 0;
    bool first_iter = true;
    do {
      std::vector<scoped_refptr<IOBuffer>> bufs;
      std::vector<TestCompletionCallback> callbacks(transactions_.size());

      for (size_t i = 0; i < transactions_.size(); i++) {
        bufs.push_back(base::MakeRefCounted<IOBuffer>(kDefaultBufferSize));

        // If we have deleted a transaction in the first iteration, then do not
        // invoke Read on it, in subsequent iterations.
        if (!first_iter && deleteType != DeleteTransactionType::NONE &&
            i == delete_index)
          continue;

        // For it to be an idle transaction, do not invoke Read.
        if (deleteType == DeleteTransactionType::IDLE && i == delete_index)
          continue;

        rv = writers_->Read(bufs[i].get(), kDefaultBufferSize,
                            callbacks[i].callback(), transactions_[i].get());
        EXPECT_EQ(ERR_IO_PENDING, rv);  // Since the default is asynchronous.
      }

      if (first_iter && deleteType != DeleteTransactionType::NONE) {
        writers_->RemoveTransaction(transactions_.at(delete_index).get(),
                                    false /* success */);
      }

      // Verify Add Transaction should succeed mid-read.
      AddTransactionToExistingWriters();

      std::vector<int> rvs;
      for (size_t i = 0; i < callbacks.size(); i++) {
        if (i == delete_index && deleteType != DeleteTransactionType::NONE)
          continue;
        rv = callbacks[i].WaitForResult();
        rvs.push_back(rv);
      }

      // Verify all transactions should read the same length buffer.
      for (size_t i = 1; i < rvs.size(); i++) {
        ASSERT_EQ(rvs[i - 1], rvs[i]);
      }

      if (rv > 0) {
        for (size_t i = 0; i < results.size(); i++) {
          if (i == delete_index && deleteType != DeleteTransactionType::NONE &&
              deleteType != DeleteTransactionType::ACTIVE) {
            continue;
          }
          results.at(i).append(bufs[i]->data(), rv);
        }
      }
      first_iter = false;
    } while (rv > 0);

    for (size_t i = 0; i < results.size(); i++) {
      if (i == delete_index && deleteType != DeleteTransactionType::NONE &&
          deleteType != DeleteTransactionType::ACTIVE) {
        continue;
      }
      EXPECT_EQ(kSimpleGET_Transaction.data, results[i]);
    }

    EXPECT_EQ(OK, rv);
  }

  // Creates a transaction and performs two reads. Returns after the second read
  // has begun but before its callback has run.
  void StopMidRead() {
    CreateWritersAddTransaction();
    EXPECT_FALSE(writers_->IsEmpty());
    EXPECT_EQ(1u, transactions_.size());
    TestHttpCacheTransaction* transaction = transactions_[0].get();

    // Read a few bytes so that truncation is possible.
    TestCompletionCallback callback;
    scoped_refptr<IOBuffer> buf = base::MakeRefCounted<IOBuffer>(5);
    int rv = writers_->Read(buf.get(), 5, callback.callback(), transaction);
    EXPECT_EQ(ERR_IO_PENDING, rv);  // Since the default is asynchronous.
    EXPECT_EQ(5, callback.GetResult(rv));

    // Start reading a few more bytes and return.
    buf = base::MakeRefCounted<IOBuffer>(5);
    rv = writers_->Read(buf.get(), 5, base::BindOnce([](int rv) {}),
                        transaction);
    EXPECT_EQ(ERR_IO_PENDING, rv);
  }

  void ReadAll() { ReadAllDeleteTransaction(DeleteTransactionType::NONE); }

  int ReadCacheWriteFailure(std::vector<std::string>* results) {
    int rv = 0;
    int active_transaction_rv = 0;
    bool first_iter = true;
    do {
      std::vector<scoped_refptr<IOBuffer>> bufs;
      std::vector<TestCompletionCallback> callbacks(results->size());

      // Fail the request.
      cache_.disk_cache()->set_soft_failures_mask(MockDiskEntry::FAIL_ALL);

      // We have to open the entry again to propagate the failure flag.
      disk_cache::Entry* en;
      cache_.OpenBackendEntry(kSimpleGET_Transaction.url, &en);
      en->Close();

      for (size_t i = 0; i < transactions_.size(); i++) {
        bufs.push_back(base::MakeRefCounted<IOBuffer>(30));

        if (!first_iter && i > 0)
          break;
        rv = writers_->Read(bufs[i].get(), 30, callbacks[i].callback(),
                            transactions_[i].get());
        EXPECT_EQ(ERR_IO_PENDING, rv);  // Since the default is asynchronous.
      }

      for (size_t i = 0; i < callbacks.size(); i++) {
        // Only active transaction should succeed.
        if (i == 0) {
          active_transaction_rv = callbacks[i].WaitForResult();
          EXPECT_LE(0, active_transaction_rv);
          results->at(0).append(bufs[i]->data(), active_transaction_rv);
        } else if (first_iter) {
          rv = callbacks[i].WaitForResult();
          EXPECT_EQ(ERR_CACHE_WRITE_FAILURE, rv);
        }
      }

      first_iter = false;
    } while (active_transaction_rv > 0);

    return active_transaction_rv;
  }

  int ReadNetworkFailure(std::vector<std::string>* results, Error error) {
    int rv = 0;
    std::vector<scoped_refptr<IOBuffer>> bufs;
    std::vector<TestCompletionCallback> callbacks(results->size());

    for (size_t i = 0; i < transactions_.size(); i++) {
      bufs.push_back(base::MakeRefCounted<IOBuffer>(30));

      rv = writers_->Read(bufs[i].get(), 30, callbacks[i].callback(),
                          transactions_[i].get());
      EXPECT_EQ(ERR_IO_PENDING, rv);  // Since the default is asynchronous.
    }

    for (auto& callback : callbacks) {
      rv = callback.WaitForResult();
      EXPECT_EQ(error, rv);
    }

    return error;
  }

  bool StopCaching() {
    TestHttpCacheTransaction* transaction = transactions_.begin()->get();
    EXPECT_TRUE(transaction);
    return writers_->StopCaching(transaction);
  }

  void RemoveFirstTransaction() {
    TestHttpCacheTransaction* transaction = transactions_.begin()->get();
    EXPECT_TRUE(transaction);
    writers_->RemoveTransaction(transaction, false /* success */);
  }

  void UpdateAndVerifyPriority(RequestPriority priority) {
    writers_->UpdatePriority();
    EXPECT_EQ(priority, writers_->priority_);
  }

  bool ShouldKeepEntry() const { return writers_->should_keep_entry_; }

  bool Truncated() const {
    const int kResponseInfoIndex = 0;  // Keep updated with HttpCache.
    TestCompletionCallback callback;
    int io_buf_len = entry_->disk_entry->GetDataSize(kResponseInfoIndex);
    if (io_buf_len == 0)
      return false;

    scoped_refptr<IOBuffer> read_buffer =
        base::MakeRefCounted<IOBuffer>(io_buf_len);
    int rv = disk_entry_->ReadData(kResponseInfoIndex, 0, read_buffer.get(),
                                   io_buf_len, callback.callback());
    rv = callback.GetResult(rv);
    HttpResponseInfo response_info;
    bool truncated;
    HttpCache::ParseResponseInfo(read_buffer->data(), io_buf_len,
                                 &response_info, &truncated);
    return truncated;
  }

  bool ShouldTruncate() { return writers_->ShouldTruncate(); }

  bool CanAddWriters() {
    HttpCache::ParallelWritingPattern parallel_writing_pattern_;
    return writers_->CanAddWriters(&parallel_writing_pattern_);
  }

  ScopedMockTransaction scoped_transaction_;
  MockHttpCache cache_;
  std::unique_ptr<HttpCache::Writers> writers_;
  disk_cache::Entry* disk_entry_;
  std::unique_ptr<HttpCache::ActiveEntry> entry_;
  TestHttpCache test_cache_;

  // Should be before transactions_ since it is accessed in the network
  // transaction's destructor.
  MockHttpRequest request_;

  HttpResponseInfo response_info_;
  static const int kDefaultBufferSize = 256;

  std::vector<std::unique_ptr<TestHttpCacheTransaction>> transactions_;
};

const int WritersTest::kDefaultBufferSize;

// Tests successful addition of a transaction.
TEST_F(WritersTest, AddTransaction) {
  CreateWritersAddTransaction();
  EXPECT_FALSE(writers_->IsEmpty());

  // Verify keep_entry_ is true by default.
  EXPECT_TRUE(ShouldKeepEntry());
}

// Tests successful addition of multiple transactions.
TEST_F(WritersTest, AddManyTransactions) {
  CreateWritersAddTransaction();
  EXPECT_FALSE(writers_->IsEmpty());

  for (int i = 0; i < 5; i++)
    AddTransactionToExistingWriters();

  EXPECT_EQ(6, writers_->GetTransactionsCount());
}

// Tests that CanAddWriters should return false if it is writing exclusively.
TEST_F(WritersTest, AddTransactionsExclusive) {
  CreateWritersAddTransaction(HttpCache::PARALLEL_WRITING_NOT_JOIN_RANGE);
  EXPECT_FALSE(writers_->IsEmpty());

  EXPECT_FALSE(CanAddWriters());
}

// Tests StopCaching should not stop caching if there are multiple writers.
TEST_F(WritersTest, StopCachingMultipleWriters) {
  CreateWritersAddTransaction();
  EXPECT_FALSE(writers_->IsEmpty());

  EXPECT_TRUE(CanAddWriters());
  AddTransactionToExistingWriters();

  EXPECT_FALSE(StopCaching());
  EXPECT_TRUE(CanAddWriters());
}

// Tests StopCaching should stop caching if there is a single writer.
TEST_F(WritersTest, StopCaching) {
  CreateWritersAddTransaction();
  EXPECT_FALSE(writers_->IsEmpty());

  EXPECT_TRUE(StopCaching());
  EXPECT_FALSE(CanAddWriters());
}

// Tests that when the writers object completes, it passes any non-pending
// transactions to WritersDoneWritingToEntry.
TEST_F(WritersTest, MakeReaders) {
  CreateWritersAddTransaction();
  AddTransactionToExistingWriters();
  AddTransactionToExistingWriters();

  std::string remaining_content;
  Read(&remaining_content);

  EXPECT_EQ(1, test_cache_.WritersDoneWritingToEntryCount());
  EXPECT_FALSE(Truncated());
  EXPECT_EQ(2u, test_cache_.MakeReadersSize());
}

// Tests StopCaching should be successful when invoked mid-read.
TEST_F(WritersTest, StopCachingMidReadKeepEntry) {
  StopMidRead();

  // Stop caching and keep the entry after the transaction finishes.
  writers_->StopCaching(true /* keep_entry */);

  // Cannot add more writers while we are in network read-only state.
  EXPECT_FALSE(CanAddWriters());

  // Complete the pending read;
  base::RunLoop().RunUntilIdle();

  // Read the rest of the content and the cache entry should have truncated.
  std::string remaining_content;
  Read(&remaining_content);
  EXPECT_EQ(1, test_cache_.WritersDoneWritingToEntryCount());
  EXPECT_TRUE(Truncated());
}

// Tests StopCaching should be successful when invoked mid-read.
TEST_F(WritersTest, StopCachingMidReadDropEntry) {
  StopMidRead();

  writers_->StopCaching(false /* keep_entry */);

  // Cannot add more writers while we are in network read only state.
  EXPECT_FALSE(CanAddWriters());

  // Complete the pending read.
  base::RunLoop().RunUntilIdle();

  // Read the rest of the content and the cache entry shouldn't have truncated.
  std::string remaining_content;
  Read(&remaining_content);
  EXPECT_EQ(1, test_cache_.WritersDoneWritingToEntryCount());
  EXPECT_FALSE(Truncated());
}

// Tests removing of an idle transaction and change in priority.
TEST_F(WritersTest, RemoveIdleTransaction) {
  CreateWritersAddTransactionPriority(HIGHEST);
  UpdateAndVerifyPriority(HIGHEST);

  AddTransactionToExistingWriters();
  UpdateAndVerifyPriority(HIGHEST);

  EXPECT_FALSE(writers_->IsEmpty());
  EXPECT_EQ(2, writers_->GetTransactionsCount());

  RemoveFirstTransaction();
  EXPECT_EQ(1, writers_->GetTransactionsCount());

  UpdateAndVerifyPriority(DEFAULT_PRIORITY);
}

// Tests that Read is successful.
TEST_F(WritersTest, Read) {
  CreateWritersAddTransaction();
  EXPECT_FALSE(writers_->IsEmpty());

  std::string content;
  int rv = Read(&content);

  EXPECT_THAT(rv, IsOk());
  std::string expected(kSimpleGET_Transaction.data);
  EXPECT_EQ(expected, content);
}

// Tests that multiple transactions can read the same data simultaneously.
TEST_F(WritersTest, ReadMultiple) {
  CreateWritersAddTransaction();
  EXPECT_FALSE(writers_->IsEmpty());

  EXPECT_TRUE(CanAddWriters());
  AddTransactionToExistingWriters();
  AddTransactionToExistingWriters();

  ReadAll();

  EXPECT_EQ(1, test_cache_.WritersDoneWritingToEntryCount());
}

// Tests that multiple transactions can read the same data simultaneously.
TEST_F(WritersTest, ReadMultipleDifferentBufferSizes) {
  CreateWritersAddTransaction();
  EXPECT_FALSE(writers_->IsEmpty());

  EXPECT_TRUE(CanAddWriters());
  AddTransactionToExistingWriters();

  std::vector<int> buffer_lengths{20, 10};
  ReadVerifyTwoDifferentBufferLengths(buffer_lengths);
}

// Same as above but tests the first transaction having smaller buffer size
// than the next.
TEST_F(WritersTest, ReadMultipleDifferentBufferSizes1) {
  CreateWritersAddTransaction();
  EXPECT_FALSE(writers_->IsEmpty());

  EXPECT_TRUE(CanAddWriters());
  AddTransactionToExistingWriters();

  std::vector<int> buffer_lengths{10, 20};
  ReadVerifyTwoDifferentBufferLengths(buffer_lengths);
}

// Tests that ongoing Read completes even when active transaction is deleted
// mid-read. Any transactions waiting should be able to get the read buffer.
TEST_F(WritersTest, ReadMultipleDeleteActiveTransaction) {
  CreateWritersAddTransaction();
  EXPECT_FALSE(writers_->IsEmpty());

  EXPECT_TRUE(CanAddWriters());
  AddTransactionToExistingWriters();
  AddTransactionToExistingWriters();

  ReadAllDeleteTransaction(DeleteTransactionType::ACTIVE);
  EXPECT_EQ(1, test_cache_.WritersDoneWritingToEntryCount());
}

// Tests that ongoing Read is ignored when an active transaction is deleted
// mid-read and there are no more transactions. It should also successfully
// initiate truncation of the entry.
TEST_F(WritersTest, MidReadDeleteActiveTransaction) {
  StopMidRead();

  // Removed the transaction while the read is pending.
  RemoveFirstTransaction();

  EXPECT_EQ(1, test_cache_.WritersDoneWritingToEntryCount());
  EXPECT_TRUE(Truncated());
  EXPECT_TRUE(writers_->IsEmpty());
}

// Tests that removing a waiting for read transaction does not impact other
// transactions.
TEST_F(WritersTest, ReadMultipleDeleteWaitingTransaction) {
  CreateWritersAddTransaction();
  EXPECT_FALSE(writers_->IsEmpty());

  EXPECT_TRUE(CanAddWriters());
  AddTransactionToExistingWriters();
  AddTransactionToExistingWriters();
  AddTransactionToExistingWriters();

  std::vector<std::string> contents(4);
  ReadAllDeleteTransaction(DeleteTransactionType::WAITING);
}

// Tests that removing an idle transaction does not impact other transactions.
TEST_F(WritersTest, ReadMultipleDeleteIdleTransaction) {
  CreateWritersAddTransaction();
  EXPECT_FALSE(writers_->IsEmpty());

  EXPECT_TRUE(CanAddWriters());
  AddTransactionToExistingWriters();
  AddTransactionToExistingWriters();

  std::vector<std::string> contents(3);
  ReadAllDeleteTransaction(DeleteTransactionType::IDLE);
}

// Tests cache write failure.
TEST_F(WritersTest, ReadMultipleCacheWriteFailed) {
  CreateWritersAddTransaction();
  EXPECT_FALSE(writers_->IsEmpty());

  EXPECT_TRUE(CanAddWriters());
  AddTransactionToExistingWriters();
  AddTransactionToExistingWriters();

  std::vector<std::string> contents(3);
  int rv = ReadCacheWriteFailure(&contents);

  EXPECT_THAT(rv, IsOk());
  std::string expected(kSimpleGET_Transaction.data);

  // Only active_transaction_ should succeed.
  EXPECT_EQ(expected, contents.at(0));
}

// Tests that network read failure fails all transactions: active, waiting and
// idle.
TEST_F(WritersTest, ReadMultipleNetworkReadFailed) {
  ScopedMockTransaction transaction(kSimpleGET_Transaction);
  transaction.read_return_code = ERR_INTERNET_DISCONNECTED;
  MockHttpRequest request(transaction);
  request_ = request;

  CreateWritersAddTransaction();
  EXPECT_FALSE(writers_->IsEmpty());

  EXPECT_TRUE(CanAddWriters());
  AddTransactionToExistingWriters();
  AddTransactionToExistingWriters();

  std::vector<std::string> contents(3);
  int rv = ReadNetworkFailure(&contents, ERR_INTERNET_DISCONNECTED);

  EXPECT_EQ(ERR_INTERNET_DISCONNECTED, rv);
}

// Tests GetLoadState.
TEST_F(WritersTest, GetLoadState) {
  CreateWritersAddTransaction();
  EXPECT_FALSE(writers_->IsEmpty());

  EXPECT_EQ(LOAD_STATE_IDLE, writers_->GetLoadState());
}

// Tests truncating logic.
TEST_F(WritersTest, TruncateEntryFail) {
  CreateWritersAddTransaction();

  EXPECT_FALSE(writers_->IsEmpty());

  RemoveFirstTransaction();

  // Should return false since no content was written to the entry.
  EXPECT_FALSE(ShouldTruncate());
  EXPECT_FALSE(ShouldKeepEntry());
}

// Set network read only.
TEST_F(WritersTest, StopCachingWithKeepEntry) {
  CreateWritersAddTransaction(HttpCache::PARALLEL_WRITING_NOT_JOIN_RANGE);
  EXPECT_FALSE(writers_->network_read_only());

  writers_->StopCaching(true /* keep_entry */);
  EXPECT_TRUE(writers_->network_read_only());
  EXPECT_TRUE(ShouldKeepEntry());
}

TEST_F(WritersTest, StopCachingWithNotKeepEntry) {
  CreateWritersAddTransaction(HttpCache::PARALLEL_WRITING_NOT_JOIN_RANGE);
  EXPECT_FALSE(writers_->network_read_only());

  writers_->StopCaching(false /* keep_entry */);
  EXPECT_TRUE(writers_->network_read_only());
  EXPECT_FALSE(ShouldKeepEntry());
}

// Tests that if content-encoding is set, the entry should not be marked as
// truncated, since we should not be creating range requests for compressed
// entries.
TEST_F(WritersTest, ContentEncodingShouldNotTruncate) {
  CreateWritersAddTransaction(HttpCache::PARALLEL_WRITING_JOIN,
                              true /* content_encoding_present */);
  std::string result;
  ReadFewBytes(&result);

  EXPECT_FALSE(ShouldTruncate());
  EXPECT_FALSE(ShouldKeepEntry());
}

}  // namespace net
