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 <stddef.h>
6 #include <stdint.h>
7 
8 #include <list>
9 #include <utility>
10 #include <vector>
11 
12 #include "base/bind.h"
13 #include "base/containers/flat_map.h"
14 #include "base/files/file_enumerator.h"
15 #include "base/files/file_path.h"
16 #include "base/files/file_util.h"
17 #include "base/files/scoped_temp_dir.h"
18 #include "base/guid.h"
19 #include "base/macros.h"
20 #include "base/memory/ptr_util.h"
21 #include "base/memory/scoped_refptr.h"
22 #include "base/run_loop.h"
23 #include "base/stl_util.h"
24 #include "base/strings/string_number_conversions.h"
25 #include "base/test/bind.h"
26 #include "base/test/metrics/histogram_tester.h"
27 #include "base/threading/thread_task_runner_handle.h"
28 #include "build/build_config.h"
29 #include "content/browser/blob_storage/chrome_blob_storage_context.h"
30 #include "content/browser/cache_storage/cache_storage.pb.h"
31 #include "content/browser/cache_storage/cache_storage_cache_handle.h"
32 #include "content/browser/cache_storage/cache_storage_context_impl.h"
33 #include "content/browser/cache_storage/cache_storage_quota_client.h"
34 #include "content/browser/cache_storage/cache_storage_scheduler.h"
35 #include "content/browser/cache_storage/cross_sequence/cross_sequence_cache_storage_manager.h"
36 #include "content/browser/cache_storage/legacy/legacy_cache_storage.h"
37 #include "content/browser/cache_storage/legacy/legacy_cache_storage_manager.h"
38 #include "content/common/background_fetch/background_fetch_types.h"
39 #include "content/public/browser/browser_thread.h"
40 #include "content/public/browser/storage_usage_info.h"
41 #include "content/public/test/browser_task_environment.h"
42 #include "content/public/test/test_browser_context.h"
43 #include "content/public/test/test_utils.h"
44 #include "mojo/public/cpp/bindings/pending_remote.h"
45 #include "mojo/public/cpp/bindings/receiver.h"
46 #include "mojo/public/cpp/bindings/remote.h"
47 #include "net/disk_cache/disk_cache.h"
48 #include "services/network/public/mojom/fetch_api.mojom.h"
49 #include "storage/browser/blob/blob_storage_context.h"
50 #include "storage/browser/quota/padding_key.h"
51 #include "storage/browser/quota/quota_client_type.h"
52 #include "storage/browser/quota/quota_manager_proxy.h"
53 #include "storage/browser/test/fake_blob.h"
54 #include "storage/browser/test/mock_quota_manager_proxy.h"
55 #include "storage/browser/test/mock_special_storage_policy.h"
56 #include "testing/gmock/include/gmock/gmock-matchers.h"
57 #include "testing/gtest/include/gtest/gtest.h"
58 #include "third_party/blink/public/mojom/cache_storage/cache_storage.mojom.h"
59 #include "third_party/blink/public/mojom/fetch/fetch_api_request.mojom.h"
60 #include "url/gurl.h"
61 #include "url/origin.h"
62 
63 using blink::mojom::CacheStorageError;
64 using blink::mojom::CacheStorageVerboseErrorPtr;
65 using network::mojom::FetchResponseType;
66 
67 namespace content {
68 namespace cache_storage_manager_unittest {
69 
70 enum class TestManager {
71   kLegacy,
72   kCrossSequence,
73 };
74 
75 enum class TestStorage {
76   kDisk,
77   kMemory,
78 };
79 
80 struct Param {
Paramcontent::cache_storage_manager_unittest::Param81   Param(TestManager manager, TestStorage storage)
82       : manager_(manager), storage_(storage) {}
83 
84   TestManager manager_;
85   TestStorage storage_;
86 };
87 
88 using blink::mojom::StorageType;
89 using ResponseHeaderMap = base::flat_map<std::string, std::string>;
90 
91 class DelayedBlob : public storage::FakeBlob {
92  public:
DelayedBlob(mojo::PendingReceiver<blink::mojom::Blob> receiver,std::string data,base::OnceClosure read_closure)93   DelayedBlob(mojo::PendingReceiver<blink::mojom::Blob> receiver,
94               std::string data,
95               base::OnceClosure read_closure)
96       : FakeBlob("foo"),
97         receiver_(this, std::move(receiver)),
98         data_(std::move(data)),
99         read_closure_(std::move(read_closure)) {}
100 
Resume()101   void Resume() {
102     paused_ = false;
103     MaybeComplete();
104   }
105 
ReadAll(mojo::ScopedDataPipeProducerHandle producer_handle,mojo::PendingRemote<blink::mojom::BlobReaderClient> client)106   void ReadAll(
107       mojo::ScopedDataPipeProducerHandle producer_handle,
108       mojo::PendingRemote<blink::mojom::BlobReaderClient> client) override {
109     client_.Bind(std::move(client));
110     producer_handle_ = std::move(producer_handle);
111 
112     client_->OnCalculatedSize(data_.length(), data_.length());
113 
114     // This should always succeed immediately because we size the pipe to
115     // hold the entire blob for tiny data lengths.
116     uint32_t num_bytes = data_.length();
117     producer_handle_->WriteData(data_.data(), &num_bytes,
118                                 MOJO_WRITE_DATA_FLAG_NONE);
119     ASSERT_EQ(data_.length(), num_bytes);
120 
121     // Signal that ReadAll() was called.
122     std::move(read_closure_).Run();
123 
124     MaybeComplete();
125   }
126 
127  private:
MaybeComplete()128   void MaybeComplete() {
129     if (paused_ || !client_)
130       return;
131     client_->OnComplete(net::OK, data_.length());
132     client_.reset();
133     producer_handle_.reset();
134   }
135 
136   mojo::Receiver<blink::mojom::Blob> receiver_;
137   std::string data_;
138   base::OnceClosure read_closure_;
139   mojo::Remote<blink::mojom::BlobReaderClient> client_;
140   mojo::ScopedDataPipeProducerHandle producer_handle_;
141   bool paused_ = true;
142 };
143 
144 // Scheduler implementation that will invoke a callback after the
145 // next operation has been started.
146 class CallbackScheduler : public CacheStorageScheduler {
147  public:
CallbackScheduler(base::OnceClosure callback)148   explicit CallbackScheduler(base::OnceClosure callback)
149       : CacheStorageScheduler(CacheStorageSchedulerClient::kCache,
150                               base::ThreadTaskRunnerHandle::Get()),
151         callback_(std::move(callback)) {}
152 
153  protected:
DispatchOperationTask(base::OnceClosure task)154   void DispatchOperationTask(base::OnceClosure task) override {
155     auto wrapped = base::BindOnce(&CallbackScheduler::ExecuteTask,
156                                   base::Unretained(this), std::move(task));
157     CacheStorageScheduler::DispatchOperationTask(std::move(wrapped));
158   }
159 
160  private:
ExecuteTask(base::OnceClosure task)161   void ExecuteTask(base::OnceClosure task) {
162     std::move(task).Run();
163     if (callback_)
164       std::move(callback_).Run();
165   }
166 
167   base::OnceClosure callback_;
168 };
169 
170 class MockCacheStorageQuotaManagerProxy
171     : public storage::MockQuotaManagerProxy {
172  public:
MockCacheStorageQuotaManagerProxy(storage::MockQuotaManager * quota_manager,base::SingleThreadTaskRunner * task_runner)173   MockCacheStorageQuotaManagerProxy(storage::MockQuotaManager* quota_manager,
174                                     base::SingleThreadTaskRunner* task_runner)
175       : MockQuotaManagerProxy(quota_manager, task_runner) {}
176 
RegisterClient(scoped_refptr<storage::QuotaClient> client,storage::QuotaClientType client_type,const std::vector<blink::mojom::StorageType> & storage_types)177   void RegisterClient(
178       scoped_refptr<storage::QuotaClient> client,
179       storage::QuotaClientType client_type,
180       const std::vector<blink::mojom::StorageType>& storage_types) override {
181     registered_clients_.push_back(std::move(client));
182   }
183 
SimulateQuotaManagerDestroyed()184   void SimulateQuotaManagerDestroyed() override {
185     for (const auto& client : registered_clients_) {
186       client->OnQuotaManagerDestroyed();
187     }
188     registered_clients_.clear();
189   }
190 
191  private:
~MockCacheStorageQuotaManagerProxy()192   ~MockCacheStorageQuotaManagerProxy() override {
193     DCHECK(registered_clients_.empty());
194   }
195 
196   std::vector<scoped_refptr<storage::QuotaClient>> registered_clients_;
197 };
198 
IsIndexFileCurrent(const base::FilePath & cache_dir)199 bool IsIndexFileCurrent(const base::FilePath& cache_dir) {
200   base::File::Info info;
201   const base::FilePath index_path =
202       cache_dir.AppendASCII(LegacyCacheStorage::kIndexFileName);
203   if (!GetFileInfo(index_path, &info))
204     return false;
205   base::Time index_last_modified = info.last_modified;
206 
207   base::FileEnumerator enumerator(cache_dir, false,
208                                   base::FileEnumerator::DIRECTORIES);
209   for (base::FilePath file_path = enumerator.Next(); !file_path.empty();
210        file_path = enumerator.Next()) {
211     if (!GetFileInfo(file_path, &info))
212       return false;
213     if (index_last_modified < info.last_modified)
214       return false;
215   }
216 
217   return true;
218 }
219 
220 class TestCacheStorageObserver : public CacheStorageContextImpl::Observer {
221  public:
TestCacheStorageObserver()222   TestCacheStorageObserver() : loop_(std::make_unique<base::RunLoop>()) {}
223 
OnCacheListChanged(const url::Origin & origin)224   void OnCacheListChanged(const url::Origin& origin) override {
225     ++notify_list_changed_count;
226     loop_->Quit();
227   }
228 
OnCacheContentChanged(const url::Origin & origin,const std::string & cache_name)229   void OnCacheContentChanged(const url::Origin& origin,
230                              const std::string& cache_name) override {
231     ++notify_content_changed_count;
232     loop_->Quit();
233   }
234 
Wait()235   void Wait() {
236     loop_->Run();
237     loop_ = std::make_unique<base::RunLoop>();
238   }
239 
240   base::OnceClosure callback;
241   int notify_list_changed_count = 0;
242   int notify_content_changed_count = 0;
243 
244   std::unique_ptr<base::RunLoop> loop_;
245 };
246 
247 class TestCacheStorageContext : public CacheStorageContextWithManager {
248  public:
TestCacheStorageContext(scoped_refptr<CacheStorageManager> manager)249   explicit TestCacheStorageContext(scoped_refptr<CacheStorageManager> manager)
250       : manager_(std::move(manager)) {}
251 
CacheManager()252   scoped_refptr<CacheStorageManager> CacheManager() override {
253     return manager_;
254   }
255 
GetAllOriginsInfo(GetUsageInfoCallback callback)256   void GetAllOriginsInfo(GetUsageInfoCallback callback) override {
257     NOTREACHED();
258   }
259 
DeleteForOrigin(const url::Origin & origin)260   void DeleteForOrigin(const url::Origin& origin) override { NOTREACHED(); }
261 
262  private:
263   ~TestCacheStorageContext() override = default;
264   scoped_refptr<CacheStorageManager> manager_;
265 };
266 
267 class CacheStorageManagerTest : public testing::Test {
268  public:
CacheStorageManagerTest()269   CacheStorageManagerTest()
270       : task_environment_(BrowserTaskEnvironment::IO_MAINLOOP),
271         blob_storage_context_(nullptr),
272         observers_(
273             base::MakeRefCounted<CacheStorageContextImpl::ObserverList>()),
274         origin1_(url::Origin::Create(GURL("http://example1.com"))),
275         origin2_(url::Origin::Create(GURL("http://example2.com"))) {}
276 
SetUp()277   void SetUp() override {
278     base::FilePath temp_dir_path;
279     if (!MemoryOnly())
280       ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
281 
282     CreateStorageManager();
283   }
284 
TearDown()285   void TearDown() override {
286     DestroyStorageManager();
287     disk_cache::FlushCacheThreadForTesting();
288     content::RunAllTasksUntilIdle();
289   }
290 
MemoryOnly()291   virtual bool MemoryOnly() { return false; }
ManagerType()292   virtual TestManager ManagerType() { return TestManager::kLegacy; }
293 
BoolCallback(base::RunLoop * run_loop,bool value)294   void BoolCallback(base::RunLoop* run_loop, bool value) {
295     callback_bool_ = value;
296     run_loop->Quit();
297   }
298 
ErrorCallback(base::RunLoop * run_loop,CacheStorageError error)299   void ErrorCallback(base::RunLoop* run_loop, CacheStorageError error) {
300     callback_error_ = error;
301     callback_bool_ = error == CacheStorageError::kSuccess;
302     run_loop->Quit();
303   }
304 
BoolAndErrorCallback(base::RunLoop * run_loop,bool value,CacheStorageError error)305   void BoolAndErrorCallback(base::RunLoop* run_loop,
306                             bool value,
307                             CacheStorageError error) {
308     callback_bool_ = value;
309     callback_error_ = error;
310     run_loop->Quit();
311   }
312 
CacheAndErrorCallback(base::RunLoop * run_loop,CacheStorageCacheHandle cache_handle,CacheStorageError error)313   void CacheAndErrorCallback(base::RunLoop* run_loop,
314                              CacheStorageCacheHandle cache_handle,
315                              CacheStorageError error) {
316     callback_cache_handle_ = std::move(cache_handle);
317     callback_error_ = error;
318     run_loop->Quit();
319   }
320 
CacheMetadataCallback(base::RunLoop * run_loop,std::vector<std::string> cache_names)321   void CacheMetadataCallback(base::RunLoop* run_loop,
322                              std::vector<std::string> cache_names) {
323     cache_names_ = std::move(cache_names);
324     run_loop->Quit();
325   }
326 
GetFirstIndexName() const327   const std::string& GetFirstIndexName() const { return cache_names_.front(); }
328 
GetIndexNames() const329   std::vector<std::string> GetIndexNames() const { return cache_names_; }
330 
CachePutCallback(base::RunLoop * run_loop,CacheStorageVerboseErrorPtr error)331   void CachePutCallback(base::RunLoop* run_loop,
332                         CacheStorageVerboseErrorPtr error) {
333     callback_error_ = error->value;
334     run_loop->Quit();
335   }
336 
CacheDeleteCallback(base::RunLoop * run_loop,CacheStorageVerboseErrorPtr error)337   void CacheDeleteCallback(base::RunLoop* run_loop,
338                            CacheStorageVerboseErrorPtr error) {
339     callback_error_ = error->value;
340     run_loop->Quit();
341   }
342 
CacheMatchCallback(base::RunLoop * run_loop,CacheStorageError error,blink::mojom::FetchAPIResponsePtr response)343   void CacheMatchCallback(base::RunLoop* run_loop,
344                           CacheStorageError error,
345                           blink::mojom::FetchAPIResponsePtr response) {
346     callback_error_ = error;
347     callback_cache_handle_response_ = std::move(response);
348     run_loop->Quit();
349   }
350 
CacheMatchAllCallback(base::RunLoop * run_loop,CacheStorageError error,std::vector<blink::mojom::FetchAPIResponsePtr>)351   void CacheMatchAllCallback(base::RunLoop* run_loop,
352                              CacheStorageError error,
353                              std::vector<blink::mojom::FetchAPIResponsePtr>) {
354     callback_error_ = error;
355     run_loop->Quit();
356   }
357 
CreateStorageManager()358   void CreateStorageManager() {
359     ChromeBlobStorageContext* blob_storage_context(
360         ChromeBlobStorageContext::GetFor(&browser_context_));
361     // Wait for ChromeBlobStorageContext to finish initializing.
362     base::RunLoop().RunUntilIdle();
363 
364     mojo::PendingRemote<storage::mojom::BlobStorageContext> remote;
365     blob_storage_context->BindMojoContext(
366         remote.InitWithNewPipeAndPassReceiver());
367     blob_storage_context_ =
368         base::MakeRefCounted<BlobStorageContextWrapper>(std::move(remote));
369 
370     base::FilePath temp_dir_path;
371     if (!MemoryOnly())
372       temp_dir_path = temp_dir_.GetPath();
373 
374     quota_policy_ = base::MakeRefCounted<storage::MockSpecialStoragePolicy>();
375     mock_quota_manager_ = base::MakeRefCounted<storage::MockQuotaManager>(
376         MemoryOnly(), temp_dir_path, base::ThreadTaskRunnerHandle::Get().get(),
377         quota_policy_.get());
378     mock_quota_manager_->SetQuota(origin1_, StorageType::kTemporary,
379                                   1024 * 1024 * 100);
380     mock_quota_manager_->SetQuota(origin2_, StorageType::kTemporary,
381                                   1024 * 1024 * 100);
382 
383     quota_manager_proxy_ =
384         base::MakeRefCounted<MockCacheStorageQuotaManagerProxy>(
385             mock_quota_manager_.get(),
386             base::ThreadTaskRunnerHandle::Get().get());
387 
388     auto legacy_manager = LegacyCacheStorageManager::Create(
389         temp_dir_path, base::ThreadTaskRunnerHandle::Get(),
390         base::ThreadTaskRunnerHandle::Get(), quota_manager_proxy_, observers_);
391     legacy_manager->SetBlobParametersForCache(blob_storage_context_);
392 
393     switch (ManagerType()) {
394       case TestManager::kLegacy:
395         cache_manager_ = std::move(legacy_manager);
396         break;
397       case TestManager::kCrossSequence:
398         auto context = base::MakeRefCounted<TestCacheStorageContext>(
399             std::move(legacy_manager));
400         cache_manager_ = base::MakeRefCounted<CrossSequenceCacheStorageManager>(
401             base::ThreadTaskRunnerHandle::Get(), std::move(context));
402         break;
403     }
404   }
405 
RecreateStorageManager()406   void RecreateStorageManager() {
407     DCHECK(cache_manager_);
408     auto* legacy_manager =
409         static_cast<LegacyCacheStorageManager*>(cache_manager_.get());
410     cache_manager_ =
411         LegacyCacheStorageManager::CreateForTesting(legacy_manager);
412   }
413 
FlushCacheStorageIndex(const url::Origin & origin)414   bool FlushCacheStorageIndex(const url::Origin& origin) {
415     DCHECK(ManagerType() == TestManager::kLegacy);
416     callback_bool_ = false;
417     base::RunLoop loop;
418     auto* impl = LegacyCacheStorage::From(CacheStorageForOrigin(origin));
419     bool write_was_scheduled = impl->InitiateScheduledIndexWriteForTest(
420         base::BindOnce(&CacheStorageManagerTest::BoolCallback,
421                        base::Unretained(this), &loop));
422     loop.Run();
423     DCHECK(callback_bool_);
424     return write_was_scheduled;
425   }
426 
DestroyStorageManager()427   void DestroyStorageManager() {
428     if (quota_manager_proxy_)
429       quota_manager_proxy_->SimulateQuotaManagerDestroyed();
430 
431     callback_cache_handle_ = CacheStorageCacheHandle();
432     callback_bool_ = false;
433     callback_cache_handle_response_ = nullptr;
434     cache_names_.clear();
435     callback_all_origins_usage_.clear();
436 
437     base::RunLoop().RunUntilIdle();
438     quota_manager_proxy_ = nullptr;
439 
440     blob_storage_context_ = nullptr;
441 
442     quota_policy_ = nullptr;
443     mock_quota_manager_ = nullptr;
444 
445     cache_manager_ = nullptr;
446   }
447 
CheckOpHistograms(base::HistogramTester & histogram_tester,const char * op_name)448   void CheckOpHistograms(base::HistogramTester& histogram_tester,
449                          const char* op_name) {
450     std::string base("ServiceWorkerCache.CacheStorage.Scheduler.");
451     histogram_tester.ExpectTotalCount(base + "OperationDuration2." + op_name,
452                                       1);
453     histogram_tester.ExpectTotalCount(base + "QueueDuration2." + op_name, 1);
454     histogram_tester.ExpectTotalCount(base + "QueueLength." + op_name, 1);
455   }
456 
Open(const url::Origin & origin,const std::string & cache_name,CacheStorageOwner owner=CacheStorageOwner::kCacheAPI)457   bool Open(const url::Origin& origin,
458             const std::string& cache_name,
459             CacheStorageOwner owner = CacheStorageOwner::kCacheAPI) {
460     base::HistogramTester histogram_tester;
461     base::RunLoop loop;
462     CacheStorageHandle cache_storage =
463         cache_manager_->OpenCacheStorage(origin, owner);
464     cache_storage.value()->OpenCache(
465         cache_name, /* trace_id = */ 0,
466         base::BindOnce(&CacheStorageManagerTest::CacheAndErrorCallback,
467                        base::Unretained(this), base::Unretained(&loop)));
468     loop.Run();
469 
470     bool error = callback_error_ != CacheStorageError::kSuccess;
471     if (error) {
472       EXPECT_FALSE(callback_cache_handle_.value());
473     } else {
474       EXPECT_TRUE(callback_cache_handle_.value());
475       CheckOpHistograms(histogram_tester, "Open");
476     }
477     return !error;
478   }
479 
Has(const url::Origin & origin,const std::string & cache_name,CacheStorageOwner owner=CacheStorageOwner::kCacheAPI)480   bool Has(const url::Origin& origin,
481            const std::string& cache_name,
482            CacheStorageOwner owner = CacheStorageOwner::kCacheAPI) {
483     base::HistogramTester histogram_tester;
484     base::RunLoop loop;
485     CacheStorageHandle cache_storage =
486         cache_manager_->OpenCacheStorage(origin, owner);
487     cache_storage.value()->HasCache(
488         cache_name, /* trace_id = */ 0,
489         base::BindOnce(&CacheStorageManagerTest::BoolAndErrorCallback,
490                        base::Unretained(this), base::Unretained(&loop)));
491     loop.Run();
492     CheckOpHistograms(histogram_tester, "Has");
493     return callback_bool_;
494   }
495 
Delete(const url::Origin & origin,const std::string & cache_name,CacheStorageOwner owner=CacheStorageOwner::kCacheAPI)496   bool Delete(const url::Origin& origin,
497               const std::string& cache_name,
498               CacheStorageOwner owner = CacheStorageOwner::kCacheAPI) {
499     base::HistogramTester histogram_tester;
500     base::RunLoop loop;
501     CacheStorageHandle cache_storage =
502         cache_manager_->OpenCacheStorage(origin, owner);
503     cache_storage.value()->DoomCache(
504         cache_name, /* trace_id = */ 0,
505         base::BindOnce(&CacheStorageManagerTest::ErrorCallback,
506                        base::Unretained(this), base::Unretained(&loop)));
507     loop.Run();
508     CheckOpHistograms(histogram_tester, "Delete");
509     return callback_bool_;
510   }
511 
Keys(const url::Origin & origin,CacheStorageOwner owner=CacheStorageOwner::kCacheAPI)512   size_t Keys(const url::Origin& origin,
513               CacheStorageOwner owner = CacheStorageOwner::kCacheAPI) {
514     base::HistogramTester histogram_tester;
515     base::RunLoop loop;
516     CacheStorageHandle cache_storage =
517         cache_manager_->OpenCacheStorage(origin, owner);
518     cache_storage.value()->EnumerateCaches(
519         /* trace_id = */ 0,
520         base::BindOnce(&CacheStorageManagerTest::CacheMetadataCallback,
521                        base::Unretained(this), base::Unretained(&loop)));
522     loop.Run();
523     CheckOpHistograms(histogram_tester, "Keys");
524     return cache_names_.size();
525   }
526 
StorageMatch(const url::Origin & origin,const std::string & cache_name,const GURL & url,blink::mojom::CacheQueryOptionsPtr match_options=nullptr,CacheStorageOwner owner=CacheStorageOwner::kCacheAPI)527   bool StorageMatch(const url::Origin& origin,
528                     const std::string& cache_name,
529                     const GURL& url,
530                     blink::mojom::CacheQueryOptionsPtr match_options = nullptr,
531                     CacheStorageOwner owner = CacheStorageOwner::kCacheAPI) {
532     auto request = blink::mojom::FetchAPIRequest::New();
533     request->url = url;
534     return StorageMatchWithRequest(origin, cache_name, std::move(request),
535                                    std::move(match_options), owner);
536   }
537 
StorageMatchWithRequest(const url::Origin & origin,const std::string & cache_name,blink::mojom::FetchAPIRequestPtr request,blink::mojom::CacheQueryOptionsPtr match_options=nullptr,CacheStorageOwner owner=CacheStorageOwner::kCacheAPI)538   bool StorageMatchWithRequest(
539       const url::Origin& origin,
540       const std::string& cache_name,
541       blink::mojom::FetchAPIRequestPtr request,
542       blink::mojom::CacheQueryOptionsPtr match_options = nullptr,
543       CacheStorageOwner owner = CacheStorageOwner::kCacheAPI) {
544     base::HistogramTester histogram_tester;
545     base::RunLoop loop;
546     CacheStorageHandle cache_storage =
547         cache_manager_->OpenCacheStorage(origin, owner);
548     cache_storage.value()->MatchCache(
549         cache_name, std::move(request), std::move(match_options),
550         CacheStorageSchedulerPriority::kNormal, /* trace_id = */ 0,
551         base::BindOnce(&CacheStorageManagerTest::CacheMatchCallback,
552                        base::Unretained(this), base::Unretained(&loop)));
553     loop.Run();
554     if (callback_error_ == CacheStorageError::kSuccess)
555       CheckOpHistograms(histogram_tester, "Match");
556     return callback_error_ == CacheStorageError::kSuccess;
557   }
558 
StorageMatchAll(const url::Origin & origin,const GURL & url,blink::mojom::CacheQueryOptionsPtr match_options=nullptr)559   bool StorageMatchAll(
560       const url::Origin& origin,
561       const GURL& url,
562       blink::mojom::CacheQueryOptionsPtr match_options = nullptr) {
563     auto request = blink::mojom::FetchAPIRequest::New();
564     request->url = url;
565     return StorageMatchAllWithRequest(origin, std::move(request),
566                                       std::move(match_options));
567   }
568 
StorageMatchAllWithRequest(const url::Origin & origin,blink::mojom::FetchAPIRequestPtr request,blink::mojom::CacheQueryOptionsPtr match_options=nullptr,CacheStorageOwner owner=CacheStorageOwner::kCacheAPI)569   bool StorageMatchAllWithRequest(
570       const url::Origin& origin,
571       blink::mojom::FetchAPIRequestPtr request,
572       blink::mojom::CacheQueryOptionsPtr match_options = nullptr,
573       CacheStorageOwner owner = CacheStorageOwner::kCacheAPI) {
574     base::HistogramTester histogram_tester;
575     base::RunLoop loop;
576     CacheStorageHandle cache_storage =
577         cache_manager_->OpenCacheStorage(origin, owner);
578     cache_storage.value()->MatchAllCaches(
579         std::move(request), std::move(match_options),
580         CacheStorageSchedulerPriority::kNormal, /* trace_id = */ 0,
581         base::BindOnce(&CacheStorageManagerTest::CacheMatchCallback,
582                        base::Unretained(this), base::Unretained(&loop)));
583     loop.Run();
584     if (callback_error_ == CacheStorageError::kSuccess)
585       CheckOpHistograms(histogram_tester, "MatchAll");
586     return callback_error_ == CacheStorageError::kSuccess;
587   }
588 
Write(const url::Origin & origin,CacheStorageOwner owner,const std::string & cache_name,const std::string & request_url)589   bool Write(const url::Origin& origin,
590              CacheStorageOwner owner,
591              const std::string& cache_name,
592              const std::string& request_url) {
593     auto request = blink::mojom::FetchAPIRequest::New();
594     request->url = GURL(request_url);
595 
596     base::RunLoop loop;
597     CacheStorageHandle cache_storage =
598         cache_manager_->OpenCacheStorage(origin, owner);
599     cache_storage.value()->WriteToCache(
600         cache_name, std::move(request), blink::mojom::FetchAPIResponse::New(),
601         /* trace_id = */ 0,
602         base::BindOnce(&CacheStorageManagerTest::ErrorCallback,
603                        base::Unretained(this), base::Unretained(&loop)));
604     loop.Run();
605     return callback_bool_;
606   }
607 
CachePut(CacheStorageCache * cache,const GURL & url,FetchResponseType response_type=FetchResponseType::kDefault)608   bool CachePut(CacheStorageCache* cache,
609                 const GURL& url,
610                 FetchResponseType response_type = FetchResponseType::kDefault) {
611     auto request = blink::mojom::FetchAPIRequest::New();
612     request->url = url;
613 
614     return CachePutWithStatusCode(cache, std::move(request), 200,
615                                   response_type);
616   }
617 
CachePutWithRequestAndHeaders(CacheStorageCache * cache,blink::mojom::FetchAPIRequestPtr request,ResponseHeaderMap response_headers,FetchResponseType response_type=FetchResponseType::kDefault)618   bool CachePutWithRequestAndHeaders(
619       CacheStorageCache* cache,
620       blink::mojom::FetchAPIRequestPtr request,
621       ResponseHeaderMap response_headers,
622       FetchResponseType response_type = FetchResponseType::kDefault) {
623     return CachePutWithStatusCode(cache, std::move(request), 200, response_type,
624                                   std::move(response_headers));
625   }
626 
CachePutWithStatusCode(CacheStorageCache * cache,blink::mojom::FetchAPIRequestPtr request,int status_code,FetchResponseType response_type=FetchResponseType::kDefault,ResponseHeaderMap response_headers=ResponseHeaderMap ())627   bool CachePutWithStatusCode(
628       CacheStorageCache* cache,
629       blink::mojom::FetchAPIRequestPtr request,
630       int status_code,
631       FetchResponseType response_type = FetchResponseType::kDefault,
632       ResponseHeaderMap response_headers = ResponseHeaderMap()) {
633     std::string blob_uuid = base::GenerateGUID();
634 
635     auto blob = blink::mojom::SerializedBlob::New();
636     blob->uuid = blob_uuid;
637     blob->size = request->url.spec().size();
638     auto& str = request->url.spec();
639     blob_storage_context_->context()->RegisterFromMemory(
640         blob->blob.InitWithNewPipeAndPassReceiver(), blob_uuid,
641         std::vector<uint8_t>(str.begin(), str.end()));
642 
643     base::RunLoop loop;
644     CachePutWithStatusCodeAndBlobInternal(cache, std::move(request),
645                                           status_code, std::move(blob), &loop,
646                                           response_type, response_headers);
647     loop.Run();
648 
649     return callback_error_ == CacheStorageError::kSuccess;
650   }
651 
CachePutWithStatusCodeAndBlobInternal(CacheStorageCache * cache,blink::mojom::FetchAPIRequestPtr request,int status_code,blink::mojom::SerializedBlobPtr blob,base::RunLoop * loop,FetchResponseType response_type=FetchResponseType::kDefault,ResponseHeaderMap response_headers=ResponseHeaderMap ())652   void CachePutWithStatusCodeAndBlobInternal(
653       CacheStorageCache* cache,
654       blink::mojom::FetchAPIRequestPtr request,
655       int status_code,
656       blink::mojom::SerializedBlobPtr blob,
657       base::RunLoop* loop,
658       FetchResponseType response_type = FetchResponseType::kDefault,
659       ResponseHeaderMap response_headers = ResponseHeaderMap()) {
660     auto response = blink::mojom::FetchAPIResponse::New(
661         std::vector<GURL>({request->url}), status_code, "OK", response_type,
662         network::mojom::FetchResponseSource::kUnspecified, response_headers,
663         base::nullopt /* mime_type */, net::HttpRequestHeaders::kGetMethod,
664         std::move(blob), blink::mojom::ServiceWorkerResponseError::kUnknown,
665         base::Time(), std::string() /* cache_storage_cache_name */,
666         std::vector<std::string>() /* cors_exposed_header_names */,
667         nullptr /* side_data_blob */,
668         nullptr /* side_data_blob_for_cache_put */,
669         network::mojom::ParsedHeaders::New(),
670         net::HttpResponseInfo::CONNECTION_INFO_UNKNOWN,
671         "unknown" /* alpn_negotiated_protocol */,
672         false /* loaded_with_credentials */, false /* was_fetched_via_spdy */,
673         false /* has_range_requested */);
674 
675     blink::mojom::BatchOperationPtr operation =
676         blink::mojom::BatchOperation::New();
677     operation->operation_type = blink::mojom::OperationType::kPut;
678     operation->request = std::move(request);
679     operation->response = std::move(response);
680 
681     std::vector<blink::mojom::BatchOperationPtr> operations;
682     operations.emplace_back(std::move(operation));
683     cache->BatchOperation(
684         std::move(operations), /* trace_id = */ 0,
685         base::BindOnce(&CacheStorageManagerTest::CachePutCallback,
686                        base::Unretained(this), base::Unretained(loop)),
687         CacheStorageCache::BadMessageCallback());
688   }
689 
CacheDelete(CacheStorageCache * cache,const GURL & url)690   bool CacheDelete(CacheStorageCache* cache, const GURL& url) {
691     auto request = blink::mojom::FetchAPIRequest::New();
692     request->url = url;
693 
694     blink::mojom::BatchOperationPtr operation =
695         blink::mojom::BatchOperation::New();
696     operation->operation_type = blink::mojom::OperationType::kDelete;
697     operation->request = std::move(request);
698     operation->response = blink::mojom::FetchAPIResponse::New();
699 
700     std::vector<blink::mojom::BatchOperationPtr> operations;
701     operations.emplace_back(std::move(operation));
702     base::RunLoop loop;
703     cache->BatchOperation(
704         std::move(operations), /* trace_id = */ 0,
705         base::BindOnce(&CacheStorageManagerTest::CacheDeleteCallback,
706                        base::Unretained(this), base::Unretained(&loop)),
707         CacheStorageCache::BadMessageCallback());
708     loop.Run();
709 
710     return callback_error_ == CacheStorageError::kSuccess;
711   }
712 
CacheMatch(CacheStorageCache * cache,const GURL & url)713   bool CacheMatch(CacheStorageCache* cache, const GURL& url) {
714     auto request = blink::mojom::FetchAPIRequest::New();
715     request->url = url;
716     base::RunLoop loop;
717     cache->Match(
718         std::move(request), nullptr, CacheStorageSchedulerPriority::kNormal,
719         /* trace_id = */ 0,
720         base::BindOnce(&CacheStorageManagerTest::CacheMatchCallback,
721                        base::Unretained(this), base::Unretained(&loop)));
722     loop.Run();
723 
724     return callback_error_ == CacheStorageError::kSuccess;
725   }
726 
CacheStorageForOrigin(const url::Origin & origin)727   CacheStorageHandle CacheStorageForOrigin(const url::Origin& origin) {
728     return cache_manager_->OpenCacheStorage(origin,
729                                             CacheStorageOwner::kCacheAPI);
730   }
731 
GetOriginUsage(const url::Origin & origin,CacheStorageOwner owner=CacheStorageOwner::kCacheAPI)732   int64_t GetOriginUsage(
733       const url::Origin& origin,
734       CacheStorageOwner owner = CacheStorageOwner::kCacheAPI) {
735     base::RunLoop loop;
736     cache_manager_->GetOriginUsage(
737         origin, owner,
738         base::BindOnce(&CacheStorageManagerTest::UsageCallback,
739                        base::Unretained(this), base::Unretained(&loop)));
740     loop.Run();
741     return callback_usage_;
742   }
743 
UsageCallback(base::RunLoop * run_loop,int64_t usage)744   void UsageCallback(base::RunLoop* run_loop, int64_t usage) {
745     callback_usage_ = usage;
746     run_loop->Quit();
747   }
748 
GetAllOriginsUsage(CacheStorageOwner owner=CacheStorageOwner::kCacheAPI)749   std::vector<StorageUsageInfo> GetAllOriginsUsage(
750       CacheStorageOwner owner = CacheStorageOwner::kCacheAPI) {
751     base::RunLoop loop;
752     cache_manager_->GetAllOriginsUsage(
753         owner, base::BindLambdaForTesting(
754                    [&](const std::vector<StorageUsageInfo>& usage) {
755                      callback_all_origins_usage_ = usage;
756                      loop.Quit();
757                    }));
758     loop.Run();
759     return callback_all_origins_usage_;
760   }
761 
GetSizeThenCloseAllCaches(const url::Origin & origin)762   int64_t GetSizeThenCloseAllCaches(const url::Origin& origin) {
763     DCHECK(ManagerType() == TestManager::kLegacy);
764     base::RunLoop loop;
765     CacheStorageHandle cache_storage = CacheStorageForOrigin(origin);
766     LegacyCacheStorage::From(cache_storage)
767         ->GetSizeThenCloseAllCaches(
768             base::BindOnce(&CacheStorageManagerTest::UsageCallback,
769                            base::Unretained(this), &loop));
770     loop.Run();
771     return callback_usage_;
772   }
773 
Size(const url::Origin & origin)774   int64_t Size(const url::Origin& origin) {
775     DCHECK(ManagerType() == TestManager::kLegacy);
776     base::RunLoop loop;
777     CacheStorageHandle cache_storage = CacheStorageForOrigin(origin);
778     LegacyCacheStorage::From(cache_storage)
779         ->Size(base::BindOnce(&CacheStorageManagerTest::UsageCallback,
780                               base::Unretained(this), &loop));
781     loop.Run();
782     return callback_usage_;
783   }
784 
GetQuotaOriginUsage(const url::Origin & origin)785   int64_t GetQuotaOriginUsage(const url::Origin& origin) {
786     int64_t usage(CacheStorage::kSizeUnknown);
787     base::RunLoop loop;
788     quota_manager_proxy_->GetUsageAndQuota(
789         base::ThreadTaskRunnerHandle::Get().get(), origin,
790         StorageType::kTemporary,
791         base::BindOnce(&CacheStorageManagerTest::DidGetQuotaOriginUsage,
792                        base::Unretained(this), base::Unretained(&usage),
793                        &loop));
794     loop.Run();
795     return usage;
796   }
797 
DidGetQuotaOriginUsage(int64_t * out_usage,base::RunLoop * run_loop,blink::mojom::QuotaStatusCode status_code,int64_t usage,int64_t quota)798   void DidGetQuotaOriginUsage(int64_t* out_usage,
799                               base::RunLoop* run_loop,
800                               blink::mojom::QuotaStatusCode status_code,
801                               int64_t usage,
802                               int64_t quota) {
803     if (status_code == blink::mojom::QuotaStatusCode::kOk)
804       *out_usage = usage;
805     run_loop->Quit();
806   }
807 
808  protected:
809   // Temporary directory must be allocated first so as to be destroyed last.
810   base::ScopedTempDir temp_dir_;
811 
812   BrowserTaskEnvironment task_environment_;
813   TestBrowserContext browser_context_;
814   scoped_refptr<BlobStorageContextWrapper> blob_storage_context_;
815 
816   scoped_refptr<storage::MockSpecialStoragePolicy> quota_policy_;
817   scoped_refptr<storage::MockQuotaManager> mock_quota_manager_;
818   scoped_refptr<MockCacheStorageQuotaManagerProxy> quota_manager_proxy_;
819   scoped_refptr<CacheStorageContextImpl::ObserverList> observers_;
820   scoped_refptr<CacheStorageManager> cache_manager_;
821 
822   CacheStorageCacheHandle callback_cache_handle_;
823   int callback_bool_ = false;
824   CacheStorageError callback_error_ = CacheStorageError::kSuccess;
825   blink::mojom::FetchAPIResponsePtr callback_cache_handle_response_;
826   std::vector<std::string> cache_names_;
827 
828   const url::Origin origin1_;
829   const url::Origin origin2_;
830 
831   int64_t callback_usage_;
832   std::vector<StorageUsageInfo> callback_all_origins_usage_;
833 
834  private:
835   DISALLOW_COPY_AND_ASSIGN(CacheStorageManagerTest);
836 };
837 
838 class CacheStorageManagerMemoryOnlyTest : public CacheStorageManagerTest {
839  public:
MemoryOnly()840   bool MemoryOnly() override { return true; }
841 };
842 
843 class CacheStorageManagerTestP : public CacheStorageManagerTest,
844                                  public testing::WithParamInterface<Param> {
845  public:
MemoryOnly()846   bool MemoryOnly() override {
847     return GetParam().storage_ == TestStorage::kMemory;
848   }
ManagerType()849   TestManager ManagerType() override { return GetParam().manager_; }
850 };
851 
852 // Some tests must be run on the LegacyCacheStorageManager.  This could
853 // be for a number of reasons:
854 //  * The test needs to use internal APIs on the legacy manager.
855 //  * The test is checking behavior that is only true for "real" manager's
856 //    like that Open() will return the exact same c++ pointer for the
857 //    underlying cache.  This assumption is not truee for the cross-sequence
858 //    wrapper.
859 class CacheStorageManagerLegacyOnlyTestP
860     : public CacheStorageManagerTest,
861       public testing::WithParamInterface<TestStorage> {
MemoryOnly()862   bool MemoryOnly() override { return GetParam() == TestStorage::kMemory; }
863 };
864 
TEST_F(CacheStorageManagerTest,TestsRunOnIOThread)865 TEST_F(CacheStorageManagerTest, TestsRunOnIOThread) {
866   EXPECT_TRUE(BrowserThread::CurrentlyOn(BrowserThread::IO));
867 }
868 
TEST_P(CacheStorageManagerTestP,OpenCache)869 TEST_P(CacheStorageManagerTestP, OpenCache) {
870   EXPECT_TRUE(Open(origin1_, "foo"));
871 }
872 
TEST_P(CacheStorageManagerTestP,OpenTwoCaches)873 TEST_P(CacheStorageManagerTestP, OpenTwoCaches) {
874   EXPECT_TRUE(Open(origin1_, "foo"));
875   EXPECT_TRUE(Open(origin1_, "bar"));
876 }
877 
TEST_P(CacheStorageManagerTestP,OpenSameCacheDifferentOwners)878 TEST_P(CacheStorageManagerTestP, OpenSameCacheDifferentOwners) {
879   EXPECT_TRUE(Open(origin1_, "foo", CacheStorageOwner::kCacheAPI));
880   CacheStorageCacheHandle cache_handle = std::move(callback_cache_handle_);
881   EXPECT_TRUE(Open(origin1_, "foo", CacheStorageOwner::kBackgroundFetch));
882   EXPECT_NE(callback_cache_handle_.value(), cache_handle.value());
883 }
884 
TEST_P(CacheStorageManagerTestP,CachePointersDiffer)885 TEST_P(CacheStorageManagerTestP, CachePointersDiffer) {
886   EXPECT_TRUE(Open(origin1_, "foo"));
887   CacheStorageCacheHandle cache_handle = std::move(callback_cache_handle_);
888   EXPECT_TRUE(Open(origin1_, "bar"));
889   EXPECT_NE(callback_cache_handle_.value(), cache_handle.value());
890 }
891 
TEST_P(CacheStorageManagerTestP,Open2CachesSameNameDiffOrigins)892 TEST_P(CacheStorageManagerTestP, Open2CachesSameNameDiffOrigins) {
893   EXPECT_TRUE(Open(origin1_, "foo"));
894   CacheStorageCacheHandle cache_handle = std::move(callback_cache_handle_);
895   EXPECT_TRUE(Open(origin2_, "foo"));
896   EXPECT_NE(cache_handle.value(), callback_cache_handle_.value());
897 }
898 
TEST_P(CacheStorageManagerLegacyOnlyTestP,OpenExistingCache)899 TEST_P(CacheStorageManagerLegacyOnlyTestP, OpenExistingCache) {
900   EXPECT_TRUE(Open(origin1_, "foo"));
901   CacheStorageCacheHandle cache_handle = std::move(callback_cache_handle_);
902   EXPECT_TRUE(Open(origin1_, "foo"));
903   EXPECT_EQ(callback_cache_handle_.value(), cache_handle.value());
904 }
905 
TEST_P(CacheStorageManagerTestP,HasCache)906 TEST_P(CacheStorageManagerTestP, HasCache) {
907   EXPECT_TRUE(Open(origin1_, "foo"));
908   EXPECT_TRUE(Has(origin1_, "foo"));
909   EXPECT_TRUE(callback_bool_);
910 }
911 
TEST_P(CacheStorageManagerTestP,HasCacheDifferentOwners)912 TEST_P(CacheStorageManagerTestP, HasCacheDifferentOwners) {
913   EXPECT_TRUE(Open(origin1_, "public", CacheStorageOwner::kCacheAPI));
914   EXPECT_TRUE(Open(origin1_, "bgf", CacheStorageOwner::kBackgroundFetch));
915 
916   EXPECT_TRUE(Has(origin1_, "public", CacheStorageOwner::kCacheAPI));
917   EXPECT_TRUE(callback_bool_);
918   EXPECT_FALSE(Has(origin1_, "bgf", CacheStorageOwner::kCacheAPI));
919   EXPECT_FALSE(callback_bool_);
920 
921   EXPECT_TRUE(Has(origin1_, "bgf", CacheStorageOwner::kBackgroundFetch));
922   EXPECT_TRUE(callback_bool_);
923   EXPECT_FALSE(Has(origin1_, "public", CacheStorageOwner::kBackgroundFetch));
924   EXPECT_FALSE(callback_bool_);
925 }
926 
TEST_P(CacheStorageManagerTestP,HasNonExistent)927 TEST_P(CacheStorageManagerTestP, HasNonExistent) {
928   EXPECT_FALSE(Has(origin1_, "foo"));
929 }
930 
TEST_P(CacheStorageManagerTestP,DeleteCache)931 TEST_P(CacheStorageManagerTestP, DeleteCache) {
932   EXPECT_TRUE(Open(origin1_, "foo"));
933   EXPECT_TRUE(Delete(origin1_, "foo"));
934   EXPECT_FALSE(Has(origin1_, "foo"));
935 }
936 
TEST_P(CacheStorageManagerTestP,DeleteTwice)937 TEST_P(CacheStorageManagerTestP, DeleteTwice) {
938   EXPECT_TRUE(Open(origin1_, "foo"));
939   EXPECT_TRUE(Delete(origin1_, "foo"));
940   EXPECT_FALSE(Delete(origin1_, "foo"));
941   EXPECT_EQ(CacheStorageError::kErrorNotFound, callback_error_);
942 }
943 
TEST_P(CacheStorageManagerTestP,DeleteCacheReducesOriginSize)944 TEST_P(CacheStorageManagerTestP, DeleteCacheReducesOriginSize) {
945   EXPECT_TRUE(Open(origin1_, "foo"));
946   EXPECT_TRUE(
947       CachePut(callback_cache_handle_.value(), GURL("http://example.com/foo")));
948   // The quota manager gets updated after the put operation runs its callback so
949   // run the event loop.
950   base::RunLoop().RunUntilIdle();
951   int64_t put_delta = quota_manager_proxy_->last_notified_delta();
952   EXPECT_LT(0, put_delta);
953   EXPECT_TRUE(Delete(origin1_, "foo"));
954 
955   // Drop the cache handle so that the cache can be erased from disk.
956   callback_cache_handle_ = CacheStorageCacheHandle();
957   base::RunLoop().RunUntilIdle();
958 
959   EXPECT_EQ(-1 * quota_manager_proxy_->last_notified_delta(), put_delta);
960 }
961 
TEST_P(CacheStorageManagerTestP,EmptyKeys)962 TEST_P(CacheStorageManagerTestP, EmptyKeys) {
963   EXPECT_EQ(0u, Keys(origin1_));
964 }
965 
TEST_P(CacheStorageManagerTestP,SomeKeys)966 TEST_P(CacheStorageManagerTestP, SomeKeys) {
967   EXPECT_TRUE(Open(origin1_, "foo"));
968   EXPECT_TRUE(Open(origin1_, "bar"));
969   EXPECT_TRUE(Open(origin2_, "baz"));
970   EXPECT_EQ(2u, Keys(origin1_));
971   std::vector<std::string> expected_keys;
972   expected_keys.push_back("foo");
973   expected_keys.push_back("bar");
974   EXPECT_EQ(expected_keys, GetIndexNames());
975   EXPECT_EQ(1u, Keys(origin2_));
976   EXPECT_STREQ("baz", GetFirstIndexName().c_str());
977 }
978 
TEST_P(CacheStorageManagerTestP,DeletedKeysGone)979 TEST_P(CacheStorageManagerTestP, DeletedKeysGone) {
980   EXPECT_TRUE(Open(origin1_, "foo"));
981   EXPECT_TRUE(Open(origin1_, "bar"));
982   EXPECT_TRUE(Open(origin2_, "baz"));
983   EXPECT_TRUE(Delete(origin1_, "bar"));
984   EXPECT_EQ(1u, Keys(origin1_));
985   EXPECT_STREQ("foo", GetFirstIndexName().c_str());
986 }
987 
TEST_P(CacheStorageManagerTestP,StorageMatchEntryExists)988 TEST_P(CacheStorageManagerTestP, StorageMatchEntryExists) {
989   EXPECT_TRUE(Open(origin1_, "foo"));
990   EXPECT_TRUE(
991       CachePut(callback_cache_handle_.value(), GURL("http://example.com/foo")));
992   EXPECT_TRUE(StorageMatch(origin1_, "foo", GURL("http://example.com/foo")));
993 }
994 
TEST_P(CacheStorageManagerTestP,StorageMatchNoEntry)995 TEST_P(CacheStorageManagerTestP, StorageMatchNoEntry) {
996   EXPECT_TRUE(Open(origin1_, "foo"));
997   EXPECT_TRUE(
998       CachePut(callback_cache_handle_.value(), GURL("http://example.com/foo")));
999   EXPECT_FALSE(StorageMatch(origin1_, "foo", GURL("http://example.com/bar")));
1000   EXPECT_EQ(CacheStorageError::kErrorNotFound, callback_error_);
1001 }
1002 
TEST_P(CacheStorageManagerTestP,StorageMatchNoCache)1003 TEST_P(CacheStorageManagerTestP, StorageMatchNoCache) {
1004   EXPECT_TRUE(Open(origin1_, "foo"));
1005   EXPECT_TRUE(
1006       CachePut(callback_cache_handle_.value(), GURL("http://example.com/foo")));
1007   EXPECT_FALSE(StorageMatch(origin1_, "bar", GURL("http://example.com/foo")));
1008   EXPECT_EQ(CacheStorageError::kErrorCacheNameNotFound, callback_error_);
1009 }
1010 
TEST_P(CacheStorageManagerTestP,StorageMatchAllEntryExists)1011 TEST_P(CacheStorageManagerTestP, StorageMatchAllEntryExists) {
1012   EXPECT_TRUE(Open(origin1_, "foo"));
1013   EXPECT_TRUE(
1014       CachePut(callback_cache_handle_.value(), GURL("http://example.com/foo")));
1015   EXPECT_TRUE(StorageMatchAll(origin1_, GURL("http://example.com/foo")));
1016 }
1017 
TEST_P(CacheStorageManagerTestP,StorageMatchAllNoEntry)1018 TEST_P(CacheStorageManagerTestP, StorageMatchAllNoEntry) {
1019   EXPECT_TRUE(Open(origin1_, "foo"));
1020   EXPECT_TRUE(
1021       CachePut(callback_cache_handle_.value(), GURL("http://example.com/foo")));
1022   EXPECT_FALSE(StorageMatchAll(origin1_, GURL("http://example.com/bar")));
1023   EXPECT_EQ(CacheStorageError::kErrorNotFound, callback_error_);
1024 }
1025 
TEST_P(CacheStorageManagerTestP,StorageMatchAllNoCaches)1026 TEST_P(CacheStorageManagerTestP, StorageMatchAllNoCaches) {
1027   EXPECT_FALSE(StorageMatchAll(origin1_, GURL("http://example.com/foo")));
1028   EXPECT_EQ(CacheStorageError::kErrorNotFound, callback_error_);
1029 }
1030 
TEST_P(CacheStorageManagerTestP,StorageMatchDifferentOwners)1031 TEST_P(CacheStorageManagerTestP, StorageMatchDifferentOwners) {
1032   EXPECT_TRUE(Open(origin1_, "foo", CacheStorageOwner::kCacheAPI));
1033   EXPECT_TRUE(CachePut(callback_cache_handle_.value(),
1034                        GURL("http://example.com/public")));
1035   EXPECT_TRUE(Open(origin1_, "foo", CacheStorageOwner::kBackgroundFetch));
1036   EXPECT_TRUE(
1037       CachePut(callback_cache_handle_.value(), GURL("http://example.com/bgf")));
1038 
1039   // Check the public cache.
1040   EXPECT_TRUE(StorageMatch(origin1_, "foo", GURL("http://example.com/public"),
1041                            nullptr, CacheStorageOwner::kCacheAPI));
1042   EXPECT_FALSE(StorageMatch(origin1_, "foo", GURL("http://example.com/bgf"),
1043                             nullptr, CacheStorageOwner::kCacheAPI));
1044 
1045   // Check the internal cache.
1046   EXPECT_FALSE(StorageMatch(origin1_, "foo", GURL("http://example.com/public"),
1047                             nullptr, CacheStorageOwner::kBackgroundFetch));
1048   EXPECT_TRUE(StorageMatch(origin1_, "foo", GURL("http://example.com/bgf"),
1049                            nullptr, CacheStorageOwner::kBackgroundFetch));
1050 }
1051 
TEST_F(CacheStorageManagerTest,StorageReuseCacheName)1052 TEST_F(CacheStorageManagerTest, StorageReuseCacheName) {
1053   // Deleting a cache and creating one with the same name and adding an entry
1054   // with the same URL should work. (see crbug.com/542668)
1055   const GURL kTestURL = GURL("http://example.com/foo");
1056   EXPECT_TRUE(Open(origin1_, "foo"));
1057   EXPECT_TRUE(CachePut(callback_cache_handle_.value(), kTestURL));
1058   EXPECT_TRUE(CacheMatch(callback_cache_handle_.value(), kTestURL));
1059 
1060   EXPECT_TRUE(Delete(origin1_, "foo"));
1061   // The cache is deleted but the handle to one of its entries is still
1062   // open. Creating a new cache in the same directory would fail on Windows.
1063   EXPECT_TRUE(Open(origin1_, "foo"));
1064   EXPECT_TRUE(CachePut(callback_cache_handle_.value(), kTestURL));
1065 }
1066 
TEST_P(CacheStorageManagerTestP,DropRefAfterNewCacheWithSameNameCreated)1067 TEST_P(CacheStorageManagerTestP, DropRefAfterNewCacheWithSameNameCreated) {
1068   // Make sure that dropping the final cache handle to a doomed cache doesn't
1069   // affect newer caches with the same name. (see crbug.com/631467)
1070 
1071   // 1. Create cache A and hang onto the handle
1072   const GURL kTestURL = GURL("http://example.com/foo");
1073   EXPECT_TRUE(Open(origin1_, "foo"));
1074   CacheStorageCacheHandle cache_handle = std::move(callback_cache_handle_);
1075 
1076   // 2. Doom the cache
1077   EXPECT_TRUE(Delete(origin1_, "foo"));
1078 
1079   // 3. Create cache B (with the same name)
1080   EXPECT_TRUE(Open(origin1_, "foo"));
1081 
1082   // 4. Drop handle to A
1083   cache_handle = CacheStorageCacheHandle();
1084 
1085   // 5. Verify that B still works
1086   EXPECT_FALSE(CacheMatch(callback_cache_handle_.value(), kTestURL));
1087 }
1088 
TEST_P(CacheStorageManagerTestP,DeleteCorrectDirectory)1089 TEST_P(CacheStorageManagerTestP, DeleteCorrectDirectory) {
1090   // This test reproduces crbug.com/630036.
1091   // 1. Cache A with name "foo" is created
1092   const GURL kTestURL = GURL("http://example.com/foo");
1093   EXPECT_TRUE(Open(origin1_, "foo"));
1094   CacheStorageCacheHandle cache_handle = std::move(callback_cache_handle_);
1095 
1096   // 2. Cache A is doomed, but js hangs onto the handle.
1097   EXPECT_TRUE(Delete(origin1_, "foo"));
1098 
1099   // 3. Cache B with name "foo" is created
1100   EXPECT_TRUE(Open(origin1_, "foo"));
1101 
1102   // 4. Cache B is doomed, and both handles are reset.
1103   EXPECT_TRUE(Delete(origin1_, "foo"));
1104   cache_handle = CacheStorageCacheHandle();
1105 
1106   // Do some busy work on a different cache to move the cache pool threads
1107   // along and trigger the bug.
1108   EXPECT_TRUE(Open(origin1_, "bar"));
1109   EXPECT_TRUE(CachePut(callback_cache_handle_.value(), kTestURL));
1110   EXPECT_TRUE(CacheMatch(callback_cache_handle_.value(), kTestURL));
1111 }
1112 
TEST_P(CacheStorageManagerTestP,StorageMatchAllEntryExistsTwice)1113 TEST_P(CacheStorageManagerTestP, StorageMatchAllEntryExistsTwice) {
1114   EXPECT_TRUE(Open(origin1_, "foo"));
1115   // |request_1| and |request_2| has the same url.
1116   auto request_1 = blink::mojom::FetchAPIRequest::New();
1117   request_1->url = GURL("http://example.com/foo");
1118   auto request_2 = BackgroundFetchSettledFetch::CloneRequest(request_1);
1119   EXPECT_TRUE(CachePutWithStatusCode(callback_cache_handle_.value(),
1120                                      std::move(request_1), 200));
1121   EXPECT_TRUE(Open(origin1_, "bar"));
1122   EXPECT_TRUE(CachePutWithStatusCode(callback_cache_handle_.value(),
1123                                      std::move(request_2), 201));
1124 
1125   EXPECT_TRUE(StorageMatchAll(origin1_, GURL("http://example.com/foo")));
1126 
1127   // The caches need to be searched in order of creation, so verify that the
1128   // response came from the first cache.
1129   EXPECT_EQ(200, callback_cache_handle_response_->status_code);
1130 }
1131 
TEST_P(CacheStorageManagerTestP,StorageMatchInOneOfMany)1132 TEST_P(CacheStorageManagerTestP, StorageMatchInOneOfMany) {
1133   EXPECT_TRUE(Open(origin1_, "foo"));
1134   EXPECT_TRUE(Open(origin1_, "bar"));
1135   EXPECT_TRUE(
1136       CachePut(callback_cache_handle_.value(), GURL("http://example.com/foo")));
1137   EXPECT_TRUE(Open(origin1_, "baz"));
1138 
1139   EXPECT_TRUE(StorageMatchAll(origin1_, GURL("http://example.com/foo")));
1140 }
1141 
TEST_P(CacheStorageManagerLegacyOnlyTestP,Chinese)1142 TEST_P(CacheStorageManagerLegacyOnlyTestP, Chinese) {
1143   EXPECT_TRUE(Open(origin1_, "你好"));
1144   CacheStorageCacheHandle cache_handle = std::move(callback_cache_handle_);
1145   EXPECT_TRUE(Open(origin1_, "你好"));
1146   EXPECT_EQ(callback_cache_handle_.value(), cache_handle.value());
1147   EXPECT_EQ(1u, Keys(origin1_));
1148   EXPECT_STREQ("你好", GetFirstIndexName().c_str());
1149 }
1150 
TEST_F(CacheStorageManagerTest,EmptyKey)1151 TEST_F(CacheStorageManagerTest, EmptyKey) {
1152   EXPECT_TRUE(Open(origin1_, ""));
1153   CacheStorageCacheHandle cache_handle = std::move(callback_cache_handle_);
1154   EXPECT_TRUE(Open(origin1_, ""));
1155   EXPECT_EQ(cache_handle.value(), callback_cache_handle_.value());
1156   EXPECT_EQ(1u, Keys(origin1_));
1157   EXPECT_STREQ("", GetFirstIndexName().c_str());
1158   EXPECT_TRUE(Has(origin1_, ""));
1159   EXPECT_TRUE(Delete(origin1_, ""));
1160   EXPECT_EQ(0u, Keys(origin1_));
1161 }
1162 
TEST_F(CacheStorageManagerTest,DataPersists)1163 TEST_F(CacheStorageManagerTest, DataPersists) {
1164   EXPECT_TRUE(Open(origin1_, "foo"));
1165   EXPECT_TRUE(Open(origin1_, "bar"));
1166   EXPECT_TRUE(Open(origin1_, "baz"));
1167   EXPECT_TRUE(Open(origin2_, "raz"));
1168   EXPECT_TRUE(Delete(origin1_, "bar"));
1169   quota_manager_proxy_->SimulateQuotaManagerDestroyed();
1170   RecreateStorageManager();
1171   EXPECT_EQ(2u, Keys(origin1_));
1172   std::vector<std::string> expected_keys;
1173   expected_keys.push_back("foo");
1174   expected_keys.push_back("baz");
1175   EXPECT_EQ(expected_keys, GetIndexNames());
1176 }
1177 
TEST_F(CacheStorageManagerMemoryOnlyTest,DataLostWhenMemoryOnly)1178 TEST_F(CacheStorageManagerMemoryOnlyTest, DataLostWhenMemoryOnly) {
1179   EXPECT_TRUE(Open(origin1_, "foo"));
1180   EXPECT_TRUE(Open(origin2_, "baz"));
1181   quota_manager_proxy_->SimulateQuotaManagerDestroyed();
1182   RecreateStorageManager();
1183   EXPECT_EQ(0u, Keys(origin1_));
1184 }
1185 
TEST_F(CacheStorageManagerTest,BadCacheName)1186 TEST_F(CacheStorageManagerTest, BadCacheName) {
1187   // Since the implementation writes cache names to disk, ensure that we don't
1188   // escape the directory.
1189   const std::string bad_name = "../../../../../../../../../../../../../../foo";
1190   EXPECT_TRUE(Open(origin1_, bad_name));
1191   EXPECT_EQ(1u, Keys(origin1_));
1192   EXPECT_STREQ(bad_name.c_str(), GetFirstIndexName().c_str());
1193 }
1194 
TEST_F(CacheStorageManagerTest,BadOriginName)1195 TEST_F(CacheStorageManagerTest, BadOriginName) {
1196   // Since the implementation writes origin names to disk, ensure that we don't
1197   // escape the directory.
1198   url::Origin bad_origin(url::Origin::Create(
1199       GURL("http://../../../../../../../../../../../../../../foo")));
1200   EXPECT_TRUE(Open(bad_origin, "foo"));
1201   EXPECT_EQ(1u, Keys(bad_origin));
1202   EXPECT_STREQ("foo", GetFirstIndexName().c_str());
1203 }
1204 
1205 // Dropping a reference to a cache should not immediately destroy it.  These
1206 // warm cache objects are kept alive to optimize the next open.
TEST_F(CacheStorageManagerTest,DropReference)1207 TEST_F(CacheStorageManagerTest, DropReference) {
1208   CacheStorageHandle cache_storage = CacheStorageForOrigin(origin1_);
1209 
1210   EXPECT_TRUE(Open(origin1_, "foo"));
1211   base::WeakPtr<LegacyCacheStorageCache> cache =
1212       LegacyCacheStorageCache::From(callback_cache_handle_)->AsWeakPtr();
1213   // Run a cache operation to ensure that the cache has finished initializing so
1214   // that when the handle is dropped it could possibly close immediately.
1215   EXPECT_FALSE(CacheMatch(callback_cache_handle_.value(),
1216                           GURL("http://example.com/foo")));
1217 
1218   callback_cache_handle_ = CacheStorageCacheHandle();
1219   EXPECT_TRUE(cache) << "unreferenced cache destroyed while owning "
1220                         "CacheStorage is still referenced";
1221 
1222   cache_storage = CacheStorageHandle();
1223   EXPECT_FALSE(cache) << "unreferenced cache not destroyed after last "
1224                          "CacheStorage reference removed";
1225 }
1226 
1227 // Deleting a cache should remove any warmed caches that been kept alive
1228 // without a reference.
TEST_F(CacheStorageManagerTest,DropReferenceAndDelete)1229 TEST_F(CacheStorageManagerTest, DropReferenceAndDelete) {
1230   // Hold a reference to the CacheStorage to permit the warmed
1231   // CacheStorageCache to be kept alive.
1232   CacheStorageHandle cache_storage = CacheStorageForOrigin(origin1_);
1233 
1234   EXPECT_TRUE(Open(origin1_, "foo"));
1235   base::WeakPtr<LegacyCacheStorageCache> cache =
1236       LegacyCacheStorageCache::From(callback_cache_handle_)->AsWeakPtr();
1237   // Run a cache operation to ensure that the cache has finished initializing so
1238   // that when the handle is dropped it could possibly close immediately.
1239   EXPECT_FALSE(CacheMatch(callback_cache_handle_.value(),
1240                           GURL("http://example.com/foo")));
1241 
1242   callback_cache_handle_ = CacheStorageCacheHandle();
1243   EXPECT_TRUE(cache) << "unreferenced cache destroyed while owning "
1244                         "CacheStorage is still referenced";
1245 
1246   // Delete() should trigger its destruction, however.
1247   EXPECT_TRUE(Delete(origin1_, "foo"));
1248   base::RunLoop().RunUntilIdle();
1249 
1250   EXPECT_FALSE(cache)
1251       << "deleted cache not destroyed after last reference removed";
1252 }
1253 
1254 // Critical memory pressure should remove any warmed caches that been kept
1255 // alive without a reference.
TEST_F(CacheStorageManagerTest,DropReferenceAndMemoryPressure)1256 TEST_F(CacheStorageManagerTest, DropReferenceAndMemoryPressure) {
1257   // Hold a reference to the CacheStorage to permit the warmed
1258   // CacheStorageCache to be kept alive.
1259   CacheStorageHandle cache_storage = CacheStorageForOrigin(origin1_);
1260 
1261   EXPECT_TRUE(Open(origin1_, "foo"));
1262   base::WeakPtr<LegacyCacheStorageCache> cache =
1263       LegacyCacheStorageCache::From(callback_cache_handle_)->AsWeakPtr();
1264   // Run a cache operation to ensure that the cache has finished initializing so
1265   // that when the handle is dropped it could possibly close immediately.
1266   EXPECT_FALSE(CacheMatch(callback_cache_handle_.value(),
1267                           GURL("http://example.com/foo")));
1268 
1269   callback_cache_handle_ = CacheStorageCacheHandle();
1270   EXPECT_TRUE(cache) << "unreferenced cache destroyed while owning "
1271                         "CacheStorage is still referenced";
1272 
1273   // Moderate memory pressure should not destroy unreferenced cache objects
1274   // since reading data back in from disk can be expensive.
1275   base::MemoryPressureListener::NotifyMemoryPressure(
1276       base::MemoryPressureListener::MemoryPressureLevel::
1277           MEMORY_PRESSURE_LEVEL_MODERATE);
1278   base::RunLoop().RunUntilIdle();
1279   EXPECT_TRUE(cache);
1280 
1281   // Critical memory pressure should destroy unreferenced cache objects.
1282   base::MemoryPressureListener::NotifyMemoryPressure(
1283       base::MemoryPressureListener::MemoryPressureLevel::
1284           MEMORY_PRESSURE_LEVEL_CRITICAL);
1285   base::RunLoop().RunUntilIdle();
1286 
1287   EXPECT_FALSE(cache)
1288       << "unreferenced cache not destroyed on critical memory pressure";
1289 }
1290 
TEST_F(CacheStorageManagerTest,DropReferenceDuringQuery)1291 TEST_F(CacheStorageManagerTest, DropReferenceDuringQuery) {
1292   // Setup the cache and execute an operation to make sure all initialization
1293   // is complete.
1294   EXPECT_TRUE(Open(origin1_, "foo"));
1295   base::WeakPtr<LegacyCacheStorageCache> cache =
1296       LegacyCacheStorageCache::From(callback_cache_handle_)->AsWeakPtr();
1297   EXPECT_FALSE(CacheMatch(callback_cache_handle_.value(),
1298                           GURL("http://example.com/foo")));
1299 
1300   // Override the cache scheduler so that we can take an action below
1301   // after the query operation begins.
1302   base::RunLoop scheduler_loop;
1303   auto scheduler =
1304       std::make_unique<CallbackScheduler>(scheduler_loop.QuitClosure());
1305   cache->SetSchedulerForTesting(std::move(scheduler));
1306 
1307   // Perform a MatchAll() operation to trigger a full query of the cache
1308   // that does not hit the fast path optimization.
1309   base::RunLoop match_loop;
1310   cache->MatchAll(
1311       nullptr, nullptr, /* trace_id = */ 0,
1312       base::BindOnce(&CacheStorageManagerTest::CacheMatchAllCallback,
1313                      base::Unretained(this), base::Unretained(&match_loop)));
1314 
1315   // Wait for the MatchAll operation to begin.
1316   scheduler_loop.Run();
1317 
1318   // Clear the external cache handle.
1319   callback_cache_handle_ = CacheStorageCacheHandle();
1320 
1321   // Wait for the MatchAll operation to complete as expected.
1322   match_loop.Run();
1323   EXPECT_EQ(CacheStorageError::kSuccess, callback_error_);
1324 }
1325 // A cache continues to work so long as there is a handle to it. Only after the
1326 // last cache handle is deleted can the cache be freed.
TEST_P(CacheStorageManagerTestP,CacheWorksAfterDelete)1327 TEST_P(CacheStorageManagerTestP, CacheWorksAfterDelete) {
1328   const GURL kFooURL("http://example.com/foo");
1329   const GURL kBarURL("http://example.com/bar");
1330   const GURL kBazURL("http://example.com/baz");
1331   EXPECT_TRUE(Open(origin1_, "foo"));
1332   CacheStorageCacheHandle original_handle = std::move(callback_cache_handle_);
1333   EXPECT_TRUE(CachePut(original_handle.value(), kFooURL));
1334   EXPECT_TRUE(Delete(origin1_, "foo"));
1335 
1336   // Verify that the existing cache handle still works.
1337   EXPECT_TRUE(CacheMatch(original_handle.value(), kFooURL));
1338   EXPECT_TRUE(CachePut(original_handle.value(), kBarURL));
1339   EXPECT_TRUE(CacheMatch(original_handle.value(), kBarURL));
1340 
1341   // The cache shouldn't be visible to subsequent storage operations.
1342   EXPECT_EQ(0u, Keys(origin1_));
1343 
1344   // Open a new cache with the same name, it should create a new cache, but not
1345   // interfere with the original cache.
1346   EXPECT_TRUE(Open(origin1_, "foo"));
1347   CacheStorageCacheHandle new_handle = std::move(callback_cache_handle_);
1348   EXPECT_TRUE(CachePut(new_handle.value(), kBazURL));
1349 
1350   EXPECT_FALSE(CacheMatch(new_handle.value(), kFooURL));
1351   EXPECT_FALSE(CacheMatch(new_handle.value(), kBarURL));
1352   EXPECT_TRUE(CacheMatch(new_handle.value(), kBazURL));
1353 
1354   EXPECT_TRUE(CacheMatch(original_handle.value(), kFooURL));
1355   EXPECT_TRUE(CacheMatch(original_handle.value(), kBarURL));
1356   EXPECT_FALSE(CacheMatch(original_handle.value(), kBazURL));
1357 }
1358 
1359 // Deleted caches can still be modified, but all changes will eventually be
1360 // thrown away when all references are released.
TEST_F(CacheStorageManagerTest,DeletedCacheIgnoredInIndex)1361 TEST_F(CacheStorageManagerTest, DeletedCacheIgnoredInIndex) {
1362   const GURL kFooURL("http://example.com/foo");
1363   const GURL kBarURL("http://example.com/bar");
1364   const GURL kBazURL("http://example.com/baz");
1365   const std::string kCacheName = "foo";
1366 
1367   EXPECT_TRUE(Open(origin1_, kCacheName));
1368   auto original_handle = std::move(callback_cache_handle_);
1369   EXPECT_TRUE(CachePut(original_handle.value(), kFooURL));
1370   EXPECT_TRUE(Delete(origin1_, kCacheName));
1371 
1372   // Now a second cache using the same name, but with different data.
1373   EXPECT_TRUE(Open(origin1_, kCacheName));
1374   auto new_handle = std::move(callback_cache_handle_);
1375   EXPECT_TRUE(CachePut(new_handle.value(), kFooURL));
1376   EXPECT_TRUE(CachePut(new_handle.value(), kBarURL));
1377   EXPECT_TRUE(CachePut(new_handle.value(), kBazURL));
1378   auto new_cache_size = Size(origin1_);
1379 
1380   // Now modify the first cache.
1381   EXPECT_TRUE(CachePut(original_handle.value(), kBarURL));
1382 
1383   // Now deref both caches, and recreate the storage manager.
1384   original_handle = CacheStorageCacheHandle();
1385   new_handle = CacheStorageCacheHandle();
1386   EXPECT_TRUE(FlushCacheStorageIndex(origin1_));
1387   DestroyStorageManager();
1388   CreateStorageManager();
1389 
1390   EXPECT_TRUE(Open(origin1_, kCacheName));
1391   EXPECT_EQ(new_cache_size, Size(origin1_));
1392 }
1393 
TEST_F(CacheStorageManagerTest,TestErrorInitializingCache)1394 TEST_F(CacheStorageManagerTest, TestErrorInitializingCache) {
1395   if (MemoryOnly())
1396     return;
1397   const GURL kFooURL("http://example.com/foo");
1398   const std::string kCacheName = "foo";
1399 
1400   EXPECT_TRUE(Open(origin1_, kCacheName));
1401   auto original_handle = std::move(callback_cache_handle_);
1402   EXPECT_TRUE(CachePut(original_handle.value(), kFooURL));
1403   auto size_before_close = Size(origin1_);
1404   EXPECT_GT(size_before_close, 0);
1405 
1406   CacheStorageHandle cache_storage = CacheStorageForOrigin(origin1_);
1407   auto cache_handle =
1408       LegacyCacheStorage::From(cache_storage)->GetLoadedCache(kCacheName);
1409   base::FilePath cache_path =
1410       LegacyCacheStorageCache::From(cache_handle)->path();
1411   base::FilePath storage_path = cache_path.DirName();
1412   base::FilePath index_path = cache_path.AppendASCII("index");
1413   cache_handle = CacheStorageCacheHandle();
1414 
1415   // Do our best to flush any pending cache_storage index file writes to disk
1416   // before proceeding.  This does not guarantee the simple disk_cache index
1417   // is written, though.
1418   EXPECT_TRUE(FlushCacheStorageIndex(origin1_));
1419   EXPECT_FALSE(FlushCacheStorageIndex(origin1_));
1420 
1421   DestroyStorageManager();
1422 
1423   // Truncate the SimpleCache index to force an error when next opened.
1424   ASSERT_FALSE(index_path.empty());
1425   ASSERT_TRUE(base::WriteFile(index_path, "hello"));
1426 
1427   // The cache_storage index and simple disk_cache index files are written from
1428   // background threads.  They may be written in unexpected orders due to timing
1429   // differences.  We need to ensure the cache directory to have a newer time
1430   // stamp, though, in order for the Size() method to actually try calculating
1431   // the size from the corrupted simple disk_cache.  Therefore we force the
1432   // cache_storage index to have a much older time to ensure that it is not used
1433   // in the following Size() call.
1434   base::FilePath cache_index_path =
1435       storage_path.AppendASCII(LegacyCacheStorage::kIndexFileName);
1436   base::Time t = base::Time::Now() + base::TimeDelta::FromHours(-1);
1437   EXPECT_TRUE(base::TouchFile(cache_index_path, t, t));
1438   EXPECT_FALSE(IsIndexFileCurrent(storage_path));
1439 
1440   CreateStorageManager();
1441 
1442   EXPECT_TRUE(Open(origin1_, kCacheName));
1443   EXPECT_EQ(0, Size(origin1_));
1444 }
1445 
TEST_F(CacheStorageManagerTest,CacheSizeCorrectAfterReopen)1446 TEST_F(CacheStorageManagerTest, CacheSizeCorrectAfterReopen) {
1447   const GURL kFooURL("http://example.com/foo");
1448   const std::string kCacheName = "foo";
1449 
1450   EXPECT_TRUE(Open(origin1_, kCacheName));
1451   auto original_handle = std::move(callback_cache_handle_);
1452   EXPECT_TRUE(CachePut(original_handle.value(), kFooURL));
1453   auto size_before_close = Size(origin1_);
1454   EXPECT_GT(size_before_close, 0);
1455 
1456   DestroyStorageManager();
1457   CreateStorageManager();
1458 
1459   EXPECT_TRUE(Open(origin1_, kCacheName));
1460   EXPECT_EQ(size_before_close, Size(origin1_));
1461 }
1462 
TEST_F(CacheStorageManagerTest,CacheSizePaddedAfterReopen)1463 TEST_F(CacheStorageManagerTest, CacheSizePaddedAfterReopen) {
1464   const GURL kFooURL = origin1_.GetURL().Resolve("foo");
1465   const std::string kCacheName = "foo";
1466 
1467   int64_t put_delta = quota_manager_proxy_->last_notified_delta();
1468   EXPECT_EQ(0, put_delta);
1469   EXPECT_EQ(0, quota_manager_proxy_->notify_storage_modified_count());
1470 
1471   EXPECT_TRUE(Open(origin1_, kCacheName));
1472   CacheStorageCacheHandle original_handle = std::move(callback_cache_handle_);
1473 
1474   base::RunLoop().RunUntilIdle();
1475   put_delta += quota_manager_proxy_->last_notified_delta();
1476   EXPECT_EQ(0, put_delta);
1477   EXPECT_EQ(0, quota_manager_proxy_->notify_storage_modified_count());
1478 
1479   EXPECT_TRUE(
1480       CachePut(original_handle.value(), kFooURL, FetchResponseType::kOpaque));
1481   int64_t cache_size_before_close = Size(origin1_);
1482   base::FilePath storage_dir =
1483       LegacyCacheStorageCache::From(original_handle)->path().DirName();
1484   original_handle = CacheStorageCacheHandle();
1485   EXPECT_GT(cache_size_before_close, 0);
1486 
1487   base::RunLoop().RunUntilIdle();
1488   EXPECT_EQ(cache_size_before_close, GetQuotaOriginUsage(origin1_));
1489 
1490   base::RunLoop().RunUntilIdle();
1491   put_delta = quota_manager_proxy_->last_notified_delta();
1492   EXPECT_GT(put_delta, 0);
1493   EXPECT_EQ(1, quota_manager_proxy_->notify_storage_modified_count());
1494 
1495   EXPECT_EQ(GetQuotaOriginUsage(origin1_), put_delta);
1496 
1497   // Close the caches and cache manager.
1498   EXPECT_TRUE(FlushCacheStorageIndex(origin1_));
1499   DestroyStorageManager();
1500 
1501   // Create a new CacheStorageManager that hasn't yet loaded the origin.
1502   CreateStorageManager();
1503   quota_manager_proxy_->SimulateQuotaManagerDestroyed();
1504   RecreateStorageManager();
1505   EXPECT_TRUE(Open(origin1_, kCacheName));
1506 
1507   base::RunLoop().RunUntilIdle();
1508   put_delta = quota_manager_proxy_->last_notified_delta();
1509   EXPECT_EQ(0, put_delta);
1510   EXPECT_EQ(0, quota_manager_proxy_->notify_storage_modified_count());
1511 
1512   EXPECT_EQ(cache_size_before_close, Size(origin1_));
1513 }
1514 
TEST_F(CacheStorageManagerTest,QuotaCorrectAfterReopen)1515 TEST_F(CacheStorageManagerTest, QuotaCorrectAfterReopen) {
1516   const std::string kCacheName = "foo";
1517 
1518   // Choose a response type that will not be padded so that the expected
1519   // cache size can be calculated.
1520   const FetchResponseType response_type = FetchResponseType::kCors;
1521 
1522   // Create a new cache.
1523   int64_t cache_size;
1524   {
1525     EXPECT_TRUE(Open(origin1_, kCacheName));
1526     CacheStorageCacheHandle cache_handle = std::move(callback_cache_handle_);
1527     base::RunLoop().RunUntilIdle();
1528 
1529     const GURL kFooURL = origin1_.GetURL().Resolve("foo");
1530     EXPECT_TRUE(CachePut(cache_handle.value(), kFooURL, response_type));
1531     cache_size = Size(origin1_);
1532 
1533     EXPECT_EQ(cache_size, GetQuotaOriginUsage(origin1_));
1534   }
1535 
1536   // Wait for the dereferenced cache to be closed.
1537   base::RunLoop().RunUntilIdle();
1538 
1539   // Now reopen the cache.
1540   EXPECT_TRUE(Open(origin1_, kCacheName));
1541   CacheStorageCacheHandle cache_handle = std::move(callback_cache_handle_);
1542   base::RunLoop().RunUntilIdle();
1543   EXPECT_EQ(cache_size, GetQuotaOriginUsage(origin1_));
1544 
1545   // And write a second equally sized value and verify size is doubled.
1546   const GURL kBarURL = origin1_.GetURL().Resolve("bar");
1547   EXPECT_TRUE(CachePut(cache_handle.value(), kBarURL, response_type));
1548 
1549   EXPECT_EQ(2 * cache_size, GetQuotaOriginUsage(origin1_));
1550 }
1551 
TEST_F(CacheStorageManagerTest,PersistedCacheKeyUsed)1552 TEST_F(CacheStorageManagerTest, PersistedCacheKeyUsed) {
1553   const GURL kFooURL = origin1_.GetURL().Resolve("foo");
1554   const std::string kCacheName = "foo";
1555 
1556   EXPECT_TRUE(Open(origin1_, kCacheName));
1557   CacheStorageCacheHandle original_handle = std::move(callback_cache_handle_);
1558 
1559   EXPECT_TRUE(
1560       CachePut(original_handle.value(), kFooURL, FetchResponseType::kOpaque));
1561 
1562   int64_t cache_size_after_put = Size(origin1_);
1563   EXPECT_LT(0, cache_size_after_put);
1564 
1565   // Close the caches and cache manager.
1566   EXPECT_TRUE(FlushCacheStorageIndex(origin1_));
1567   DestroyStorageManager();
1568 
1569   // ResetPaddingKeyForTesting isn't thread safe so
1570   base::RunLoop().RunUntilIdle();
1571   storage::ResetPaddingKeyForTesting();
1572 
1573   // Create a new CacheStorageManager that hasn't yet loaded the origin.
1574   CreateStorageManager();
1575   quota_manager_proxy_->SimulateQuotaManagerDestroyed();
1576   RecreateStorageManager();
1577 
1578   // Reopening the origin/cache creates a new CacheStorage instance with a new
1579   // random key.
1580   EXPECT_TRUE(Open(origin1_, kCacheName));
1581 
1582   // Size (before any change) should be the same as before it was closed.
1583   EXPECT_EQ(cache_size_after_put, Size(origin1_));
1584 
1585   // Delete the value. If the new padding key was used to deduct the padded size
1586   // then after deletion we would expect to see a non-zero cache size.
1587   EXPECT_TRUE(Delete(origin1_, "foo"));
1588   EXPECT_EQ(0, Size(origin1_));
1589 
1590   // Now put the exact same resource back into the cache. This time we expect to
1591   // see a different size as the padding is calculated with a different key.
1592   CacheStorageCacheHandle new_handle = std::move(callback_cache_handle_);
1593   EXPECT_TRUE(
1594       CachePut(new_handle.value(), kFooURL, FetchResponseType::kOpaque));
1595 
1596   EXPECT_NE(cache_size_after_put, Size(origin1_));
1597 }
1598 
1599 // With a memory cache the cache can't be freed from memory until the client
1600 // calls delete.
TEST_F(CacheStorageManagerMemoryOnlyTest,MemoryLosesReferenceOnlyAfterDelete)1601 TEST_F(CacheStorageManagerMemoryOnlyTest, MemoryLosesReferenceOnlyAfterDelete) {
1602   EXPECT_TRUE(Open(origin1_, "foo"));
1603   base::WeakPtr<LegacyCacheStorageCache> cache =
1604       LegacyCacheStorageCache::From(callback_cache_handle_)->AsWeakPtr();
1605   callback_cache_handle_ = CacheStorageCacheHandle();
1606   EXPECT_TRUE(cache);
1607   EXPECT_TRUE(Delete(origin1_, "foo"));
1608   base::RunLoop().RunUntilIdle();
1609   EXPECT_FALSE(cache);
1610 }
1611 
TEST_P(CacheStorageManagerTestP,DeleteBeforeRelease)1612 TEST_P(CacheStorageManagerTestP, DeleteBeforeRelease) {
1613   EXPECT_TRUE(Open(origin1_, "foo"));
1614   EXPECT_TRUE(Delete(origin1_, "foo"));
1615   EXPECT_TRUE(callback_cache_handle_.value());
1616 }
1617 
TEST_P(CacheStorageManagerLegacyOnlyTestP,OpenRunsSerially)1618 TEST_P(CacheStorageManagerLegacyOnlyTestP, OpenRunsSerially) {
1619   EXPECT_FALSE(Delete(origin1_, "tmp"));  // Init storage.
1620   CacheStorageHandle cache_storage = CacheStorageForOrigin(origin1_);
1621   auto* impl = LegacyCacheStorage::From(cache_storage);
1622   auto id = impl->StartAsyncOperationForTesting();
1623 
1624   base::RunLoop open_loop;
1625   cache_storage.value()->OpenCache(
1626       "foo", /* trace_id = */ 0,
1627       base::BindOnce(&CacheStorageManagerTest::CacheAndErrorCallback,
1628                      base::Unretained(this), base::Unretained(&open_loop)));
1629 
1630   base::RunLoop().RunUntilIdle();
1631   EXPECT_FALSE(callback_cache_handle_.value());
1632 
1633   impl->CompleteAsyncOperationForTesting(id);
1634   open_loop.Run();
1635   EXPECT_TRUE(callback_cache_handle_.value());
1636 }
1637 
TEST_P(CacheStorageManagerTestP,GetOriginUsage)1638 TEST_P(CacheStorageManagerTestP, GetOriginUsage) {
1639   EXPECT_EQ(0, GetOriginUsage(origin1_));
1640   EXPECT_TRUE(Open(origin1_, "foo"));
1641   EXPECT_EQ(0, GetOriginUsage(origin1_));
1642   EXPECT_TRUE(
1643       CachePut(callback_cache_handle_.value(), GURL("http://example.com/foo")));
1644   int64_t foo_size = GetOriginUsage(origin1_);
1645   EXPECT_LT(0, GetOriginUsage(origin1_));
1646   EXPECT_EQ(0, GetOriginUsage(origin2_));
1647 
1648   // Add the same entry into a second cache, the size should double.
1649   EXPECT_TRUE(Open(origin1_, "bar"));
1650   EXPECT_TRUE(
1651       CachePut(callback_cache_handle_.value(), GURL("http://example.com/foo")));
1652   EXPECT_EQ(2 * foo_size, GetOriginUsage(origin1_));
1653 }
1654 
TEST_P(CacheStorageManagerTestP,GetAllOriginsUsage)1655 TEST_P(CacheStorageManagerTestP, GetAllOriginsUsage) {
1656   EXPECT_EQ(0ULL, GetAllOriginsUsage().size());
1657   // Put one entry in a cache on origin 1.
1658   EXPECT_TRUE(Open(origin1_, "foo"));
1659   EXPECT_TRUE(
1660       CachePut(callback_cache_handle_.value(), GURL("http://example.com/foo")));
1661 
1662   // Put two entries (of identical size) in a cache on origin 2.
1663   EXPECT_TRUE(Open(origin2_, "foo"));
1664   EXPECT_TRUE(
1665       CachePut(callback_cache_handle_.value(), GURL("http://example.com/foo")));
1666   EXPECT_TRUE(
1667       CachePut(callback_cache_handle_.value(), GURL("http://example.com/bar")));
1668 
1669   std::vector<StorageUsageInfo> usage = GetAllOriginsUsage();
1670   EXPECT_EQ(2ULL, usage.size());
1671 
1672   int origin1_index = usage[0].origin == origin1_ ? 0 : 1;
1673   int origin2_index = usage[1].origin == origin2_ ? 1 : 0;
1674   EXPECT_NE(origin1_index, origin2_index);
1675 
1676   int64_t origin1_size = usage[origin1_index].total_size_bytes;
1677   int64_t origin2_size = usage[origin2_index].total_size_bytes;
1678   EXPECT_EQ(2 * origin1_size, origin2_size);
1679 
1680   if (MemoryOnly()) {
1681     EXPECT_TRUE(usage[origin1_index].last_modified.is_null());
1682     EXPECT_TRUE(usage[origin2_index].last_modified.is_null());
1683   } else {
1684     EXPECT_FALSE(usage[origin1_index].last_modified.is_null());
1685     EXPECT_FALSE(usage[origin2_index].last_modified.is_null());
1686   }
1687 }
1688 
TEST_P(CacheStorageManagerTestP,GetAllOriginsUsageDifferentOwners)1689 TEST_P(CacheStorageManagerTestP, GetAllOriginsUsageDifferentOwners) {
1690   EXPECT_EQ(0ULL, GetAllOriginsUsage(CacheStorageOwner::kCacheAPI).size());
1691   EXPECT_EQ(0ULL,
1692             GetAllOriginsUsage(CacheStorageOwner::kBackgroundFetch).size());
1693 
1694   // Put one entry in a cache of owner 1.
1695   EXPECT_TRUE(Open(origin1_, "foo", CacheStorageOwner::kCacheAPI));
1696   EXPECT_TRUE(
1697       CachePut(callback_cache_handle_.value(), GURL("http://example.com/foo")));
1698 
1699   // Put two entries (of identical size) in two origins in a cache of owner 2.
1700   EXPECT_TRUE(Open(origin1_, "foo", CacheStorageOwner::kBackgroundFetch));
1701   EXPECT_TRUE(
1702       CachePut(callback_cache_handle_.value(), GURL("http://example.com/foo")));
1703   EXPECT_TRUE(Open(origin2_, "foo", CacheStorageOwner::kBackgroundFetch));
1704   EXPECT_TRUE(
1705       CachePut(callback_cache_handle_.value(), GURL("http://example.com/bar")));
1706 
1707   std::vector<StorageUsageInfo> usage_cache =
1708       GetAllOriginsUsage(CacheStorageOwner::kCacheAPI);
1709   EXPECT_EQ(1ULL, usage_cache.size());
1710   std::vector<StorageUsageInfo> usage_bgf =
1711       GetAllOriginsUsage(CacheStorageOwner::kBackgroundFetch);
1712   EXPECT_EQ(2ULL, usage_bgf.size());
1713 
1714   int origin1_index = usage_bgf[0].origin == origin1_ ? 0 : 1;
1715   int origin2_index = usage_bgf[1].origin == origin2_ ? 1 : 0;
1716   EXPECT_NE(origin1_index, origin2_index);
1717 
1718   EXPECT_EQ(usage_cache[0].origin, origin1_);
1719   EXPECT_EQ(usage_bgf[origin1_index].origin, origin1_);
1720   EXPECT_EQ(usage_bgf[origin2_index].origin, origin2_);
1721 
1722   EXPECT_EQ(usage_cache[0].total_size_bytes,
1723             usage_bgf[origin1_index].total_size_bytes);
1724 
1725   if (MemoryOnly()) {
1726     EXPECT_TRUE(usage_cache[0].last_modified.is_null());
1727     EXPECT_TRUE(usage_bgf[origin1_index].last_modified.is_null());
1728     EXPECT_TRUE(usage_bgf[origin2_index].last_modified.is_null());
1729   } else {
1730     EXPECT_FALSE(usage_cache[0].last_modified.is_null());
1731     EXPECT_FALSE(usage_bgf[origin1_index].last_modified.is_null());
1732     EXPECT_FALSE(usage_bgf[origin2_index].last_modified.is_null());
1733   }
1734 }
1735 
1736 // TODO(crbug.com/760687): Flaky on Fuchsia.
1737 #if defined(OS_FUCHSIA)
1738 #define MAYBE_GetAllOriginsUsageWithOldIndex DISABLED_GetAllOriginsUsageWithOldIndex
1739 #else
1740 #define MAYBE_GetAllOriginsUsageWithOldIndex GetAllOriginsUsageWithOldIndex
1741 #endif
TEST_F(CacheStorageManagerTest,MAYBE_GetAllOriginsUsageWithOldIndex)1742 TEST_F(CacheStorageManagerTest, MAYBE_GetAllOriginsUsageWithOldIndex) {
1743   // Write a single value (V1) to the cache.
1744   const GURL kFooURL = origin1_.GetURL().Resolve("foo");
1745   const std::string kCacheName = "foo";
1746   EXPECT_TRUE(Open(origin1_, kCacheName));
1747   CacheStorageCacheHandle original_handle = std::move(callback_cache_handle_);
1748 
1749   EXPECT_TRUE(CachePut(original_handle.value(), kFooURL));
1750   int64_t cache_size_v1 = Size(origin1_);
1751   base::FilePath storage_dir =
1752       LegacyCacheStorageCache::From(original_handle)->path().DirName();
1753   original_handle = CacheStorageCacheHandle();
1754   EXPECT_GE(cache_size_v1, 0);
1755 
1756   // Close the caches and cache manager.
1757   EXPECT_TRUE(FlushCacheStorageIndex(origin1_));
1758   DestroyStorageManager();
1759 
1760   // Save a copy of the V1 index.
1761   EXPECT_TRUE(IsIndexFileCurrent(storage_dir));
1762   base::FilePath index_path = storage_dir.AppendASCII("index.txt");
1763   EXPECT_TRUE(base::PathExists(index_path));
1764   base::FilePath backup_index_path = storage_dir.AppendASCII("index.txt.bak");
1765   EXPECT_TRUE(base::CopyFile(index_path, backup_index_path));
1766 
1767   // Create a new CacheStorageManager that hasn't yet loaded the origin.
1768   CreateStorageManager();
1769   quota_manager_proxy_->SimulateQuotaManagerDestroyed();
1770   RecreateStorageManager();
1771 
1772   // Create a second value (V2) in the cache.
1773   EXPECT_TRUE(Open(origin1_, kCacheName));
1774   original_handle = std::move(callback_cache_handle_);
1775   const GURL kBarURL = origin1_.GetURL().Resolve("bar");
1776   EXPECT_TRUE(CachePut(original_handle.value(), kBarURL));
1777   original_handle = CacheStorageCacheHandle();
1778 
1779   // Capture the size before the index has necessarily flushed to disk.
1780   std::vector<StorageUsageInfo> usage = GetAllOriginsUsage();
1781   ASSERT_EQ(1ULL, usage.size());
1782   int64_t usage_before_close = usage[0].total_size_bytes;
1783   EXPECT_GT(usage_before_close, 0);
1784 
1785   // Flush the index to ensure we can read it correctly from the index file.
1786   EXPECT_TRUE(FlushCacheStorageIndex(origin1_));
1787 
1788   // Close the caches and cache manager.
1789   DestroyStorageManager();
1790 
1791   CreateStorageManager();
1792   quota_manager_proxy_->SimulateQuotaManagerDestroyed();
1793   RecreateStorageManager();
1794 
1795   // Read the size from the index file.
1796   CreateStorageManager();
1797   usage = GetAllOriginsUsage();
1798   ASSERT_EQ(1ULL, usage.size());
1799   EXPECT_EQ(usage_before_close, usage[0].total_size_bytes);
1800 
1801   DestroyStorageManager();
1802 
1803   // Restore the index to the V1 state. Make the access/mod times of index file
1804   // older than the other directories in the store to trigger size
1805   // recalculation.
1806   EXPECT_TRUE(base::CopyFile(backup_index_path, index_path));
1807   base::Time t = base::Time::Now() - base::TimeDelta::FromHours(1);
1808   EXPECT_TRUE(base::TouchFile(index_path, t, t));
1809   EXPECT_FALSE(IsIndexFileCurrent(storage_dir));
1810 
1811   // Read the size with the stale index file forcing a recalculation.
1812   CreateStorageManager();
1813   usage = GetAllOriginsUsage();
1814   ASSERT_EQ(1ULL, usage.size());
1815 
1816   EXPECT_EQ(usage_before_close, usage[0].total_size_bytes);
1817 
1818   EXPECT_FALSE(usage[0].last_modified.is_null());
1819 }
1820 
1821 // TODO(crbug.com/760687): Flaky on Fuchsia.
1822 #if defined(OS_FUCHSIA)
1823 #define MAYBE_GetOriginSizeWithOldIndex DISABLED_GetOriginSizeWithOldIndex
1824 #else
1825 #define MAYBE_GetOriginSizeWithOldIndex GetOriginSizeWithOldIndex
1826 #endif
TEST_F(CacheStorageManagerTest,MAYBE_GetOriginSizeWithOldIndex)1827 TEST_F(CacheStorageManagerTest, MAYBE_GetOriginSizeWithOldIndex) {
1828   // Write a single value (V1) to the cache.
1829   const GURL kFooURL = origin1_.GetURL().Resolve("foo");
1830   const std::string kCacheName = "foo";
1831   EXPECT_TRUE(Open(origin1_, kCacheName));
1832   CacheStorageCacheHandle original_handle = std::move(callback_cache_handle_);
1833 
1834   EXPECT_TRUE(CachePut(original_handle.value(), kFooURL));
1835   int64_t cache_size_v1 = Size(origin1_);
1836   base::FilePath storage_dir =
1837       LegacyCacheStorageCache::From(original_handle)->path().DirName();
1838   original_handle = CacheStorageCacheHandle();
1839   EXPECT_GE(cache_size_v1, 0);
1840 
1841   // Close the caches and cache manager.
1842   EXPECT_TRUE(FlushCacheStorageIndex(origin1_));
1843   DestroyStorageManager();
1844 
1845   // Save a copy of the V1 index.
1846   EXPECT_TRUE(IsIndexFileCurrent(storage_dir));
1847   base::FilePath index_path = storage_dir.AppendASCII("index.txt");
1848   EXPECT_TRUE(base::PathExists(index_path));
1849   base::FilePath backup_index_path = storage_dir.AppendASCII("index.txt.bak");
1850   EXPECT_TRUE(base::CopyFile(index_path, backup_index_path));
1851 
1852   // Create a new CacheStorageManager that hasn't yet loaded the origin.
1853   CreateStorageManager();
1854   quota_manager_proxy_->SimulateQuotaManagerDestroyed();
1855   RecreateStorageManager();
1856 
1857   // Reopen the cache and write a second value (V2).
1858   EXPECT_TRUE(Open(origin1_, kCacheName));
1859   original_handle = std::move(callback_cache_handle_);
1860   const GURL kBarURL = origin1_.GetURL().Resolve("bar");
1861   EXPECT_TRUE(CachePut(original_handle.value(), kBarURL));
1862   original_handle = CacheStorageCacheHandle();
1863   int64_t cache_size_v2 = Size(origin1_);
1864   EXPECT_GE(cache_size_v2, 0);
1865 
1866   // Close the caches and cache manager.
1867   DestroyStorageManager();
1868 
1869   // Restore the index to the V1 state.
1870   EXPECT_TRUE(base::CopyFile(backup_index_path, index_path));
1871 
1872   // Make the access/mod times of index file older than the other files in the
1873   // cache to trigger size recalculation.
1874   base::Time t = base::Time::Now() - base::TimeDelta::FromHours(1);
1875   EXPECT_TRUE(base::TouchFile(index_path, t, t));
1876   EXPECT_FALSE(IsIndexFileCurrent(storage_dir));
1877 
1878   // Reopen the cache and ensure the size is correct for the V2 value.
1879   CreateStorageManager();
1880   EXPECT_TRUE(Open(origin1_, kCacheName));
1881   EXPECT_EQ(cache_size_v2, Size(origin1_));
1882 }
1883 
TEST_P(CacheStorageManagerLegacyOnlyTestP,GetSizeThenCloseAllCaches)1884 TEST_P(CacheStorageManagerLegacyOnlyTestP, GetSizeThenCloseAllCaches) {
1885   EXPECT_TRUE(Open(origin1_, "foo"));
1886   EXPECT_TRUE(
1887       CachePut(callback_cache_handle_.value(), GURL("http://example.com/foo")));
1888   EXPECT_TRUE(CachePut(callback_cache_handle_.value(),
1889                        GURL("http://example.com/foo2")));
1890   EXPECT_TRUE(Open(origin1_, "bar"));
1891   EXPECT_TRUE(
1892       CachePut(callback_cache_handle_.value(), GURL("http://example.com/bar")));
1893 
1894   int64_t origin_size = GetOriginUsage(origin1_);
1895   EXPECT_LT(0, origin_size);
1896 
1897   EXPECT_EQ(origin_size, GetSizeThenCloseAllCaches(origin1_));
1898   EXPECT_FALSE(
1899       CachePut(callback_cache_handle_.value(), GURL("http://example.com/baz")));
1900 }
1901 
TEST_P(CacheStorageManagerLegacyOnlyTestP,GetSizeThenCloseAllCachesTwoOwners)1902 TEST_P(CacheStorageManagerLegacyOnlyTestP, GetSizeThenCloseAllCachesTwoOwners) {
1903   EXPECT_TRUE(Open(origin1_, "foo", CacheStorageOwner::kCacheAPI));
1904   CacheStorageCacheHandle public_handle = std::move(callback_cache_handle_);
1905   EXPECT_TRUE(Open(origin1_, "foo", CacheStorageOwner::kBackgroundFetch));
1906   CacheStorageCacheHandle bgf_handle = std::move(callback_cache_handle_);
1907 
1908   EXPECT_TRUE(
1909       CachePut(public_handle.value(), GURL("http://example.com/public")));
1910   EXPECT_TRUE(CachePut(bgf_handle.value(), GURL("http://example.com/bgf")));
1911 
1912   int64_t origin_size = GetOriginUsage(origin1_);
1913   EXPECT_LT(0, origin_size);
1914 
1915   EXPECT_EQ(origin_size, GetSizeThenCloseAllCaches(origin1_));
1916   EXPECT_FALSE(CachePut(public_handle.value(), GURL("http://example.com/baz")));
1917 }
1918 
TEST_P(CacheStorageManagerLegacyOnlyTestP,GetSizeThenCloseAllCachesAfterDelete)1919 TEST_P(CacheStorageManagerLegacyOnlyTestP,
1920        GetSizeThenCloseAllCachesAfterDelete) {
1921   // Tests that doomed caches are also deleted by GetSizeThenCloseAllCaches.
1922   EXPECT_TRUE(Open(origin1_, "foo"));
1923   EXPECT_TRUE(
1924       CachePut(callback_cache_handle_.value(), GURL("http://example.com/foo")));
1925 
1926   int64_t size_after_put = GetOriginUsage(origin1_);
1927   EXPECT_LT(0, size_after_put);
1928 
1929   // Keep a handle to a (soon-to-be deleted cache).
1930   auto saved_cache_handle = callback_cache_handle_.Clone();
1931 
1932   // Delete will only doom the cache because there is still at least one handle
1933   // referencing an open cache.
1934   EXPECT_TRUE(Delete(origin1_, "foo"));
1935 
1936   // GetSizeThenCloseAllCaches should close the cache (which is then deleted)
1937   // even though there is still an open handle.
1938   EXPECT_EQ(size_after_put, GetSizeThenCloseAllCaches(origin1_));
1939   EXPECT_EQ(0, GetOriginUsage(origin1_));
1940 }
1941 
TEST_F(CacheStorageManagerTest,DeleteUnreferencedCacheDirectories)1942 TEST_F(CacheStorageManagerTest, DeleteUnreferencedCacheDirectories) {
1943   // Create a referenced cache.
1944   EXPECT_TRUE(Open(origin1_, "foo"));
1945   EXPECT_TRUE(
1946       CachePut(callback_cache_handle_.value(), GURL("http://example.com/foo")));
1947 
1948   // Create an unreferenced directory next to the referenced one.
1949   auto* legacy_manager =
1950       static_cast<LegacyCacheStorageManager*>(cache_manager_.get());
1951   base::FilePath origin_path = LegacyCacheStorageManager::ConstructOriginPath(
1952       legacy_manager->root_path(), origin1_, CacheStorageOwner::kCacheAPI);
1953   base::FilePath unreferenced_path = origin_path.AppendASCII("bar");
1954   EXPECT_TRUE(CreateDirectory(unreferenced_path));
1955   EXPECT_TRUE(base::DirectoryExists(unreferenced_path));
1956 
1957   // Create a new StorageManager so that the next time the cache is opened
1958   // the unreferenced directory can be deleted.
1959   quota_manager_proxy_->SimulateQuotaManagerDestroyed();
1960   RecreateStorageManager();
1961 
1962   // Verify that the referenced cache still works.
1963   EXPECT_TRUE(Open(origin1_, "foo"));
1964   EXPECT_TRUE(CacheMatch(callback_cache_handle_.value(),
1965                          GURL("http://example.com/foo")));
1966 
1967   // Verify that the unreferenced cache is gone.
1968   EXPECT_FALSE(base::DirectoryExists(unreferenced_path));
1969 }
1970 
TEST_P(CacheStorageManagerTestP,OpenCacheStorageAccessed)1971 TEST_P(CacheStorageManagerTestP, OpenCacheStorageAccessed) {
1972   EXPECT_EQ(0, quota_manager_proxy_->notify_storage_accessed_count());
1973   EXPECT_TRUE(Open(origin1_, "foo"));
1974   EXPECT_EQ(1, quota_manager_proxy_->notify_storage_accessed_count());
1975 }
1976 
TEST_P(CacheStorageManagerTestP,HasStorageAccessed)1977 TEST_P(CacheStorageManagerTestP, HasStorageAccessed) {
1978   EXPECT_EQ(0, quota_manager_proxy_->notify_storage_accessed_count());
1979   EXPECT_FALSE(Has(origin1_, "foo"));
1980   EXPECT_EQ(1, quota_manager_proxy_->notify_storage_accessed_count());
1981 }
1982 
TEST_P(CacheStorageManagerTestP,DeleteStorageAccessed)1983 TEST_P(CacheStorageManagerTestP, DeleteStorageAccessed) {
1984   EXPECT_EQ(0, quota_manager_proxy_->notify_storage_accessed_count());
1985   EXPECT_FALSE(Delete(origin1_, "foo"));
1986   EXPECT_EQ(1, quota_manager_proxy_->notify_storage_accessed_count());
1987 }
1988 
TEST_P(CacheStorageManagerTestP,KeysStorageAccessed)1989 TEST_P(CacheStorageManagerTestP, KeysStorageAccessed) {
1990   EXPECT_EQ(0, quota_manager_proxy_->notify_storage_accessed_count());
1991   EXPECT_EQ(0u, Keys(origin1_));
1992   EXPECT_EQ(1, quota_manager_proxy_->notify_storage_accessed_count());
1993 }
1994 
TEST_P(CacheStorageManagerTestP,MatchCacheStorageAccessed)1995 TEST_P(CacheStorageManagerTestP, MatchCacheStorageAccessed) {
1996   EXPECT_EQ(0, quota_manager_proxy_->notify_storage_accessed_count());
1997   EXPECT_FALSE(StorageMatch(origin1_, "foo", GURL("http://example.com/foo")));
1998   EXPECT_EQ(1, quota_manager_proxy_->notify_storage_accessed_count());
1999 }
2000 
TEST_P(CacheStorageManagerTestP,MatchAllCachesStorageAccessed)2001 TEST_P(CacheStorageManagerTestP, MatchAllCachesStorageAccessed) {
2002   EXPECT_EQ(0, quota_manager_proxy_->notify_storage_accessed_count());
2003   EXPECT_FALSE(StorageMatchAll(origin1_, GURL("http://example.com/foo")));
2004   EXPECT_EQ(1, quota_manager_proxy_->notify_storage_accessed_count());
2005 }
2006 
TEST_P(CacheStorageManagerLegacyOnlyTestP,SizeStorageAccessed)2007 TEST_P(CacheStorageManagerLegacyOnlyTestP, SizeStorageAccessed) {
2008   EXPECT_EQ(0, Size(origin1_));
2009   // Size is not part of the web API and should not notify the quota manager of
2010   // an access.
2011   EXPECT_EQ(0, quota_manager_proxy_->notify_storage_accessed_count());
2012 }
2013 
TEST_P(CacheStorageManagerLegacyOnlyTestP,SizeThenCloseStorageAccessed)2014 TEST_P(CacheStorageManagerLegacyOnlyTestP, SizeThenCloseStorageAccessed) {
2015   EXPECT_EQ(0, GetSizeThenCloseAllCaches(origin1_));
2016   // GetSizeThenCloseAllCaches is not part of the web API and should not notify
2017   // the quota manager of an access.
2018   EXPECT_EQ(0, quota_manager_proxy_->notify_storage_accessed_count());
2019 }
2020 
TEST_P(CacheStorageManagerTestP,NotifyCacheListChanged_Created)2021 TEST_P(CacheStorageManagerTestP, NotifyCacheListChanged_Created) {
2022   TestCacheStorageObserver observer;
2023   observers_->AddObserver(&observer);
2024 
2025   EXPECT_EQ(0, observer.notify_list_changed_count);
2026   EXPECT_TRUE(Open(origin1_, "foo"));
2027   observer.Wait();
2028   EXPECT_EQ(1, observer.notify_list_changed_count);
2029   EXPECT_TRUE(
2030       CachePut(callback_cache_handle_.value(), GURL("http://example.com/foo")));
2031   observer.Wait();
2032   EXPECT_EQ(1, observer.notify_list_changed_count);
2033 }
2034 
TEST_P(CacheStorageManagerTestP,NotifyCacheListChanged_Deleted)2035 TEST_P(CacheStorageManagerTestP, NotifyCacheListChanged_Deleted) {
2036   TestCacheStorageObserver observer;
2037   observers_->AddObserver(&observer);
2038 
2039   EXPECT_EQ(0, observer.notify_list_changed_count);
2040   EXPECT_FALSE(Delete(origin1_, "foo"));
2041   // Give any unexpected observer tasks a chance to run.
2042   base::RunLoop().RunUntilIdle();
2043   EXPECT_EQ(0, observer.notify_list_changed_count);
2044   EXPECT_TRUE(Open(origin1_, "foo"));
2045   observer.Wait();
2046   EXPECT_EQ(1, observer.notify_list_changed_count);
2047   EXPECT_TRUE(Delete(origin1_, "foo"));
2048   observer.Wait();
2049   EXPECT_EQ(2, observer.notify_list_changed_count);
2050 }
2051 
TEST_P(CacheStorageManagerTestP,NotifyCacheListChanged_DeletedThenCreated)2052 TEST_P(CacheStorageManagerTestP, NotifyCacheListChanged_DeletedThenCreated) {
2053   TestCacheStorageObserver observer;
2054   observers_->AddObserver(&observer);
2055 
2056   EXPECT_EQ(0, observer.notify_list_changed_count);
2057   EXPECT_TRUE(Open(origin1_, "foo"));
2058   observer.Wait();
2059   EXPECT_EQ(1, observer.notify_list_changed_count);
2060   EXPECT_TRUE(Delete(origin1_, "foo"));
2061   observer.Wait();
2062   EXPECT_EQ(2, observer.notify_list_changed_count);
2063   EXPECT_TRUE(Open(origin2_, "foo2"));
2064   observer.Wait();
2065   EXPECT_EQ(3, observer.notify_list_changed_count);
2066 }
2067 
TEST_P(CacheStorageManagerTestP,NotifyCacheContentChanged_PutEntry)2068 TEST_P(CacheStorageManagerTestP, NotifyCacheContentChanged_PutEntry) {
2069   TestCacheStorageObserver observer;
2070   observers_->AddObserver(&observer);
2071 
2072   EXPECT_EQ(0, observer.notify_content_changed_count);
2073   EXPECT_TRUE(Open(origin1_, "foo"));
2074   observer.Wait();
2075   EXPECT_EQ(0, observer.notify_content_changed_count);
2076   EXPECT_TRUE(
2077       CachePut(callback_cache_handle_.value(), GURL("http://example.com/foo")));
2078   observer.Wait();
2079   EXPECT_EQ(1, observer.notify_content_changed_count);
2080   EXPECT_TRUE(CachePut(callback_cache_handle_.value(),
2081                        GURL("http://example.com/foo1")));
2082   observer.Wait();
2083   EXPECT_TRUE(CachePut(callback_cache_handle_.value(),
2084                        GURL("http://example.com/foo2")));
2085   observer.Wait();
2086   EXPECT_EQ(3, observer.notify_content_changed_count);
2087 }
2088 
TEST_P(CacheStorageManagerTestP,NotifyCacheContentChanged_DeleteEntry)2089 TEST_P(CacheStorageManagerTestP, NotifyCacheContentChanged_DeleteEntry) {
2090   TestCacheStorageObserver observer;
2091   observers_->AddObserver(&observer);
2092 
2093   EXPECT_EQ(0, observer.notify_content_changed_count);
2094   EXPECT_FALSE(Delete(origin1_, "foo"));
2095   base::RunLoop().RunUntilIdle();
2096   EXPECT_EQ(0, observer.notify_content_changed_count);
2097   EXPECT_TRUE(Open(origin1_, "foo"));
2098   observer.Wait();
2099   EXPECT_EQ(0, observer.notify_content_changed_count);
2100   EXPECT_TRUE(
2101       CachePut(callback_cache_handle_.value(), GURL("http://example.com/foo")));
2102   observer.Wait();
2103   EXPECT_EQ(1, observer.notify_content_changed_count);
2104   EXPECT_TRUE(CacheDelete(callback_cache_handle_.value(),
2105                           GURL("http://example.com/foo")));
2106   observer.Wait();
2107   EXPECT_EQ(2, observer.notify_content_changed_count);
2108   EXPECT_FALSE(CacheDelete(callback_cache_handle_.value(),
2109                            GURL("http://example.com/foo")));
2110   // Give any unexpected observer tasks a chance to run.
2111   base::RunLoop().RunUntilIdle();
2112   EXPECT_EQ(2, observer.notify_content_changed_count);
2113 }
2114 
TEST_P(CacheStorageManagerTestP,NotifyCacheContentChanged_DeleteThenPutEntry)2115 TEST_P(CacheStorageManagerTestP, NotifyCacheContentChanged_DeleteThenPutEntry) {
2116   TestCacheStorageObserver observer;
2117   observers_->AddObserver(&observer);
2118 
2119   EXPECT_EQ(0, observer.notify_content_changed_count);
2120   EXPECT_TRUE(Open(origin1_, "foo"));
2121   observer.Wait();
2122   EXPECT_EQ(0, observer.notify_content_changed_count);
2123   EXPECT_TRUE(
2124       CachePut(callback_cache_handle_.value(), GURL("http://example.com/foo")));
2125   observer.Wait();
2126   EXPECT_EQ(1, observer.notify_content_changed_count);
2127   EXPECT_TRUE(CacheDelete(callback_cache_handle_.value(),
2128                           GURL("http://example.com/foo")));
2129   observer.Wait();
2130   EXPECT_EQ(2, observer.notify_content_changed_count);
2131   EXPECT_TRUE(
2132       CachePut(callback_cache_handle_.value(), GURL("http://example.com/foo")));
2133   observer.Wait();
2134   EXPECT_EQ(3, observer.notify_content_changed_count);
2135   EXPECT_TRUE(CacheDelete(callback_cache_handle_.value(),
2136                           GURL("http://example.com/foo")));
2137   observer.Wait();
2138   EXPECT_EQ(4, observer.notify_content_changed_count);
2139 }
2140 
TEST_P(CacheStorageManagerTestP,StorageMatch_IgnoreSearch)2141 TEST_P(CacheStorageManagerTestP, StorageMatch_IgnoreSearch) {
2142   EXPECT_TRUE(Open(origin1_, "foo"));
2143   EXPECT_TRUE(CachePut(callback_cache_handle_.value(),
2144                        GURL("http://example.com/foo?bar")));
2145 
2146   EXPECT_FALSE(StorageMatch(origin1_, "foo", GURL("http://example.com/foo")));
2147 
2148   blink::mojom::CacheQueryOptionsPtr match_options =
2149       blink::mojom::CacheQueryOptions::New();
2150   match_options->ignore_search = true;
2151   EXPECT_TRUE(StorageMatch(origin1_, "foo", GURL("http://example.com/foo"),
2152                            std::move(match_options)));
2153 }
2154 
TEST_P(CacheStorageManagerTestP,StorageMatch_IgnoreMethod)2155 TEST_P(CacheStorageManagerTestP, StorageMatch_IgnoreMethod) {
2156   GURL url = GURL("http://example.com/foo");
2157   EXPECT_TRUE(Open(origin1_, "foo"));
2158   EXPECT_TRUE(CachePut(callback_cache_handle_.value(), url));
2159 
2160   auto post_request = blink::mojom::FetchAPIRequest::New();
2161   post_request->url = url;
2162   post_request->method = "POST";
2163   EXPECT_FALSE(StorageMatchWithRequest(
2164       origin1_, "foo",
2165       BackgroundFetchSettledFetch::CloneRequest(post_request)));
2166 
2167   blink::mojom::CacheQueryOptionsPtr match_options =
2168       blink::mojom::CacheQueryOptions::New();
2169   match_options->ignore_method = true;
2170   EXPECT_TRUE(StorageMatchWithRequest(origin1_, "foo", std::move(post_request),
2171                                       std::move(match_options)));
2172 }
2173 
TEST_P(CacheStorageManagerTestP,StorageMatch_IgnoreVary)2174 TEST_P(CacheStorageManagerTestP, StorageMatch_IgnoreVary) {
2175   GURL url = GURL("http://example.com/foo");
2176   EXPECT_TRUE(Open(origin1_, "foo"));
2177 
2178   auto request = blink::mojom::FetchAPIRequest::New();
2179   request->url = url;
2180   request->headers["vary_foo"] = "foo";
2181   // |request_1| and |request_2| has the same url and headers.
2182   auto request_1 = BackgroundFetchSettledFetch::CloneRequest(request);
2183   auto request_2 = BackgroundFetchSettledFetch::CloneRequest(request);
2184 
2185   ResponseHeaderMap response_headers;
2186   response_headers["vary"] = "vary_foo";
2187 
2188   EXPECT_TRUE(CachePutWithRequestAndHeaders(callback_cache_handle_.value(),
2189                                             std::move(request_1),
2190                                             std::move(response_headers)));
2191   EXPECT_TRUE(StorageMatchWithRequest(origin1_, "foo", std::move(request_2)));
2192 
2193   request->headers["vary_foo"] = "bar";
2194   // |request_3| and |request_4| has the same url and headers.
2195   auto request_3 = BackgroundFetchSettledFetch::CloneRequest(request);
2196   auto request_4 = BackgroundFetchSettledFetch::CloneRequest(request);
2197   EXPECT_FALSE(StorageMatchWithRequest(origin1_, "foo", std::move(request_3)));
2198 
2199   blink::mojom::CacheQueryOptionsPtr match_options =
2200       blink::mojom::CacheQueryOptions::New();
2201   match_options->ignore_vary = true;
2202   EXPECT_TRUE(StorageMatchWithRequest(origin1_, "foo", std::move(request_4),
2203                                       std::move(match_options)));
2204 }
2205 
TEST_P(CacheStorageManagerTestP,StorageMatchAll_IgnoreSearch)2206 TEST_P(CacheStorageManagerTestP, StorageMatchAll_IgnoreSearch) {
2207   EXPECT_TRUE(Open(origin1_, "foo"));
2208   EXPECT_TRUE(CachePut(callback_cache_handle_.value(),
2209                        GURL("http://example.com/foo?bar")));
2210 
2211   EXPECT_FALSE(StorageMatchAll(origin1_, GURL("http://example.com/foo")));
2212 
2213   blink::mojom::CacheQueryOptionsPtr match_options =
2214       blink::mojom::CacheQueryOptions::New();
2215   match_options->ignore_search = true;
2216   EXPECT_TRUE(StorageMatchAll(origin1_, GURL("http://example.com/foo"),
2217                               std::move(match_options)));
2218 }
2219 
TEST_P(CacheStorageManagerTestP,StorageMatchAll_IgnoreMethod)2220 TEST_P(CacheStorageManagerTestP, StorageMatchAll_IgnoreMethod) {
2221   GURL url = GURL("http://example.com/foo");
2222   EXPECT_TRUE(Open(origin1_, "foo"));
2223   EXPECT_TRUE(CachePut(callback_cache_handle_.value(), url));
2224 
2225   auto post_request = blink::mojom::FetchAPIRequest::New();
2226   post_request->url = url;
2227   post_request->method = "POST";
2228   EXPECT_FALSE(StorageMatchAllWithRequest(
2229       origin1_, BackgroundFetchSettledFetch::CloneRequest(post_request)));
2230 
2231   blink::mojom::CacheQueryOptionsPtr match_options =
2232       blink::mojom::CacheQueryOptions::New();
2233   match_options->ignore_method = true;
2234   EXPECT_TRUE(StorageMatchAllWithRequest(origin1_, std::move(post_request),
2235                                          std::move(match_options)));
2236 }
2237 
TEST_P(CacheStorageManagerTestP,StorageMatchAll_IgnoreVary)2238 TEST_P(CacheStorageManagerTestP, StorageMatchAll_IgnoreVary) {
2239   GURL url = GURL("http://example.com/foo");
2240   EXPECT_TRUE(Open(origin1_, "foo"));
2241 
2242   auto request = blink::mojom::FetchAPIRequest::New();
2243   request->url = url;
2244   request->headers["vary_foo"] = "foo";
2245   // |request_1| and |request_2| has the same url and headers.
2246   auto request_1 = BackgroundFetchSettledFetch::CloneRequest(request);
2247   auto request_2 = BackgroundFetchSettledFetch::CloneRequest(request);
2248 
2249   ResponseHeaderMap response_headers;
2250   response_headers["vary"] = "vary_foo";
2251 
2252   EXPECT_TRUE(CachePutWithRequestAndHeaders(
2253       callback_cache_handle_.value(), std::move(request_1), response_headers));
2254   EXPECT_TRUE(StorageMatchAllWithRequest(origin1_, std::move(request_2)));
2255 
2256   request->headers["vary_foo"] = "bar";
2257   // |request_3| and |request_4| has the same url and headers.
2258   auto request_3 = BackgroundFetchSettledFetch::CloneRequest(request);
2259   auto request_4 = BackgroundFetchSettledFetch::CloneRequest(request);
2260   EXPECT_FALSE(StorageMatchAllWithRequest(origin1_, std::move(request_3)));
2261 
2262   blink::mojom::CacheQueryOptionsPtr match_options =
2263       blink::mojom::CacheQueryOptions::New();
2264   match_options->ignore_vary = true;
2265   EXPECT_TRUE(StorageMatchAllWithRequest(origin1_, std::move(request_4),
2266                                          std::move(match_options)));
2267 }
2268 
TEST_P(CacheStorageManagerTestP,StorageWriteToCache)2269 TEST_P(CacheStorageManagerTestP, StorageWriteToCache) {
2270   EXPECT_TRUE(Open(origin1_, "foo", CacheStorageOwner::kBackgroundFetch));
2271 
2272   EXPECT_TRUE(Write(origin1_, CacheStorageOwner::kBackgroundFetch, "foo",
2273                     "http://example.com/foo"));
2274 
2275   // Match request we just wrote.
2276   EXPECT_TRUE(StorageMatch(origin1_, "foo", GURL("http://example.com/foo"),
2277                            nullptr, CacheStorageOwner::kBackgroundFetch));
2278 
2279   // Don't match with different origin.
2280   EXPECT_FALSE(StorageMatch(origin2_, "foo", GURL("http://example.com/foo"),
2281                             nullptr, CacheStorageOwner::kBackgroundFetch));
2282   // Don't match with different cache name.
2283   EXPECT_FALSE(StorageMatch(origin1_, "bar", GURL("http://example.com/foo"),
2284                             nullptr, CacheStorageOwner::kBackgroundFetch));
2285   // Don't match with different request.
2286   EXPECT_FALSE(StorageMatch(origin1_, "foo", GURL("http://example.com/bar"),
2287                             nullptr, CacheStorageOwner::kBackgroundFetch));
2288   // Don't match with different owner.
2289   EXPECT_FALSE(StorageMatch(origin1_, "foo", GURL("http://example.com/foo"),
2290                             nullptr, CacheStorageOwner::kCacheAPI));
2291 }
2292 
TEST_F(CacheStorageManagerTest,WriteIndexOnlyScheduledWhenValueChanges)2293 TEST_F(CacheStorageManagerTest, WriteIndexOnlyScheduledWhenValueChanges) {
2294   const char* kCacheName = "WriteIndexOnlyScheduledWhenValueChanges";
2295 
2296   // In order to make sure operations are flushed through the various scheduler
2297   // queues we match against a non-existant URL.  This should always return
2298   // false from Match() and when it completes we know any previous operations
2299   // have completed as well.
2300   const GURL kNonExistant("http://example.com/bar");
2301   const GURL kResource("https://example.com/foo");
2302 
2303   // Opening a new cache should require writing the index.
2304   EXPECT_TRUE(Open(origin1_, kCacheName));
2305   EXPECT_FALSE(CacheMatch(callback_cache_handle_.value(), kNonExistant));
2306   EXPECT_TRUE(FlushCacheStorageIndex(origin1_));
2307 
2308   // Allow the cache to close.
2309   callback_cache_handle_ = CacheStorageCacheHandle();
2310 
2311   // Opening an existing cache should *not* require writing the index.
2312   EXPECT_TRUE(Open(origin1_, kCacheName));
2313   EXPECT_FALSE(CacheMatch(callback_cache_handle_.value(), kNonExistant));
2314   EXPECT_FALSE(FlushCacheStorageIndex(origin1_));
2315 
2316   // Putting a value in the cache should require writing the index.
2317   EXPECT_TRUE(CachePut(callback_cache_handle_.value(), kResource));
2318   EXPECT_TRUE(FlushCacheStorageIndex(origin1_));
2319 
2320   // Allow the cache to close.
2321   callback_cache_handle_ = CacheStorageCacheHandle();
2322 
2323   // Opening an existing cache after writing a value should *not* require
2324   // writing the index.
2325   EXPECT_TRUE(Open(origin1_, kCacheName));
2326   EXPECT_FALSE(CacheMatch(callback_cache_handle_.value(), kNonExistant));
2327   EXPECT_TRUE(CacheMatch(callback_cache_handle_.value(), kResource));
2328   EXPECT_FALSE(FlushCacheStorageIndex(origin1_));
2329 }
2330 
TEST_P(CacheStorageManagerTestP,SlowPutCompletesWithoutExternalRef)2331 TEST_P(CacheStorageManagerTestP, SlowPutCompletesWithoutExternalRef) {
2332   EXPECT_TRUE(Open(origin1_, "foo"));
2333 
2334   auto request = blink::mojom::FetchAPIRequest::New();
2335   request->url = GURL("http://example.com/foo");
2336 
2337   // Start defining a blob for the response body.
2338   std::string body_data("hello world");
2339   auto blob = blink::mojom::SerializedBlob::New();
2340   blob->uuid = "mock blob";
2341   blob->size = body_data.length();
2342 
2343   // Provide a fake blob implementation that delays completion.  This will
2344   // allow us to pause the writing operation so we can drop the external
2345   // reference.
2346   base::RunLoop blob_loop;
2347   DelayedBlob delayed_blob(blob->blob.InitWithNewPipeAndPassReceiver(),
2348                            body_data, blob_loop.QuitClosure());
2349 
2350   // Begin the operation to write the blob into the cache.
2351   base::RunLoop cache_loop;
2352   CachePutWithStatusCodeAndBlobInternal(callback_cache_handle_.value(),
2353                                         std::move(request), 200,
2354                                         std::move(blob), &cache_loop);
2355 
2356   // Wait for blob's ReadAll() method to be called.
2357   blob_loop.Run();
2358 
2359   // Drop the external reference to the cache.  The operation should hold
2360   // itself alive, but previous versions of the code would destroy the cache
2361   // immediately at this step.
2362   callback_cache_handle_ = CacheStorageCacheHandle();
2363 
2364   // Signal the blob to complete reading.
2365   delayed_blob.Resume();
2366 
2367   // Wait for the cache write operation to be complete and verify that it
2368   // succeeded.
2369   cache_loop.Run();
2370   EXPECT_EQ(CacheStorageError::kSuccess, callback_error_);
2371 }
2372 
2373 class CacheStorageQuotaClientTest : public CacheStorageManagerTest {
2374  protected:
2375   CacheStorageQuotaClientTest() = default;
2376 
SetUp()2377   void SetUp() override {
2378     CacheStorageManagerTest::SetUp();
2379     quota_client_ = base::MakeRefCounted<CacheStorageQuotaClient>(
2380         cache_manager_, CacheStorageOwner::kCacheAPI);
2381   }
2382 
QuotaUsageCallback(base::RunLoop * run_loop,int64_t usage)2383   void QuotaUsageCallback(base::RunLoop* run_loop, int64_t usage) {
2384     callback_quota_usage_ = usage;
2385     run_loop->Quit();
2386   }
2387 
OriginsCallback(base::RunLoop * run_loop,const std::vector<url::Origin> & origins)2388   void OriginsCallback(base::RunLoop* run_loop,
2389                        const std::vector<url::Origin>& origins) {
2390     callback_origins_ = origins;
2391     run_loop->Quit();
2392   }
2393 
DeleteOriginCallback(base::RunLoop * run_loop,blink::mojom::QuotaStatusCode status)2394   void DeleteOriginCallback(base::RunLoop* run_loop,
2395                             blink::mojom::QuotaStatusCode status) {
2396     callback_status_ = status;
2397     run_loop->Quit();
2398   }
2399 
QuotaGetOriginUsage(const url::Origin & origin)2400   int64_t QuotaGetOriginUsage(const url::Origin& origin) {
2401     base::RunLoop loop;
2402     quota_client_->GetOriginUsage(
2403         origin, StorageType::kTemporary,
2404         base::BindOnce(&CacheStorageQuotaClientTest::QuotaUsageCallback,
2405                        base::Unretained(this), base::Unretained(&loop)));
2406     loop.Run();
2407     return callback_quota_usage_;
2408   }
2409 
QuotaGetOriginsForType()2410   size_t QuotaGetOriginsForType() {
2411     base::RunLoop loop;
2412     quota_client_->GetOriginsForType(
2413         StorageType::kTemporary,
2414         base::BindOnce(&CacheStorageQuotaClientTest::OriginsCallback,
2415                        base::Unretained(this), base::Unretained(&loop)));
2416     loop.Run();
2417     return callback_origins_.size();
2418   }
2419 
QuotaGetOriginsForHost(const std::string & host)2420   size_t QuotaGetOriginsForHost(const std::string& host) {
2421     base::RunLoop loop;
2422     quota_client_->GetOriginsForHost(
2423         StorageType::kTemporary, host,
2424         base::BindOnce(&CacheStorageQuotaClientTest::OriginsCallback,
2425                        base::Unretained(this), base::Unretained(&loop)));
2426     loop.Run();
2427     return callback_origins_.size();
2428   }
2429 
QuotaDeleteOriginData(const url::Origin & origin)2430   bool QuotaDeleteOriginData(const url::Origin& origin) {
2431     base::RunLoop loop;
2432     quota_client_->DeleteOriginData(
2433         origin, StorageType::kTemporary,
2434         base::BindOnce(&CacheStorageQuotaClientTest::DeleteOriginCallback,
2435                        base::Unretained(this), base::Unretained(&loop)));
2436     loop.Run();
2437     return callback_status_ == blink::mojom::QuotaStatusCode::kOk;
2438   }
2439 
2440   scoped_refptr<CacheStorageQuotaClient> quota_client_;
2441 
2442   blink::mojom::QuotaStatusCode callback_status_;
2443   int64_t callback_quota_usage_ = 0;
2444   std::vector<url::Origin> callback_origins_;
2445 
2446  private:
2447   DISALLOW_COPY_AND_ASSIGN(CacheStorageQuotaClientTest);
2448 };
2449 
2450 class CacheStorageQuotaClientDiskOnlyTest : public CacheStorageQuotaClientTest {
2451  public:
MemoryOnly()2452   bool MemoryOnly() override { return false; }
2453 };
2454 
2455 class CacheStorageQuotaClientTestP : public CacheStorageQuotaClientTest,
2456                                      public testing::WithParamInterface<Param> {
MemoryOnly()2457   bool MemoryOnly() override {
2458     return GetParam().storage_ == TestStorage::kMemory;
2459   }
ManagerType()2460   TestManager ManagerType() override { return GetParam().manager_; }
2461 };
2462 
TEST_P(CacheStorageQuotaClientTestP,QuotaGetOriginUsage)2463 TEST_P(CacheStorageQuotaClientTestP, QuotaGetOriginUsage) {
2464   EXPECT_EQ(0, QuotaGetOriginUsage(origin1_));
2465   EXPECT_TRUE(Open(origin1_, "foo"));
2466   EXPECT_TRUE(
2467       CachePut(callback_cache_handle_.value(), GURL("http://example.com/foo")));
2468   EXPECT_LT(0, QuotaGetOriginUsage(origin1_));
2469 }
2470 
TEST_P(CacheStorageQuotaClientTestP,QuotaGetOriginsForType)2471 TEST_P(CacheStorageQuotaClientTestP, QuotaGetOriginsForType) {
2472   EXPECT_EQ(0u, QuotaGetOriginsForType());
2473   EXPECT_TRUE(Open(origin1_, "foo"));
2474   EXPECT_TRUE(Open(origin1_, "bar"));
2475   EXPECT_TRUE(Open(origin2_, "foo"));
2476   EXPECT_EQ(2u, QuotaGetOriginsForType());
2477 }
2478 
TEST_P(CacheStorageQuotaClientTestP,QuotaGetOriginsForTypeDifferentOwners)2479 TEST_P(CacheStorageQuotaClientTestP, QuotaGetOriginsForTypeDifferentOwners) {
2480   EXPECT_EQ(0u, QuotaGetOriginsForType());
2481   EXPECT_TRUE(Open(origin1_, "foo"));
2482   // The |quota_client_| is registered for CacheStorageOwner::kCacheAPI, so this
2483   // Open is ignored.
2484   EXPECT_TRUE(Open(origin2_, "bar", CacheStorageOwner::kBackgroundFetch));
2485   EXPECT_EQ(1u, QuotaGetOriginsForType());
2486 }
2487 
TEST_P(CacheStorageQuotaClientTestP,QuotaGetOriginsForHost)2488 TEST_P(CacheStorageQuotaClientTestP, QuotaGetOriginsForHost) {
2489   EXPECT_EQ(0u, QuotaGetOriginsForHost("example.com"));
2490   EXPECT_TRUE(
2491       Open(url::Origin::Create(GURL("http://example.com:8080")), "foo"));
2492   EXPECT_TRUE(
2493       Open(url::Origin::Create(GURL("http://example.com:9000")), "foo"));
2494   EXPECT_TRUE(Open(url::Origin::Create(GURL("ftp://example.com")), "foo"));
2495   EXPECT_TRUE(Open(url::Origin::Create(GURL("http://example2.com")), "foo"));
2496   EXPECT_EQ(3u, QuotaGetOriginsForHost("example.com"));
2497   EXPECT_EQ(1u, QuotaGetOriginsForHost("example2.com"));
2498   EXPECT_THAT(
2499       callback_origins_,
2500       testing::Contains(url::Origin::Create(GURL("http://example2.com"))));
2501   EXPECT_EQ(0u, QuotaGetOriginsForHost("unknown.com"));
2502 }
2503 
TEST_P(CacheStorageQuotaClientTestP,QuotaDeleteOriginData)2504 TEST_P(CacheStorageQuotaClientTestP, QuotaDeleteOriginData) {
2505   EXPECT_EQ(0, QuotaGetOriginUsage(origin1_));
2506   EXPECT_TRUE(Open(origin1_, "foo"));
2507   // Call put to test that initialized caches are properly deleted too.
2508   EXPECT_TRUE(
2509       CachePut(callback_cache_handle_.value(), GURL("http://example.com/foo")));
2510   EXPECT_TRUE(Open(origin1_, "bar"));
2511   EXPECT_TRUE(Open(origin2_, "baz"));
2512 
2513   int64_t origin1_size = QuotaGetOriginUsage(origin1_);
2514   EXPECT_LT(0, origin1_size);
2515 
2516   EXPECT_TRUE(QuotaDeleteOriginData(origin1_));
2517 
2518   EXPECT_EQ(-1 * origin1_size, quota_manager_proxy_->last_notified_delta());
2519   EXPECT_EQ(0, QuotaGetOriginUsage(origin1_));
2520   EXPECT_FALSE(Has(origin1_, "foo"));
2521   EXPECT_FALSE(Has(origin1_, "bar"));
2522   EXPECT_TRUE(Has(origin2_, "baz"));
2523   EXPECT_TRUE(Open(origin1_, "foo"));
2524 }
2525 
TEST_P(CacheStorageQuotaClientTestP,QuotaDeleteEmptyOrigin)2526 TEST_P(CacheStorageQuotaClientTestP, QuotaDeleteEmptyOrigin) {
2527   EXPECT_TRUE(QuotaDeleteOriginData(origin1_));
2528 }
2529 
TEST_F(CacheStorageQuotaClientDiskOnlyTest,QuotaDeleteUnloadedOriginData)2530 TEST_F(CacheStorageQuotaClientDiskOnlyTest, QuotaDeleteUnloadedOriginData) {
2531   EXPECT_TRUE(Open(origin1_, "foo"));
2532   // Call put to test that initialized caches are properly deleted too.
2533   EXPECT_TRUE(
2534       CachePut(callback_cache_handle_.value(), GURL("http://example.com/foo")));
2535 
2536   // Close the cache backend so that it writes out its index to disk.
2537   base::RunLoop run_loop;
2538   LegacyCacheStorageCache::From(callback_cache_handle_)
2539       ->Close(run_loop.QuitClosure());
2540   run_loop.Run();
2541 
2542   // Create a new CacheStorageManager that hasn't yet loaded the origin.
2543   quota_manager_proxy_->SimulateQuotaManagerDestroyed();
2544   RecreateStorageManager();
2545   quota_client_ = base::MakeRefCounted<CacheStorageQuotaClient>(
2546       cache_manager_, CacheStorageOwner::kCacheAPI);
2547 
2548   EXPECT_TRUE(QuotaDeleteOriginData(origin1_));
2549   EXPECT_EQ(0, QuotaGetOriginUsage(origin1_));
2550 }
2551 
2552 INSTANTIATE_TEST_SUITE_P(
2553     CacheStorageManagerTests,
2554     CacheStorageManagerTestP,
2555     ::testing::Values(Param(TestManager::kLegacy, TestStorage::kMemory),
2556                       Param(TestManager::kLegacy, TestStorage::kDisk),
2557                       Param(TestManager::kCrossSequence, TestStorage::kMemory),
2558                       Param(TestManager::kCrossSequence, TestStorage::kDisk)));
2559 
2560 INSTANTIATE_TEST_SUITE_P(CacheStorageManagerTests,
2561                          CacheStorageManagerLegacyOnlyTestP,
2562                          ::testing::Values(TestStorage::kMemory,
2563                                            TestStorage::kDisk));
2564 
2565 INSTANTIATE_TEST_SUITE_P(
2566     CacheStorageQuotaClientTests,
2567     CacheStorageQuotaClientTestP,
2568     ::testing::Values(Param(TestManager::kLegacy, TestStorage::kMemory),
2569                       Param(TestManager::kLegacy, TestStorage::kDisk),
2570                       Param(TestManager::kCrossSequence, TestStorage::kMemory),
2571                       Param(TestManager::kCrossSequence, TestStorage::kDisk)));
2572 
2573 }  // namespace cache_storage_manager_unittest
2574 }  // namespace content
2575