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

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: Storing padding key in cache. 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>
11 #include <set> 11 #include <set>
12 #include <utility> 12 #include <utility>
13 13
14 #include "base/files/file_path.h" 14 #include "base/files/file_path.h"
15 #include "base/files/file_util.h"
15 #include "base/files/scoped_temp_dir.h" 16 #include "base/files/scoped_temp_dir.h"
16 #include "base/logging.h" 17 #include "base/logging.h"
17 #include "base/macros.h" 18 #include "base/macros.h"
18 #include "base/memory/ptr_util.h" 19 #include "base/memory/ptr_util.h"
19 #include "base/memory/ref_counted.h" 20 #include "base/memory/ref_counted.h"
20 #include "base/run_loop.h" 21 #include "base/run_loop.h"
21 #include "base/strings/string_split.h" 22 #include "base/strings/string_split.h"
22 #include "base/threading/thread_task_runner_handle.h" 23 #include "base/threading/thread_task_runner_handle.h"
23 #include "content/browser/blob_storage/chrome_blob_storage_context.h" 24 #include "content/browser/blob_storage/chrome_blob_storage_context.h"
24 #include "content/browser/cache_storage/cache_storage_cache_handle.h" 25 #include "content/browser/cache_storage/cache_storage_cache_handle.h"
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
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 126 matching lines...) Expand 10 before | Expand all | Expand 10 after
283 const scoped_refptr<net::URLRequestContextGetter>& request_context_getter, 287 const scoped_refptr<net::URLRequestContextGetter>& request_context_getter,
284 const scoped_refptr<storage::QuotaManagerProxy>& quota_manager_proxy, 288 const scoped_refptr<storage::QuotaManagerProxy>& quota_manager_proxy,
285 base::WeakPtr<storage::BlobStorageContext> blob_context) 289 base::WeakPtr<storage::BlobStorageContext> blob_context)
286 : CacheStorageCache(origin, 290 : CacheStorageCache(origin,
287 cache_name, 291 cache_name,
288 path, 292 path,
289 cache_storage, 293 cache_storage,
290 request_context_getter, 294 request_context_getter,
291 quota_manager_proxy, 295 quota_manager_proxy,
292 blob_context, 296 blob_context,
293 0 /* cache_size */), 297 0 /* cache_size */,
298 0 /* cache_padding */,
299 "123abc" /* padding_key */),
294 delay_backend_creation_(false) {} 300 delay_backend_creation_(false) {}
295 301
296 void CreateBackend(const ErrorCallback& callback) override { 302 void CreateBackend(const ErrorCallback& callback) override {
297 backend_creation_callback_ = callback; 303 backend_creation_callback_ = callback;
298 if (delay_backend_creation_) 304 if (delay_backend_creation_)
299 return; 305 return;
300 ContinueCreateBackend(); 306 ContinueCreateBackend();
301 } 307 }
302 308
303 void ContinueCreateBackend() { 309 void ContinueCreateBackend() {
(...skipping 378 matching lines...) Expand 10 before | Expand all | Expand 10 after
682 688
683 void VerifyAllOpsFail() { 689 void VerifyAllOpsFail() {
684 EXPECT_FALSE(Put(no_body_request_, no_body_response_)); 690 EXPECT_FALSE(Put(no_body_request_, no_body_response_));
685 EXPECT_FALSE(Match(no_body_request_)); 691 EXPECT_FALSE(Match(no_body_request_));
686 EXPECT_FALSE(Delete(body_request_)); 692 EXPECT_FALSE(Delete(body_request_));
687 EXPECT_FALSE(Keys()); 693 EXPECT_FALSE(Keys());
688 } 694 }
689 695
690 virtual bool MemoryOnly() { return false; } 696 virtual bool MemoryOnly() { return false; }
691 697
698 virtual bool PadResources() const { return false; }
699
692 void SetMaxQuerySizeBytes(size_t max_bytes) { 700 void SetMaxQuerySizeBytes(size_t max_bytes) {
693 cache_->max_query_size_bytes_ = max_bytes; 701 cache_->max_query_size_bytes_ = max_bytes;
694 } 702 }
695 703
696 protected: 704 protected:
697 base::ScopedTempDir temp_dir_; 705 base::ScopedTempDir temp_dir_;
698 TestBrowserThreadBundle browser_thread_bundle_; 706 TestBrowserThreadBundle browser_thread_bundle_;
699 TestBrowserContext browser_context_; 707 TestBrowserContext browser_context_;
700 std::unique_ptr<net::URLRequestJobFactoryImpl> url_request_job_factory_; 708 std::unique_ptr<net::URLRequestJobFactoryImpl> url_request_job_factory_;
701 scoped_refptr<MockSpecialStoragePolicy> quota_policy_; 709 scoped_refptr<MockSpecialStoragePolicy> quota_policy_;
(...skipping 14 matching lines...) Expand all
716 std::string expected_blob_data_; 724 std::string expected_blob_data_;
717 725
718 CacheStorageError callback_error_ = CACHE_STORAGE_OK; 726 CacheStorageError callback_error_ = CACHE_STORAGE_OK;
719 std::unique_ptr<ServiceWorkerResponse> callback_response_; 727 std::unique_ptr<ServiceWorkerResponse> callback_response_;
720 std::unique_ptr<storage::BlobDataHandle> callback_response_data_; 728 std::unique_ptr<storage::BlobDataHandle> callback_response_data_;
721 std::vector<std::string> callback_strings_; 729 std::vector<std::string> callback_strings_;
722 bool callback_closed_ = false; 730 bool callback_closed_ = false;
723 int64_t callback_size_ = 0; 731 int64_t callback_size_ = 0;
724 }; 732 };
725 733
734 enum class CacheLocation { IN_MEMORY, ON_DISK };
735
736 enum class PadType { ADD_PADDING, NO_PADDING };
737
726 class CacheStorageCacheTestP : public CacheStorageCacheTest, 738 class CacheStorageCacheTestP : public CacheStorageCacheTest,
727 public testing::WithParamInterface<bool> { 739 public testing::WithParamInterface<
728 bool MemoryOnly() override { return !GetParam(); } 740 testing::tuple<CacheLocation, PadType>> {
741 public:
742 bool MemoryOnly() override {
743 return testing::get<0>(GetParam()) == CacheLocation::IN_MEMORY;
744 }
745
746 bool PadResources() const override {
jkarlin 2017/06/08 18:58:48 It's unclear to me what PadResources is being used
cmumford 2017/06/12 18:09:31 It was, but unnecessarily, so I removed it.
747 return testing::get<1>(GetParam()) == PadType::ADD_PADDING;
748 }
729 }; 749 };
730 750
731 TEST_P(CacheStorageCacheTestP, PutNoBody) { 751 TEST_P(CacheStorageCacheTestP, PutNoBody) {
732 EXPECT_TRUE(Put(no_body_request_, no_body_response_)); 752 EXPECT_TRUE(Put(no_body_request_, no_body_response_));
733 } 753 }
734 754
735 TEST_P(CacheStorageCacheTestP, PutBody) { 755 TEST_P(CacheStorageCacheTestP, PutBody) {
736 EXPECT_TRUE(Put(body_request_, body_response_)); 756 EXPECT_TRUE(Put(body_request_, body_response_));
737 } 757 }
738 758
(...skipping 848 matching lines...) Expand 10 before | Expand all | Expand 10 after
1587 EXPECT_TRUE(Delete(no_body_request_)); 1607 EXPECT_TRUE(Delete(no_body_request_));
1588 EXPECT_EQ(0, Size()); 1608 EXPECT_EQ(0, Size());
1589 1609
1590 EXPECT_TRUE(Put(body_request_, body_response_)); 1610 EXPECT_TRUE(Put(body_request_, body_response_));
1591 EXPECT_LT(no_body_size, Size()); 1611 EXPECT_LT(no_body_size, Size());
1592 1612
1593 EXPECT_TRUE(Delete(body_request_)); 1613 EXPECT_TRUE(Delete(body_request_));
1594 EXPECT_EQ(0, Size()); 1614 EXPECT_EQ(0, Size());
1595 } 1615 }
1596 1616
1617 TEST_P(CacheStorageCacheTestP, VerifyOpaqueSizePadding) {
1618 // Test InMemory/OnDisk configs
1619 if (PadResources())
1620 return;
1621
1622 const std::string padding_key = "123abc";
1623
1624 ServiceWorkerFetchRequest non_opaque_request(body_request_);
1625 non_opaque_request.url = GURL("http://example.com/no-pad.html");
1626 ServiceWorkerResponse non_opaque_response(body_response_);
1627 EXPECT_EQ(CacheStorageCache::CalculateResponsePadding(non_opaque_response,
jkarlin 2017/06/08 18:58:48 EXPECT_EQ(0, ...)
cmumford 2017/06/12 18:09:31 Done.
1628 padding_key),
1629 0);
1630 EXPECT_TRUE(Put(non_opaque_request, non_opaque_response));
1631 int64_t non_padded_cache_size = Size();
1632
1633 ServiceWorkerFetchRequest opaque_request(non_opaque_request);
1634 opaque_request.url = GURL("http://example.com/opaque.html");
1635 // Same URL length means same cache sizes (ignoring padding).
1636 EXPECT_EQ(opaque_request.url.spec().length(),
1637 non_opaque_request.url.spec().length());
1638 ServiceWorkerResponse opaque_response(non_opaque_response);
1639 opaque_response.response_type = blink::kWebServiceWorkerResponseTypeOpaque;
1640
1641 const int64_t padding_size =
1642 CacheStorageCache::CalculateResponsePadding(opaque_response, padding_key);
jkarlin 2017/06/08 18:58:48 I'd rather that we not call this private function
cmumford 2017/06/12 18:09:31 Will do. Technically padding can be zero, so the t
1643 EXPECT_GT(padding_size, 0);
1644 EXPECT_TRUE(Put(opaque_request, opaque_response));
1645 EXPECT_EQ(2 * non_padded_cache_size + padding_size, Size());
1646 }
1647
1597 TEST_P(CacheStorageCacheTestP, GetSizeThenClose) { 1648 TEST_P(CacheStorageCacheTestP, GetSizeThenClose) {
1598 EXPECT_TRUE(Put(body_request_, body_response_)); 1649 EXPECT_TRUE(Put(body_request_, body_response_));
1599 int64_t cache_size = Size(); 1650 int64_t cache_size = Size();
1600 EXPECT_EQ(cache_size, GetSizeThenClose()); 1651 EXPECT_EQ(cache_size, GetSizeThenClose());
1601 VerifyAllOpsFail(); 1652 VerifyAllOpsFail();
1602 } 1653 }
1603 1654
1604 TEST_P(CacheStorageCacheTestP, OpsFailOnClosedBackend) { 1655 TEST_P(CacheStorageCacheTestP, OpsFailOnClosedBackend) {
1605 // Create the backend and put something in it. 1656 // Create the backend and put something in it.
1606 EXPECT_TRUE(Put(body_request_, body_response_)); 1657 EXPECT_TRUE(Put(body_request_, body_response_));
1607 EXPECT_TRUE(Close()); 1658 EXPECT_TRUE(Close());
1608 VerifyAllOpsFail(); 1659 VerifyAllOpsFail();
1609 } 1660 }
1610 1661
1611 TEST_P(CacheStorageCacheTestP, VerifySerialScheduling) { 1662 TEST_P(CacheStorageCacheTestP, VerifySerialScheduling) {
1612 // Start two operations, the first one is delayed but the second isn't. The 1663 // Start two operations, the first one is delayed but the second isn't. The
1613 // second should wait for the first. 1664 // second should wait for the first.
1614 EXPECT_TRUE(Keys()); // Opens the backend. 1665 EXPECT_TRUE(Keys()); // Opens the backend.
1615 DelayableBackend* delayable_backend = cache_->UseDelayableBackend(); 1666 DelayableBackend* delayable_backend = cache_->UseDelayableBackend();
1616 delayable_backend->set_delay_doom(true); 1667 delayable_backend->set_delay_open_entry(true);
1617 1668
1618 int sequence_out = -1; 1669 int sequence_out = -1;
1619 1670
1620 CacheStorageBatchOperation operation1; 1671 CacheStorageBatchOperation operation1;
1621 operation1.operation_type = CACHE_STORAGE_CACHE_OPERATION_TYPE_PUT; 1672 operation1.operation_type = CACHE_STORAGE_CACHE_OPERATION_TYPE_PUT;
1622 operation1.request = body_request_; 1673 operation1.request = body_request_;
1623 operation1.response = body_response_; 1674 operation1.response = body_response_;
1624 1675
1625 std::unique_ptr<base::RunLoop> close_loop1(new base::RunLoop()); 1676 std::unique_ptr<base::RunLoop> close_loop1(new base::RunLoop());
1626 cache_->BatchOperation( 1677 cache_->BatchOperation(
1627 std::vector<CacheStorageBatchOperation>(1, operation1), 1678 std::vector<CacheStorageBatchOperation>(1, operation1),
1628 base::Bind(&CacheStorageCacheTest::SequenceCallback, 1679 base::Bind(&CacheStorageCacheTest::SequenceCallback,
1629 base::Unretained(this), 1, &sequence_out, close_loop1.get())); 1680 base::Unretained(this), 1, &sequence_out, close_loop1.get()));
1630 1681
1631 // Blocks on creating the cache entry. 1682 // Blocks on creating the cache entry.
1632 base::RunLoop().RunUntilIdle(); 1683 base::RunLoop().RunUntilIdle();
1633 1684
1634 CacheStorageBatchOperation operation2; 1685 CacheStorageBatchOperation operation2;
1635 operation2.operation_type = CACHE_STORAGE_CACHE_OPERATION_TYPE_PUT; 1686 operation2.operation_type = CACHE_STORAGE_CACHE_OPERATION_TYPE_PUT;
1636 operation2.request = body_request_; 1687 operation2.request = body_request_;
1637 operation2.response = body_response_; 1688 operation2.response = body_response_;
1638 1689
1639 delayable_backend->set_delay_doom(false); 1690 delayable_backend->set_delay_open_entry(false);
1640 std::unique_ptr<base::RunLoop> close_loop2(new base::RunLoop()); 1691 std::unique_ptr<base::RunLoop> close_loop2(new base::RunLoop());
1641 cache_->BatchOperation( 1692 cache_->BatchOperation(
1642 std::vector<CacheStorageBatchOperation>(1, operation2), 1693 std::vector<CacheStorageBatchOperation>(1, operation2),
1643 base::Bind(&CacheStorageCacheTest::SequenceCallback, 1694 base::Bind(&CacheStorageCacheTest::SequenceCallback,
1644 base::Unretained(this), 2, &sequence_out, close_loop2.get())); 1695 base::Unretained(this), 2, &sequence_out, close_loop2.get()));
1645 1696
1646 // The second put operation should wait for the first to complete. 1697 // The second put operation should wait for the first to complete.
1647 base::RunLoop().RunUntilIdle(); 1698 base::RunLoop().RunUntilIdle();
1648 EXPECT_FALSE(callback_response_); 1699 EXPECT_FALSE(callback_response_);
1649 1700
1650 delayable_backend->DoomEntryContinue(); 1701 EXPECT_TRUE(delayable_backend->OpenEntryContinue());
1651 close_loop1->Run(); 1702 close_loop1->Run();
1652 EXPECT_EQ(1, sequence_out); 1703 EXPECT_EQ(1, sequence_out);
1653 close_loop2->Run(); 1704 close_loop2->Run();
1654 EXPECT_EQ(2, sequence_out); 1705 EXPECT_EQ(2, sequence_out);
1655 } 1706 }
1656 1707
1657 INSTANTIATE_TEST_CASE_P(CacheStorageCacheTest, 1708 INSTANTIATE_TEST_CASE_P(
1658 CacheStorageCacheTestP, 1709 CacheStorageCacheTest,
1659 ::testing::Values(false, true)); 1710 CacheStorageCacheTestP,
1711 ::testing::Combine(
1712 ::testing::Values(CacheLocation::IN_MEMORY, CacheLocation::ON_DISK),
1713 ::testing::Values(PadType::ADD_PADDING, PadType::NO_PADDING)));
1660 1714
1661 } // namespace content 1715 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698