Upstream version 10.39.225.0
[platform/framework/web/crosswalk.git] / src / content / browser / service_worker / service_worker_cache_storage_manager_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 "content/browser/service_worker/service_worker_cache_storage_manager.h"
6
7 #include "base/files/file_path.h"
8 #include "base/files/scoped_temp_dir.h"
9 #include "base/message_loop/message_loop_proxy.h"
10 #include "base/run_loop.h"
11 #include "content/browser/fileapi/chrome_blob_storage_context.h"
12 #include "content/public/browser/browser_thread.h"
13 #include "content/public/test/test_browser_context.h"
14 #include "content/public/test/test_browser_thread_bundle.h"
15 #include "net/url_request/url_request_context_getter.h"
16 #include "storage/browser/blob/blob_storage_context.h"
17 #include "testing/gtest/include/gtest/gtest.h"
18
19 namespace content {
20
21 class ServiceWorkerCacheStorageManagerTest : public testing::Test {
22  protected:
23   ServiceWorkerCacheStorageManagerTest()
24       : browser_thread_bundle_(TestBrowserThreadBundle::IO_MAINLOOP),
25         callback_bool_(false),
26         callback_error_(
27             ServiceWorkerCacheStorage::CACHE_STORAGE_ERROR_NO_ERROR),
28         callback_cache_error_(ServiceWorkerCache::ErrorTypeOK),
29         origin1_("http://example1.com"),
30         origin2_("http://example2.com") {}
31
32   virtual void SetUp() OVERRIDE {
33     ChromeBlobStorageContext* blob_storage_context(
34         ChromeBlobStorageContext::GetFor(&browser_context_));
35     // Wait for ChromeBlobStorageContext to finish initializing.
36     base::RunLoop().RunUntilIdle();
37
38     net::URLRequestContext* url_request_context =
39         browser_context_.GetRequestContext()->GetURLRequestContext();
40     if (MemoryOnly()) {
41       cache_manager_ = ServiceWorkerCacheStorageManager::Create(
42           base::FilePath(), base::MessageLoopProxy::current());
43     } else {
44       ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
45       cache_manager_ = ServiceWorkerCacheStorageManager::Create(
46           temp_dir_.path(), base::MessageLoopProxy::current());
47     }
48
49     cache_manager_->SetBlobParametersForCache(
50         url_request_context, blob_storage_context->context()->AsWeakPtr());
51   }
52
53   virtual void TearDown() OVERRIDE {
54     base::RunLoop().RunUntilIdle();
55   }
56
57   virtual bool MemoryOnly() { return false; }
58
59   void BoolAndErrorCallback(
60       base::RunLoop* run_loop,
61       bool value,
62       ServiceWorkerCacheStorage::CacheStorageError error) {
63     callback_bool_ = value;
64     callback_error_ = error;
65     run_loop->Quit();
66   }
67
68   void CacheAndErrorCallback(
69       base::RunLoop* run_loop,
70       const scoped_refptr<ServiceWorkerCache>& cache,
71       ServiceWorkerCacheStorage::CacheStorageError error) {
72     callback_cache_ = cache;
73     callback_error_ = error;
74     run_loop->Quit();
75   }
76
77   void StringsAndErrorCallback(
78       base::RunLoop* run_loop,
79       const std::vector<std::string>& strings,
80       ServiceWorkerCacheStorage::CacheStorageError error) {
81     callback_strings_ = strings;
82     callback_error_ = error;
83     run_loop->Quit();
84   }
85
86   void CachePutCallback(base::RunLoop* run_loop,
87                         ServiceWorkerCache::ErrorType error) {
88     callback_cache_error_ = error;
89     run_loop->Quit();
90   }
91
92   void CacheMatchCallback(
93       base::RunLoop* run_loop,
94       ServiceWorkerCache::ErrorType error,
95       scoped_ptr<ServiceWorkerResponse> response,
96       scoped_ptr<storage::BlobDataHandle> blob_data_handle) {
97     callback_cache_error_ = error;
98     callback_cache_response_ = response.Pass();
99     // Deliberately drop the data handle as only the url is being tested.
100     run_loop->Quit();
101   }
102
103   bool CreateCache(const GURL& origin, const std::string& cache_name) {
104     scoped_ptr<base::RunLoop> loop(new base::RunLoop());
105     cache_manager_->CreateCache(
106         origin,
107         cache_name,
108         base::Bind(&ServiceWorkerCacheStorageManagerTest::CacheAndErrorCallback,
109                    base::Unretained(this),
110                    base::Unretained(loop.get())));
111     loop->Run();
112
113     bool error = callback_error_ !=
114                  ServiceWorkerCacheStorage::CACHE_STORAGE_ERROR_NO_ERROR;
115     if (error)
116       EXPECT_TRUE(!callback_cache_.get());
117     else
118       EXPECT_TRUE(callback_cache_.get());
119     return !error;
120   }
121
122   bool Get(const GURL& origin, const std::string& cache_name) {
123     scoped_ptr<base::RunLoop> loop(new base::RunLoop());
124     cache_manager_->GetCache(
125         origin,
126         cache_name,
127         base::Bind(&ServiceWorkerCacheStorageManagerTest::CacheAndErrorCallback,
128                    base::Unretained(this),
129                    base::Unretained(loop.get())));
130     loop->Run();
131
132     bool error = callback_error_ !=
133                  ServiceWorkerCacheStorage::CACHE_STORAGE_ERROR_NO_ERROR;
134     if (error)
135       EXPECT_TRUE(!callback_cache_.get());
136     else
137       EXPECT_TRUE(callback_cache_.get());
138     return !error;
139   }
140
141   bool Has(const GURL& origin, const std::string& cache_name) {
142     scoped_ptr<base::RunLoop> loop(new base::RunLoop());
143     cache_manager_->HasCache(
144         origin,
145         cache_name,
146         base::Bind(&ServiceWorkerCacheStorageManagerTest::BoolAndErrorCallback,
147                    base::Unretained(this),
148                    base::Unretained(loop.get())));
149     loop->Run();
150
151     return callback_bool_;
152   }
153
154   bool Delete(const GURL& origin, const std::string& cache_name) {
155     scoped_ptr<base::RunLoop> loop(new base::RunLoop());
156     cache_manager_->DeleteCache(
157         origin,
158         cache_name,
159         base::Bind(&ServiceWorkerCacheStorageManagerTest::BoolAndErrorCallback,
160                    base::Unretained(this),
161                    base::Unretained(loop.get())));
162     loop->Run();
163
164     return callback_bool_;
165   }
166
167   bool Keys(const GURL& origin) {
168     scoped_ptr<base::RunLoop> loop(new base::RunLoop());
169     cache_manager_->EnumerateCaches(
170         origin,
171         base::Bind(
172             &ServiceWorkerCacheStorageManagerTest::StringsAndErrorCallback,
173             base::Unretained(this),
174             base::Unretained(loop.get())));
175     loop->Run();
176
177     bool error = callback_error_ !=
178                  ServiceWorkerCacheStorage::CACHE_STORAGE_ERROR_NO_ERROR;
179     return !error;
180   }
181
182   bool CachePut(const scoped_refptr<ServiceWorkerCache>& cache,
183                 const std::string& url) {
184     scoped_ptr<ServiceWorkerFetchRequest> request(
185         new ServiceWorkerFetchRequest());
186     scoped_ptr<ServiceWorkerResponse> response(new ServiceWorkerResponse());
187     request->url = GURL("http://example.com/foo");
188     response->url = GURL("http://example.com/foo");
189     scoped_ptr<base::RunLoop> loop(new base::RunLoop());
190     cache->Put(
191         request.Pass(),
192         response.Pass(),
193         base::Bind(&ServiceWorkerCacheStorageManagerTest::CachePutCallback,
194                    base::Unretained(this),
195                    base::Unretained(loop.get())));
196     loop->Run();
197
198     bool error = callback_cache_error_ != ServiceWorkerCache::ErrorTypeOK;
199     return !error;
200   }
201
202   bool CacheMatch(const scoped_refptr<ServiceWorkerCache>& cache,
203                   const std::string& url) {
204     scoped_ptr<ServiceWorkerFetchRequest> request(
205         new ServiceWorkerFetchRequest());
206     request->url = GURL("http://example.com/foo");
207     scoped_ptr<base::RunLoop> loop(new base::RunLoop());
208     cache->Match(
209         request.Pass(),
210         base::Bind(&ServiceWorkerCacheStorageManagerTest::CacheMatchCallback,
211                    base::Unretained(this),
212                    base::Unretained(loop.get())));
213     loop->Run();
214
215     bool error = callback_cache_error_ != ServiceWorkerCache::ErrorTypeOK;
216     return !error;
217   }
218
219  protected:
220   TestBrowserContext browser_context_;
221   TestBrowserThreadBundle browser_thread_bundle_;
222
223   base::ScopedTempDir temp_dir_;
224   scoped_ptr<ServiceWorkerCacheStorageManager> cache_manager_;
225
226   scoped_refptr<ServiceWorkerCache> callback_cache_;
227   int callback_bool_;
228   ServiceWorkerCacheStorage::CacheStorageError callback_error_;
229   ServiceWorkerCache::ErrorType callback_cache_error_;
230   scoped_ptr<ServiceWorkerResponse> callback_cache_response_;
231   std::vector<std::string> callback_strings_;
232
233   const GURL origin1_;
234   const GURL origin2_;
235
236  private:
237   DISALLOW_COPY_AND_ASSIGN(ServiceWorkerCacheStorageManagerTest);
238 };
239
240 class ServiceWorkerCacheStorageManagerMemoryOnlyTest
241     : public ServiceWorkerCacheStorageManagerTest {
242   virtual bool MemoryOnly() OVERRIDE { return true; }
243 };
244
245 class ServiceWorkerCacheStorageManagerTestP
246     : public ServiceWorkerCacheStorageManagerTest,
247       public testing::WithParamInterface<bool> {
248   virtual bool MemoryOnly() OVERRIDE { return !GetParam(); }
249 };
250
251 TEST_F(ServiceWorkerCacheStorageManagerTest, TestsRunOnIOThread) {
252   EXPECT_TRUE(BrowserThread::CurrentlyOn(BrowserThread::IO));
253 }
254
255 TEST_P(ServiceWorkerCacheStorageManagerTestP, CreateCache) {
256   EXPECT_TRUE(CreateCache(origin1_, "foo"));
257 }
258
259 TEST_P(ServiceWorkerCacheStorageManagerTestP, CreateDuplicateCache) {
260   EXPECT_TRUE(CreateCache(origin1_, "foo"));
261   EXPECT_FALSE(CreateCache(origin1_, "foo"));
262   EXPECT_EQ(ServiceWorkerCacheStorage::CACHE_STORAGE_ERROR_EXISTS,
263             callback_error_);
264 }
265
266 TEST_P(ServiceWorkerCacheStorageManagerTestP, CreateTwoCaches) {
267   EXPECT_TRUE(CreateCache(origin1_, "foo"));
268   EXPECT_TRUE(CreateCache(origin1_, "bar"));
269 }
270
271 TEST_P(ServiceWorkerCacheStorageManagerTestP, CachePointersDiffer) {
272   EXPECT_TRUE(CreateCache(origin1_, "foo"));
273   scoped_refptr<ServiceWorkerCache> cache = callback_cache_;
274   EXPECT_TRUE(CreateCache(origin1_, "bar"));
275   EXPECT_TRUE(cache.get() != callback_cache_.get());
276 }
277
278 TEST_P(ServiceWorkerCacheStorageManagerTestP, Create2CachesSameNameDiffSWs) {
279   EXPECT_TRUE(CreateCache(origin1_, "foo"));
280   EXPECT_TRUE(CreateCache(origin2_, "foo"));
281 }
282
283 TEST_P(ServiceWorkerCacheStorageManagerTestP, GetCache) {
284   EXPECT_TRUE(CreateCache(origin1_, "foo"));
285   scoped_refptr<ServiceWorkerCache> cache = callback_cache_;
286   EXPECT_TRUE(Get(origin1_, "foo"));
287   EXPECT_TRUE(cache.get() == callback_cache_.get());
288 }
289
290 TEST_P(ServiceWorkerCacheStorageManagerTestP, GetNonExistent) {
291   EXPECT_FALSE(Get(origin1_, "foo"));
292   EXPECT_EQ(ServiceWorkerCacheStorage::CACHE_STORAGE_ERROR_NOT_FOUND,
293             callback_error_);
294 }
295
296 TEST_P(ServiceWorkerCacheStorageManagerTestP, HasCache) {
297   EXPECT_TRUE(CreateCache(origin1_, "foo"));
298   EXPECT_TRUE(Has(origin1_, "foo"));
299   EXPECT_TRUE(callback_bool_);
300 }
301
302 TEST_P(ServiceWorkerCacheStorageManagerTestP, HasNonExistent) {
303   EXPECT_FALSE(Has(origin1_, "foo"));
304 }
305
306 TEST_P(ServiceWorkerCacheStorageManagerTestP, DeleteCache) {
307   EXPECT_TRUE(CreateCache(origin1_, "foo"));
308   EXPECT_TRUE(Delete(origin1_, "foo"));
309   EXPECT_FALSE(Get(origin1_, "foo"));
310   EXPECT_EQ(ServiceWorkerCacheStorage::CACHE_STORAGE_ERROR_NOT_FOUND,
311             callback_error_);
312 }
313
314 TEST_P(ServiceWorkerCacheStorageManagerTestP, DeleteTwice) {
315   EXPECT_TRUE(CreateCache(origin1_, "foo"));
316   EXPECT_TRUE(Delete(origin1_, "foo"));
317   EXPECT_FALSE(Delete(origin1_, "foo"));
318   EXPECT_EQ(ServiceWorkerCacheStorage::CACHE_STORAGE_ERROR_NOT_FOUND,
319             callback_error_);
320 }
321
322 TEST_P(ServiceWorkerCacheStorageManagerTestP, EmptyKeys) {
323   EXPECT_TRUE(Keys(origin1_));
324   EXPECT_TRUE(callback_strings_.empty());
325 }
326
327 TEST_P(ServiceWorkerCacheStorageManagerTestP, SomeKeys) {
328   EXPECT_TRUE(CreateCache(origin1_, "foo"));
329   EXPECT_TRUE(CreateCache(origin1_, "bar"));
330   EXPECT_TRUE(CreateCache(origin2_, "baz"));
331   EXPECT_TRUE(Keys(origin1_));
332   EXPECT_EQ(2u, callback_strings_.size());
333   std::vector<std::string> expected_keys;
334   expected_keys.push_back("foo");
335   expected_keys.push_back("bar");
336   EXPECT_TRUE(expected_keys == callback_strings_);
337   EXPECT_TRUE(Keys(origin2_));
338   EXPECT_EQ(1u, callback_strings_.size());
339   EXPECT_STREQ("baz", callback_strings_[0].c_str());
340 }
341
342 TEST_P(ServiceWorkerCacheStorageManagerTestP, DeletedKeysGone) {
343   EXPECT_TRUE(CreateCache(origin1_, "foo"));
344   EXPECT_TRUE(CreateCache(origin1_, "bar"));
345   EXPECT_TRUE(CreateCache(origin2_, "baz"));
346   EXPECT_TRUE(Delete(origin1_, "bar"));
347   EXPECT_TRUE(Keys(origin1_));
348   EXPECT_EQ(1u, callback_strings_.size());
349   EXPECT_STREQ("foo", callback_strings_[0].c_str());
350 }
351
352 TEST_P(ServiceWorkerCacheStorageManagerTestP, Chinese) {
353   EXPECT_TRUE(CreateCache(origin1_, "你好"));
354   scoped_refptr<ServiceWorkerCache> cache = callback_cache_;
355   EXPECT_TRUE(Get(origin1_, "你好"));
356   EXPECT_TRUE(cache.get() == callback_cache_.get());
357   EXPECT_TRUE(Keys(origin1_));
358   EXPECT_EQ(1u, callback_strings_.size());
359   EXPECT_TRUE("你好" == callback_strings_[0]);
360 }
361
362 TEST_F(ServiceWorkerCacheStorageManagerTest, EmptyKey) {
363   EXPECT_TRUE(CreateCache(origin1_, ""));
364   scoped_refptr<ServiceWorkerCache> cache = callback_cache_;
365   EXPECT_TRUE(Get(origin1_, ""));
366   EXPECT_EQ(cache.get(), callback_cache_.get());
367   EXPECT_TRUE(Keys(origin1_));
368   EXPECT_EQ(1u, callback_strings_.size());
369   EXPECT_TRUE("" == callback_strings_[0]);
370   EXPECT_TRUE(Has(origin1_, ""));
371   EXPECT_TRUE(Delete(origin1_, ""));
372   EXPECT_TRUE(Keys(origin1_));
373   EXPECT_EQ(0u, callback_strings_.size());
374 }
375
376 TEST_F(ServiceWorkerCacheStorageManagerTest, DataPersists) {
377   EXPECT_TRUE(CreateCache(origin1_, "foo"));
378   EXPECT_TRUE(CreateCache(origin1_, "bar"));
379   EXPECT_TRUE(CreateCache(origin1_, "baz"));
380   EXPECT_TRUE(CreateCache(origin2_, "raz"));
381   EXPECT_TRUE(Delete(origin1_, "bar"));
382   cache_manager_ =
383       ServiceWorkerCacheStorageManager::Create(cache_manager_.get());
384   EXPECT_TRUE(Keys(origin1_));
385   EXPECT_EQ(2u, callback_strings_.size());
386   std::vector<std::string> expected_keys;
387   expected_keys.push_back("foo");
388   expected_keys.push_back("baz");
389   EXPECT_TRUE(expected_keys == callback_strings_);
390 }
391
392 TEST_F(ServiceWorkerCacheStorageManagerMemoryOnlyTest, DataLostWhenMemoryOnly) {
393   EXPECT_TRUE(CreateCache(origin1_, "foo"));
394   EXPECT_TRUE(CreateCache(origin2_, "baz"));
395   cache_manager_ =
396       ServiceWorkerCacheStorageManager::Create(cache_manager_.get());
397   EXPECT_TRUE(Keys(origin1_));
398   EXPECT_EQ(0u, callback_strings_.size());
399 }
400
401 TEST_F(ServiceWorkerCacheStorageManagerTest, BadCacheName) {
402   // Since the implementation writes cache names to disk, ensure that we don't
403   // escape the directory.
404   const std::string bad_name = "../../../../../../../../../../../../../../foo";
405   EXPECT_TRUE(CreateCache(origin1_, bad_name));
406   EXPECT_TRUE(Keys(origin1_));
407   EXPECT_EQ(1u, callback_strings_.size());
408   EXPECT_STREQ(bad_name.c_str(), callback_strings_[0].c_str());
409 }
410
411 TEST_F(ServiceWorkerCacheStorageManagerTest, BadOriginName) {
412   // Since the implementation writes origin names to disk, ensure that we don't
413   // escape the directory.
414   GURL bad_origin("../../../../../../../../../../../../../../foo");
415   EXPECT_TRUE(CreateCache(bad_origin, "foo"));
416   EXPECT_TRUE(Keys(bad_origin));
417   EXPECT_EQ(1u, callback_strings_.size());
418   EXPECT_STREQ("foo", callback_strings_[0].c_str());
419 }
420
421 // With a persistent cache if the client drops its reference to a
422 // ServiceWorkerCache
423 // it should be deleted.
424 TEST_F(ServiceWorkerCacheStorageManagerTest, DropReference) {
425   EXPECT_TRUE(CreateCache(origin1_, "foo"));
426   base::WeakPtr<ServiceWorkerCache> cache = callback_cache_->AsWeakPtr();
427   callback_cache_ = NULL;
428   EXPECT_TRUE(!cache);
429 }
430
431 // With a memory cache the cache can't be freed from memory until the client
432 // calls delete.
433 TEST_F(ServiceWorkerCacheStorageManagerMemoryOnlyTest,
434        MemoryLosesReferenceOnlyAfterDelete) {
435   EXPECT_TRUE(CreateCache(origin1_, "foo"));
436   base::WeakPtr<ServiceWorkerCache> cache = callback_cache_->AsWeakPtr();
437   callback_cache_ = NULL;
438   EXPECT_TRUE(cache);
439   EXPECT_TRUE(Delete(origin1_, "foo"));
440   EXPECT_FALSE(cache);
441 }
442
443 TEST_P(ServiceWorkerCacheStorageManagerTestP, RecreateCacheOnDemand) {
444   EXPECT_TRUE(CreateCache(origin1_, "foo"));
445   EXPECT_TRUE(CachePut(callback_cache_, "bar"));
446   callback_cache_ = NULL;
447   EXPECT_TRUE(Get(origin1_, "foo"));
448   EXPECT_TRUE(CacheMatch(callback_cache_, "bar"));
449 }
450
451 TEST_P(ServiceWorkerCacheStorageManagerTestP, DeleteBeforeRelease) {
452   EXPECT_TRUE(CreateCache(origin1_, "foo"));
453   EXPECT_TRUE(Delete(origin1_, "foo"));
454   EXPECT_TRUE(callback_cache_->AsWeakPtr());
455 }
456
457 INSTANTIATE_TEST_CASE_P(ServiceWorkerCacheStorageManagerTests,
458                         ServiceWorkerCacheStorageManagerTestP,
459                         ::testing::Values(false, true));
460
461 }  // namespace content