diff options
Diffstat (limited to 'chromium/content/browser/appcache/appcache_quota_client_unittest.cc')
-rw-r--r-- | chromium/content/browser/appcache/appcache_quota_client_unittest.cc | 437 |
1 files changed, 437 insertions, 0 deletions
diff --git a/chromium/content/browser/appcache/appcache_quota_client_unittest.cc b/chromium/content/browser/appcache/appcache_quota_client_unittest.cc new file mode 100644 index 00000000000..3a32e95dd2f --- /dev/null +++ b/chromium/content/browser/appcache/appcache_quota_client_unittest.cc @@ -0,0 +1,437 @@ +// 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 <map> +#include <set> + +#include "base/bind.h" +#include "base/message_loop/message_loop_proxy.h" +#include "base/run_loop.h" +#include "content/browser/appcache/mock_appcache_service.h" +#include "net/base/net_errors.h" +#include "testing/gtest/include/gtest/gtest.h" +#include "webkit/browser/appcache/appcache_quota_client.h" + +using appcache::AppCacheQuotaClient; + +namespace content { + +// Declared to shorten the line lengths. +static const quota::StorageType kTemp = quota::kStorageTypeTemporary; +static const quota::StorageType kPerm = quota::kStorageTypePersistent; + +// Base class for our test fixtures. +class AppCacheQuotaClientTest : public testing::Test { + public: + const GURL kOriginA; + const GURL kOriginB; + const GURL kOriginOther; + + AppCacheQuotaClientTest() + : kOriginA("http://host"), + kOriginB("http://host:8000"), + kOriginOther("http://other"), + usage_(0), + delete_status_(quota::kQuotaStatusUnknown), + num_get_origin_usage_completions_(0), + num_get_origins_completions_(0), + num_delete_origins_completions_(0), + weak_factory_(this) { + } + + int64 GetOriginUsage( + quota::QuotaClient* client, + const GURL& origin, + quota::StorageType type) { + usage_ = -1; + AsyncGetOriginUsage(client, origin, type); + base::RunLoop().RunUntilIdle(); + return usage_; + } + + const std::set<GURL>& GetOriginsForType( + quota::QuotaClient* client, + quota::StorageType type) { + origins_.clear(); + AsyncGetOriginsForType(client, type); + base::RunLoop().RunUntilIdle(); + return origins_; + } + + const std::set<GURL>& GetOriginsForHost( + quota::QuotaClient* client, + quota::StorageType type, + const std::string& host) { + origins_.clear(); + AsyncGetOriginsForHost(client, type, host); + base::RunLoop().RunUntilIdle(); + return origins_; + } + + quota::QuotaStatusCode DeleteOriginData( + quota::QuotaClient* client, + quota::StorageType type, + const GURL& origin) { + delete_status_ = quota::kQuotaStatusUnknown; + AsyncDeleteOriginData(client, type, origin); + base::RunLoop().RunUntilIdle(); + return delete_status_; + } + + void AsyncGetOriginUsage( + quota::QuotaClient* client, + const GURL& origin, + quota::StorageType type) { + client->GetOriginUsage( + origin, type, + base::Bind(&AppCacheQuotaClientTest::OnGetOriginUsageComplete, + weak_factory_.GetWeakPtr())); + } + + void AsyncGetOriginsForType( + quota::QuotaClient* client, + quota::StorageType type) { + client->GetOriginsForType( + type, + base::Bind(&AppCacheQuotaClientTest::OnGetOriginsComplete, + weak_factory_.GetWeakPtr())); + } + + void AsyncGetOriginsForHost( + quota::QuotaClient* client, + quota::StorageType type, + const std::string& host) { + client->GetOriginsForHost( + type, host, + base::Bind(&AppCacheQuotaClientTest::OnGetOriginsComplete, + weak_factory_.GetWeakPtr())); + } + + void AsyncDeleteOriginData( + quota::QuotaClient* client, + quota::StorageType type, + const GURL& origin) { + client->DeleteOriginData( + origin, type, + base::Bind(&AppCacheQuotaClientTest::OnDeleteOriginDataComplete, + weak_factory_.GetWeakPtr())); + } + + void SetUsageMapEntry(const GURL& origin, int64 usage) { + mock_service_.storage()->usage_map_[origin] = usage; + } + + AppCacheQuotaClient* CreateClient() { + return new AppCacheQuotaClient(&mock_service_); + } + + void Call_NotifyAppCacheReady(AppCacheQuotaClient* client) { + client->NotifyAppCacheReady(); + } + + void Call_NotifyAppCacheDestroyed(AppCacheQuotaClient* client) { + client->NotifyAppCacheDestroyed(); + } + + void Call_OnQuotaManagerDestroyed(AppCacheQuotaClient* client) { + client->OnQuotaManagerDestroyed(); + } + + protected: + void OnGetOriginUsageComplete(int64 usage) { + ++num_get_origin_usage_completions_; + usage_ = usage; + } + + void OnGetOriginsComplete(const std::set<GURL>& origins) { + ++num_get_origins_completions_; + origins_ = origins; + } + + void OnDeleteOriginDataComplete(quota::QuotaStatusCode status) { + ++num_delete_origins_completions_; + delete_status_ = status; + } + + base::MessageLoop message_loop_; + int64 usage_; + std::set<GURL> origins_; + quota::QuotaStatusCode delete_status_; + int num_get_origin_usage_completions_; + int num_get_origins_completions_; + int num_delete_origins_completions_; + MockAppCacheService mock_service_; + base::WeakPtrFactory<AppCacheQuotaClientTest> weak_factory_; +}; + + +TEST_F(AppCacheQuotaClientTest, BasicCreateDestroy) { + AppCacheQuotaClient* client = CreateClient(); + Call_NotifyAppCacheReady(client); + Call_OnQuotaManagerDestroyed(client); + Call_NotifyAppCacheDestroyed(client); +} + +TEST_F(AppCacheQuotaClientTest, EmptyService) { + AppCacheQuotaClient* client = CreateClient(); + Call_NotifyAppCacheReady(client); + + EXPECT_EQ(0, GetOriginUsage(client, kOriginA, kTemp)); + EXPECT_EQ(0, GetOriginUsage(client, kOriginA, kPerm)); + EXPECT_TRUE(GetOriginsForType(client, kTemp).empty()); + EXPECT_TRUE(GetOriginsForType(client, kPerm).empty()); + EXPECT_TRUE(GetOriginsForHost(client, kTemp, kOriginA.host()).empty()); + EXPECT_TRUE(GetOriginsForHost(client, kPerm, kOriginA.host()).empty()); + EXPECT_EQ(quota::kQuotaStatusOk, DeleteOriginData(client, kTemp, kOriginA)); + EXPECT_EQ(quota::kQuotaStatusOk, DeleteOriginData(client, kPerm, kOriginA)); + + Call_NotifyAppCacheDestroyed(client); + Call_OnQuotaManagerDestroyed(client); +} + +TEST_F(AppCacheQuotaClientTest, NoService) { + AppCacheQuotaClient* client = CreateClient(); + Call_NotifyAppCacheReady(client); + Call_NotifyAppCacheDestroyed(client); + + EXPECT_EQ(0, GetOriginUsage(client, kOriginA, kTemp)); + EXPECT_EQ(0, GetOriginUsage(client, kOriginA, kPerm)); + EXPECT_TRUE(GetOriginsForType(client, kTemp).empty()); + EXPECT_TRUE(GetOriginsForType(client, kPerm).empty()); + EXPECT_TRUE(GetOriginsForHost(client, kTemp, kOriginA.host()).empty()); + EXPECT_TRUE(GetOriginsForHost(client, kPerm, kOriginA.host()).empty()); + EXPECT_EQ(quota::kQuotaErrorAbort, + DeleteOriginData(client, kTemp, kOriginA)); + EXPECT_EQ(quota::kQuotaErrorAbort, + DeleteOriginData(client, kPerm, kOriginA)); + + Call_OnQuotaManagerDestroyed(client); +} + +TEST_F(AppCacheQuotaClientTest, GetOriginUsage) { + AppCacheQuotaClient* client = CreateClient(); + Call_NotifyAppCacheReady(client); + + SetUsageMapEntry(kOriginA, 1000); + EXPECT_EQ(1000, GetOriginUsage(client, kOriginA, kTemp)); + EXPECT_EQ(0, GetOriginUsage(client, kOriginA, kPerm)); + + Call_NotifyAppCacheDestroyed(client); + Call_OnQuotaManagerDestroyed(client); +} + +TEST_F(AppCacheQuotaClientTest, GetOriginsForHost) { + AppCacheQuotaClient* client = CreateClient(); + Call_NotifyAppCacheReady(client); + + EXPECT_EQ(kOriginA.host(), kOriginB.host()); + EXPECT_NE(kOriginA.host(), kOriginOther.host()); + + std::set<GURL> origins = GetOriginsForHost(client, kTemp, kOriginA.host()); + EXPECT_TRUE(origins.empty()); + + SetUsageMapEntry(kOriginA, 1000); + SetUsageMapEntry(kOriginB, 10); + SetUsageMapEntry(kOriginOther, 500); + + origins = GetOriginsForHost(client, kTemp, kOriginA.host()); + EXPECT_EQ(2ul, origins.size()); + EXPECT_TRUE(origins.find(kOriginA) != origins.end()); + EXPECT_TRUE(origins.find(kOriginB) != origins.end()); + + origins = GetOriginsForHost(client, kTemp, kOriginOther.host()); + EXPECT_EQ(1ul, origins.size()); + EXPECT_TRUE(origins.find(kOriginOther) != origins.end()); + + origins = GetOriginsForHost(client, kPerm, kOriginA.host()); + EXPECT_TRUE(origins.empty()); + + Call_NotifyAppCacheDestroyed(client); + Call_OnQuotaManagerDestroyed(client); +} + +TEST_F(AppCacheQuotaClientTest, GetOriginsForType) { + AppCacheQuotaClient* client = CreateClient(); + Call_NotifyAppCacheReady(client); + + EXPECT_TRUE(GetOriginsForType(client, kTemp).empty()); + EXPECT_TRUE(GetOriginsForType(client, kPerm).empty()); + + SetUsageMapEntry(kOriginA, 1000); + SetUsageMapEntry(kOriginB, 10); + + std::set<GURL> origins = GetOriginsForType(client, kTemp); + EXPECT_EQ(2ul, origins.size()); + EXPECT_TRUE(origins.find(kOriginA) != origins.end()); + EXPECT_TRUE(origins.find(kOriginB) != origins.end()); + + EXPECT_TRUE(GetOriginsForType(client, kPerm).empty()); + + Call_NotifyAppCacheDestroyed(client); + Call_OnQuotaManagerDestroyed(client); +} + +TEST_F(AppCacheQuotaClientTest, DeleteOriginData) { + AppCacheQuotaClient* client = CreateClient(); + Call_NotifyAppCacheReady(client); + + // Perm deletions are short circuited in the Client and + // should not reach the AppCacheServiceImpl. + EXPECT_EQ(quota::kQuotaStatusOk, + DeleteOriginData(client, kPerm, kOriginA)); + EXPECT_EQ(0, mock_service_.delete_called_count()); + + EXPECT_EQ(quota::kQuotaStatusOk, + DeleteOriginData(client, kTemp, kOriginA)); + EXPECT_EQ(1, mock_service_.delete_called_count()); + + mock_service_.set_mock_delete_appcaches_for_origin_result( + net::ERR_ABORTED); + EXPECT_EQ(quota::kQuotaErrorAbort, + DeleteOriginData(client, kTemp, kOriginA)); + EXPECT_EQ(2, mock_service_.delete_called_count()); + + Call_OnQuotaManagerDestroyed(client); + Call_NotifyAppCacheDestroyed(client); +} + +TEST_F(AppCacheQuotaClientTest, PendingRequests) { + AppCacheQuotaClient* client = CreateClient(); + + SetUsageMapEntry(kOriginA, 1000); + SetUsageMapEntry(kOriginB, 10); + SetUsageMapEntry(kOriginOther, 500); + + // Queue up some reqeusts. + AsyncGetOriginUsage(client, kOriginA, kPerm); + AsyncGetOriginUsage(client, kOriginB, kTemp); + AsyncGetOriginsForType(client, kPerm); + AsyncGetOriginsForType(client, kTemp); + AsyncGetOriginsForHost(client, kTemp, kOriginA.host()); + AsyncGetOriginsForHost(client, kTemp, kOriginOther.host()); + AsyncDeleteOriginData(client, kTemp, kOriginA); + AsyncDeleteOriginData(client, kPerm, kOriginA); + AsyncDeleteOriginData(client, kTemp, kOriginB); + + EXPECT_EQ(0, num_get_origin_usage_completions_); + EXPECT_EQ(0, num_get_origins_completions_); + EXPECT_EQ(0, num_delete_origins_completions_); + base::RunLoop().RunUntilIdle(); + EXPECT_EQ(0, num_get_origin_usage_completions_); + EXPECT_EQ(0, num_get_origins_completions_); + EXPECT_EQ(0, num_delete_origins_completions_); + + // Pending requests should get serviced when the appcache is ready. + Call_NotifyAppCacheReady(client); + EXPECT_EQ(2, num_get_origin_usage_completions_); + EXPECT_EQ(4, num_get_origins_completions_); + EXPECT_EQ(0, num_delete_origins_completions_); + base::RunLoop().RunUntilIdle(); + EXPECT_EQ(3, num_delete_origins_completions_); // deletes are really async + + // They should be serviced in order requested. + EXPECT_EQ(10, usage_); + EXPECT_EQ(1ul, origins_.size()); + EXPECT_TRUE(origins_.find(kOriginOther) != origins_.end()); + + Call_NotifyAppCacheDestroyed(client); + Call_OnQuotaManagerDestroyed(client); +} + +TEST_F(AppCacheQuotaClientTest, DestroyServiceWithPending) { + AppCacheQuotaClient* client = CreateClient(); + + SetUsageMapEntry(kOriginA, 1000); + SetUsageMapEntry(kOriginB, 10); + SetUsageMapEntry(kOriginOther, 500); + + // Queue up some reqeusts prior to being ready. + AsyncGetOriginUsage(client, kOriginA, kPerm); + AsyncGetOriginUsage(client, kOriginB, kTemp); + AsyncGetOriginsForType(client, kPerm); + AsyncGetOriginsForType(client, kTemp); + AsyncGetOriginsForHost(client, kTemp, kOriginA.host()); + AsyncGetOriginsForHost(client, kTemp, kOriginOther.host()); + AsyncDeleteOriginData(client, kTemp, kOriginA); + AsyncDeleteOriginData(client, kPerm, kOriginA); + AsyncDeleteOriginData(client, kTemp, kOriginB); + base::RunLoop().RunUntilIdle(); + EXPECT_EQ(0, num_get_origin_usage_completions_); + EXPECT_EQ(0, num_get_origins_completions_); + EXPECT_EQ(0, num_delete_origins_completions_); + + // Kill the service. + Call_NotifyAppCacheDestroyed(client); + + // All should have been aborted and called completion. + EXPECT_EQ(2, num_get_origin_usage_completions_); + EXPECT_EQ(4, num_get_origins_completions_); + EXPECT_EQ(3, num_delete_origins_completions_); + EXPECT_EQ(0, usage_); + EXPECT_TRUE(origins_.empty()); + EXPECT_EQ(quota::kQuotaErrorAbort, delete_status_); + + Call_OnQuotaManagerDestroyed(client); +} + +TEST_F(AppCacheQuotaClientTest, DestroyQuotaManagerWithPending) { + AppCacheQuotaClient* client = CreateClient(); + + SetUsageMapEntry(kOriginA, 1000); + SetUsageMapEntry(kOriginB, 10); + SetUsageMapEntry(kOriginOther, 500); + + // Queue up some reqeusts prior to being ready. + AsyncGetOriginUsage(client, kOriginA, kPerm); + AsyncGetOriginUsage(client, kOriginB, kTemp); + AsyncGetOriginsForType(client, kPerm); + AsyncGetOriginsForType(client, kTemp); + AsyncGetOriginsForHost(client, kTemp, kOriginA.host()); + AsyncGetOriginsForHost(client, kTemp, kOriginOther.host()); + AsyncDeleteOriginData(client, kTemp, kOriginA); + AsyncDeleteOriginData(client, kPerm, kOriginA); + AsyncDeleteOriginData(client, kTemp, kOriginB); + base::RunLoop().RunUntilIdle(); + EXPECT_EQ(0, num_get_origin_usage_completions_); + EXPECT_EQ(0, num_get_origins_completions_); + EXPECT_EQ(0, num_delete_origins_completions_); + + // Kill the quota manager. + Call_OnQuotaManagerDestroyed(client); + Call_NotifyAppCacheReady(client); + + // Callbacks should be deleted and not called. + base::RunLoop().RunUntilIdle(); + EXPECT_EQ(0, num_get_origin_usage_completions_); + EXPECT_EQ(0, num_get_origins_completions_); + EXPECT_EQ(0, num_delete_origins_completions_); + + Call_NotifyAppCacheDestroyed(client); +} + +TEST_F(AppCacheQuotaClientTest, DestroyWithDeleteInProgress) { + AppCacheQuotaClient* client = CreateClient(); + Call_NotifyAppCacheReady(client); + + // Start an async delete. + AsyncDeleteOriginData(client, kTemp, kOriginB); + EXPECT_EQ(0, num_delete_origins_completions_); + + // Kill the service. + Call_NotifyAppCacheDestroyed(client); + + // Should have been aborted. + EXPECT_EQ(1, num_delete_origins_completions_); + EXPECT_EQ(quota::kQuotaErrorAbort, delete_status_); + + // A real completion callback from the service should + // be dropped if it comes in after NotifyAppCacheDestroyed. + base::RunLoop().RunUntilIdle(); + EXPECT_EQ(1, num_delete_origins_completions_); + EXPECT_EQ(quota::kQuotaErrorAbort, delete_status_); + + Call_OnQuotaManagerDestroyed(client); +} + +} // namespace content |