1 // Copyright (c) 2011 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
8 #include "base/files/file_path.h"
9 #include "base/files/file_util.h"
10 #include "base/files/scoped_temp_dir.h"
11 #include "base/message_loop/message_loop.h"
12 #include "base/test/test_simple_task_runner.h"
13 #include "base/threading/thread.h"
14 #include "content/browser/browser_thread_impl.h"
15 #include "content/browser/indexed_db/indexed_db_context_impl.h"
16 #include "content/browser/indexed_db/indexed_db_quota_client.h"
17 #include "content/browser/quota/mock_quota_manager.h"
18 #include "content/public/browser/storage_partition.h"
19 #include "content/public/test/test_browser_context.h"
20 #include "content/public/test/test_browser_thread_bundle.h"
21 #include "storage/common/database/database_identifier.h"
22 #include "testing/gtest/include/gtest/gtest.h"
24 // Declared to shorten the line lengths.
25 static const storage::StorageType kTemp = storage::kStorageTypeTemporary;
26 static const storage::StorageType kPerm = storage::kStorageTypePersistent;
30 // Base class for our test fixtures.
31 class IndexedDBQuotaClientTest : public testing::Test {
35 const GURL kOriginOther;
37 IndexedDBQuotaClientTest()
38 : kOriginA("http://host"),
39 kOriginB("http://host:8000"),
40 kOriginOther("http://other"),
42 task_runner_(new base::TestSimpleTaskRunner),
44 browser_context_.reset(new TestBrowserContext());
46 scoped_refptr<storage::QuotaManager> quota_manager =
47 new MockQuotaManager(false /*in_memory*/,
48 browser_context_->GetPath(),
49 base::MessageLoop::current()->message_loop_proxy(),
50 base::MessageLoop::current()->message_loop_proxy(),
51 browser_context_->GetSpecialStoragePolicy());
54 new IndexedDBContextImpl(browser_context_->GetPath(),
55 browser_context_->GetSpecialStoragePolicy(),
56 quota_manager->proxy(),
58 base::MessageLoop::current()->RunUntilIdle();
62 void FlushIndexedDBTaskRunner() { task_runner_->RunUntilIdle(); }
64 void setup_temp_dir() {
65 ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
66 base::FilePath indexeddb_dir =
67 temp_dir_.path().Append(IndexedDBContextImpl::kIndexedDBDirectory);
68 ASSERT_TRUE(base::CreateDirectory(indexeddb_dir));
69 idb_context()->set_data_path_for_testing(indexeddb_dir);
72 ~IndexedDBQuotaClientTest() override {
73 FlushIndexedDBTaskRunner();
75 browser_context_.reset();
76 base::MessageLoop::current()->RunUntilIdle();
79 int64 GetOriginUsage(storage::QuotaClient* client,
81 storage::StorageType type) {
83 client->GetOriginUsage(
86 base::Bind(&IndexedDBQuotaClientTest::OnGetOriginUsageComplete,
87 weak_factory_.GetWeakPtr()));
88 FlushIndexedDBTaskRunner();
89 base::MessageLoop::current()->RunUntilIdle();
90 EXPECT_GT(usage_, -1);
94 const std::set<GURL>& GetOriginsForType(storage::QuotaClient* client,
95 storage::StorageType type) {
97 client->GetOriginsForType(
99 base::Bind(&IndexedDBQuotaClientTest::OnGetOriginsComplete,
100 weak_factory_.GetWeakPtr()));
101 FlushIndexedDBTaskRunner();
102 base::MessageLoop::current()->RunUntilIdle();
106 const std::set<GURL>& GetOriginsForHost(storage::QuotaClient* client,
107 storage::StorageType type,
108 const std::string& host) {
110 client->GetOriginsForHost(
113 base::Bind(&IndexedDBQuotaClientTest::OnGetOriginsComplete,
114 weak_factory_.GetWeakPtr()));
115 FlushIndexedDBTaskRunner();
116 base::MessageLoop::current()->RunUntilIdle();
120 storage::QuotaStatusCode DeleteOrigin(storage::QuotaClient* client,
121 const GURL& origin_url) {
122 delete_status_ = storage::kQuotaStatusUnknown;
123 client->DeleteOriginData(
126 base::Bind(&IndexedDBQuotaClientTest::OnDeleteOriginComplete,
127 weak_factory_.GetWeakPtr()));
128 FlushIndexedDBTaskRunner();
129 base::MessageLoop::current()->RunUntilIdle();
130 return delete_status_;
133 IndexedDBContextImpl* idb_context() { return idb_context_.get(); }
135 void SetFileSizeTo(const base::FilePath& path, int size) {
136 std::string junk(size, 'a');
137 ASSERT_EQ(size, base::WriteFile(path, junk.c_str(), size));
140 void AddFakeIndexedDB(const GURL& origin, int size) {
141 base::FilePath file_path_origin = idb_context()->GetFilePathForTesting(
142 storage::GetIdentifierFromOrigin(origin));
143 if (!base::CreateDirectory(file_path_origin)) {
144 LOG(ERROR) << "failed to base::CreateDirectory "
145 << file_path_origin.value();
147 file_path_origin = file_path_origin.Append(FILE_PATH_LITERAL("fake_file"));
148 SetFileSizeTo(file_path_origin, size);
149 idb_context()->ResetCaches();
153 void OnGetOriginUsageComplete(int64 usage) { usage_ = usage; }
155 void OnGetOriginsComplete(const std::set<GURL>& origins) {
159 void OnDeleteOriginComplete(storage::QuotaStatusCode code) {
160 delete_status_ = code;
163 base::ScopedTempDir temp_dir_;
165 std::set<GURL> origins_;
166 scoped_refptr<base::TestSimpleTaskRunner> task_runner_;
167 scoped_refptr<IndexedDBContextImpl> idb_context_;
168 content::TestBrowserThreadBundle thread_bundle_;
169 scoped_ptr<TestBrowserContext> browser_context_;
170 storage::QuotaStatusCode delete_status_;
171 base::WeakPtrFactory<IndexedDBQuotaClientTest> weak_factory_;
173 DISALLOW_COPY_AND_ASSIGN(IndexedDBQuotaClientTest);
176 TEST_F(IndexedDBQuotaClientTest, GetOriginUsage) {
177 IndexedDBQuotaClient client(idb_context());
179 AddFakeIndexedDB(kOriginA, 6);
180 AddFakeIndexedDB(kOriginB, 3);
181 EXPECT_EQ(6, GetOriginUsage(&client, kOriginA, kTemp));
182 EXPECT_EQ(0, GetOriginUsage(&client, kOriginA, kPerm));
183 EXPECT_EQ(3, GetOriginUsage(&client, kOriginB, kTemp));
184 EXPECT_EQ(0, GetOriginUsage(&client, kOriginB, kPerm));
186 AddFakeIndexedDB(kOriginA, 1000);
187 EXPECT_EQ(1000, GetOriginUsage(&client, kOriginA, kTemp));
188 EXPECT_EQ(0, GetOriginUsage(&client, kOriginA, kPerm));
189 EXPECT_EQ(3, GetOriginUsage(&client, kOriginB, kTemp));
190 EXPECT_EQ(0, GetOriginUsage(&client, kOriginB, kPerm));
193 TEST_F(IndexedDBQuotaClientTest, GetOriginsForHost) {
194 IndexedDBQuotaClient client(idb_context());
196 EXPECT_EQ(kOriginA.host(), kOriginB.host());
197 EXPECT_NE(kOriginA.host(), kOriginOther.host());
199 std::set<GURL> origins = GetOriginsForHost(&client, kTemp, kOriginA.host());
200 EXPECT_TRUE(origins.empty());
202 AddFakeIndexedDB(kOriginA, 1000);
203 origins = GetOriginsForHost(&client, kTemp, kOriginA.host());
204 EXPECT_EQ(origins.size(), 1ul);
205 EXPECT_TRUE(origins.find(kOriginA) != origins.end());
207 AddFakeIndexedDB(kOriginB, 1000);
208 origins = GetOriginsForHost(&client, kTemp, kOriginA.host());
209 EXPECT_EQ(origins.size(), 2ul);
210 EXPECT_TRUE(origins.find(kOriginA) != origins.end());
211 EXPECT_TRUE(origins.find(kOriginB) != origins.end());
213 EXPECT_TRUE(GetOriginsForHost(&client, kPerm, kOriginA.host()).empty());
214 EXPECT_TRUE(GetOriginsForHost(&client, kTemp, kOriginOther.host()).empty());
217 TEST_F(IndexedDBQuotaClientTest, GetOriginsForType) {
218 IndexedDBQuotaClient client(idb_context());
220 EXPECT_TRUE(GetOriginsForType(&client, kTemp).empty());
221 EXPECT_TRUE(GetOriginsForType(&client, kPerm).empty());
223 AddFakeIndexedDB(kOriginA, 1000);
224 std::set<GURL> origins = GetOriginsForType(&client, kTemp);
225 EXPECT_EQ(origins.size(), 1ul);
226 EXPECT_TRUE(origins.find(kOriginA) != origins.end());
228 EXPECT_TRUE(GetOriginsForType(&client, kPerm).empty());
231 TEST_F(IndexedDBQuotaClientTest, DeleteOrigin) {
232 IndexedDBQuotaClient client(idb_context());
234 AddFakeIndexedDB(kOriginA, 1000);
235 AddFakeIndexedDB(kOriginB, 50);
236 EXPECT_EQ(1000, GetOriginUsage(&client, kOriginA, kTemp));
237 EXPECT_EQ(50, GetOriginUsage(&client, kOriginB, kTemp));
239 storage::QuotaStatusCode delete_status = DeleteOrigin(&client, kOriginA);
240 EXPECT_EQ(storage::kQuotaStatusOk, delete_status);
241 EXPECT_EQ(0, GetOriginUsage(&client, kOriginA, kTemp));
242 EXPECT_EQ(50, GetOriginUsage(&client, kOriginB, kTemp));
245 } // namespace content