| 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) { |
| 151 *defer = true; |
| 152 } |
| 153 |
| 150 class DeleteCacheCompletionCallback : public TestCompletionCallbackBase { | 154 class DeleteCacheCompletionCallback : public TestCompletionCallbackBase { |
| 151 public: | 155 public: |
| 152 explicit DeleteCacheCompletionCallback(MockHttpCache* cache) | 156 explicit DeleteCacheCompletionCallback(MockHttpCache* cache) |
| 153 : cache_(cache), | 157 : cache_(cache), |
| 154 callback_(base::Bind(&DeleteCacheCompletionCallback::OnComplete, | 158 callback_(base::Bind(&DeleteCacheCompletionCallback::OnComplete, |
| 155 base::Unretained(this))) { | 159 base::Unretained(this))) { |
| 156 } | 160 } |
| 157 | 161 |
| 158 const CompletionCallback& callback() const { return callback_; } | 162 const CompletionCallback& callback() const { return callback_; } |
| 159 | 163 |
| (...skipping 15 matching lines...) Expand all Loading... |
| 175 void ReadAndVerifyTransaction(HttpTransaction* trans, | 179 void ReadAndVerifyTransaction(HttpTransaction* trans, |
| 176 const MockTransaction& trans_info) { | 180 const MockTransaction& trans_info) { |
| 177 std::string content; | 181 std::string content; |
| 178 int rv = ReadTransaction(trans, &content); | 182 int rv = ReadTransaction(trans, &content); |
| 179 | 183 |
| 180 EXPECT_THAT(rv, IsOk()); | 184 EXPECT_THAT(rv, IsOk()); |
| 181 std::string expected(trans_info.data); | 185 std::string expected(trans_info.data); |
| 182 EXPECT_EQ(expected, content); | 186 EXPECT_EQ(expected, content); |
| 183 } | 187 } |
| 184 | 188 |
| 189 void ReadRemainingAndVerifyTransaction(HttpTransaction* trans, |
| 190 std::string& already_read, |
| 191 const MockTransaction& trans_info) { |
| 192 std::string content; |
| 193 int rv = ReadTransaction(trans, &content); |
| 194 EXPECT_THAT(rv, IsOk()); |
| 195 |
| 196 std::string expected(trans_info.data); |
| 197 EXPECT_EQ(expected, already_read + content); |
| 198 } |
| 199 |
| 185 void RunTransactionTestBase(HttpCache* cache, | 200 void RunTransactionTestBase(HttpCache* cache, |
| 186 const MockTransaction& trans_info, | 201 const MockTransaction& trans_info, |
| 187 const MockHttpRequest& request, | 202 const MockHttpRequest& request, |
| 188 HttpResponseInfo* response_info, | 203 HttpResponseInfo* response_info, |
| 189 const NetLogWithSource& net_log, | 204 const NetLogWithSource& net_log, |
| 190 LoadTimingInfo* load_timing_info, | 205 LoadTimingInfo* load_timing_info, |
| 191 int64_t* sent_bytes, | 206 int64_t* sent_bytes, |
| 192 int64_t* received_bytes, | 207 int64_t* received_bytes, |
| 193 IPEndPoint* remote_endpoint) { | 208 IPEndPoint* remote_endpoint) { |
| 194 TestCompletionCallback callback; | 209 TestCompletionCallback callback; |
| (...skipping 1148 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1343 EXPECT_EQ(1, cache.disk_cache()->open_count()); | 1358 EXPECT_EQ(1, cache.disk_cache()->open_count()); |
| 1344 EXPECT_EQ(1, cache.disk_cache()->create_count()); | 1359 EXPECT_EQ(1, cache.disk_cache()->create_count()); |
| 1345 RemoveMockTransaction(&transaction); | 1360 RemoveMockTransaction(&transaction); |
| 1346 } | 1361 } |
| 1347 | 1362 |
| 1348 TEST(HttpCache, SimpleGET_ManyReaders) { | 1363 TEST(HttpCache, SimpleGET_ManyReaders) { |
| 1349 MockHttpCache cache; | 1364 MockHttpCache cache; |
| 1350 | 1365 |
| 1351 MockHttpRequest request(kSimpleGET_Transaction); | 1366 MockHttpRequest request(kSimpleGET_Transaction); |
| 1352 | 1367 |
| 1353 std::vector<Context*> context_list; | 1368 std::vector<std::unique_ptr<Context>> context_list; |
| 1354 const int kNumTransactions = 5; | 1369 const int kNumTransactions = 5; |
| 1355 | 1370 |
| 1356 for (int i = 0; i < kNumTransactions; ++i) { | 1371 for (int i = 0; i < kNumTransactions; ++i) { |
| 1357 context_list.push_back(new Context()); | 1372 context_list.push_back(base::MakeUnique<Context>()); |
| 1358 Context* c = context_list[i]; | 1373 auto& c = context_list[i]; |
| 1359 | 1374 |
| 1360 c->result = cache.CreateTransaction(&c->trans); | 1375 c->result = cache.CreateTransaction(&c->trans); |
| 1361 ASSERT_THAT(c->result, IsOk()); | 1376 ASSERT_THAT(c->result, IsOk()); |
| 1362 EXPECT_EQ(LOAD_STATE_IDLE, c->trans->GetLoadState()); | 1377 EXPECT_EQ(LOAD_STATE_IDLE, c->trans->GetLoadState()); |
| 1363 | 1378 |
| 1364 c->result = | 1379 c->result = |
| 1365 c->trans->Start(&request, c->callback.callback(), NetLogWithSource()); | 1380 c->trans->Start(&request, c->callback.callback(), NetLogWithSource()); |
| 1366 } | 1381 } |
| 1367 | 1382 |
| 1368 // All requests are waiting for the active entry. | 1383 // All requests are waiting for the active entry. |
| 1369 for (int i = 0; i < kNumTransactions; ++i) { | 1384 for (auto& context : context_list) { |
| 1370 Context* c = context_list[i]; | 1385 EXPECT_EQ(LOAD_STATE_WAITING_FOR_CACHE, context->trans->GetLoadState()); |
| 1371 EXPECT_EQ(LOAD_STATE_WAITING_FOR_CACHE, c->trans->GetLoadState()); | |
| 1372 } | 1386 } |
| 1373 | 1387 |
| 1374 // Allow all requests to move from the Create queue to the active entry. | 1388 // Allow all requests to move from the Create queue to the active entry. |
| 1375 base::RunLoop().RunUntilIdle(); | 1389 base::RunLoop().RunUntilIdle(); |
| 1376 | 1390 |
| 1377 // The first request should be a writer at this point, and the subsequent | 1391 // The first request should be a writer at this point, and the subsequent |
| 1378 // requests should be pending. | 1392 // requests should have passed the validation phase and waiting for the |
| 1393 // response to be written to the cache before they can read. |
| 1394 EXPECT_TRUE(cache.IsWriterPresent(kSimpleGET_Transaction.url)); |
| 1395 EXPECT_EQ(kNumTransactions - 1, |
| 1396 cache.GetCountDoneHeadersQueue(kSimpleGET_Transaction.url)); |
| 1379 | 1397 |
| 1380 EXPECT_EQ(1, cache.network_layer()->transaction_count()); | 1398 EXPECT_EQ(1, cache.network_layer()->transaction_count()); |
| 1381 EXPECT_EQ(0, cache.disk_cache()->open_count()); | 1399 EXPECT_EQ(0, cache.disk_cache()->open_count()); |
| 1382 EXPECT_EQ(1, cache.disk_cache()->create_count()); | 1400 EXPECT_EQ(1, cache.disk_cache()->create_count()); |
| 1383 | 1401 |
| 1384 // All requests depend on the writer, and the writer is between Start and | 1402 // All requests depend on the writer, and the writer is between Start and |
| 1385 // Read, i.e. idle. | 1403 // Read, i.e. idle. |
| 1386 for (int i = 0; i < kNumTransactions; ++i) { | 1404 for (auto& context : context_list) { |
| 1387 Context* c = context_list[i]; | 1405 EXPECT_EQ(LOAD_STATE_IDLE, context->trans->GetLoadState()); |
| 1388 EXPECT_EQ(LOAD_STATE_IDLE, c->trans->GetLoadState()); | 1406 } |
| 1389 } | 1407 |
| 1390 | 1408 for (int i = 0; i < kNumTransactions; ++i) { |
| 1391 for (int i = 0; i < kNumTransactions; ++i) { | 1409 auto& c = context_list[i]; |
| 1392 Context* c = context_list[i]; | |
| 1393 if (c->result == ERR_IO_PENDING) | 1410 if (c->result == ERR_IO_PENDING) |
| 1394 c->result = c->callback.WaitForResult(); | 1411 c->result = c->callback.WaitForResult(); |
| 1412 |
| 1413 if (i > 0) { |
| 1414 EXPECT_FALSE(cache.IsWriterPresent(kSimpleGET_Transaction.url)); |
| 1415 EXPECT_EQ(kNumTransactions - i, |
| 1416 cache.GetCountReaders(kSimpleGET_Transaction.url)); |
| 1417 } |
| 1418 |
| 1395 ReadAndVerifyTransaction(c->trans.get(), kSimpleGET_Transaction); | 1419 ReadAndVerifyTransaction(c->trans.get(), kSimpleGET_Transaction); |
| 1396 } | 1420 } |
| 1397 | 1421 |
| 1398 // We should not have had to re-open the disk entry | 1422 // We should not have had to re-open the disk entry |
| 1399 | 1423 |
| 1400 EXPECT_EQ(1, cache.network_layer()->transaction_count()); | 1424 EXPECT_EQ(1, cache.network_layer()->transaction_count()); |
| 1401 EXPECT_EQ(0, cache.disk_cache()->open_count()); | 1425 EXPECT_EQ(0, cache.disk_cache()->open_count()); |
| 1402 EXPECT_EQ(1, cache.disk_cache()->create_count()); | 1426 EXPECT_EQ(1, cache.disk_cache()->create_count()); |
| 1403 | 1427 } |
| 1404 for (int i = 0; i < kNumTransactions; ++i) { | 1428 |
| 1405 Context* c = context_list[i]; | 1429 // Tests that we can have parallel validation on range requests. |
| 1406 delete c; | 1430 TEST(HttpCache, RangeGET_ParallelValidationNoMatch) { |
| 1407 } | 1431 MockHttpCache cache; |
| 1432 |
| 1433 ScopedMockTransaction transaction(kRangeGET_TransactionOK); |
| 1434 MockHttpRequest request(transaction); |
| 1435 |
| 1436 std::vector<std::unique_ptr<Context>> context_list; |
| 1437 const int kNumTransactions = 5; |
| 1438 |
| 1439 for (int i = 0; i < kNumTransactions; ++i) { |
| 1440 context_list.push_back(base::MakeUnique<Context>()); |
| 1441 auto& c = context_list[i]; |
| 1442 |
| 1443 c->result = cache.CreateTransaction(&c->trans); |
| 1444 ASSERT_THAT(c->result, IsOk()); |
| 1445 EXPECT_EQ(LOAD_STATE_IDLE, c->trans->GetLoadState()); |
| 1446 |
| 1447 c->result = |
| 1448 c->trans->Start(&request, c->callback.callback(), NetLogWithSource()); |
| 1449 } |
| 1450 |
| 1451 // All requests are waiting for the active entry. |
| 1452 for (auto& context : context_list) { |
| 1453 EXPECT_EQ(LOAD_STATE_WAITING_FOR_CACHE, context->trans->GetLoadState()); |
| 1454 } |
| 1455 |
| 1456 // Allow all requests to move from the Create queue to the active entry. |
| 1457 base::RunLoop().RunUntilIdle(); |
| 1458 |
| 1459 // The first entry should have been doomed. Since the 1st transaction has not |
| 1460 // started writing to the cache, MockDiskEntry::CouldBeSparse() returns false |
| 1461 // leading to restarting the dooming the entry and restarting the second |
| 1462 // transaction. |
| 1463 EXPECT_TRUE(cache.IsWriterPresent(kRangeGET_TransactionOK.url)); |
| 1464 EXPECT_EQ(0, cache.GetCountDoneHeadersQueue(kRangeGET_TransactionOK.url)); |
| 1465 |
| 1466 EXPECT_EQ(5, cache.network_layer()->transaction_count()); |
| 1467 EXPECT_EQ(0, cache.disk_cache()->open_count()); |
| 1468 EXPECT_EQ(5, cache.disk_cache()->create_count()); |
| 1469 |
| 1470 for (auto& context : context_list) { |
| 1471 EXPECT_EQ(LOAD_STATE_IDLE, context->trans->GetLoadState()); |
| 1472 } |
| 1473 |
| 1474 for (int i = 0; i < kNumTransactions; ++i) { |
| 1475 auto& c = context_list[i]; |
| 1476 if (c->result == ERR_IO_PENDING) |
| 1477 c->result = c->callback.WaitForResult(); |
| 1478 |
| 1479 ReadAndVerifyTransaction(c->trans.get(), kRangeGET_TransactionOK); |
| 1480 } |
| 1481 |
| 1482 EXPECT_EQ(5, cache.network_layer()->transaction_count()); |
| 1483 EXPECT_EQ(0, cache.disk_cache()->open_count()); |
| 1484 EXPECT_EQ(5, cache.disk_cache()->create_count()); |
| 1485 } |
| 1486 |
| 1487 // Tests parallel validation on range requests with non-overlapping ranges. |
| 1488 TEST(HttpCache, RangeGET_ParallelValidationDifferentRanges) { |
| 1489 MockHttpCache cache; |
| 1490 |
| 1491 ScopedMockTransaction transaction(kRangeGET_TransactionOK); |
| 1492 |
| 1493 std::vector<std::unique_ptr<Context>> context_list; |
| 1494 const int kNumTransactions = 2; |
| 1495 |
| 1496 for (int i = 0; i < kNumTransactions; ++i) { |
| 1497 context_list.push_back(base::MakeUnique<Context>()); |
| 1498 } |
| 1499 |
| 1500 // Let 1st transaction complete headers phase for ranges 40-49. |
| 1501 std::string first_read; |
| 1502 { |
| 1503 MockHttpRequest request(transaction); |
| 1504 auto& c = context_list[0]; |
| 1505 c->result = cache.CreateTransaction(&c->trans); |
| 1506 ASSERT_THAT(c->result, IsOk()); |
| 1507 EXPECT_EQ(LOAD_STATE_IDLE, c->trans->GetLoadState()); |
| 1508 |
| 1509 c->result = |
| 1510 c->trans->Start(&request, c->callback.callback(), NetLogWithSource()); |
| 1511 base::RunLoop().RunUntilIdle(); |
| 1512 |
| 1513 // Start writing to the cache so that MockDiskEntry::CouldBeSparse() returns |
| 1514 // true. |
| 1515 const int kBufferSize = 5; |
| 1516 scoped_refptr<IOBuffer> buffer(new IOBuffer(kBufferSize)); |
| 1517 ReleaseBufferCompletionCallback cb(buffer.get()); |
| 1518 c->result = c->trans->Read(buffer.get(), kBufferSize, cb.callback()); |
| 1519 EXPECT_EQ(kBufferSize, cb.GetResult(c->result)); |
| 1520 |
| 1521 std::string data_read(buffer->data(), kBufferSize); |
| 1522 first_read = data_read; |
| 1523 |
| 1524 EXPECT_EQ(LOAD_STATE_READING_RESPONSE, c->trans->GetLoadState()); |
| 1525 } |
| 1526 |
| 1527 // 2nd transaction requests ranges 30-39. |
| 1528 { |
| 1529 transaction.request_headers = "Range: bytes = 30-39\r\n" EXTRA_HEADER; |
| 1530 MockHttpRequest request(transaction); |
| 1531 auto& c = context_list[1]; |
| 1532 c->result = cache.CreateTransaction(&c->trans); |
| 1533 ASSERT_THAT(c->result, IsOk()); |
| 1534 EXPECT_EQ(LOAD_STATE_IDLE, c->trans->GetLoadState()); |
| 1535 |
| 1536 c->result = |
| 1537 c->trans->Start(&request, c->callback.callback(), NetLogWithSource()); |
| 1538 base::RunLoop().RunUntilIdle(); |
| 1539 |
| 1540 EXPECT_EQ(LOAD_STATE_IDLE, c->trans->GetLoadState()); |
| 1541 } |
| 1542 |
| 1543 EXPECT_TRUE(cache.IsWriterPresent(kRangeGET_TransactionOK.url)); |
| 1544 EXPECT_EQ(1, cache.GetCountDoneHeadersQueue(kRangeGET_TransactionOK.url)); |
| 1545 |
| 1546 EXPECT_EQ(2, cache.network_layer()->transaction_count()); |
| 1547 EXPECT_EQ(0, cache.disk_cache()->open_count()); |
| 1548 EXPECT_EQ(1, cache.disk_cache()->create_count()); |
| 1549 |
| 1550 for (int i = 0; i < kNumTransactions; ++i) { |
| 1551 auto& c = context_list[i]; |
| 1552 if (c->result == ERR_IO_PENDING) |
| 1553 c->result = c->callback.WaitForResult(); |
| 1554 |
| 1555 if (i == 0) { |
| 1556 ReadRemainingAndVerifyTransaction(c->trans.get(), first_read, |
| 1557 transaction); |
| 1558 continue; |
| 1559 } |
| 1560 |
| 1561 transaction.data = "rg: 30-39 "; |
| 1562 ReadAndVerifyTransaction(c->trans.get(), transaction); |
| 1563 } |
| 1564 |
| 1565 EXPECT_EQ(2, cache.network_layer()->transaction_count()); |
| 1566 EXPECT_EQ(0, cache.disk_cache()->open_count()); |
| 1567 EXPECT_EQ(1, cache.disk_cache()->create_count()); |
| 1568 |
| 1569 // Fetch from the cache to check that ranges 30-49 have been successfully |
| 1570 // cached. |
| 1571 { |
| 1572 MockTransaction transaction(kRangeGET_TransactionOK); |
| 1573 transaction.request_headers = "Range: bytes = 30-49\r\n" EXTRA_HEADER; |
| 1574 transaction.data = "rg: 30-39 rg: 40-49 "; |
| 1575 std::string headers; |
| 1576 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers); |
| 1577 Verify206Response(headers, 30, 49); |
| 1578 } |
| 1579 |
| 1580 EXPECT_EQ(2, cache.network_layer()->transaction_count()); |
| 1581 EXPECT_EQ(1, cache.disk_cache()->open_count()); |
| 1582 EXPECT_EQ(1, cache.disk_cache()->create_count()); |
| 1583 } |
| 1584 |
| 1585 // Tests parallel validation on range requests with overlapping ranges. |
| 1586 TEST(HttpCache, RangeGET_ParallelValidationOverlappingRanges) { |
| 1587 MockHttpCache cache; |
| 1588 |
| 1589 ScopedMockTransaction transaction(kRangeGET_TransactionOK); |
| 1590 |
| 1591 std::vector<std::unique_ptr<Context>> context_list; |
| 1592 const int kNumTransactions = 2; |
| 1593 |
| 1594 for (int i = 0; i < kNumTransactions; ++i) { |
| 1595 context_list.push_back(base::MakeUnique<Context>()); |
| 1596 } |
| 1597 |
| 1598 // Let 1st transaction complete headers phase for ranges 40-49. |
| 1599 std::string first_read; |
| 1600 { |
| 1601 MockHttpRequest request(transaction); |
| 1602 auto& c = context_list[0]; |
| 1603 c->result = cache.CreateTransaction(&c->trans); |
| 1604 ASSERT_THAT(c->result, IsOk()); |
| 1605 EXPECT_EQ(LOAD_STATE_IDLE, c->trans->GetLoadState()); |
| 1606 |
| 1607 c->result = |
| 1608 c->trans->Start(&request, c->callback.callback(), NetLogWithSource()); |
| 1609 base::RunLoop().RunUntilIdle(); |
| 1610 |
| 1611 // Start writing to the cache so that MockDiskEntry::CouldBeSparse() returns |
| 1612 // true. |
| 1613 const int kBufferSize = 5; |
| 1614 scoped_refptr<IOBuffer> buffer(new IOBuffer(kBufferSize)); |
| 1615 ReleaseBufferCompletionCallback cb(buffer.get()); |
| 1616 c->result = c->trans->Read(buffer.get(), kBufferSize, cb.callback()); |
| 1617 EXPECT_EQ(kBufferSize, cb.GetResult(c->result)); |
| 1618 |
| 1619 std::string data_read(buffer->data(), kBufferSize); |
| 1620 first_read = data_read; |
| 1621 |
| 1622 EXPECT_EQ(LOAD_STATE_READING_RESPONSE, c->trans->GetLoadState()); |
| 1623 } |
| 1624 |
| 1625 // 2nd transaction requests ranges 30-49. |
| 1626 { |
| 1627 transaction.request_headers = "Range: bytes = 30-49\r\n" EXTRA_HEADER; |
| 1628 MockHttpRequest request(transaction); |
| 1629 auto& c = context_list[1]; |
| 1630 c->result = cache.CreateTransaction(&c->trans); |
| 1631 ASSERT_THAT(c->result, IsOk()); |
| 1632 EXPECT_EQ(LOAD_STATE_IDLE, c->trans->GetLoadState()); |
| 1633 |
| 1634 c->result = |
| 1635 c->trans->Start(&request, c->callback.callback(), NetLogWithSource()); |
| 1636 base::RunLoop().RunUntilIdle(); |
| 1637 |
| 1638 EXPECT_EQ(LOAD_STATE_IDLE, c->trans->GetLoadState()); |
| 1639 } |
| 1640 |
| 1641 EXPECT_TRUE(cache.IsWriterPresent(kRangeGET_TransactionOK.url)); |
| 1642 EXPECT_EQ(1, cache.GetCountDoneHeadersQueue(kRangeGET_TransactionOK.url)); |
| 1643 |
| 1644 // Should have created another transaction for the uncached range. |
| 1645 EXPECT_EQ(2, cache.network_layer()->transaction_count()); |
| 1646 EXPECT_EQ(0, cache.disk_cache()->open_count()); |
| 1647 EXPECT_EQ(1, cache.disk_cache()->create_count()); |
| 1648 |
| 1649 for (int i = 0; i < kNumTransactions; ++i) { |
| 1650 auto& c = context_list[i]; |
| 1651 if (c->result == ERR_IO_PENDING) |
| 1652 c->result = c->callback.WaitForResult(); |
| 1653 |
| 1654 if (i == 0) { |
| 1655 ReadRemainingAndVerifyTransaction(c->trans.get(), first_read, |
| 1656 transaction); |
| 1657 continue; |
| 1658 } |
| 1659 |
| 1660 transaction.data = "rg: 30-39 rg: 40-49 "; |
| 1661 ReadAndVerifyTransaction(c->trans.get(), transaction); |
| 1662 } |
| 1663 |
| 1664 EXPECT_EQ(2, cache.network_layer()->transaction_count()); |
| 1665 EXPECT_EQ(0, cache.disk_cache()->open_count()); |
| 1666 EXPECT_EQ(1, cache.disk_cache()->create_count()); |
| 1667 |
| 1668 // Fetch from the cache to check that ranges 30-49 have been successfully |
| 1669 // cached. |
| 1670 { |
| 1671 MockTransaction transaction(kRangeGET_TransactionOK); |
| 1672 transaction.request_headers = "Range: bytes = 30-49\r\n" EXTRA_HEADER; |
| 1673 transaction.data = "rg: 30-39 rg: 40-49 "; |
| 1674 std::string headers; |
| 1675 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers); |
| 1676 Verify206Response(headers, 30, 49); |
| 1677 } |
| 1678 |
| 1679 EXPECT_EQ(2, cache.network_layer()->transaction_count()); |
| 1680 EXPECT_EQ(0, cache.disk_cache()->open_count()); |
| 1681 EXPECT_EQ(1, cache.disk_cache()->create_count()); |
| 1682 } |
| 1683 |
| 1684 // Tests that a GET followed by a DELETE results in DELETE immediately starting |
| 1685 // the headers phase and the entry is doomed. |
| 1686 TEST(HttpCache, SimpleGET_ParallelValidationDelete) { |
| 1687 MockHttpCache cache; |
| 1688 |
| 1689 MockHttpRequest request(kSimpleGET_Transaction); |
| 1690 request.load_flags |= LOAD_VALIDATE_CACHE; |
| 1691 |
| 1692 MockHttpRequest delete_request(kSimpleGET_Transaction); |
| 1693 delete_request.method = "DELETE"; |
| 1694 |
| 1695 std::vector<std::unique_ptr<Context>> context_list; |
| 1696 const int kNumTransactions = 2; |
| 1697 |
| 1698 for (int i = 0; i < kNumTransactions; ++i) { |
| 1699 context_list.push_back(base::MakeUnique<Context>()); |
| 1700 auto& c = context_list[i]; |
| 1701 |
| 1702 MockHttpRequest* this_request = &request; |
| 1703 if (i == 1) |
| 1704 this_request = &delete_request; |
| 1705 |
| 1706 c->result = cache.CreateTransaction(&c->trans); |
| 1707 ASSERT_THAT(c->result, IsOk()); |
| 1708 EXPECT_EQ(LOAD_STATE_IDLE, c->trans->GetLoadState()); |
| 1709 |
| 1710 c->result = c->trans->Start(this_request, c->callback.callback(), |
| 1711 NetLogWithSource()); |
| 1712 } |
| 1713 |
| 1714 // All requests are waiting for the active entry. |
| 1715 for (auto& context : context_list) { |
| 1716 EXPECT_EQ(LOAD_STATE_WAITING_FOR_CACHE, context->trans->GetLoadState()); |
| 1717 } |
| 1718 |
| 1719 // Allow all requests to move from the Create queue to the active entry. |
| 1720 base::RunLoop().RunUntilIdle(); |
| 1721 |
| 1722 // The first request should be a writer at this point, and the subsequent |
| 1723 // request should have passed the validation phase and doomed the existing |
| 1724 // entry. |
| 1725 EXPECT_TRUE( |
| 1726 cache.disk_cache()->IsDiskEntryDoomed(kSimpleGET_Transaction.url)); |
| 1727 |
| 1728 EXPECT_EQ(2, cache.network_layer()->transaction_count()); |
| 1729 EXPECT_EQ(0, cache.disk_cache()->open_count()); |
| 1730 EXPECT_EQ(1, cache.disk_cache()->create_count()); |
| 1731 |
| 1732 // All requests depend on the writer, and the writer is between Start and |
| 1733 // Read, i.e. idle. |
| 1734 for (auto& context : context_list) { |
| 1735 EXPECT_EQ(LOAD_STATE_IDLE, context->trans->GetLoadState()); |
| 1736 } |
| 1737 |
| 1738 for (auto& context : context_list) { |
| 1739 if (context->result == ERR_IO_PENDING) |
| 1740 context->result = context->callback.WaitForResult(); |
| 1741 ReadAndVerifyTransaction(context->trans.get(), kSimpleGET_Transaction); |
| 1742 } |
| 1743 |
| 1744 EXPECT_EQ(2, cache.network_layer()->transaction_count()); |
| 1745 EXPECT_EQ(0, cache.disk_cache()->open_count()); |
| 1746 EXPECT_EQ(1, cache.disk_cache()->create_count()); |
| 1747 } |
| 1748 |
| 1749 // Tests that a transaction which is in validated queue can be destroyed without |
| 1750 // any impact to other transactions. |
| 1751 TEST(HttpCache, SimpleGET_ParallelValidationCancelValidated) { |
| 1752 MockHttpCache cache; |
| 1753 |
| 1754 MockHttpRequest request(kSimpleGET_Transaction); |
| 1755 |
| 1756 std::vector<std::unique_ptr<Context>> context_list; |
| 1757 const int kNumTransactions = 2; |
| 1758 |
| 1759 for (int i = 0; i < kNumTransactions; ++i) { |
| 1760 context_list.push_back(base::MakeUnique<Context>()); |
| 1761 auto& c = context_list[i]; |
| 1762 |
| 1763 c->result = cache.CreateTransaction(&c->trans); |
| 1764 ASSERT_THAT(c->result, IsOk()); |
| 1765 |
| 1766 c->result = |
| 1767 c->trans->Start(&request, c->callback.callback(), NetLogWithSource()); |
| 1768 } |
| 1769 |
| 1770 // Allow all requests to move from the Create queue to the active entry. |
| 1771 base::RunLoop().RunUntilIdle(); |
| 1772 |
| 1773 // The first request should be a writer at this point, and the subsequent |
| 1774 // requests should have completed validation. |
| 1775 |
| 1776 EXPECT_EQ(1, cache.network_layer()->transaction_count()); |
| 1777 EXPECT_EQ(0, cache.disk_cache()->open_count()); |
| 1778 EXPECT_EQ(1, cache.disk_cache()->create_count()); |
| 1779 |
| 1780 EXPECT_TRUE(cache.IsWriterPresent(kSimpleGET_Transaction.url)); |
| 1781 EXPECT_EQ(1, cache.GetCountDoneHeadersQueue(kSimpleGET_Transaction.url)); |
| 1782 |
| 1783 context_list[1].reset(); |
| 1784 |
| 1785 EXPECT_EQ(0, cache.GetCountDoneHeadersQueue(kSimpleGET_Transaction.url)); |
| 1786 |
| 1787 // Complete the rest of the transactions. |
| 1788 for (auto& context : context_list) { |
| 1789 if (!context) |
| 1790 continue; |
| 1791 ReadAndVerifyTransaction(context->trans.get(), kSimpleGET_Transaction); |
| 1792 } |
| 1793 |
| 1794 EXPECT_EQ(1, cache.network_layer()->transaction_count()); |
| 1795 EXPECT_EQ(0, cache.disk_cache()->open_count()); |
| 1796 EXPECT_EQ(1, cache.disk_cache()->create_count()); |
| 1797 } |
| 1798 |
| 1799 // Tests that a transaction which is in readers can be destroyed without |
| 1800 // any impact to other transactions. |
| 1801 TEST(HttpCache, SimpleGET_ParallelValidationCancelReader) { |
| 1802 MockHttpCache cache; |
| 1803 |
| 1804 MockHttpRequest request(kSimpleGET_Transaction); |
| 1805 |
| 1806 MockTransaction transaction(kSimpleGET_Transaction); |
| 1807 transaction.load_flags |= LOAD_VALIDATE_CACHE; |
| 1808 MockHttpRequest validate_request(transaction); |
| 1809 |
| 1810 int kNumTransactions = 4; |
| 1811 std::vector<std::unique_ptr<Context>> context_list; |
| 1812 |
| 1813 for (int i = 0; i < kNumTransactions; ++i) { |
| 1814 context_list.push_back(base::MakeUnique<Context>()); |
| 1815 auto& c = context_list[i]; |
| 1816 |
| 1817 c->result = cache.CreateTransaction(&c->trans); |
| 1818 ASSERT_THAT(c->result, IsOk()); |
| 1819 |
| 1820 MockHttpRequest* this_request = &request; |
| 1821 if (i == 3) { |
| 1822 this_request = &validate_request; |
| 1823 c->trans->SetBeforeNetworkStartCallback(base::Bind(&DeferNetworkStart)); |
| 1824 } |
| 1825 |
| 1826 c->result = c->trans->Start(this_request, c->callback.callback(), |
| 1827 NetLogWithSource()); |
| 1828 } |
| 1829 |
| 1830 // Allow all requests to move from the Create queue to the active entry. |
| 1831 base::RunLoop().RunUntilIdle(); |
| 1832 |
| 1833 EXPECT_EQ(2, cache.network_layer()->transaction_count()); |
| 1834 EXPECT_EQ(0, cache.disk_cache()->open_count()); |
| 1835 EXPECT_EQ(1, cache.disk_cache()->create_count()); |
| 1836 |
| 1837 EXPECT_TRUE(cache.IsWriterPresent(kSimpleGET_Transaction.url)); |
| 1838 EXPECT_EQ(2, cache.GetCountDoneHeadersQueue(kSimpleGET_Transaction.url)); |
| 1839 EXPECT_TRUE(cache.IsHeadersTransactionPresent(kSimpleGET_Transaction.url)); |
| 1840 |
| 1841 // Complete the response body. |
| 1842 auto& c = context_list[0]; |
| 1843 ReadAndVerifyTransaction(c->trans.get(), kSimpleGET_Transaction); |
| 1844 |
| 1845 // Rest of the transactions should move to readers. |
| 1846 EXPECT_FALSE(cache.IsWriterPresent(kSimpleGET_Transaction.url)); |
| 1847 EXPECT_EQ(2, cache.GetCountReaders(kSimpleGET_Transaction.url)); |
| 1848 EXPECT_EQ(0, cache.GetCountDoneHeadersQueue(kSimpleGET_Transaction.url)); |
| 1849 EXPECT_TRUE(cache.IsHeadersTransactionPresent(kSimpleGET_Transaction.url)); |
| 1850 |
| 1851 // Add 2 new transactions. |
| 1852 kNumTransactions = 6; |
| 1853 |
| 1854 for (int i = 4; i < kNumTransactions; ++i) { |
| 1855 context_list.push_back(base::MakeUnique<Context>()); |
| 1856 auto& c = context_list[i]; |
| 1857 |
| 1858 c->result = cache.CreateTransaction(&c->trans); |
| 1859 ASSERT_THAT(c->result, IsOk()); |
| 1860 |
| 1861 c->result = |
| 1862 c->trans->Start(&request, c->callback.callback(), NetLogWithSource()); |
| 1863 } |
| 1864 |
| 1865 EXPECT_EQ(2, cache.GetCountAddToEntryQueue(kSimpleGET_Transaction.url)); |
| 1866 |
| 1867 // Delete a reader. |
| 1868 context_list[1].reset(); |
| 1869 |
| 1870 // Deleting the reader did not impact any other transaction. |
| 1871 EXPECT_EQ(1, cache.GetCountReaders(kSimpleGET_Transaction.url)); |
| 1872 EXPECT_EQ(2, cache.GetCountAddToEntryQueue(kSimpleGET_Transaction.url)); |
| 1873 EXPECT_TRUE(cache.IsHeadersTransactionPresent(kSimpleGET_Transaction.url)); |
| 1874 |
| 1875 // Resume network start for headers_transaction. It will doom the entry as it |
| 1876 // will be a 200 and will go to network for the response body. |
| 1877 auto& context = context_list[3]; |
| 1878 context->trans->ResumeNetworkStart(); |
| 1879 |
| 1880 // The pending transactions will be added to a new entry. |
| 1881 base::RunLoop().RunUntilIdle(); |
| 1882 |
| 1883 EXPECT_EQ(1, cache.GetCountDoneHeadersQueue(kSimpleGET_Transaction.url)); |
| 1884 EXPECT_TRUE(cache.IsWriterPresent(kSimpleGET_Transaction.url)); |
| 1885 |
| 1886 // Complete the rest of the transactions. |
| 1887 for (int i = 2; i < kNumTransactions; ++i) { |
| 1888 auto& c = context_list[i]; |
| 1889 ReadAndVerifyTransaction(c->trans.get(), kSimpleGET_Transaction); |
| 1890 } |
| 1891 |
| 1892 EXPECT_EQ(3, cache.network_layer()->transaction_count()); |
| 1893 EXPECT_EQ(0, cache.disk_cache()->open_count()); |
| 1894 EXPECT_EQ(2, cache.disk_cache()->create_count()); |
| 1895 } |
| 1896 |
| 1897 // Tests that a transaction is in validated queue and writer is destroyed |
| 1898 // leading to restarting the validated transaction. |
| 1899 TEST(HttpCache, SimpleGET_ParallelValidationCancelWriter) { |
| 1900 MockHttpCache cache; |
| 1901 |
| 1902 MockHttpRequest request(kSimpleGET_Transaction); |
| 1903 |
| 1904 MockTransaction transaction(kSimpleGET_Transaction); |
| 1905 transaction.load_flags |= LOAD_VALIDATE_CACHE; |
| 1906 MockHttpRequest validate_request(transaction); |
| 1907 |
| 1908 const int kNumTransactions = 3; |
| 1909 std::vector<std::unique_ptr<Context>> context_list; |
| 1910 |
| 1911 for (int i = 0; i < kNumTransactions; ++i) { |
| 1912 context_list.push_back(base::MakeUnique<Context>()); |
| 1913 auto& c = context_list[i]; |
| 1914 |
| 1915 c->result = cache.CreateTransaction(&c->trans); |
| 1916 ASSERT_THAT(c->result, IsOk()); |
| 1917 |
| 1918 MockHttpRequest* this_request = &request; |
| 1919 if (i == 2) { |
| 1920 this_request = &validate_request; |
| 1921 c->trans->SetBeforeNetworkStartCallback(base::Bind(&DeferNetworkStart)); |
| 1922 } |
| 1923 |
| 1924 c->result = c->trans->Start(this_request, c->callback.callback(), |
| 1925 NetLogWithSource()); |
| 1926 } |
| 1927 |
| 1928 // Allow all requests to move from the Create queue to the active entry. |
| 1929 base::RunLoop().RunUntilIdle(); |
| 1930 |
| 1931 EXPECT_EQ(2, cache.network_layer()->transaction_count()); |
| 1932 EXPECT_EQ(0, cache.disk_cache()->open_count()); |
| 1933 EXPECT_EQ(1, cache.disk_cache()->create_count()); |
| 1934 |
| 1935 EXPECT_TRUE(cache.IsWriterPresent(kSimpleGET_Transaction.url)); |
| 1936 EXPECT_TRUE(cache.IsHeadersTransactionPresent(kSimpleGET_Transaction.url)); |
| 1937 EXPECT_EQ(1, cache.GetCountDoneHeadersQueue(kSimpleGET_Transaction.url)); |
| 1938 |
| 1939 // Deleting the writer at this point will lead to destroying the entry and |
| 1940 // restarting the remaining transactions which will then create a new entry. |
| 1941 context_list[0].reset(); |
| 1942 |
| 1943 // Resume network start for headers_transaction. It should be restarted due to |
| 1944 // writer cancellation. |
| 1945 auto& c = context_list[2]; |
| 1946 c->trans->ResumeNetworkStart(); |
| 1947 |
| 1948 base::RunLoop().RunUntilIdle(); |
| 1949 |
| 1950 EXPECT_TRUE(cache.IsWriterPresent(kSimpleGET_Transaction.url)); |
| 1951 EXPECT_TRUE(cache.IsHeadersTransactionPresent(kSimpleGET_Transaction.url)); |
| 1952 |
| 1953 // Resume network start for the transaction the second time. |
| 1954 c->trans->ResumeNetworkStart(); |
| 1955 base::RunLoop().RunUntilIdle(); |
| 1956 |
| 1957 // Headers transaction would have doomed the new entry created. |
| 1958 EXPECT_TRUE( |
| 1959 cache.disk_cache()->IsDiskEntryDoomed(kSimpleGET_Transaction.url)); |
| 1960 |
| 1961 // Complete the rest of the transactions. |
| 1962 for (auto& context : context_list) { |
| 1963 if (!context) |
| 1964 continue; |
| 1965 ReadAndVerifyTransaction(context->trans.get(), kSimpleGET_Transaction); |
| 1966 } |
| 1967 |
| 1968 EXPECT_EQ(4, cache.network_layer()->transaction_count()); |
| 1969 EXPECT_EQ(0, cache.disk_cache()->open_count()); |
| 1970 EXPECT_EQ(2, cache.disk_cache()->create_count()); |
| 1971 } |
| 1972 |
| 1973 // Tests that a transaction is currently in headers phase and is destroyed |
| 1974 // leading to destroying the entry. |
| 1975 TEST(HttpCache, SimpleGET_ParallelValidationCancelHeaders) { |
| 1976 MockHttpCache cache; |
| 1977 |
| 1978 MockHttpRequest request(kSimpleGET_Transaction); |
| 1979 |
| 1980 const int kNumTransactions = 2; |
| 1981 std::vector<std::unique_ptr<Context>> context_list; |
| 1982 |
| 1983 for (int i = 0; i < kNumTransactions; ++i) { |
| 1984 context_list.push_back(base::MakeUnique<Context>()); |
| 1985 auto& c = context_list[i]; |
| 1986 |
| 1987 c->result = cache.CreateTransaction(&c->trans); |
| 1988 ASSERT_THAT(c->result, IsOk()); |
| 1989 |
| 1990 if (i == 0) |
| 1991 c->trans->SetBeforeNetworkStartCallback(base::Bind(&DeferNetworkStart)); |
| 1992 |
| 1993 c->result = |
| 1994 c->trans->Start(&request, c->callback.callback(), NetLogWithSource()); |
| 1995 } |
| 1996 |
| 1997 base::RunLoop().RunUntilIdle(); |
| 1998 |
| 1999 EXPECT_TRUE(cache.IsHeadersTransactionPresent(kSimpleGET_Transaction.url)); |
| 2000 EXPECT_EQ(1, cache.GetCountAddToEntryQueue(kSimpleGET_Transaction.url)); |
| 2001 |
| 2002 EXPECT_EQ(1, cache.network_layer()->transaction_count()); |
| 2003 EXPECT_EQ(0, cache.disk_cache()->open_count()); |
| 2004 EXPECT_EQ(1, cache.disk_cache()->create_count()); |
| 2005 |
| 2006 // Delete the headers transaction. |
| 2007 context_list[0].reset(); |
| 2008 |
| 2009 base::RunLoop().RunUntilIdle(); |
| 2010 |
| 2011 // Complete the rest of the transactions. |
| 2012 for (auto& context : context_list) { |
| 2013 if (!context) |
| 2014 continue; |
| 2015 ReadAndVerifyTransaction(context->trans.get(), kSimpleGET_Transaction); |
| 2016 } |
| 2017 |
| 2018 EXPECT_EQ(2, cache.network_layer()->transaction_count()); |
| 2019 EXPECT_EQ(0, cache.disk_cache()->open_count()); |
| 2020 EXPECT_EQ(2, cache.disk_cache()->create_count()); |
| 2021 } |
| 2022 |
| 2023 // Similar to the above test, except here cache write fails and the |
| 2024 // validated transactions should be restarted. |
| 2025 TEST(HttpCache, SimpleGET_ParallelValidationFailWrite) { |
| 2026 MockHttpCache cache; |
| 2027 |
| 2028 MockHttpRequest request(kSimpleGET_Transaction); |
| 2029 |
| 2030 const int kNumTransactions = 5; |
| 2031 std::vector<std::unique_ptr<Context>> context_list; |
| 2032 |
| 2033 for (int i = 0; i < kNumTransactions; ++i) { |
| 2034 context_list.push_back(base::MakeUnique<Context>()); |
| 2035 auto& c = context_list[i]; |
| 2036 |
| 2037 c->result = cache.CreateTransaction(&c->trans); |
| 2038 ASSERT_THAT(c->result, IsOk()); |
| 2039 EXPECT_EQ(LOAD_STATE_IDLE, c->trans->GetLoadState()); |
| 2040 |
| 2041 c->result = |
| 2042 c->trans->Start(&request, c->callback.callback(), NetLogWithSource()); |
| 2043 } |
| 2044 |
| 2045 // All requests are waiting for the active entry. |
| 2046 for (auto& context : context_list) { |
| 2047 EXPECT_EQ(LOAD_STATE_WAITING_FOR_CACHE, context->trans->GetLoadState()); |
| 2048 } |
| 2049 |
| 2050 // Allow all requests to move from the Create queue to the active entry. |
| 2051 base::RunLoop().RunUntilIdle(); |
| 2052 |
| 2053 // The first request should be a writer at this point, and the subsequent |
| 2054 // requests should have passed the validation phase and waiting for the |
| 2055 // response to be written to the cache before they can read. |
| 2056 EXPECT_TRUE(cache.IsWriterPresent(kSimpleGET_Transaction.url)); |
| 2057 EXPECT_EQ(4, cache.GetCountDoneHeadersQueue(kSimpleGET_Transaction.url)); |
| 2058 |
| 2059 // All requests depend on the writer, and the writer is between Start and |
| 2060 // Read, i.e. idle. |
| 2061 for (auto& context : context_list) { |
| 2062 EXPECT_EQ(LOAD_STATE_IDLE, context->trans->GetLoadState()); |
| 2063 } |
| 2064 |
| 2065 // The first request should be a writer at this point, and the subsequent |
| 2066 // requests should have passed the validation phase and waiting for the |
| 2067 // response to be written to the cache before they can read. |
| 2068 |
| 2069 EXPECT_EQ(1, cache.network_layer()->transaction_count()); |
| 2070 EXPECT_EQ(0, cache.disk_cache()->open_count()); |
| 2071 EXPECT_EQ(1, cache.disk_cache()->create_count()); |
| 2072 |
| 2073 // Fail the request. |
| 2074 cache.disk_cache()->set_soft_failures(true); |
| 2075 // We have to open the entry again to propagate the failure flag. |
| 2076 disk_cache::Entry* en; |
| 2077 cache.OpenBackendEntry(kSimpleGET_Transaction.url, &en); |
| 2078 en->Close(); |
| 2079 |
| 2080 for (int i = 0; i < kNumTransactions; ++i) { |
| 2081 auto& c = context_list[i]; |
| 2082 if (c->result == ERR_IO_PENDING) |
| 2083 c->result = c->callback.WaitForResult(); |
| 2084 if (i == 1) { |
| 2085 // The earlier entry must be destroyed and its disk entry doomed. |
| 2086 EXPECT_TRUE( |
| 2087 cache.disk_cache()->IsDiskEntryDoomed(kSimpleGET_Transaction.url)); |
| 2088 } |
| 2089 ReadAndVerifyTransaction(c->trans.get(), kSimpleGET_Transaction); |
| 2090 } |
| 2091 |
| 2092 // Since validated transactions were restarted and new entry read/write |
| 2093 // operations would also fail, all requests would have gone to the network. |
| 2094 EXPECT_EQ(5, cache.network_layer()->transaction_count()); |
| 2095 EXPECT_EQ(1, cache.disk_cache()->open_count()); |
| 2096 EXPECT_EQ(5, cache.disk_cache()->create_count()); |
| 1408 } | 2097 } |
| 1409 | 2098 |
| 1410 // This is a test for http://code.google.com/p/chromium/issues/detail?id=4769. | 2099 // This is a test for http://code.google.com/p/chromium/issues/detail?id=4769. |
| 1411 // If cancelling a request is racing with another request for the same resource | 2100 // If cancelling a request is racing with another request for the same resource |
| 1412 // finishing, we have to make sure that we remove both transactions from the | 2101 // finishing, we have to make sure that we remove both transactions from the |
| 1413 // entry. | 2102 // entry. |
| 1414 TEST(HttpCache, SimpleGET_RacingReaders) { | 2103 TEST(HttpCache, SimpleGET_RacingReaders) { |
| 1415 MockHttpCache cache; | 2104 MockHttpCache cache; |
| 1416 | 2105 |
| 1417 MockHttpRequest request(kSimpleGET_Transaction); | 2106 MockHttpRequest request(kSimpleGET_Transaction); |
| (...skipping 26 matching lines...) Expand all Loading... |
| 1444 | 2133 |
| 1445 EXPECT_EQ(1, cache.network_layer()->transaction_count()); | 2134 EXPECT_EQ(1, cache.network_layer()->transaction_count()); |
| 1446 EXPECT_EQ(0, cache.disk_cache()->open_count()); | 2135 EXPECT_EQ(0, cache.disk_cache()->open_count()); |
| 1447 EXPECT_EQ(1, cache.disk_cache()->create_count()); | 2136 EXPECT_EQ(1, cache.disk_cache()->create_count()); |
| 1448 | 2137 |
| 1449 Context* c = context_list[0]; | 2138 Context* c = context_list[0]; |
| 1450 ASSERT_THAT(c->result, IsError(ERR_IO_PENDING)); | 2139 ASSERT_THAT(c->result, IsError(ERR_IO_PENDING)); |
| 1451 c->result = c->callback.WaitForResult(); | 2140 c->result = c->callback.WaitForResult(); |
| 1452 ReadAndVerifyTransaction(c->trans.get(), kSimpleGET_Transaction); | 2141 ReadAndVerifyTransaction(c->trans.get(), kSimpleGET_Transaction); |
| 1453 | 2142 |
| 1454 // Now we have 2 active readers and two queued transactions. | 2143 // Now all transactions should be waiting for read to be invoked. Two readers |
| 1455 | 2144 // are because of the load flags and remaining two transactions were converted |
| 2145 // to readers after skipping validation. Note that the remaining two went on |
| 2146 // to process the headers in parallel with readers present on the entry. |
| 1456 EXPECT_EQ(LOAD_STATE_IDLE, context_list[2]->trans->GetLoadState()); | 2147 EXPECT_EQ(LOAD_STATE_IDLE, context_list[2]->trans->GetLoadState()); |
| 1457 EXPECT_EQ(LOAD_STATE_WAITING_FOR_CACHE, | 2148 EXPECT_EQ(LOAD_STATE_IDLE, context_list[3]->trans->GetLoadState()); |
| 1458 context_list[3]->trans->GetLoadState()); | |
| 1459 | 2149 |
| 1460 c = context_list[1]; | 2150 c = context_list[1]; |
| 1461 ASSERT_THAT(c->result, IsError(ERR_IO_PENDING)); | 2151 ASSERT_THAT(c->result, IsError(ERR_IO_PENDING)); |
| 1462 c->result = c->callback.WaitForResult(); | 2152 c->result = c->callback.WaitForResult(); |
| 1463 if (c->result == OK) | 2153 if (c->result == OK) |
| 1464 ReadAndVerifyTransaction(c->trans.get(), kSimpleGET_Transaction); | 2154 ReadAndVerifyTransaction(c->trans.get(), kSimpleGET_Transaction); |
| 1465 | 2155 |
| 1466 // At this point we have one reader, two pending transactions and a task on | 2156 // At this point we have one reader, two pending transactions and a task on |
| 1467 // the queue to move to the next transaction. Now we cancel the request that | 2157 // the queue to move to the next transaction. Now we cancel the request that |
| 1468 // is the current reader, and expect the queued task to be able to start the | 2158 // is the current reader, and expect the queued task to be able to start the |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1513 ASSERT_THAT(c->result, IsOk()); | 2203 ASSERT_THAT(c->result, IsOk()); |
| 1514 | 2204 |
| 1515 MockHttpRequest* this_request = &request; | 2205 MockHttpRequest* this_request = &request; |
| 1516 if (i == 3) | 2206 if (i == 3) |
| 1517 this_request = &writer_request; | 2207 this_request = &writer_request; |
| 1518 | 2208 |
| 1519 c->result = c->trans->Start(this_request, c->callback.callback(), | 2209 c->result = c->trans->Start(this_request, c->callback.callback(), |
| 1520 NetLogWithSource()); | 2210 NetLogWithSource()); |
| 1521 } | 2211 } |
| 1522 | 2212 |
| 2213 base::RunLoop().RunUntilIdle(); |
| 2214 |
| 1523 // The first request should be a writer at this point, and the two subsequent | 2215 // The first request should be a writer at this point, and the two subsequent |
| 1524 // requests should be pending. The last request doomed the first entry. | 2216 // requests should be pending. The last request doomed the first entry. |
| 1525 | 2217 |
| 1526 EXPECT_EQ(2, cache.network_layer()->transaction_count()); | 2218 EXPECT_EQ(2, cache.network_layer()->transaction_count()); |
| 1527 | 2219 |
| 1528 // Cancel the first queued transaction. | 2220 // Cancel the second transaction. Note that this and the 3rd transactions |
| 2221 // would have completed their headers phase and would be waiting in the |
| 2222 // done_headers_queue when the 2nd transaction is cancelled. |
| 1529 context_list[1].reset(); | 2223 context_list[1].reset(); |
| 1530 | 2224 |
| 1531 for (int i = 0; i < kNumTransactions; ++i) { | 2225 for (int i = 0; i < kNumTransactions; ++i) { |
| 1532 if (i == 1) | 2226 if (i == 1) |
| 1533 continue; | 2227 continue; |
| 1534 Context* c = context_list[i].get(); | 2228 Context* c = context_list[i].get(); |
| 1535 ASSERT_THAT(c->result, IsError(ERR_IO_PENDING)); | 2229 ASSERT_THAT(c->result, IsError(ERR_IO_PENDING)); |
| 1536 c->result = c->callback.WaitForResult(); | 2230 c->result = c->callback.WaitForResult(); |
| 1537 ReadAndVerifyTransaction(c->trans.get(), kSimpleGET_Transaction); | 2231 ReadAndVerifyTransaction(c->trans.get(), kSimpleGET_Transaction); |
| 1538 } | 2232 } |
| (...skipping 21 matching lines...) Expand all Loading... |
| 1560 ASSERT_THAT(c->result, IsOk()); | 2254 ASSERT_THAT(c->result, IsOk()); |
| 1561 | 2255 |
| 1562 c->result = | 2256 c->result = |
| 1563 c->trans->Start(&request, c->callback.callback(), NetLogWithSource()); | 2257 c->trans->Start(&request, c->callback.callback(), NetLogWithSource()); |
| 1564 } | 2258 } |
| 1565 | 2259 |
| 1566 // Allow all requests to move from the Create queue to the active entry. | 2260 // Allow all requests to move from the Create queue to the active entry. |
| 1567 base::RunLoop().RunUntilIdle(); | 2261 base::RunLoop().RunUntilIdle(); |
| 1568 | 2262 |
| 1569 // The first request should be a writer at this point, and the subsequent | 2263 // The first request should be a writer at this point, and the subsequent |
| 1570 // requests should be pending. | 2264 // requests should have completed validation. Since the validation does not |
| 2265 // result in a match, a new entry would be created. |
| 1571 | 2266 |
| 1572 EXPECT_EQ(1, cache.network_layer()->transaction_count()); | 2267 EXPECT_EQ(3, cache.network_layer()->transaction_count()); |
| 1573 EXPECT_EQ(0, cache.disk_cache()->open_count()); | 2268 EXPECT_EQ(0, cache.disk_cache()->open_count()); |
| 1574 EXPECT_EQ(1, cache.disk_cache()->create_count()); | 2269 EXPECT_EQ(2, cache.disk_cache()->create_count()); |
| 1575 | 2270 |
| 1576 // Now, make sure that the second request asks for the entry not to be stored. | 2271 // Now, make sure that the second request asks for the entry not to be stored. |
| 1577 request_handler.set_no_store(true); | 2272 request_handler.set_no_store(true); |
| 1578 | 2273 |
| 1579 for (int i = 0; i < kNumTransactions; ++i) { | 2274 for (int i = 0; i < kNumTransactions; ++i) { |
| 1580 Context* c = context_list[i]; | 2275 Context* c = context_list[i]; |
| 1581 if (c->result == ERR_IO_PENDING) | 2276 if (c->result == ERR_IO_PENDING) |
| 1582 c->result = c->callback.WaitForResult(); | 2277 c->result = c->callback.WaitForResult(); |
| 1583 ReadAndVerifyTransaction(c->trans.get(), kFastNoStoreGET_Transaction); | 2278 ReadAndVerifyTransaction(c->trans.get(), kFastNoStoreGET_Transaction); |
| 1584 delete c; | 2279 delete c; |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1618 | 2313 |
| 1619 EXPECT_EQ(1, cache.network_layer()->transaction_count()); | 2314 EXPECT_EQ(1, cache.network_layer()->transaction_count()); |
| 1620 EXPECT_EQ(0, cache.disk_cache()->open_count()); | 2315 EXPECT_EQ(0, cache.disk_cache()->open_count()); |
| 1621 EXPECT_EQ(1, cache.disk_cache()->create_count()); | 2316 EXPECT_EQ(1, cache.disk_cache()->create_count()); |
| 1622 | 2317 |
| 1623 for (int i = 0; i < kNumTransactions; ++i) { | 2318 for (int i = 0; i < kNumTransactions; ++i) { |
| 1624 Context* c = context_list[i]; | 2319 Context* c = context_list[i]; |
| 1625 if (c->result == ERR_IO_PENDING) | 2320 if (c->result == ERR_IO_PENDING) |
| 1626 c->result = c->callback.WaitForResult(); | 2321 c->result = c->callback.WaitForResult(); |
| 1627 // Destroy only the first transaction. | 2322 // Destroy only the first transaction. |
| 2323 // This should lead to all transactions to restart, even those that have |
| 2324 // validated themselves and were waiting for the writer transaction to |
| 2325 // complete writing to the cache. |
| 1628 if (i == 0) { | 2326 if (i == 0) { |
| 1629 delete c; | 2327 delete c; |
| 1630 context_list[i] = NULL; | 2328 context_list[i] = NULL; |
| 1631 } | 2329 } |
| 1632 } | 2330 } |
| 1633 | 2331 |
| 1634 // Complete the rest of the transactions. | 2332 // Complete the rest of the transactions. |
| 1635 for (int i = 1; i < kNumTransactions; ++i) { | 2333 for (int i = 1; i < kNumTransactions; ++i) { |
| 1636 Context* c = context_list[i]; | 2334 Context* c = context_list[i]; |
| 1637 ReadAndVerifyTransaction(c->trans.get(), kSimpleGET_Transaction); | 2335 ReadAndVerifyTransaction(c->trans.get(), kSimpleGET_Transaction); |
| (...skipping 895 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2533 } | 3231 } |
| 2534 | 3232 |
| 2535 // Helper that does 4 requests using HttpCache: | 3233 // Helper that does 4 requests using HttpCache: |
| 2536 // | 3234 // |
| 2537 // (1) loads |kUrl| -- expects |net_response_1| to be returned. | 3235 // (1) loads |kUrl| -- expects |net_response_1| to be returned. |
| 2538 // (2) loads |kUrl| from cache only -- expects |net_response_1| to be returned. | 3236 // (2) loads |kUrl| from cache only -- expects |net_response_1| to be returned. |
| 2539 // (3) loads |kUrl| using |extra_request_headers| -- expects |net_response_2| to | 3237 // (3) loads |kUrl| using |extra_request_headers| -- expects |net_response_2| to |
| 2540 // be returned. | 3238 // be returned. |
| 2541 // (4) loads |kUrl| from cache only -- expects |cached_response_2| to be | 3239 // (4) loads |kUrl| from cache only -- expects |cached_response_2| to be |
| 2542 // returned. | 3240 // returned. |
| 3241 // The entry will be created once and will be opened for the 3 subsequent |
| 3242 // requests. |
| 2543 static void ConditionalizedRequestUpdatesCacheHelper( | 3243 static void ConditionalizedRequestUpdatesCacheHelper( |
| 2544 const Response& net_response_1, | 3244 const Response& net_response_1, |
| 2545 const Response& net_response_2, | 3245 const Response& net_response_2, |
| 2546 const Response& cached_response_2, | 3246 const Response& cached_response_2, |
| 2547 const char* extra_request_headers) { | 3247 const char* extra_request_headers) { |
| 2548 MockHttpCache cache; | 3248 MockHttpCache cache; |
| 2549 | 3249 |
| 2550 // The URL we will be requesting. | 3250 // The URL we will be requesting. |
| 2551 const char kUrl[] = "http://foobar.com/main.css"; | 3251 const char kUrl[] = "http://foobar.com/main.css"; |
| 2552 | 3252 |
| (...skipping 3555 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6108 pending->trans->Start(&request, pending->callback.callback(), | 6808 pending->trans->Start(&request, pending->callback.callback(), |
| 6109 NetLogWithSource())); | 6809 NetLogWithSource())); |
| 6110 EXPECT_THAT(c->callback.GetResult(rv), IsOk()); | 6810 EXPECT_THAT(c->callback.GetResult(rv), IsOk()); |
| 6111 | 6811 |
| 6112 // Make sure that the entry has some data stored. | 6812 // Make sure that the entry has some data stored. |
| 6113 scoped_refptr<IOBufferWithSize> buf(new IOBufferWithSize(5)); | 6813 scoped_refptr<IOBufferWithSize> buf(new IOBufferWithSize(5)); |
| 6114 rv = c->trans->Read(buf.get(), buf->size(), c->callback.callback()); | 6814 rv = c->trans->Read(buf.get(), buf->size(), c->callback.callback()); |
| 6115 EXPECT_EQ(5, c->callback.GetResult(rv)); | 6815 EXPECT_EQ(5, c->callback.GetResult(rv)); |
| 6116 | 6816 |
| 6117 // Cancel the requests. | 6817 // Cancel the requests. |
| 6818 // Since |pending| is currently validating the already written headers |
| 6819 // it will be restarted as well. |
| 6118 delete c; | 6820 delete c; |
| 6119 delete pending; | 6821 delete pending; |
| 6120 | 6822 |
| 6121 EXPECT_EQ(1, cache.network_layer()->transaction_count()); | 6823 EXPECT_EQ(1, cache.network_layer()->transaction_count()); |
| 6122 EXPECT_EQ(1, cache.disk_cache()->open_count()); | 6824 EXPECT_EQ(1, cache.disk_cache()->open_count()); |
| 6123 EXPECT_EQ(2, cache.disk_cache()->create_count()); | 6825 EXPECT_EQ(1, cache.disk_cache()->create_count()); |
| 6124 | 6826 |
| 6125 base::RunLoop().RunUntilIdle(); | 6827 base::RunLoop().RunUntilIdle(); |
| 6126 RemoveMockTransaction(&transaction); | 6828 RemoveMockTransaction(&transaction); |
| 6127 } | 6829 } |
| 6128 | 6830 |
| 6129 // Tests that we delete truncated entries if the server changes its mind midway. | 6831 // Tests that we delete truncated entries if the server changes its mind midway. |
| 6130 TEST(HttpCache, GET_IncompleteResource2) { | 6832 TEST(HttpCache, GET_IncompleteResource2) { |
| 6131 MockHttpCache cache; | 6833 MockHttpCache cache; |
| 6132 AddMockTransaction(&kRangeGET_TransactionOK); | 6834 AddMockTransaction(&kRangeGET_TransactionOK); |
| 6133 | 6835 |
| (...skipping 704 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6838 | 7540 |
| 6839 RunTransactionTestWithResponseInfo(cache.http_cache(), kSimpleGET_Transaction, | 7541 RunTransactionTestWithResponseInfo(cache.http_cache(), kSimpleGET_Transaction, |
| 6840 &response); | 7542 &response); |
| 6841 EXPECT_TRUE(response.metadata.get() == NULL); | 7543 EXPECT_TRUE(response.metadata.get() == NULL); |
| 6842 | 7544 |
| 6843 EXPECT_EQ(1, cache.network_layer()->transaction_count()); | 7545 EXPECT_EQ(1, cache.network_layer()->transaction_count()); |
| 6844 EXPECT_EQ(2, cache.disk_cache()->open_count()); | 7546 EXPECT_EQ(2, cache.disk_cache()->open_count()); |
| 6845 EXPECT_EQ(1, cache.disk_cache()->create_count()); | 7547 EXPECT_EQ(1, cache.disk_cache()->create_count()); |
| 6846 } | 7548 } |
| 6847 | 7549 |
| 6848 // Tests that if a metadata writer transaction hits cache lock timeout, it will | |
| 6849 // error out. | |
| 6850 TEST(HttpCache, WriteMetadata_CacheLockTimeout) { | |
| 6851 MockHttpCache cache; | |
| 6852 | |
| 6853 // Write to the cache | |
| 6854 HttpResponseInfo response; | |
| 6855 RunTransactionTestWithResponseInfo(cache.http_cache(), kSimpleGET_Transaction, | |
| 6856 &response); | |
| 6857 EXPECT_FALSE(response.metadata.get()); | |
| 6858 | |
| 6859 MockHttpRequest request(kSimpleGET_Transaction); | |
| 6860 Context c1; | |
| 6861 ASSERT_THAT(cache.CreateTransaction(&c1.trans), IsOk()); | |
| 6862 ASSERT_EQ(ERR_IO_PENDING, c1.trans->Start(&request, c1.callback.callback(), | |
| 6863 NetLogWithSource())); | |
| 6864 | |
| 6865 cache.SimulateCacheLockTimeout(); | |
| 6866 | |
| 6867 // Write meta data to the same entry. | |
| 6868 scoped_refptr<IOBufferWithSize> buf(new IOBufferWithSize(50)); | |
| 6869 memset(buf->data(), 0, buf->size()); | |
| 6870 base::strlcpy(buf->data(), "Hi there", buf->size()); | |
| 6871 cache.http_cache()->WriteMetadata(GURL(kSimpleGET_Transaction.url), | |
| 6872 DEFAULT_PRIORITY, response.response_time, | |
| 6873 buf.get(), buf->size()); | |
| 6874 | |
| 6875 // Release the buffer before the operation takes place. | |
| 6876 buf = NULL; | |
| 6877 | |
| 6878 // Makes sure we finish pending operations. | |
| 6879 base::RunLoop().RunUntilIdle(); | |
| 6880 | |
| 6881 RunTransactionTestWithResponseInfo(cache.http_cache(), kSimpleGET_Transaction, | |
| 6882 &response); | |
| 6883 | |
| 6884 // The writer transaction should fail due to cache lock timeout. | |
| 6885 ASSERT_FALSE(response.metadata.get()); | |
| 6886 } | |
| 6887 | |
| 6888 // Tests that we ignore VARY checks when writing metadata since the request | 7550 // Tests that we ignore VARY checks when writing metadata since the request |
| 6889 // headers for the WriteMetadata transaction are made up. | 7551 // headers for the WriteMetadata transaction are made up. |
| 6890 TEST(HttpCache, WriteMetadata_IgnoreVary) { | 7552 TEST(HttpCache, WriteMetadata_IgnoreVary) { |
| 6891 MockHttpCache cache; | 7553 MockHttpCache cache; |
| 6892 | 7554 |
| 6893 // Write to the cache | 7555 // Write to the cache |
| 6894 HttpResponseInfo response; | 7556 HttpResponseInfo response; |
| 6895 ScopedMockTransaction transaction(kSimpleGET_Transaction); | 7557 ScopedMockTransaction transaction(kSimpleGET_Transaction); |
| 6896 transaction.request_headers = "accept-encoding: gzip\r\n"; | 7558 transaction.request_headers = "accept-encoding: gzip\r\n"; |
| 6897 transaction.response_headers = | 7559 transaction.response_headers = |
| (...skipping 307 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7205 MockHttpRequest request(mock_transaction); | 7867 MockHttpRequest request(mock_transaction); |
| 7206 | 7868 |
| 7207 { | 7869 { |
| 7208 std::unique_ptr<HttpTransaction> trans; | 7870 std::unique_ptr<HttpTransaction> trans; |
| 7209 ASSERT_THAT(cache.CreateTransaction(&trans), IsOk()); | 7871 ASSERT_THAT(cache.CreateTransaction(&trans), IsOk()); |
| 7210 | 7872 |
| 7211 int rv = trans->Start(&request, callback.callback(), NetLogWithSource()); | 7873 int rv = trans->Start(&request, callback.callback(), NetLogWithSource()); |
| 7212 EXPECT_THAT(callback.GetResult(rv), IsOk()); | 7874 EXPECT_THAT(callback.GetResult(rv), IsOk()); |
| 7213 | 7875 |
| 7214 trans->StopCaching(); | 7876 trans->StopCaching(); |
| 7215 | |
| 7216 scoped_refptr<IOBuffer> buf(new IOBuffer(256)); | |
| 7217 rv = trans->Read(buf.get(), 10, callback.callback()); | |
| 7218 EXPECT_EQ(callback.GetResult(rv), 10); | |
| 7219 } | 7877 } |
| 7220 RemoveMockTransaction(&mock_transaction); | 7878 RemoveMockTransaction(&mock_transaction); |
| 7221 | 7879 |
| 7222 // Make sure that the ActiveEntry is gone. | 7880 // Make sure that the ActiveEntry is gone. |
| 7223 base::RunLoop().RunUntilIdle(); | 7881 base::RunLoop().RunUntilIdle(); |
| 7224 | 7882 |
| 7225 // Verify that the entry is gone. | 7883 // Verify that the entry is gone. |
| 7226 RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction); | 7884 RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction); |
| 7227 | 7885 |
| 7228 EXPECT_EQ(2, cache.network_layer()->transaction_count()); | 7886 EXPECT_EQ(2, cache.network_layer()->transaction_count()); |
| (...skipping 1031 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 8260 ASSERT_TRUE(attrs->GetDictionary( | 8918 ASSERT_TRUE(attrs->GetDictionary( |
| 8261 base::trace_event::MemoryAllocatorDump::kNameSize, &size_attrs)); | 8919 base::trace_event::MemoryAllocatorDump::kNameSize, &size_attrs)); |
| 8262 std::string size; | 8920 std::string size; |
| 8263 ASSERT_TRUE(size_attrs->GetString("value", &size)); | 8921 ASSERT_TRUE(size_attrs->GetString("value", &size)); |
| 8264 int actual_size = 0; | 8922 int actual_size = 0; |
| 8265 ASSERT_TRUE(base::HexStringToInt(size, &actual_size)); | 8923 ASSERT_TRUE(base::HexStringToInt(size, &actual_size)); |
| 8266 ASSERT_LT(0, actual_size); | 8924 ASSERT_LT(0, actual_size); |
| 8267 } | 8925 } |
| 8268 | 8926 |
| 8269 } // namespace net | 8927 } // namespace net |
| OLD | NEW |