Upstream version 10.39.225.0
[platform/framework/web/crosswalk.git] / src / content / browser / appcache / appcache_quota_client_unittest.cc
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.
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 "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"
15
16 namespace content {
17
18 // Declared to shorten the line lengths.
19 static const storage::StorageType kTemp = storage::kStorageTypeTemporary;
20 static const storage::StorageType kPerm = storage::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_(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) {}
39
40   int64 GetOriginUsage(storage::QuotaClient* client,
41                        const GURL& origin,
42                        storage::StorageType type) {
43     usage_ = -1;
44     AsyncGetOriginUsage(client, origin, type);
45     base::RunLoop().RunUntilIdle();
46     return usage_;
47   }
48
49   const std::set<GURL>& GetOriginsForType(storage::QuotaClient* client,
50                                           storage::StorageType type) {
51     origins_.clear();
52     AsyncGetOriginsForType(client, type);
53     base::RunLoop().RunUntilIdle();
54     return origins_;
55   }
56
57   const std::set<GURL>& GetOriginsForHost(storage::QuotaClient* client,
58                                           storage::StorageType type,
59                                           const std::string& host) {
60     origins_.clear();
61     AsyncGetOriginsForHost(client, type, host);
62     base::RunLoop().RunUntilIdle();
63     return origins_;
64   }
65
66   storage::QuotaStatusCode DeleteOriginData(storage::QuotaClient* client,
67                                             storage::StorageType type,
68                                             const GURL& origin) {
69     delete_status_ = storage::kQuotaStatusUnknown;
70     AsyncDeleteOriginData(client, type, origin);
71     base::RunLoop().RunUntilIdle();
72     return delete_status_;
73   }
74
75   void AsyncGetOriginUsage(storage::QuotaClient* client,
76                            const GURL& origin,
77                            storage::StorageType type) {
78     client->GetOriginUsage(
79         origin, type,
80         base::Bind(&AppCacheQuotaClientTest::OnGetOriginUsageComplete,
81                    weak_factory_.GetWeakPtr()));
82   }
83
84   void AsyncGetOriginsForType(storage::QuotaClient* client,
85                               storage::StorageType type) {
86     client->GetOriginsForType(
87         type,
88         base::Bind(&AppCacheQuotaClientTest::OnGetOriginsComplete,
89                    weak_factory_.GetWeakPtr()));
90   }
91
92   void AsyncGetOriginsForHost(storage::QuotaClient* client,
93                               storage::StorageType type,
94                               const std::string& host) {
95     client->GetOriginsForHost(
96         type, host,
97         base::Bind(&AppCacheQuotaClientTest::OnGetOriginsComplete,
98                    weak_factory_.GetWeakPtr()));
99   }
100
101   void AsyncDeleteOriginData(storage::QuotaClient* client,
102                              storage::StorageType type,
103                              const GURL& origin) {
104     client->DeleteOriginData(
105         origin, type,
106         base::Bind(&AppCacheQuotaClientTest::OnDeleteOriginDataComplete,
107                    weak_factory_.GetWeakPtr()));
108   }
109
110   void SetUsageMapEntry(const GURL& origin, int64 usage) {
111     mock_service_.storage()->usage_map_[origin] = usage;
112   }
113
114   AppCacheQuotaClient* CreateClient() {
115     return new AppCacheQuotaClient(&mock_service_);
116   }
117
118   void Call_NotifyAppCacheReady(AppCacheQuotaClient* client) {
119     client->NotifyAppCacheReady();
120   }
121
122   void Call_NotifyAppCacheDestroyed(AppCacheQuotaClient* client) {
123     client->NotifyAppCacheDestroyed();
124   }
125
126   void Call_OnQuotaManagerDestroyed(AppCacheQuotaClient* client) {
127     client->OnQuotaManagerDestroyed();
128   }
129
130  protected:
131   void OnGetOriginUsageComplete(int64 usage) {
132     ++num_get_origin_usage_completions_;
133     usage_ = usage;
134   }
135
136   void OnGetOriginsComplete(const std::set<GURL>& origins) {
137     ++num_get_origins_completions_;
138     origins_ = origins;
139   }
140
141   void OnDeleteOriginDataComplete(storage::QuotaStatusCode status) {
142     ++num_delete_origins_completions_;
143     delete_status_ = status;
144   }
145
146   base::MessageLoop message_loop_;
147   int64 usage_;
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_;
155 };
156
157
158 TEST_F(AppCacheQuotaClientTest, BasicCreateDestroy) {
159   AppCacheQuotaClient* client = CreateClient();
160   Call_NotifyAppCacheReady(client);
161   Call_OnQuotaManagerDestroyed(client);
162   Call_NotifyAppCacheDestroyed(client);
163 }
164
165 TEST_F(AppCacheQuotaClientTest, EmptyService) {
166   AppCacheQuotaClient* client = CreateClient();
167   Call_NotifyAppCacheReady(client);
168
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));
177
178   Call_NotifyAppCacheDestroyed(client);
179   Call_OnQuotaManagerDestroyed(client);
180 }
181
182 TEST_F(AppCacheQuotaClientTest, NoService) {
183   AppCacheQuotaClient* client = CreateClient();
184   Call_NotifyAppCacheReady(client);
185   Call_NotifyAppCacheDestroyed(client);
186
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));
197
198   Call_OnQuotaManagerDestroyed(client);
199 }
200
201 TEST_F(AppCacheQuotaClientTest, GetOriginUsage) {
202   AppCacheQuotaClient* client = CreateClient();
203   Call_NotifyAppCacheReady(client);
204
205   SetUsageMapEntry(kOriginA, 1000);
206   EXPECT_EQ(1000, GetOriginUsage(client, kOriginA, kTemp));
207   EXPECT_EQ(0, GetOriginUsage(client, kOriginA, kPerm));
208
209   Call_NotifyAppCacheDestroyed(client);
210   Call_OnQuotaManagerDestroyed(client);
211 }
212
213 TEST_F(AppCacheQuotaClientTest, GetOriginsForHost) {
214   AppCacheQuotaClient* client = CreateClient();
215   Call_NotifyAppCacheReady(client);
216
217   EXPECT_EQ(kOriginA.host(), kOriginB.host());
218   EXPECT_NE(kOriginA.host(), kOriginOther.host());
219
220   std::set<GURL> origins = GetOriginsForHost(client, kTemp, kOriginA.host());
221   EXPECT_TRUE(origins.empty());
222
223   SetUsageMapEntry(kOriginA, 1000);
224   SetUsageMapEntry(kOriginB, 10);
225   SetUsageMapEntry(kOriginOther, 500);
226
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());
231
232   origins = GetOriginsForHost(client, kTemp, kOriginOther.host());
233   EXPECT_EQ(1ul, origins.size());
234   EXPECT_TRUE(origins.find(kOriginOther) != origins.end());
235
236   origins = GetOriginsForHost(client, kPerm, kOriginA.host());
237   EXPECT_TRUE(origins.empty());
238
239   Call_NotifyAppCacheDestroyed(client);
240   Call_OnQuotaManagerDestroyed(client);
241 }
242
243 TEST_F(AppCacheQuotaClientTest, GetOriginsForType) {
244   AppCacheQuotaClient* client = CreateClient();
245   Call_NotifyAppCacheReady(client);
246
247   EXPECT_TRUE(GetOriginsForType(client, kTemp).empty());
248   EXPECT_TRUE(GetOriginsForType(client, kPerm).empty());
249
250   SetUsageMapEntry(kOriginA, 1000);
251   SetUsageMapEntry(kOriginB, 10);
252
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());
257
258   EXPECT_TRUE(GetOriginsForType(client, kPerm).empty());
259
260   Call_NotifyAppCacheDestroyed(client);
261   Call_OnQuotaManagerDestroyed(client);
262 }
263
264 TEST_F(AppCacheQuotaClientTest, DeleteOriginData) {
265   AppCacheQuotaClient* client = CreateClient();
266   Call_NotifyAppCacheReady(client);
267
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());
272
273   EXPECT_EQ(storage::kQuotaStatusOk, DeleteOriginData(client, kTemp, kOriginA));
274   EXPECT_EQ(1, mock_service_.delete_called_count());
275
276   mock_service_.set_mock_delete_appcaches_for_origin_result(
277       net::ERR_ABORTED);
278   EXPECT_EQ(storage::kQuotaErrorAbort,
279             DeleteOriginData(client, kTemp, kOriginA));
280   EXPECT_EQ(2, mock_service_.delete_called_count());
281
282   Call_OnQuotaManagerDestroyed(client);
283   Call_NotifyAppCacheDestroyed(client);
284 }
285
286 TEST_F(AppCacheQuotaClientTest, PendingRequests) {
287   AppCacheQuotaClient* client = CreateClient();
288
289   SetUsageMapEntry(kOriginA, 1000);
290   SetUsageMapEntry(kOriginB, 10);
291   SetUsageMapEntry(kOriginOther, 500);
292
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);
303
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_);
311
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
319
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());
324
325   Call_NotifyAppCacheDestroyed(client);
326   Call_OnQuotaManagerDestroyed(client);
327 }
328
329 TEST_F(AppCacheQuotaClientTest, DestroyServiceWithPending) {
330   AppCacheQuotaClient* client = CreateClient();
331
332   SetUsageMapEntry(kOriginA, 1000);
333   SetUsageMapEntry(kOriginB, 10);
334   SetUsageMapEntry(kOriginOther, 500);
335
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_);
350
351   // Kill the service.
352   Call_NotifyAppCacheDestroyed(client);
353
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_);
361
362   Call_OnQuotaManagerDestroyed(client);
363 }
364
365 TEST_F(AppCacheQuotaClientTest, DestroyQuotaManagerWithPending) {
366   AppCacheQuotaClient* client = CreateClient();
367
368   SetUsageMapEntry(kOriginA, 1000);
369   SetUsageMapEntry(kOriginB, 10);
370   SetUsageMapEntry(kOriginOther, 500);
371
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_);
386
387   // Kill the quota manager.
388   Call_OnQuotaManagerDestroyed(client);
389   Call_NotifyAppCacheReady(client);
390
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_);
396
397   Call_NotifyAppCacheDestroyed(client);
398 }
399
400 TEST_F(AppCacheQuotaClientTest, DestroyWithDeleteInProgress) {
401   AppCacheQuotaClient* client = CreateClient();
402   Call_NotifyAppCacheReady(client);
403
404   // Start an async delete.
405   AsyncDeleteOriginData(client, kTemp, kOriginB);
406   EXPECT_EQ(0, num_delete_origins_completions_);
407
408   // Kill the service.
409   Call_NotifyAppCacheDestroyed(client);
410
411   // Should have been aborted.
412   EXPECT_EQ(1, num_delete_origins_completions_);
413   EXPECT_EQ(storage::kQuotaErrorAbort, delete_status_);
414
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_);
420
421   Call_OnQuotaManagerDestroyed(client);
422 }
423
424 }  // namespace content