1 // Copyright (c) 2012 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/message_loop.h"
10 #include "base/message_loop_proxy.h"
11 #include "base/utf_string_conversions.h"
12 #include "net/base/completion_callback.h"
13 #include "net/base/net_errors.h"
14 #include "testing/gtest/include/gtest/gtest.h"
15 #include "webkit/base/origin_url_conversions.h"
16 #include "webkit/database/database_quota_client.h"
17 #include "webkit/database/database_tracker.h"
18 #include "webkit/database/database_util.h"
20 namespace webkit_database
{
22 // Declared to shorten the line lengths.
23 static const quota::StorageType kTemp
= quota::kStorageTypeTemporary
;
24 static const quota::StorageType kPerm
= quota::kStorageTypePersistent
;
26 // Mock tracker class the mocks up those methods of the tracker
27 // that are used by the QuotaClient.
28 class MockDatabaseTracker
: public DatabaseTracker
{
31 : DatabaseTracker(base::FilePath(), false, NULL
, NULL
, NULL
),
32 delete_called_count_(0),
33 async_delete_(false) {}
35 virtual bool GetOriginInfo(
36 const base::string16
& origin_identifier
,
37 OriginInfo
* info
) OVERRIDE
{
38 std::map
<GURL
, MockOriginInfo
>::const_iterator found
=
39 mock_origin_infos_
.find(
40 webkit_base::GetOriginURLFromIdentifier(origin_identifier
));
41 if (found
== mock_origin_infos_
.end())
43 *info
= OriginInfo(found
->second
);
47 virtual bool GetAllOriginIdentifiers(
48 std::vector
<base::string16
>* origins_identifiers
) OVERRIDE
{
49 std::map
<GURL
, MockOriginInfo
>::const_iterator iter
;
50 for (iter
= mock_origin_infos_
.begin();
51 iter
!= mock_origin_infos_
.end();
53 origins_identifiers
->push_back(iter
->second
.GetOrigin());
58 virtual bool GetAllOriginsInfo(
59 std::vector
<OriginInfo
>* origins_info
) OVERRIDE
{
60 std::map
<GURL
, MockOriginInfo
>::const_iterator iter
;
61 for (iter
= mock_origin_infos_
.begin();
62 iter
!= mock_origin_infos_
.end();
64 origins_info
->push_back(OriginInfo(iter
->second
));
69 virtual int DeleteDataForOrigin(
70 const base::string16
& origin_id
,
71 const net::CompletionCallback
& callback
) OVERRIDE
{
72 ++delete_called_count_
;
74 base::MessageLoopProxy::current()->PostTask(
76 base::Bind(&MockDatabaseTracker::AsyncDeleteDataForOrigin
, this,
78 return net::ERR_IO_PENDING
;
83 void AsyncDeleteDataForOrigin(const net::CompletionCallback
& callback
) {
84 callback
.Run(net::OK
);
87 void AddMockDatabase(const GURL
& origin
, const char* name
, int size
) {
88 MockOriginInfo
& info
= mock_origin_infos_
[origin
];
89 info
.set_origin(webkit_base::GetOriginIdentifierFromURL(origin
));
90 info
.AddMockDatabase(ASCIIToUTF16(name
), size
);
93 int delete_called_count() { return delete_called_count_
; }
94 bool async_delete() { return async_delete_
; }
95 void set_async_delete(bool async
) { async_delete_
= async
; }
98 virtual ~MockDatabaseTracker() {}
101 class MockOriginInfo
: public OriginInfo
{
103 void set_origin(const base::string16
& origin_id
) {
107 void AddMockDatabase(const base::string16
& name
, int size
) {
108 EXPECT_TRUE(database_info_
.find(name
) == database_info_
.end());
109 database_info_
[name
].first
= size
;
114 int delete_called_count_
;
116 std::map
<GURL
, MockOriginInfo
> mock_origin_infos_
;
120 // Base class for our test fixtures.
121 class DatabaseQuotaClientTest
: public testing::Test
{
125 const GURL kOriginOther
;
127 DatabaseQuotaClientTest()
128 : kOriginA("http://host"),
129 kOriginB("http://host:8000"),
130 kOriginOther("http://other"),
132 mock_tracker_(new MockDatabaseTracker
),
133 weak_factory_(this) {
136 int64
GetOriginUsage(
137 quota::QuotaClient
* client
,
139 quota::StorageType type
) {
141 client
->GetOriginUsage(
143 base::Bind(&DatabaseQuotaClientTest::OnGetOriginUsageComplete
,
144 weak_factory_
.GetWeakPtr()));
145 base::MessageLoop::current()->RunUntilIdle();
149 const std::set
<GURL
>& GetOriginsForType(
150 quota::QuotaClient
* client
,
151 quota::StorageType type
) {
153 client
->GetOriginsForType(
155 base::Bind(&DatabaseQuotaClientTest::OnGetOriginsComplete
,
156 weak_factory_
.GetWeakPtr()));
157 base::MessageLoop::current()->RunUntilIdle();
161 const std::set
<GURL
>& GetOriginsForHost(
162 quota::QuotaClient
* client
,
163 quota::StorageType type
,
164 const std::string
& host
) {
166 client
->GetOriginsForHost(
168 base::Bind(&DatabaseQuotaClientTest::OnGetOriginsComplete
,
169 weak_factory_
.GetWeakPtr()));
170 base::MessageLoop::current()->RunUntilIdle();
174 bool DeleteOriginData(
175 quota::QuotaClient
* client
,
176 quota::StorageType type
,
177 const GURL
& origin
) {
178 delete_status_
= quota::kQuotaStatusUnknown
;
179 client
->DeleteOriginData(
181 base::Bind(&DatabaseQuotaClientTest::OnDeleteOriginDataComplete
,
182 weak_factory_
.GetWeakPtr()));
183 base::MessageLoop::current()->RunUntilIdle();
184 return delete_status_
== quota::kQuotaStatusOk
;
187 MockDatabaseTracker
* mock_tracker() { return mock_tracker_
.get(); }
191 void OnGetOriginUsageComplete(int64 usage
) {
195 void OnGetOriginsComplete(const std::set
<GURL
>& origins
,
196 quota::StorageType type
) {
201 void OnDeleteOriginDataComplete(quota::QuotaStatusCode status
) {
202 delete_status_
= status
;
205 base::MessageLoop message_loop_
;
207 std::set
<GURL
> origins_
;
208 quota::StorageType type_
;
209 quota::QuotaStatusCode delete_status_
;
210 scoped_refptr
<MockDatabaseTracker
> mock_tracker_
;
211 base::WeakPtrFactory
<DatabaseQuotaClientTest
> weak_factory_
;
215 TEST_F(DatabaseQuotaClientTest
, GetOriginUsage
) {
216 DatabaseQuotaClient
client(
217 base::MessageLoopProxy::current(),
220 EXPECT_EQ(0, GetOriginUsage(&client
, kOriginA
, kTemp
));
221 EXPECT_EQ(0, GetOriginUsage(&client
, kOriginA
, kPerm
));
223 mock_tracker()->AddMockDatabase(kOriginA
, "fooDB", 1000);
224 EXPECT_EQ(1000, GetOriginUsage(&client
, kOriginA
, kTemp
));
225 EXPECT_EQ(0, GetOriginUsage(&client
, kOriginA
, kPerm
));
227 EXPECT_EQ(0, GetOriginUsage(&client
, kOriginB
, kPerm
));
228 EXPECT_EQ(0, GetOriginUsage(&client
, kOriginB
, kTemp
));
231 TEST_F(DatabaseQuotaClientTest
, GetOriginsForHost
) {
232 DatabaseQuotaClient
client(
233 base::MessageLoopProxy::current(),
236 EXPECT_EQ(kOriginA
.host(), kOriginB
.host());
237 EXPECT_NE(kOriginA
.host(), kOriginOther
.host());
239 std::set
<GURL
> origins
= GetOriginsForHost(&client
, kTemp
, kOriginA
.host());
240 EXPECT_TRUE(origins
.empty());
242 mock_tracker()->AddMockDatabase(kOriginA
, "fooDB", 1000);
243 origins
= GetOriginsForHost(&client
, kTemp
, kOriginA
.host());
244 EXPECT_EQ(origins
.size(), 1ul);
245 EXPECT_TRUE(origins
.find(kOriginA
) != origins
.end());
247 mock_tracker()->AddMockDatabase(kOriginB
, "barDB", 1000);
248 origins
= GetOriginsForHost(&client
, kTemp
, kOriginA
.host());
249 EXPECT_EQ(origins
.size(), 2ul);
250 EXPECT_TRUE(origins
.find(kOriginA
) != origins
.end());
251 EXPECT_TRUE(origins
.find(kOriginB
) != origins
.end());
253 EXPECT_TRUE(GetOriginsForHost(&client
, kPerm
, kOriginA
.host()).empty());
254 EXPECT_TRUE(GetOriginsForHost(&client
, kTemp
, kOriginOther
.host()).empty());
257 TEST_F(DatabaseQuotaClientTest
, GetOriginsForType
) {
258 DatabaseQuotaClient
client(
259 base::MessageLoopProxy::current(),
262 EXPECT_TRUE(GetOriginsForType(&client
, kTemp
).empty());
263 EXPECT_TRUE(GetOriginsForType(&client
, kPerm
).empty());
265 mock_tracker()->AddMockDatabase(kOriginA
, "fooDB", 1000);
266 std::set
<GURL
> origins
= GetOriginsForType(&client
, kTemp
);
267 EXPECT_EQ(origins
.size(), 1ul);
268 EXPECT_TRUE(origins
.find(kOriginA
) != origins
.end());
270 EXPECT_TRUE(GetOriginsForType(&client
, kPerm
).empty());
273 TEST_F(DatabaseQuotaClientTest
, DeleteOriginData
) {
274 DatabaseQuotaClient
client(
275 base::MessageLoopProxy::current(),
278 // Perm deletions are short circuited in the Client and
279 // should not reach the DatabaseTracker.
280 EXPECT_TRUE(DeleteOriginData(&client
, kPerm
, kOriginA
));
281 EXPECT_EQ(0, mock_tracker()->delete_called_count());
283 mock_tracker()->set_async_delete(false);
284 EXPECT_TRUE(DeleteOriginData(&client
, kTemp
, kOriginA
));
285 EXPECT_EQ(1, mock_tracker()->delete_called_count());
287 mock_tracker()->set_async_delete(true);
288 EXPECT_TRUE(DeleteOriginData(&client
, kTemp
, kOriginA
));
289 EXPECT_EQ(2, mock_tracker()->delete_called_count());
292 } // namespace webkit_database