| Index: net/http/http_cache_unittest.cc
|
| diff --git a/net/http/http_cache_unittest.cc b/net/http/http_cache_unittest.cc
|
| index 869708fd5602892ecedeff35968a91ff7613f214..b01427a7a6164b85c0ede119fb4c1da12d1bc7d7 100644
|
| --- a/net/http/http_cache_unittest.cc
|
| +++ b/net/http/http_cache_unittest.cc
|
| @@ -1576,6 +1576,92 @@ TEST(HttpCache, RangeGET_ParallelValidationDifferentRanges) {
|
| EXPECT_EQ(1, cache.disk_cache()->create_count());
|
| }
|
|
|
| +// Tests parallel validation on range requests can be successfully restarted
|
| +// when there is a cache lock timeout.
|
| +TEST(HttpCache, RangeGET_ParallelValidationCacheLockTimeout) {
|
| + MockHttpCache cache;
|
| +
|
| + ScopedMockTransaction transaction(kRangeGET_TransactionOK);
|
| +
|
| + std::vector<std::unique_ptr<Context>> context_list;
|
| + const int kNumTransactions = 2;
|
| +
|
| + for (int i = 0; i < kNumTransactions; ++i) {
|
| + context_list.push_back(base::MakeUnique<Context>());
|
| + }
|
| +
|
| + // Let 1st transaction complete headers phase for ranges 40-49.
|
| + std::string first_read;
|
| + MockHttpRequest request1(transaction);
|
| + {
|
| + auto& c = context_list[0];
|
| + c->result = cache.CreateTransaction(&c->trans);
|
| + ASSERT_THAT(c->result, IsOk());
|
| + EXPECT_EQ(LOAD_STATE_IDLE, c->trans->GetLoadState());
|
| +
|
| + c->result =
|
| + c->trans->Start(&request1, c->callback.callback(), NetLogWithSource());
|
| + base::RunLoop().RunUntilIdle();
|
| +
|
| + // Start writing to the cache so that MockDiskEntry::CouldBeSparse() returns
|
| + // true.
|
| + const int kBufferSize = 5;
|
| + scoped_refptr<IOBuffer> buffer(new IOBuffer(kBufferSize));
|
| + ReleaseBufferCompletionCallback cb(buffer.get());
|
| + c->result = c->trans->Read(buffer.get(), kBufferSize, cb.callback());
|
| + EXPECT_EQ(kBufferSize, cb.GetResult(c->result));
|
| +
|
| + std::string data_read(buffer->data(), kBufferSize);
|
| + first_read = data_read;
|
| +
|
| + EXPECT_EQ(LOAD_STATE_READING_RESPONSE, c->trans->GetLoadState());
|
| + }
|
| +
|
| + cache.SimulateCacheLockTimeoutAfterHeaders();
|
| +
|
| + // 2nd transaction requests ranges 30-39.
|
| + transaction.request_headers = "Range: bytes = 30-39\r\n" EXTRA_HEADER;
|
| + MockHttpRequest request2(transaction);
|
| + {
|
| + auto& c = context_list[1];
|
| + c->result = cache.CreateTransaction(&c->trans);
|
| + ASSERT_THAT(c->result, IsOk());
|
| + EXPECT_EQ(LOAD_STATE_IDLE, c->trans->GetLoadState());
|
| +
|
| + c->result =
|
| + c->trans->Start(&request2, c->callback.callback(), NetLogWithSource());
|
| + base::RunLoop().RunUntilIdle();
|
| +
|
| + EXPECT_EQ(LOAD_STATE_IDLE, c->trans->GetLoadState());
|
| + }
|
| +
|
| + EXPECT_TRUE(cache.IsWriterPresent(kRangeGET_TransactionOK.url));
|
| + EXPECT_EQ(0, cache.GetCountDoneHeadersQueue(kRangeGET_TransactionOK.url));
|
| +
|
| + EXPECT_EQ(3, cache.network_layer()->transaction_count());
|
| + EXPECT_EQ(0, cache.disk_cache()->open_count());
|
| + EXPECT_EQ(1, cache.disk_cache()->create_count());
|
| +
|
| + for (int i = 0; i < kNumTransactions; ++i) {
|
| + auto& c = context_list[i];
|
| + if (c->result == ERR_IO_PENDING)
|
| + c->result = c->callback.WaitForResult();
|
| +
|
| + if (i == 0) {
|
| + ReadRemainingAndVerifyTransaction(c->trans.get(), first_read,
|
| + transaction);
|
| + continue;
|
| + }
|
| +
|
| + transaction.data = "rg: 30-39 ";
|
| + ReadAndVerifyTransaction(c->trans.get(), transaction);
|
| + }
|
| +
|
| + EXPECT_EQ(3, cache.network_layer()->transaction_count());
|
| + EXPECT_EQ(0, cache.disk_cache()->open_count());
|
| + EXPECT_EQ(1, cache.disk_cache()->create_count());
|
| +}
|
| +
|
| // Tests parallel validation on range requests with overlapping ranges.
|
| TEST(HttpCache, RangeGET_ParallelValidationOverlappingRanges) {
|
| MockHttpCache cache;
|
| @@ -1939,6 +2025,53 @@ TEST(HttpCache, SimpleGET_ParallelValidationCancelValidated) {
|
| EXPECT_EQ(1, cache.disk_cache()->create_count());
|
| }
|
|
|
| +// Tests that a transaction which is in validated queue can timeout and start
|
| +// reading from the network without writing to the cache.
|
| +TEST(HttpCache, SimpleGET_ParallelValidationValidatedTimeout) {
|
| + MockHttpCache cache;
|
| +
|
| + MockHttpRequest request(kSimpleGET_Transaction);
|
| +
|
| + std::vector<std::unique_ptr<Context>> context_list;
|
| + const int kNumTransactions = 2;
|
| +
|
| + for (int i = 0; i < kNumTransactions; ++i) {
|
| + context_list.push_back(base::MakeUnique<Context>());
|
| + auto& c = context_list[i];
|
| +
|
| + if (i == 1)
|
| + cache.SimulateCacheLockTimeoutAfterHeaders();
|
| +
|
| + c->result = cache.CreateTransaction(&c->trans);
|
| + ASSERT_THAT(c->result, IsOk());
|
| +
|
| + c->result =
|
| + c->trans->Start(&request, c->callback.callback(), NetLogWithSource());
|
| + }
|
| +
|
| + // Allow all requests to move from the Create queue to the active entry.
|
| + base::RunLoop().RunUntilIdle();
|
| +
|
| + // The first request should be a writer at this point, and the subsequent
|
| + // requests should have completed validation, timed out and restarted.
|
| +
|
| + EXPECT_EQ(2, cache.network_layer()->transaction_count());
|
| + EXPECT_EQ(0, cache.disk_cache()->open_count());
|
| + EXPECT_EQ(1, cache.disk_cache()->create_count());
|
| +
|
| + EXPECT_TRUE(cache.IsWriterPresent(kSimpleGET_Transaction.url));
|
| + EXPECT_EQ(0, cache.GetCountDoneHeadersQueue(kSimpleGET_Transaction.url));
|
| +
|
| + // Complete the rest of the transactions.
|
| + for (auto& context : context_list) {
|
| + ReadAndVerifyTransaction(context->trans.get(), kSimpleGET_Transaction);
|
| + }
|
| +
|
| + EXPECT_EQ(2, cache.network_layer()->transaction_count());
|
| + EXPECT_EQ(0, cache.disk_cache()->open_count());
|
| + EXPECT_EQ(1, cache.disk_cache()->create_count());
|
| +}
|
| +
|
| // Tests that a transaction which is in readers can be destroyed without
|
| // any impact to other transactions.
|
| TEST(HttpCache, SimpleGET_ParallelValidationCancelReader) {
|
|
|