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/file_path.h"
9 #include "base/file_util.h"
10 #include "base/files/scoped_temp_dir.h"
11 #include "base/message_loop.h"
12 #include "base/message_loop_proxy.h"
13 #include "content/browser/browser_thread_impl.h"
14 #include "content/browser/in_process_webkit/indexed_db_context_impl.h"
15 #include "content/browser/in_process_webkit/indexed_db_quota_client.h"
16 #include "content/public/browser/storage_partition.h"
17 #include "content/public/test/test_browser_context.h"
18 #include "testing/gtest/include/gtest/gtest.h"
19 #include "webkit/database/database_util.h"
21 // Declared to shorten the line lengths.
22 static const quota::StorageType kTemp
= quota::kStorageTypeTemporary
;
23 static const quota::StorageType kPerm
= quota::kStorageTypePersistent
;
25 using namespace webkit_database
;
29 // Base class for our test fixtures.
30 class IndexedDBQuotaClientTest
: public testing::Test
{
34 const GURL kOriginOther
;
36 IndexedDBQuotaClientTest()
37 : kOriginA("http://host"),
38 kOriginB("http://host:8000"),
39 kOriginOther("http://other"),
41 weak_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)),
42 message_loop_(MessageLoop::TYPE_IO
),
43 db_thread_(BrowserThread::DB
, &message_loop_
),
44 webkit_thread_(BrowserThread::WEBKIT_DEPRECATED
, &message_loop_
),
45 file_thread_(BrowserThread::FILE, &message_loop_
),
46 file_user_blocking_thread_(
47 BrowserThread::FILE_USER_BLOCKING
, &message_loop_
),
48 io_thread_(BrowserThread::IO
, &message_loop_
) {
49 browser_context_
.reset(new TestBrowserContext());
50 idb_context_
= static_cast<IndexedDBContextImpl
*>(
51 BrowserContext::GetDefaultStoragePartition(browser_context_
.get())->
52 GetIndexedDBContext());
53 message_loop_
.RunUntilIdle();
56 void setup_temp_dir() {
57 ASSERT_TRUE(temp_dir_
.CreateUniqueTempDir());
58 FilePath indexeddb_dir
= temp_dir_
.path().Append(
59 IndexedDBContextImpl::kIndexedDBDirectory
);
60 ASSERT_TRUE(file_util::CreateDirectory(indexeddb_dir
));
61 idb_context()->set_data_path_for_testing(indexeddb_dir
);
64 ~IndexedDBQuotaClientTest() {
65 // IndexedDBContext needs to be destructed on
66 // BrowserThread::WEBKIT_DEPRECATED, which is also a member variable of this
67 // class. Cause IndexedDBContext's destruction now to ensure that it
68 // doesn't outlive BrowserThread::WEBKIT_DEPRECATED.
70 browser_context_
.reset();
71 MessageLoop::current()->RunUntilIdle();
75 quota::QuotaClient
* client
,
77 quota::StorageType type
) {
79 client
->GetOriginUsage(
81 base::Bind(&IndexedDBQuotaClientTest::OnGetOriginUsageComplete
,
82 weak_factory_
.GetWeakPtr()));
83 MessageLoop::current()->RunUntilIdle();
84 EXPECT_GT(usage_
, -1);
88 const std::set
<GURL
>& GetOriginsForType(
89 quota::QuotaClient
* client
,
90 quota::StorageType type
) {
92 type_
= quota::kStorageTypeTemporary
;
93 client
->GetOriginsForType(
95 base::Bind(&IndexedDBQuotaClientTest::OnGetOriginsComplete
,
96 weak_factory_
.GetWeakPtr()));
97 MessageLoop::current()->RunUntilIdle();
101 const std::set
<GURL
>& GetOriginsForHost(
102 quota::QuotaClient
* client
,
103 quota::StorageType type
,
104 const std::string
& host
) {
106 type_
= quota::kStorageTypeTemporary
;
107 client
->GetOriginsForHost(
109 base::Bind(&IndexedDBQuotaClientTest::OnGetOriginsComplete
,
110 weak_factory_
.GetWeakPtr()));
111 MessageLoop::current()->RunUntilIdle();
115 quota::QuotaStatusCode
DeleteOrigin(quota::QuotaClient
* client
,
116 const GURL
& origin_url
) {
117 delete_status_
= quota::kQuotaStatusUnknown
;
118 client
->DeleteOriginData(
120 base::Bind(&IndexedDBQuotaClientTest::OnDeleteOriginComplete
,
121 weak_factory_
.GetWeakPtr()));
122 MessageLoop::current()->RunUntilIdle();
123 return delete_status_
;
126 IndexedDBContextImpl
* idb_context() { return idb_context_
.get(); }
128 void SetFileSizeTo(const FilePath
& path
, int size
) {
129 std::string
junk(size
, 'a');
130 ASSERT_EQ(size
, file_util::WriteFile(path
, junk
.c_str(), size
));
133 void AddFakeIndexedDB(const GURL
& origin
, int size
) {
134 FilePath file_path_origin
= idb_context()->GetFilePathForTesting(
135 DatabaseUtil::GetOriginIdentifier(origin
));
136 if (!file_util::CreateDirectory(file_path_origin
)) {
137 LOG(ERROR
) << "failed to file_util::CreateDirectory "
138 << file_path_origin
.value();
140 file_path_origin
= file_path_origin
.Append(FILE_PATH_LITERAL("fake_file"));
141 SetFileSizeTo(file_path_origin
, size
);
142 idb_context()->ResetCaches();
146 void OnGetOriginUsageComplete(int64 usage
) {
150 void OnGetOriginsComplete(const std::set
<GURL
>& origins
,
151 quota::StorageType type
) {
156 void OnDeleteOriginComplete(quota::QuotaStatusCode code
) {
157 delete_status_
= code
;
160 base::ScopedTempDir temp_dir_
;
162 std::set
<GURL
> origins_
;
163 quota::StorageType type_
;
164 scoped_refptr
<IndexedDBContextImpl
> idb_context_
;
165 base::WeakPtrFactory
<IndexedDBQuotaClientTest
> weak_factory_
;
166 MessageLoop message_loop_
;
167 BrowserThreadImpl db_thread_
;
168 BrowserThreadImpl webkit_thread_
;
169 BrowserThreadImpl file_thread_
;
170 BrowserThreadImpl file_user_blocking_thread_
;
171 BrowserThreadImpl io_thread_
;
172 scoped_ptr
<TestBrowserContext
> browser_context_
;
173 quota::QuotaStatusCode delete_status_
;
176 TEST_F(IndexedDBQuotaClientTest
, GetOriginUsage
) {
177 IndexedDBQuotaClient
client(
178 base::MessageLoopProxy::current(),
181 AddFakeIndexedDB(kOriginA
, 6);
182 AddFakeIndexedDB(kOriginB
, 3);
183 EXPECT_EQ(6, GetOriginUsage(&client
, kOriginA
, kTemp
));
184 EXPECT_EQ(0, GetOriginUsage(&client
, kOriginA
, kPerm
));
185 EXPECT_EQ(3, GetOriginUsage(&client
, kOriginB
, kTemp
));
186 EXPECT_EQ(0, GetOriginUsage(&client
, kOriginB
, kPerm
));
188 AddFakeIndexedDB(kOriginA
, 1000);
189 EXPECT_EQ(1000, GetOriginUsage(&client
, kOriginA
, kTemp
));
190 EXPECT_EQ(0, GetOriginUsage(&client
, kOriginA
, kPerm
));
191 EXPECT_EQ(3, GetOriginUsage(&client
, kOriginB
, kTemp
));
192 EXPECT_EQ(0, GetOriginUsage(&client
, kOriginB
, kPerm
));
195 TEST_F(IndexedDBQuotaClientTest
, GetOriginsForHost
) {
196 IndexedDBQuotaClient
client(
197 base::MessageLoopProxy::current(),
200 EXPECT_EQ(kOriginA
.host(), kOriginB
.host());
201 EXPECT_NE(kOriginA
.host(), kOriginOther
.host());
203 std::set
<GURL
> origins
= GetOriginsForHost(&client
, kTemp
, kOriginA
.host());
204 EXPECT_TRUE(origins
.empty());
206 AddFakeIndexedDB(kOriginA
, 1000);
207 origins
= GetOriginsForHost(&client
, kTemp
, kOriginA
.host());
208 EXPECT_EQ(origins
.size(), 1ul);
209 EXPECT_TRUE(origins
.find(kOriginA
) != origins
.end());
211 AddFakeIndexedDB(kOriginB
, 1000);
212 origins
= GetOriginsForHost(&client
, kTemp
, kOriginA
.host());
213 EXPECT_EQ(origins
.size(), 2ul);
214 EXPECT_TRUE(origins
.find(kOriginA
) != origins
.end());
215 EXPECT_TRUE(origins
.find(kOriginB
) != origins
.end());
217 EXPECT_TRUE(GetOriginsForHost(&client
, kPerm
, kOriginA
.host()).empty());
218 EXPECT_TRUE(GetOriginsForHost(&client
, kTemp
, kOriginOther
.host()).empty());
221 TEST_F(IndexedDBQuotaClientTest
, GetOriginsForType
) {
222 IndexedDBQuotaClient
client(
223 base::MessageLoopProxy::current(),
226 EXPECT_TRUE(GetOriginsForType(&client
, kTemp
).empty());
227 EXPECT_TRUE(GetOriginsForType(&client
, kPerm
).empty());
229 AddFakeIndexedDB(kOriginA
, 1000);
230 std::set
<GURL
> origins
= GetOriginsForType(&client
, kTemp
);
231 EXPECT_EQ(origins
.size(), 1ul);
232 EXPECT_TRUE(origins
.find(kOriginA
) != origins
.end());
234 EXPECT_TRUE(GetOriginsForType(&client
, kPerm
).empty());
237 TEST_F(IndexedDBQuotaClientTest
, DeleteOrigin
) {
238 IndexedDBQuotaClient
client(
239 base::MessageLoopProxy::current(),
242 AddFakeIndexedDB(kOriginA
, 1000);
243 AddFakeIndexedDB(kOriginB
, 50);
244 EXPECT_EQ(1000, GetOriginUsage(&client
, kOriginA
, kTemp
));
245 EXPECT_EQ(50, GetOriginUsage(&client
, kOriginB
, kTemp
));
247 quota::QuotaStatusCode delete_status
= DeleteOrigin(&client
, kOriginA
);
248 EXPECT_EQ(quota::kQuotaStatusOk
, delete_status
);
249 EXPECT_EQ(0, GetOriginUsage(&client
, kOriginA
, kTemp
));
250 EXPECT_EQ(50, GetOriginUsage(&client
, kOriginB
, kTemp
));
253 } // namespace content