1 // Copyright 2014 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/location.h"
10 #include "base/run_loop.h"
11 #include "base/single_thread_task_runner.h"
12 #include "base/strings/utf_string_conversions.h"
13 #include "base/thread_task_runner_handle.h"
14 #include "net/base/completion_callback.h"
15 #include "net/base/net_errors.h"
16 #include "storage/browser/database/database_quota_client.h"
17 #include "storage/browser/database/database_tracker.h"
18 #include "storage/browser/database/database_util.h"
19 #include "storage/common/database/database_identifier.h"
20 #include "testing/gtest/include/gtest/gtest.h"
22 using storage::DatabaseQuotaClient
;
23 using storage::DatabaseTracker
;
24 using storage::OriginInfo
;
28 // Declared to shorten the line lengths.
29 static const storage::StorageType kTemp
= storage::kStorageTypeTemporary
;
30 static const storage::StorageType kPerm
= storage::kStorageTypePersistent
;
32 // Mock tracker class the mocks up those methods of the tracker
33 // that are used by the QuotaClient.
34 class MockDatabaseTracker
: public DatabaseTracker
{
37 : DatabaseTracker(base::FilePath(), false, NULL
, NULL
, NULL
),
38 delete_called_count_(0),
39 async_delete_(false) {}
41 bool GetOriginInfo(const std::string
& origin_identifier
,
42 OriginInfo
* info
) override
{
43 std::map
<GURL
, MockOriginInfo
>::const_iterator found
=
44 mock_origin_infos_
.find(
45 storage::GetOriginFromIdentifier(origin_identifier
));
46 if (found
== mock_origin_infos_
.end())
48 *info
= OriginInfo(found
->second
);
52 bool GetAllOriginIdentifiers(
53 std::vector
<std::string
>* origins_identifiers
) override
{
54 std::map
<GURL
, MockOriginInfo
>::const_iterator iter
;
55 for (iter
= mock_origin_infos_
.begin();
56 iter
!= mock_origin_infos_
.end();
58 origins_identifiers
->push_back(iter
->second
.GetOriginIdentifier());
63 bool GetAllOriginsInfo(std::vector
<OriginInfo
>* origins_info
) override
{
64 std::map
<GURL
, MockOriginInfo
>::const_iterator iter
;
65 for (iter
= mock_origin_infos_
.begin();
66 iter
!= mock_origin_infos_
.end();
68 origins_info
->push_back(OriginInfo(iter
->second
));
73 int DeleteDataForOrigin(const std::string
& origin_identifier
,
74 const net::CompletionCallback
& callback
) override
{
75 ++delete_called_count_
;
77 base::ThreadTaskRunnerHandle::Get()->PostTask(
78 FROM_HERE
, base::Bind(&MockDatabaseTracker::AsyncDeleteDataForOrigin
,
80 return net::ERR_IO_PENDING
;
85 void AsyncDeleteDataForOrigin(const net::CompletionCallback
& callback
) {
86 callback
.Run(net::OK
);
89 void AddMockDatabase(const GURL
& origin
, const char* name
, int size
) {
90 MockOriginInfo
& info
= mock_origin_infos_
[origin
];
91 info
.set_origin(storage::GetIdentifierFromOrigin(origin
));
92 info
.AddMockDatabase(base::ASCIIToUTF16(name
), size
);
95 int delete_called_count() { return delete_called_count_
; }
96 bool async_delete() { return async_delete_
; }
97 void set_async_delete(bool async
) { async_delete_
= async
; }
100 ~MockDatabaseTracker() override
{}
103 class MockOriginInfo
: public OriginInfo
{
105 void set_origin(const std::string
& origin_identifier
) {
106 origin_identifier_
= origin_identifier
;
109 void AddMockDatabase(const base::string16
& name
, int size
) {
110 EXPECT_TRUE(database_info_
.find(name
) == database_info_
.end());
111 database_info_
[name
].first
= size
;
116 int delete_called_count_
;
118 std::map
<GURL
, MockOriginInfo
> mock_origin_infos_
;
122 // Base class for our test fixtures.
123 class DatabaseQuotaClientTest
: public testing::Test
{
127 const GURL kOriginOther
;
129 DatabaseQuotaClientTest()
130 : kOriginA("http://host"),
131 kOriginB("http://host:8000"),
132 kOriginOther("http://other"),
134 mock_tracker_(new MockDatabaseTracker
),
135 weak_factory_(this) {
138 int64
GetOriginUsage(storage::QuotaClient
* client
,
140 storage::StorageType type
) {
142 client
->GetOriginUsage(
144 base::Bind(&DatabaseQuotaClientTest::OnGetOriginUsageComplete
,
145 weak_factory_
.GetWeakPtr()));
146 base::RunLoop().RunUntilIdle();
150 const std::set
<GURL
>& GetOriginsForType(storage::QuotaClient
* client
,
151 storage::StorageType type
) {
153 client
->GetOriginsForType(
155 base::Bind(&DatabaseQuotaClientTest::OnGetOriginsComplete
,
156 weak_factory_
.GetWeakPtr()));
157 base::RunLoop().RunUntilIdle();
161 const std::set
<GURL
>& GetOriginsForHost(storage::QuotaClient
* client
,
162 storage::StorageType type
,
163 const std::string
& host
) {
165 client
->GetOriginsForHost(
167 base::Bind(&DatabaseQuotaClientTest::OnGetOriginsComplete
,
168 weak_factory_
.GetWeakPtr()));
169 base::RunLoop().RunUntilIdle();
173 bool DeleteOriginData(storage::QuotaClient
* client
,
174 storage::StorageType type
,
175 const GURL
& origin
) {
176 delete_status_
= storage::kQuotaStatusUnknown
;
177 client
->DeleteOriginData(
179 base::Bind(&DatabaseQuotaClientTest::OnDeleteOriginDataComplete
,
180 weak_factory_
.GetWeakPtr()));
181 base::RunLoop().RunUntilIdle();
182 return delete_status_
== storage::kQuotaStatusOk
;
185 MockDatabaseTracker
* mock_tracker() { return mock_tracker_
.get(); }
189 void OnGetOriginUsageComplete(int64 usage
) {
193 void OnGetOriginsComplete(const std::set
<GURL
>& origins
) {
197 void OnDeleteOriginDataComplete(storage::QuotaStatusCode status
) {
198 delete_status_
= status
;
201 base::MessageLoop message_loop_
;
203 std::set
<GURL
> origins_
;
204 storage::QuotaStatusCode delete_status_
;
205 scoped_refptr
<MockDatabaseTracker
> mock_tracker_
;
206 base::WeakPtrFactory
<DatabaseQuotaClientTest
> weak_factory_
;
210 TEST_F(DatabaseQuotaClientTest
, GetOriginUsage
) {
211 DatabaseQuotaClient
client(base::ThreadTaskRunnerHandle::Get().get(),
214 EXPECT_EQ(0, GetOriginUsage(&client
, kOriginA
, kTemp
));
215 EXPECT_EQ(0, GetOriginUsage(&client
, kOriginA
, kPerm
));
217 mock_tracker()->AddMockDatabase(kOriginA
, "fooDB", 1000);
218 EXPECT_EQ(1000, GetOriginUsage(&client
, kOriginA
, kTemp
));
219 EXPECT_EQ(0, GetOriginUsage(&client
, kOriginA
, kPerm
));
221 EXPECT_EQ(0, GetOriginUsage(&client
, kOriginB
, kPerm
));
222 EXPECT_EQ(0, GetOriginUsage(&client
, kOriginB
, kTemp
));
225 TEST_F(DatabaseQuotaClientTest
, GetOriginsForHost
) {
226 DatabaseQuotaClient
client(base::ThreadTaskRunnerHandle::Get().get(),
229 EXPECT_EQ(kOriginA
.host(), kOriginB
.host());
230 EXPECT_NE(kOriginA
.host(), kOriginOther
.host());
232 std::set
<GURL
> origins
= GetOriginsForHost(&client
, kTemp
, kOriginA
.host());
233 EXPECT_TRUE(origins
.empty());
235 mock_tracker()->AddMockDatabase(kOriginA
, "fooDB", 1000);
236 origins
= GetOriginsForHost(&client
, kTemp
, kOriginA
.host());
237 EXPECT_EQ(origins
.size(), 1ul);
238 EXPECT_TRUE(origins
.find(kOriginA
) != origins
.end());
240 mock_tracker()->AddMockDatabase(kOriginB
, "barDB", 1000);
241 origins
= GetOriginsForHost(&client
, kTemp
, kOriginA
.host());
242 EXPECT_EQ(origins
.size(), 2ul);
243 EXPECT_TRUE(origins
.find(kOriginA
) != origins
.end());
244 EXPECT_TRUE(origins
.find(kOriginB
) != origins
.end());
246 EXPECT_TRUE(GetOriginsForHost(&client
, kPerm
, kOriginA
.host()).empty());
247 EXPECT_TRUE(GetOriginsForHost(&client
, kTemp
, kOriginOther
.host()).empty());
250 TEST_F(DatabaseQuotaClientTest
, GetOriginsForType
) {
251 DatabaseQuotaClient
client(base::ThreadTaskRunnerHandle::Get().get(),
254 EXPECT_TRUE(GetOriginsForType(&client
, kTemp
).empty());
255 EXPECT_TRUE(GetOriginsForType(&client
, kPerm
).empty());
257 mock_tracker()->AddMockDatabase(kOriginA
, "fooDB", 1000);
258 std::set
<GURL
> origins
= GetOriginsForType(&client
, kTemp
);
259 EXPECT_EQ(origins
.size(), 1ul);
260 EXPECT_TRUE(origins
.find(kOriginA
) != origins
.end());
262 EXPECT_TRUE(GetOriginsForType(&client
, kPerm
).empty());
265 TEST_F(DatabaseQuotaClientTest
, DeleteOriginData
) {
266 DatabaseQuotaClient
client(base::ThreadTaskRunnerHandle::Get().get(),
269 // Perm deletions are short circuited in the Client and
270 // should not reach the DatabaseTracker.
271 EXPECT_TRUE(DeleteOriginData(&client
, kPerm
, kOriginA
));
272 EXPECT_EQ(0, mock_tracker()->delete_called_count());
274 mock_tracker()->set_async_delete(false);
275 EXPECT_TRUE(DeleteOriginData(&client
, kTemp
, kOriginA
));
276 EXPECT_EQ(1, mock_tracker()->delete_called_count());
278 mock_tracker()->set_async_delete(true);
279 EXPECT_TRUE(DeleteOriginData(&client
, kTemp
, kOriginA
));
280 EXPECT_EQ(2, mock_tracker()->delete_called_count());
283 } // namespace content