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/cache_storage/cache_storage_manager.h"
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/run_loop.h"
11 #include "base/stl_util.h"
12 #include "base/thread_task_runner_handle.h"
13 #include "content/browser/cache_storage/cache_storage_quota_client.h"
14 #include "content/browser/fileapi/chrome_blob_storage_context.h"
15 #include "content/browser/quota/mock_quota_manager_proxy.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"
26 class CacheStorageManagerTest
: public testing::Test
{
28 CacheStorageManagerTest()
29 : browser_thread_bundle_(TestBrowserThreadBundle::IO_MAINLOOP
),
30 callback_bool_(false),
31 callback_error_(CACHE_STORAGE_OK
),
32 origin1_("http://example1.com"),
33 origin2_("http://example2.com") {}
35 void SetUp() override
{
36 ChromeBlobStorageContext
* blob_storage_context(
37 ChromeBlobStorageContext::GetFor(&browser_context_
));
38 // Wait for ChromeBlobStorageContext to finish initializing.
39 base::RunLoop().RunUntilIdle();
41 quota_manager_proxy_
= new MockQuotaManagerProxy(
42 nullptr, base::ThreadTaskRunnerHandle::Get().get());
45 cache_manager_
= CacheStorageManager::Create(
46 base::FilePath(), base::ThreadTaskRunnerHandle::Get(),
47 quota_manager_proxy_
);
49 ASSERT_TRUE(temp_dir_
.CreateUniqueTempDir());
50 cache_manager_
= CacheStorageManager::Create(
51 temp_dir_
.path(), base::ThreadTaskRunnerHandle::Get(),
52 quota_manager_proxy_
);
55 cache_manager_
->SetBlobParametersForCache(
56 browser_context_
.GetRequestContext(),
57 blob_storage_context
->context()->AsWeakPtr());
60 void TearDown() override
{
61 quota_manager_proxy_
->SimulateQuotaManagerDestroyed();
62 base::RunLoop().RunUntilIdle();
65 virtual bool MemoryOnly() { return false; }
67 void BoolAndErrorCallback(base::RunLoop
* run_loop
,
69 CacheStorageError error
) {
70 callback_bool_
= value
;
71 callback_error_
= error
;
75 void CacheAndErrorCallback(base::RunLoop
* run_loop
,
76 const scoped_refptr
<CacheStorageCache
>& cache
,
77 CacheStorageError error
) {
78 callback_cache_
= cache
;
79 callback_error_
= error
;
83 void StringsAndErrorCallback(base::RunLoop
* run_loop
,
84 const std::vector
<std::string
>& strings
,
85 CacheStorageError error
) {
86 callback_strings_
= strings
;
87 callback_error_
= error
;
91 void CachePutCallback(base::RunLoop
* run_loop
, CacheStorageError error
) {
92 callback_error_
= error
;
96 void CacheMatchCallback(
97 base::RunLoop
* run_loop
,
98 CacheStorageError error
,
99 scoped_ptr
<ServiceWorkerResponse
> response
,
100 scoped_ptr
<storage::BlobDataHandle
> blob_data_handle
) {
101 callback_error_
= error
;
102 callback_cache_response_
= response
.Pass();
103 // Deliberately drop the data handle as only the url is being tested.
107 bool Open(const GURL
& origin
, const std::string
& cache_name
) {
108 scoped_ptr
<base::RunLoop
> loop(new base::RunLoop());
109 cache_manager_
->OpenCache(
111 base::Bind(&CacheStorageManagerTest::CacheAndErrorCallback
,
112 base::Unretained(this), base::Unretained(loop
.get())));
115 bool error
= callback_error_
!= CACHE_STORAGE_OK
;
117 EXPECT_TRUE(!callback_cache_
.get());
119 EXPECT_TRUE(callback_cache_
.get());
123 bool Has(const GURL
& origin
, const std::string
& cache_name
) {
124 scoped_ptr
<base::RunLoop
> loop(new base::RunLoop());
125 cache_manager_
->HasCache(
127 base::Bind(&CacheStorageManagerTest::BoolAndErrorCallback
,
128 base::Unretained(this), base::Unretained(loop
.get())));
131 return callback_bool_
;
134 bool Delete(const GURL
& origin
, const std::string
& cache_name
) {
135 scoped_ptr
<base::RunLoop
> loop(new base::RunLoop());
136 cache_manager_
->DeleteCache(
138 base::Bind(&CacheStorageManagerTest::BoolAndErrorCallback
,
139 base::Unretained(this), base::Unretained(loop
.get())));
142 return callback_bool_
;
145 bool Keys(const GURL
& origin
) {
146 scoped_ptr
<base::RunLoop
> loop(new base::RunLoop());
147 cache_manager_
->EnumerateCaches(
149 base::Bind(&CacheStorageManagerTest::StringsAndErrorCallback
,
150 base::Unretained(this), base::Unretained(loop
.get())));
153 return callback_error_
== CACHE_STORAGE_OK
;
156 bool StorageMatch(const GURL
& origin
,
157 const std::string
& cache_name
,
159 scoped_ptr
<ServiceWorkerFetchRequest
> request(
160 new ServiceWorkerFetchRequest());
162 scoped_ptr
<base::RunLoop
> loop(new base::RunLoop());
163 cache_manager_
->MatchCache(
164 origin
, cache_name
, request
.Pass(),
165 base::Bind(&CacheStorageManagerTest::CacheMatchCallback
,
166 base::Unretained(this), base::Unretained(loop
.get())));
169 return callback_error_
== CACHE_STORAGE_OK
;
172 bool StorageMatchAll(const GURL
& origin
, const GURL
& url
) {
173 scoped_ptr
<ServiceWorkerFetchRequest
> request(
174 new ServiceWorkerFetchRequest());
176 scoped_ptr
<base::RunLoop
> loop(new base::RunLoop());
177 cache_manager_
->MatchAllCaches(
178 origin
, request
.Pass(),
179 base::Bind(&CacheStorageManagerTest::CacheMatchCallback
,
180 base::Unretained(this), base::Unretained(loop
.get())));
183 return callback_error_
== CACHE_STORAGE_OK
;
186 bool CachePut(const scoped_refptr
<CacheStorageCache
>& cache
,
188 ServiceWorkerFetchRequest request
;
189 ServiceWorkerResponse response
;
193 CacheStorageBatchOperation operation
;
194 operation
.operation_type
= CACHE_STORAGE_CACHE_OPERATION_TYPE_PUT
;
195 operation
.request
= request
;
196 operation
.response
= response
;
198 scoped_ptr
<base::RunLoop
> loop(new base::RunLoop());
199 cache
->BatchOperation(
200 std::vector
<CacheStorageBatchOperation
>(1, operation
),
201 base::Bind(&CacheStorageManagerTest::CachePutCallback
,
202 base::Unretained(this), base::Unretained(loop
.get())));
205 return callback_error_
== CACHE_STORAGE_OK
;
208 bool CacheMatch(const scoped_refptr
<CacheStorageCache
>& cache
,
210 scoped_ptr
<ServiceWorkerFetchRequest
> request(
211 new ServiceWorkerFetchRequest());
213 scoped_ptr
<base::RunLoop
> loop(new base::RunLoop());
216 base::Bind(&CacheStorageManagerTest::CacheMatchCallback
,
217 base::Unretained(this), base::Unretained(loop
.get())));
220 return callback_error_
== CACHE_STORAGE_OK
;
223 CacheStorage
* CacheStorageForOrigin(const GURL
& origin
) {
224 return cache_manager_
->FindOrCreateCacheStorage(origin
);
228 TestBrowserContext browser_context_
;
229 TestBrowserThreadBundle browser_thread_bundle_
;
231 base::ScopedTempDir temp_dir_
;
232 scoped_refptr
<MockQuotaManagerProxy
> quota_manager_proxy_
;
233 scoped_ptr
<CacheStorageManager
> cache_manager_
;
235 scoped_refptr
<CacheStorageCache
> callback_cache_
;
237 CacheStorageError callback_error_
;
238 scoped_ptr
<ServiceWorkerResponse
> callback_cache_response_
;
239 std::vector
<std::string
> callback_strings_
;
245 DISALLOW_COPY_AND_ASSIGN(CacheStorageManagerTest
);
248 class CacheStorageManagerMemoryOnlyTest
: public CacheStorageManagerTest
{
249 bool MemoryOnly() override
{ return true; }
252 class CacheStorageManagerTestP
: public CacheStorageManagerTest
,
253 public testing::WithParamInterface
<bool> {
254 bool MemoryOnly() override
{ return !GetParam(); }
257 TEST_F(CacheStorageManagerTest
, TestsRunOnIOThread
) {
258 EXPECT_TRUE(BrowserThread::CurrentlyOn(BrowserThread::IO
));
261 TEST_P(CacheStorageManagerTestP
, OpenCache
) {
262 EXPECT_TRUE(Open(origin1_
, "foo"));
265 TEST_P(CacheStorageManagerTestP
, OpenTwoCaches
) {
266 EXPECT_TRUE(Open(origin1_
, "foo"));
267 EXPECT_TRUE(Open(origin1_
, "bar"));
270 TEST_P(CacheStorageManagerTestP
, CachePointersDiffer
) {
271 EXPECT_TRUE(Open(origin1_
, "foo"));
272 scoped_refptr
<CacheStorageCache
> cache
= callback_cache_
;
273 EXPECT_TRUE(Open(origin1_
, "bar"));
274 EXPECT_NE(callback_cache_
.get(), cache
.get());
277 TEST_P(CacheStorageManagerTestP
, Open2CachesSameNameDiffOrigins
) {
278 EXPECT_TRUE(Open(origin1_
, "foo"));
279 scoped_refptr
<CacheStorageCache
> cache
= callback_cache_
;
280 EXPECT_TRUE(Open(origin2_
, "foo"));
281 EXPECT_NE(cache
.get(), callback_cache_
.get());
284 TEST_P(CacheStorageManagerTestP
, OpenExistingCache
) {
285 EXPECT_TRUE(Open(origin1_
, "foo"));
286 scoped_refptr
<CacheStorageCache
> cache
= callback_cache_
;
287 EXPECT_TRUE(Open(origin1_
, "foo"));
288 EXPECT_EQ(callback_cache_
.get(), cache
.get());
291 TEST_P(CacheStorageManagerTestP
, HasCache
) {
292 EXPECT_TRUE(Open(origin1_
, "foo"));
293 EXPECT_TRUE(Has(origin1_
, "foo"));
294 EXPECT_TRUE(callback_bool_
);
297 TEST_P(CacheStorageManagerTestP
, HasNonExistent
) {
298 EXPECT_FALSE(Has(origin1_
, "foo"));
301 TEST_P(CacheStorageManagerTestP
, DeleteCache
) {
302 EXPECT_TRUE(Open(origin1_
, "foo"));
303 EXPECT_TRUE(Delete(origin1_
, "foo"));
304 EXPECT_FALSE(Has(origin1_
, "foo"));
307 TEST_P(CacheStorageManagerTestP
, DeleteTwice
) {
308 EXPECT_TRUE(Open(origin1_
, "foo"));
309 EXPECT_TRUE(Delete(origin1_
, "foo"));
310 EXPECT_FALSE(Delete(origin1_
, "foo"));
311 EXPECT_EQ(CACHE_STORAGE_ERROR_NOT_FOUND
, callback_error_
);
314 TEST_P(CacheStorageManagerTestP
, EmptyKeys
) {
315 EXPECT_TRUE(Keys(origin1_
));
316 EXPECT_TRUE(callback_strings_
.empty());
319 TEST_P(CacheStorageManagerTestP
, SomeKeys
) {
320 EXPECT_TRUE(Open(origin1_
, "foo"));
321 EXPECT_TRUE(Open(origin1_
, "bar"));
322 EXPECT_TRUE(Open(origin2_
, "baz"));
323 EXPECT_TRUE(Keys(origin1_
));
324 EXPECT_EQ(2u, callback_strings_
.size());
325 std::vector
<std::string
> expected_keys
;
326 expected_keys
.push_back("foo");
327 expected_keys
.push_back("bar");
328 EXPECT_EQ(expected_keys
, callback_strings_
);
329 EXPECT_TRUE(Keys(origin2_
));
330 EXPECT_EQ(1u, callback_strings_
.size());
331 EXPECT_STREQ("baz", callback_strings_
[0].c_str());
334 TEST_P(CacheStorageManagerTestP
, DeletedKeysGone
) {
335 EXPECT_TRUE(Open(origin1_
, "foo"));
336 EXPECT_TRUE(Open(origin1_
, "bar"));
337 EXPECT_TRUE(Open(origin2_
, "baz"));
338 EXPECT_TRUE(Delete(origin1_
, "bar"));
339 EXPECT_TRUE(Keys(origin1_
));
340 EXPECT_EQ(1u, callback_strings_
.size());
341 EXPECT_STREQ("foo", callback_strings_
[0].c_str());
344 TEST_P(CacheStorageManagerTestP
, StorageMatchEntryExists
) {
345 EXPECT_TRUE(Open(origin1_
, "foo"));
346 EXPECT_TRUE(CachePut(callback_cache_
, GURL("http://example.com/foo")));
347 EXPECT_TRUE(StorageMatch(origin1_
, "foo", GURL("http://example.com/foo")));
350 TEST_P(CacheStorageManagerTestP
, StorageMatchNoEntry
) {
351 EXPECT_TRUE(Open(origin1_
, "foo"));
352 EXPECT_TRUE(CachePut(callback_cache_
, GURL("http://example.com/foo")));
353 EXPECT_FALSE(StorageMatch(origin1_
, "foo", GURL("http://example.com/bar")));
354 EXPECT_EQ(CACHE_STORAGE_ERROR_NOT_FOUND
, callback_error_
);
357 TEST_P(CacheStorageManagerTestP
, StorageMatchNoCache
) {
358 EXPECT_TRUE(Open(origin1_
, "foo"));
359 EXPECT_TRUE(CachePut(callback_cache_
, GURL("http://example.com/foo")));
360 EXPECT_FALSE(StorageMatch(origin1_
, "bar", GURL("http://example.com/foo")));
361 EXPECT_EQ(CACHE_STORAGE_ERROR_NOT_FOUND
, callback_error_
);
364 TEST_P(CacheStorageManagerTestP
, StorageMatchAllEntryExists
) {
365 EXPECT_TRUE(Open(origin1_
, "foo"));
366 EXPECT_TRUE(CachePut(callback_cache_
, GURL("http://example.com/foo")));
367 EXPECT_TRUE(StorageMatchAll(origin1_
, GURL("http://example.com/foo")));
370 TEST_P(CacheStorageManagerTestP
, StorageMatchAllNoEntry
) {
371 EXPECT_TRUE(Open(origin1_
, "foo"));
372 EXPECT_TRUE(CachePut(callback_cache_
, GURL("http://example.com/foo")));
373 EXPECT_FALSE(StorageMatchAll(origin1_
, GURL("http://example.com/bar")));
374 EXPECT_EQ(CACHE_STORAGE_ERROR_NOT_FOUND
, callback_error_
);
377 TEST_P(CacheStorageManagerTestP
, StorageMatchAllNoCaches
) {
378 EXPECT_FALSE(StorageMatchAll(origin1_
, GURL("http://example.com/foo")));
379 EXPECT_EQ(CACHE_STORAGE_ERROR_NOT_FOUND
, callback_error_
);
382 TEST_P(CacheStorageManagerTestP
, StorageMatchAllEntryExistsTwice
) {
383 EXPECT_TRUE(Open(origin1_
, "foo"));
384 EXPECT_TRUE(CachePut(callback_cache_
, GURL("http://example.com/foo")));
385 EXPECT_TRUE(Open(origin1_
, "bar"));
386 EXPECT_TRUE(CachePut(callback_cache_
, GURL("http://example.com/foo")));
388 EXPECT_TRUE(StorageMatchAll(origin1_
, GURL("http://example.com/foo")));
391 TEST_P(CacheStorageManagerTestP
, StorageMatchInOneOfMany
) {
392 EXPECT_TRUE(Open(origin1_
, "foo"));
393 EXPECT_TRUE(Open(origin1_
, "bar"));
394 EXPECT_TRUE(CachePut(callback_cache_
, GURL("http://example.com/foo")));
395 EXPECT_TRUE(Open(origin1_
, "baz"));
397 EXPECT_TRUE(StorageMatchAll(origin1_
, GURL("http://example.com/foo")));
400 TEST_P(CacheStorageManagerTestP
, Chinese
) {
401 EXPECT_TRUE(Open(origin1_
, "ä½ å¥½"));
402 scoped_refptr
<CacheStorageCache
> cache
= callback_cache_
;
403 EXPECT_TRUE(Open(origin1_
, "ä½ å¥½"));
404 EXPECT_EQ(callback_cache_
.get(), cache
.get());
405 EXPECT_TRUE(Keys(origin1_
));
406 EXPECT_EQ(1u, callback_strings_
.size());
407 EXPECT_STREQ("ä½ å¥½", callback_strings_
[0].c_str());
410 TEST_F(CacheStorageManagerTest
, EmptyKey
) {
411 EXPECT_TRUE(Open(origin1_
, ""));
412 scoped_refptr
<CacheStorageCache
> cache
= callback_cache_
;
413 EXPECT_TRUE(Open(origin1_
, ""));
414 EXPECT_EQ(cache
.get(), callback_cache_
.get());
415 EXPECT_TRUE(Keys(origin1_
));
416 EXPECT_EQ(1u, callback_strings_
.size());
417 EXPECT_STREQ("", callback_strings_
[0].c_str());
418 EXPECT_TRUE(Has(origin1_
, ""));
419 EXPECT_TRUE(Delete(origin1_
, ""));
420 EXPECT_TRUE(Keys(origin1_
));
421 EXPECT_EQ(0u, callback_strings_
.size());
424 TEST_F(CacheStorageManagerTest
, DataPersists
) {
425 EXPECT_TRUE(Open(origin1_
, "foo"));
426 EXPECT_TRUE(Open(origin1_
, "bar"));
427 EXPECT_TRUE(Open(origin1_
, "baz"));
428 EXPECT_TRUE(Open(origin2_
, "raz"));
429 EXPECT_TRUE(Delete(origin1_
, "bar"));
430 quota_manager_proxy_
->SimulateQuotaManagerDestroyed();
431 cache_manager_
= CacheStorageManager::Create(cache_manager_
.get());
432 EXPECT_TRUE(Keys(origin1_
));
433 EXPECT_EQ(2u, callback_strings_
.size());
434 std::vector
<std::string
> expected_keys
;
435 expected_keys
.push_back("foo");
436 expected_keys
.push_back("baz");
437 EXPECT_EQ(expected_keys
, callback_strings_
);
440 TEST_F(CacheStorageManagerMemoryOnlyTest
, DataLostWhenMemoryOnly
) {
441 EXPECT_TRUE(Open(origin1_
, "foo"));
442 EXPECT_TRUE(Open(origin2_
, "baz"));
443 quota_manager_proxy_
->SimulateQuotaManagerDestroyed();
444 cache_manager_
= CacheStorageManager::Create(cache_manager_
.get());
445 EXPECT_TRUE(Keys(origin1_
));
446 EXPECT_EQ(0u, callback_strings_
.size());
449 TEST_F(CacheStorageManagerTest
, BadCacheName
) {
450 // Since the implementation writes cache names to disk, ensure that we don't
451 // escape the directory.
452 const std::string bad_name
= "../../../../../../../../../../../../../../foo";
453 EXPECT_TRUE(Open(origin1_
, bad_name
));
454 EXPECT_TRUE(Keys(origin1_
));
455 EXPECT_EQ(1u, callback_strings_
.size());
456 EXPECT_STREQ(bad_name
.c_str(), callback_strings_
[0].c_str());
459 TEST_F(CacheStorageManagerTest
, BadOriginName
) {
460 // Since the implementation writes origin names to disk, ensure that we don't
461 // escape the directory.
462 GURL
bad_origin("http://../../../../../../../../../../../../../../foo");
463 EXPECT_TRUE(Open(bad_origin
, "foo"));
464 EXPECT_TRUE(Keys(bad_origin
));
465 EXPECT_EQ(1u, callback_strings_
.size());
466 EXPECT_STREQ("foo", callback_strings_
[0].c_str());
469 // With a persistent cache if the client drops its reference to a
471 // it should be deleted.
472 TEST_F(CacheStorageManagerTest
, DropReference
) {
473 EXPECT_TRUE(Open(origin1_
, "foo"));
474 base::WeakPtr
<CacheStorageCache
> cache
= callback_cache_
->AsWeakPtr();
475 callback_cache_
= NULL
;
479 // With a memory cache the cache can't be freed from memory until the client
481 TEST_F(CacheStorageManagerMemoryOnlyTest
, MemoryLosesReferenceOnlyAfterDelete
) {
482 EXPECT_TRUE(Open(origin1_
, "foo"));
483 base::WeakPtr
<CacheStorageCache
> cache
= callback_cache_
->AsWeakPtr();
484 callback_cache_
= NULL
;
486 EXPECT_TRUE(Delete(origin1_
, "foo"));
490 TEST_P(CacheStorageManagerTestP
, DeleteBeforeRelease
) {
491 EXPECT_TRUE(Open(origin1_
, "foo"));
492 EXPECT_TRUE(Delete(origin1_
, "foo"));
493 EXPECT_TRUE(callback_cache_
->AsWeakPtr());
496 TEST_P(CacheStorageManagerTestP
, OpenRunsSerially
) {
497 EXPECT_FALSE(Delete(origin1_
, "tmp")); // Init storage.
498 CacheStorage
* cache_storage
= CacheStorageForOrigin(origin1_
);
499 cache_storage
->StartAsyncOperationForTesting();
501 scoped_ptr
<base::RunLoop
> open_loop(new base::RunLoop());
502 cache_manager_
->OpenCache(
504 base::Bind(&CacheStorageManagerTest::CacheAndErrorCallback
,
505 base::Unretained(this), base::Unretained(open_loop
.get())));
507 base::RunLoop().RunUntilIdle();
508 EXPECT_FALSE(callback_cache_
);
510 cache_storage
->CompleteAsyncOperationForTesting();
512 EXPECT_TRUE(callback_cache_
);
515 TEST_F(CacheStorageManagerMemoryOnlyTest
, MemoryBackedSize
) {
516 CacheStorage
* cache_storage
= CacheStorageForOrigin(origin1_
);
517 EXPECT_EQ(0, cache_storage
->MemoryBackedSize());
519 EXPECT_TRUE(Open(origin1_
, "foo"));
520 scoped_refptr
<CacheStorageCache
> foo_cache
= callback_cache_
;
521 EXPECT_TRUE(Open(origin1_
, "bar"));
522 scoped_refptr
<CacheStorageCache
> bar_cache
= callback_cache_
;
523 EXPECT_EQ(0, cache_storage
->MemoryBackedSize());
525 EXPECT_TRUE(CachePut(foo_cache
, GURL("http://example.com/foo")));
526 EXPECT_LT(0, cache_storage
->MemoryBackedSize());
527 int64 foo_size
= cache_storage
->MemoryBackedSize();
529 EXPECT_TRUE(CachePut(bar_cache
, GURL("http://example.com/foo")));
530 EXPECT_EQ(foo_size
* 2, cache_storage
->MemoryBackedSize());
533 TEST_F(CacheStorageManagerTest
, MemoryBackedSizePersistent
) {
534 CacheStorage
* cache_storage
= CacheStorageForOrigin(origin1_
);
535 EXPECT_EQ(0, cache_storage
->MemoryBackedSize());
536 EXPECT_TRUE(Open(origin1_
, "foo"));
537 EXPECT_TRUE(CachePut(callback_cache_
, GURL("http://example.com/foo")));
538 EXPECT_EQ(0, cache_storage
->MemoryBackedSize());
541 class CacheStorageMigrationTest
: public CacheStorageManagerTest
{
543 CacheStorageMigrationTest() : cache1_("foo"), cache2_("bar") {}
545 void SetUp() override
{
546 CacheStorageManagerTest::SetUp();
548 // Populate a cache, then move it to the "legacy" location
549 // so that tests can verify the results of migration.
550 legacy_path_
= CacheStorageManager::ConstructLegacyOriginPath(
551 cache_manager_
->root_path(), origin1_
);
552 new_path_
= CacheStorageManager::ConstructOriginPath(
553 cache_manager_
->root_path(), origin1_
);
555 ASSERT_FALSE(base::DirectoryExists(legacy_path_
));
556 ASSERT_FALSE(base::DirectoryExists(new_path_
));
557 ASSERT_TRUE(Open(origin1_
, cache1_
));
558 ASSERT_TRUE(Open(origin1_
, cache2_
));
559 callback_cache_
= nullptr;
560 ASSERT_FALSE(base::DirectoryExists(legacy_path_
));
561 ASSERT_TRUE(base::DirectoryExists(new_path_
));
563 quota_manager_proxy_
->SimulateQuotaManagerDestroyed();
564 cache_manager_
= CacheStorageManager::Create(cache_manager_
.get());
566 ASSERT_TRUE(base::Move(new_path_
, legacy_path_
));
567 ASSERT_TRUE(base::DirectoryExists(legacy_path_
));
568 ASSERT_FALSE(base::DirectoryExists(new_path_
));
571 int64
GetOriginUsage(const GURL
& origin
) {
572 scoped_ptr
<base::RunLoop
> loop(new base::RunLoop());
573 cache_manager_
->GetOriginUsage(
575 base::Bind(&CacheStorageMigrationTest::UsageCallback
,
576 base::Unretained(this), base::Unretained(loop
.get())));
578 return callback_usage_
;
581 void UsageCallback(base::RunLoop
* run_loop
, int64 usage
) {
582 callback_usage_
= usage
;
586 base::FilePath legacy_path_
;
587 base::FilePath new_path_
;
589 const std::string cache1_
;
590 const std::string cache2_
;
592 int64 callback_usage_
;
594 DISALLOW_COPY_AND_ASSIGN(CacheStorageMigrationTest
);
597 TEST_F(CacheStorageMigrationTest
, OpenCache
) {
598 EXPECT_TRUE(Open(origin1_
, cache1_
));
599 EXPECT_FALSE(base::DirectoryExists(legacy_path_
));
600 EXPECT_TRUE(base::DirectoryExists(new_path_
));
602 EXPECT_TRUE(Keys(origin1_
));
603 std::vector
<std::string
> expected_keys
;
604 expected_keys
.push_back(cache1_
);
605 expected_keys
.push_back(cache2_
);
606 EXPECT_EQ(expected_keys
, callback_strings_
);
609 TEST_F(CacheStorageMigrationTest
, DeleteCache
) {
610 EXPECT_TRUE(Delete(origin1_
, cache1_
));
611 EXPECT_FALSE(base::DirectoryExists(legacy_path_
));
612 EXPECT_TRUE(base::DirectoryExists(new_path_
));
614 EXPECT_TRUE(Keys(origin1_
));
615 std::vector
<std::string
> expected_keys
;
616 expected_keys
.push_back(cache2_
);
617 EXPECT_EQ(expected_keys
, callback_strings_
);
620 TEST_F(CacheStorageMigrationTest
, GetOriginUsage
) {
621 EXPECT_GT(GetOriginUsage(origin1_
), 0);
622 EXPECT_FALSE(base::DirectoryExists(legacy_path_
));
623 EXPECT_TRUE(base::DirectoryExists(new_path_
));
626 TEST_F(CacheStorageMigrationTest
, MoveFailure
) {
627 // Revert the migration.
628 ASSERT_TRUE(base::Move(legacy_path_
, new_path_
));
629 ASSERT_FALSE(base::DirectoryExists(legacy_path_
));
630 ASSERT_TRUE(base::DirectoryExists(new_path_
));
632 // Make a dummy legacy directory.
633 ASSERT_TRUE(base::CreateDirectory(legacy_path_
));
635 // Ensure that migration doesn't stomp existing new directory,
636 // but does clean up old directory.
637 EXPECT_TRUE(Open(origin1_
, cache1_
));
638 EXPECT_FALSE(base::DirectoryExists(legacy_path_
));
639 EXPECT_TRUE(base::DirectoryExists(new_path_
));
641 EXPECT_TRUE(Keys(origin1_
));
642 std::vector
<std::string
> expected_keys
;
643 expected_keys
.push_back(cache1_
);
644 expected_keys
.push_back(cache2_
);
645 EXPECT_EQ(expected_keys
, callback_strings_
);
648 class CacheStorageQuotaClientTest
: public CacheStorageManagerTest
{
650 CacheStorageQuotaClientTest() {}
652 void SetUp() override
{
653 CacheStorageManagerTest::SetUp();
655 new CacheStorageQuotaClient(cache_manager_
->AsWeakPtr()));
658 void UsageCallback(base::RunLoop
* run_loop
, int64 usage
) {
659 callback_usage_
= usage
;
663 void OriginsCallback(base::RunLoop
* run_loop
, const std::set
<GURL
>& origins
) {
664 callback_origins_
= origins
;
668 void DeleteOriginCallback(base::RunLoop
* run_loop
,
669 storage::QuotaStatusCode status
) {
670 callback_status_
= status
;
674 int64
QuotaGetOriginUsage(const GURL
& origin
) {
675 scoped_ptr
<base::RunLoop
> loop(new base::RunLoop());
676 quota_client_
->GetOriginUsage(
677 origin
, storage::kStorageTypeTemporary
,
678 base::Bind(&CacheStorageQuotaClientTest::UsageCallback
,
679 base::Unretained(this), base::Unretained(loop
.get())));
681 return callback_usage_
;
684 size_t QuotaGetOriginsForType() {
685 scoped_ptr
<base::RunLoop
> loop(new base::RunLoop());
686 quota_client_
->GetOriginsForType(
687 storage::kStorageTypeTemporary
,
688 base::Bind(&CacheStorageQuotaClientTest::OriginsCallback
,
689 base::Unretained(this), base::Unretained(loop
.get())));
691 return callback_origins_
.size();
694 size_t QuotaGetOriginsForHost(const std::string
& host
) {
695 scoped_ptr
<base::RunLoop
> loop(new base::RunLoop());
696 quota_client_
->GetOriginsForHost(
697 storage::kStorageTypeTemporary
, host
,
698 base::Bind(&CacheStorageQuotaClientTest::OriginsCallback
,
699 base::Unretained(this), base::Unretained(loop
.get())));
701 return callback_origins_
.size();
704 bool QuotaDeleteOriginData(const GURL
& origin
) {
705 scoped_ptr
<base::RunLoop
> loop(new base::RunLoop());
706 quota_client_
->DeleteOriginData(
707 origin
, storage::kStorageTypeTemporary
,
708 base::Bind(&CacheStorageQuotaClientTest::DeleteOriginCallback
,
709 base::Unretained(this), base::Unretained(loop
.get())));
711 return callback_status_
== storage::kQuotaStatusOk
;
714 bool QuotaDoesSupport(storage::StorageType type
) {
715 return quota_client_
->DoesSupport(type
);
718 scoped_ptr
<CacheStorageQuotaClient
> quota_client_
;
720 storage::QuotaStatusCode callback_status_
;
721 int64 callback_usage_
;
722 std::set
<GURL
> callback_origins_
;
724 DISALLOW_COPY_AND_ASSIGN(CacheStorageQuotaClientTest
);
727 class CacheStorageQuotaClientTestP
: public CacheStorageQuotaClientTest
,
728 public testing::WithParamInterface
<bool> {
729 bool MemoryOnly() override
{ return !GetParam(); }
732 TEST_P(CacheStorageQuotaClientTestP
, QuotaID
) {
733 EXPECT_EQ(storage::QuotaClient::kServiceWorkerCache
, quota_client_
->id());
736 TEST_P(CacheStorageQuotaClientTestP
, QuotaGetOriginUsage
) {
737 EXPECT_EQ(0, QuotaGetOriginUsage(origin1_
));
738 EXPECT_TRUE(Open(origin1_
, "foo"));
739 EXPECT_TRUE(CachePut(callback_cache_
, GURL("http://example.com/foo")));
740 EXPECT_LT(0, QuotaGetOriginUsage(origin1_
));
743 TEST_P(CacheStorageQuotaClientTestP
, QuotaGetOriginsForType
) {
744 EXPECT_EQ(0u, QuotaGetOriginsForType());
745 EXPECT_TRUE(Open(origin1_
, "foo"));
746 EXPECT_TRUE(Open(origin1_
, "bar"));
747 EXPECT_TRUE(Open(origin2_
, "foo"));
748 EXPECT_EQ(2u, QuotaGetOriginsForType());
751 TEST_P(CacheStorageQuotaClientTestP
, QuotaGetOriginsForHost
) {
752 EXPECT_EQ(0u, QuotaGetOriginsForHost("example.com"));
753 EXPECT_TRUE(Open(GURL("http://example.com:8080"), "foo"));
754 EXPECT_TRUE(Open(GURL("http://example.com:9000"), "foo"));
755 EXPECT_TRUE(Open(GURL("ftp://example.com"), "foo"));
756 EXPECT_TRUE(Open(GURL("http://example2.com"), "foo"));
757 EXPECT_EQ(3u, QuotaGetOriginsForHost("example.com"));
758 EXPECT_EQ(1u, QuotaGetOriginsForHost("example2.com"));
759 EXPECT_TRUE(callback_origins_
.find(GURL("http://example2.com")) !=
760 callback_origins_
.end());
761 EXPECT_EQ(0u, QuotaGetOriginsForHost("unknown.com"));
764 TEST_P(CacheStorageQuotaClientTestP
, QuotaDeleteOriginData
) {
765 EXPECT_TRUE(Open(origin1_
, "foo"));
766 // Call put to test that initialized caches are properly deleted too.
767 EXPECT_TRUE(CachePut(callback_cache_
, GURL("http://example.com/foo")));
768 EXPECT_TRUE(Open(origin1_
, "bar"));
769 EXPECT_TRUE(Open(origin2_
, "baz"));
771 EXPECT_TRUE(QuotaDeleteOriginData(origin1_
));
773 EXPECT_FALSE(Has(origin1_
, "foo"));
774 EXPECT_FALSE(Has(origin1_
, "bar"));
775 EXPECT_TRUE(Has(origin2_
, "baz"));
776 EXPECT_TRUE(Open(origin1_
, "foo"));
779 TEST_P(CacheStorageQuotaClientTestP
, QuotaDeleteEmptyOrigin
) {
780 EXPECT_TRUE(QuotaDeleteOriginData(origin1_
));
783 TEST_P(CacheStorageQuotaClientTestP
, QuotaDoesSupport
) {
784 EXPECT_TRUE(QuotaDoesSupport(storage::kStorageTypeTemporary
));
785 EXPECT_FALSE(QuotaDoesSupport(storage::kStorageTypePersistent
));
786 EXPECT_FALSE(QuotaDoesSupport(storage::kStorageTypeSyncable
));
787 EXPECT_FALSE(QuotaDoesSupport(storage::kStorageTypeQuotaNotManaged
));
788 EXPECT_FALSE(QuotaDoesSupport(storage::kStorageTypeUnknown
));
791 INSTANTIATE_TEST_CASE_P(CacheStorageManagerTests
,
792 CacheStorageManagerTestP
,
793 ::testing::Values(false, true));
795 INSTANTIATE_TEST_CASE_P(CacheStorageQuotaClientTests
,
796 CacheStorageQuotaClientTestP
,
797 ::testing::Values(false, true));
799 } // namespace content