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 |