 Chromium Code Reviews
 Chromium Code Reviews Issue 137493003:
  Appcache::OnCorruptionDetected handling  (Closed) 
  Base URL: svn://svn.chromium.org/chrome/trunk/src
    
  
    Issue 137493003:
  Appcache::OnCorruptionDetected handling  (Closed) 
  Base URL: svn://svn.chromium.org/chrome/trunk/src| 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 <stack> | 5 #include <stack> | 
| 6 | 6 | 
| 7 #include "base/bind.h" | 7 #include "base/bind.h" | 
| 8 #include "base/bind_helpers.h" | 8 #include "base/bind_helpers.h" | 
| 9 #include "base/callback.h" | 9 #include "base/callback.h" | 
| 10 #include "base/file_util.h" | 10 #include "base/file_util.h" | 
| 11 #include "base/files/scoped_temp_dir.h" | 11 #include "base/files/scoped_temp_dir.h" | 
| 12 #include "base/memory/scoped_ptr.h" | 12 #include "base/memory/scoped_ptr.h" | 
| 13 #include "base/message_loop/message_loop.h" | 13 #include "base/message_loop/message_loop.h" | 
| 14 #include "base/synchronization/waitable_event.h" | 14 #include "base/synchronization/waitable_event.h" | 
| 15 #include "base/threading/thread.h" | 15 #include "base/threading/thread.h" | 
| 16 #include "net/base/net_errors.h" | 16 #include "net/base/net_errors.h" | 
| 17 #include "net/base/request_priority.h" | 17 #include "net/base/request_priority.h" | 
| 18 #include "net/http/http_response_headers.h" | 18 #include "net/http/http_response_headers.h" | 
| 19 #include "net/url_request/url_request_error_job.h" | 19 #include "net/url_request/url_request_error_job.h" | 
| 20 #include "net/url_request/url_request_job_factory_impl.h" | 20 #include "net/url_request/url_request_job_factory_impl.h" | 
| 21 #include "net/url_request/url_request_test_job.h" | 21 #include "net/url_request/url_request_test_job.h" | 
| 22 #include "net/url_request/url_request_test_util.h" | 22 #include "net/url_request/url_request_test_util.h" | 
| 23 #include "sql/test/test_helpers.h" | |
| 23 #include "testing/gtest/include/gtest/gtest.h" | 24 #include "testing/gtest/include/gtest/gtest.h" | 
| 24 #include "webkit/browser/appcache/appcache.h" | 25 #include "webkit/browser/appcache/appcache.h" | 
| 25 #include "webkit/browser/appcache/appcache_backend_impl.h" | 26 #include "webkit/browser/appcache/appcache_backend_impl.h" | 
| 26 #include "webkit/browser/appcache/appcache_database.h" | 27 #include "webkit/browser/appcache/appcache_database.h" | 
| 27 #include "webkit/browser/appcache/appcache_entry.h" | 28 #include "webkit/browser/appcache/appcache_entry.h" | 
| 28 #include "webkit/browser/appcache/appcache_group.h" | 29 #include "webkit/browser/appcache/appcache_group.h" | 
| 29 #include "webkit/browser/appcache/appcache_host.h" | 30 #include "webkit/browser/appcache/appcache_host.h" | 
| 30 #include "webkit/browser/appcache/appcache_interceptor.h" | 31 #include "webkit/browser/appcache/appcache_interceptor.h" | 
| 31 #include "webkit/browser/appcache/appcache_request_handler.h" | 32 #include "webkit/browser/appcache/appcache_request_handler.h" | 
| 32 #include "webkit/browser/appcache/appcache_service.h" | 33 #include "webkit/browser/appcache/appcache_service.h" | 
| (...skipping 223 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 256 base::FilePath(), | 257 base::FilePath(), | 
| 257 io_thread->message_loop_proxy().get(), | 258 io_thread->message_loop_proxy().get(), | 
| 258 db_thread->message_loop_proxy().get(), | 259 db_thread->message_loop_proxy().get(), | 
| 259 NULL), | 260 NULL), | 
| 260 async_(false) {} | 261 async_(false) {} | 
| 261 | 262 | 
| 262 virtual void GetUsageAndQuota( | 263 virtual void GetUsageAndQuota( | 
| 263 const GURL& origin, | 264 const GURL& origin, | 
| 264 quota::StorageType type, | 265 quota::StorageType type, | 
| 265 const GetUsageAndQuotaCallback& callback) OVERRIDE { | 266 const GetUsageAndQuotaCallback& callback) OVERRIDE { | 
| 266 EXPECT_EQ(kOrigin, origin); | |
| 267 EXPECT_EQ(quota::kStorageTypeTemporary, type); | 267 EXPECT_EQ(quota::kStorageTypeTemporary, type); | 
| 268 if (async_) { | 268 if (async_) { | 
| 269 base::MessageLoop::current()->PostTask( | 269 base::MessageLoop::current()->PostTask( | 
| 270 FROM_HERE, | 270 FROM_HERE, | 
| 271 base::Bind(&MockQuotaManager::CallCallback, | 271 base::Bind(&MockQuotaManager::CallCallback, | 
| 272 base::Unretained(this), | 272 base::Unretained(this), | 
| 273 callback)); | 273 callback)); | 
| 274 return; | 274 return; | 
| 275 } | 275 } | 
| 276 CallCallback(callback); | 276 CallCallback(callback); | 
| (...skipping 1287 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1564 &AppCacheStorageImplTest::Verify_ExclusionNotFound, | 1564 &AppCacheStorageImplTest::Verify_ExclusionNotFound, | 
| 1565 base::Unretained(this), kOnlineNamespaceWithinFallback, 3)); | 1565 base::Unretained(this), kOnlineNamespaceWithinFallback, 3)); | 
| 1566 storage()->FindResponseForMainRequest( | 1566 storage()->FindResponseForMainRequest( | 
| 1567 kOnlineNamespaceWithinFallback, GURL(), delegate()); | 1567 kOnlineNamespaceWithinFallback, GURL(), delegate()); | 
| 1568 return; | 1568 return; | 
| 1569 } | 1569 } | 
| 1570 | 1570 | 
| 1571 TestFinished(); | 1571 TestFinished(); | 
| 1572 } | 1572 } | 
| 1573 | 1573 | 
| 1574 // Reinitialize ------------------------------- | 1574 // Reinitialize ------------------------------- | 
| 1575 // This test is somewhat of a system integration test. | 1575 // These tests are somewhat of a system integration test. | 
| 1576 // It relies on running a mock http server on our IO thread, | 1576 // They rely on running a mock http server on our IO thread, | 
| 1577 // and involves other appcache classes to get some code | 1577 // and involves other appcache classes to get some code | 
| 1578 // coverage thruout when Reinitialize happens. | 1578 // coverage thruout when Reinitialize happens. | 
| 1579 | 1579 | 
| 1580 class MockServiceObserver : public AppCacheService::Observer { | 1580 class MockServiceObserver : public AppCacheService::Observer { | 
| 1581 public: | 1581 public: | 
| 1582 explicit MockServiceObserver(AppCacheStorageImplTest* test) | 1582 explicit MockServiceObserver(AppCacheStorageImplTest* test) | 
| 1583 : test_(test) {} | 1583 : test_(test) {} | 
| 1584 | 1584 | 
| 1585 virtual void OnServiceReinitialized( | 1585 virtual void OnServiceReinitialized( | 
| 1586 AppCacheStorageReference* old_storage_ref) OVERRIDE { | 1586 AppCacheStorageReference* old_storage_ref) OVERRIDE { | 
| (...skipping 25 matching lines...) Expand all Loading... | |
| 1612 } | 1612 } | 
| 1613 virtual void OnLogMessage(int host_id, LogLevel log_level, | 1613 virtual void OnLogMessage(int host_id, LogLevel log_level, | 
| 1614 const std::string& message) OVERRIDE {} | 1614 const std::string& message) OVERRIDE {} | 
| 1615 virtual void OnContentBlocked( | 1615 virtual void OnContentBlocked( | 
| 1616 int host_id, const GURL& manifest_url) OVERRIDE {} | 1616 int host_id, const GURL& manifest_url) OVERRIDE {} | 
| 1617 | 1617 | 
| 1618 bool error_event_was_raised_; | 1618 bool error_event_was_raised_; | 
| 1619 }; | 1619 }; | 
| 1620 | 1620 | 
| 1621 void Reinitialize1() { | 1621 void Reinitialize1() { | 
| 1622 // Recover from a corrupt disk cache discovered while | |
| 1623 // installing a new appcache. | |
| 1622 Reinitialize(1); | 1624 Reinitialize(1); | 
| 1623 } | 1625 } | 
| 1624 | 1626 | 
| 1625 void Reinitialize2() { | 1627 void Reinitialize2() { | 
| 1628 // Recover from a corrupt disk cache discovered while | |
| 1629 // trying to load a resource from an existing appcache. | |
| 1626 Reinitialize(2); | 1630 Reinitialize(2); | 
| 1627 } | 1631 } | 
| 1628 | 1632 | 
| 1633 void Reinitialize3() { | |
| 1634 // Recover from a corrupt sql database discovered while | |
| 1635 // installing a new appcache. | |
| 1636 Reinitialize(3); | |
| 1637 } | |
| 1638 | |
| 1629 void Reinitialize(int test_case) { | 1639 void Reinitialize(int test_case) { | 
| 
kinuko
2014/01/29 07:40:30
nit: for readability does it make sense to use a l
 
michaeln
2014/01/29 20:44:16
well yes, of course it does :)
 | |
| 1630 // Unlike all of the other tests, this one actually read/write files. | 1640 // Unlike all of the other tests, this one actually read/write files. | 
| 1631 ASSERT_TRUE(temp_directory_.CreateUniqueTempDir()); | 1641 ASSERT_TRUE(temp_directory_.CreateUniqueTempDir()); | 
| 1632 | 1642 | 
| 1633 // Create a corrupt/unopenable disk_cache index file. | 1643 AppCacheDatabase db(temp_directory_.path().AppendASCII("Index")); | 
| 1634 const std::string kCorruptData("deadbeef"); | 1644 EXPECT_TRUE(db.LazyOpen(true)); | 
| 1635 base::FilePath disk_cache_directory = | 1645 | 
| 1636 temp_directory_.path().AppendASCII("Cache"); | 1646 if (test_case == 1 || test_case == 2) { | 
| 1637 ASSERT_TRUE(base::CreateDirectory(disk_cache_directory)); | 1647 // Create a corrupt/unopenable disk_cache index file. | 
| 1638 base::FilePath index_file = disk_cache_directory.AppendASCII("index"); | 1648 const std::string kCorruptData("deadbeef"); | 
| 1639 EXPECT_EQ(static_cast<int>(kCorruptData.length()), | 1649 base::FilePath disk_cache_directory = | 
| 1640 file_util::WriteFile( | 1650 temp_directory_.path().AppendASCII("Cache"); | 
| 1641 index_file, kCorruptData.data(), kCorruptData.length())); | 1651 ASSERT_TRUE(base::CreateDirectory(disk_cache_directory)); | 
| 1652 base::FilePath index_file = disk_cache_directory.AppendASCII("index"); | |
| 1653 EXPECT_EQ(static_cast<int>(kCorruptData.length()), | |
| 1654 file_util::WriteFile( | |
| 1655 index_file, kCorruptData.data(), kCorruptData.length())); | |
| 1656 } | |
| 1642 | 1657 | 
| 1643 // Create records for a degenerate cached manifest that only contains | 1658 // Create records for a degenerate cached manifest that only contains | 
| 1644 // one entry for the manifest file resource. | 1659 // one entry for the manifest file resource. | 
| 1645 if (test_case == 2) { | 1660 if (test_case == 2) { | 
| 1646 AppCacheDatabase db(temp_directory_.path().AppendASCII("Index")); | 1661 AppCacheDatabase db(temp_directory_.path().AppendASCII("Index")); | 
| 1647 GURL manifest_url = MockHttpServer::GetMockUrl("manifest"); | 1662 GURL manifest_url = MockHttpServer::GetMockUrl("manifest"); | 
| 1648 | 1663 | 
| 1649 AppCacheDatabase::GroupRecord group_record; | 1664 AppCacheDatabase::GroupRecord group_record; | 
| 1650 group_record.group_id = 1; | 1665 group_record.group_id = 1; | 
| 1651 group_record.manifest_url = manifest_url; | 1666 group_record.manifest_url = manifest_url; | 
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1690 base::Bind(&AppCacheStorageImplTest::Continue_Reinitialize, | 1705 base::Bind(&AppCacheStorageImplTest::Continue_Reinitialize, | 
| 1691 base::Unretained(this), | 1706 base::Unretained(this), | 
| 1692 test_case)); | 1707 test_case)); | 
| 1693 } | 1708 } | 
| 1694 | 1709 | 
| 1695 void Continue_Reinitialize(int test_case) { | 1710 void Continue_Reinitialize(int test_case) { | 
| 1696 const int kMockProcessId = 1; | 1711 const int kMockProcessId = 1; | 
| 1697 backend_.reset(new AppCacheBackendImpl); | 1712 backend_.reset(new AppCacheBackendImpl); | 
| 1698 backend_->Initialize(service_.get(), &frontend_, kMockProcessId); | 1713 backend_->Initialize(service_.get(), &frontend_, kMockProcessId); | 
| 1699 | 1714 | 
| 1700 if (test_case == 1) { | 1715 if (test_case == 3) { | 
| 1716 // Break the db file | |
| 1717 EXPECT_FALSE(database()->was_corruption_detected()); | |
| 1718 ASSERT_TRUE(sql::test::CorruptSizeInHeader( | |
| 1719 temp_directory_.path().AppendASCII("Index"))); | |
| 1720 } | |
| 1721 | |
| 1722 if (test_case == 1 || test_case == 3) { | |
| 1701 // Try to create a new appcache, the resulting update job will | 1723 // Try to create a new appcache, the resulting update job will | 
| 1702 // eventually fail when it gets to disk cache initialization. | 1724 // eventually fail when it gets to disk cache initialization. | 
| 1703 backend_->RegisterHost(1); | 1725 backend_->RegisterHost(1); | 
| 1704 AppCacheHost* host1 = backend_->GetHost(1); | 1726 AppCacheHost* host1 = backend_->GetHost(1); | 
| 1705 const GURL kEmptyPageUrl(MockHttpServer::GetMockUrl("empty.html")); | 1727 const GURL kEmptyPageUrl(MockHttpServer::GetMockUrl("empty.html")); | 
| 1706 host1->first_party_url_ = kEmptyPageUrl; | 1728 host1->first_party_url_ = kEmptyPageUrl; | 
| 1707 host1->SelectCache(kEmptyPageUrl, | 1729 host1->SelectCache(kEmptyPageUrl, | 
| 1708 kNoCacheId, | 1730 kNoCacheId, | 
| 1709 MockHttpServer::GetMockUrl("manifest")); | 1731 MockHttpServer::GetMockUrl("manifest")); | 
| 1710 } else { | 1732 } else { | 
| (...skipping 22 matching lines...) Expand all Loading... | |
| 1733 void Verify_Reinitialized(int test_case) { | 1755 void Verify_Reinitialized(int test_case) { | 
| 1734 // Verify we got notified of reinit and a new storage instance is created, | 1756 // Verify we got notified of reinit and a new storage instance is created, | 
| 1735 // and that the old data has been deleted. | 1757 // and that the old data has been deleted. | 
| 1736 EXPECT_TRUE(observer_->observed_old_storage_.get()); | 1758 EXPECT_TRUE(observer_->observed_old_storage_.get()); | 
| 1737 EXPECT_TRUE(observer_->observed_old_storage_->storage() != storage()); | 1759 EXPECT_TRUE(observer_->observed_old_storage_->storage() != storage()); | 
| 1738 EXPECT_FALSE(PathExists( | 1760 EXPECT_FALSE(PathExists( | 
| 1739 temp_directory_.path().AppendASCII("Cache").AppendASCII("index"))); | 1761 temp_directory_.path().AppendASCII("Cache").AppendASCII("index"))); | 
| 1740 EXPECT_FALSE(PathExists( | 1762 EXPECT_FALSE(PathExists( | 
| 1741 temp_directory_.path().AppendASCII("Index"))); | 1763 temp_directory_.path().AppendASCII("Index"))); | 
| 1742 | 1764 | 
| 1765 if (test_case == 3) { | |
| 1766 AppCacheStorageImpl* storage = static_cast<AppCacheStorageImpl*>( | |
| 1767 observer_->observed_old_storage_->storage()); | |
| 1768 EXPECT_TRUE(storage->database_->was_corruption_detected()); | |
| 1769 } | |
| 1770 | |
| 1743 // Verify that the hosts saw appropriate events. | 1771 // Verify that the hosts saw appropriate events. | 
| 1744 if (test_case == 1) { | 1772 if (test_case == 1 || test_case == 3) { | 
| 1745 EXPECT_TRUE(frontend_.error_event_was_raised_); | 1773 EXPECT_TRUE(frontend_.error_event_was_raised_); | 
| 1746 AppCacheHost* host1 = backend_->GetHost(1); | 1774 AppCacheHost* host1 = backend_->GetHost(1); | 
| 1747 EXPECT_FALSE(host1->associated_cache()); | 1775 EXPECT_FALSE(host1->associated_cache()); | 
| 1748 EXPECT_FALSE(host1->group_being_updated_); | 1776 EXPECT_FALSE(host1->group_being_updated_); | 
| 1749 EXPECT_TRUE(host1->disabled_storage_reference_.get()); | 1777 EXPECT_TRUE(host1->disabled_storage_reference_.get()); | 
| 1750 } else { | 1778 } else { | 
| 1751 ASSERT_EQ(2, test_case); | 1779 ASSERT_EQ(2, test_case); | 
| 1752 AppCacheHost* host2 = backend_->GetHost(2); | 1780 AppCacheHost* host2 = backend_->GetHost(2); | 
| 1753 EXPECT_EQ(1, host2->main_resource_cache_->cache_id()); | 1781 EXPECT_EQ(1, host2->main_resource_cache_->cache_id()); | 
| 1754 EXPECT_TRUE(host2->disabled_storage_reference_.get()); | 1782 EXPECT_TRUE(host2->disabled_storage_reference_.get()); | 
| (...skipping 201 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1956 } | 1984 } | 
| 1957 | 1985 | 
| 1958 TEST_F(AppCacheStorageImplTest, Reinitialize1) { | 1986 TEST_F(AppCacheStorageImplTest, Reinitialize1) { | 
| 1959 RunTestOnIOThread(&AppCacheStorageImplTest::Reinitialize1); | 1987 RunTestOnIOThread(&AppCacheStorageImplTest::Reinitialize1); | 
| 1960 } | 1988 } | 
| 1961 | 1989 | 
| 1962 TEST_F(AppCacheStorageImplTest, Reinitialize2) { | 1990 TEST_F(AppCacheStorageImplTest, Reinitialize2) { | 
| 1963 RunTestOnIOThread(&AppCacheStorageImplTest::Reinitialize2); | 1991 RunTestOnIOThread(&AppCacheStorageImplTest::Reinitialize2); | 
| 1964 } | 1992 } | 
| 1965 | 1993 | 
| 1994 TEST_F(AppCacheStorageImplTest, Reinitialize3) { | |
| 1995 RunTestOnIOThread(&AppCacheStorageImplTest::Reinitialize3); | |
| 1996 } | |
| 1997 | |
| 1966 // That's all folks! | 1998 // That's all folks! | 
| 1967 | 1999 | 
| 1968 } // namespace appcache | 2000 } // namespace appcache | 
| OLD | NEW |