| Index: webkit/appcache/appcache_quota_client_unittest.cc
|
| ===================================================================
|
| --- webkit/appcache/appcache_quota_client_unittest.cc (revision 0)
|
| +++ webkit/appcache/appcache_quota_client_unittest.cc (revision 0)
|
| @@ -0,0 +1,429 @@
|
| +// Copyright (c) 2011 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 "base/memory/scoped_callback_factory.h"
|
| +#include "base/message_loop.h"
|
| +#include "base/message_loop_proxy.h"
|
| +#include "net/base/net_errors.h"
|
| +#include "testing/gtest/include/gtest/gtest.h"
|
| +#include "webkit/appcache/appcache_quota_client.h"
|
| +#include "webkit/appcache/mock_appcache_service.h"
|
| +
|
| +namespace appcache {
|
| +
|
| +// 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),
|
| + callback_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)) {
|
| + }
|
| +
|
| + int64 GetOriginUsage(
|
| + quota::QuotaClient* client,
|
| + const GURL& origin,
|
| + quota::StorageType type) {
|
| + usage_ = -1;
|
| + AsyncGetOriginUsage(client, origin, type);
|
| + MessageLoop::current()->RunAllPending();
|
| + return usage_;
|
| + }
|
| +
|
| + const std::set<GURL>& GetOriginsForType(
|
| + quota::QuotaClient* client,
|
| + quota::StorageType type) {
|
| + origins_.clear();
|
| + AsyncGetOriginsForType(client, type);
|
| + MessageLoop::current()->RunAllPending();
|
| + return origins_;
|
| + }
|
| +
|
| + const std::set<GURL>& GetOriginsForHost(
|
| + quota::QuotaClient* client,
|
| + quota::StorageType type,
|
| + const std::string& host) {
|
| + origins_.clear();
|
| + AsyncGetOriginsForHost(client, type, host);
|
| + MessageLoop::current()->RunAllPending();
|
| + return origins_;
|
| + }
|
| +
|
| + quota::QuotaStatusCode DeleteOriginData(
|
| + quota::QuotaClient* client,
|
| + quota::StorageType type,
|
| + const GURL& origin) {
|
| + delete_status_ = quota::kQuotaStatusUnknown;
|
| + AsyncDeleteOriginData(client, type, origin);
|
| + MessageLoop::current()->RunAllPending();
|
| + return delete_status_;
|
| + }
|
| +
|
| + void AsyncGetOriginUsage(
|
| + quota::QuotaClient* client,
|
| + const GURL& origin,
|
| + quota::StorageType type) {
|
| + client->GetOriginUsage(origin, type,
|
| + callback_factory_.NewCallback(
|
| + &AppCacheQuotaClientTest::OnGetOriginUsageComplete));
|
| + }
|
| +
|
| + void AsyncGetOriginsForType(
|
| + quota::QuotaClient* client,
|
| + quota::StorageType type) {
|
| + client->GetOriginsForType(type,
|
| + callback_factory_.NewCallback(
|
| + &AppCacheQuotaClientTest::OnGetOriginsComplete));
|
| + }
|
| +
|
| + void AsyncGetOriginsForHost(
|
| + quota::QuotaClient* client,
|
| + quota::StorageType type,
|
| + const std::string& host) {
|
| + client->GetOriginsForHost(type, host,
|
| + callback_factory_.NewCallback(
|
| + &AppCacheQuotaClientTest::OnGetOriginsComplete));
|
| + }
|
| +
|
| + void AsyncDeleteOriginData(
|
| + quota::QuotaClient* client,
|
| + quota::StorageType type,
|
| + const GURL& origin) {
|
| + client->DeleteOriginData(origin, type,
|
| + callback_factory_.NewCallback(
|
| + &AppCacheQuotaClientTest::OnDeleteOriginDataComplete));
|
| + }
|
| +
|
| + 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;
|
| + }
|
| +
|
| + 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::ScopedCallbackFactory<AppCacheQuotaClientTest> callback_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 AppCacheService.
|
| + 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_);
|
| + MessageLoop::current()->RunAllPending();
|
| + 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_);
|
| + MessageLoop::current()->RunAllPending();
|
| + 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);
|
| + MessageLoop::current()->RunAllPending();
|
| + 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);
|
| + MessageLoop::current()->RunAllPending();
|
| + 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.
|
| + MessageLoop::current()->RunAllPending();
|
| + 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.
|
| + MessageLoop::current()->RunAllPending();
|
| + EXPECT_EQ(1, num_delete_origins_completions_);
|
| + EXPECT_EQ(quota::kQuotaErrorAbort, delete_status_);
|
| +
|
| + Call_OnQuotaManagerDestroyed(client);
|
| +}
|
| +
|
| +} // namespace appcache
|
|
|
| Property changes on: webkit\appcache\appcache_quota_client_unittest.cc
|
| ___________________________________________________________________
|
| Added: svn:eol-style
|
| + LF
|
|
|
|
|