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

Side by Side Diff: net/http/http_cache_unittest.cc

Issue 2970133002: DoomPartialEntry should not attempt to doom an already doomed entry. (Closed)
Patch Set: GetDiskEntryRef added and doomed_entries_ removed Created 3 years, 5 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 unified diff | Download patch
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "net/http/http_cache.h" 5 #include "net/http/http_cache.h"
6 6
7 #include <stdint.h> 7 #include <stdint.h>
8 8
9 #include <algorithm> 9 #include <algorithm>
10 #include <memory> 10 #include <memory>
(...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after
140 // same value. 140 // same value.
141 EXPECT_FALSE(load_timing_info.send_start.is_null()); 141 EXPECT_FALSE(load_timing_info.send_start.is_null());
142 EXPECT_EQ(load_timing_info.send_start, load_timing_info.send_end); 142 EXPECT_EQ(load_timing_info.send_start, load_timing_info.send_end);
143 143
144 // Set by URLRequest / URLRequestHttpJob, at a higher level. 144 // Set by URLRequest / URLRequestHttpJob, at a higher level.
145 EXPECT_TRUE(load_timing_info.request_start_time.is_null()); 145 EXPECT_TRUE(load_timing_info.request_start_time.is_null());
146 EXPECT_TRUE(load_timing_info.request_start.is_null()); 146 EXPECT_TRUE(load_timing_info.request_start.is_null());
147 EXPECT_TRUE(load_timing_info.receive_headers_end.is_null()); 147 EXPECT_TRUE(load_timing_info.receive_headers_end.is_null());
148 } 148 }
149 149
150 void DeferNetworkStart(bool* defer) { 150 void DeferCallback(bool* defer) {
151 *defer = true; 151 *defer = true;
152 } 152 }
153 153
154 class DeleteCacheCompletionCallback : public TestCompletionCallbackBase { 154 class DeleteCacheCompletionCallback : public TestCompletionCallbackBase {
155 public: 155 public:
156 explicit DeleteCacheCompletionCallback(MockHttpCache* cache) 156 explicit DeleteCacheCompletionCallback(MockHttpCache* cache)
157 : cache_(cache), 157 : cache_(cache),
158 callback_(base::Bind(&DeleteCacheCompletionCallback::OnComplete, 158 callback_(base::Bind(&DeleteCacheCompletionCallback::OnComplete,
159 base::Unretained(this))) { 159 base::Unretained(this))) {
160 } 160 }
(...skipping 1310 matching lines...) Expand 10 before | Expand all | Expand 10 after
1471 c->result = c->callback.WaitForResult(); 1471 c->result = c->callback.WaitForResult();
1472 1472
1473 ReadAndVerifyTransaction(c->trans.get(), kRangeGET_TransactionOK); 1473 ReadAndVerifyTransaction(c->trans.get(), kRangeGET_TransactionOK);
1474 } 1474 }
1475 1475
1476 EXPECT_EQ(5, cache.network_layer()->transaction_count()); 1476 EXPECT_EQ(5, cache.network_layer()->transaction_count());
1477 EXPECT_EQ(0, cache.disk_cache()->open_count()); 1477 EXPECT_EQ(0, cache.disk_cache()->open_count());
1478 EXPECT_EQ(5, cache.disk_cache()->create_count()); 1478 EXPECT_EQ(5, cache.disk_cache()->create_count());
1479 } 1479 }
1480 1480
1481 // Tests that if a transaction is dooming the entry and the entry was doomed by
1482 // another transaction that was not part of the entry and created a new entry,
1483 // the new entry should not be incorrectly doomed. (crbug.com/736993)
1484 TEST(HttpCache, RangeGET_ParallelValidationNoMatchDoomEntry) {
1485 MockHttpCache cache;
1486
1487 ScopedMockTransaction transaction(kRangeGET_TransactionOK);
1488 MockHttpRequest request(transaction);
1489
1490 MockTransaction dooming_transaction(kRangeGET_TransactionOK);
1491 dooming_transaction.load_flags |= LOAD_BYPASS_CACHE;
1492 MockHttpRequest dooming_request(dooming_transaction);
1493
1494 std::vector<std::unique_ptr<Context>> context_list;
1495 const int kNumTransactions = 3;
1496
1497 MockDiskEntry* first_entry = nullptr;
1498 MockDiskEntry* second_entry = nullptr;
1499 for (int i = 0; i < kNumTransactions; ++i) {
1500 context_list.push_back(base::MakeUnique<Context>());
1501 auto& c = context_list[i];
1502
1503 c->result = cache.CreateTransaction(&c->trans);
1504 ASSERT_THAT(c->result, IsOk());
1505 EXPECT_EQ(LOAD_STATE_IDLE, c->trans->GetLoadState());
1506
1507 MockHttpRequest* this_request = &request;
1508
1509 if (i == 2)
1510 this_request = &dooming_request;
1511
1512 if (i == 1) {
1513 ASSERT_TRUE(first_entry);
1514 first_entry->SetDefer(MockDiskEntry::DEFER_READ);
1515 }
1516
1517 c->result = c->trans->Start(this_request, c->callback.callback(),
1518 NetLogWithSource());
1519
1520 // Continue the transactions. 2nd will pause at the cache reading state and
1521 // 3rd transaction will doom the entry.
1522 base::RunLoop().RunUntilIdle();
1523
1524 // Check status of the first and second entries after every transaction.
1525 switch (i) {
1526 case 0:
1527 first_entry =
1528 cache.disk_cache()->GetDiskEntryRef(kRangeGET_TransactionOK.url);
1529 break;
1530 case 1:
1531 EXPECT_FALSE(first_entry->is_doomed());
1532 break;
1533 case 2:
1534 EXPECT_TRUE(first_entry->is_doomed());
1535 second_entry =
1536 cache.disk_cache()->GetDiskEntryRef(kRangeGET_TransactionOK.url);
1537 EXPECT_FALSE(second_entry->is_doomed());
1538 break;
1539 }
1540 }
1541 // Resume cache read by 1st transaction which will lead to dooming the entry
1542 // as well since the entry cannot be validated. This double dooming should not
1543 // lead to an assertion.
1544 first_entry->ResumeCacheOperation();
1545 base::RunLoop().RunUntilIdle();
1546
1547 // Since second_entry is already created, when 1st transaction goes on to
1548 // create an entry, it will get ERR_CACHE_RACE leading to dooming of
1549 // second_entry and creation of a third entry.
1550 EXPECT_TRUE(second_entry->is_doomed());
1551
1552 EXPECT_EQ(3, cache.network_layer()->transaction_count());
1553 EXPECT_EQ(0, cache.disk_cache()->open_count());
1554 EXPECT_EQ(3, cache.disk_cache()->create_count());
1555
1556 for (auto& context : context_list) {
1557 EXPECT_EQ(LOAD_STATE_IDLE, context->trans->GetLoadState());
1558 }
1559
1560 for (auto& c : context_list) {
1561 ReadAndVerifyTransaction(c->trans.get(), kRangeGET_TransactionOK);
1562 }
1563
1564 EXPECT_EQ(3, cache.network_layer()->transaction_count());
1565 EXPECT_EQ(0, cache.disk_cache()->open_count());
1566 EXPECT_EQ(3, cache.disk_cache()->create_count());
1567
1568 if (first_entry)
1569 first_entry->Close();
1570 if (second_entry)
1571 second_entry->Close();
1572 }
1573
1574 // Same as above but tests that the 2nd transaction does not do anything if
1575 // there is nothing to doom. (crbug.com/736993)
1576 TEST(HttpCache, RangeGET_ParallelValidationNoMatchDoomEntry1) {
1577 MockHttpCache cache;
1578
1579 ScopedMockTransaction transaction(kRangeGET_TransactionOK);
1580 MockHttpRequest request(transaction);
1581
1582 MockTransaction dooming_transaction(kRangeGET_TransactionOK);
1583 dooming_transaction.load_flags |= LOAD_BYPASS_CACHE;
1584 MockHttpRequest dooming_request(dooming_transaction);
1585
1586 std::vector<std::unique_ptr<Context>> context_list;
1587 const int kNumTransactions = 3;
1588
1589 MockDiskEntry* first_entry = nullptr;
1590 for (int i = 0; i < kNumTransactions; ++i) {
1591 context_list.push_back(base::MakeUnique<Context>());
1592 auto& c = context_list[i];
1593
1594 c->result = cache.CreateTransaction(&c->trans);
1595 ASSERT_THAT(c->result, IsOk());
1596 EXPECT_EQ(LOAD_STATE_IDLE, c->trans->GetLoadState());
1597
1598 MockHttpRequest* this_request = &request;
1599
1600 if (i == 2) {
1601 this_request = &dooming_request;
1602 cache.disk_cache()->SetDefer(MockDiskEntry::DEFER_CREATE);
1603 }
1604
1605 if (i == 1) {
1606 ASSERT_TRUE(first_entry != nullptr);
1607 first_entry->SetDefer(MockDiskEntry::DEFER_READ);
1608 }
1609
1610 c->result = c->trans->Start(this_request, c->callback.callback(),
1611 NetLogWithSource());
1612
1613 // Continue the transactions. 2nd will pause at the cache reading state and
1614 // 3rd transaction will doom the entry and pause before creating a new
1615 // entry.
1616 base::RunLoop().RunUntilIdle();
1617
1618 // Check status of the entry after every transaction.
1619 switch (i) {
1620 case 0:
1621 first_entry =
1622 cache.disk_cache()->GetDiskEntryRef(kRangeGET_TransactionOK.url);
1623 break;
1624 case 1:
1625 EXPECT_FALSE(first_entry->is_doomed());
1626 break;
1627 case 2:
1628 EXPECT_TRUE(first_entry->is_doomed());
1629 break;
1630 }
1631 }
1632 // Resume cache read by 2nd transaction which will lead to dooming the entry
1633 // as well since the entry cannot be validated. This double dooming should not
1634 // lead to an assertion.
1635 first_entry->ResumeCacheOperation();
1636 base::RunLoop().RunUntilIdle();
1637
1638 // Resume creation of entry by 3rd transaction.
1639 cache.disk_cache()->ResumeCacheOperation();
1640 base::RunLoop().RunUntilIdle();
1641
1642 // Note that since 3rd transaction's entry is already created but its
1643 // callback is deferred, MockDiskCache's implementation returns
1644 // ERR_CACHE_CREATE_FAILURE when 2nd transaction tries to create an entry
1645 // during that time, leading to it switching over to pass-through mode.
1646 // Thus the number of entries is 2 below.
1647 EXPECT_EQ(3, cache.network_layer()->transaction_count());
1648 EXPECT_EQ(0, cache.disk_cache()->open_count());
1649 EXPECT_EQ(2, cache.disk_cache()->create_count());
1650
1651 for (auto& context : context_list) {
1652 EXPECT_EQ(LOAD_STATE_IDLE, context->trans->GetLoadState());
1653 }
1654
1655 for (auto& c : context_list) {
1656 ReadAndVerifyTransaction(c->trans.get(), kRangeGET_TransactionOK);
1657 }
1658
1659 EXPECT_EQ(3, cache.network_layer()->transaction_count());
1660 EXPECT_EQ(0, cache.disk_cache()->open_count());
1661 EXPECT_EQ(2, cache.disk_cache()->create_count());
1662
1663 if (first_entry)
1664 first_entry->Close();
1665 }
1666
1481 // Tests parallel validation on range requests with non-overlapping ranges. 1667 // Tests parallel validation on range requests with non-overlapping ranges.
1482 TEST(HttpCache, RangeGET_ParallelValidationDifferentRanges) { 1668 TEST(HttpCache, RangeGET_ParallelValidationDifferentRanges) {
1483 MockHttpCache cache; 1669 MockHttpCache cache;
1484 1670
1485 ScopedMockTransaction transaction(kRangeGET_TransactionOK); 1671 ScopedMockTransaction transaction(kRangeGET_TransactionOK);
1486 1672
1487 std::vector<std::unique_ptr<Context>> context_list; 1673 std::vector<std::unique_ptr<Context>> context_list;
1488 const int kNumTransactions = 2; 1674 const int kNumTransactions = 2;
1489 1675
1490 for (int i = 0; i < kNumTransactions; ++i) { 1676 for (int i = 0; i < kNumTransactions; ++i) {
(...skipping 661 matching lines...) Expand 10 before | Expand all | Expand 10 after
2152 for (int i = 0; i < kNumTransactions; ++i) { 2338 for (int i = 0; i < kNumTransactions; ++i) {
2153 context_list.push_back(base::MakeUnique<Context>()); 2339 context_list.push_back(base::MakeUnique<Context>());
2154 auto& c = context_list[i]; 2340 auto& c = context_list[i];
2155 2341
2156 c->result = cache.CreateTransaction(&c->trans); 2342 c->result = cache.CreateTransaction(&c->trans);
2157 ASSERT_THAT(c->result, IsOk()); 2343 ASSERT_THAT(c->result, IsOk());
2158 2344
2159 MockHttpRequest* this_request = &request; 2345 MockHttpRequest* this_request = &request;
2160 if (i == 3) { 2346 if (i == 3) {
2161 this_request = &validate_request; 2347 this_request = &validate_request;
2162 c->trans->SetBeforeNetworkStartCallback(base::Bind(&DeferNetworkStart)); 2348 c->trans->SetBeforeNetworkStartCallback(base::Bind(&DeferCallback));
2163 } 2349 }
2164 2350
2165 c->result = c->trans->Start(this_request, c->callback.callback(), 2351 c->result = c->trans->Start(this_request, c->callback.callback(),
2166 NetLogWithSource()); 2352 NetLogWithSource());
2167 } 2353 }
2168 2354
2169 // Allow all requests to move from the Create queue to the active entry. 2355 // Allow all requests to move from the Create queue to the active entry.
2170 base::RunLoop().RunUntilIdle(); 2356 base::RunLoop().RunUntilIdle();
2171 2357
2172 EXPECT_EQ(2, cache.network_layer()->transaction_count()); 2358 EXPECT_EQ(2, cache.network_layer()->transaction_count());
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after
2250 for (int i = 0; i < kNumTransactions; ++i) { 2436 for (int i = 0; i < kNumTransactions; ++i) {
2251 context_list.push_back(base::MakeUnique<Context>()); 2437 context_list.push_back(base::MakeUnique<Context>());
2252 auto& c = context_list[i]; 2438 auto& c = context_list[i];
2253 2439
2254 c->result = cache.CreateTransaction(&c->trans); 2440 c->result = cache.CreateTransaction(&c->trans);
2255 ASSERT_THAT(c->result, IsOk()); 2441 ASSERT_THAT(c->result, IsOk());
2256 2442
2257 MockHttpRequest* this_request = &request; 2443 MockHttpRequest* this_request = &request;
2258 if (i == 2) { 2444 if (i == 2) {
2259 this_request = &validate_request; 2445 this_request = &validate_request;
2260 c->trans->SetBeforeNetworkStartCallback(base::Bind(&DeferNetworkStart)); 2446 c->trans->SetBeforeNetworkStartCallback(base::Bind(&DeferCallback));
2261 } 2447 }
2262 2448
2263 c->result = c->trans->Start(this_request, c->callback.callback(), 2449 c->result = c->trans->Start(this_request, c->callback.callback(),
2264 NetLogWithSource()); 2450 NetLogWithSource());
2265 } 2451 }
2266 2452
2267 // Allow all requests to move from the Create queue to the active entry. 2453 // Allow all requests to move from the Create queue to the active entry.
2268 base::RunLoop().RunUntilIdle(); 2454 base::RunLoop().RunUntilIdle();
2269 2455
2270 EXPECT_EQ(2, cache.network_layer()->transaction_count()); 2456 EXPECT_EQ(2, cache.network_layer()->transaction_count());
(...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after
2388 for (int i = 0; i < kNumTransactions; ++i) { 2574 for (int i = 0; i < kNumTransactions; ++i) {
2389 context_list.push_back(base::MakeUnique<Context>()); 2575 context_list.push_back(base::MakeUnique<Context>());
2390 auto& c = context_list[i]; 2576 auto& c = context_list[i];
2391 2577
2392 c->result = cache.CreateTransaction(&c->trans); 2578 c->result = cache.CreateTransaction(&c->trans);
2393 ASSERT_THAT(c->result, IsOk()); 2579 ASSERT_THAT(c->result, IsOk());
2394 2580
2395 MockHttpRequest* this_request = &request; 2581 MockHttpRequest* this_request = &request;
2396 if (i == 2) { 2582 if (i == 2) {
2397 this_request = &validate_request; 2583 this_request = &validate_request;
2398 c->trans->SetBeforeNetworkStartCallback(base::Bind(&DeferNetworkStart)); 2584 c->trans->SetBeforeNetworkStartCallback(base::Bind(&DeferCallback));
2399 } 2585 }
2400 2586
2401 c->result = c->trans->Start(this_request, c->callback.callback(), 2587 c->result = c->trans->Start(this_request, c->callback.callback(),
2402 NetLogWithSource()); 2588 NetLogWithSource());
2403 } 2589 }
2404 2590
2405 // Allow all requests to move from the Create queue to the active entry. 2591 // Allow all requests to move from the Create queue to the active entry.
2406 base::RunLoop().RunUntilIdle(); 2592 base::RunLoop().RunUntilIdle();
2407 2593
2408 EXPECT_EQ(2, cache.network_layer()->transaction_count()); 2594 EXPECT_EQ(2, cache.network_layer()->transaction_count());
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
2454 std::vector<std::unique_ptr<Context>> context_list; 2640 std::vector<std::unique_ptr<Context>> context_list;
2455 2641
2456 for (int i = 0; i < kNumTransactions; ++i) { 2642 for (int i = 0; i < kNumTransactions; ++i) {
2457 context_list.push_back(base::MakeUnique<Context>()); 2643 context_list.push_back(base::MakeUnique<Context>());
2458 auto& c = context_list[i]; 2644 auto& c = context_list[i];
2459 2645
2460 c->result = cache.CreateTransaction(&c->trans); 2646 c->result = cache.CreateTransaction(&c->trans);
2461 ASSERT_THAT(c->result, IsOk()); 2647 ASSERT_THAT(c->result, IsOk());
2462 2648
2463 if (i == 0) 2649 if (i == 0)
2464 c->trans->SetBeforeNetworkStartCallback(base::Bind(&DeferNetworkStart)); 2650 c->trans->SetBeforeNetworkStartCallback(base::Bind(&DeferCallback));
2465 2651
2466 c->result = 2652 c->result =
2467 c->trans->Start(&request, c->callback.callback(), NetLogWithSource()); 2653 c->trans->Start(&request, c->callback.callback(), NetLogWithSource());
2468 } 2654 }
2469 2655
2470 base::RunLoop().RunUntilIdle(); 2656 base::RunLoop().RunUntilIdle();
2471 2657
2472 EXPECT_TRUE(cache.IsHeadersTransactionPresent(kSimpleGET_Transaction.url)); 2658 EXPECT_TRUE(cache.IsHeadersTransactionPresent(kSimpleGET_Transaction.url));
2473 EXPECT_EQ(1, cache.GetCountAddToEntryQueue(kSimpleGET_Transaction.url)); 2659 EXPECT_EQ(1, cache.GetCountAddToEntryQueue(kSimpleGET_Transaction.url));
2474 2660
(...skipping 6884 matching lines...) Expand 10 before | Expand all | Expand 10 after
9359 ASSERT_TRUE(attrs->GetDictionary( 9545 ASSERT_TRUE(attrs->GetDictionary(
9360 base::trace_event::MemoryAllocatorDump::kNameSize, &size_attrs)); 9546 base::trace_event::MemoryAllocatorDump::kNameSize, &size_attrs));
9361 std::string size; 9547 std::string size;
9362 ASSERT_TRUE(size_attrs->GetString("value", &size)); 9548 ASSERT_TRUE(size_attrs->GetString("value", &size));
9363 int actual_size = 0; 9549 int actual_size = 0;
9364 ASSERT_TRUE(base::HexStringToInt(size, &actual_size)); 9550 ASSERT_TRUE(base::HexStringToInt(size, &actual_size));
9365 ASSERT_LT(0, actual_size); 9551 ASSERT_LT(0, actual_size);
9366 } 9552 }
9367 9553
9368 } // namespace net 9554 } // namespace net
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698