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

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: Rebased and resolved conflicts. Created 3 years, 7 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 525 matching lines...) Expand 10 before | Expand all | Expand 10 after
682 686
683 void VerifyAllOpsFail() { 687 void VerifyAllOpsFail() {
684 EXPECT_FALSE(Put(no_body_request_, no_body_response_)); 688 EXPECT_FALSE(Put(no_body_request_, no_body_response_));
685 EXPECT_FALSE(Match(no_body_request_)); 689 EXPECT_FALSE(Match(no_body_request_));
686 EXPECT_FALSE(Delete(body_request_)); 690 EXPECT_FALSE(Delete(body_request_));
687 EXPECT_FALSE(Keys()); 691 EXPECT_FALSE(Keys());
688 } 692 }
689 693
690 virtual bool MemoryOnly() { return false; } 694 virtual bool MemoryOnly() { return false; }
691 695
696 virtual bool PadResources() const { return false; }
697
692 void SetMaxQuerySizeBytes(size_t max_bytes) { 698 void SetMaxQuerySizeBytes(size_t max_bytes) {
693 cache_->max_query_size_bytes_ = max_bytes; 699 cache_->max_query_size_bytes_ = max_bytes;
694 } 700 }
695 701
696 protected: 702 protected:
697 base::ScopedTempDir temp_dir_; 703 base::ScopedTempDir temp_dir_;
698 TestBrowserThreadBundle browser_thread_bundle_; 704 TestBrowserThreadBundle browser_thread_bundle_;
699 TestBrowserContext browser_context_; 705 TestBrowserContext browser_context_;
700 std::unique_ptr<net::URLRequestJobFactoryImpl> url_request_job_factory_; 706 std::unique_ptr<net::URLRequestJobFactoryImpl> url_request_job_factory_;
701 scoped_refptr<MockSpecialStoragePolicy> quota_policy_; 707 scoped_refptr<MockSpecialStoragePolicy> quota_policy_;
(...skipping 14 matching lines...) Expand all
716 std::string expected_blob_data_; 722 std::string expected_blob_data_;
717 723
718 CacheStorageError callback_error_ = CACHE_STORAGE_OK; 724 CacheStorageError callback_error_ = CACHE_STORAGE_OK;
719 std::unique_ptr<ServiceWorkerResponse> callback_response_; 725 std::unique_ptr<ServiceWorkerResponse> callback_response_;
720 std::unique_ptr<storage::BlobDataHandle> callback_response_data_; 726 std::unique_ptr<storage::BlobDataHandle> callback_response_data_;
721 std::vector<std::string> callback_strings_; 727 std::vector<std::string> callback_strings_;
722 bool callback_closed_ = false; 728 bool callback_closed_ = false;
723 int64_t callback_size_ = 0; 729 int64_t callback_size_ = 0;
724 }; 730 };
725 731
732 enum class CacheLocation { IN_MEMORY, ON_DISK };
733
734 enum class PadType { ADD_PADDING, NO_PADDING };
735
726 class CacheStorageCacheTestP : public CacheStorageCacheTest, 736 class CacheStorageCacheTestP : public CacheStorageCacheTest,
727 public testing::WithParamInterface<bool> { 737 public testing::WithParamInterface<
728 bool MemoryOnly() override { return !GetParam(); } 738 testing::tuple<CacheLocation, PadType>> {
739 public:
740 bool MemoryOnly() override {
741 return testing::get<0>(GetParam()) == CacheLocation::IN_MEMORY;
742 }
743
744 bool PadResources() const override {
745 return testing::get<1>(GetParam()) == PadType::ADD_PADDING;
746 }
729 }; 747 };
730 748
731 TEST_P(CacheStorageCacheTestP, PutNoBody) { 749 TEST_P(CacheStorageCacheTestP, PutNoBody) {
732 EXPECT_TRUE(Put(no_body_request_, no_body_response_)); 750 EXPECT_TRUE(Put(no_body_request_, no_body_response_));
733 } 751 }
734 752
735 TEST_P(CacheStorageCacheTestP, PutBody) { 753 TEST_P(CacheStorageCacheTestP, PutBody) {
736 EXPECT_TRUE(Put(body_request_, body_response_)); 754 EXPECT_TRUE(Put(body_request_, body_response_));
737 } 755 }
738 756
(...skipping 848 matching lines...) Expand 10 before | Expand all | Expand 10 after
1587 EXPECT_TRUE(Delete(no_body_request_)); 1605 EXPECT_TRUE(Delete(no_body_request_));
1588 EXPECT_EQ(0, Size()); 1606 EXPECT_EQ(0, Size());
1589 1607
1590 EXPECT_TRUE(Put(body_request_, body_response_)); 1608 EXPECT_TRUE(Put(body_request_, body_response_));
1591 EXPECT_LT(no_body_size, Size()); 1609 EXPECT_LT(no_body_size, Size());
1592 1610
1593 EXPECT_TRUE(Delete(body_request_)); 1611 EXPECT_TRUE(Delete(body_request_));
1594 EXPECT_EQ(0, Size()); 1612 EXPECT_EQ(0, Size());
1595 } 1613 }
1596 1614
1615 TEST_P(CacheStorageCacheTestP, VerifyOpaqueSizePadding) {
1616 // Test InMemory/OnDisk configs
1617 if (PadResources())
1618 return;
1619
1620 ServiceWorkerFetchRequest non_opaque_request(body_request_);
1621 non_opaque_request.url = GURL("http://example.com/no-pad.html");
1622 ServiceWorkerResponse non_opaque_response(body_response_);
1623 EXPECT_EQ(CacheStorageCache::CalculateResponsePadding(non_opaque_response),
1624 0);
1625 EXPECT_TRUE(Put(non_opaque_request, non_opaque_response));
1626 int64_t non_padded_cache_size = Size();
1627
1628 ServiceWorkerFetchRequest opaque_request(non_opaque_request);
1629 opaque_request.url = GURL("http://example.com/opaque.html");
1630 // Same URL length means same cache sizes (ignoring padding).
1631 EXPECT_EQ(opaque_request.url.spec().length(),
1632 non_opaque_request.url.spec().length());
1633 ServiceWorkerResponse opaque_response(non_opaque_response);
1634 opaque_response.response_type = blink::kWebServiceWorkerResponseTypeOpaque;
1635
1636 const int64_t padding_size =
1637 CacheStorageCache::CalculateResponsePadding(opaque_response);
1638 EXPECT_GT(padding_size, 0);
1639 EXPECT_TRUE(Put(opaque_request, opaque_response));
1640 EXPECT_EQ(2 * non_padded_cache_size + padding_size, Size());
1641 }
1642
1597 TEST_P(CacheStorageCacheTestP, GetSizeThenClose) { 1643 TEST_P(CacheStorageCacheTestP, GetSizeThenClose) {
1598 EXPECT_TRUE(Put(body_request_, body_response_)); 1644 EXPECT_TRUE(Put(body_request_, body_response_));
1599 int64_t cache_size = Size(); 1645 int64_t cache_size = Size();
1600 EXPECT_EQ(cache_size, GetSizeThenClose()); 1646 EXPECT_EQ(cache_size, GetSizeThenClose());
1601 VerifyAllOpsFail(); 1647 VerifyAllOpsFail();
1602 } 1648 }
1603 1649
1604 TEST_P(CacheStorageCacheTestP, OpsFailOnClosedBackend) { 1650 TEST_P(CacheStorageCacheTestP, OpsFailOnClosedBackend) {
1605 // Create the backend and put something in it. 1651 // Create the backend and put something in it.
1606 EXPECT_TRUE(Put(body_request_, body_response_)); 1652 EXPECT_TRUE(Put(body_request_, body_response_));
1607 EXPECT_TRUE(Close()); 1653 EXPECT_TRUE(Close());
1608 VerifyAllOpsFail(); 1654 VerifyAllOpsFail();
1609 } 1655 }
1610 1656
1611 TEST_P(CacheStorageCacheTestP, VerifySerialScheduling) { 1657 TEST_P(CacheStorageCacheTestP, VerifySerialScheduling) {
1612 // Start two operations, the first one is delayed but the second isn't. The 1658 // Start two operations, the first one is delayed but the second isn't. The
1613 // second should wait for the first. 1659 // second should wait for the first.
1614 EXPECT_TRUE(Keys()); // Opens the backend. 1660 EXPECT_TRUE(Keys()); // Opens the backend.
1615 DelayableBackend* delayable_backend = cache_->UseDelayableBackend(); 1661 DelayableBackend* delayable_backend = cache_->UseDelayableBackend();
1616 delayable_backend->set_delay_doom(true); 1662 delayable_backend->set_delay_open_entry(true);
1617 1663
1618 int sequence_out = -1; 1664 int sequence_out = -1;
1619 1665
1620 CacheStorageBatchOperation operation1; 1666 CacheStorageBatchOperation operation1;
1621 operation1.operation_type = CACHE_STORAGE_CACHE_OPERATION_TYPE_PUT; 1667 operation1.operation_type = CACHE_STORAGE_CACHE_OPERATION_TYPE_PUT;
1622 operation1.request = body_request_; 1668 operation1.request = body_request_;
1623 operation1.response = body_response_; 1669 operation1.response = body_response_;
1624 1670
1625 std::unique_ptr<base::RunLoop> close_loop1(new base::RunLoop()); 1671 std::unique_ptr<base::RunLoop> close_loop1(new base::RunLoop());
1626 cache_->BatchOperation( 1672 cache_->BatchOperation(
1627 std::vector<CacheStorageBatchOperation>(1, operation1), 1673 std::vector<CacheStorageBatchOperation>(1, operation1),
1628 base::Bind(&CacheStorageCacheTest::SequenceCallback, 1674 base::Bind(&CacheStorageCacheTest::SequenceCallback,
1629 base::Unretained(this), 1, &sequence_out, close_loop1.get())); 1675 base::Unretained(this), 1, &sequence_out, close_loop1.get()));
1630 1676
1631 // Blocks on creating the cache entry. 1677 // Blocks on creating the cache entry.
1632 base::RunLoop().RunUntilIdle(); 1678 base::RunLoop().RunUntilIdle();
1633 1679
1634 CacheStorageBatchOperation operation2; 1680 CacheStorageBatchOperation operation2;
1635 operation2.operation_type = CACHE_STORAGE_CACHE_OPERATION_TYPE_PUT; 1681 operation2.operation_type = CACHE_STORAGE_CACHE_OPERATION_TYPE_PUT;
1636 operation2.request = body_request_; 1682 operation2.request = body_request_;
1637 operation2.response = body_response_; 1683 operation2.response = body_response_;
1638 1684
1639 delayable_backend->set_delay_doom(false); 1685 delayable_backend->set_delay_open_entry(false);
1640 std::unique_ptr<base::RunLoop> close_loop2(new base::RunLoop()); 1686 std::unique_ptr<base::RunLoop> close_loop2(new base::RunLoop());
1641 cache_->BatchOperation( 1687 cache_->BatchOperation(
1642 std::vector<CacheStorageBatchOperation>(1, operation2), 1688 std::vector<CacheStorageBatchOperation>(1, operation2),
1643 base::Bind(&CacheStorageCacheTest::SequenceCallback, 1689 base::Bind(&CacheStorageCacheTest::SequenceCallback,
1644 base::Unretained(this), 2, &sequence_out, close_loop2.get())); 1690 base::Unretained(this), 2, &sequence_out, close_loop2.get()));
1645 1691
1646 // The second put operation should wait for the first to complete. 1692 // The second put operation should wait for the first to complete.
1647 base::RunLoop().RunUntilIdle(); 1693 base::RunLoop().RunUntilIdle();
1648 EXPECT_FALSE(callback_response_); 1694 EXPECT_FALSE(callback_response_);
1649 1695
1650 delayable_backend->DoomEntryContinue(); 1696 EXPECT_TRUE(delayable_backend->OpenEntryContinue());
1651 close_loop1->Run(); 1697 close_loop1->Run();
1652 EXPECT_EQ(1, sequence_out); 1698 EXPECT_EQ(1, sequence_out);
1653 close_loop2->Run(); 1699 close_loop2->Run();
1654 EXPECT_EQ(2, sequence_out); 1700 EXPECT_EQ(2, sequence_out);
1655 } 1701 }
1656 1702
1657 INSTANTIATE_TEST_CASE_P(CacheStorageCacheTest, 1703 INSTANTIATE_TEST_CASE_P(
1658 CacheStorageCacheTestP, 1704 CacheStorageCacheTest,
1659 ::testing::Values(false, true)); 1705 CacheStorageCacheTestP,
1706 ::testing::Combine(
1707 ::testing::Values(CacheLocation::IN_MEMORY, CacheLocation::ON_DISK),
1708 ::testing::Values(PadType::ADD_PADDING, PadType::NO_PADDING)));
1660 1709
1661 } // namespace content 1710 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698