| // Copyright 2014 The Chromium Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include "content/browser/service_worker/service_worker_cache_storage_manager.h" |
| |
| #include "base/files/file_path.h" |
| #include "base/files/scoped_temp_dir.h" |
| #include "base/message_loop/message_loop_proxy.h" |
| #include "base/run_loop.h" |
| #include "content/browser/fileapi/chrome_blob_storage_context.h" |
| #include "content/browser/quota/mock_quota_manager_proxy.h" |
| #include "content/browser/service_worker/service_worker_cache_quota_client.h" |
| #include "content/public/browser/browser_thread.h" |
| #include "content/public/test/test_browser_context.h" |
| #include "content/public/test/test_browser_thread_bundle.h" |
| #include "net/url_request/url_request_context_getter.h" |
| #include "storage/browser/blob/blob_storage_context.h" |
| #include "storage/browser/quota/quota_manager_proxy.h" |
| #include "testing/gtest/include/gtest/gtest.h" |
| |
| namespace content { |
| |
| class ServiceWorkerCacheStorageManagerTest : public testing::Test { |
| protected: |
| ServiceWorkerCacheStorageManagerTest() |
| : browser_thread_bundle_(TestBrowserThreadBundle::IO_MAINLOOP), |
| callback_bool_(false), |
| callback_error_( |
| ServiceWorkerCacheStorage::CACHE_STORAGE_ERROR_NO_ERROR), |
| callback_cache_error_(ServiceWorkerCache::ErrorTypeOK), |
| origin1_("http://example1.com"), |
| origin2_("http://example2.com") {} |
| |
| void SetUp() override { |
| ChromeBlobStorageContext* blob_storage_context( |
| ChromeBlobStorageContext::GetFor(&browser_context_)); |
| // Wait for ChromeBlobStorageContext to finish initializing. |
| base::RunLoop().RunUntilIdle(); |
| |
| quota_manager_proxy_ = new MockQuotaManagerProxy( |
| nullptr, base::MessageLoopProxy::current().get()); |
| |
| net::URLRequestContext* url_request_context = |
| browser_context_.GetRequestContext()->GetURLRequestContext(); |
| if (MemoryOnly()) { |
| cache_manager_ = ServiceWorkerCacheStorageManager::Create( |
| base::FilePath(), |
| base::MessageLoopProxy::current(), |
| quota_manager_proxy_); |
| } else { |
| ASSERT_TRUE(temp_dir_.CreateUniqueTempDir()); |
| cache_manager_ = ServiceWorkerCacheStorageManager::Create( |
| temp_dir_.path(), |
| base::MessageLoopProxy::current(), |
| quota_manager_proxy_); |
| } |
| |
| cache_manager_->SetBlobParametersForCache( |
| url_request_context, blob_storage_context->context()->AsWeakPtr()); |
| } |
| |
| void TearDown() override { |
| quota_manager_proxy_->SimulateQuotaManagerDestroyed(); |
| base::RunLoop().RunUntilIdle(); |
| } |
| |
| virtual bool MemoryOnly() { return false; } |
| |
| void BoolAndErrorCallback( |
| base::RunLoop* run_loop, |
| bool value, |
| ServiceWorkerCacheStorage::CacheStorageError error) { |
| callback_bool_ = value; |
| callback_error_ = error; |
| run_loop->Quit(); |
| } |
| |
| void CacheAndErrorCallback( |
| base::RunLoop* run_loop, |
| const scoped_refptr<ServiceWorkerCache>& cache, |
| ServiceWorkerCacheStorage::CacheStorageError error) { |
| callback_cache_ = cache; |
| callback_error_ = error; |
| run_loop->Quit(); |
| } |
| |
| void StringsAndErrorCallback( |
| base::RunLoop* run_loop, |
| const std::vector<std::string>& strings, |
| ServiceWorkerCacheStorage::CacheStorageError error) { |
| callback_strings_ = strings; |
| callback_error_ = error; |
| run_loop->Quit(); |
| } |
| |
| void CachePutCallback(base::RunLoop* run_loop, |
| ServiceWorkerCache::ErrorType error, |
| scoped_ptr<ServiceWorkerResponse> response, |
| scoped_ptr<storage::BlobDataHandle> blob_data_handle) { |
| callback_cache_error_ = error; |
| run_loop->Quit(); |
| } |
| |
| void CacheMatchCallback( |
| base::RunLoop* run_loop, |
| ServiceWorkerCache::ErrorType error, |
| scoped_ptr<ServiceWorkerResponse> response, |
| scoped_ptr<storage::BlobDataHandle> blob_data_handle) { |
| callback_cache_error_ = error; |
| callback_cache_response_ = response.Pass(); |
| // Deliberately drop the data handle as only the url is being tested. |
| run_loop->Quit(); |
| } |
| |
| bool Open(const GURL& origin, const std::string& cache_name) { |
| scoped_ptr<base::RunLoop> loop(new base::RunLoop()); |
| cache_manager_->OpenCache( |
| origin, |
| cache_name, |
| base::Bind(&ServiceWorkerCacheStorageManagerTest::CacheAndErrorCallback, |
| base::Unretained(this), |
| base::Unretained(loop.get()))); |
| loop->Run(); |
| |
| bool error = callback_error_ != |
| ServiceWorkerCacheStorage::CACHE_STORAGE_ERROR_NO_ERROR; |
| if (error) |
| EXPECT_TRUE(!callback_cache_.get()); |
| else |
| EXPECT_TRUE(callback_cache_.get()); |
| return !error; |
| } |
| |
| bool Has(const GURL& origin, const std::string& cache_name) { |
| scoped_ptr<base::RunLoop> loop(new base::RunLoop()); |
| cache_manager_->HasCache( |
| origin, |
| cache_name, |
| base::Bind(&ServiceWorkerCacheStorageManagerTest::BoolAndErrorCallback, |
| base::Unretained(this), |
| base::Unretained(loop.get()))); |
| loop->Run(); |
| |
| return callback_bool_; |
| } |
| |
| bool Delete(const GURL& origin, const std::string& cache_name) { |
| scoped_ptr<base::RunLoop> loop(new base::RunLoop()); |
| cache_manager_->DeleteCache( |
| origin, |
| cache_name, |
| base::Bind(&ServiceWorkerCacheStorageManagerTest::BoolAndErrorCallback, |
| base::Unretained(this), |
| base::Unretained(loop.get()))); |
| loop->Run(); |
| |
| return callback_bool_; |
| } |
| |
| bool Keys(const GURL& origin) { |
| scoped_ptr<base::RunLoop> loop(new base::RunLoop()); |
| cache_manager_->EnumerateCaches( |
| origin, |
| base::Bind( |
| &ServiceWorkerCacheStorageManagerTest::StringsAndErrorCallback, |
| base::Unretained(this), |
| base::Unretained(loop.get()))); |
| loop->Run(); |
| |
| bool error = callback_error_ != |
| ServiceWorkerCacheStorage::CACHE_STORAGE_ERROR_NO_ERROR; |
| return !error; |
| } |
| |
| bool CachePut(const scoped_refptr<ServiceWorkerCache>& cache, |
| const GURL& url) { |
| scoped_ptr<ServiceWorkerFetchRequest> request( |
| new ServiceWorkerFetchRequest()); |
| scoped_ptr<ServiceWorkerResponse> response(new ServiceWorkerResponse()); |
| request->url = url; |
| response->url = url; |
| scoped_ptr<base::RunLoop> loop(new base::RunLoop()); |
| cache->Put( |
| request.Pass(), |
| response.Pass(), |
| base::Bind(&ServiceWorkerCacheStorageManagerTest::CachePutCallback, |
| base::Unretained(this), |
| base::Unretained(loop.get()))); |
| loop->Run(); |
| |
| bool error = callback_cache_error_ != ServiceWorkerCache::ErrorTypeOK; |
| return !error; |
| } |
| |
| bool CacheMatch(const scoped_refptr<ServiceWorkerCache>& cache, |
| const GURL& url) { |
| scoped_ptr<ServiceWorkerFetchRequest> request( |
| new ServiceWorkerFetchRequest()); |
| request->url = url; |
| scoped_ptr<base::RunLoop> loop(new base::RunLoop()); |
| cache->Match( |
| request.Pass(), |
| base::Bind(&ServiceWorkerCacheStorageManagerTest::CacheMatchCallback, |
| base::Unretained(this), |
| base::Unretained(loop.get()))); |
| loop->Run(); |
| |
| bool error = callback_cache_error_ != ServiceWorkerCache::ErrorTypeOK; |
| return !error; |
| } |
| |
| ServiceWorkerCacheStorage* CacheStorageForOrigin(const GURL& origin) { |
| return cache_manager_->FindOrCreateServiceWorkerCacheManager(origin); |
| } |
| |
| protected: |
| TestBrowserContext browser_context_; |
| TestBrowserThreadBundle browser_thread_bundle_; |
| |
| base::ScopedTempDir temp_dir_; |
| scoped_refptr<MockQuotaManagerProxy> quota_manager_proxy_; |
| scoped_ptr<ServiceWorkerCacheStorageManager> cache_manager_; |
| |
| scoped_refptr<ServiceWorkerCache> callback_cache_; |
| int callback_bool_; |
| ServiceWorkerCacheStorage::CacheStorageError callback_error_; |
| ServiceWorkerCache::ErrorType callback_cache_error_; |
| scoped_ptr<ServiceWorkerResponse> callback_cache_response_; |
| std::vector<std::string> callback_strings_; |
| |
| const GURL origin1_; |
| const GURL origin2_; |
| |
| private: |
| DISALLOW_COPY_AND_ASSIGN(ServiceWorkerCacheStorageManagerTest); |
| }; |
| |
| class ServiceWorkerCacheStorageManagerMemoryOnlyTest |
| : public ServiceWorkerCacheStorageManagerTest { |
| bool MemoryOnly() override { return true; } |
| }; |
| |
| class ServiceWorkerCacheStorageManagerTestP |
| : public ServiceWorkerCacheStorageManagerTest, |
| public testing::WithParamInterface<bool> { |
| bool MemoryOnly() override { return !GetParam(); } |
| }; |
| |
| TEST_F(ServiceWorkerCacheStorageManagerTest, TestsRunOnIOThread) { |
| EXPECT_TRUE(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
| } |
| |
| TEST_P(ServiceWorkerCacheStorageManagerTestP, OpenCache) { |
| EXPECT_TRUE(Open(origin1_, "foo")); |
| } |
| |
| TEST_P(ServiceWorkerCacheStorageManagerTestP, OpenTwoCaches) { |
| EXPECT_TRUE(Open(origin1_, "foo")); |
| EXPECT_TRUE(Open(origin1_, "bar")); |
| } |
| |
| TEST_P(ServiceWorkerCacheStorageManagerTestP, CachePointersDiffer) { |
| EXPECT_TRUE(Open(origin1_, "foo")); |
| scoped_refptr<ServiceWorkerCache> cache = callback_cache_; |
| EXPECT_TRUE(Open(origin1_, "bar")); |
| EXPECT_NE(callback_cache_.get(), cache.get()); |
| } |
| |
| TEST_P(ServiceWorkerCacheStorageManagerTestP, Open2CachesSameNameDiffOrigins) { |
| EXPECT_TRUE(Open(origin1_, "foo")); |
| scoped_refptr<ServiceWorkerCache> cache = callback_cache_; |
| EXPECT_TRUE(Open(origin2_, "foo")); |
| EXPECT_NE(cache.get(), callback_cache_.get()); |
| } |
| |
| TEST_P(ServiceWorkerCacheStorageManagerTestP, OpenExistingCache) { |
| EXPECT_TRUE(Open(origin1_, "foo")); |
| scoped_refptr<ServiceWorkerCache> cache = callback_cache_; |
| EXPECT_TRUE(Open(origin1_, "foo")); |
| EXPECT_EQ(callback_cache_.get(), cache.get()); |
| } |
| |
| TEST_P(ServiceWorkerCacheStorageManagerTestP, HasCache) { |
| EXPECT_TRUE(Open(origin1_, "foo")); |
| EXPECT_TRUE(Has(origin1_, "foo")); |
| EXPECT_TRUE(callback_bool_); |
| } |
| |
| TEST_P(ServiceWorkerCacheStorageManagerTestP, HasNonExistent) { |
| EXPECT_FALSE(Has(origin1_, "foo")); |
| } |
| |
| TEST_P(ServiceWorkerCacheStorageManagerTestP, DeleteCache) { |
| EXPECT_TRUE(Open(origin1_, "foo")); |
| EXPECT_TRUE(Delete(origin1_, "foo")); |
| EXPECT_FALSE(Has(origin1_, "foo")); |
| } |
| |
| TEST_P(ServiceWorkerCacheStorageManagerTestP, DeleteTwice) { |
| EXPECT_TRUE(Open(origin1_, "foo")); |
| EXPECT_TRUE(Delete(origin1_, "foo")); |
| EXPECT_FALSE(Delete(origin1_, "foo")); |
| EXPECT_EQ(ServiceWorkerCacheStorage::CACHE_STORAGE_ERROR_NOT_FOUND, |
| callback_error_); |
| } |
| |
| TEST_P(ServiceWorkerCacheStorageManagerTestP, EmptyKeys) { |
| EXPECT_TRUE(Keys(origin1_)); |
| EXPECT_TRUE(callback_strings_.empty()); |
| } |
| |
| TEST_P(ServiceWorkerCacheStorageManagerTestP, SomeKeys) { |
| EXPECT_TRUE(Open(origin1_, "foo")); |
| EXPECT_TRUE(Open(origin1_, "bar")); |
| EXPECT_TRUE(Open(origin2_, "baz")); |
| EXPECT_TRUE(Keys(origin1_)); |
| EXPECT_EQ(2u, callback_strings_.size()); |
| std::vector<std::string> expected_keys; |
| expected_keys.push_back("foo"); |
| expected_keys.push_back("bar"); |
| EXPECT_EQ(expected_keys, callback_strings_); |
| EXPECT_TRUE(Keys(origin2_)); |
| EXPECT_EQ(1u, callback_strings_.size()); |
| EXPECT_STREQ("baz", callback_strings_[0].c_str()); |
| } |
| |
| TEST_P(ServiceWorkerCacheStorageManagerTestP, DeletedKeysGone) { |
| EXPECT_TRUE(Open(origin1_, "foo")); |
| EXPECT_TRUE(Open(origin1_, "bar")); |
| EXPECT_TRUE(Open(origin2_, "baz")); |
| EXPECT_TRUE(Delete(origin1_, "bar")); |
| EXPECT_TRUE(Keys(origin1_)); |
| EXPECT_EQ(1u, callback_strings_.size()); |
| EXPECT_STREQ("foo", callback_strings_[0].c_str()); |
| } |
| |
| TEST_P(ServiceWorkerCacheStorageManagerTestP, Chinese) { |
| EXPECT_TRUE(Open(origin1_, "ä½ å¥½")); |
| scoped_refptr<ServiceWorkerCache> cache = callback_cache_; |
| EXPECT_TRUE(Open(origin1_, "ä½ å¥½")); |
| EXPECT_EQ(callback_cache_.get(), cache.get()); |
| EXPECT_TRUE(Keys(origin1_)); |
| EXPECT_EQ(1u, callback_strings_.size()); |
| EXPECT_STREQ("ä½ å¥½", callback_strings_[0].c_str()); |
| } |
| |
| TEST_F(ServiceWorkerCacheStorageManagerTest, EmptyKey) { |
| EXPECT_TRUE(Open(origin1_, "")); |
| scoped_refptr<ServiceWorkerCache> cache = callback_cache_; |
| EXPECT_TRUE(Open(origin1_, "")); |
| EXPECT_EQ(cache.get(), callback_cache_.get()); |
| EXPECT_TRUE(Keys(origin1_)); |
| EXPECT_EQ(1u, callback_strings_.size()); |
| EXPECT_STREQ("", callback_strings_[0].c_str()); |
| EXPECT_TRUE(Has(origin1_, "")); |
| EXPECT_TRUE(Delete(origin1_, "")); |
| EXPECT_TRUE(Keys(origin1_)); |
| EXPECT_EQ(0u, callback_strings_.size()); |
| } |
| |
| TEST_F(ServiceWorkerCacheStorageManagerTest, DataPersists) { |
| EXPECT_TRUE(Open(origin1_, "foo")); |
| EXPECT_TRUE(Open(origin1_, "bar")); |
| EXPECT_TRUE(Open(origin1_, "baz")); |
| EXPECT_TRUE(Open(origin2_, "raz")); |
| EXPECT_TRUE(Delete(origin1_, "bar")); |
| quota_manager_proxy_->SimulateQuotaManagerDestroyed(); |
| cache_manager_ = |
| ServiceWorkerCacheStorageManager::Create(cache_manager_.get()); |
| EXPECT_TRUE(Keys(origin1_)); |
| EXPECT_EQ(2u, callback_strings_.size()); |
| std::vector<std::string> expected_keys; |
| expected_keys.push_back("foo"); |
| expected_keys.push_back("baz"); |
| EXPECT_EQ(expected_keys, callback_strings_); |
| } |
| |
| TEST_F(ServiceWorkerCacheStorageManagerMemoryOnlyTest, DataLostWhenMemoryOnly) { |
| EXPECT_TRUE(Open(origin1_, "foo")); |
| EXPECT_TRUE(Open(origin2_, "baz")); |
| quota_manager_proxy_->SimulateQuotaManagerDestroyed(); |
| cache_manager_ = |
| ServiceWorkerCacheStorageManager::Create(cache_manager_.get()); |
| EXPECT_TRUE(Keys(origin1_)); |
| EXPECT_EQ(0u, callback_strings_.size()); |
| } |
| |
| TEST_F(ServiceWorkerCacheStorageManagerTest, BadCacheName) { |
| // Since the implementation writes cache names to disk, ensure that we don't |
| // escape the directory. |
| const std::string bad_name = "../../../../../../../../../../../../../../foo"; |
| EXPECT_TRUE(Open(origin1_, bad_name)); |
| EXPECT_TRUE(Keys(origin1_)); |
| EXPECT_EQ(1u, callback_strings_.size()); |
| EXPECT_STREQ(bad_name.c_str(), callback_strings_[0].c_str()); |
| } |
| |
| TEST_F(ServiceWorkerCacheStorageManagerTest, BadOriginName) { |
| // Since the implementation writes origin names to disk, ensure that we don't |
| // escape the directory. |
| GURL bad_origin("http://../../../../../../../../../../../../../../foo"); |
| EXPECT_TRUE(Open(bad_origin, "foo")); |
| EXPECT_TRUE(Keys(bad_origin)); |
| EXPECT_EQ(1u, callback_strings_.size()); |
| EXPECT_STREQ("foo", callback_strings_[0].c_str()); |
| } |
| |
| // With a persistent cache if the client drops its reference to a |
| // ServiceWorkerCache |
| // it should be deleted. |
| TEST_F(ServiceWorkerCacheStorageManagerTest, DropReference) { |
| EXPECT_TRUE(Open(origin1_, "foo")); |
| base::WeakPtr<ServiceWorkerCache> cache = callback_cache_->AsWeakPtr(); |
| callback_cache_ = NULL; |
| EXPECT_TRUE(!cache); |
| } |
| |
| // With a memory cache the cache can't be freed from memory until the client |
| // calls delete. |
| TEST_F(ServiceWorkerCacheStorageManagerMemoryOnlyTest, |
| MemoryLosesReferenceOnlyAfterDelete) { |
| EXPECT_TRUE(Open(origin1_, "foo")); |
| base::WeakPtr<ServiceWorkerCache> cache = callback_cache_->AsWeakPtr(); |
| callback_cache_ = NULL; |
| EXPECT_TRUE(cache); |
| EXPECT_TRUE(Delete(origin1_, "foo")); |
| EXPECT_FALSE(cache); |
| } |
| |
| TEST_P(ServiceWorkerCacheStorageManagerTestP, RecreateCacheOnDemand) { |
| EXPECT_TRUE(Open(origin1_, "foo")); |
| EXPECT_TRUE(CachePut(callback_cache_, GURL("http://example.com/foo"))); |
| callback_cache_ = NULL; |
| EXPECT_TRUE(Open(origin1_, "foo")); |
| EXPECT_TRUE(CacheMatch(callback_cache_, GURL("http://example.com/foo"))); |
| } |
| |
| TEST_P(ServiceWorkerCacheStorageManagerTestP, DeleteBeforeRelease) { |
| EXPECT_TRUE(Open(origin1_, "foo")); |
| EXPECT_TRUE(Delete(origin1_, "foo")); |
| EXPECT_TRUE(callback_cache_->AsWeakPtr()); |
| } |
| |
| TEST_F(ServiceWorkerCacheStorageManagerMemoryOnlyTest, MemoryBackedSize) { |
| ServiceWorkerCacheStorage* cache_storage = CacheStorageForOrigin(origin1_); |
| EXPECT_EQ(0, cache_storage->MemoryBackedSize()); |
| |
| EXPECT_TRUE(Open(origin1_, "foo")); |
| scoped_refptr<ServiceWorkerCache> foo_cache = callback_cache_; |
| EXPECT_TRUE(Open(origin1_, "bar")); |
| scoped_refptr<ServiceWorkerCache> bar_cache = callback_cache_; |
| EXPECT_EQ(0, cache_storage->MemoryBackedSize()); |
| |
| EXPECT_TRUE(CachePut(foo_cache, GURL("http://example.com/foo"))); |
| EXPECT_LT(0, cache_storage->MemoryBackedSize()); |
| int64 foo_size = cache_storage->MemoryBackedSize(); |
| |
| EXPECT_TRUE(CachePut(bar_cache, GURL("http://example.com/foo"))); |
| EXPECT_EQ(foo_size * 2, cache_storage->MemoryBackedSize()); |
| } |
| |
| TEST_F(ServiceWorkerCacheStorageManagerTest, MemoryBackedSizePersistent) { |
| ServiceWorkerCacheStorage* cache_storage = CacheStorageForOrigin(origin1_); |
| EXPECT_EQ(0, cache_storage->MemoryBackedSize()); |
| EXPECT_TRUE(Open(origin1_, "foo")); |
| EXPECT_TRUE(CachePut(callback_cache_, GURL("http://example.com/foo"))); |
| EXPECT_EQ(0, cache_storage->MemoryBackedSize()); |
| } |
| |
| class ServiceWorkerCacheQuotaClientTest |
| : public ServiceWorkerCacheStorageManagerTest { |
| protected: |
| ServiceWorkerCacheQuotaClientTest() {} |
| |
| void SetUp() override { |
| ServiceWorkerCacheStorageManagerTest::SetUp(); |
| quota_client_.reset( |
| new ServiceWorkerCacheQuotaClient(cache_manager_->AsWeakPtr())); |
| } |
| |
| void UsageCallback(base::RunLoop* run_loop, int64 usage) { |
| callback_usage_ = usage; |
| run_loop->Quit(); |
| } |
| |
| void OriginsCallback(base::RunLoop* run_loop, const std::set<GURL>& origins) { |
| callback_origins_ = origins; |
| run_loop->Quit(); |
| } |
| |
| void DeleteOriginCallback(base::RunLoop* run_loop, |
| storage::QuotaStatusCode status) { |
| callback_status_ = status; |
| run_loop->Quit(); |
| } |
| |
| int64 QuotaGetOriginUsage(const GURL& origin) { |
| scoped_ptr<base::RunLoop> loop(new base::RunLoop()); |
| quota_client_->GetOriginUsage( |
| origin, |
| storage::kStorageTypeTemporary, |
| base::Bind(&ServiceWorkerCacheQuotaClientTest::UsageCallback, |
| base::Unretained(this), |
| base::Unretained(loop.get()))); |
| loop->Run(); |
| return callback_usage_; |
| } |
| |
| size_t QuotaGetOriginsForType() { |
| scoped_ptr<base::RunLoop> loop(new base::RunLoop()); |
| quota_client_->GetOriginsForType( |
| storage::kStorageTypeTemporary, |
| base::Bind(&ServiceWorkerCacheQuotaClientTest::OriginsCallback, |
| base::Unretained(this), |
| base::Unretained(loop.get()))); |
| loop->Run(); |
| return callback_origins_.size(); |
| } |
| |
| size_t QuotaGetOriginsForHost(const std::string& host) { |
| scoped_ptr<base::RunLoop> loop(new base::RunLoop()); |
| quota_client_->GetOriginsForHost( |
| storage::kStorageTypeTemporary, |
| host, |
| base::Bind(&ServiceWorkerCacheQuotaClientTest::OriginsCallback, |
| base::Unretained(this), |
| base::Unretained(loop.get()))); |
| loop->Run(); |
| return callback_origins_.size(); |
| } |
| |
| bool QuotaDeleteOriginData(const GURL& origin) { |
| scoped_ptr<base::RunLoop> loop(new base::RunLoop()); |
| quota_client_->DeleteOriginData( |
| origin, |
| storage::kStorageTypeTemporary, |
| base::Bind(&ServiceWorkerCacheQuotaClientTest::DeleteOriginCallback, |
| base::Unretained(this), |
| base::Unretained(loop.get()))); |
| loop->Run(); |
| return callback_status_ == storage::kQuotaStatusOk; |
| } |
| |
| bool QuotaDoesSupport(storage::StorageType type) { |
| return quota_client_->DoesSupport(type); |
| } |
| |
| scoped_ptr<ServiceWorkerCacheQuotaClient> quota_client_; |
| |
| storage::QuotaStatusCode callback_status_; |
| int64 callback_usage_; |
| std::set<GURL> callback_origins_; |
| |
| DISALLOW_COPY_AND_ASSIGN(ServiceWorkerCacheQuotaClientTest); |
| }; |
| |
| class ServiceWorkerCacheQuotaClientTestP |
| : public ServiceWorkerCacheQuotaClientTest, |
| public testing::WithParamInterface<bool> { |
| bool MemoryOnly() override { return !GetParam(); } |
| }; |
| |
| TEST_P(ServiceWorkerCacheQuotaClientTestP, QuotaID) { |
| EXPECT_EQ(storage::QuotaClient::kServiceWorkerCache, quota_client_->id()); |
| } |
| |
| TEST_P(ServiceWorkerCacheQuotaClientTestP, QuotaGetOriginUsage) { |
| EXPECT_EQ(0, QuotaGetOriginUsage(origin1_)); |
| EXPECT_TRUE(Open(origin1_, "foo")); |
| EXPECT_TRUE(CachePut(callback_cache_, GURL("http://example.com/foo"))); |
| EXPECT_LT(0, QuotaGetOriginUsage(origin1_)); |
| } |
| |
| TEST_P(ServiceWorkerCacheQuotaClientTestP, QuotaGetOriginsForType) { |
| EXPECT_EQ(0u, QuotaGetOriginsForType()); |
| EXPECT_TRUE(Open(origin1_, "foo")); |
| EXPECT_TRUE(Open(origin1_, "bar")); |
| EXPECT_TRUE(Open(origin2_, "foo")); |
| EXPECT_EQ(2u, QuotaGetOriginsForType()); |
| } |
| |
| TEST_P(ServiceWorkerCacheQuotaClientTestP, QuotaGetOriginsForHost) { |
| EXPECT_EQ(0u, QuotaGetOriginsForHost("example.com")); |
| EXPECT_TRUE(Open(GURL("http://example.com:8080"), "foo")); |
| EXPECT_TRUE(Open(GURL("http://example.com:9000"), "foo")); |
| EXPECT_TRUE(Open(GURL("ftp://example.com"), "foo")); |
| EXPECT_TRUE(Open(GURL("http://example2.com"), "foo")); |
| EXPECT_EQ(3u, QuotaGetOriginsForHost("example.com")); |
| EXPECT_EQ(1u, QuotaGetOriginsForHost("example2.com")); |
| EXPECT_TRUE(callback_origins_.find(GURL("http://example2.com")) != |
| callback_origins_.end()); |
| EXPECT_EQ(0u, QuotaGetOriginsForHost("unknown.com")); |
| } |
| |
| TEST_P(ServiceWorkerCacheQuotaClientTestP, QuotaDeleteOriginData) { |
| EXPECT_TRUE(Open(origin1_, "foo")); |
| // Call put to test that initialized caches are properly deleted too. |
| EXPECT_TRUE(CachePut(callback_cache_, GURL("http://example.com/foo"))); |
| EXPECT_TRUE(Open(origin1_, "bar")); |
| EXPECT_TRUE(Open(origin2_, "baz")); |
| |
| EXPECT_TRUE(QuotaDeleteOriginData(origin1_)); |
| |
| EXPECT_FALSE(Has(origin1_, "foo")); |
| EXPECT_FALSE(Has(origin1_, "bar")); |
| EXPECT_TRUE(Has(origin2_, "baz")); |
| EXPECT_TRUE(Open(origin1_, "foo")); |
| } |
| |
| TEST_P(ServiceWorkerCacheQuotaClientTestP, QuotaDeleteEmptyOrigin) { |
| EXPECT_TRUE(QuotaDeleteOriginData(origin1_)); |
| } |
| |
| TEST_P(ServiceWorkerCacheQuotaClientTestP, QuotaDoesSupport) { |
| EXPECT_TRUE(QuotaDoesSupport(storage::kStorageTypeTemporary)); |
| EXPECT_FALSE(QuotaDoesSupport(storage::kStorageTypePersistent)); |
| EXPECT_FALSE(QuotaDoesSupport(storage::kStorageTypeSyncable)); |
| EXPECT_FALSE(QuotaDoesSupport(storage::kStorageTypeQuotaNotManaged)); |
| EXPECT_FALSE(QuotaDoesSupport(storage::kStorageTypeUnknown)); |
| } |
| |
| INSTANTIATE_TEST_CASE_P(ServiceWorkerCacheStorageManagerTests, |
| ServiceWorkerCacheStorageManagerTestP, |
| ::testing::Values(false, true)); |
| |
| INSTANTIATE_TEST_CASE_P(ServiceWorkerCacheQuotaClientTests, |
| ServiceWorkerCacheQuotaClientTestP, |
| ::testing::Values(false, true)); |
| |
| } // namespace content |