Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(444)

Unified Diff: net/http/http_cache_unittest.cc

Issue 2953983003: Adds cache lock timeout handling after finishing headers phase. (Closed)
Patch Set: Changed bypass lock condition and renamed AddTimeoutHandler Created 3 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
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) {

Powered by Google App Engine
This is Rietveld 408576698