| 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 24 matching lines...) Expand all Loading... |
| 1611 error_event_was_raised_ = true; | 1611 error_event_was_raised_ = true; |
| 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 enum ReinitTestCase { |
| 1622 CORRUPT_CACHE_ON_INSTALL, |
| 1623 CORRUPT_CACHE_ON_LOAD_EXISTING, |
| 1624 CORRUPT_SQL_ON_INSTALL |
| 1625 }; |
| 1626 |
| 1621 void Reinitialize1() { | 1627 void Reinitialize1() { |
| 1622 Reinitialize(1); | 1628 // Recover from a corrupt disk cache discovered while |
| 1629 // installing a new appcache. |
| 1630 Reinitialize(CORRUPT_CACHE_ON_INSTALL); |
| 1623 } | 1631 } |
| 1624 | 1632 |
| 1625 void Reinitialize2() { | 1633 void Reinitialize2() { |
| 1626 Reinitialize(2); | 1634 // Recover from a corrupt disk cache discovered while |
| 1635 // trying to load a resource from an existing appcache. |
| 1636 Reinitialize(CORRUPT_CACHE_ON_LOAD_EXISTING); |
| 1627 } | 1637 } |
| 1628 | 1638 |
| 1629 void Reinitialize(int test_case) { | 1639 void Reinitialize3() { |
| 1640 // Recover from a corrupt sql database discovered while |
| 1641 // installing a new appcache. |
| 1642 Reinitialize(CORRUPT_SQL_ON_INSTALL); |
| 1643 } |
| 1644 |
| 1645 void Reinitialize(ReinitTestCase test_case) { |
| 1630 // Unlike all of the other tests, this one actually read/write files. | 1646 // Unlike all of the other tests, this one actually read/write files. |
| 1631 ASSERT_TRUE(temp_directory_.CreateUniqueTempDir()); | 1647 ASSERT_TRUE(temp_directory_.CreateUniqueTempDir()); |
| 1632 | 1648 |
| 1633 // Create a corrupt/unopenable disk_cache index file. | 1649 AppCacheDatabase db(temp_directory_.path().AppendASCII("Index")); |
| 1634 const std::string kCorruptData("deadbeef"); | 1650 EXPECT_TRUE(db.LazyOpen(true)); |
| 1635 base::FilePath disk_cache_directory = | 1651 |
| 1636 temp_directory_.path().AppendASCII("Cache"); | 1652 if (test_case == CORRUPT_CACHE_ON_INSTALL || |
| 1637 ASSERT_TRUE(base::CreateDirectory(disk_cache_directory)); | 1653 test_case == CORRUPT_CACHE_ON_LOAD_EXISTING) { |
| 1638 base::FilePath index_file = disk_cache_directory.AppendASCII("index"); | 1654 // Create a corrupt/unopenable disk_cache index file. |
| 1639 EXPECT_EQ(static_cast<int>(kCorruptData.length()), | 1655 const std::string kCorruptData("deadbeef"); |
| 1640 file_util::WriteFile( | 1656 base::FilePath disk_cache_directory = |
| 1641 index_file, kCorruptData.data(), kCorruptData.length())); | 1657 temp_directory_.path().AppendASCII("Cache"); |
| 1658 ASSERT_TRUE(base::CreateDirectory(disk_cache_directory)); |
| 1659 base::FilePath index_file = disk_cache_directory.AppendASCII("index"); |
| 1660 EXPECT_EQ(static_cast<int>(kCorruptData.length()), |
| 1661 file_util::WriteFile( |
| 1662 index_file, kCorruptData.data(), kCorruptData.length())); |
| 1663 } |
| 1642 | 1664 |
| 1643 // Create records for a degenerate cached manifest that only contains | 1665 // Create records for a degenerate cached manifest that only contains |
| 1644 // one entry for the manifest file resource. | 1666 // one entry for the manifest file resource. |
| 1645 if (test_case == 2) { | 1667 if (test_case == CORRUPT_CACHE_ON_LOAD_EXISTING) { |
| 1646 AppCacheDatabase db(temp_directory_.path().AppendASCII("Index")); | 1668 AppCacheDatabase db(temp_directory_.path().AppendASCII("Index")); |
| 1647 GURL manifest_url = MockHttpServer::GetMockUrl("manifest"); | 1669 GURL manifest_url = MockHttpServer::GetMockUrl("manifest"); |
| 1648 | 1670 |
| 1649 AppCacheDatabase::GroupRecord group_record; | 1671 AppCacheDatabase::GroupRecord group_record; |
| 1650 group_record.group_id = 1; | 1672 group_record.group_id = 1; |
| 1651 group_record.manifest_url = manifest_url; | 1673 group_record.manifest_url = manifest_url; |
| 1652 group_record.origin = manifest_url.GetOrigin(); | 1674 group_record.origin = manifest_url.GetOrigin(); |
| 1653 EXPECT_TRUE(db.InsertGroup(&group_record)); | 1675 EXPECT_TRUE(db.InsertGroup(&group_record)); |
| 1654 AppCacheDatabase::CacheRecord cache_record; | 1676 AppCacheDatabase::CacheRecord cache_record; |
| 1655 cache_record.cache_id = 1; | 1677 cache_record.cache_id = 1; |
| (...skipping 29 matching lines...) Expand all Loading... |
| 1685 // We continue after the init task is complete including the callback | 1707 // We continue after the init task is complete including the callback |
| 1686 // on the current thread. | 1708 // on the current thread. |
| 1687 FlushDbThreadTasks(); | 1709 FlushDbThreadTasks(); |
| 1688 base::MessageLoop::current()->PostTask( | 1710 base::MessageLoop::current()->PostTask( |
| 1689 FROM_HERE, | 1711 FROM_HERE, |
| 1690 base::Bind(&AppCacheStorageImplTest::Continue_Reinitialize, | 1712 base::Bind(&AppCacheStorageImplTest::Continue_Reinitialize, |
| 1691 base::Unretained(this), | 1713 base::Unretained(this), |
| 1692 test_case)); | 1714 test_case)); |
| 1693 } | 1715 } |
| 1694 | 1716 |
| 1695 void Continue_Reinitialize(int test_case) { | 1717 void Continue_Reinitialize(ReinitTestCase test_case) { |
| 1696 const int kMockProcessId = 1; | 1718 const int kMockProcessId = 1; |
| 1697 backend_.reset(new AppCacheBackendImpl); | 1719 backend_.reset(new AppCacheBackendImpl); |
| 1698 backend_->Initialize(service_.get(), &frontend_, kMockProcessId); | 1720 backend_->Initialize(service_.get(), &frontend_, kMockProcessId); |
| 1699 | 1721 |
| 1700 if (test_case == 1) { | 1722 if (test_case == CORRUPT_SQL_ON_INSTALL) { |
| 1723 // Break the db file |
| 1724 EXPECT_FALSE(database()->was_corruption_detected()); |
| 1725 ASSERT_TRUE(sql::test::CorruptSizeInHeader( |
| 1726 temp_directory_.path().AppendASCII("Index"))); |
| 1727 } |
| 1728 |
| 1729 if (test_case == CORRUPT_CACHE_ON_INSTALL || |
| 1730 test_case == CORRUPT_SQL_ON_INSTALL) { |
| 1701 // Try to create a new appcache, the resulting update job will | 1731 // Try to create a new appcache, the resulting update job will |
| 1702 // eventually fail when it gets to disk cache initialization. | 1732 // eventually fail when it gets to disk cache initialization. |
| 1703 backend_->RegisterHost(1); | 1733 backend_->RegisterHost(1); |
| 1704 AppCacheHost* host1 = backend_->GetHost(1); | 1734 AppCacheHost* host1 = backend_->GetHost(1); |
| 1705 const GURL kEmptyPageUrl(MockHttpServer::GetMockUrl("empty.html")); | 1735 const GURL kEmptyPageUrl(MockHttpServer::GetMockUrl("empty.html")); |
| 1706 host1->first_party_url_ = kEmptyPageUrl; | 1736 host1->first_party_url_ = kEmptyPageUrl; |
| 1707 host1->SelectCache(kEmptyPageUrl, | 1737 host1->SelectCache(kEmptyPageUrl, |
| 1708 kNoCacheId, | 1738 kNoCacheId, |
| 1709 MockHttpServer::GetMockUrl("manifest")); | 1739 MockHttpServer::GetMockUrl("manifest")); |
| 1710 } else { | 1740 } else { |
| 1711 ASSERT_EQ(2, test_case); | 1741 ASSERT_EQ(CORRUPT_CACHE_ON_LOAD_EXISTING, test_case); |
| 1712 // Try to access the existing cache manifest. | 1742 // Try to access the existing cache manifest. |
| 1713 // The URLRequestJob will eventually fail when it gets to disk | 1743 // The URLRequestJob will eventually fail when it gets to disk |
| 1714 // cache initialization. | 1744 // cache initialization. |
| 1715 backend_->RegisterHost(2); | 1745 backend_->RegisterHost(2); |
| 1716 AppCacheHost* host2 = backend_->GetHost(2); | 1746 AppCacheHost* host2 = backend_->GetHost(2); |
| 1717 GURL manifest_url = MockHttpServer::GetMockUrl("manifest"); | 1747 GURL manifest_url = MockHttpServer::GetMockUrl("manifest"); |
| 1718 request_ = service()->request_context()->CreateRequest( | 1748 request_ = service()->request_context()->CreateRequest( |
| 1719 manifest_url, net::DEFAULT_PRIORITY, NULL); | 1749 manifest_url, net::DEFAULT_PRIORITY, NULL); |
| 1720 AppCacheInterceptor::SetExtraRequestInfo( | 1750 AppCacheInterceptor::SetExtraRequestInfo( |
| 1721 request_.get(), service_.get(), | 1751 request_.get(), service_.get(), |
| 1722 backend_->process_id(), host2->host_id(), | 1752 backend_->process_id(), host2->host_id(), |
| 1723 ResourceType::MAIN_FRAME); | 1753 ResourceType::MAIN_FRAME); |
| 1724 request_->Start(); | 1754 request_->Start(); |
| 1725 } | 1755 } |
| 1726 | 1756 |
| 1727 PushNextTask(base::Bind( | 1757 PushNextTask(base::Bind( |
| 1728 &AppCacheStorageImplTest::Verify_Reinitialized, | 1758 &AppCacheStorageImplTest::Verify_Reinitialized, |
| 1729 base::Unretained(this), | 1759 base::Unretained(this), |
| 1730 test_case)); | 1760 test_case)); |
| 1731 } | 1761 } |
| 1732 | 1762 |
| 1733 void Verify_Reinitialized(int test_case) { | 1763 void Verify_Reinitialized(ReinitTestCase test_case) { |
| 1734 // Verify we got notified of reinit and a new storage instance is created, | 1764 // Verify we got notified of reinit and a new storage instance is created, |
| 1735 // and that the old data has been deleted. | 1765 // and that the old data has been deleted. |
| 1736 EXPECT_TRUE(observer_->observed_old_storage_.get()); | 1766 EXPECT_TRUE(observer_->observed_old_storage_.get()); |
| 1737 EXPECT_TRUE(observer_->observed_old_storage_->storage() != storage()); | 1767 EXPECT_TRUE(observer_->observed_old_storage_->storage() != storage()); |
| 1738 EXPECT_FALSE(PathExists( | 1768 EXPECT_FALSE(PathExists( |
| 1739 temp_directory_.path().AppendASCII("Cache").AppendASCII("index"))); | 1769 temp_directory_.path().AppendASCII("Cache").AppendASCII("index"))); |
| 1740 EXPECT_FALSE(PathExists( | 1770 EXPECT_FALSE(PathExists( |
| 1741 temp_directory_.path().AppendASCII("Index"))); | 1771 temp_directory_.path().AppendASCII("Index"))); |
| 1742 | 1772 |
| 1773 if (test_case == CORRUPT_SQL_ON_INSTALL) { |
| 1774 AppCacheStorageImpl* storage = static_cast<AppCacheStorageImpl*>( |
| 1775 observer_->observed_old_storage_->storage()); |
| 1776 EXPECT_TRUE(storage->database_->was_corruption_detected()); |
| 1777 } |
| 1778 |
| 1743 // Verify that the hosts saw appropriate events. | 1779 // Verify that the hosts saw appropriate events. |
| 1744 if (test_case == 1) { | 1780 if (test_case == CORRUPT_CACHE_ON_INSTALL || |
| 1781 test_case == CORRUPT_SQL_ON_INSTALL) { |
| 1745 EXPECT_TRUE(frontend_.error_event_was_raised_); | 1782 EXPECT_TRUE(frontend_.error_event_was_raised_); |
| 1746 AppCacheHost* host1 = backend_->GetHost(1); | 1783 AppCacheHost* host1 = backend_->GetHost(1); |
| 1747 EXPECT_FALSE(host1->associated_cache()); | 1784 EXPECT_FALSE(host1->associated_cache()); |
| 1748 EXPECT_FALSE(host1->group_being_updated_); | 1785 EXPECT_FALSE(host1->group_being_updated_); |
| 1749 EXPECT_TRUE(host1->disabled_storage_reference_.get()); | 1786 EXPECT_TRUE(host1->disabled_storage_reference_.get()); |
| 1750 } else { | 1787 } else { |
| 1751 ASSERT_EQ(2, test_case); | 1788 ASSERT_EQ(CORRUPT_CACHE_ON_LOAD_EXISTING, test_case); |
| 1752 AppCacheHost* host2 = backend_->GetHost(2); | 1789 AppCacheHost* host2 = backend_->GetHost(2); |
| 1753 EXPECT_EQ(1, host2->main_resource_cache_->cache_id()); | 1790 EXPECT_EQ(1, host2->main_resource_cache_->cache_id()); |
| 1754 EXPECT_TRUE(host2->disabled_storage_reference_.get()); | 1791 EXPECT_TRUE(host2->disabled_storage_reference_.get()); |
| 1755 } | 1792 } |
| 1756 | 1793 |
| 1757 // Cleanup and claim victory. | 1794 // Cleanup and claim victory. |
| 1758 service_->RemoveObserver(observer_.get()); | 1795 service_->RemoveObserver(observer_.get()); |
| 1759 request_.reset(); | 1796 request_.reset(); |
| 1760 backend_.reset(); | 1797 backend_.reset(); |
| 1761 observer_.reset(); | 1798 observer_.reset(); |
| (...skipping 194 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1956 } | 1993 } |
| 1957 | 1994 |
| 1958 TEST_F(AppCacheStorageImplTest, Reinitialize1) { | 1995 TEST_F(AppCacheStorageImplTest, Reinitialize1) { |
| 1959 RunTestOnIOThread(&AppCacheStorageImplTest::Reinitialize1); | 1996 RunTestOnIOThread(&AppCacheStorageImplTest::Reinitialize1); |
| 1960 } | 1997 } |
| 1961 | 1998 |
| 1962 TEST_F(AppCacheStorageImplTest, Reinitialize2) { | 1999 TEST_F(AppCacheStorageImplTest, Reinitialize2) { |
| 1963 RunTestOnIOThread(&AppCacheStorageImplTest::Reinitialize2); | 2000 RunTestOnIOThread(&AppCacheStorageImplTest::Reinitialize2); |
| 1964 } | 2001 } |
| 1965 | 2002 |
| 2003 TEST_F(AppCacheStorageImplTest, Reinitialize3) { |
| 2004 RunTestOnIOThread(&AppCacheStorageImplTest::Reinitialize3); |
| 2005 } |
| 2006 |
| 1966 // That's all folks! | 2007 // That's all folks! |
| 1967 | 2008 |
| 1968 } // namespace appcache | 2009 } // namespace appcache |
| OLD | NEW |