| 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 1357 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1368 // All requests are waiting for the active entry. | 1368 // All requests are waiting for the active entry. |
| 1369 for (int i = 0; i < kNumTransactions; ++i) { | 1369 for (int i = 0; i < kNumTransactions; ++i) { |
| 1370 Context* c = context_list[i]; | 1370 Context* c = context_list[i]; |
| 1371 EXPECT_EQ(LOAD_STATE_WAITING_FOR_CACHE, c->trans->GetLoadState()); | 1371 EXPECT_EQ(LOAD_STATE_WAITING_FOR_CACHE, c->trans->GetLoadState()); |
| 1372 } | 1372 } |
| 1373 | 1373 |
| 1374 // Allow all requests to move from the Create queue to the active entry. | 1374 // Allow all requests to move from the Create queue to the active entry. |
| 1375 base::RunLoop().RunUntilIdle(); | 1375 base::RunLoop().RunUntilIdle(); |
| 1376 | 1376 |
| 1377 // The first request should be a writer at this point, and the subsequent | 1377 // The first request should be a writer at this point, and the subsequent |
| 1378 // requests should be pending. | 1378 // requests should have passed the validation phase and waiting for the |
| 1379 // response to be written to the cache before they can read. |
| 1380 EXPECT_TRUE(cache.IsWriterPresent(kSimpleGET_Transaction.url)); |
| 1381 EXPECT_EQ(4, cache.GetCountDoneHeadersQueue(kSimpleGET_Transaction.url)); |
| 1379 | 1382 |
| 1380 EXPECT_EQ(1, cache.network_layer()->transaction_count()); | 1383 EXPECT_EQ(1, cache.network_layer()->transaction_count()); |
| 1381 EXPECT_EQ(0, cache.disk_cache()->open_count()); | 1384 EXPECT_EQ(0, cache.disk_cache()->open_count()); |
| 1382 EXPECT_EQ(1, cache.disk_cache()->create_count()); | 1385 EXPECT_EQ(1, cache.disk_cache()->create_count()); |
| 1383 | 1386 |
| 1384 // All requests depend on the writer, and the writer is between Start and | 1387 // All requests depend on the writer, and the writer is between Start and |
| 1385 // Read, i.e. idle. | 1388 // Read, i.e. idle. |
| 1386 for (int i = 0; i < kNumTransactions; ++i) { | 1389 for (int i = 0; i < kNumTransactions; ++i) { |
| 1387 Context* c = context_list[i]; | 1390 Context* c = context_list[i]; |
| 1388 EXPECT_EQ(LOAD_STATE_IDLE, c->trans->GetLoadState()); | 1391 EXPECT_EQ(LOAD_STATE_IDLE, c->trans->GetLoadState()); |
| 1389 } | 1392 } |
| 1390 | 1393 |
| 1391 for (int i = 0; i < kNumTransactions; ++i) { | 1394 for (int i = 0; i < kNumTransactions; ++i) { |
| 1392 Context* c = context_list[i]; | 1395 Context* c = context_list[i]; |
| 1393 if (c->result == ERR_IO_PENDING) | 1396 if (c->result == ERR_IO_PENDING) |
| 1394 c->result = c->callback.WaitForResult(); | 1397 c->result = c->callback.WaitForResult(); |
| 1398 |
| 1399 if (i == 1) { |
| 1400 EXPECT_FALSE(cache.IsWriterPresent(kSimpleGET_Transaction.url)); |
| 1401 EXPECT_EQ(4, cache.GetCountReaders(kSimpleGET_Transaction.url)); |
| 1402 } |
| 1403 |
| 1395 ReadAndVerifyTransaction(c->trans.get(), kSimpleGET_Transaction); | 1404 ReadAndVerifyTransaction(c->trans.get(), kSimpleGET_Transaction); |
| 1396 } | 1405 } |
| 1397 | 1406 |
| 1398 // We should not have had to re-open the disk entry | 1407 // We should not have had to re-open the disk entry |
| 1399 | 1408 |
| 1400 EXPECT_EQ(1, cache.network_layer()->transaction_count()); | 1409 EXPECT_EQ(1, cache.network_layer()->transaction_count()); |
| 1401 EXPECT_EQ(0, cache.disk_cache()->open_count()); | 1410 EXPECT_EQ(0, cache.disk_cache()->open_count()); |
| 1402 EXPECT_EQ(1, cache.disk_cache()->create_count()); | 1411 EXPECT_EQ(1, cache.disk_cache()->create_count()); |
| 1403 | 1412 |
| 1404 for (int i = 0; i < kNumTransactions; ++i) { | 1413 for (int i = 0; i < kNumTransactions; ++i) { |
| 1405 Context* c = context_list[i]; | 1414 Context* c = context_list[i]; |
| 1406 delete c; | 1415 delete c; |
| 1407 } | 1416 } |
| 1408 } | 1417 } |
| 1409 | 1418 |
| 1419 // Similar to the above test, except here cache write fails and the |
| 1420 // validated transactions should be restarted. |
| 1421 TEST(HttpCache, SimpleGET_ParallelValidationFailWrite) { |
| 1422 MockHttpCache cache; |
| 1423 |
| 1424 MockHttpRequest request(kSimpleGET_Transaction); |
| 1425 |
| 1426 std::vector<Context*> context_list; |
| 1427 const int kNumTransactions = 5; |
| 1428 |
| 1429 for (int i = 0; i < kNumTransactions; ++i) { |
| 1430 context_list.push_back(new Context()); |
| 1431 Context* c = context_list[i]; |
| 1432 |
| 1433 c->result = cache.CreateTransaction(&c->trans); |
| 1434 ASSERT_THAT(c->result, IsOk()); |
| 1435 EXPECT_EQ(LOAD_STATE_IDLE, c->trans->GetLoadState()); |
| 1436 |
| 1437 c->result = |
| 1438 c->trans->Start(&request, c->callback.callback(), NetLogWithSource()); |
| 1439 } |
| 1440 |
| 1441 // All requests are waiting for the active entry. |
| 1442 for (int i = 0; i < kNumTransactions; ++i) { |
| 1443 Context* c = context_list[i]; |
| 1444 EXPECT_EQ(LOAD_STATE_WAITING_FOR_CACHE, c->trans->GetLoadState()); |
| 1445 } |
| 1446 |
| 1447 // Allow all requests to move from the Create queue to the active entry. |
| 1448 base::RunLoop().RunUntilIdle(); |
| 1449 |
| 1450 // The first request should be a writer at this point, and the subsequent |
| 1451 // requests should have passed the validation phase and waiting for the |
| 1452 // response to be written to the cache before they can read. |
| 1453 EXPECT_TRUE(cache.IsWriterPresent(kSimpleGET_Transaction.url)); |
| 1454 EXPECT_EQ(4, cache.GetCountDoneHeadersQueue(kSimpleGET_Transaction.url)); |
| 1455 |
| 1456 // All requests depend on the writer, and the writer is between Start and |
| 1457 // Read, i.e. idle. |
| 1458 for (int i = 0; i < kNumTransactions; ++i) { |
| 1459 Context* c = context_list[i]; |
| 1460 EXPECT_EQ(LOAD_STATE_IDLE, c->trans->GetLoadState()); |
| 1461 } |
| 1462 |
| 1463 // The first request should be a writer at this point, and the subsequent |
| 1464 // requests should have passed the validation phase and waiting for the |
| 1465 // response to be written to the cache before they can read. |
| 1466 |
| 1467 EXPECT_EQ(1, cache.network_layer()->transaction_count()); |
| 1468 EXPECT_EQ(0, cache.disk_cache()->open_count()); |
| 1469 EXPECT_EQ(1, cache.disk_cache()->create_count()); |
| 1470 |
| 1471 // Fail the request. |
| 1472 cache.disk_cache()->set_soft_failures(true); |
| 1473 // We have to open the entry again to propagate the failure flag. |
| 1474 disk_cache::Entry* en; |
| 1475 cache.OpenBackendEntry(kSimpleGET_Transaction.url, &en); |
| 1476 en->Close(); |
| 1477 |
| 1478 for (int i = 0; i < kNumTransactions; ++i) { |
| 1479 Context* c = context_list[i]; |
| 1480 if (c->result == ERR_IO_PENDING) |
| 1481 c->result = c->callback.WaitForResult(); |
| 1482 if (i == 1) { |
| 1483 // The earlier entry must be destroyed and its disk entry doomed. |
| 1484 EXPECT_TRUE( |
| 1485 cache.disk_cache()->IsDiskEntryDoomed(kSimpleGET_Transaction.url)); |
| 1486 } |
| 1487 ReadAndVerifyTransaction(c->trans.get(), kSimpleGET_Transaction); |
| 1488 } |
| 1489 |
| 1490 // Since validated transactions were restarted and new entry read/write |
| 1491 // operations would also fail, all requests would have gone to the network. |
| 1492 EXPECT_EQ(5, cache.network_layer()->transaction_count()); |
| 1493 EXPECT_EQ(1, cache.disk_cache()->open_count()); |
| 1494 EXPECT_EQ(5, cache.disk_cache()->create_count()); |
| 1495 |
| 1496 for (int i = 0; i < kNumTransactions; ++i) { |
| 1497 Context* c = context_list[i]; |
| 1498 delete c; |
| 1499 } |
| 1500 } |
| 1501 |
| 1410 // This is a test for http://code.google.com/p/chromium/issues/detail?id=4769. | 1502 // 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 | 1503 // 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 | 1504 // finishing, we have to make sure that we remove both transactions from the |
| 1413 // entry. | 1505 // entry. |
| 1414 TEST(HttpCache, SimpleGET_RacingReaders) { | 1506 TEST(HttpCache, SimpleGET_RacingReaders) { |
| 1415 MockHttpCache cache; | 1507 MockHttpCache cache; |
| 1416 | 1508 |
| 1417 MockHttpRequest request(kSimpleGET_Transaction); | 1509 MockHttpRequest request(kSimpleGET_Transaction); |
| 1418 MockHttpRequest reader_request(kSimpleGET_Transaction); | 1510 MockHttpRequest reader_request(kSimpleGET_Transaction); |
| 1419 reader_request.load_flags = LOAD_ONLY_FROM_CACHE | LOAD_SKIP_CACHE_VALIDATION; | 1511 reader_request.load_flags = LOAD_ONLY_FROM_CACHE | LOAD_SKIP_CACHE_VALIDATION; |
| (...skipping 24 matching lines...) Expand all Loading... |
| 1444 | 1536 |
| 1445 EXPECT_EQ(1, cache.network_layer()->transaction_count()); | 1537 EXPECT_EQ(1, cache.network_layer()->transaction_count()); |
| 1446 EXPECT_EQ(0, cache.disk_cache()->open_count()); | 1538 EXPECT_EQ(0, cache.disk_cache()->open_count()); |
| 1447 EXPECT_EQ(1, cache.disk_cache()->create_count()); | 1539 EXPECT_EQ(1, cache.disk_cache()->create_count()); |
| 1448 | 1540 |
| 1449 Context* c = context_list[0]; | 1541 Context* c = context_list[0]; |
| 1450 ASSERT_THAT(c->result, IsError(ERR_IO_PENDING)); | 1542 ASSERT_THAT(c->result, IsError(ERR_IO_PENDING)); |
| 1451 c->result = c->callback.WaitForResult(); | 1543 c->result = c->callback.WaitForResult(); |
| 1452 ReadAndVerifyTransaction(c->trans.get(), kSimpleGET_Transaction); | 1544 ReadAndVerifyTransaction(c->trans.get(), kSimpleGET_Transaction); |
| 1453 | 1545 |
| 1454 // Now we have 2 active readers and two queued transactions. | 1546 // Now all transactions should be waiting for read to be invoked. Two readers |
| 1455 | 1547 // are because of the load flags and remaining two transactions were converted |
| 1548 // to readers after skipping validation. Note that the remaining two went on |
| 1549 // to process the headers in parallel with readers presnt on the entry. |
| 1456 EXPECT_EQ(LOAD_STATE_IDLE, context_list[2]->trans->GetLoadState()); | 1550 EXPECT_EQ(LOAD_STATE_IDLE, context_list[2]->trans->GetLoadState()); |
| 1457 EXPECT_EQ(LOAD_STATE_WAITING_FOR_CACHE, | 1551 EXPECT_EQ(LOAD_STATE_IDLE, context_list[3]->trans->GetLoadState()); |
| 1458 context_list[3]->trans->GetLoadState()); | |
| 1459 | 1552 |
| 1460 c = context_list[1]; | 1553 c = context_list[1]; |
| 1461 ASSERT_THAT(c->result, IsError(ERR_IO_PENDING)); | 1554 ASSERT_THAT(c->result, IsError(ERR_IO_PENDING)); |
| 1462 c->result = c->callback.WaitForResult(); | 1555 c->result = c->callback.WaitForResult(); |
| 1463 if (c->result == OK) | 1556 if (c->result == OK) |
| 1464 ReadAndVerifyTransaction(c->trans.get(), kSimpleGET_Transaction); | 1557 ReadAndVerifyTransaction(c->trans.get(), kSimpleGET_Transaction); |
| 1465 | 1558 |
| 1466 // At this point we have one reader, two pending transactions and a task on | 1559 // 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 | 1560 // 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 | 1561 // 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()); | 1606 ASSERT_THAT(c->result, IsOk()); |
| 1514 | 1607 |
| 1515 MockHttpRequest* this_request = &request; | 1608 MockHttpRequest* this_request = &request; |
| 1516 if (i == 3) | 1609 if (i == 3) |
| 1517 this_request = &writer_request; | 1610 this_request = &writer_request; |
| 1518 | 1611 |
| 1519 c->result = c->trans->Start(this_request, c->callback.callback(), | 1612 c->result = c->trans->Start(this_request, c->callback.callback(), |
| 1520 NetLogWithSource()); | 1613 NetLogWithSource()); |
| 1521 } | 1614 } |
| 1522 | 1615 |
| 1616 base::RunLoop().RunUntilIdle(); |
| 1617 |
| 1523 // The first request should be a writer at this point, and the two subsequent | 1618 // 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. | 1619 // requests should be pending. The last request doomed the first entry. |
| 1525 | 1620 |
| 1526 EXPECT_EQ(2, cache.network_layer()->transaction_count()); | 1621 EXPECT_EQ(2, cache.network_layer()->transaction_count()); |
| 1527 | 1622 |
| 1528 // Cancel the first queued transaction. | 1623 // Cancel the second transaction. Note that this and the 3rd transactions |
| 1624 // would have completed their headers phase and would be waiting in the |
| 1625 // done_headers_queue when the 2nd transaction is cancelled. |
| 1529 context_list[1].reset(); | 1626 context_list[1].reset(); |
| 1530 | 1627 |
| 1531 for (int i = 0; i < kNumTransactions; ++i) { | 1628 for (int i = 0; i < kNumTransactions; ++i) { |
| 1532 if (i == 1) | 1629 if (i == 1) |
| 1533 continue; | 1630 continue; |
| 1534 Context* c = context_list[i].get(); | 1631 Context* c = context_list[i].get(); |
| 1535 ASSERT_THAT(c->result, IsError(ERR_IO_PENDING)); | 1632 ASSERT_THAT(c->result, IsError(ERR_IO_PENDING)); |
| 1536 c->result = c->callback.WaitForResult(); | 1633 c->result = c->callback.WaitForResult(); |
| 1537 ReadAndVerifyTransaction(c->trans.get(), kSimpleGET_Transaction); | 1634 ReadAndVerifyTransaction(c->trans.get(), kSimpleGET_Transaction); |
| 1538 } | 1635 } |
| (...skipping 21 matching lines...) Expand all Loading... |
| 1560 ASSERT_THAT(c->result, IsOk()); | 1657 ASSERT_THAT(c->result, IsOk()); |
| 1561 | 1658 |
| 1562 c->result = | 1659 c->result = |
| 1563 c->trans->Start(&request, c->callback.callback(), NetLogWithSource()); | 1660 c->trans->Start(&request, c->callback.callback(), NetLogWithSource()); |
| 1564 } | 1661 } |
| 1565 | 1662 |
| 1566 // Allow all requests to move from the Create queue to the active entry. | 1663 // Allow all requests to move from the Create queue to the active entry. |
| 1567 base::RunLoop().RunUntilIdle(); | 1664 base::RunLoop().RunUntilIdle(); |
| 1568 | 1665 |
| 1569 // The first request should be a writer at this point, and the subsequent | 1666 // The first request should be a writer at this point, and the subsequent |
| 1570 // requests should be pending. | 1667 // requests should have completed validation. Since the validation does not |
| 1668 // result in a match, a new entry would be created. |
| 1571 | 1669 |
| 1572 EXPECT_EQ(1, cache.network_layer()->transaction_count()); | 1670 EXPECT_EQ(3, cache.network_layer()->transaction_count()); |
| 1573 EXPECT_EQ(0, cache.disk_cache()->open_count()); | 1671 EXPECT_EQ(0, cache.disk_cache()->open_count()); |
| 1574 EXPECT_EQ(1, cache.disk_cache()->create_count()); | 1672 EXPECT_EQ(2, cache.disk_cache()->create_count()); |
| 1575 | 1673 |
| 1576 // Now, make sure that the second request asks for the entry not to be stored. | 1674 // Now, make sure that the second request asks for the entry not to be stored. |
| 1577 request_handler.set_no_store(true); | 1675 request_handler.set_no_store(true); |
| 1578 | 1676 |
| 1579 for (int i = 0; i < kNumTransactions; ++i) { | 1677 for (int i = 0; i < kNumTransactions; ++i) { |
| 1580 Context* c = context_list[i]; | 1678 Context* c = context_list[i]; |
| 1581 if (c->result == ERR_IO_PENDING) | 1679 if (c->result == ERR_IO_PENDING) |
| 1582 c->result = c->callback.WaitForResult(); | 1680 c->result = c->callback.WaitForResult(); |
| 1583 ReadAndVerifyTransaction(c->trans.get(), kFastNoStoreGET_Transaction); | 1681 ReadAndVerifyTransaction(c->trans.get(), kFastNoStoreGET_Transaction); |
| 1584 delete c; | 1682 delete c; |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1618 | 1716 |
| 1619 EXPECT_EQ(1, cache.network_layer()->transaction_count()); | 1717 EXPECT_EQ(1, cache.network_layer()->transaction_count()); |
| 1620 EXPECT_EQ(0, cache.disk_cache()->open_count()); | 1718 EXPECT_EQ(0, cache.disk_cache()->open_count()); |
| 1621 EXPECT_EQ(1, cache.disk_cache()->create_count()); | 1719 EXPECT_EQ(1, cache.disk_cache()->create_count()); |
| 1622 | 1720 |
| 1623 for (int i = 0; i < kNumTransactions; ++i) { | 1721 for (int i = 0; i < kNumTransactions; ++i) { |
| 1624 Context* c = context_list[i]; | 1722 Context* c = context_list[i]; |
| 1625 if (c->result == ERR_IO_PENDING) | 1723 if (c->result == ERR_IO_PENDING) |
| 1626 c->result = c->callback.WaitForResult(); | 1724 c->result = c->callback.WaitForResult(); |
| 1627 // Destroy only the first transaction. | 1725 // Destroy only the first transaction. |
| 1726 // This should lead to all transactions to restart, even those that have |
| 1727 // validated themselves and were waiting for the writer transaction to |
| 1728 // complete writing to the cache. |
| 1628 if (i == 0) { | 1729 if (i == 0) { |
| 1629 delete c; | 1730 delete c; |
| 1630 context_list[i] = NULL; | 1731 context_list[i] = NULL; |
| 1631 } | 1732 } |
| 1632 } | 1733 } |
| 1633 | 1734 |
| 1634 // Complete the rest of the transactions. | 1735 // Complete the rest of the transactions. |
| 1635 for (int i = 1; i < kNumTransactions; ++i) { | 1736 for (int i = 1; i < kNumTransactions; ++i) { |
| 1636 Context* c = context_list[i]; | 1737 Context* c = context_list[i]; |
| 1637 ReadAndVerifyTransaction(c->trans.get(), kSimpleGET_Transaction); | 1738 ReadAndVerifyTransaction(c->trans.get(), kSimpleGET_Transaction); |
| 1638 } | 1739 } |
| 1639 | 1740 |
| 1640 // We should have had to re-open the disk entry. | 1741 // We should have had to re-open the disk entry. |
| 1641 | 1742 |
| 1642 EXPECT_EQ(2, cache.network_layer()->transaction_count()); | 1743 EXPECT_EQ(2, cache.network_layer()->transaction_count()); |
| 1643 EXPECT_EQ(0, cache.disk_cache()->open_count()); | 1744 EXPECT_EQ(0, cache.disk_cache()->open_count()); |
| 1644 EXPECT_EQ(2, cache.disk_cache()->create_count()); | 1745 EXPECT_EQ(2, cache.disk_cache()->create_count()); |
| 1645 | 1746 |
| 1646 for (int i = 1; i < kNumTransactions; ++i) { | 1747 for (int i = 1; i < kNumTransactions; ++i) { |
| 1647 Context* c = context_list[i]; | 1748 Context* c = context_list[i]; |
| 1648 delete c; | 1749 delete c; |
| 1649 } | 1750 } |
| 1650 } | 1751 } |
| 1651 | 1752 |
| 1753 // Tests that a transaction which is in validated queue can be destroyed without |
| 1754 // any impact to other transactions. |
| 1755 TEST(HttpCache, SimpleGET_ManyWriters_CancelValidated) { |
| 1756 MockHttpCache cache; |
| 1757 |
| 1758 MockHttpRequest request(kSimpleGET_Transaction); |
| 1759 |
| 1760 std::vector<Context*> context_list; |
| 1761 const int kNumTransactions = 2; |
| 1762 |
| 1763 for (int i = 0; i < kNumTransactions; ++i) { |
| 1764 context_list.push_back(new Context()); |
| 1765 Context* c = context_list[i]; |
| 1766 |
| 1767 c->result = cache.CreateTransaction(&c->trans); |
| 1768 ASSERT_THAT(c->result, IsOk()); |
| 1769 |
| 1770 c->result = |
| 1771 c->trans->Start(&request, c->callback.callback(), NetLogWithSource()); |
| 1772 } |
| 1773 |
| 1774 // Allow all requests to move from the Create queue to the active entry. |
| 1775 base::RunLoop().RunUntilIdle(); |
| 1776 |
| 1777 // The first request should be a writer at this point, and the subsequent |
| 1778 // requests should be pending. |
| 1779 |
| 1780 EXPECT_EQ(1, cache.network_layer()->transaction_count()); |
| 1781 EXPECT_EQ(0, cache.disk_cache()->open_count()); |
| 1782 EXPECT_EQ(1, cache.disk_cache()->create_count()); |
| 1783 |
| 1784 for (int i = 0; i < kNumTransactions; ++i) { |
| 1785 Context* c = context_list[i]; |
| 1786 if (i == 0 && c->result == ERR_IO_PENDING) |
| 1787 c->result = c->callback.WaitForResult(); |
| 1788 // Destroy one of the transactions waiting after the validated stage. |
| 1789 if (i == 1) { |
| 1790 delete c; |
| 1791 context_list[i] = NULL; |
| 1792 } |
| 1793 } |
| 1794 |
| 1795 // Complete the rest of the transactions. |
| 1796 for (int i = 0; i < kNumTransactions; ++i) { |
| 1797 if (i == 1) |
| 1798 continue; |
| 1799 Context* c = context_list[i]; |
| 1800 ReadAndVerifyTransaction(c->trans.get(), kSimpleGET_Transaction); |
| 1801 } |
| 1802 |
| 1803 // We should have had to re-open the disk entry. |
| 1804 |
| 1805 EXPECT_EQ(1, cache.network_layer()->transaction_count()); |
| 1806 EXPECT_EQ(0, cache.disk_cache()->open_count()); |
| 1807 EXPECT_EQ(1, cache.disk_cache()->create_count()); |
| 1808 |
| 1809 for (int i = 0; i < kNumTransactions; ++i) { |
| 1810 if (i == 1) |
| 1811 continue; |
| 1812 Context* c = context_list[i]; |
| 1813 delete c; |
| 1814 } |
| 1815 } |
| 1816 |
| 1817 // Tests that a transaction which is currently validating can be destroyed |
| 1818 // without any impact to other transactions. |
| 1819 TEST(HttpCache, SimpleGET_ManyWriters_CancelValidating) { |
| 1820 MockHttpCache cache; |
| 1821 |
| 1822 MockHttpRequest request(kSimpleGET_Transaction); |
| 1823 |
| 1824 std::vector<Context*> context_list; |
| 1825 const int kNumTransactions = 2; |
| 1826 |
| 1827 for (int i = 0; i < kNumTransactions; ++i) { |
| 1828 context_list.push_back(new Context()); |
| 1829 Context* c = context_list[i]; |
| 1830 |
| 1831 c->result = cache.CreateTransaction(&c->trans); |
| 1832 ASSERT_THAT(c->result, IsOk()); |
| 1833 |
| 1834 c->result = |
| 1835 c->trans->Start(&request, c->callback.callback(), NetLogWithSource()); |
| 1836 } |
| 1837 |
| 1838 // Delete the currently validating transaction. |
| 1839 Context* c = context_list[1]; |
| 1840 EXPECT_EQ(ERR_IO_PENDING, c->result); |
| 1841 delete c; |
| 1842 context_list[1] = nullptr; |
| 1843 |
| 1844 // Allow all requests to move from the Create queue to the active entry. |
| 1845 base::RunLoop().RunUntilIdle(); |
| 1846 |
| 1847 // The first request should be a writer at this point, and the subsequent |
| 1848 // requests should be pending. |
| 1849 |
| 1850 EXPECT_EQ(1, cache.network_layer()->transaction_count()); |
| 1851 EXPECT_EQ(0, cache.disk_cache()->open_count()); |
| 1852 EXPECT_EQ(1, cache.disk_cache()->create_count()); |
| 1853 |
| 1854 for (int i = 0; i < kNumTransactions; ++i) { |
| 1855 if (i == 1) |
| 1856 continue; |
| 1857 Context* c = context_list[i]; |
| 1858 if (c->result == ERR_IO_PENDING) |
| 1859 c->result = c->callback.WaitForResult(); |
| 1860 } |
| 1861 |
| 1862 // Complete the rest of the transactions. |
| 1863 for (int i = 0; i < kNumTransactions; ++i) { |
| 1864 if (i == 1) |
| 1865 continue; |
| 1866 Context* c = context_list[i]; |
| 1867 ReadAndVerifyTransaction(c->trans.get(), kSimpleGET_Transaction); |
| 1868 } |
| 1869 |
| 1870 // We should have had to re-open the disk entry. |
| 1871 |
| 1872 EXPECT_EQ(1, cache.network_layer()->transaction_count()); |
| 1873 EXPECT_EQ(0, cache.disk_cache()->open_count()); |
| 1874 EXPECT_EQ(1, cache.disk_cache()->create_count()); |
| 1875 |
| 1876 for (int i = 0; i < kNumTransactions; ++i) { |
| 1877 if (i == 1) |
| 1878 continue; |
| 1879 Context* c = context_list[i]; |
| 1880 delete c; |
| 1881 } |
| 1882 } |
| 1883 |
| 1652 // Tests that we can cancel requests that are queued waiting to open the disk | 1884 // Tests that we can cancel requests that are queued waiting to open the disk |
| 1653 // cache entry. | 1885 // cache entry. |
| 1654 TEST(HttpCache, SimpleGET_ManyWriters_CancelCreate) { | 1886 TEST(HttpCache, SimpleGET_ManyWriters_CancelCreate) { |
| 1655 MockHttpCache cache; | 1887 MockHttpCache cache; |
| 1656 | 1888 |
| 1657 MockHttpRequest request(kSimpleGET_Transaction); | 1889 MockHttpRequest request(kSimpleGET_Transaction); |
| 1658 | 1890 |
| 1659 std::vector<Context*> context_list; | 1891 std::vector<Context*> context_list; |
| 1660 const int kNumTransactions = 5; | 1892 const int kNumTransactions = 5; |
| 1661 | 1893 |
| (...skipping 871 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2533 } | 2765 } |
| 2534 | 2766 |
| 2535 // Helper that does 4 requests using HttpCache: | 2767 // Helper that does 4 requests using HttpCache: |
| 2536 // | 2768 // |
| 2537 // (1) loads |kUrl| -- expects |net_response_1| to be returned. | 2769 // (1) loads |kUrl| -- expects |net_response_1| to be returned. |
| 2538 // (2) loads |kUrl| from cache only -- expects |net_response_1| to be returned. | 2770 // (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 | 2771 // (3) loads |kUrl| using |extra_request_headers| -- expects |net_response_2| to |
| 2540 // be returned. | 2772 // be returned. |
| 2541 // (4) loads |kUrl| from cache only -- expects |cached_response_2| to be | 2773 // (4) loads |kUrl| from cache only -- expects |cached_response_2| to be |
| 2542 // returned. | 2774 // returned. |
| 2775 // The entry will be created once and will be opened for the 3 subsequent |
| 2776 // requests. |
| 2543 static void ConditionalizedRequestUpdatesCacheHelper( | 2777 static void ConditionalizedRequestUpdatesCacheHelper( |
| 2544 const Response& net_response_1, | 2778 const Response& net_response_1, |
| 2545 const Response& net_response_2, | 2779 const Response& net_response_2, |
| 2546 const Response& cached_response_2, | 2780 const Response& cached_response_2, |
| 2547 const char* extra_request_headers) { | 2781 const char* extra_request_headers) { |
| 2548 MockHttpCache cache; | 2782 MockHttpCache cache; |
| 2549 | 2783 |
| 2550 // The URL we will be requesting. | 2784 // The URL we will be requesting. |
| 2551 const char kUrl[] = "http://foobar.com/main.css"; | 2785 const char kUrl[] = "http://foobar.com/main.css"; |
| 2552 | 2786 |
| (...skipping 3555 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6108 pending->trans->Start(&request, pending->callback.callback(), | 6342 pending->trans->Start(&request, pending->callback.callback(), |
| 6109 NetLogWithSource())); | 6343 NetLogWithSource())); |
| 6110 EXPECT_THAT(c->callback.GetResult(rv), IsOk()); | 6344 EXPECT_THAT(c->callback.GetResult(rv), IsOk()); |
| 6111 | 6345 |
| 6112 // Make sure that the entry has some data stored. | 6346 // Make sure that the entry has some data stored. |
| 6113 scoped_refptr<IOBufferWithSize> buf(new IOBufferWithSize(5)); | 6347 scoped_refptr<IOBufferWithSize> buf(new IOBufferWithSize(5)); |
| 6114 rv = c->trans->Read(buf.get(), buf->size(), c->callback.callback()); | 6348 rv = c->trans->Read(buf.get(), buf->size(), c->callback.callback()); |
| 6115 EXPECT_EQ(5, c->callback.GetResult(rv)); | 6349 EXPECT_EQ(5, c->callback.GetResult(rv)); |
| 6116 | 6350 |
| 6117 // Cancel the requests. | 6351 // Cancel the requests. |
| 6352 // Since |pending| is currently vaidating the already written headers |
| 6353 // it will be restarted as well. |
| 6118 delete c; | 6354 delete c; |
| 6119 delete pending; | 6355 delete pending; |
| 6120 | 6356 |
| 6121 EXPECT_EQ(1, cache.network_layer()->transaction_count()); | 6357 EXPECT_EQ(1, cache.network_layer()->transaction_count()); |
| 6122 EXPECT_EQ(1, cache.disk_cache()->open_count()); | 6358 EXPECT_EQ(1, cache.disk_cache()->open_count()); |
| 6123 EXPECT_EQ(2, cache.disk_cache()->create_count()); | 6359 EXPECT_EQ(1, cache.disk_cache()->create_count()); |
| 6124 | 6360 |
| 6125 base::RunLoop().RunUntilIdle(); | 6361 base::RunLoop().RunUntilIdle(); |
| 6126 RemoveMockTransaction(&transaction); | 6362 RemoveMockTransaction(&transaction); |
| 6127 } | 6363 } |
| 6128 | 6364 |
| 6129 // Tests that we delete truncated entries if the server changes its mind midway. | 6365 // Tests that we delete truncated entries if the server changes its mind midway. |
| 6130 TEST(HttpCache, GET_IncompleteResource2) { | 6366 TEST(HttpCache, GET_IncompleteResource2) { |
| 6131 MockHttpCache cache; | 6367 MockHttpCache cache; |
| 6132 AddMockTransaction(&kRangeGET_TransactionOK); | 6368 AddMockTransaction(&kRangeGET_TransactionOK); |
| 6133 | 6369 |
| (...skipping 704 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6838 | 7074 |
| 6839 RunTransactionTestWithResponseInfo(cache.http_cache(), kSimpleGET_Transaction, | 7075 RunTransactionTestWithResponseInfo(cache.http_cache(), kSimpleGET_Transaction, |
| 6840 &response); | 7076 &response); |
| 6841 EXPECT_TRUE(response.metadata.get() == NULL); | 7077 EXPECT_TRUE(response.metadata.get() == NULL); |
| 6842 | 7078 |
| 6843 EXPECT_EQ(1, cache.network_layer()->transaction_count()); | 7079 EXPECT_EQ(1, cache.network_layer()->transaction_count()); |
| 6844 EXPECT_EQ(2, cache.disk_cache()->open_count()); | 7080 EXPECT_EQ(2, cache.disk_cache()->open_count()); |
| 6845 EXPECT_EQ(1, cache.disk_cache()->create_count()); | 7081 EXPECT_EQ(1, cache.disk_cache()->create_count()); |
| 6846 } | 7082 } |
| 6847 | 7083 |
| 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 | 7084 // Tests that we ignore VARY checks when writing metadata since the request |
| 6889 // headers for the WriteMetadata transaction are made up. | 7085 // headers for the WriteMetadata transaction are made up. |
| 6890 TEST(HttpCache, WriteMetadata_IgnoreVary) { | 7086 TEST(HttpCache, WriteMetadata_IgnoreVary) { |
| 6891 MockHttpCache cache; | 7087 MockHttpCache cache; |
| 6892 | 7088 |
| 6893 // Write to the cache | 7089 // Write to the cache |
| 6894 HttpResponseInfo response; | 7090 HttpResponseInfo response; |
| 6895 ScopedMockTransaction transaction(kSimpleGET_Transaction); | 7091 ScopedMockTransaction transaction(kSimpleGET_Transaction); |
| 6896 transaction.request_headers = "accept-encoding: gzip\r\n"; | 7092 transaction.request_headers = "accept-encoding: gzip\r\n"; |
| 6897 transaction.response_headers = | 7093 transaction.response_headers = |
| (...skipping 307 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7205 MockHttpRequest request(mock_transaction); | 7401 MockHttpRequest request(mock_transaction); |
| 7206 | 7402 |
| 7207 { | 7403 { |
| 7208 std::unique_ptr<HttpTransaction> trans; | 7404 std::unique_ptr<HttpTransaction> trans; |
| 7209 ASSERT_THAT(cache.CreateTransaction(&trans), IsOk()); | 7405 ASSERT_THAT(cache.CreateTransaction(&trans), IsOk()); |
| 7210 | 7406 |
| 7211 int rv = trans->Start(&request, callback.callback(), NetLogWithSource()); | 7407 int rv = trans->Start(&request, callback.callback(), NetLogWithSource()); |
| 7212 EXPECT_THAT(callback.GetResult(rv), IsOk()); | 7408 EXPECT_THAT(callback.GetResult(rv), IsOk()); |
| 7213 | 7409 |
| 7214 trans->StopCaching(); | 7410 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 } | 7411 } |
| 7220 RemoveMockTransaction(&mock_transaction); | 7412 RemoveMockTransaction(&mock_transaction); |
| 7221 | 7413 |
| 7222 // Make sure that the ActiveEntry is gone. | 7414 // Make sure that the ActiveEntry is gone. |
| 7223 base::RunLoop().RunUntilIdle(); | 7415 base::RunLoop().RunUntilIdle(); |
| 7224 | 7416 |
| 7225 // Verify that the entry is gone. | 7417 // Verify that the entry is gone. |
| 7226 RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction); | 7418 RunTransactionTest(cache.http_cache(), kSimpleGET_Transaction); |
| 7227 | 7419 |
| 7228 EXPECT_EQ(2, cache.network_layer()->transaction_count()); | 7420 EXPECT_EQ(2, cache.network_layer()->transaction_count()); |
| (...skipping 1173 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 8402 ASSERT_TRUE(attrs->GetDictionary( | 8594 ASSERT_TRUE(attrs->GetDictionary( |
| 8403 base::trace_event::MemoryAllocatorDump::kNameSize, &size_attrs)); | 8595 base::trace_event::MemoryAllocatorDump::kNameSize, &size_attrs)); |
| 8404 std::string size; | 8596 std::string size; |
| 8405 ASSERT_TRUE(size_attrs->GetString("value", &size)); | 8597 ASSERT_TRUE(size_attrs->GetString("value", &size)); |
| 8406 int actual_size = 0; | 8598 int actual_size = 0; |
| 8407 ASSERT_TRUE(base::HexStringToInt(size, &actual_size)); | 8599 ASSERT_TRUE(base::HexStringToInt(size, &actual_size)); |
| 8408 ASSERT_LT(0, actual_size); | 8600 ASSERT_LT(0, actual_size); |
| 8409 } | 8601 } |
| 8410 | 8602 |
| 8411 } // namespace net | 8603 } // namespace net |
| OLD | NEW |