OLD | NEW |
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 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 "base/basictypes.h" | 5 #include "base/basictypes.h" |
6 #include "base/file_util.h" | 6 #include "base/file_util.h" |
7 #include "base/string_util.h" | 7 #include "base/string_util.h" |
8 #include "base/stringprintf.h" | 8 #include "base/stringprintf.h" |
9 #include "base/third_party/dynamic_annotations/dynamic_annotations.h" | 9 #include "base/third_party/dynamic_annotations/dynamic_annotations.h" |
10 #include "base/threading/platform_thread.h" | 10 #include "base/threading/platform_thread.h" |
11 #include "net/base/io_buffer.h" | 11 #include "net/base/io_buffer.h" |
12 #include "net/base/net_errors.h" | 12 #include "net/base/net_errors.h" |
13 #include "net/base/test_completion_callback.h" | 13 #include "net/base/test_completion_callback.h" |
14 #include "net/disk_cache/backend_impl.h" | 14 #include "net/disk_cache/backend_impl.h" |
15 #include "net/disk_cache/cache_util.h" | 15 #include "net/disk_cache/cache_util.h" |
16 #include "net/disk_cache/disk_cache_test_base.h" | 16 #include "net/disk_cache/disk_cache_test_base.h" |
17 #include "net/disk_cache/disk_cache_test_util.h" | 17 #include "net/disk_cache/disk_cache_test_util.h" |
| 18 #include "net/disk_cache/entry_impl.h" |
18 #include "net/disk_cache/histogram_macros.h" | 19 #include "net/disk_cache/histogram_macros.h" |
19 #include "net/disk_cache/mapped_file.h" | 20 #include "net/disk_cache/mapped_file.h" |
20 #include "net/disk_cache/mem_backend_impl.h" | 21 #include "net/disk_cache/mem_backend_impl.h" |
21 #include "testing/gtest/include/gtest/gtest.h" | 22 #include "testing/gtest/include/gtest/gtest.h" |
22 | 23 |
23 #if defined(OS_WIN) | 24 #if defined(OS_WIN) |
24 #include "base/win/scoped_handle.h" | 25 #include "base/win/scoped_handle.h" |
25 #endif | 26 #endif |
26 | 27 |
27 using base::Time; | 28 using base::Time; |
(...skipping 16 matching lines...) Expand all Loading... |
44 void BackendInvalidEntryEnumeration(); | 45 void BackendInvalidEntryEnumeration(); |
45 void BackendFixEnumerators(); | 46 void BackendFixEnumerators(); |
46 void BackendDoomRecent(); | 47 void BackendDoomRecent(); |
47 void BackendDoomBetween(); | 48 void BackendDoomBetween(); |
48 void BackendTransaction(const std::string& name, int num_entries, bool load); | 49 void BackendTransaction(const std::string& name, int num_entries, bool load); |
49 void BackendRecoverInsert(); | 50 void BackendRecoverInsert(); |
50 void BackendRecoverRemove(); | 51 void BackendRecoverRemove(); |
51 void BackendRecoverWithEviction(); | 52 void BackendRecoverWithEviction(); |
52 void BackendInvalidEntry2(); | 53 void BackendInvalidEntry2(); |
53 void BackendInvalidEntry3(); | 54 void BackendInvalidEntry3(); |
| 55 void BackendInvalidEntry7(); |
| 56 void BackendInvalidEntry8(); |
| 57 void BackendInvalidEntry9(bool eviction); |
| 58 void BackendInvalidEntry10(bool eviction); |
| 59 void BackendInvalidEntry11(bool eviction); |
| 60 void BackendTrimInvalidEntry12(); |
54 void BackendNotMarkedButDirty(const std::string& name); | 61 void BackendNotMarkedButDirty(const std::string& name); |
55 void BackendDoomAll(); | 62 void BackendDoomAll(); |
56 void BackendDoomAll2(); | 63 void BackendDoomAll2(); |
57 void BackendInvalidRankings(); | 64 void BackendInvalidRankings(); |
58 void BackendInvalidRankings2(); | 65 void BackendInvalidRankings2(); |
59 void BackendDisable(); | 66 void BackendDisable(); |
60 void BackendDisable2(); | 67 void BackendDisable2(); |
61 void BackendDisable3(); | 68 void BackendDisable3(); |
62 void BackendDisable4(); | 69 void BackendDisable4(); |
63 }; | 70 }; |
(...skipping 1428 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1492 | 1499 |
1493 // This should not delete the cache. | 1500 // This should not delete the cache. |
1494 entry->Doom(); | 1501 entry->Doom(); |
1495 FlushQueueForTest(); | 1502 FlushQueueForTest(); |
1496 entry->Close(); | 1503 entry->Close(); |
1497 | 1504 |
1498 ASSERT_EQ(net::OK, OpenEntry("some other key", &entry)); | 1505 ASSERT_EQ(net::OK, OpenEntry("some other key", &entry)); |
1499 entry->Close(); | 1506 entry->Close(); |
1500 } | 1507 } |
1501 | 1508 |
| 1509 // Tests handling of corrupt entries by keeping the rankings node around, with |
| 1510 // a fatal failure. |
| 1511 void DiskCacheBackendTest::BackendInvalidEntry7() { |
| 1512 SetDirectMode(); |
| 1513 const int kSize = 0x3000; // 12 kB. |
| 1514 SetMaxSize(kSize * 10); |
| 1515 InitCache(); |
| 1516 |
| 1517 std::string first("some key"); |
| 1518 std::string second("something else"); |
| 1519 disk_cache::Entry* entry; |
| 1520 ASSERT_EQ(net::OK, CreateEntry(first, &entry)); |
| 1521 entry->Close(); |
| 1522 ASSERT_EQ(net::OK, CreateEntry(second, &entry)); |
| 1523 |
| 1524 // Corrupt this entry. |
| 1525 disk_cache::EntryImpl* entry_impl = |
| 1526 static_cast<disk_cache::EntryImpl*>(entry); |
| 1527 |
| 1528 entry_impl->rankings()->Data()->next = 0; |
| 1529 entry_impl->rankings()->Store(); |
| 1530 entry->Close(); |
| 1531 FlushQueueForTest(); |
| 1532 EXPECT_EQ(2, cache_->GetEntryCount()); |
| 1533 |
| 1534 // This should detect the bad entry. |
| 1535 EXPECT_NE(net::OK, OpenEntry(second, &entry)); |
| 1536 EXPECT_EQ(1, cache_->GetEntryCount()); |
| 1537 |
| 1538 // We should delete the cache. The list still has a corrupt node. |
| 1539 void* iter = NULL; |
| 1540 EXPECT_NE(net::OK, OpenNextEntry(&iter, &entry)); |
| 1541 EXPECT_EQ(0, cache_->GetEntryCount()); |
| 1542 } |
| 1543 |
| 1544 TEST_F(DiskCacheBackendTest, InvalidEntry7) { |
| 1545 BackendInvalidEntry7(); |
| 1546 } |
| 1547 |
| 1548 TEST_F(DiskCacheBackendTest, NewEvictionInvalidEntry7) { |
| 1549 SetNewEviction(); |
| 1550 BackendInvalidEntry7(); |
| 1551 } |
| 1552 |
| 1553 // Tests handling of corrupt entries by keeping the rankings node around, with |
| 1554 // a non fatal failure. |
| 1555 void DiskCacheBackendTest::BackendInvalidEntry8() { |
| 1556 SetDirectMode(); |
| 1557 const int kSize = 0x3000; // 12 kB |
| 1558 SetMaxSize(kSize * 10); |
| 1559 InitCache(); |
| 1560 |
| 1561 std::string first("some key"); |
| 1562 std::string second("something else"); |
| 1563 disk_cache::Entry* entry; |
| 1564 ASSERT_EQ(net::OK, CreateEntry(first, &entry)); |
| 1565 entry->Close(); |
| 1566 ASSERT_EQ(net::OK, CreateEntry(second, &entry)); |
| 1567 |
| 1568 // Corrupt this entry. |
| 1569 disk_cache::EntryImpl* entry_impl = |
| 1570 static_cast<disk_cache::EntryImpl*>(entry); |
| 1571 |
| 1572 entry_impl->rankings()->Data()->contents = 0; |
| 1573 entry_impl->rankings()->Store(); |
| 1574 entry->Close(); |
| 1575 FlushQueueForTest(); |
| 1576 EXPECT_EQ(2, cache_->GetEntryCount()); |
| 1577 |
| 1578 // This should detect the bad entry. |
| 1579 EXPECT_NE(net::OK, OpenEntry(second, &entry)); |
| 1580 EXPECT_EQ(1, cache_->GetEntryCount()); |
| 1581 |
| 1582 // We should not delete the cache. |
| 1583 void* iter = NULL; |
| 1584 ASSERT_EQ(net::OK, OpenNextEntry(&iter, &entry)); |
| 1585 entry->Close(); |
| 1586 EXPECT_NE(net::OK, OpenNextEntry(&iter, &entry)); |
| 1587 EXPECT_EQ(1, cache_->GetEntryCount()); |
| 1588 } |
| 1589 |
| 1590 TEST_F(DiskCacheBackendTest, InvalidEntry8) { |
| 1591 BackendInvalidEntry8(); |
| 1592 } |
| 1593 |
| 1594 TEST_F(DiskCacheBackendTest, NewEvictionInvalidEntry8) { |
| 1595 SetNewEviction(); |
| 1596 BackendInvalidEntry8(); |
| 1597 } |
| 1598 |
| 1599 // Tests handling of corrupt entries detected by enumerations. Note that these |
| 1600 // tests (xx9 to xx11) are basically just going though slightly different |
| 1601 // codepaths so they are tighlty coupled with the code, but that is better than |
| 1602 // not testing error handling code. |
| 1603 void DiskCacheBackendTest::BackendInvalidEntry9(bool eviction) { |
| 1604 SetDirectMode(); |
| 1605 const int kSize = 0x3000; // 12 kB. |
| 1606 SetMaxSize(kSize * 10); |
| 1607 InitCache(); |
| 1608 |
| 1609 std::string first("some key"); |
| 1610 std::string second("something else"); |
| 1611 disk_cache::Entry* entry; |
| 1612 ASSERT_EQ(net::OK, CreateEntry(first, &entry)); |
| 1613 entry->Close(); |
| 1614 ASSERT_EQ(net::OK, CreateEntry(second, &entry)); |
| 1615 |
| 1616 // Corrupt this entry. |
| 1617 disk_cache::EntryImpl* entry_impl = |
| 1618 static_cast<disk_cache::EntryImpl*>(entry); |
| 1619 |
| 1620 entry_impl->entry()->Data()->state = 0xbad; |
| 1621 entry_impl->entry()->Store(); |
| 1622 entry->Close(); |
| 1623 FlushQueueForTest(); |
| 1624 EXPECT_EQ(2, cache_->GetEntryCount()); |
| 1625 |
| 1626 if (eviction) { |
| 1627 TrimForTest(false); |
| 1628 EXPECT_EQ(1, cache_->GetEntryCount()); |
| 1629 TrimForTest(false); |
| 1630 EXPECT_EQ(1, cache_->GetEntryCount()); |
| 1631 } else { |
| 1632 // We should detect the problem through the list, but we should not delete |
| 1633 // the entry, just fail the iteration. |
| 1634 void* iter = NULL; |
| 1635 EXPECT_NE(net::OK, OpenNextEntry(&iter, &entry)); |
| 1636 |
| 1637 // Now a full iteration will work, and return one entry. |
| 1638 ASSERT_EQ(net::OK, OpenNextEntry(&iter, &entry)); |
| 1639 entry->Close(); |
| 1640 EXPECT_NE(net::OK, OpenNextEntry(&iter, &entry)); |
| 1641 |
| 1642 // This should detect what's left of the bad entry. |
| 1643 EXPECT_NE(net::OK, OpenEntry(second, &entry)); |
| 1644 EXPECT_EQ(2, cache_->GetEntryCount()); |
| 1645 } |
| 1646 DisableIntegrityCheck(); |
| 1647 } |
| 1648 |
| 1649 TEST_F(DiskCacheBackendTest, InvalidEntry9) { |
| 1650 BackendInvalidEntry9(false); |
| 1651 } |
| 1652 |
| 1653 TEST_F(DiskCacheBackendTest, NewEvictionInvalidEntry9) { |
| 1654 SetNewEviction(); |
| 1655 BackendInvalidEntry9(false); |
| 1656 } |
| 1657 |
| 1658 TEST_F(DiskCacheBackendTest, TrimInvalidEntry9) { |
| 1659 BackendInvalidEntry9(true); |
| 1660 } |
| 1661 |
| 1662 TEST_F(DiskCacheBackendTest, NewEvictionTrimInvalidEntry9) { |
| 1663 SetNewEviction(); |
| 1664 BackendInvalidEntry9(true); |
| 1665 } |
| 1666 |
| 1667 // Tests handling of corrupt entries detected by enumerations. |
| 1668 void DiskCacheBackendTest::BackendInvalidEntry10(bool eviction) { |
| 1669 SetDirectMode(); |
| 1670 const int kSize = 0x3000; // 12 kB. |
| 1671 SetMaxSize(kSize * 10); |
| 1672 SetNewEviction(); |
| 1673 InitCache(); |
| 1674 |
| 1675 std::string first("some key"); |
| 1676 std::string second("something else"); |
| 1677 disk_cache::Entry* entry; |
| 1678 ASSERT_EQ(net::OK, CreateEntry(first, &entry)); |
| 1679 entry->Close(); |
| 1680 ASSERT_EQ(net::OK, OpenEntry(first, &entry)); |
| 1681 EXPECT_EQ(0, WriteData(entry, 0, 200, NULL, 0, false)); |
| 1682 entry->Close(); |
| 1683 ASSERT_EQ(net::OK, CreateEntry(second, &entry)); |
| 1684 |
| 1685 // Corrupt this entry. |
| 1686 disk_cache::EntryImpl* entry_impl = |
| 1687 static_cast<disk_cache::EntryImpl*>(entry); |
| 1688 |
| 1689 entry_impl->entry()->Data()->state = 0xbad; |
| 1690 entry_impl->entry()->Store(); |
| 1691 entry->Close(); |
| 1692 ASSERT_EQ(net::OK, CreateEntry("third", &entry)); |
| 1693 entry->Close(); |
| 1694 EXPECT_EQ(3, cache_->GetEntryCount()); |
| 1695 |
| 1696 // We have: |
| 1697 // List 0: third -> second (bad). |
| 1698 // List 1: first. |
| 1699 |
| 1700 if (eviction) { |
| 1701 // Detection order: second -> first -> third. |
| 1702 TrimForTest(false); |
| 1703 EXPECT_EQ(3, cache_->GetEntryCount()); |
| 1704 TrimForTest(false); |
| 1705 EXPECT_EQ(2, cache_->GetEntryCount()); |
| 1706 TrimForTest(false); |
| 1707 EXPECT_EQ(1, cache_->GetEntryCount()); |
| 1708 } else { |
| 1709 // Detection order: third -> second -> first. |
| 1710 // We should detect the problem through the list, but we should not delete |
| 1711 // the entry. |
| 1712 void* iter = NULL; |
| 1713 ASSERT_EQ(net::OK, OpenNextEntry(&iter, &entry)); |
| 1714 entry->Close(); |
| 1715 ASSERT_EQ(net::OK, OpenNextEntry(&iter, &entry)); |
| 1716 EXPECT_EQ(first, entry->GetKey()); |
| 1717 entry->Close(); |
| 1718 EXPECT_NE(net::OK, OpenNextEntry(&iter, &entry)); |
| 1719 } |
| 1720 DisableIntegrityCheck(); |
| 1721 } |
| 1722 |
| 1723 TEST_F(DiskCacheBackendTest, InvalidEntry10) { |
| 1724 BackendInvalidEntry10(false); |
| 1725 } |
| 1726 |
| 1727 TEST_F(DiskCacheBackendTest, TrimInvalidEntry10) { |
| 1728 BackendInvalidEntry10(true); |
| 1729 } |
| 1730 |
| 1731 // Tests handling of corrupt entries detected by enumerations. |
| 1732 void DiskCacheBackendTest::BackendInvalidEntry11(bool eviction) { |
| 1733 SetDirectMode(); |
| 1734 const int kSize = 0x3000; // 12 kB. |
| 1735 SetMaxSize(kSize * 10); |
| 1736 SetNewEviction(); |
| 1737 InitCache(); |
| 1738 |
| 1739 std::string first("some key"); |
| 1740 std::string second("something else"); |
| 1741 disk_cache::Entry* entry; |
| 1742 ASSERT_EQ(net::OK, CreateEntry(first, &entry)); |
| 1743 entry->Close(); |
| 1744 ASSERT_EQ(net::OK, OpenEntry(first, &entry)); |
| 1745 EXPECT_EQ(0, WriteData(entry, 0, 200, NULL, 0, false)); |
| 1746 entry->Close(); |
| 1747 ASSERT_EQ(net::OK, CreateEntry(second, &entry)); |
| 1748 entry->Close(); |
| 1749 ASSERT_EQ(net::OK, OpenEntry(second, &entry)); |
| 1750 EXPECT_EQ(0, WriteData(entry, 0, 200, NULL, 0, false)); |
| 1751 |
| 1752 // Corrupt this entry. |
| 1753 disk_cache::EntryImpl* entry_impl = |
| 1754 static_cast<disk_cache::EntryImpl*>(entry); |
| 1755 |
| 1756 entry_impl->entry()->Data()->state = 0xbad; |
| 1757 entry_impl->entry()->Store(); |
| 1758 entry->Close(); |
| 1759 ASSERT_EQ(net::OK, CreateEntry("third", &entry)); |
| 1760 entry->Close(); |
| 1761 FlushQueueForTest(); |
| 1762 EXPECT_EQ(3, cache_->GetEntryCount()); |
| 1763 |
| 1764 // We have: |
| 1765 // List 0: third. |
| 1766 // List 1: second (bad) -> first. |
| 1767 |
| 1768 if (eviction) { |
| 1769 // Detection order: third -> first -> second. |
| 1770 TrimForTest(false); |
| 1771 EXPECT_EQ(2, cache_->GetEntryCount()); |
| 1772 TrimForTest(false); |
| 1773 EXPECT_EQ(1, cache_->GetEntryCount()); |
| 1774 TrimForTest(false); |
| 1775 EXPECT_EQ(1, cache_->GetEntryCount()); |
| 1776 } else { |
| 1777 // Detection order: third -> second. |
| 1778 // We should detect the problem through the list, but we should not delete |
| 1779 // the entry, just fail the iteration. |
| 1780 void* iter = NULL; |
| 1781 ASSERT_EQ(net::OK, OpenNextEntry(&iter, &entry)); |
| 1782 entry->Close(); |
| 1783 EXPECT_NE(net::OK, OpenNextEntry(&iter, &entry)); |
| 1784 |
| 1785 // Now a full iteration will work, and return two entries. |
| 1786 ASSERT_EQ(net::OK, OpenNextEntry(&iter, &entry)); |
| 1787 entry->Close(); |
| 1788 ASSERT_EQ(net::OK, OpenNextEntry(&iter, &entry)); |
| 1789 entry->Close(); |
| 1790 EXPECT_NE(net::OK, OpenNextEntry(&iter, &entry)); |
| 1791 } |
| 1792 DisableIntegrityCheck(); |
| 1793 } |
| 1794 |
| 1795 TEST_F(DiskCacheBackendTest, InvalidEntry11) { |
| 1796 BackendInvalidEntry11(false); |
| 1797 } |
| 1798 |
| 1799 TEST_F(DiskCacheBackendTest, TrimInvalidEntry11) { |
| 1800 BackendInvalidEntry11(true); |
| 1801 } |
| 1802 |
| 1803 // Tests handling of corrupt entries in the middle of a long eviction run. |
| 1804 void DiskCacheBackendTest::BackendTrimInvalidEntry12() { |
| 1805 SetDirectMode(); |
| 1806 const int kSize = 0x3000; // 12 kB |
| 1807 SetMaxSize(kSize * 10); |
| 1808 InitCache(); |
| 1809 |
| 1810 std::string first("some key"); |
| 1811 std::string second("something else"); |
| 1812 disk_cache::Entry* entry; |
| 1813 ASSERT_EQ(net::OK, CreateEntry(first, &entry)); |
| 1814 entry->Close(); |
| 1815 ASSERT_EQ(net::OK, CreateEntry(second, &entry)); |
| 1816 |
| 1817 // Corrupt this entry. |
| 1818 disk_cache::EntryImpl* entry_impl = |
| 1819 static_cast<disk_cache::EntryImpl*>(entry); |
| 1820 |
| 1821 entry_impl->entry()->Data()->state = 0xbad; |
| 1822 entry_impl->entry()->Store(); |
| 1823 entry->Close(); |
| 1824 ASSERT_EQ(net::OK, CreateEntry("third", &entry)); |
| 1825 entry->Close(); |
| 1826 ASSERT_EQ(net::OK, CreateEntry("fourth", &entry)); |
| 1827 TrimForTest(true); |
| 1828 EXPECT_EQ(1, cache_->GetEntryCount()); |
| 1829 entry->Close(); |
| 1830 DisableIntegrityCheck(); |
| 1831 } |
| 1832 |
| 1833 TEST_F(DiskCacheBackendTest, TrimInvalidEntry12) { |
| 1834 BackendTrimInvalidEntry12(); |
| 1835 } |
| 1836 |
| 1837 TEST_F(DiskCacheBackendTest, NewEvictionTrimInvalidEntry12) { |
| 1838 SetNewEviction(); |
| 1839 BackendTrimInvalidEntry12(); |
| 1840 } |
| 1841 |
1502 // We want to be able to deal with abnormal dirty entries. | 1842 // We want to be able to deal with abnormal dirty entries. |
1503 void DiskCacheBackendTest::BackendNotMarkedButDirty(const std::string& name) { | 1843 void DiskCacheBackendTest::BackendNotMarkedButDirty(const std::string& name) { |
1504 ASSERT_TRUE(CopyTestCache(name)); | 1844 ASSERT_TRUE(CopyTestCache(name)); |
1505 DisableFirstCleanup(); | 1845 DisableFirstCleanup(); |
1506 InitCache(); | 1846 InitCache(); |
1507 | 1847 |
1508 disk_cache::Entry *entry1, *entry2; | 1848 disk_cache::Entry *entry1, *entry2; |
1509 ASSERT_EQ(net::OK, OpenEntry("the first key", &entry1)); | 1849 ASSERT_EQ(net::OK, OpenEntry("the first key", &entry1)); |
1510 EXPECT_NE(net::OK, OpenEntry("some other key", &entry2)); | 1850 EXPECT_NE(net::OK, OpenEntry("some other key", &entry2)); |
1511 entry1->Close(); | 1851 entry1->Close(); |
(...skipping 621 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2133 // Ping the oldest entry. | 2473 // Ping the oldest entry. |
2134 cache_->OnExternalCacheHit("key0"); | 2474 cache_->OnExternalCacheHit("key0"); |
2135 | 2475 |
2136 TrimForTest(false); | 2476 TrimForTest(false); |
2137 | 2477 |
2138 // Make sure the older key remains. | 2478 // Make sure the older key remains. |
2139 EXPECT_EQ(1, cache_->GetEntryCount()); | 2479 EXPECT_EQ(1, cache_->GetEntryCount()); |
2140 ASSERT_EQ(net::OK, OpenEntry("key0", &entry)); | 2480 ASSERT_EQ(net::OK, OpenEntry("key0", &entry)); |
2141 entry->Close(); | 2481 entry->Close(); |
2142 } | 2482 } |
OLD | NEW |