Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(28)

Side by Side Diff: net/disk_cache/backend_unittest.cc

Issue 8065015: Disk Cache: Improve handling of dirty entries. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: Created 9 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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
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
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
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 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698