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.
9 #include "base/message_loop/message_loop_proxy.h"
10 #include "base/run_loop.h"
11 #include "content/browser/appcache/appcache_quota_client.h"
12 #include "content/browser/appcache/mock_appcache_service.h"
13 #include "net/base/net_errors.h"
14 #include "testing/gtest/include/gtest/gtest.h"
18 // Declared to shorten the line lengths.
19 static const storage::StorageType kTemp
= storage::kStorageTypeTemporary
;
20 static const storage::StorageType kPerm
= storage::kStorageTypePersistent
;
22 // Base class for our test fixtures.
23 class AppCacheQuotaClientTest
: public testing::Test
{
27 const GURL kOriginOther
;
29 AppCacheQuotaClientTest()
30 : kOriginA("http://host"),
31 kOriginB("http://host:8000"),
32 kOriginOther("http://other"),
34 delete_status_(storage::kQuotaStatusUnknown
),
35 num_get_origin_usage_completions_(0),
36 num_get_origins_completions_(0),
37 num_delete_origins_completions_(0),
38 weak_factory_(this) {}
40 int64
GetOriginUsage(storage::QuotaClient
* client
,
42 storage::StorageType type
) {
44 AsyncGetOriginUsage(client
, origin
, type
);
45 base::RunLoop().RunUntilIdle();
49 const std::set
<GURL
>& GetOriginsForType(storage::QuotaClient
* client
,
50 storage::StorageType type
) {
52 AsyncGetOriginsForType(client
, type
);
53 base::RunLoop().RunUntilIdle();
57 const std::set
<GURL
>& GetOriginsForHost(storage::QuotaClient
* client
,
58 storage::StorageType type
,
59 const std::string
& host
) {
61 AsyncGetOriginsForHost(client
, type
, host
);
62 base::RunLoop().RunUntilIdle();
66 storage::QuotaStatusCode
DeleteOriginData(storage::QuotaClient
* client
,
67 storage::StorageType type
,
69 delete_status_
= storage::kQuotaStatusUnknown
;
70 AsyncDeleteOriginData(client
, type
, origin
);
71 base::RunLoop().RunUntilIdle();
72 return delete_status_
;
75 void AsyncGetOriginUsage(storage::QuotaClient
* client
,
77 storage::StorageType type
) {
78 client
->GetOriginUsage(
80 base::Bind(&AppCacheQuotaClientTest::OnGetOriginUsageComplete
,
81 weak_factory_
.GetWeakPtr()));
84 void AsyncGetOriginsForType(storage::QuotaClient
* client
,
85 storage::StorageType type
) {
86 client
->GetOriginsForType(
88 base::Bind(&AppCacheQuotaClientTest::OnGetOriginsComplete
,
89 weak_factory_
.GetWeakPtr()));
92 void AsyncGetOriginsForHost(storage::QuotaClient
* client
,
93 storage::StorageType type
,
94 const std::string
& host
) {
95 client
->GetOriginsForHost(
97 base::Bind(&AppCacheQuotaClientTest::OnGetOriginsComplete
,
98 weak_factory_
.GetWeakPtr()));
101 void AsyncDeleteOriginData(storage::QuotaClient
* client
,
102 storage::StorageType type
,
103 const GURL
& origin
) {
104 client
->DeleteOriginData(
106 base::Bind(&AppCacheQuotaClientTest::OnDeleteOriginDataComplete
,
107 weak_factory_
.GetWeakPtr()));
110 void SetUsageMapEntry(const GURL
& origin
, int64 usage
) {
111 mock_service_
.storage()->usage_map_
[origin
] = usage
;
114 AppCacheQuotaClient
* CreateClient() {
115 return new AppCacheQuotaClient(&mock_service_
);
118 void Call_NotifyAppCacheReady(AppCacheQuotaClient
* client
) {
119 client
->NotifyAppCacheReady();
122 void Call_NotifyAppCacheDestroyed(AppCacheQuotaClient
* client
) {
123 client
->NotifyAppCacheDestroyed();
126 void Call_OnQuotaManagerDestroyed(AppCacheQuotaClient
* client
) {
127 client
->OnQuotaManagerDestroyed();
131 void OnGetOriginUsageComplete(int64 usage
) {
132 ++num_get_origin_usage_completions_
;
136 void OnGetOriginsComplete(const std::set
<GURL
>& origins
) {
137 ++num_get_origins_completions_
;
141 void OnDeleteOriginDataComplete(storage::QuotaStatusCode status
) {
142 ++num_delete_origins_completions_
;
143 delete_status_
= status
;
146 base::MessageLoop message_loop_
;
148 std::set
<GURL
> origins_
;
149 storage::QuotaStatusCode delete_status_
;
150 int num_get_origin_usage_completions_
;
151 int num_get_origins_completions_
;
152 int num_delete_origins_completions_
;
153 MockAppCacheService mock_service_
;
154 base::WeakPtrFactory
<AppCacheQuotaClientTest
> weak_factory_
;
158 TEST_F(AppCacheQuotaClientTest
, BasicCreateDestroy
) {
159 AppCacheQuotaClient
* client
= CreateClient();
160 Call_NotifyAppCacheReady(client
);
161 Call_OnQuotaManagerDestroyed(client
);
162 Call_NotifyAppCacheDestroyed(client
);
165 TEST_F(AppCacheQuotaClientTest
, EmptyService
) {
166 AppCacheQuotaClient
* client
= CreateClient();
167 Call_NotifyAppCacheReady(client
);
169 EXPECT_EQ(0, GetOriginUsage(client
, kOriginA
, kTemp
));
170 EXPECT_EQ(0, GetOriginUsage(client
, kOriginA
, kPerm
));
171 EXPECT_TRUE(GetOriginsForType(client
, kTemp
).empty());
172 EXPECT_TRUE(GetOriginsForType(client
, kPerm
).empty());
173 EXPECT_TRUE(GetOriginsForHost(client
, kTemp
, kOriginA
.host()).empty());
174 EXPECT_TRUE(GetOriginsForHost(client
, kPerm
, kOriginA
.host()).empty());
175 EXPECT_EQ(storage::kQuotaStatusOk
, DeleteOriginData(client
, kTemp
, kOriginA
));
176 EXPECT_EQ(storage::kQuotaStatusOk
, DeleteOriginData(client
, kPerm
, kOriginA
));
178 Call_NotifyAppCacheDestroyed(client
);
179 Call_OnQuotaManagerDestroyed(client
);
182 TEST_F(AppCacheQuotaClientTest
, NoService
) {
183 AppCacheQuotaClient
* client
= CreateClient();
184 Call_NotifyAppCacheReady(client
);
185 Call_NotifyAppCacheDestroyed(client
);
187 EXPECT_EQ(0, GetOriginUsage(client
, kOriginA
, kTemp
));
188 EXPECT_EQ(0, GetOriginUsage(client
, kOriginA
, kPerm
));
189 EXPECT_TRUE(GetOriginsForType(client
, kTemp
).empty());
190 EXPECT_TRUE(GetOriginsForType(client
, kPerm
).empty());
191 EXPECT_TRUE(GetOriginsForHost(client
, kTemp
, kOriginA
.host()).empty());
192 EXPECT_TRUE(GetOriginsForHost(client
, kPerm
, kOriginA
.host()).empty());
193 EXPECT_EQ(storage::kQuotaErrorAbort
,
194 DeleteOriginData(client
, kTemp
, kOriginA
));
195 EXPECT_EQ(storage::kQuotaErrorAbort
,
196 DeleteOriginData(client
, kPerm
, kOriginA
));
198 Call_OnQuotaManagerDestroyed(client
);
201 TEST_F(AppCacheQuotaClientTest
, GetOriginUsage
) {
202 AppCacheQuotaClient
* client
= CreateClient();
203 Call_NotifyAppCacheReady(client
);
205 SetUsageMapEntry(kOriginA
, 1000);
206 EXPECT_EQ(1000, GetOriginUsage(client
, kOriginA
, kTemp
));
207 EXPECT_EQ(0, GetOriginUsage(client
, kOriginA
, kPerm
));
209 Call_NotifyAppCacheDestroyed(client
);
210 Call_OnQuotaManagerDestroyed(client
);
213 TEST_F(AppCacheQuotaClientTest
, GetOriginsForHost
) {
214 AppCacheQuotaClient
* client
= CreateClient();
215 Call_NotifyAppCacheReady(client
);
217 EXPECT_EQ(kOriginA
.host(), kOriginB
.host());
218 EXPECT_NE(kOriginA
.host(), kOriginOther
.host());
220 std::set
<GURL
> origins
= GetOriginsForHost(client
, kTemp
, kOriginA
.host());
221 EXPECT_TRUE(origins
.empty());
223 SetUsageMapEntry(kOriginA
, 1000);
224 SetUsageMapEntry(kOriginB
, 10);
225 SetUsageMapEntry(kOriginOther
, 500);
227 origins
= GetOriginsForHost(client
, kTemp
, kOriginA
.host());
228 EXPECT_EQ(2ul, origins
.size());
229 EXPECT_TRUE(origins
.find(kOriginA
) != origins
.end());
230 EXPECT_TRUE(origins
.find(kOriginB
) != origins
.end());
232 origins
= GetOriginsForHost(client
, kTemp
, kOriginOther
.host());
233 EXPECT_EQ(1ul, origins
.size());
234 EXPECT_TRUE(origins
.find(kOriginOther
) != origins
.end());
236 origins
= GetOriginsForHost(client
, kPerm
, kOriginA
.host());
237 EXPECT_TRUE(origins
.empty());
239 Call_NotifyAppCacheDestroyed(client
);
240 Call_OnQuotaManagerDestroyed(client
);
243 TEST_F(AppCacheQuotaClientTest
, GetOriginsForType
) {
244 AppCacheQuotaClient
* client
= CreateClient();
245 Call_NotifyAppCacheReady(client
);
247 EXPECT_TRUE(GetOriginsForType(client
, kTemp
).empty());
248 EXPECT_TRUE(GetOriginsForType(client
, kPerm
).empty());
250 SetUsageMapEntry(kOriginA
, 1000);
251 SetUsageMapEntry(kOriginB
, 10);
253 std::set
<GURL
> origins
= GetOriginsForType(client
, kTemp
);
254 EXPECT_EQ(2ul, origins
.size());
255 EXPECT_TRUE(origins
.find(kOriginA
) != origins
.end());
256 EXPECT_TRUE(origins
.find(kOriginB
) != origins
.end());
258 EXPECT_TRUE(GetOriginsForType(client
, kPerm
).empty());
260 Call_NotifyAppCacheDestroyed(client
);
261 Call_OnQuotaManagerDestroyed(client
);
264 TEST_F(AppCacheQuotaClientTest
, DeleteOriginData
) {
265 AppCacheQuotaClient
* client
= CreateClient();
266 Call_NotifyAppCacheReady(client
);
268 // Perm deletions are short circuited in the Client and
269 // should not reach the AppCacheServiceImpl.
270 EXPECT_EQ(storage::kQuotaStatusOk
, DeleteOriginData(client
, kPerm
, kOriginA
));
271 EXPECT_EQ(0, mock_service_
.delete_called_count());
273 EXPECT_EQ(storage::kQuotaStatusOk
, DeleteOriginData(client
, kTemp
, kOriginA
));
274 EXPECT_EQ(1, mock_service_
.delete_called_count());
276 mock_service_
.set_mock_delete_appcaches_for_origin_result(
278 EXPECT_EQ(storage::kQuotaErrorAbort
,
279 DeleteOriginData(client
, kTemp
, kOriginA
));
280 EXPECT_EQ(2, mock_service_
.delete_called_count());
282 Call_OnQuotaManagerDestroyed(client
);
283 Call_NotifyAppCacheDestroyed(client
);
286 TEST_F(AppCacheQuotaClientTest
, PendingRequests
) {
287 AppCacheQuotaClient
* client
= CreateClient();
289 SetUsageMapEntry(kOriginA
, 1000);
290 SetUsageMapEntry(kOriginB
, 10);
291 SetUsageMapEntry(kOriginOther
, 500);
293 // Queue up some reqeusts.
294 AsyncGetOriginUsage(client
, kOriginA
, kPerm
);
295 AsyncGetOriginUsage(client
, kOriginB
, kTemp
);
296 AsyncGetOriginsForType(client
, kPerm
);
297 AsyncGetOriginsForType(client
, kTemp
);
298 AsyncGetOriginsForHost(client
, kTemp
, kOriginA
.host());
299 AsyncGetOriginsForHost(client
, kTemp
, kOriginOther
.host());
300 AsyncDeleteOriginData(client
, kTemp
, kOriginA
);
301 AsyncDeleteOriginData(client
, kPerm
, kOriginA
);
302 AsyncDeleteOriginData(client
, kTemp
, kOriginB
);
304 EXPECT_EQ(0, num_get_origin_usage_completions_
);
305 EXPECT_EQ(0, num_get_origins_completions_
);
306 EXPECT_EQ(0, num_delete_origins_completions_
);
307 base::RunLoop().RunUntilIdle();
308 EXPECT_EQ(0, num_get_origin_usage_completions_
);
309 EXPECT_EQ(0, num_get_origins_completions_
);
310 EXPECT_EQ(0, num_delete_origins_completions_
);
312 // Pending requests should get serviced when the appcache is ready.
313 Call_NotifyAppCacheReady(client
);
314 EXPECT_EQ(2, num_get_origin_usage_completions_
);
315 EXPECT_EQ(4, num_get_origins_completions_
);
316 EXPECT_EQ(0, num_delete_origins_completions_
);
317 base::RunLoop().RunUntilIdle();
318 EXPECT_EQ(3, num_delete_origins_completions_
); // deletes are really async
320 // They should be serviced in order requested.
321 EXPECT_EQ(10, usage_
);
322 EXPECT_EQ(1ul, origins_
.size());
323 EXPECT_TRUE(origins_
.find(kOriginOther
) != origins_
.end());
325 Call_NotifyAppCacheDestroyed(client
);
326 Call_OnQuotaManagerDestroyed(client
);
329 TEST_F(AppCacheQuotaClientTest
, DestroyServiceWithPending
) {
330 AppCacheQuotaClient
* client
= CreateClient();
332 SetUsageMapEntry(kOriginA
, 1000);
333 SetUsageMapEntry(kOriginB
, 10);
334 SetUsageMapEntry(kOriginOther
, 500);
336 // Queue up some reqeusts prior to being ready.
337 AsyncGetOriginUsage(client
, kOriginA
, kPerm
);
338 AsyncGetOriginUsage(client
, kOriginB
, kTemp
);
339 AsyncGetOriginsForType(client
, kPerm
);
340 AsyncGetOriginsForType(client
, kTemp
);
341 AsyncGetOriginsForHost(client
, kTemp
, kOriginA
.host());
342 AsyncGetOriginsForHost(client
, kTemp
, kOriginOther
.host());
343 AsyncDeleteOriginData(client
, kTemp
, kOriginA
);
344 AsyncDeleteOriginData(client
, kPerm
, kOriginA
);
345 AsyncDeleteOriginData(client
, kTemp
, kOriginB
);
346 base::RunLoop().RunUntilIdle();
347 EXPECT_EQ(0, num_get_origin_usage_completions_
);
348 EXPECT_EQ(0, num_get_origins_completions_
);
349 EXPECT_EQ(0, num_delete_origins_completions_
);
352 Call_NotifyAppCacheDestroyed(client
);
354 // All should have been aborted and called completion.
355 EXPECT_EQ(2, num_get_origin_usage_completions_
);
356 EXPECT_EQ(4, num_get_origins_completions_
);
357 EXPECT_EQ(3, num_delete_origins_completions_
);
358 EXPECT_EQ(0, usage_
);
359 EXPECT_TRUE(origins_
.empty());
360 EXPECT_EQ(storage::kQuotaErrorAbort
, delete_status_
);
362 Call_OnQuotaManagerDestroyed(client
);
365 TEST_F(AppCacheQuotaClientTest
, DestroyQuotaManagerWithPending
) {
366 AppCacheQuotaClient
* client
= CreateClient();
368 SetUsageMapEntry(kOriginA
, 1000);
369 SetUsageMapEntry(kOriginB
, 10);
370 SetUsageMapEntry(kOriginOther
, 500);
372 // Queue up some reqeusts prior to being ready.
373 AsyncGetOriginUsage(client
, kOriginA
, kPerm
);
374 AsyncGetOriginUsage(client
, kOriginB
, kTemp
);
375 AsyncGetOriginsForType(client
, kPerm
);
376 AsyncGetOriginsForType(client
, kTemp
);
377 AsyncGetOriginsForHost(client
, kTemp
, kOriginA
.host());
378 AsyncGetOriginsForHost(client
, kTemp
, kOriginOther
.host());
379 AsyncDeleteOriginData(client
, kTemp
, kOriginA
);
380 AsyncDeleteOriginData(client
, kPerm
, kOriginA
);
381 AsyncDeleteOriginData(client
, kTemp
, kOriginB
);
382 base::RunLoop().RunUntilIdle();
383 EXPECT_EQ(0, num_get_origin_usage_completions_
);
384 EXPECT_EQ(0, num_get_origins_completions_
);
385 EXPECT_EQ(0, num_delete_origins_completions_
);
387 // Kill the quota manager.
388 Call_OnQuotaManagerDestroyed(client
);
389 Call_NotifyAppCacheReady(client
);
391 // Callbacks should be deleted and not called.
392 base::RunLoop().RunUntilIdle();
393 EXPECT_EQ(0, num_get_origin_usage_completions_
);
394 EXPECT_EQ(0, num_get_origins_completions_
);
395 EXPECT_EQ(0, num_delete_origins_completions_
);
397 Call_NotifyAppCacheDestroyed(client
);
400 TEST_F(AppCacheQuotaClientTest
, DestroyWithDeleteInProgress
) {
401 AppCacheQuotaClient
* client
= CreateClient();
402 Call_NotifyAppCacheReady(client
);
404 // Start an async delete.
405 AsyncDeleteOriginData(client
, kTemp
, kOriginB
);
406 EXPECT_EQ(0, num_delete_origins_completions_
);
409 Call_NotifyAppCacheDestroyed(client
);
411 // Should have been aborted.
412 EXPECT_EQ(1, num_delete_origins_completions_
);
413 EXPECT_EQ(storage::kQuotaErrorAbort
, delete_status_
);
415 // A real completion callback from the service should
416 // be dropped if it comes in after NotifyAppCacheDestroyed.
417 base::RunLoop().RunUntilIdle();
418 EXPECT_EQ(1, num_delete_origins_completions_
);
419 EXPECT_EQ(storage::kQuotaErrorAbort
, delete_status_
);
421 Call_OnQuotaManagerDestroyed(client
);
424 } // namespace content