OLD | NEW |
| (Empty) |
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/file_util.h" | |
9 #include "base/files/scoped_temp_dir.h" | |
10 #include "base/message_loop/message_loop_proxy.h" | |
11 #include "base/run_loop.h" | |
12 #include "base/stl_util.h" | |
13 #include "content/browser/fileapi/chrome_blob_storage_context.h" | |
14 #include "content/browser/quota/mock_quota_manager_proxy.h" | |
15 #include "content/browser/service_worker/service_worker_cache_quota_client.h" | |
16 #include "content/public/browser/browser_thread.h" | |
17 #include "content/public/test/test_browser_context.h" | |
18 #include "content/public/test/test_browser_thread_bundle.h" | |
19 #include "net/url_request/url_request_context_getter.h" | |
20 #include "storage/browser/blob/blob_storage_context.h" | |
21 #include "storage/browser/quota/quota_manager_proxy.h" | |
22 #include "testing/gtest/include/gtest/gtest.h" | |
23 | |
24 namespace content { | |
25 | |
26 class ServiceWorkerCacheStorageManagerTest : public testing::Test { | |
27 public: | |
28 ServiceWorkerCacheStorageManagerTest() | |
29 : browser_thread_bundle_(TestBrowserThreadBundle::IO_MAINLOOP), | |
30 callback_bool_(false), | |
31 callback_error_( | |
32 ServiceWorkerCacheStorage::CACHE_STORAGE_ERROR_NO_ERROR), | |
33 callback_cache_error_(ServiceWorkerCache::ERROR_TYPE_OK), | |
34 origin1_("http://example1.com"), | |
35 origin2_("http://example2.com") {} | |
36 | |
37 void SetUp() override { | |
38 ChromeBlobStorageContext* blob_storage_context( | |
39 ChromeBlobStorageContext::GetFor(&browser_context_)); | |
40 // Wait for ChromeBlobStorageContext to finish initializing. | |
41 base::RunLoop().RunUntilIdle(); | |
42 | |
43 quota_manager_proxy_ = new MockQuotaManagerProxy( | |
44 nullptr, base::MessageLoopProxy::current().get()); | |
45 | |
46 net::URLRequestContext* url_request_context = | |
47 browser_context_.GetRequestContext()->GetURLRequestContext(); | |
48 if (MemoryOnly()) { | |
49 cache_manager_ = ServiceWorkerCacheStorageManager::Create( | |
50 base::FilePath(), | |
51 base::MessageLoopProxy::current(), | |
52 quota_manager_proxy_); | |
53 } else { | |
54 ASSERT_TRUE(temp_dir_.CreateUniqueTempDir()); | |
55 cache_manager_ = ServiceWorkerCacheStorageManager::Create( | |
56 temp_dir_.path(), | |
57 base::MessageLoopProxy::current(), | |
58 quota_manager_proxy_); | |
59 } | |
60 | |
61 cache_manager_->SetBlobParametersForCache( | |
62 url_request_context, blob_storage_context->context()->AsWeakPtr()); | |
63 } | |
64 | |
65 void TearDown() override { | |
66 quota_manager_proxy_->SimulateQuotaManagerDestroyed(); | |
67 base::RunLoop().RunUntilIdle(); | |
68 } | |
69 | |
70 virtual bool MemoryOnly() { return false; } | |
71 | |
72 void BoolAndErrorCallback( | |
73 base::RunLoop* run_loop, | |
74 bool value, | |
75 ServiceWorkerCacheStorage::CacheStorageError error) { | |
76 callback_bool_ = value; | |
77 callback_error_ = error; | |
78 run_loop->Quit(); | |
79 } | |
80 | |
81 void CacheAndErrorCallback( | |
82 base::RunLoop* run_loop, | |
83 const scoped_refptr<ServiceWorkerCache>& cache, | |
84 ServiceWorkerCacheStorage::CacheStorageError error) { | |
85 callback_cache_ = cache; | |
86 callback_error_ = error; | |
87 run_loop->Quit(); | |
88 } | |
89 | |
90 void StringsAndErrorCallback( | |
91 base::RunLoop* run_loop, | |
92 const std::vector<std::string>& strings, | |
93 ServiceWorkerCacheStorage::CacheStorageError error) { | |
94 callback_strings_ = strings; | |
95 callback_error_ = error; | |
96 run_loop->Quit(); | |
97 } | |
98 | |
99 void CachePutCallback(base::RunLoop* run_loop, | |
100 ServiceWorkerCache::ErrorType error, | |
101 scoped_ptr<ServiceWorkerResponse> response, | |
102 scoped_ptr<storage::BlobDataHandle> blob_data_handle) { | |
103 callback_cache_error_ = error; | |
104 run_loop->Quit(); | |
105 } | |
106 | |
107 void CacheMatchCallback( | |
108 base::RunLoop* run_loop, | |
109 ServiceWorkerCache::ErrorType error, | |
110 scoped_ptr<ServiceWorkerResponse> response, | |
111 scoped_ptr<storage::BlobDataHandle> blob_data_handle) { | |
112 callback_cache_error_ = error; | |
113 callback_cache_response_ = response.Pass(); | |
114 // Deliberately drop the data handle as only the url is being tested. | |
115 run_loop->Quit(); | |
116 } | |
117 | |
118 bool Open(const GURL& origin, const std::string& cache_name) { | |
119 scoped_ptr<base::RunLoop> loop(new base::RunLoop()); | |
120 cache_manager_->OpenCache( | |
121 origin, | |
122 cache_name, | |
123 base::Bind(&ServiceWorkerCacheStorageManagerTest::CacheAndErrorCallback, | |
124 base::Unretained(this), | |
125 base::Unretained(loop.get()))); | |
126 loop->Run(); | |
127 | |
128 bool error = callback_error_ != | |
129 ServiceWorkerCacheStorage::CACHE_STORAGE_ERROR_NO_ERROR; | |
130 if (error) | |
131 EXPECT_TRUE(!callback_cache_.get()); | |
132 else | |
133 EXPECT_TRUE(callback_cache_.get()); | |
134 return !error; | |
135 } | |
136 | |
137 bool Has(const GURL& origin, const std::string& cache_name) { | |
138 scoped_ptr<base::RunLoop> loop(new base::RunLoop()); | |
139 cache_manager_->HasCache( | |
140 origin, | |
141 cache_name, | |
142 base::Bind(&ServiceWorkerCacheStorageManagerTest::BoolAndErrorCallback, | |
143 base::Unretained(this), | |
144 base::Unretained(loop.get()))); | |
145 loop->Run(); | |
146 | |
147 return callback_bool_; | |
148 } | |
149 | |
150 bool Delete(const GURL& origin, const std::string& cache_name) { | |
151 scoped_ptr<base::RunLoop> loop(new base::RunLoop()); | |
152 cache_manager_->DeleteCache( | |
153 origin, | |
154 cache_name, | |
155 base::Bind(&ServiceWorkerCacheStorageManagerTest::BoolAndErrorCallback, | |
156 base::Unretained(this), | |
157 base::Unretained(loop.get()))); | |
158 loop->Run(); | |
159 | |
160 return callback_bool_; | |
161 } | |
162 | |
163 bool Keys(const GURL& origin) { | |
164 scoped_ptr<base::RunLoop> loop(new base::RunLoop()); | |
165 cache_manager_->EnumerateCaches( | |
166 origin, | |
167 base::Bind( | |
168 &ServiceWorkerCacheStorageManagerTest::StringsAndErrorCallback, | |
169 base::Unretained(this), | |
170 base::Unretained(loop.get()))); | |
171 loop->Run(); | |
172 | |
173 bool error = callback_error_ != | |
174 ServiceWorkerCacheStorage::CACHE_STORAGE_ERROR_NO_ERROR; | |
175 return !error; | |
176 } | |
177 | |
178 bool StorageMatch(const GURL& origin, | |
179 const std::string& cache_name, | |
180 const GURL& url) { | |
181 scoped_ptr<ServiceWorkerFetchRequest> request( | |
182 new ServiceWorkerFetchRequest()); | |
183 request->url = url; | |
184 scoped_ptr<base::RunLoop> loop(new base::RunLoop()); | |
185 cache_manager_->MatchCache( | |
186 origin, cache_name, request.Pass(), | |
187 base::Bind(&ServiceWorkerCacheStorageManagerTest::CacheMatchCallback, | |
188 base::Unretained(this), base::Unretained(loop.get()))); | |
189 loop->Run(); | |
190 | |
191 bool error = callback_cache_error_ != ServiceWorkerCache::ERROR_TYPE_OK; | |
192 return !error; | |
193 } | |
194 | |
195 bool StorageMatchAll(const GURL& origin, const GURL& url) { | |
196 scoped_ptr<ServiceWorkerFetchRequest> request( | |
197 new ServiceWorkerFetchRequest()); | |
198 request->url = url; | |
199 scoped_ptr<base::RunLoop> loop(new base::RunLoop()); | |
200 cache_manager_->MatchAllCaches( | |
201 origin, request.Pass(), | |
202 base::Bind(&ServiceWorkerCacheStorageManagerTest::CacheMatchCallback, | |
203 base::Unretained(this), base::Unretained(loop.get()))); | |
204 loop->Run(); | |
205 | |
206 bool error = callback_cache_error_ != ServiceWorkerCache::ERROR_TYPE_OK; | |
207 return !error; | |
208 } | |
209 | |
210 bool CachePut(const scoped_refptr<ServiceWorkerCache>& cache, | |
211 const GURL& url) { | |
212 scoped_ptr<ServiceWorkerFetchRequest> request( | |
213 new ServiceWorkerFetchRequest()); | |
214 scoped_ptr<ServiceWorkerResponse> response(new ServiceWorkerResponse()); | |
215 request->url = url; | |
216 response->url = url; | |
217 scoped_ptr<base::RunLoop> loop(new base::RunLoop()); | |
218 cache->Put( | |
219 request.Pass(), | |
220 response.Pass(), | |
221 base::Bind(&ServiceWorkerCacheStorageManagerTest::CachePutCallback, | |
222 base::Unretained(this), | |
223 base::Unretained(loop.get()))); | |
224 loop->Run(); | |
225 | |
226 bool error = callback_cache_error_ != ServiceWorkerCache::ERROR_TYPE_OK; | |
227 return !error; | |
228 } | |
229 | |
230 bool CacheMatch(const scoped_refptr<ServiceWorkerCache>& cache, | |
231 const GURL& url) { | |
232 scoped_ptr<ServiceWorkerFetchRequest> request( | |
233 new ServiceWorkerFetchRequest()); | |
234 request->url = url; | |
235 scoped_ptr<base::RunLoop> loop(new base::RunLoop()); | |
236 cache->Match( | |
237 request.Pass(), | |
238 base::Bind(&ServiceWorkerCacheStorageManagerTest::CacheMatchCallback, | |
239 base::Unretained(this), | |
240 base::Unretained(loop.get()))); | |
241 loop->Run(); | |
242 | |
243 bool error = callback_cache_error_ != ServiceWorkerCache::ERROR_TYPE_OK; | |
244 return !error; | |
245 } | |
246 | |
247 ServiceWorkerCacheStorage* CacheStorageForOrigin(const GURL& origin) { | |
248 return cache_manager_->FindOrCreateServiceWorkerCacheManager(origin); | |
249 } | |
250 | |
251 protected: | |
252 TestBrowserContext browser_context_; | |
253 TestBrowserThreadBundle browser_thread_bundle_; | |
254 | |
255 base::ScopedTempDir temp_dir_; | |
256 scoped_refptr<MockQuotaManagerProxy> quota_manager_proxy_; | |
257 scoped_ptr<ServiceWorkerCacheStorageManager> cache_manager_; | |
258 | |
259 scoped_refptr<ServiceWorkerCache> callback_cache_; | |
260 int callback_bool_; | |
261 ServiceWorkerCacheStorage::CacheStorageError callback_error_; | |
262 ServiceWorkerCache::ErrorType callback_cache_error_; | |
263 scoped_ptr<ServiceWorkerResponse> callback_cache_response_; | |
264 std::vector<std::string> callback_strings_; | |
265 | |
266 const GURL origin1_; | |
267 const GURL origin2_; | |
268 | |
269 private: | |
270 DISALLOW_COPY_AND_ASSIGN(ServiceWorkerCacheStorageManagerTest); | |
271 }; | |
272 | |
273 class ServiceWorkerCacheStorageManagerMemoryOnlyTest | |
274 : public ServiceWorkerCacheStorageManagerTest { | |
275 bool MemoryOnly() override { return true; } | |
276 }; | |
277 | |
278 class ServiceWorkerCacheStorageManagerTestP | |
279 : public ServiceWorkerCacheStorageManagerTest, | |
280 public testing::WithParamInterface<bool> { | |
281 bool MemoryOnly() override { return !GetParam(); } | |
282 }; | |
283 | |
284 TEST_F(ServiceWorkerCacheStorageManagerTest, TestsRunOnIOThread) { | |
285 EXPECT_TRUE(BrowserThread::CurrentlyOn(BrowserThread::IO)); | |
286 } | |
287 | |
288 TEST_P(ServiceWorkerCacheStorageManagerTestP, OpenCache) { | |
289 EXPECT_TRUE(Open(origin1_, "foo")); | |
290 } | |
291 | |
292 TEST_P(ServiceWorkerCacheStorageManagerTestP, OpenTwoCaches) { | |
293 EXPECT_TRUE(Open(origin1_, "foo")); | |
294 EXPECT_TRUE(Open(origin1_, "bar")); | |
295 } | |
296 | |
297 TEST_P(ServiceWorkerCacheStorageManagerTestP, CachePointersDiffer) { | |
298 EXPECT_TRUE(Open(origin1_, "foo")); | |
299 scoped_refptr<ServiceWorkerCache> cache = callback_cache_; | |
300 EXPECT_TRUE(Open(origin1_, "bar")); | |
301 EXPECT_NE(callback_cache_.get(), cache.get()); | |
302 } | |
303 | |
304 TEST_P(ServiceWorkerCacheStorageManagerTestP, Open2CachesSameNameDiffOrigins) { | |
305 EXPECT_TRUE(Open(origin1_, "foo")); | |
306 scoped_refptr<ServiceWorkerCache> cache = callback_cache_; | |
307 EXPECT_TRUE(Open(origin2_, "foo")); | |
308 EXPECT_NE(cache.get(), callback_cache_.get()); | |
309 } | |
310 | |
311 TEST_P(ServiceWorkerCacheStorageManagerTestP, OpenExistingCache) { | |
312 EXPECT_TRUE(Open(origin1_, "foo")); | |
313 scoped_refptr<ServiceWorkerCache> cache = callback_cache_; | |
314 EXPECT_TRUE(Open(origin1_, "foo")); | |
315 EXPECT_EQ(callback_cache_.get(), cache.get()); | |
316 } | |
317 | |
318 TEST_P(ServiceWorkerCacheStorageManagerTestP, HasCache) { | |
319 EXPECT_TRUE(Open(origin1_, "foo")); | |
320 EXPECT_TRUE(Has(origin1_, "foo")); | |
321 EXPECT_TRUE(callback_bool_); | |
322 } | |
323 | |
324 TEST_P(ServiceWorkerCacheStorageManagerTestP, HasNonExistent) { | |
325 EXPECT_FALSE(Has(origin1_, "foo")); | |
326 } | |
327 | |
328 TEST_P(ServiceWorkerCacheStorageManagerTestP, DeleteCache) { | |
329 EXPECT_TRUE(Open(origin1_, "foo")); | |
330 EXPECT_TRUE(Delete(origin1_, "foo")); | |
331 EXPECT_FALSE(Has(origin1_, "foo")); | |
332 } | |
333 | |
334 TEST_P(ServiceWorkerCacheStorageManagerTestP, DeleteTwice) { | |
335 EXPECT_TRUE(Open(origin1_, "foo")); | |
336 EXPECT_TRUE(Delete(origin1_, "foo")); | |
337 EXPECT_FALSE(Delete(origin1_, "foo")); | |
338 EXPECT_EQ(ServiceWorkerCacheStorage::CACHE_STORAGE_ERROR_NOT_FOUND, | |
339 callback_error_); | |
340 } | |
341 | |
342 TEST_P(ServiceWorkerCacheStorageManagerTestP, EmptyKeys) { | |
343 EXPECT_TRUE(Keys(origin1_)); | |
344 EXPECT_TRUE(callback_strings_.empty()); | |
345 } | |
346 | |
347 TEST_P(ServiceWorkerCacheStorageManagerTestP, SomeKeys) { | |
348 EXPECT_TRUE(Open(origin1_, "foo")); | |
349 EXPECT_TRUE(Open(origin1_, "bar")); | |
350 EXPECT_TRUE(Open(origin2_, "baz")); | |
351 EXPECT_TRUE(Keys(origin1_)); | |
352 EXPECT_EQ(2u, callback_strings_.size()); | |
353 std::vector<std::string> expected_keys; | |
354 expected_keys.push_back("foo"); | |
355 expected_keys.push_back("bar"); | |
356 EXPECT_EQ(expected_keys, callback_strings_); | |
357 EXPECT_TRUE(Keys(origin2_)); | |
358 EXPECT_EQ(1u, callback_strings_.size()); | |
359 EXPECT_STREQ("baz", callback_strings_[0].c_str()); | |
360 } | |
361 | |
362 TEST_P(ServiceWorkerCacheStorageManagerTestP, DeletedKeysGone) { | |
363 EXPECT_TRUE(Open(origin1_, "foo")); | |
364 EXPECT_TRUE(Open(origin1_, "bar")); | |
365 EXPECT_TRUE(Open(origin2_, "baz")); | |
366 EXPECT_TRUE(Delete(origin1_, "bar")); | |
367 EXPECT_TRUE(Keys(origin1_)); | |
368 EXPECT_EQ(1u, callback_strings_.size()); | |
369 EXPECT_STREQ("foo", callback_strings_[0].c_str()); | |
370 } | |
371 | |
372 TEST_P(ServiceWorkerCacheStorageManagerTestP, StorageMatchEntryExists) { | |
373 EXPECT_TRUE(Open(origin1_, "foo")); | |
374 EXPECT_TRUE(CachePut(callback_cache_, GURL("http://example.com/foo"))); | |
375 EXPECT_TRUE(StorageMatch(origin1_, "foo", GURL("http://example.com/foo"))); | |
376 } | |
377 | |
378 TEST_P(ServiceWorkerCacheStorageManagerTestP, StorageMatchNoEntry) { | |
379 EXPECT_TRUE(Open(origin1_, "foo")); | |
380 EXPECT_TRUE(CachePut(callback_cache_, GURL("http://example.com/foo"))); | |
381 EXPECT_FALSE(StorageMatch(origin1_, "foo", GURL("http://example.com/bar"))); | |
382 EXPECT_EQ(ServiceWorkerCache::ERROR_TYPE_NOT_FOUND, callback_cache_error_); | |
383 } | |
384 | |
385 TEST_P(ServiceWorkerCacheStorageManagerTestP, StorageMatchNoCache) { | |
386 EXPECT_TRUE(Open(origin1_, "foo")); | |
387 EXPECT_TRUE(CachePut(callback_cache_, GURL("http://example.com/foo"))); | |
388 EXPECT_FALSE(StorageMatch(origin1_, "bar", GURL("http://example.com/foo"))); | |
389 EXPECT_EQ(ServiceWorkerCache::ERROR_TYPE_NOT_FOUND, callback_cache_error_); | |
390 } | |
391 | |
392 TEST_P(ServiceWorkerCacheStorageManagerTestP, StorageMatchAllEntryExists) { | |
393 EXPECT_TRUE(Open(origin1_, "foo")); | |
394 EXPECT_TRUE(CachePut(callback_cache_, GURL("http://example.com/foo"))); | |
395 EXPECT_TRUE(StorageMatchAll(origin1_, GURL("http://example.com/foo"))); | |
396 } | |
397 | |
398 TEST_P(ServiceWorkerCacheStorageManagerTestP, StorageMatchAllNoEntry) { | |
399 EXPECT_TRUE(Open(origin1_, "foo")); | |
400 EXPECT_TRUE(CachePut(callback_cache_, GURL("http://example.com/foo"))); | |
401 EXPECT_FALSE(StorageMatchAll(origin1_, GURL("http://example.com/bar"))); | |
402 EXPECT_EQ(ServiceWorkerCache::ERROR_TYPE_NOT_FOUND, callback_cache_error_); | |
403 } | |
404 | |
405 TEST_P(ServiceWorkerCacheStorageManagerTestP, StorageMatchAllNoCaches) { | |
406 EXPECT_FALSE(StorageMatchAll(origin1_, GURL("http://example.com/foo"))); | |
407 EXPECT_EQ(ServiceWorkerCache::ERROR_TYPE_NOT_FOUND, callback_cache_error_); | |
408 } | |
409 | |
410 TEST_P(ServiceWorkerCacheStorageManagerTestP, StorageMatchAllEntryExistsTwice) { | |
411 EXPECT_TRUE(Open(origin1_, "foo")); | |
412 EXPECT_TRUE(CachePut(callback_cache_, GURL("http://example.com/foo"))); | |
413 EXPECT_TRUE(Open(origin1_, "bar")); | |
414 EXPECT_TRUE(CachePut(callback_cache_, GURL("http://example.com/foo"))); | |
415 | |
416 EXPECT_TRUE(StorageMatchAll(origin1_, GURL("http://example.com/foo"))); | |
417 } | |
418 | |
419 TEST_P(ServiceWorkerCacheStorageManagerTestP, StorageMatchInOneOfMany) { | |
420 EXPECT_TRUE(Open(origin1_, "foo")); | |
421 EXPECT_TRUE(Open(origin1_, "bar")); | |
422 EXPECT_TRUE(CachePut(callback_cache_, GURL("http://example.com/foo"))); | |
423 EXPECT_TRUE(Open(origin1_, "baz")); | |
424 | |
425 EXPECT_TRUE(StorageMatchAll(origin1_, GURL("http://example.com/foo"))); | |
426 } | |
427 | |
428 TEST_P(ServiceWorkerCacheStorageManagerTestP, Chinese) { | |
429 EXPECT_TRUE(Open(origin1_, "ä½ å¥½")); | |
430 scoped_refptr<ServiceWorkerCache> cache = callback_cache_; | |
431 EXPECT_TRUE(Open(origin1_, "ä½ å¥½")); | |
432 EXPECT_EQ(callback_cache_.get(), cache.get()); | |
433 EXPECT_TRUE(Keys(origin1_)); | |
434 EXPECT_EQ(1u, callback_strings_.size()); | |
435 EXPECT_STREQ("ä½ å¥½", callback_strings_[0].c_str()); | |
436 } | |
437 | |
438 TEST_F(ServiceWorkerCacheStorageManagerTest, EmptyKey) { | |
439 EXPECT_TRUE(Open(origin1_, "")); | |
440 scoped_refptr<ServiceWorkerCache> cache = callback_cache_; | |
441 EXPECT_TRUE(Open(origin1_, "")); | |
442 EXPECT_EQ(cache.get(), callback_cache_.get()); | |
443 EXPECT_TRUE(Keys(origin1_)); | |
444 EXPECT_EQ(1u, callback_strings_.size()); | |
445 EXPECT_STREQ("", callback_strings_[0].c_str()); | |
446 EXPECT_TRUE(Has(origin1_, "")); | |
447 EXPECT_TRUE(Delete(origin1_, "")); | |
448 EXPECT_TRUE(Keys(origin1_)); | |
449 EXPECT_EQ(0u, callback_strings_.size()); | |
450 } | |
451 | |
452 TEST_F(ServiceWorkerCacheStorageManagerTest, DataPersists) { | |
453 EXPECT_TRUE(Open(origin1_, "foo")); | |
454 EXPECT_TRUE(Open(origin1_, "bar")); | |
455 EXPECT_TRUE(Open(origin1_, "baz")); | |
456 EXPECT_TRUE(Open(origin2_, "raz")); | |
457 EXPECT_TRUE(Delete(origin1_, "bar")); | |
458 quota_manager_proxy_->SimulateQuotaManagerDestroyed(); | |
459 cache_manager_ = | |
460 ServiceWorkerCacheStorageManager::Create(cache_manager_.get()); | |
461 EXPECT_TRUE(Keys(origin1_)); | |
462 EXPECT_EQ(2u, callback_strings_.size()); | |
463 std::vector<std::string> expected_keys; | |
464 expected_keys.push_back("foo"); | |
465 expected_keys.push_back("baz"); | |
466 EXPECT_EQ(expected_keys, callback_strings_); | |
467 } | |
468 | |
469 TEST_F(ServiceWorkerCacheStorageManagerMemoryOnlyTest, DataLostWhenMemoryOnly) { | |
470 EXPECT_TRUE(Open(origin1_, "foo")); | |
471 EXPECT_TRUE(Open(origin2_, "baz")); | |
472 quota_manager_proxy_->SimulateQuotaManagerDestroyed(); | |
473 cache_manager_ = | |
474 ServiceWorkerCacheStorageManager::Create(cache_manager_.get()); | |
475 EXPECT_TRUE(Keys(origin1_)); | |
476 EXPECT_EQ(0u, callback_strings_.size()); | |
477 } | |
478 | |
479 TEST_F(ServiceWorkerCacheStorageManagerTest, BadCacheName) { | |
480 // Since the implementation writes cache names to disk, ensure that we don't | |
481 // escape the directory. | |
482 const std::string bad_name = "../../../../../../../../../../../../../../foo"; | |
483 EXPECT_TRUE(Open(origin1_, bad_name)); | |
484 EXPECT_TRUE(Keys(origin1_)); | |
485 EXPECT_EQ(1u, callback_strings_.size()); | |
486 EXPECT_STREQ(bad_name.c_str(), callback_strings_[0].c_str()); | |
487 } | |
488 | |
489 TEST_F(ServiceWorkerCacheStorageManagerTest, BadOriginName) { | |
490 // Since the implementation writes origin names to disk, ensure that we don't | |
491 // escape the directory. | |
492 GURL bad_origin("http://../../../../../../../../../../../../../../foo"); | |
493 EXPECT_TRUE(Open(bad_origin, "foo")); | |
494 EXPECT_TRUE(Keys(bad_origin)); | |
495 EXPECT_EQ(1u, callback_strings_.size()); | |
496 EXPECT_STREQ("foo", callback_strings_[0].c_str()); | |
497 } | |
498 | |
499 // With a persistent cache if the client drops its reference to a | |
500 // ServiceWorkerCache | |
501 // it should be deleted. | |
502 TEST_F(ServiceWorkerCacheStorageManagerTest, DropReference) { | |
503 EXPECT_TRUE(Open(origin1_, "foo")); | |
504 base::WeakPtr<ServiceWorkerCache> cache = callback_cache_->AsWeakPtr(); | |
505 callback_cache_ = NULL; | |
506 EXPECT_TRUE(!cache); | |
507 } | |
508 | |
509 // With a memory cache the cache can't be freed from memory until the client | |
510 // calls delete. | |
511 TEST_F(ServiceWorkerCacheStorageManagerMemoryOnlyTest, | |
512 MemoryLosesReferenceOnlyAfterDelete) { | |
513 EXPECT_TRUE(Open(origin1_, "foo")); | |
514 base::WeakPtr<ServiceWorkerCache> cache = callback_cache_->AsWeakPtr(); | |
515 callback_cache_ = NULL; | |
516 EXPECT_TRUE(cache); | |
517 EXPECT_TRUE(Delete(origin1_, "foo")); | |
518 EXPECT_FALSE(cache); | |
519 } | |
520 | |
521 TEST_P(ServiceWorkerCacheStorageManagerTestP, DeleteBeforeRelease) { | |
522 EXPECT_TRUE(Open(origin1_, "foo")); | |
523 EXPECT_TRUE(Delete(origin1_, "foo")); | |
524 EXPECT_TRUE(callback_cache_->AsWeakPtr()); | |
525 } | |
526 | |
527 TEST_P(ServiceWorkerCacheStorageManagerTestP, OpenRunsSerially) { | |
528 EXPECT_FALSE(Delete(origin1_, "tmp")); // Init storage. | |
529 ServiceWorkerCacheStorage* cache_storage = CacheStorageForOrigin(origin1_); | |
530 cache_storage->StartAsyncOperationForTesting(); | |
531 | |
532 scoped_ptr<base::RunLoop> open_loop(new base::RunLoop()); | |
533 cache_manager_->OpenCache( | |
534 origin1_, "foo", | |
535 base::Bind(&ServiceWorkerCacheStorageManagerTest::CacheAndErrorCallback, | |
536 base::Unretained(this), base::Unretained(open_loop.get()))); | |
537 | |
538 base::RunLoop().RunUntilIdle(); | |
539 EXPECT_FALSE(callback_cache_); | |
540 | |
541 cache_storage->CompleteAsyncOperationForTesting(); | |
542 open_loop->Run(); | |
543 EXPECT_TRUE(callback_cache_); | |
544 } | |
545 | |
546 TEST_F(ServiceWorkerCacheStorageManagerMemoryOnlyTest, MemoryBackedSize) { | |
547 ServiceWorkerCacheStorage* cache_storage = CacheStorageForOrigin(origin1_); | |
548 EXPECT_EQ(0, cache_storage->MemoryBackedSize()); | |
549 | |
550 EXPECT_TRUE(Open(origin1_, "foo")); | |
551 scoped_refptr<ServiceWorkerCache> foo_cache = callback_cache_; | |
552 EXPECT_TRUE(Open(origin1_, "bar")); | |
553 scoped_refptr<ServiceWorkerCache> bar_cache = callback_cache_; | |
554 EXPECT_EQ(0, cache_storage->MemoryBackedSize()); | |
555 | |
556 EXPECT_TRUE(CachePut(foo_cache, GURL("http://example.com/foo"))); | |
557 EXPECT_LT(0, cache_storage->MemoryBackedSize()); | |
558 int64 foo_size = cache_storage->MemoryBackedSize(); | |
559 | |
560 EXPECT_TRUE(CachePut(bar_cache, GURL("http://example.com/foo"))); | |
561 EXPECT_EQ(foo_size * 2, cache_storage->MemoryBackedSize()); | |
562 } | |
563 | |
564 TEST_F(ServiceWorkerCacheStorageManagerTest, MemoryBackedSizePersistent) { | |
565 ServiceWorkerCacheStorage* cache_storage = CacheStorageForOrigin(origin1_); | |
566 EXPECT_EQ(0, cache_storage->MemoryBackedSize()); | |
567 EXPECT_TRUE(Open(origin1_, "foo")); | |
568 EXPECT_TRUE(CachePut(callback_cache_, GURL("http://example.com/foo"))); | |
569 EXPECT_EQ(0, cache_storage->MemoryBackedSize()); | |
570 } | |
571 | |
572 class ServiceWorkerCacheStorageMigrationTest | |
573 : public ServiceWorkerCacheStorageManagerTest { | |
574 protected: | |
575 ServiceWorkerCacheStorageMigrationTest() : cache1_("foo"), cache2_("bar") {} | |
576 | |
577 void SetUp() override { | |
578 ServiceWorkerCacheStorageManagerTest::SetUp(); | |
579 | |
580 // Populate a cache, then move it to the "legacy" location | |
581 // so that tests can verify the results of migration. | |
582 legacy_path_ = ServiceWorkerCacheStorageManager::ConstructLegacyOriginPath( | |
583 cache_manager_->root_path(), origin1_); | |
584 new_path_ = ServiceWorkerCacheStorageManager::ConstructOriginPath( | |
585 cache_manager_->root_path(), origin1_); | |
586 | |
587 ASSERT_FALSE(base::DirectoryExists(legacy_path_)); | |
588 ASSERT_FALSE(base::DirectoryExists(new_path_)); | |
589 ASSERT_TRUE(Open(origin1_, cache1_)); | |
590 ASSERT_TRUE(Open(origin1_, cache2_)); | |
591 callback_cache_ = nullptr; | |
592 ASSERT_FALSE(base::DirectoryExists(legacy_path_)); | |
593 ASSERT_TRUE(base::DirectoryExists(new_path_)); | |
594 | |
595 quota_manager_proxy_->SimulateQuotaManagerDestroyed(); | |
596 cache_manager_ = | |
597 ServiceWorkerCacheStorageManager::Create(cache_manager_.get()); | |
598 | |
599 ASSERT_TRUE(base::Move(new_path_, legacy_path_)); | |
600 ASSERT_TRUE(base::DirectoryExists(legacy_path_)); | |
601 ASSERT_FALSE(base::DirectoryExists(new_path_)); | |
602 } | |
603 | |
604 int64 GetOriginUsage(const GURL& origin) { | |
605 scoped_ptr<base::RunLoop> loop(new base::RunLoop()); | |
606 cache_manager_->GetOriginUsage( | |
607 origin, | |
608 base::Bind(&ServiceWorkerCacheStorageMigrationTest::UsageCallback, | |
609 base::Unretained(this), base::Unretained(loop.get()))); | |
610 loop->Run(); | |
611 return callback_usage_; | |
612 } | |
613 | |
614 void UsageCallback(base::RunLoop* run_loop, int64 usage) { | |
615 callback_usage_ = usage; | |
616 run_loop->Quit(); | |
617 } | |
618 | |
619 base::FilePath legacy_path_; | |
620 base::FilePath new_path_; | |
621 | |
622 const std::string cache1_; | |
623 const std::string cache2_; | |
624 | |
625 int64 callback_usage_; | |
626 | |
627 DISALLOW_COPY_AND_ASSIGN(ServiceWorkerCacheStorageMigrationTest); | |
628 }; | |
629 | |
630 TEST_F(ServiceWorkerCacheStorageMigrationTest, OpenCache) { | |
631 EXPECT_TRUE(Open(origin1_, cache1_)); | |
632 EXPECT_FALSE(base::DirectoryExists(legacy_path_)); | |
633 EXPECT_TRUE(base::DirectoryExists(new_path_)); | |
634 | |
635 EXPECT_TRUE(Keys(origin1_)); | |
636 std::vector<std::string> expected_keys; | |
637 expected_keys.push_back(cache1_); | |
638 expected_keys.push_back(cache2_); | |
639 EXPECT_EQ(expected_keys, callback_strings_); | |
640 } | |
641 | |
642 TEST_F(ServiceWorkerCacheStorageMigrationTest, DeleteCache) { | |
643 EXPECT_TRUE(Delete(origin1_, cache1_)); | |
644 EXPECT_FALSE(base::DirectoryExists(legacy_path_)); | |
645 EXPECT_TRUE(base::DirectoryExists(new_path_)); | |
646 | |
647 EXPECT_TRUE(Keys(origin1_)); | |
648 std::vector<std::string> expected_keys; | |
649 expected_keys.push_back(cache2_); | |
650 EXPECT_EQ(expected_keys, callback_strings_); | |
651 } | |
652 | |
653 TEST_F(ServiceWorkerCacheStorageMigrationTest, GetOriginUsage) { | |
654 EXPECT_GT(GetOriginUsage(origin1_), 0); | |
655 EXPECT_FALSE(base::DirectoryExists(legacy_path_)); | |
656 EXPECT_TRUE(base::DirectoryExists(new_path_)); | |
657 } | |
658 | |
659 TEST_F(ServiceWorkerCacheStorageMigrationTest, MoveFailure) { | |
660 // Revert the migration. | |
661 ASSERT_TRUE(base::Move(legacy_path_, new_path_)); | |
662 ASSERT_FALSE(base::DirectoryExists(legacy_path_)); | |
663 ASSERT_TRUE(base::DirectoryExists(new_path_)); | |
664 | |
665 // Make a dummy legacy directory. | |
666 ASSERT_TRUE(base::CreateDirectory(legacy_path_)); | |
667 | |
668 // Ensure that migration doesn't stomp existing new directory, | |
669 // but does clean up old directory. | |
670 EXPECT_TRUE(Open(origin1_, cache1_)); | |
671 EXPECT_FALSE(base::DirectoryExists(legacy_path_)); | |
672 EXPECT_TRUE(base::DirectoryExists(new_path_)); | |
673 | |
674 EXPECT_TRUE(Keys(origin1_)); | |
675 std::vector<std::string> expected_keys; | |
676 expected_keys.push_back(cache1_); | |
677 expected_keys.push_back(cache2_); | |
678 EXPECT_EQ(expected_keys, callback_strings_); | |
679 } | |
680 | |
681 class ServiceWorkerCacheQuotaClientTest | |
682 : public ServiceWorkerCacheStorageManagerTest { | |
683 protected: | |
684 ServiceWorkerCacheQuotaClientTest() {} | |
685 | |
686 void SetUp() override { | |
687 ServiceWorkerCacheStorageManagerTest::SetUp(); | |
688 quota_client_.reset( | |
689 new ServiceWorkerCacheQuotaClient(cache_manager_->AsWeakPtr())); | |
690 } | |
691 | |
692 void UsageCallback(base::RunLoop* run_loop, int64 usage) { | |
693 callback_usage_ = usage; | |
694 run_loop->Quit(); | |
695 } | |
696 | |
697 void OriginsCallback(base::RunLoop* run_loop, const std::set<GURL>& origins) { | |
698 callback_origins_ = origins; | |
699 run_loop->Quit(); | |
700 } | |
701 | |
702 void DeleteOriginCallback(base::RunLoop* run_loop, | |
703 storage::QuotaStatusCode status) { | |
704 callback_status_ = status; | |
705 run_loop->Quit(); | |
706 } | |
707 | |
708 int64 QuotaGetOriginUsage(const GURL& origin) { | |
709 scoped_ptr<base::RunLoop> loop(new base::RunLoop()); | |
710 quota_client_->GetOriginUsage( | |
711 origin, | |
712 storage::kStorageTypeTemporary, | |
713 base::Bind(&ServiceWorkerCacheQuotaClientTest::UsageCallback, | |
714 base::Unretained(this), | |
715 base::Unretained(loop.get()))); | |
716 loop->Run(); | |
717 return callback_usage_; | |
718 } | |
719 | |
720 size_t QuotaGetOriginsForType() { | |
721 scoped_ptr<base::RunLoop> loop(new base::RunLoop()); | |
722 quota_client_->GetOriginsForType( | |
723 storage::kStorageTypeTemporary, | |
724 base::Bind(&ServiceWorkerCacheQuotaClientTest::OriginsCallback, | |
725 base::Unretained(this), | |
726 base::Unretained(loop.get()))); | |
727 loop->Run(); | |
728 return callback_origins_.size(); | |
729 } | |
730 | |
731 size_t QuotaGetOriginsForHost(const std::string& host) { | |
732 scoped_ptr<base::RunLoop> loop(new base::RunLoop()); | |
733 quota_client_->GetOriginsForHost( | |
734 storage::kStorageTypeTemporary, | |
735 host, | |
736 base::Bind(&ServiceWorkerCacheQuotaClientTest::OriginsCallback, | |
737 base::Unretained(this), | |
738 base::Unretained(loop.get()))); | |
739 loop->Run(); | |
740 return callback_origins_.size(); | |
741 } | |
742 | |
743 bool QuotaDeleteOriginData(const GURL& origin) { | |
744 scoped_ptr<base::RunLoop> loop(new base::RunLoop()); | |
745 quota_client_->DeleteOriginData( | |
746 origin, | |
747 storage::kStorageTypeTemporary, | |
748 base::Bind(&ServiceWorkerCacheQuotaClientTest::DeleteOriginCallback, | |
749 base::Unretained(this), | |
750 base::Unretained(loop.get()))); | |
751 loop->Run(); | |
752 return callback_status_ == storage::kQuotaStatusOk; | |
753 } | |
754 | |
755 bool QuotaDoesSupport(storage::StorageType type) { | |
756 return quota_client_->DoesSupport(type); | |
757 } | |
758 | |
759 scoped_ptr<ServiceWorkerCacheQuotaClient> quota_client_; | |
760 | |
761 storage::QuotaStatusCode callback_status_; | |
762 int64 callback_usage_; | |
763 std::set<GURL> callback_origins_; | |
764 | |
765 DISALLOW_COPY_AND_ASSIGN(ServiceWorkerCacheQuotaClientTest); | |
766 }; | |
767 | |
768 class ServiceWorkerCacheQuotaClientTestP | |
769 : public ServiceWorkerCacheQuotaClientTest, | |
770 public testing::WithParamInterface<bool> { | |
771 bool MemoryOnly() override { return !GetParam(); } | |
772 }; | |
773 | |
774 TEST_P(ServiceWorkerCacheQuotaClientTestP, QuotaID) { | |
775 EXPECT_EQ(storage::QuotaClient::kServiceWorkerCache, quota_client_->id()); | |
776 } | |
777 | |
778 TEST_P(ServiceWorkerCacheQuotaClientTestP, QuotaGetOriginUsage) { | |
779 EXPECT_EQ(0, QuotaGetOriginUsage(origin1_)); | |
780 EXPECT_TRUE(Open(origin1_, "foo")); | |
781 EXPECT_TRUE(CachePut(callback_cache_, GURL("http://example.com/foo"))); | |
782 EXPECT_LT(0, QuotaGetOriginUsage(origin1_)); | |
783 } | |
784 | |
785 TEST_P(ServiceWorkerCacheQuotaClientTestP, QuotaGetOriginsForType) { | |
786 EXPECT_EQ(0u, QuotaGetOriginsForType()); | |
787 EXPECT_TRUE(Open(origin1_, "foo")); | |
788 EXPECT_TRUE(Open(origin1_, "bar")); | |
789 EXPECT_TRUE(Open(origin2_, "foo")); | |
790 EXPECT_EQ(2u, QuotaGetOriginsForType()); | |
791 } | |
792 | |
793 TEST_P(ServiceWorkerCacheQuotaClientTestP, QuotaGetOriginsForHost) { | |
794 EXPECT_EQ(0u, QuotaGetOriginsForHost("example.com")); | |
795 EXPECT_TRUE(Open(GURL("http://example.com:8080"), "foo")); | |
796 EXPECT_TRUE(Open(GURL("http://example.com:9000"), "foo")); | |
797 EXPECT_TRUE(Open(GURL("ftp://example.com"), "foo")); | |
798 EXPECT_TRUE(Open(GURL("http://example2.com"), "foo")); | |
799 EXPECT_EQ(3u, QuotaGetOriginsForHost("example.com")); | |
800 EXPECT_EQ(1u, QuotaGetOriginsForHost("example2.com")); | |
801 EXPECT_TRUE(callback_origins_.find(GURL("http://example2.com")) != | |
802 callback_origins_.end()); | |
803 EXPECT_EQ(0u, QuotaGetOriginsForHost("unknown.com")); | |
804 } | |
805 | |
806 TEST_P(ServiceWorkerCacheQuotaClientTestP, QuotaDeleteOriginData) { | |
807 EXPECT_TRUE(Open(origin1_, "foo")); | |
808 // Call put to test that initialized caches are properly deleted too. | |
809 EXPECT_TRUE(CachePut(callback_cache_, GURL("http://example.com/foo"))); | |
810 EXPECT_TRUE(Open(origin1_, "bar")); | |
811 EXPECT_TRUE(Open(origin2_, "baz")); | |
812 | |
813 EXPECT_TRUE(QuotaDeleteOriginData(origin1_)); | |
814 | |
815 EXPECT_FALSE(Has(origin1_, "foo")); | |
816 EXPECT_FALSE(Has(origin1_, "bar")); | |
817 EXPECT_TRUE(Has(origin2_, "baz")); | |
818 EXPECT_TRUE(Open(origin1_, "foo")); | |
819 } | |
820 | |
821 TEST_P(ServiceWorkerCacheQuotaClientTestP, QuotaDeleteEmptyOrigin) { | |
822 EXPECT_TRUE(QuotaDeleteOriginData(origin1_)); | |
823 } | |
824 | |
825 TEST_P(ServiceWorkerCacheQuotaClientTestP, QuotaDoesSupport) { | |
826 EXPECT_TRUE(QuotaDoesSupport(storage::kStorageTypeTemporary)); | |
827 EXPECT_FALSE(QuotaDoesSupport(storage::kStorageTypePersistent)); | |
828 EXPECT_FALSE(QuotaDoesSupport(storage::kStorageTypeSyncable)); | |
829 EXPECT_FALSE(QuotaDoesSupport(storage::kStorageTypeQuotaNotManaged)); | |
830 EXPECT_FALSE(QuotaDoesSupport(storage::kStorageTypeUnknown)); | |
831 } | |
832 | |
833 INSTANTIATE_TEST_CASE_P(ServiceWorkerCacheStorageManagerTests, | |
834 ServiceWorkerCacheStorageManagerTestP, | |
835 ::testing::Values(false, true)); | |
836 | |
837 INSTANTIATE_TEST_CASE_P(ServiceWorkerCacheQuotaClientTests, | |
838 ServiceWorkerCacheQuotaClientTestP, | |
839 ::testing::Values(false, true)); | |
840 | |
841 } // namespace content | |
OLD | NEW |