Upstream version 7.35.144.0
[platform/framework/web/crosswalk.git] / src / webkit / browser / appcache / appcache_quota_client_unittest.cc
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.
4
5 #include <map>
6 #include <set>
7
8 #include "base/bind.h"
9 #include "base/message_loop/message_loop_proxy.h"
10 #include "base/run_loop.h"
11 #include "net/base/net_errors.h"
12 #include "testing/gtest/include/gtest/gtest.h"
13 #include "webkit/browser/appcache/appcache_quota_client.h"
14 #include "webkit/browser/appcache/mock_appcache_service.h"
15
16 namespace appcache {
17
18 // Declared to shorten the line lengths.
19 static const quota::StorageType kTemp = quota::kStorageTypeTemporary;
20 static const quota::StorageType kPerm = quota::kStorageTypePersistent;
21
22 // Base class for our test fixtures.
23 class AppCacheQuotaClientTest : public testing::Test {
24  public:
25   const GURL kOriginA;
26   const GURL kOriginB;
27   const GURL kOriginOther;
28
29   AppCacheQuotaClientTest()
30       : kOriginA("http://host"),
31         kOriginB("http://host:8000"),
32         kOriginOther("http://other"),
33         usage_(0),
34         delete_status_(quota::kQuotaStatusUnknown),
35         num_get_origin_usage_completions_(0),
36         num_get_origins_completions_(0),
37         num_delete_origins_completions_(0),
38         weak_factory_(this) {
39   }
40
41   int64 GetOriginUsage(
42       quota::QuotaClient* client,
43       const GURL& origin,
44       quota::StorageType type) {
45     usage_ = -1;
46     AsyncGetOriginUsage(client, origin, type);
47     base::RunLoop().RunUntilIdle();
48     return usage_;
49   }
50
51   const std::set<GURL>& GetOriginsForType(
52       quota::QuotaClient* client,
53       quota::StorageType type) {
54     origins_.clear();
55     AsyncGetOriginsForType(client, type);
56     base::RunLoop().RunUntilIdle();
57     return origins_;
58   }
59
60   const std::set<GURL>& GetOriginsForHost(
61       quota::QuotaClient* client,
62       quota::StorageType type,
63       const std::string& host) {
64     origins_.clear();
65     AsyncGetOriginsForHost(client, type, host);
66     base::RunLoop().RunUntilIdle();
67     return origins_;
68   }
69
70   quota::QuotaStatusCode DeleteOriginData(
71       quota::QuotaClient* client,
72       quota::StorageType type,
73       const GURL& origin) {
74     delete_status_ = quota::kQuotaStatusUnknown;
75     AsyncDeleteOriginData(client, type, origin);
76     base::RunLoop().RunUntilIdle();
77     return delete_status_;
78   }
79
80   void AsyncGetOriginUsage(
81       quota::QuotaClient* client,
82       const GURL& origin,
83       quota::StorageType type) {
84     client->GetOriginUsage(
85         origin, type,
86         base::Bind(&AppCacheQuotaClientTest::OnGetOriginUsageComplete,
87                    weak_factory_.GetWeakPtr()));
88   }
89
90   void AsyncGetOriginsForType(
91       quota::QuotaClient* client,
92       quota::StorageType type) {
93     client->GetOriginsForType(
94         type,
95         base::Bind(&AppCacheQuotaClientTest::OnGetOriginsComplete,
96                    weak_factory_.GetWeakPtr()));
97   }
98
99   void AsyncGetOriginsForHost(
100       quota::QuotaClient* client,
101       quota::StorageType type,
102       const std::string& host) {
103     client->GetOriginsForHost(
104         type, host,
105         base::Bind(&AppCacheQuotaClientTest::OnGetOriginsComplete,
106                    weak_factory_.GetWeakPtr()));
107   }
108
109   void AsyncDeleteOriginData(
110       quota::QuotaClient* client,
111       quota::StorageType type,
112       const GURL& origin) {
113     client->DeleteOriginData(
114         origin, type,
115         base::Bind(&AppCacheQuotaClientTest::OnDeleteOriginDataComplete,
116                    weak_factory_.GetWeakPtr()));
117   }
118
119   void SetUsageMapEntry(const GURL& origin, int64 usage) {
120     mock_service_.storage()->usage_map_[origin] = usage;
121   }
122
123   AppCacheQuotaClient* CreateClient() {
124     return new AppCacheQuotaClient(&mock_service_);
125   }
126
127   void Call_NotifyAppCacheReady(AppCacheQuotaClient* client) {
128     client->NotifyAppCacheReady();
129   }
130
131   void Call_NotifyAppCacheDestroyed(AppCacheQuotaClient* client) {
132     client->NotifyAppCacheDestroyed();
133   }
134
135   void Call_OnQuotaManagerDestroyed(AppCacheQuotaClient* client) {
136     client->OnQuotaManagerDestroyed();
137   }
138
139  protected:
140   void OnGetOriginUsageComplete(int64 usage) {
141     ++num_get_origin_usage_completions_;
142     usage_ = usage;
143   }
144
145   void OnGetOriginsComplete(const std::set<GURL>& origins) {
146     ++num_get_origins_completions_;
147     origins_ = origins;
148   }
149
150   void OnDeleteOriginDataComplete(quota::QuotaStatusCode status) {
151     ++num_delete_origins_completions_;
152     delete_status_ = status;
153   }
154
155   base::MessageLoop message_loop_;
156   int64 usage_;
157   std::set<GURL> origins_;
158   quota::QuotaStatusCode delete_status_;
159   int num_get_origin_usage_completions_;
160   int num_get_origins_completions_;
161   int num_delete_origins_completions_;
162   MockAppCacheService mock_service_;
163   base::WeakPtrFactory<AppCacheQuotaClientTest> weak_factory_;
164 };
165
166
167 TEST_F(AppCacheQuotaClientTest, BasicCreateDestroy) {
168   AppCacheQuotaClient* client = CreateClient();
169   Call_NotifyAppCacheReady(client);
170   Call_OnQuotaManagerDestroyed(client);
171   Call_NotifyAppCacheDestroyed(client);
172 }
173
174 TEST_F(AppCacheQuotaClientTest, EmptyService) {
175   AppCacheQuotaClient* client = CreateClient();
176   Call_NotifyAppCacheReady(client);
177
178   EXPECT_EQ(0, GetOriginUsage(client, kOriginA, kTemp));
179   EXPECT_EQ(0, GetOriginUsage(client, kOriginA, kPerm));
180   EXPECT_TRUE(GetOriginsForType(client, kTemp).empty());
181   EXPECT_TRUE(GetOriginsForType(client, kPerm).empty());
182   EXPECT_TRUE(GetOriginsForHost(client, kTemp, kOriginA.host()).empty());
183   EXPECT_TRUE(GetOriginsForHost(client, kPerm, kOriginA.host()).empty());
184   EXPECT_EQ(quota::kQuotaStatusOk, DeleteOriginData(client, kTemp, kOriginA));
185   EXPECT_EQ(quota::kQuotaStatusOk, DeleteOriginData(client, kPerm, kOriginA));
186
187   Call_NotifyAppCacheDestroyed(client);
188   Call_OnQuotaManagerDestroyed(client);
189 }
190
191 TEST_F(AppCacheQuotaClientTest, NoService) {
192   AppCacheQuotaClient* client = CreateClient();
193   Call_NotifyAppCacheReady(client);
194   Call_NotifyAppCacheDestroyed(client);
195
196   EXPECT_EQ(0, GetOriginUsage(client, kOriginA, kTemp));
197   EXPECT_EQ(0, GetOriginUsage(client, kOriginA, kPerm));
198   EXPECT_TRUE(GetOriginsForType(client, kTemp).empty());
199   EXPECT_TRUE(GetOriginsForType(client, kPerm).empty());
200   EXPECT_TRUE(GetOriginsForHost(client, kTemp, kOriginA.host()).empty());
201   EXPECT_TRUE(GetOriginsForHost(client, kPerm, kOriginA.host()).empty());
202   EXPECT_EQ(quota::kQuotaErrorAbort,
203             DeleteOriginData(client, kTemp, kOriginA));
204   EXPECT_EQ(quota::kQuotaErrorAbort,
205             DeleteOriginData(client, kPerm, kOriginA));
206
207   Call_OnQuotaManagerDestroyed(client);
208 }
209
210 TEST_F(AppCacheQuotaClientTest, GetOriginUsage) {
211   AppCacheQuotaClient* client = CreateClient();
212   Call_NotifyAppCacheReady(client);
213
214   SetUsageMapEntry(kOriginA, 1000);
215   EXPECT_EQ(1000, GetOriginUsage(client, kOriginA, kTemp));
216   EXPECT_EQ(0, GetOriginUsage(client, kOriginA, kPerm));
217
218   Call_NotifyAppCacheDestroyed(client);
219   Call_OnQuotaManagerDestroyed(client);
220 }
221
222 TEST_F(AppCacheQuotaClientTest, GetOriginsForHost) {
223   AppCacheQuotaClient* client = CreateClient();
224   Call_NotifyAppCacheReady(client);
225
226   EXPECT_EQ(kOriginA.host(), kOriginB.host());
227   EXPECT_NE(kOriginA.host(), kOriginOther.host());
228
229   std::set<GURL> origins = GetOriginsForHost(client, kTemp, kOriginA.host());
230   EXPECT_TRUE(origins.empty());
231
232   SetUsageMapEntry(kOriginA, 1000);
233   SetUsageMapEntry(kOriginB, 10);
234   SetUsageMapEntry(kOriginOther, 500);
235
236   origins = GetOriginsForHost(client, kTemp, kOriginA.host());
237   EXPECT_EQ(2ul, origins.size());
238   EXPECT_TRUE(origins.find(kOriginA) != origins.end());
239   EXPECT_TRUE(origins.find(kOriginB) != origins.end());
240
241   origins = GetOriginsForHost(client, kTemp, kOriginOther.host());
242   EXPECT_EQ(1ul, origins.size());
243   EXPECT_TRUE(origins.find(kOriginOther) != origins.end());
244
245   origins = GetOriginsForHost(client, kPerm, kOriginA.host());
246   EXPECT_TRUE(origins.empty());
247
248   Call_NotifyAppCacheDestroyed(client);
249   Call_OnQuotaManagerDestroyed(client);
250 }
251
252 TEST_F(AppCacheQuotaClientTest, GetOriginsForType) {
253   AppCacheQuotaClient* client = CreateClient();
254   Call_NotifyAppCacheReady(client);
255
256   EXPECT_TRUE(GetOriginsForType(client, kTemp).empty());
257   EXPECT_TRUE(GetOriginsForType(client, kPerm).empty());
258
259   SetUsageMapEntry(kOriginA, 1000);
260   SetUsageMapEntry(kOriginB, 10);
261
262   std::set<GURL> origins = GetOriginsForType(client, kTemp);
263   EXPECT_EQ(2ul, origins.size());
264   EXPECT_TRUE(origins.find(kOriginA) != origins.end());
265   EXPECT_TRUE(origins.find(kOriginB) != origins.end());
266
267   EXPECT_TRUE(GetOriginsForType(client, kPerm).empty());
268
269   Call_NotifyAppCacheDestroyed(client);
270   Call_OnQuotaManagerDestroyed(client);
271 }
272
273 TEST_F(AppCacheQuotaClientTest, DeleteOriginData) {
274   AppCacheQuotaClient* client = CreateClient();
275   Call_NotifyAppCacheReady(client);
276
277   // Perm deletions are short circuited in the Client and
278   // should not reach the AppCacheService.
279   EXPECT_EQ(quota::kQuotaStatusOk,
280             DeleteOriginData(client, kPerm, kOriginA));
281   EXPECT_EQ(0, mock_service_.delete_called_count());
282
283   EXPECT_EQ(quota::kQuotaStatusOk,
284             DeleteOriginData(client, kTemp, kOriginA));
285   EXPECT_EQ(1, mock_service_.delete_called_count());
286
287   mock_service_.set_mock_delete_appcaches_for_origin_result(
288       net::ERR_ABORTED);
289   EXPECT_EQ(quota::kQuotaErrorAbort,
290             DeleteOriginData(client, kTemp, kOriginA));
291   EXPECT_EQ(2, mock_service_.delete_called_count());
292
293   Call_OnQuotaManagerDestroyed(client);
294   Call_NotifyAppCacheDestroyed(client);
295 }
296
297 TEST_F(AppCacheQuotaClientTest, PendingRequests) {
298   AppCacheQuotaClient* client = CreateClient();
299
300   SetUsageMapEntry(kOriginA, 1000);
301   SetUsageMapEntry(kOriginB, 10);
302   SetUsageMapEntry(kOriginOther, 500);
303
304   // Queue up some reqeusts.
305   AsyncGetOriginUsage(client, kOriginA, kPerm);
306   AsyncGetOriginUsage(client, kOriginB, kTemp);
307   AsyncGetOriginsForType(client, kPerm);
308   AsyncGetOriginsForType(client, kTemp);
309   AsyncGetOriginsForHost(client, kTemp, kOriginA.host());
310   AsyncGetOriginsForHost(client, kTemp, kOriginOther.host());
311   AsyncDeleteOriginData(client, kTemp, kOriginA);
312   AsyncDeleteOriginData(client, kPerm, kOriginA);
313   AsyncDeleteOriginData(client, kTemp, kOriginB);
314
315   EXPECT_EQ(0, num_get_origin_usage_completions_);
316   EXPECT_EQ(0, num_get_origins_completions_);
317   EXPECT_EQ(0, num_delete_origins_completions_);
318   base::RunLoop().RunUntilIdle();
319   EXPECT_EQ(0, num_get_origin_usage_completions_);
320   EXPECT_EQ(0, num_get_origins_completions_);
321   EXPECT_EQ(0, num_delete_origins_completions_);
322
323   // Pending requests should get serviced when the appcache is ready.
324   Call_NotifyAppCacheReady(client);
325   EXPECT_EQ(2, num_get_origin_usage_completions_);
326   EXPECT_EQ(4, num_get_origins_completions_);
327   EXPECT_EQ(0, num_delete_origins_completions_);
328   base::RunLoop().RunUntilIdle();
329   EXPECT_EQ(3, num_delete_origins_completions_);  // deletes are really async
330
331   // They should be serviced in order requested.
332   EXPECT_EQ(10, usage_);
333   EXPECT_EQ(1ul, origins_.size());
334   EXPECT_TRUE(origins_.find(kOriginOther) != origins_.end());
335
336   Call_NotifyAppCacheDestroyed(client);
337   Call_OnQuotaManagerDestroyed(client);
338 }
339
340 TEST_F(AppCacheQuotaClientTest, DestroyServiceWithPending) {
341   AppCacheQuotaClient* client = CreateClient();
342
343   SetUsageMapEntry(kOriginA, 1000);
344   SetUsageMapEntry(kOriginB, 10);
345   SetUsageMapEntry(kOriginOther, 500);
346
347   // Queue up some reqeusts prior to being ready.
348   AsyncGetOriginUsage(client, kOriginA, kPerm);
349   AsyncGetOriginUsage(client, kOriginB, kTemp);
350   AsyncGetOriginsForType(client, kPerm);
351   AsyncGetOriginsForType(client, kTemp);
352   AsyncGetOriginsForHost(client, kTemp, kOriginA.host());
353   AsyncGetOriginsForHost(client, kTemp, kOriginOther.host());
354   AsyncDeleteOriginData(client, kTemp, kOriginA);
355   AsyncDeleteOriginData(client, kPerm, kOriginA);
356   AsyncDeleteOriginData(client, kTemp, kOriginB);
357   base::RunLoop().RunUntilIdle();
358   EXPECT_EQ(0, num_get_origin_usage_completions_);
359   EXPECT_EQ(0, num_get_origins_completions_);
360   EXPECT_EQ(0, num_delete_origins_completions_);
361
362   // Kill the service.
363   Call_NotifyAppCacheDestroyed(client);
364
365   // All should have been aborted and called completion.
366   EXPECT_EQ(2, num_get_origin_usage_completions_);
367   EXPECT_EQ(4, num_get_origins_completions_);
368   EXPECT_EQ(3, num_delete_origins_completions_);
369   EXPECT_EQ(0, usage_);
370   EXPECT_TRUE(origins_.empty());
371   EXPECT_EQ(quota::kQuotaErrorAbort, delete_status_);
372
373   Call_OnQuotaManagerDestroyed(client);
374 }
375
376 TEST_F(AppCacheQuotaClientTest, DestroyQuotaManagerWithPending) {
377   AppCacheQuotaClient* client = CreateClient();
378
379   SetUsageMapEntry(kOriginA, 1000);
380   SetUsageMapEntry(kOriginB, 10);
381   SetUsageMapEntry(kOriginOther, 500);
382
383   // Queue up some reqeusts prior to being ready.
384   AsyncGetOriginUsage(client, kOriginA, kPerm);
385   AsyncGetOriginUsage(client, kOriginB, kTemp);
386   AsyncGetOriginsForType(client, kPerm);
387   AsyncGetOriginsForType(client, kTemp);
388   AsyncGetOriginsForHost(client, kTemp, kOriginA.host());
389   AsyncGetOriginsForHost(client, kTemp, kOriginOther.host());
390   AsyncDeleteOriginData(client, kTemp, kOriginA);
391   AsyncDeleteOriginData(client, kPerm, kOriginA);
392   AsyncDeleteOriginData(client, kTemp, kOriginB);
393   base::RunLoop().RunUntilIdle();
394   EXPECT_EQ(0, num_get_origin_usage_completions_);
395   EXPECT_EQ(0, num_get_origins_completions_);
396   EXPECT_EQ(0, num_delete_origins_completions_);
397
398   // Kill the quota manager.
399   Call_OnQuotaManagerDestroyed(client);
400   Call_NotifyAppCacheReady(client);
401
402   // Callbacks should be deleted and not called.
403   base::RunLoop().RunUntilIdle();
404   EXPECT_EQ(0, num_get_origin_usage_completions_);
405   EXPECT_EQ(0, num_get_origins_completions_);
406   EXPECT_EQ(0, num_delete_origins_completions_);
407
408   Call_NotifyAppCacheDestroyed(client);
409 }
410
411 TEST_F(AppCacheQuotaClientTest, DestroyWithDeleteInProgress) {
412   AppCacheQuotaClient* client = CreateClient();
413   Call_NotifyAppCacheReady(client);
414
415   // Start an async delete.
416   AsyncDeleteOriginData(client, kTemp, kOriginB);
417   EXPECT_EQ(0, num_delete_origins_completions_);
418
419   // Kill the service.
420   Call_NotifyAppCacheDestroyed(client);
421
422   // Should have been aborted.
423   EXPECT_EQ(1, num_delete_origins_completions_);
424   EXPECT_EQ(quota::kQuotaErrorAbort, delete_status_);
425
426   // A real completion callback from the service should
427   // be dropped if it comes in after NotifyAppCacheDestroyed.
428   base::RunLoop().RunUntilIdle();
429   EXPECT_EQ(1, num_delete_origins_completions_);
430   EXPECT_EQ(quota::kQuotaErrorAbort, delete_status_);
431
432   Call_OnQuotaManagerDestroyed(client);
433 }
434
435 }  // namespace appcache