| OLD | NEW |
| 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 Loading... |
| 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 Loading... |
| 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 scoped_refptr<MockDiskEntry> first_entry; |
| 1498 scoped_refptr<MockDiskEntry> second_entry; |
| 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->ResumeDiskEntryOperation(); |
| 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 |
| 1569 // Same as above but tests that the 2nd transaction does not do anything if |
| 1570 // there is nothing to doom. (crbug.com/736993) |
| 1571 TEST(HttpCache, RangeGET_ParallelValidationNoMatchDoomEntry1) { |
| 1572 MockHttpCache cache; |
| 1573 |
| 1574 ScopedMockTransaction transaction(kRangeGET_TransactionOK); |
| 1575 MockHttpRequest request(transaction); |
| 1576 |
| 1577 MockTransaction dooming_transaction(kRangeGET_TransactionOK); |
| 1578 dooming_transaction.load_flags |= LOAD_BYPASS_CACHE; |
| 1579 MockHttpRequest dooming_request(dooming_transaction); |
| 1580 |
| 1581 std::vector<std::unique_ptr<Context>> context_list; |
| 1582 const int kNumTransactions = 3; |
| 1583 |
| 1584 scoped_refptr<MockDiskEntry> first_entry; |
| 1585 for (int i = 0; i < kNumTransactions; ++i) { |
| 1586 context_list.push_back(base::MakeUnique<Context>()); |
| 1587 auto& c = context_list[i]; |
| 1588 |
| 1589 c->result = cache.CreateTransaction(&c->trans); |
| 1590 ASSERT_THAT(c->result, IsOk()); |
| 1591 EXPECT_EQ(LOAD_STATE_IDLE, c->trans->GetLoadState()); |
| 1592 |
| 1593 MockHttpRequest* this_request = &request; |
| 1594 |
| 1595 if (i == 2) { |
| 1596 this_request = &dooming_request; |
| 1597 cache.disk_cache()->SetDefer(MockDiskEntry::DEFER_CREATE); |
| 1598 } |
| 1599 |
| 1600 if (i == 1) { |
| 1601 ASSERT_TRUE(first_entry); |
| 1602 first_entry->SetDefer(MockDiskEntry::DEFER_READ); |
| 1603 } |
| 1604 |
| 1605 c->result = c->trans->Start(this_request, c->callback.callback(), |
| 1606 NetLogWithSource()); |
| 1607 |
| 1608 // Continue the transactions. 2nd will pause at the cache reading state and |
| 1609 // 3rd transaction will doom the entry and pause before creating a new |
| 1610 // entry. |
| 1611 base::RunLoop().RunUntilIdle(); |
| 1612 |
| 1613 // Check status of the entry after every transaction. |
| 1614 switch (i) { |
| 1615 case 0: |
| 1616 first_entry = |
| 1617 cache.disk_cache()->GetDiskEntryRef(kRangeGET_TransactionOK.url); |
| 1618 break; |
| 1619 case 1: |
| 1620 EXPECT_FALSE(first_entry->is_doomed()); |
| 1621 break; |
| 1622 case 2: |
| 1623 EXPECT_TRUE(first_entry->is_doomed()); |
| 1624 break; |
| 1625 } |
| 1626 } |
| 1627 // Resume cache read by 2nd transaction which will lead to dooming the entry |
| 1628 // as well since the entry cannot be validated. This double dooming should not |
| 1629 // lead to an assertion. |
| 1630 first_entry->ResumeDiskEntryOperation(); |
| 1631 base::RunLoop().RunUntilIdle(); |
| 1632 |
| 1633 // Resume creation of entry by 3rd transaction. |
| 1634 cache.disk_cache()->ResumeCacheOperation(); |
| 1635 base::RunLoop().RunUntilIdle(); |
| 1636 |
| 1637 // Note that since 3rd transaction's entry is already created but its |
| 1638 // callback is deferred, MockDiskCache's implementation returns |
| 1639 // ERR_CACHE_CREATE_FAILURE when 2nd transaction tries to create an entry |
| 1640 // during that time, leading to it switching over to pass-through mode. |
| 1641 // Thus the number of entries is 2 below. |
| 1642 EXPECT_EQ(3, cache.network_layer()->transaction_count()); |
| 1643 EXPECT_EQ(0, cache.disk_cache()->open_count()); |
| 1644 EXPECT_EQ(2, cache.disk_cache()->create_count()); |
| 1645 |
| 1646 for (auto& context : context_list) { |
| 1647 EXPECT_EQ(LOAD_STATE_IDLE, context->trans->GetLoadState()); |
| 1648 } |
| 1649 |
| 1650 for (auto& c : context_list) { |
| 1651 ReadAndVerifyTransaction(c->trans.get(), kRangeGET_TransactionOK); |
| 1652 } |
| 1653 |
| 1654 EXPECT_EQ(3, cache.network_layer()->transaction_count()); |
| 1655 EXPECT_EQ(0, cache.disk_cache()->open_count()); |
| 1656 EXPECT_EQ(2, cache.disk_cache()->create_count()); |
| 1657 } |
| 1658 |
| 1481 // Tests parallel validation on range requests with non-overlapping ranges. | 1659 // Tests parallel validation on range requests with non-overlapping ranges. |
| 1482 TEST(HttpCache, RangeGET_ParallelValidationDifferentRanges) { | 1660 TEST(HttpCache, RangeGET_ParallelValidationDifferentRanges) { |
| 1483 MockHttpCache cache; | 1661 MockHttpCache cache; |
| 1484 | 1662 |
| 1485 ScopedMockTransaction transaction(kRangeGET_TransactionOK); | 1663 ScopedMockTransaction transaction(kRangeGET_TransactionOK); |
| 1486 | 1664 |
| 1487 std::vector<std::unique_ptr<Context>> context_list; | 1665 std::vector<std::unique_ptr<Context>> context_list; |
| 1488 const int kNumTransactions = 2; | 1666 const int kNumTransactions = 2; |
| 1489 | 1667 |
| 1490 for (int i = 0; i < kNumTransactions; ++i) { | 1668 for (int i = 0; i < kNumTransactions; ++i) { |
| (...skipping 661 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2152 for (int i = 0; i < kNumTransactions; ++i) { | 2330 for (int i = 0; i < kNumTransactions; ++i) { |
| 2153 context_list.push_back(base::MakeUnique<Context>()); | 2331 context_list.push_back(base::MakeUnique<Context>()); |
| 2154 auto& c = context_list[i]; | 2332 auto& c = context_list[i]; |
| 2155 | 2333 |
| 2156 c->result = cache.CreateTransaction(&c->trans); | 2334 c->result = cache.CreateTransaction(&c->trans); |
| 2157 ASSERT_THAT(c->result, IsOk()); | 2335 ASSERT_THAT(c->result, IsOk()); |
| 2158 | 2336 |
| 2159 MockHttpRequest* this_request = &request; | 2337 MockHttpRequest* this_request = &request; |
| 2160 if (i == 3) { | 2338 if (i == 3) { |
| 2161 this_request = &validate_request; | 2339 this_request = &validate_request; |
| 2162 c->trans->SetBeforeNetworkStartCallback(base::Bind(&DeferNetworkStart)); | 2340 c->trans->SetBeforeNetworkStartCallback(base::Bind(&DeferCallback)); |
| 2163 } | 2341 } |
| 2164 | 2342 |
| 2165 c->result = c->trans->Start(this_request, c->callback.callback(), | 2343 c->result = c->trans->Start(this_request, c->callback.callback(), |
| 2166 NetLogWithSource()); | 2344 NetLogWithSource()); |
| 2167 } | 2345 } |
| 2168 | 2346 |
| 2169 // Allow all requests to move from the Create queue to the active entry. | 2347 // Allow all requests to move from the Create queue to the active entry. |
| 2170 base::RunLoop().RunUntilIdle(); | 2348 base::RunLoop().RunUntilIdle(); |
| 2171 | 2349 |
| 2172 EXPECT_EQ(2, cache.network_layer()->transaction_count()); | 2350 EXPECT_EQ(2, cache.network_layer()->transaction_count()); |
| (...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2250 for (int i = 0; i < kNumTransactions; ++i) { | 2428 for (int i = 0; i < kNumTransactions; ++i) { |
| 2251 context_list.push_back(base::MakeUnique<Context>()); | 2429 context_list.push_back(base::MakeUnique<Context>()); |
| 2252 auto& c = context_list[i]; | 2430 auto& c = context_list[i]; |
| 2253 | 2431 |
| 2254 c->result = cache.CreateTransaction(&c->trans); | 2432 c->result = cache.CreateTransaction(&c->trans); |
| 2255 ASSERT_THAT(c->result, IsOk()); | 2433 ASSERT_THAT(c->result, IsOk()); |
| 2256 | 2434 |
| 2257 MockHttpRequest* this_request = &request; | 2435 MockHttpRequest* this_request = &request; |
| 2258 if (i == 2) { | 2436 if (i == 2) { |
| 2259 this_request = &validate_request; | 2437 this_request = &validate_request; |
| 2260 c->trans->SetBeforeNetworkStartCallback(base::Bind(&DeferNetworkStart)); | 2438 c->trans->SetBeforeNetworkStartCallback(base::Bind(&DeferCallback)); |
| 2261 } | 2439 } |
| 2262 | 2440 |
| 2263 c->result = c->trans->Start(this_request, c->callback.callback(), | 2441 c->result = c->trans->Start(this_request, c->callback.callback(), |
| 2264 NetLogWithSource()); | 2442 NetLogWithSource()); |
| 2265 } | 2443 } |
| 2266 | 2444 |
| 2267 // Allow all requests to move from the Create queue to the active entry. | 2445 // Allow all requests to move from the Create queue to the active entry. |
| 2268 base::RunLoop().RunUntilIdle(); | 2446 base::RunLoop().RunUntilIdle(); |
| 2269 | 2447 |
| 2270 EXPECT_EQ(2, cache.network_layer()->transaction_count()); | 2448 EXPECT_EQ(2, cache.network_layer()->transaction_count()); |
| (...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2388 for (int i = 0; i < kNumTransactions; ++i) { | 2566 for (int i = 0; i < kNumTransactions; ++i) { |
| 2389 context_list.push_back(base::MakeUnique<Context>()); | 2567 context_list.push_back(base::MakeUnique<Context>()); |
| 2390 auto& c = context_list[i]; | 2568 auto& c = context_list[i]; |
| 2391 | 2569 |
| 2392 c->result = cache.CreateTransaction(&c->trans); | 2570 c->result = cache.CreateTransaction(&c->trans); |
| 2393 ASSERT_THAT(c->result, IsOk()); | 2571 ASSERT_THAT(c->result, IsOk()); |
| 2394 | 2572 |
| 2395 MockHttpRequest* this_request = &request; | 2573 MockHttpRequest* this_request = &request; |
| 2396 if (i == 2) { | 2574 if (i == 2) { |
| 2397 this_request = &validate_request; | 2575 this_request = &validate_request; |
| 2398 c->trans->SetBeforeNetworkStartCallback(base::Bind(&DeferNetworkStart)); | 2576 c->trans->SetBeforeNetworkStartCallback(base::Bind(&DeferCallback)); |
| 2399 } | 2577 } |
| 2400 | 2578 |
| 2401 c->result = c->trans->Start(this_request, c->callback.callback(), | 2579 c->result = c->trans->Start(this_request, c->callback.callback(), |
| 2402 NetLogWithSource()); | 2580 NetLogWithSource()); |
| 2403 } | 2581 } |
| 2404 | 2582 |
| 2405 // Allow all requests to move from the Create queue to the active entry. | 2583 // Allow all requests to move from the Create queue to the active entry. |
| 2406 base::RunLoop().RunUntilIdle(); | 2584 base::RunLoop().RunUntilIdle(); |
| 2407 | 2585 |
| 2408 EXPECT_EQ(2, cache.network_layer()->transaction_count()); | 2586 EXPECT_EQ(2, cache.network_layer()->transaction_count()); |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2454 std::vector<std::unique_ptr<Context>> context_list; | 2632 std::vector<std::unique_ptr<Context>> context_list; |
| 2455 | 2633 |
| 2456 for (int i = 0; i < kNumTransactions; ++i) { | 2634 for (int i = 0; i < kNumTransactions; ++i) { |
| 2457 context_list.push_back(base::MakeUnique<Context>()); | 2635 context_list.push_back(base::MakeUnique<Context>()); |
| 2458 auto& c = context_list[i]; | 2636 auto& c = context_list[i]; |
| 2459 | 2637 |
| 2460 c->result = cache.CreateTransaction(&c->trans); | 2638 c->result = cache.CreateTransaction(&c->trans); |
| 2461 ASSERT_THAT(c->result, IsOk()); | 2639 ASSERT_THAT(c->result, IsOk()); |
| 2462 | 2640 |
| 2463 if (i == 0) | 2641 if (i == 0) |
| 2464 c->trans->SetBeforeNetworkStartCallback(base::Bind(&DeferNetworkStart)); | 2642 c->trans->SetBeforeNetworkStartCallback(base::Bind(&DeferCallback)); |
| 2465 | 2643 |
| 2466 c->result = | 2644 c->result = |
| 2467 c->trans->Start(&request, c->callback.callback(), NetLogWithSource()); | 2645 c->trans->Start(&request, c->callback.callback(), NetLogWithSource()); |
| 2468 } | 2646 } |
| 2469 | 2647 |
| 2470 base::RunLoop().RunUntilIdle(); | 2648 base::RunLoop().RunUntilIdle(); |
| 2471 | 2649 |
| 2472 EXPECT_TRUE(cache.IsHeadersTransactionPresent(kSimpleGET_Transaction.url)); | 2650 EXPECT_TRUE(cache.IsHeadersTransactionPresent(kSimpleGET_Transaction.url)); |
| 2473 EXPECT_EQ(1, cache.GetCountAddToEntryQueue(kSimpleGET_Transaction.url)); | 2651 EXPECT_EQ(1, cache.GetCountAddToEntryQueue(kSimpleGET_Transaction.url)); |
| 2474 | 2652 |
| (...skipping 6884 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 9359 ASSERT_TRUE(attrs->GetDictionary( | 9537 ASSERT_TRUE(attrs->GetDictionary( |
| 9360 base::trace_event::MemoryAllocatorDump::kNameSize, &size_attrs)); | 9538 base::trace_event::MemoryAllocatorDump::kNameSize, &size_attrs)); |
| 9361 std::string size; | 9539 std::string size; |
| 9362 ASSERT_TRUE(size_attrs->GetString("value", &size)); | 9540 ASSERT_TRUE(size_attrs->GetString("value", &size)); |
| 9363 int actual_size = 0; | 9541 int actual_size = 0; |
| 9364 ASSERT_TRUE(base::HexStringToInt(size, &actual_size)); | 9542 ASSERT_TRUE(base::HexStringToInt(size, &actual_size)); |
| 9365 ASSERT_LT(0, actual_size); | 9543 ASSERT_LT(0, actual_size); |
| 9366 } | 9544 } |
| 9367 | 9545 |
| 9368 } // namespace net | 9546 } // namespace net |
| OLD | NEW |