Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1355)

Side by Side Diff: content/browser/cache_storage/cache_storage_cache_unittest.cc

Issue 2901083002: [CacheStorage] Pad and bin opaque resource sizes. (Closed)
Patch Set: Creating single padding key per session. Created 3 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "content/browser/cache_storage/cache_storage_cache.h" 5 #include "content/browser/cache_storage/cache_storage_cache.h"
6 6
7 #include <stddef.h> 7 #include <stddef.h>
8 #include <stdint.h> 8 #include <stdint.h>
9 9
10 #include <memory> 10 #include <memory>
(...skipping 11 matching lines...) Expand all
22 #include "base/threading/thread_task_runner_handle.h" 22 #include "base/threading/thread_task_runner_handle.h"
23 #include "content/browser/blob_storage/chrome_blob_storage_context.h" 23 #include "content/browser/blob_storage/chrome_blob_storage_context.h"
24 #include "content/browser/cache_storage/cache_storage_cache_handle.h" 24 #include "content/browser/cache_storage/cache_storage_cache_handle.h"
25 #include "content/common/cache_storage/cache_storage_types.h" 25 #include "content/common/cache_storage/cache_storage_types.h"
26 #include "content/common/service_worker/service_worker_types.h" 26 #include "content/common/service_worker/service_worker_types.h"
27 #include "content/public/browser/browser_thread.h" 27 #include "content/public/browser/browser_thread.h"
28 #include "content/public/browser/storage_partition.h" 28 #include "content/public/browser/storage_partition.h"
29 #include "content/public/common/referrer.h" 29 #include "content/public/common/referrer.h"
30 #include "content/public/test/test_browser_context.h" 30 #include "content/public/test/test_browser_context.h"
31 #include "content/public/test/test_browser_thread_bundle.h" 31 #include "content/public/test/test_browser_thread_bundle.h"
32 #include "crypto/symmetric_key.h"
32 #include "net/base/test_completion_callback.h" 33 #include "net/base/test_completion_callback.h"
33 #include "net/url_request/url_request_context.h" 34 #include "net/url_request/url_request_context.h"
34 #include "net/url_request/url_request_context_getter.h" 35 #include "net/url_request/url_request_context_getter.h"
35 #include "net/url_request/url_request_job_factory_impl.h" 36 #include "net/url_request/url_request_job_factory_impl.h"
36 #include "storage/browser/blob/blob_data_builder.h" 37 #include "storage/browser/blob/blob_data_builder.h"
37 #include "storage/browser/blob/blob_data_handle.h" 38 #include "storage/browser/blob/blob_data_handle.h"
38 #include "storage/browser/blob/blob_data_snapshot.h" 39 #include "storage/browser/blob/blob_data_snapshot.h"
39 #include "storage/browser/blob/blob_storage_context.h" 40 #include "storage/browser/blob/blob_storage_context.h"
40 #include "storage/browser/blob/blob_url_request_job_factory.h" 41 #include "storage/browser/blob/blob_url_request_job_factory.h"
41 #include "storage/browser/quota/quota_manager_proxy.h" 42 #include "storage/browser/quota/quota_manager_proxy.h"
(...skipping 15 matching lines...) Expand all
57 // The FileSystemContext and thread task runner are not actually used but a 58 // The FileSystemContext and thread task runner are not actually used but a
58 // task runner is needed to avoid a DCHECK in BlobURLRequestJob ctor. 59 // task runner is needed to avoid a DCHECK in BlobURLRequestJob ctor.
59 return base::WrapUnique(new storage::BlobProtocolHandler( 60 return base::WrapUnique(new storage::BlobProtocolHandler(
60 blob_storage_context, NULL, base::ThreadTaskRunnerHandle::Get().get())); 61 blob_storage_context, NULL, base::ThreadTaskRunnerHandle::Get().get()));
61 } 62 }
62 63
63 // A disk_cache::Backend wrapper that can delay operations. 64 // A disk_cache::Backend wrapper that can delay operations.
64 class DelayableBackend : public disk_cache::Backend { 65 class DelayableBackend : public disk_cache::Backend {
65 public: 66 public:
66 explicit DelayableBackend(std::unique_ptr<disk_cache::Backend> backend) 67 explicit DelayableBackend(std::unique_ptr<disk_cache::Backend> backend)
67 : backend_(std::move(backend)), delay_doom_(false) {} 68 : backend_(std::move(backend)), delay_open_entry_(false) {}
68 69
69 // disk_cache::Backend overrides 70 // disk_cache::Backend overrides
70 net::CacheType GetCacheType() const override { 71 net::CacheType GetCacheType() const override {
71 return backend_->GetCacheType(); 72 return backend_->GetCacheType();
72 } 73 }
73 int32_t GetEntryCount() const override { return backend_->GetEntryCount(); } 74 int32_t GetEntryCount() const override { return backend_->GetEntryCount(); }
74 int OpenEntry(const std::string& key, 75 int OpenEntry(const std::string& key,
75 disk_cache::Entry** entry, 76 disk_cache::Entry** entry,
76 const CompletionCallback& callback) override { 77 const CompletionCallback& callback) override {
78 if (delay_open_entry_ && open_entry_callback_.is_null()) {
79 open_entry_callback_ = base::Bind(&DelayableBackend::OpenEntryDelayedImpl,
80 base::Unretained(this), key,
81 base::Unretained(entry), callback);
82 return net::ERR_IO_PENDING;
83 }
77 return backend_->OpenEntry(key, entry, callback); 84 return backend_->OpenEntry(key, entry, callback);
78 } 85 }
79 86
80 int CreateEntry(const std::string& key, 87 int CreateEntry(const std::string& key,
81 disk_cache::Entry** entry, 88 disk_cache::Entry** entry,
82 const CompletionCallback& callback) override { 89 const CompletionCallback& callback) override {
83 return backend_->CreateEntry(key, entry, callback); 90 return backend_->CreateEntry(key, entry, callback);
84 } 91 }
85 int DoomEntry(const std::string& key, 92 int DoomEntry(const std::string& key,
86 const CompletionCallback& callback) override { 93 const CompletionCallback& callback) override {
87 if (delay_doom_) {
88 doom_entry_callback_ = base::Bind(&DelayableBackend::DoomEntryDelayedImpl,
89 base::Unretained(this), key, callback);
90 return net::ERR_IO_PENDING;
91 }
92
93 return backend_->DoomEntry(key, callback); 94 return backend_->DoomEntry(key, callback);
94 } 95 }
95 int DoomAllEntries(const CompletionCallback& callback) override { 96 int DoomAllEntries(const CompletionCallback& callback) override {
96 return backend_->DoomAllEntries(callback); 97 return backend_->DoomAllEntries(callback);
97 } 98 }
98 int DoomEntriesBetween(base::Time initial_time, 99 int DoomEntriesBetween(base::Time initial_time,
99 base::Time end_time, 100 base::Time end_time,
100 const CompletionCallback& callback) override { 101 const CompletionCallback& callback) override {
101 return backend_->DoomEntriesBetween(initial_time, end_time, callback); 102 return backend_->DoomEntriesBetween(initial_time, end_time, callback);
102 } 103 }
(...skipping 15 matching lines...) Expand all
118 return backend_->OnExternalCacheHit(key); 119 return backend_->OnExternalCacheHit(key);
119 } 120 }
120 121
121 size_t DumpMemoryStats( 122 size_t DumpMemoryStats(
122 base::trace_event::ProcessMemoryDump* pmd, 123 base::trace_event::ProcessMemoryDump* pmd,
123 const std::string& parent_absolute_name) const override { 124 const std::string& parent_absolute_name) const override {
124 NOTREACHED(); 125 NOTREACHED();
125 return 0u; 126 return 0u;
126 } 127 }
127 128
128 // Call to continue a delayed doom. 129 // Call to continue a delayed call to OpenEntry.
129 void DoomEntryContinue() { 130 bool OpenEntryContinue() {
130 EXPECT_FALSE(doom_entry_callback_.is_null()); 131 if (open_entry_callback_.is_null())
131 doom_entry_callback_.Run(); 132 return false;
133 open_entry_callback_.Run();
134 return true;
132 } 135 }
133 136
134 void set_delay_doom(bool value) { delay_doom_ = value; } 137 void set_delay_open_entry(bool value) { delay_open_entry_ = value; }
135 138
136 private: 139 private:
137 void DoomEntryDelayedImpl(const std::string& key, 140 void OpenEntryDelayedImpl(const std::string& key,
141 disk_cache::Entry** entry,
138 const CompletionCallback& callback) { 142 const CompletionCallback& callback) {
139 int rv = backend_->DoomEntry(key, callback); 143 int rv = backend_->OpenEntry(key, entry, callback);
140 if (rv != net::ERR_IO_PENDING) 144 if (rv != net::ERR_IO_PENDING)
141 callback.Run(rv); 145 callback.Run(rv);
142 } 146 }
143 147
144 std::unique_ptr<disk_cache::Backend> backend_; 148 std::unique_ptr<disk_cache::Backend> backend_;
145 bool delay_doom_; 149 bool delay_open_entry_;
146 base::Closure doom_entry_callback_; 150 base::Closure open_entry_callback_;
147 }; 151 };
148 152
149 void CopyBody(const storage::BlobDataHandle& blob_handle, std::string* output) { 153 void CopyBody(const storage::BlobDataHandle& blob_handle, std::string* output) {
150 *output = std::string(); 154 *output = std::string();
151 std::unique_ptr<storage::BlobDataSnapshot> data = 155 std::unique_ptr<storage::BlobDataSnapshot> data =
152 blob_handle.CreateSnapshot(); 156 blob_handle.CreateSnapshot();
153 const auto& items = data->items(); 157 const auto& items = data->items();
154 for (const auto& item : items) { 158 for (const auto& item : items) {
155 switch (item->type()) { 159 switch (item->type()) {
156 case storage::DataElement::TYPE_BYTES: { 160 case storage::DataElement::TYPE_BYTES: {
(...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after
263 return expected_side_data == actual_body; 267 return expected_side_data == actual_body;
264 } 268 }
265 269
266 ServiceWorkerResponse SetCacheName(const ServiceWorkerResponse& original) { 270 ServiceWorkerResponse SetCacheName(const ServiceWorkerResponse& original) {
267 ServiceWorkerResponse result(original); 271 ServiceWorkerResponse result(original);
268 result.is_in_cache_storage = true; 272 result.is_in_cache_storage = true;
269 result.cache_storage_cache_name = kCacheName; 273 result.cache_storage_cache_name = kCacheName;
270 return result; 274 return result;
271 } 275 }
272 276
277 std::unique_ptr<crypto::SymmetricKey> CreateTestPaddingKey() {
278 return crypto::SymmetricKey::Import(crypto::SymmetricKey::HMAC_SHA1,
279 "abc123");
280 }
281
273 } // namespace 282 } // namespace
274 283
275 // A CacheStorageCache that can optionally delay during backend creation. 284 // A CacheStorageCache that can optionally delay during backend creation.
276 class TestCacheStorageCache : public CacheStorageCache { 285 class TestCacheStorageCache : public CacheStorageCache {
277 public: 286 public:
278 TestCacheStorageCache( 287 TestCacheStorageCache(
279 const GURL& origin, 288 const GURL& origin,
280 const std::string& cache_name, 289 const std::string& cache_name,
281 const base::FilePath& path, 290 const base::FilePath& path,
282 CacheStorage* cache_storage, 291 CacheStorage* cache_storage,
283 const scoped_refptr<net::URLRequestContextGetter>& request_context_getter, 292 const scoped_refptr<net::URLRequestContextGetter>& request_context_getter,
284 const scoped_refptr<storage::QuotaManagerProxy>& quota_manager_proxy, 293 const scoped_refptr<storage::QuotaManagerProxy>& quota_manager_proxy,
285 base::WeakPtr<storage::BlobStorageContext> blob_context) 294 base::WeakPtr<storage::BlobStorageContext> blob_context)
286 : CacheStorageCache(origin, 295 : CacheStorageCache(origin,
287 cache_name, 296 cache_name,
288 path, 297 path,
289 cache_storage, 298 cache_storage,
290 request_context_getter, 299 request_context_getter,
291 quota_manager_proxy, 300 quota_manager_proxy,
292 blob_context, 301 blob_context,
293 0 /* cache_size */), 302 0 /* cache_size */,
303 0 /* cache_padding */,
304 CreateTestPaddingKey()),
294 delay_backend_creation_(false) {} 305 delay_backend_creation_(false) {}
295 306
296 void CreateBackend(const ErrorCallback& callback) override { 307 void CreateBackend(const ErrorCallback& callback) override {
297 backend_creation_callback_ = callback; 308 backend_creation_callback_ = callback;
298 if (delay_backend_creation_) 309 if (delay_backend_creation_)
299 return; 310 return;
300 ContinueCreateBackend(); 311 ContinueCreateBackend();
301 } 312 }
302 313
303 void ContinueCreateBackend() { 314 void ContinueCreateBackend() {
(...skipping 1283 matching lines...) Expand 10 before | Expand all | Expand 10 after
1587 EXPECT_TRUE(Delete(no_body_request_)); 1598 EXPECT_TRUE(Delete(no_body_request_));
1588 EXPECT_EQ(0, Size()); 1599 EXPECT_EQ(0, Size());
1589 1600
1590 EXPECT_TRUE(Put(body_request_, body_response_)); 1601 EXPECT_TRUE(Put(body_request_, body_response_));
1591 EXPECT_LT(no_body_size, Size()); 1602 EXPECT_LT(no_body_size, Size());
1592 1603
1593 EXPECT_TRUE(Delete(body_request_)); 1604 EXPECT_TRUE(Delete(body_request_));
1594 EXPECT_EQ(0, Size()); 1605 EXPECT_EQ(0, Size());
1595 } 1606 }
1596 1607
1608 TEST_F(CacheStorageCacheTest, VerifyOpaqueSizePadding) {
1609 ServiceWorkerFetchRequest non_opaque_request(body_request_);
1610 non_opaque_request.url = GURL("http://example.com/no-pad.html");
1611 ServiceWorkerResponse non_opaque_response(body_response_);
1612 EXPECT_EQ(0, CacheStorageCache::CalculateResponsePadding(
1613 non_opaque_response, CreateTestPaddingKey().get()));
1614 EXPECT_TRUE(Put(non_opaque_request, non_opaque_response));
1615 int64_t non_padded_cache_size = Size();
1616
1617 ServiceWorkerFetchRequest opaque_request(non_opaque_request);
1618 opaque_request.url = GURL("http://example.com/opaque.html");
1619 // Same URL length means same cache sizes (ignoring padding).
1620 EXPECT_EQ(opaque_request.url.spec().length(),
1621 non_opaque_request.url.spec().length());
1622 ServiceWorkerResponse opaque_response(non_opaque_response);
1623 opaque_response.response_type = blink::kWebServiceWorkerResponseTypeOpaque;
1624
1625 EXPECT_TRUE(Put(opaque_request, opaque_response));
1626 // Padding can be zero bytes, so if the opaque URL + padding key changes in
1627 // the future check for this.
1628 EXPECT_GT(Size(), 2 * non_padded_cache_size);
1629 }
1630
1597 TEST_P(CacheStorageCacheTestP, GetSizeThenClose) { 1631 TEST_P(CacheStorageCacheTestP, GetSizeThenClose) {
1598 EXPECT_TRUE(Put(body_request_, body_response_)); 1632 EXPECT_TRUE(Put(body_request_, body_response_));
1599 int64_t cache_size = Size(); 1633 int64_t cache_size = Size();
1600 EXPECT_EQ(cache_size, GetSizeThenClose()); 1634 EXPECT_EQ(cache_size, GetSizeThenClose());
1601 VerifyAllOpsFail(); 1635 VerifyAllOpsFail();
1602 } 1636 }
1603 1637
1604 TEST_P(CacheStorageCacheTestP, OpsFailOnClosedBackend) { 1638 TEST_P(CacheStorageCacheTestP, OpsFailOnClosedBackend) {
1605 // Create the backend and put something in it. 1639 // Create the backend and put something in it.
1606 EXPECT_TRUE(Put(body_request_, body_response_)); 1640 EXPECT_TRUE(Put(body_request_, body_response_));
1607 EXPECT_TRUE(Close()); 1641 EXPECT_TRUE(Close());
1608 VerifyAllOpsFail(); 1642 VerifyAllOpsFail();
1609 } 1643 }
1610 1644
1611 TEST_P(CacheStorageCacheTestP, VerifySerialScheduling) { 1645 TEST_P(CacheStorageCacheTestP, VerifySerialScheduling) {
1612 // Start two operations, the first one is delayed but the second isn't. The 1646 // Start two operations, the first one is delayed but the second isn't. The
1613 // second should wait for the first. 1647 // second should wait for the first.
1614 EXPECT_TRUE(Keys()); // Opens the backend. 1648 EXPECT_TRUE(Keys()); // Opens the backend.
1615 DelayableBackend* delayable_backend = cache_->UseDelayableBackend(); 1649 DelayableBackend* delayable_backend = cache_->UseDelayableBackend();
1616 delayable_backend->set_delay_doom(true); 1650 delayable_backend->set_delay_open_entry(true);
1617 1651
1618 int sequence_out = -1; 1652 int sequence_out = -1;
1619 1653
1620 CacheStorageBatchOperation operation1; 1654 CacheStorageBatchOperation operation1;
1621 operation1.operation_type = CACHE_STORAGE_CACHE_OPERATION_TYPE_PUT; 1655 operation1.operation_type = CACHE_STORAGE_CACHE_OPERATION_TYPE_PUT;
1622 operation1.request = body_request_; 1656 operation1.request = body_request_;
1623 operation1.response = body_response_; 1657 operation1.response = body_response_;
1624 1658
1625 std::unique_ptr<base::RunLoop> close_loop1(new base::RunLoop()); 1659 std::unique_ptr<base::RunLoop> close_loop1(new base::RunLoop());
1626 cache_->BatchOperation( 1660 cache_->BatchOperation(
1627 std::vector<CacheStorageBatchOperation>(1, operation1), 1661 std::vector<CacheStorageBatchOperation>(1, operation1),
1628 base::Bind(&CacheStorageCacheTest::SequenceCallback, 1662 base::Bind(&CacheStorageCacheTest::SequenceCallback,
1629 base::Unretained(this), 1, &sequence_out, close_loop1.get())); 1663 base::Unretained(this), 1, &sequence_out, close_loop1.get()));
1630 1664
1631 // Blocks on creating the cache entry. 1665 // Blocks on creating the cache entry.
1632 base::RunLoop().RunUntilIdle(); 1666 base::RunLoop().RunUntilIdle();
1633 1667
1634 CacheStorageBatchOperation operation2; 1668 CacheStorageBatchOperation operation2;
1635 operation2.operation_type = CACHE_STORAGE_CACHE_OPERATION_TYPE_PUT; 1669 operation2.operation_type = CACHE_STORAGE_CACHE_OPERATION_TYPE_PUT;
1636 operation2.request = body_request_; 1670 operation2.request = body_request_;
1637 operation2.response = body_response_; 1671 operation2.response = body_response_;
1638 1672
1639 delayable_backend->set_delay_doom(false); 1673 delayable_backend->set_delay_open_entry(false);
1640 std::unique_ptr<base::RunLoop> close_loop2(new base::RunLoop()); 1674 std::unique_ptr<base::RunLoop> close_loop2(new base::RunLoop());
1641 cache_->BatchOperation( 1675 cache_->BatchOperation(
1642 std::vector<CacheStorageBatchOperation>(1, operation2), 1676 std::vector<CacheStorageBatchOperation>(1, operation2),
1643 base::Bind(&CacheStorageCacheTest::SequenceCallback, 1677 base::Bind(&CacheStorageCacheTest::SequenceCallback,
1644 base::Unretained(this), 2, &sequence_out, close_loop2.get())); 1678 base::Unretained(this), 2, &sequence_out, close_loop2.get()));
1645 1679
1646 // The second put operation should wait for the first to complete. 1680 // The second put operation should wait for the first to complete.
1647 base::RunLoop().RunUntilIdle(); 1681 base::RunLoop().RunUntilIdle();
1648 EXPECT_FALSE(callback_response_); 1682 EXPECT_FALSE(callback_response_);
1649 1683
1650 delayable_backend->DoomEntryContinue(); 1684 EXPECT_TRUE(delayable_backend->OpenEntryContinue());
1651 close_loop1->Run(); 1685 close_loop1->Run();
1652 EXPECT_EQ(1, sequence_out); 1686 EXPECT_EQ(1, sequence_out);
1653 close_loop2->Run(); 1687 close_loop2->Run();
1654 EXPECT_EQ(2, sequence_out); 1688 EXPECT_EQ(2, sequence_out);
1655 } 1689 }
1656 1690
1657 INSTANTIATE_TEST_CASE_P(CacheStorageCacheTest, 1691 INSTANTIATE_TEST_CASE_P(CacheStorageCacheTest,
1658 CacheStorageCacheTestP, 1692 CacheStorageCacheTestP,
1659 ::testing::Values(false, true)); 1693 ::testing::Values(false, true));
1660 1694
1661 } // namespace content 1695 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698