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.
5 #include "content/browser/service_worker/service_worker_cache_storage_manager.h"
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"
21 class ServiceWorkerCacheStorageManagerTest : public testing::Test {
23 ServiceWorkerCacheStorageManagerTest()
24 : browser_thread_bundle_(TestBrowserThreadBundle::IO_MAINLOOP),
25 callback_bool_(false),
26 callback_cache_id_(0),
28 ServiceWorkerCacheStorage::CACHE_STORAGE_ERROR_NO_ERROR),
29 origin1_("http://example1.com"),
30 origin2_("http://example2.com") {}
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();
38 net::URLRequestContext* url_request_context =
39 browser_context_.GetRequestContext()->GetURLRequestContext();
41 cache_manager_ = ServiceWorkerCacheStorageManager::Create(
42 base::FilePath(), base::MessageLoopProxy::current());
44 ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
45 cache_manager_ = ServiceWorkerCacheStorageManager::Create(
46 temp_dir_.path(), base::MessageLoopProxy::current());
49 cache_manager_->SetBlobParametersForCache(
50 url_request_context, blob_storage_context->context()->AsWeakPtr());
53 virtual bool MemoryOnly() { return false; }
55 void BoolAndErrorCallback(
56 base::RunLoop* run_loop,
58 ServiceWorkerCacheStorage::CacheStorageError error) {
59 callback_bool_ = value;
60 callback_error_ = error;
64 void CacheAndErrorCallback(
65 base::RunLoop* run_loop,
67 ServiceWorkerCacheStorage::CacheStorageError error) {
68 callback_cache_id_ = cache_id;
69 callback_error_ = error;
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;
82 bool CreateCache(const GURL& origin, const std::string& cache_name) {
83 scoped_ptr<base::RunLoop> loop(new base::RunLoop());
84 cache_manager_->CreateCache(
87 base::Bind(&ServiceWorkerCacheStorageManagerTest::CacheAndErrorCallback,
88 base::Unretained(this),
89 base::Unretained(loop.get())));
92 bool error = callback_error_ !=
93 ServiceWorkerCacheStorage::CACHE_STORAGE_ERROR_NO_ERROR;
95 EXPECT_EQ(0, callback_cache_id_);
97 EXPECT_LT(0, callback_cache_id_);
101 bool Get(const GURL& origin, const std::string& cache_name) {
102 scoped_ptr<base::RunLoop> loop(new base::RunLoop());
103 cache_manager_->GetCache(
106 base::Bind(&ServiceWorkerCacheStorageManagerTest::CacheAndErrorCallback,
107 base::Unretained(this),
108 base::Unretained(loop.get())));
111 bool error = callback_error_ !=
112 ServiceWorkerCacheStorage::CACHE_STORAGE_ERROR_NO_ERROR;
114 EXPECT_EQ(0, callback_cache_id_);
116 EXPECT_LT(0, callback_cache_id_);
120 bool Has(const GURL& origin, const std::string& cache_name) {
121 scoped_ptr<base::RunLoop> loop(new base::RunLoop());
122 cache_manager_->HasCache(
125 base::Bind(&ServiceWorkerCacheStorageManagerTest::BoolAndErrorCallback,
126 base::Unretained(this),
127 base::Unretained(loop.get())));
130 return callback_bool_;
133 bool Delete(const GURL& origin, const std::string& cache_name) {
134 scoped_ptr<base::RunLoop> loop(new base::RunLoop());
135 cache_manager_->DeleteCache(
138 base::Bind(&ServiceWorkerCacheStorageManagerTest::BoolAndErrorCallback,
139 base::Unretained(this),
140 base::Unretained(loop.get())));
143 return callback_bool_;
146 bool Keys(const GURL& origin) {
147 scoped_ptr<base::RunLoop> loop(new base::RunLoop());
148 cache_manager_->EnumerateCaches(
151 &ServiceWorkerCacheStorageManagerTest::StringsAndErrorCallback,
152 base::Unretained(this),
153 base::Unretained(loop.get())));
156 bool error = callback_error_ !=
157 ServiceWorkerCacheStorage::CACHE_STORAGE_ERROR_NO_ERROR;
161 bool VerifyKeys(const std::vector<std::string>& expected_keys) {
162 if (expected_keys.size() != callback_strings_.size())
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]);
169 for (int i = 0, max = expected_keys.size(); i < max; ++i) {
170 if (found_set.find(expected_keys[i]) == found_set.end())
177 TestBrowserContext browser_context_;
178 TestBrowserThreadBundle browser_thread_bundle_;
180 base::ScopedTempDir temp_dir_;
181 scoped_ptr<ServiceWorkerCacheStorageManager> cache_manager_;
184 int callback_cache_id_;
185 ServiceWorkerCacheStorage::CacheStorageError callback_error_;
186 std::vector<std::string> callback_strings_;
192 DISALLOW_COPY_AND_ASSIGN(ServiceWorkerCacheStorageManagerTest);
195 class ServiceWorkerCacheStorageManagerMemoryOnlyTest
196 : public ServiceWorkerCacheStorageManagerTest {
197 virtual bool MemoryOnly() OVERRIDE { return true; }
200 class ServiceWorkerCacheStorageManagerTestP
201 : public ServiceWorkerCacheStorageManagerTest,
202 public testing::WithParamInterface<bool> {
203 virtual bool MemoryOnly() OVERRIDE { return !GetParam(); }
206 TEST_F(ServiceWorkerCacheStorageManagerTest, TestsRunOnIOThread) {
207 EXPECT_TRUE(BrowserThread::CurrentlyOn(BrowserThread::IO));
210 TEST_P(ServiceWorkerCacheStorageManagerTestP, CreateCache) {
211 EXPECT_TRUE(CreateCache(origin1_, "foo"));
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,
221 TEST_P(ServiceWorkerCacheStorageManagerTestP, CreateTwoCaches) {
222 EXPECT_TRUE(CreateCache(origin1_, "foo"));
223 EXPECT_TRUE(CreateCache(origin1_, "bar"));
226 TEST_P(ServiceWorkerCacheStorageManagerTestP, Create2CachesSameNameDiffSWs) {
227 EXPECT_TRUE(CreateCache(origin1_, "foo"));
228 EXPECT_TRUE(CreateCache(origin2_, "foo"));
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_);
238 TEST_P(ServiceWorkerCacheStorageManagerTestP, GetNonExistent) {
239 EXPECT_FALSE(Get(origin1_, "foo"));
240 EXPECT_EQ(ServiceWorkerCacheStorage::CACHE_STORAGE_ERROR_NOT_FOUND,
244 TEST_P(ServiceWorkerCacheStorageManagerTestP, HasCache) {
245 EXPECT_TRUE(CreateCache(origin1_, "foo"));
246 EXPECT_TRUE(Has(origin1_, "foo"));
247 EXPECT_TRUE(callback_bool_);
250 TEST_P(ServiceWorkerCacheStorageManagerTestP, HasNonExistent) {
251 EXPECT_FALSE(Has(origin1_, "foo"));
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,
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,
270 TEST_P(ServiceWorkerCacheStorageManagerTestP, EmptyKeys) {
271 EXPECT_TRUE(Keys(origin1_));
272 EXPECT_TRUE(callback_strings_.empty());
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());
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());
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]);
310 TEST_F(ServiceWorkerCacheStorageManagerTest, EmptyKey) {
311 EXPECT_FALSE(CreateCache(origin1_, ""));
312 EXPECT_EQ(ServiceWorkerCacheStorage::CACHE_STORAGE_ERROR_EMPTY_KEY,
315 EXPECT_FALSE(Get(origin1_, ""));
316 EXPECT_EQ(ServiceWorkerCacheStorage::CACHE_STORAGE_ERROR_EMPTY_KEY,
319 EXPECT_FALSE(Has(origin1_, ""));
320 EXPECT_EQ(ServiceWorkerCacheStorage::CACHE_STORAGE_ERROR_EMPTY_KEY,
323 EXPECT_FALSE(Delete(origin1_, ""));
324 EXPECT_EQ(ServiceWorkerCacheStorage::CACHE_STORAGE_ERROR_EMPTY_KEY,
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"));
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));
344 TEST_F(ServiceWorkerCacheStorageManagerMemoryOnlyTest, DataLostWhenMemoryOnly) {
345 EXPECT_TRUE(CreateCache(origin1_, "foo"));
346 EXPECT_TRUE(CreateCache(origin2_, "baz"));
348 ServiceWorkerCacheStorageManager::Create(cache_manager_.get());
349 EXPECT_TRUE(Keys(origin1_));
350 EXPECT_EQ(0u, callback_strings_.size());
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());
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());
373 INSTANTIATE_TEST_CASE_P(ServiceWorkerCacheStorageManagerTests,
374 ServiceWorkerCacheStorageManagerTestP,
375 ::testing::Values(false, true));
377 } // namespace content