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 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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 |
OLD | NEW |