Upstream version 9.38.198.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 "testing/gtest/include/gtest/gtest.h"
17 #include "webkit/browser/blob/blob_storage_context.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_cache_id_(0),
27         callback_error_(
28             ServiceWorkerCacheStorage::CACHE_STORAGE_ERROR_NO_ERROR),
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 bool MemoryOnly() { return false; }
54
55   void BoolAndErrorCallback(
56       base::RunLoop* run_loop,
57       bool value,
58       ServiceWorkerCacheStorage::CacheStorageError error) {
59     callback_bool_ = value;
60     callback_error_ = error;
61     run_loop->Quit();
62   }
63
64   void CacheAndErrorCallback(
65       base::RunLoop* run_loop,
66       int cache_id,
67       ServiceWorkerCacheStorage::CacheStorageError error) {
68     callback_cache_id_ = cache_id;
69     callback_error_ = error;
70     run_loop->Quit();
71   }
72
73   void StringsAndErrorCallback(
74       base::RunLoop* run_loop,
75       const std::vector<std::string>& strings,
76       ServiceWorkerCacheStorage::CacheStorageError error) {
77     callback_strings_ = strings;
78     callback_error_ = error;
79     run_loop->Quit();
80   }
81
82   bool CreateCache(const GURL& origin, const std::string& cache_name) {
83     scoped_ptr<base::RunLoop> loop(new base::RunLoop());
84     cache_manager_->CreateCache(
85         origin,
86         cache_name,
87         base::Bind(&ServiceWorkerCacheStorageManagerTest::CacheAndErrorCallback,
88                    base::Unretained(this),
89                    base::Unretained(loop.get())));
90     loop->Run();
91
92     bool error = callback_error_ !=
93                  ServiceWorkerCacheStorage::CACHE_STORAGE_ERROR_NO_ERROR;
94     if (error)
95       EXPECT_EQ(0, callback_cache_id_);
96     else
97       EXPECT_LT(0, callback_cache_id_);
98     return !error;
99   }
100
101   bool Get(const GURL& origin, const std::string& cache_name) {
102     scoped_ptr<base::RunLoop> loop(new base::RunLoop());
103     cache_manager_->GetCache(
104         origin,
105         cache_name,
106         base::Bind(&ServiceWorkerCacheStorageManagerTest::CacheAndErrorCallback,
107                    base::Unretained(this),
108                    base::Unretained(loop.get())));
109     loop->Run();
110
111     bool error = callback_error_ !=
112                  ServiceWorkerCacheStorage::CACHE_STORAGE_ERROR_NO_ERROR;
113     if (error)
114       EXPECT_EQ(0, callback_cache_id_);
115     else
116       EXPECT_LT(0, callback_cache_id_);
117     return !error;
118   }
119
120   bool Has(const GURL& origin, const std::string& cache_name) {
121     scoped_ptr<base::RunLoop> loop(new base::RunLoop());
122     cache_manager_->HasCache(
123         origin,
124         cache_name,
125         base::Bind(&ServiceWorkerCacheStorageManagerTest::BoolAndErrorCallback,
126                    base::Unretained(this),
127                    base::Unretained(loop.get())));
128     loop->Run();
129
130     return callback_bool_;
131   }
132
133   bool Delete(const GURL& origin, const std::string& cache_name) {
134     scoped_ptr<base::RunLoop> loop(new base::RunLoop());
135     cache_manager_->DeleteCache(
136         origin,
137         cache_name,
138         base::Bind(&ServiceWorkerCacheStorageManagerTest::BoolAndErrorCallback,
139                    base::Unretained(this),
140                    base::Unretained(loop.get())));
141     loop->Run();
142
143     return callback_bool_;
144   }
145
146   bool Keys(const GURL& origin) {
147     scoped_ptr<base::RunLoop> loop(new base::RunLoop());
148     cache_manager_->EnumerateCaches(
149         origin,
150         base::Bind(
151             &ServiceWorkerCacheStorageManagerTest::StringsAndErrorCallback,
152             base::Unretained(this),
153             base::Unretained(loop.get())));
154     loop->Run();
155
156     bool error = callback_error_ !=
157                  ServiceWorkerCacheStorage::CACHE_STORAGE_ERROR_NO_ERROR;
158     return !error;
159   }
160
161   bool VerifyKeys(const std::vector<std::string>& expected_keys) {
162     if (expected_keys.size() != callback_strings_.size())
163       return false;
164
165     std::set<std::string> found_set;
166     for (int i = 0, max = callback_strings_.size(); i < max; ++i)
167       found_set.insert(callback_strings_[i]);
168
169     for (int i = 0, max = expected_keys.size(); i < max; ++i) {
170       if (found_set.find(expected_keys[i]) == found_set.end())
171         return false;
172     }
173     return true;
174   }
175
176  protected:
177   TestBrowserContext browser_context_;
178   TestBrowserThreadBundle browser_thread_bundle_;
179
180   base::ScopedTempDir temp_dir_;
181   scoped_ptr<ServiceWorkerCacheStorageManager> cache_manager_;
182
183   int callback_bool_;
184   int callback_cache_id_;
185   ServiceWorkerCacheStorage::CacheStorageError callback_error_;
186   std::vector<std::string> callback_strings_;
187
188   const GURL origin1_;
189   const GURL origin2_;
190
191  private:
192   DISALLOW_COPY_AND_ASSIGN(ServiceWorkerCacheStorageManagerTest);
193 };
194
195 class ServiceWorkerCacheStorageManagerMemoryOnlyTest
196     : public ServiceWorkerCacheStorageManagerTest {
197   virtual bool MemoryOnly() OVERRIDE { return true; }
198 };
199
200 class ServiceWorkerCacheStorageManagerTestP
201     : public ServiceWorkerCacheStorageManagerTest,
202       public testing::WithParamInterface<bool> {
203   virtual bool MemoryOnly() OVERRIDE { return !GetParam(); }
204 };
205
206 TEST_F(ServiceWorkerCacheStorageManagerTest, TestsRunOnIOThread) {
207   EXPECT_TRUE(BrowserThread::CurrentlyOn(BrowserThread::IO));
208 }
209
210 TEST_P(ServiceWorkerCacheStorageManagerTestP, CreateCache) {
211   EXPECT_TRUE(CreateCache(origin1_, "foo"));
212 }
213
214 TEST_P(ServiceWorkerCacheStorageManagerTestP, CreateDuplicateCache) {
215   EXPECT_TRUE(CreateCache(origin1_, "foo"));
216   EXPECT_FALSE(CreateCache(origin1_, "foo"));
217   EXPECT_EQ(ServiceWorkerCacheStorage::CACHE_STORAGE_ERROR_EXISTS,
218             callback_error_);
219 }
220
221 TEST_P(ServiceWorkerCacheStorageManagerTestP, CreateTwoCaches) {
222   EXPECT_TRUE(CreateCache(origin1_, "foo"));
223   EXPECT_TRUE(CreateCache(origin1_, "bar"));
224 }
225
226 TEST_P(ServiceWorkerCacheStorageManagerTestP, Create2CachesSameNameDiffSWs) {
227   EXPECT_TRUE(CreateCache(origin1_, "foo"));
228   EXPECT_TRUE(CreateCache(origin2_, "foo"));
229 }
230
231 TEST_P(ServiceWorkerCacheStorageManagerTestP, GetCache) {
232   EXPECT_TRUE(CreateCache(origin1_, "foo"));
233   int cache_id = callback_cache_id_;
234   EXPECT_TRUE(Get(origin1_, "foo"));
235   EXPECT_EQ(cache_id, callback_cache_id_);
236 }
237
238 TEST_P(ServiceWorkerCacheStorageManagerTestP, GetNonExistent) {
239   EXPECT_FALSE(Get(origin1_, "foo"));
240   EXPECT_EQ(ServiceWorkerCacheStorage::CACHE_STORAGE_ERROR_NOT_FOUND,
241             callback_error_);
242 }
243
244 TEST_P(ServiceWorkerCacheStorageManagerTestP, HasCache) {
245   EXPECT_TRUE(CreateCache(origin1_, "foo"));
246   EXPECT_TRUE(Has(origin1_, "foo"));
247   EXPECT_TRUE(callback_bool_);
248 }
249
250 TEST_P(ServiceWorkerCacheStorageManagerTestP, HasNonExistent) {
251   EXPECT_FALSE(Has(origin1_, "foo"));
252 }
253
254 TEST_P(ServiceWorkerCacheStorageManagerTestP, DeleteCache) {
255   EXPECT_TRUE(CreateCache(origin1_, "foo"));
256   EXPECT_TRUE(Delete(origin1_, "foo"));
257   EXPECT_FALSE(Get(origin1_, "foo"));
258   EXPECT_EQ(ServiceWorkerCacheStorage::CACHE_STORAGE_ERROR_NOT_FOUND,
259             callback_error_);
260 }
261
262 TEST_P(ServiceWorkerCacheStorageManagerTestP, DeleteTwice) {
263   EXPECT_TRUE(CreateCache(origin1_, "foo"));
264   EXPECT_TRUE(Delete(origin1_, "foo"));
265   EXPECT_FALSE(Delete(origin1_, "foo"));
266   EXPECT_EQ(ServiceWorkerCacheStorage::CACHE_STORAGE_ERROR_NOT_FOUND,
267             callback_error_);
268 }
269
270 TEST_P(ServiceWorkerCacheStorageManagerTestP, EmptyKeys) {
271   EXPECT_TRUE(Keys(origin1_));
272   EXPECT_TRUE(callback_strings_.empty());
273 }
274
275 TEST_P(ServiceWorkerCacheStorageManagerTestP, SomeKeys) {
276   EXPECT_TRUE(CreateCache(origin1_, "foo"));
277   EXPECT_TRUE(CreateCache(origin1_, "bar"));
278   EXPECT_TRUE(CreateCache(origin2_, "baz"));
279   EXPECT_TRUE(Keys(origin1_));
280   EXPECT_EQ(2u, callback_strings_.size());
281   std::vector<std::string> expected_keys;
282   expected_keys.push_back("foo");
283   expected_keys.push_back("bar");
284   EXPECT_TRUE(VerifyKeys(expected_keys));
285   EXPECT_TRUE(Keys(origin2_));
286   EXPECT_EQ(1u, callback_strings_.size());
287   EXPECT_STREQ("baz", callback_strings_[0].c_str());
288 }
289
290 TEST_P(ServiceWorkerCacheStorageManagerTestP, DeletedKeysGone) {
291   EXPECT_TRUE(CreateCache(origin1_, "foo"));
292   EXPECT_TRUE(CreateCache(origin1_, "bar"));
293   EXPECT_TRUE(CreateCache(origin2_, "baz"));
294   EXPECT_TRUE(Delete(origin1_, "bar"));
295   EXPECT_TRUE(Keys(origin1_));
296   EXPECT_EQ(1u, callback_strings_.size());
297   EXPECT_STREQ("foo", callback_strings_[0].c_str());
298 }
299
300 TEST_P(ServiceWorkerCacheStorageManagerTestP, Chinese) {
301   EXPECT_TRUE(CreateCache(origin1_, "你好"));
302   int cache_id = callback_cache_id_;
303   EXPECT_TRUE(Get(origin1_, "你好"));
304   EXPECT_EQ(cache_id, callback_cache_id_);
305   EXPECT_TRUE(Keys(origin1_));
306   EXPECT_EQ(1u, callback_strings_.size());
307   EXPECT_TRUE("你好" == callback_strings_[0]);
308 }
309
310 TEST_F(ServiceWorkerCacheStorageManagerTest, EmptyKey) {
311   EXPECT_FALSE(CreateCache(origin1_, ""));
312   EXPECT_EQ(ServiceWorkerCacheStorage::CACHE_STORAGE_ERROR_EMPTY_KEY,
313             callback_error_);
314
315   EXPECT_FALSE(Get(origin1_, ""));
316   EXPECT_EQ(ServiceWorkerCacheStorage::CACHE_STORAGE_ERROR_EMPTY_KEY,
317             callback_error_);
318
319   EXPECT_FALSE(Has(origin1_, ""));
320   EXPECT_EQ(ServiceWorkerCacheStorage::CACHE_STORAGE_ERROR_EMPTY_KEY,
321             callback_error_);
322
323   EXPECT_FALSE(Delete(origin1_, ""));
324   EXPECT_EQ(ServiceWorkerCacheStorage::CACHE_STORAGE_ERROR_EMPTY_KEY,
325             callback_error_);
326 }
327
328 TEST_F(ServiceWorkerCacheStorageManagerTest, DataPersists) {
329   EXPECT_TRUE(CreateCache(origin1_, "foo"));
330   EXPECT_TRUE(CreateCache(origin1_, "bar"));
331   EXPECT_TRUE(CreateCache(origin1_, "baz"));
332   EXPECT_TRUE(CreateCache(origin2_, "raz"));
333   EXPECT_TRUE(Delete(origin1_, "bar"));
334   cache_manager_ =
335       ServiceWorkerCacheStorageManager::Create(cache_manager_.get());
336   EXPECT_TRUE(Keys(origin1_));
337   EXPECT_EQ(2u, callback_strings_.size());
338   std::vector<std::string> expected_keys;
339   expected_keys.push_back("foo");
340   expected_keys.push_back("baz");
341   EXPECT_TRUE(VerifyKeys(expected_keys));
342 }
343
344 TEST_F(ServiceWorkerCacheStorageManagerMemoryOnlyTest, DataLostWhenMemoryOnly) {
345   EXPECT_TRUE(CreateCache(origin1_, "foo"));
346   EXPECT_TRUE(CreateCache(origin2_, "baz"));
347   cache_manager_ =
348       ServiceWorkerCacheStorageManager::Create(cache_manager_.get());
349   EXPECT_TRUE(Keys(origin1_));
350   EXPECT_EQ(0u, callback_strings_.size());
351 }
352
353 TEST_F(ServiceWorkerCacheStorageManagerTest, BadCacheName) {
354   // Since the implementation writes cache names to disk, ensure that we don't
355   // escape the directory.
356   const std::string bad_name = "../../../../../../../../../../../../../../foo";
357   EXPECT_TRUE(CreateCache(origin1_, bad_name));
358   EXPECT_TRUE(Keys(origin1_));
359   EXPECT_EQ(1u, callback_strings_.size());
360   EXPECT_STREQ(bad_name.c_str(), callback_strings_[0].c_str());
361 }
362
363 TEST_F(ServiceWorkerCacheStorageManagerTest, BadOriginName) {
364   // Since the implementation writes origin names to disk, ensure that we don't
365   // escape the directory.
366   GURL bad_origin("../../../../../../../../../../../../../../foo");
367   EXPECT_TRUE(CreateCache(bad_origin, "foo"));
368   EXPECT_TRUE(Keys(bad_origin));
369   EXPECT_EQ(1u, callback_strings_.size());
370   EXPECT_STREQ("foo", callback_strings_[0].c_str());
371 }
372
373 INSTANTIATE_TEST_CASE_P(ServiceWorkerCacheStorageManagerTests,
374                         ServiceWorkerCacheStorageManagerTestP,
375                         ::testing::Values(false, true));
376
377 }  // namespace content