| OLD | NEW |
| 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 12 matching lines...) Expand all Loading... |
| 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 "content/public/test/test_utils.h" | 32 #include "content/public/test/test_utils.h" |
| 33 #include "crypto/symmetric_key.h" |
| 33 #include "net/base/test_completion_callback.h" | 34 #include "net/base/test_completion_callback.h" |
| 34 #include "net/disk_cache/disk_cache.h" | 35 #include "net/disk_cache/disk_cache.h" |
| 35 #include "net/url_request/url_request_context.h" | 36 #include "net/url_request/url_request_context.h" |
| 36 #include "net/url_request/url_request_context_getter.h" | 37 #include "net/url_request/url_request_context_getter.h" |
| 37 #include "net/url_request/url_request_job_factory_impl.h" | 38 #include "net/url_request/url_request_job_factory_impl.h" |
| 38 #include "storage/browser/blob/blob_data_builder.h" | 39 #include "storage/browser/blob/blob_data_builder.h" |
| 39 #include "storage/browser/blob/blob_data_handle.h" | 40 #include "storage/browser/blob/blob_data_handle.h" |
| 40 #include "storage/browser/blob/blob_data_snapshot.h" | 41 #include "storage/browser/blob/blob_data_snapshot.h" |
| 41 #include "storage/browser/blob/blob_storage_context.h" | 42 #include "storage/browser/blob/blob_storage_context.h" |
| 42 #include "storage/browser/blob/blob_url_request_job_factory.h" | 43 #include "storage/browser/blob/blob_url_request_job_factory.h" |
| (...skipping 15 matching lines...) Expand all Loading... |
| 58 std::unique_ptr<storage::BlobProtocolHandler> CreateMockBlobProtocolHandler( | 59 std::unique_ptr<storage::BlobProtocolHandler> CreateMockBlobProtocolHandler( |
| 59 storage::BlobStorageContext* blob_storage_context) { | 60 storage::BlobStorageContext* blob_storage_context) { |
| 60 return base::WrapUnique( | 61 return base::WrapUnique( |
| 61 new storage::BlobProtocolHandler(blob_storage_context, nullptr)); | 62 new storage::BlobProtocolHandler(blob_storage_context, nullptr)); |
| 62 } | 63 } |
| 63 | 64 |
| 64 // A disk_cache::Backend wrapper that can delay operations. | 65 // A disk_cache::Backend wrapper that can delay operations. |
| 65 class DelayableBackend : public disk_cache::Backend { | 66 class DelayableBackend : public disk_cache::Backend { |
| 66 public: | 67 public: |
| 67 explicit DelayableBackend(std::unique_ptr<disk_cache::Backend> backend) | 68 explicit DelayableBackend(std::unique_ptr<disk_cache::Backend> backend) |
| 68 : backend_(std::move(backend)), delay_doom_(false) {} | 69 : backend_(std::move(backend)), delay_open_entry_(false) {} |
| 69 | 70 |
| 70 // disk_cache::Backend overrides | 71 // disk_cache::Backend overrides |
| 71 net::CacheType GetCacheType() const override { | 72 net::CacheType GetCacheType() const override { |
| 72 return backend_->GetCacheType(); | 73 return backend_->GetCacheType(); |
| 73 } | 74 } |
| 74 int32_t GetEntryCount() const override { return backend_->GetEntryCount(); } | 75 int32_t GetEntryCount() const override { return backend_->GetEntryCount(); } |
| 75 int OpenEntry(const std::string& key, | 76 int OpenEntry(const std::string& key, |
| 76 disk_cache::Entry** entry, | 77 disk_cache::Entry** entry, |
| 77 const CompletionCallback& callback) override { | 78 const CompletionCallback& callback) override { |
| 79 if (delay_open_entry_ && open_entry_callback_.is_null()) { |
| 80 open_entry_callback_ = base::BindOnce( |
| 81 &DelayableBackend::OpenEntryDelayedImpl, base::Unretained(this), key, |
| 82 base::Unretained(entry), callback); |
| 83 return net::ERR_IO_PENDING; |
| 84 } |
| 78 return backend_->OpenEntry(key, entry, callback); | 85 return backend_->OpenEntry(key, entry, callback); |
| 79 } | 86 } |
| 80 | 87 |
| 81 int CreateEntry(const std::string& key, | 88 int CreateEntry(const std::string& key, |
| 82 disk_cache::Entry** entry, | 89 disk_cache::Entry** entry, |
| 83 const CompletionCallback& callback) override { | 90 const CompletionCallback& callback) override { |
| 84 return backend_->CreateEntry(key, entry, callback); | 91 return backend_->CreateEntry(key, entry, callback); |
| 85 } | 92 } |
| 86 int DoomEntry(const std::string& key, | 93 int DoomEntry(const std::string& key, |
| 87 const CompletionCallback& callback) override { | 94 const CompletionCallback& callback) override { |
| 88 if (delay_doom_) { | |
| 89 doom_entry_callback_ = | |
| 90 base::BindOnce(&DelayableBackend::DoomEntryDelayedImpl, | |
| 91 base::Unretained(this), key, callback); | |
| 92 return net::ERR_IO_PENDING; | |
| 93 } | |
| 94 | |
| 95 return backend_->DoomEntry(key, callback); | 95 return backend_->DoomEntry(key, callback); |
| 96 } | 96 } |
| 97 int DoomAllEntries(const CompletionCallback& callback) override { | 97 int DoomAllEntries(const CompletionCallback& callback) override { |
| 98 return backend_->DoomAllEntries(callback); | 98 return backend_->DoomAllEntries(callback); |
| 99 } | 99 } |
| 100 int DoomEntriesBetween(base::Time initial_time, | 100 int DoomEntriesBetween(base::Time initial_time, |
| 101 base::Time end_time, | 101 base::Time end_time, |
| 102 const CompletionCallback& callback) override { | 102 const CompletionCallback& callback) override { |
| 103 return backend_->DoomEntriesBetween(initial_time, end_time, callback); | 103 return backend_->DoomEntriesBetween(initial_time, end_time, callback); |
| 104 } | 104 } |
| (...skipping 15 matching lines...) Expand all Loading... |
| 120 return backend_->OnExternalCacheHit(key); | 120 return backend_->OnExternalCacheHit(key); |
| 121 } | 121 } |
| 122 | 122 |
| 123 size_t DumpMemoryStats( | 123 size_t DumpMemoryStats( |
| 124 base::trace_event::ProcessMemoryDump* pmd, | 124 base::trace_event::ProcessMemoryDump* pmd, |
| 125 const std::string& parent_absolute_name) const override { | 125 const std::string& parent_absolute_name) const override { |
| 126 NOTREACHED(); | 126 NOTREACHED(); |
| 127 return 0u; | 127 return 0u; |
| 128 } | 128 } |
| 129 | 129 |
| 130 // Call to continue a delayed doom. | 130 // Call to continue a delayed call to OpenEntry. |
| 131 void DoomEntryContinue() { | 131 bool OpenEntryContinue() { |
| 132 EXPECT_FALSE(doom_entry_callback_.is_null()); | 132 if (open_entry_callback_.is_null()) |
| 133 std::move(doom_entry_callback_).Run(); | 133 return false; |
| 134 std::move(open_entry_callback_).Run(); |
| 135 return true; |
| 134 } | 136 } |
| 135 | 137 |
| 136 void set_delay_doom(bool value) { delay_doom_ = value; } | 138 void set_delay_open_entry(bool value) { delay_open_entry_ = value; } |
| 137 | 139 |
| 138 private: | 140 private: |
| 139 void DoomEntryDelayedImpl(const std::string& key, | 141 void OpenEntryDelayedImpl(const std::string& key, |
| 142 disk_cache::Entry** entry, |
| 140 const CompletionCallback& callback) { | 143 const CompletionCallback& callback) { |
| 141 int rv = backend_->DoomEntry(key, callback); | 144 int rv = backend_->OpenEntry(key, entry, callback); |
| 142 if (rv != net::ERR_IO_PENDING) | 145 if (rv != net::ERR_IO_PENDING) |
| 143 callback.Run(rv); | 146 callback.Run(rv); |
| 144 } | 147 } |
| 145 | 148 |
| 146 std::unique_ptr<disk_cache::Backend> backend_; | 149 std::unique_ptr<disk_cache::Backend> backend_; |
| 147 bool delay_doom_; | 150 bool delay_open_entry_; |
| 148 base::OnceClosure doom_entry_callback_; | 151 base::OnceClosure open_entry_callback_; |
| 149 }; | 152 }; |
| 150 | 153 |
| 151 void CopyBody(const storage::BlobDataHandle& blob_handle, std::string* output) { | 154 void CopyBody(const storage::BlobDataHandle& blob_handle, std::string* output) { |
| 152 *output = std::string(); | 155 *output = std::string(); |
| 153 std::unique_ptr<storage::BlobDataSnapshot> data = | 156 std::unique_ptr<storage::BlobDataSnapshot> data = |
| 154 blob_handle.CreateSnapshot(); | 157 blob_handle.CreateSnapshot(); |
| 155 const auto& items = data->items(); | 158 const auto& items = data->items(); |
| 156 for (const auto& item : items) { | 159 for (const auto& item : items) { |
| 157 switch (item->type()) { | 160 switch (item->type()) { |
| 158 case storage::DataElement::TYPE_BYTES: { | 161 case storage::DataElement::TYPE_BYTES: { |
| (...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 265 return expected_side_data == actual_body; | 268 return expected_side_data == actual_body; |
| 266 } | 269 } |
| 267 | 270 |
| 268 ServiceWorkerResponse SetCacheName(const ServiceWorkerResponse& original) { | 271 ServiceWorkerResponse SetCacheName(const ServiceWorkerResponse& original) { |
| 269 ServiceWorkerResponse result(original); | 272 ServiceWorkerResponse result(original); |
| 270 result.is_in_cache_storage = true; | 273 result.is_in_cache_storage = true; |
| 271 result.cache_storage_cache_name = kCacheName; | 274 result.cache_storage_cache_name = kCacheName; |
| 272 return result; | 275 return result; |
| 273 } | 276 } |
| 274 | 277 |
| 278 std::unique_ptr<crypto::SymmetricKey> CreateTestPaddingKey() { |
| 279 return crypto::SymmetricKey::Import(crypto::SymmetricKey::HMAC_SHA1, |
| 280 "abc123"); |
| 281 } |
| 282 |
| 275 } // namespace | 283 } // namespace |
| 276 | 284 |
| 277 // A CacheStorageCache that can optionally delay during backend creation. | 285 // A CacheStorageCache that can optionally delay during backend creation. |
| 278 class TestCacheStorageCache : public CacheStorageCache { | 286 class TestCacheStorageCache : public CacheStorageCache { |
| 279 public: | 287 public: |
| 280 TestCacheStorageCache( | 288 TestCacheStorageCache( |
| 281 const GURL& origin, | 289 const GURL& origin, |
| 282 const std::string& cache_name, | 290 const std::string& cache_name, |
| 283 const base::FilePath& path, | 291 const base::FilePath& path, |
| 284 CacheStorage* cache_storage, | 292 CacheStorage* cache_storage, |
| 285 const scoped_refptr<net::URLRequestContextGetter>& request_context_getter, | 293 const scoped_refptr<net::URLRequestContextGetter>& request_context_getter, |
| 286 const scoped_refptr<storage::QuotaManagerProxy>& quota_manager_proxy, | 294 const scoped_refptr<storage::QuotaManagerProxy>& quota_manager_proxy, |
| 287 base::WeakPtr<storage::BlobStorageContext> blob_context) | 295 base::WeakPtr<storage::BlobStorageContext> blob_context) |
| 288 : CacheStorageCache(origin, | 296 : CacheStorageCache(origin, |
| 289 cache_name, | 297 cache_name, |
| 290 path, | 298 path, |
| 291 cache_storage, | 299 cache_storage, |
| 292 request_context_getter, | 300 request_context_getter, |
| 293 quota_manager_proxy, | 301 quota_manager_proxy, |
| 294 blob_context, | 302 blob_context, |
| 295 0 /* cache_size */), | 303 0 /* cache_size */, |
| 304 0 /* cache_padding */, |
| 305 CreateTestPaddingKey()), |
| 296 delay_backend_creation_(false) {} | 306 delay_backend_creation_(false) {} |
| 297 | 307 |
| 298 void CreateBackend(ErrorCallback callback) override { | 308 void CreateBackend(ErrorCallback callback) override { |
| 299 backend_creation_callback_ = std::move(callback); | 309 backend_creation_callback_ = std::move(callback); |
| 300 if (delay_backend_creation_) | 310 if (delay_backend_creation_) |
| 301 return; | 311 return; |
| 302 ContinueCreateBackend(); | 312 ContinueCreateBackend(); |
| 303 } | 313 } |
| 304 | 314 |
| 305 void ContinueCreateBackend() { | 315 void ContinueCreateBackend() { |
| (...skipping 1285 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1591 EXPECT_TRUE(Delete(no_body_request_)); | 1601 EXPECT_TRUE(Delete(no_body_request_)); |
| 1592 EXPECT_EQ(0, Size()); | 1602 EXPECT_EQ(0, Size()); |
| 1593 | 1603 |
| 1594 EXPECT_TRUE(Put(body_request_, body_response_)); | 1604 EXPECT_TRUE(Put(body_request_, body_response_)); |
| 1595 EXPECT_LT(no_body_size, Size()); | 1605 EXPECT_LT(no_body_size, Size()); |
| 1596 | 1606 |
| 1597 EXPECT_TRUE(Delete(body_request_)); | 1607 EXPECT_TRUE(Delete(body_request_)); |
| 1598 EXPECT_EQ(0, Size()); | 1608 EXPECT_EQ(0, Size()); |
| 1599 } | 1609 } |
| 1600 | 1610 |
| 1611 TEST_F(CacheStorageCacheTest, VerifyOpaqueSizePadding) { |
| 1612 base::Time response_time(base::Time::Now()); |
| 1613 |
| 1614 ServiceWorkerFetchRequest non_opaque_request(body_request_); |
| 1615 non_opaque_request.url = GURL("http://example.com/no-pad.html"); |
| 1616 ServiceWorkerResponse non_opaque_response(body_response_); |
| 1617 non_opaque_response.response_time = response_time; |
| 1618 EXPECT_EQ(0, CacheStorageCache::CalculateResponsePadding( |
| 1619 non_opaque_response, CreateTestPaddingKey().get(), |
| 1620 0 /* side_data_size */)); |
| 1621 EXPECT_TRUE(Put(non_opaque_request, non_opaque_response)); |
| 1622 int64_t unpadded_no_data_cache_size = Size(); |
| 1623 |
| 1624 // Now write some side data to that cache. |
| 1625 const std::string expected_side_data = "TheSideData"; |
| 1626 scoped_refptr<net::IOBuffer> side_data_buffer( |
| 1627 new net::StringIOBuffer(expected_side_data)); |
| 1628 EXPECT_TRUE(WriteSideData(non_opaque_request.url, response_time, |
| 1629 side_data_buffer, expected_side_data.length())); |
| 1630 int64_t unpadded_total_resource_size = Size(); |
| 1631 int64_t unpadded_side_data_size = |
| 1632 unpadded_total_resource_size - unpadded_no_data_cache_size; |
| 1633 EXPECT_EQ(expected_side_data.size(), |
| 1634 static_cast<size_t>(unpadded_side_data_size)); |
| 1635 EXPECT_EQ(0, CacheStorageCache::CalculateResponsePadding( |
| 1636 non_opaque_response, CreateTestPaddingKey().get(), |
| 1637 unpadded_side_data_size)); |
| 1638 |
| 1639 // Now write an identically sized opaque response. |
| 1640 ServiceWorkerFetchRequest opaque_request(non_opaque_request); |
| 1641 opaque_request.url = GURL("http://example.com/opaque.html"); |
| 1642 // Same URL length means same cache sizes (ignoring padding). |
| 1643 EXPECT_EQ(opaque_request.url.spec().length(), |
| 1644 non_opaque_request.url.spec().length()); |
| 1645 ServiceWorkerResponse opaque_response(non_opaque_response); |
| 1646 opaque_response.response_type = network::mojom::FetchResponseType::kOpaque; |
| 1647 opaque_response.response_time = response_time; |
| 1648 |
| 1649 EXPECT_TRUE(Put(opaque_request, opaque_response)); |
| 1650 // This test is fragile. Right now it deterministically adds non-zero padding. |
| 1651 // But if the url, padding key, or padding algorithm change it might become |
| 1652 // zero. |
| 1653 int64_t size_after_opaque_put = Size(); |
| 1654 int64_t opaque_padding = size_after_opaque_put - |
| 1655 2 * unpadded_no_data_cache_size - |
| 1656 unpadded_side_data_size; |
| 1657 ASSERT_GT(opaque_padding, 0); |
| 1658 |
| 1659 // Now write side data and expect to see the padding change. |
| 1660 EXPECT_TRUE(WriteSideData(opaque_request.url, response_time, side_data_buffer, |
| 1661 expected_side_data.length())); |
| 1662 int64_t current_padding = Size() - 2 * unpadded_total_resource_size; |
| 1663 EXPECT_NE(opaque_padding, current_padding); |
| 1664 |
| 1665 // Now reset opaque side data back to zero. |
| 1666 const std::string expected_side_data2 = ""; |
| 1667 scoped_refptr<net::IOBuffer> buffer2( |
| 1668 new net::StringIOBuffer(expected_side_data2)); |
| 1669 EXPECT_TRUE(WriteSideData(opaque_request.url, response_time, buffer2, |
| 1670 expected_side_data2.length())); |
| 1671 EXPECT_EQ(size_after_opaque_put, Size()); |
| 1672 |
| 1673 // And delete the opaque response entirely. |
| 1674 EXPECT_TRUE(Delete(opaque_request)); |
| 1675 EXPECT_EQ(unpadded_total_resource_size, Size()); |
| 1676 } |
| 1677 |
| 1678 TEST_F(CacheStorageCacheTest, TestDifferentOpaqueSideDataSizes) { |
| 1679 ServiceWorkerFetchRequest request(body_request_); |
| 1680 |
| 1681 ServiceWorkerResponse response(body_response_); |
| 1682 response.response_type = network::mojom::FetchResponseType::kOpaque; |
| 1683 base::Time response_time(base::Time::Now()); |
| 1684 response.response_time = response_time; |
| 1685 EXPECT_TRUE(Put(request, response)); |
| 1686 int64_t opaque_cache_size_no_side_data = Size(); |
| 1687 |
| 1688 const std::string small_side_data = "SmallSideData"; |
| 1689 scoped_refptr<net::IOBuffer> buffer1( |
| 1690 new net::StringIOBuffer(small_side_data)); |
| 1691 EXPECT_TRUE(WriteSideData(request.url, response_time, buffer1, |
| 1692 small_side_data.length())); |
| 1693 int64_t opaque_cache_size_with_side_data = Size(); |
| 1694 EXPECT_NE(opaque_cache_size_with_side_data, opaque_cache_size_no_side_data); |
| 1695 |
| 1696 // Write side data of a different size. The size should not affect the padding |
| 1697 // at all. |
| 1698 const std::string large_side_data = "LargerSideDataString"; |
| 1699 EXPECT_NE(large_side_data.length(), small_side_data.length()); |
| 1700 scoped_refptr<net::IOBuffer> buffer2( |
| 1701 new net::StringIOBuffer(large_side_data)); |
| 1702 EXPECT_TRUE(WriteSideData(request.url, response_time, buffer2, |
| 1703 large_side_data.length())); |
| 1704 int side_data_delta = large_side_data.length() - small_side_data.length(); |
| 1705 EXPECT_EQ(opaque_cache_size_with_side_data + side_data_delta, Size()); |
| 1706 } |
| 1707 |
| 1708 TEST_F(CacheStorageCacheTest, TestDoubleOpaquePut) { |
| 1709 ServiceWorkerFetchRequest request(body_request_); |
| 1710 |
| 1711 base::Time response_time(base::Time::Now()); |
| 1712 |
| 1713 ServiceWorkerResponse response(body_response_); |
| 1714 response.response_type = network::mojom::FetchResponseType::kOpaque; |
| 1715 response.response_time = response_time; |
| 1716 EXPECT_TRUE(Put(request, response)); |
| 1717 int64_t size_after_first_put = Size(); |
| 1718 |
| 1719 ServiceWorkerFetchRequest request2(body_request_); |
| 1720 ServiceWorkerResponse response2(body_response_); |
| 1721 response2.response_type = network::mojom::FetchResponseType::kOpaque; |
| 1722 response2.response_time = response_time; |
| 1723 EXPECT_TRUE(Put(request2, response2)); |
| 1724 |
| 1725 EXPECT_EQ(size_after_first_put, Size()); |
| 1726 } |
| 1727 |
| 1601 TEST_P(CacheStorageCacheTestP, GetSizeThenClose) { | 1728 TEST_P(CacheStorageCacheTestP, GetSizeThenClose) { |
| 1602 EXPECT_TRUE(Put(body_request_, body_response_)); | 1729 EXPECT_TRUE(Put(body_request_, body_response_)); |
| 1603 int64_t cache_size = Size(); | 1730 int64_t cache_size = Size(); |
| 1604 EXPECT_EQ(cache_size, GetSizeThenClose()); | 1731 EXPECT_EQ(cache_size, GetSizeThenClose()); |
| 1605 VerifyAllOpsFail(); | 1732 VerifyAllOpsFail(); |
| 1606 } | 1733 } |
| 1607 | 1734 |
| 1608 TEST_P(CacheStorageCacheTestP, OpsFailOnClosedBackend) { | 1735 TEST_P(CacheStorageCacheTestP, OpsFailOnClosedBackend) { |
| 1609 // Create the backend and put something in it. | 1736 // Create the backend and put something in it. |
| 1610 EXPECT_TRUE(Put(body_request_, body_response_)); | 1737 EXPECT_TRUE(Put(body_request_, body_response_)); |
| 1611 EXPECT_TRUE(Close()); | 1738 EXPECT_TRUE(Close()); |
| 1612 VerifyAllOpsFail(); | 1739 VerifyAllOpsFail(); |
| 1613 } | 1740 } |
| 1614 | 1741 |
| 1615 TEST_P(CacheStorageCacheTestP, VerifySerialScheduling) { | 1742 TEST_P(CacheStorageCacheTestP, VerifySerialScheduling) { |
| 1616 // Start two operations, the first one is delayed but the second isn't. The | 1743 // Start two operations, the first one is delayed but the second isn't. The |
| 1617 // second should wait for the first. | 1744 // second should wait for the first. |
| 1618 EXPECT_TRUE(Keys()); // Opens the backend. | 1745 EXPECT_TRUE(Keys()); // Opens the backend. |
| 1619 DelayableBackend* delayable_backend = cache_->UseDelayableBackend(); | 1746 DelayableBackend* delayable_backend = cache_->UseDelayableBackend(); |
| 1620 delayable_backend->set_delay_doom(true); | 1747 delayable_backend->set_delay_open_entry(true); |
| 1621 | 1748 |
| 1622 int sequence_out = -1; | 1749 int sequence_out = -1; |
| 1623 | 1750 |
| 1624 CacheStorageBatchOperation operation1; | 1751 CacheStorageBatchOperation operation1; |
| 1625 operation1.operation_type = CACHE_STORAGE_CACHE_OPERATION_TYPE_PUT; | 1752 operation1.operation_type = CACHE_STORAGE_CACHE_OPERATION_TYPE_PUT; |
| 1626 operation1.request = body_request_; | 1753 operation1.request = body_request_; |
| 1627 operation1.response = body_response_; | 1754 operation1.response = body_response_; |
| 1628 | 1755 |
| 1629 std::unique_ptr<base::RunLoop> close_loop1(new base::RunLoop()); | 1756 std::unique_ptr<base::RunLoop> close_loop1(new base::RunLoop()); |
| 1630 cache_->BatchOperation( | 1757 cache_->BatchOperation( |
| 1631 std::vector<CacheStorageBatchOperation>(1, operation1), | 1758 std::vector<CacheStorageBatchOperation>(1, operation1), |
| 1632 base::BindOnce(&CacheStorageCacheTest::SequenceCallback, | 1759 base::BindOnce(&CacheStorageCacheTest::SequenceCallback, |
| 1633 base::Unretained(this), 1, &sequence_out, | 1760 base::Unretained(this), 1, &sequence_out, |
| 1634 close_loop1.get())); | 1761 close_loop1.get())); |
| 1635 | 1762 |
| 1636 // Blocks on creating the cache entry. | 1763 // Blocks on creating the cache entry. |
| 1637 base::RunLoop().RunUntilIdle(); | 1764 base::RunLoop().RunUntilIdle(); |
| 1638 | 1765 |
| 1639 CacheStorageBatchOperation operation2; | 1766 CacheStorageBatchOperation operation2; |
| 1640 operation2.operation_type = CACHE_STORAGE_CACHE_OPERATION_TYPE_PUT; | 1767 operation2.operation_type = CACHE_STORAGE_CACHE_OPERATION_TYPE_PUT; |
| 1641 operation2.request = body_request_; | 1768 operation2.request = body_request_; |
| 1642 operation2.response = body_response_; | 1769 operation2.response = body_response_; |
| 1643 | 1770 |
| 1644 delayable_backend->set_delay_doom(false); | 1771 delayable_backend->set_delay_open_entry(false); |
| 1645 std::unique_ptr<base::RunLoop> close_loop2(new base::RunLoop()); | 1772 std::unique_ptr<base::RunLoop> close_loop2(new base::RunLoop()); |
| 1646 cache_->BatchOperation( | 1773 cache_->BatchOperation( |
| 1647 std::vector<CacheStorageBatchOperation>(1, operation2), | 1774 std::vector<CacheStorageBatchOperation>(1, operation2), |
| 1648 base::BindOnce(&CacheStorageCacheTest::SequenceCallback, | 1775 base::BindOnce(&CacheStorageCacheTest::SequenceCallback, |
| 1649 base::Unretained(this), 2, &sequence_out, | 1776 base::Unretained(this), 2, &sequence_out, |
| 1650 close_loop2.get())); | 1777 close_loop2.get())); |
| 1651 | 1778 |
| 1652 // The second put operation should wait for the first to complete. | 1779 // The second put operation should wait for the first to complete. |
| 1653 base::RunLoop().RunUntilIdle(); | 1780 base::RunLoop().RunUntilIdle(); |
| 1654 EXPECT_FALSE(callback_response_); | 1781 EXPECT_FALSE(callback_response_); |
| 1655 | 1782 |
| 1656 delayable_backend->DoomEntryContinue(); | 1783 EXPECT_TRUE(delayable_backend->OpenEntryContinue()); |
| 1657 close_loop1->Run(); | 1784 close_loop1->Run(); |
| 1658 EXPECT_EQ(1, sequence_out); | 1785 EXPECT_EQ(1, sequence_out); |
| 1659 close_loop2->Run(); | 1786 close_loop2->Run(); |
| 1660 EXPECT_EQ(2, sequence_out); | 1787 EXPECT_EQ(2, sequence_out); |
| 1661 } | 1788 } |
| 1662 | 1789 |
| 1663 INSTANTIATE_TEST_CASE_P(CacheStorageCacheTest, | 1790 INSTANTIATE_TEST_CASE_P(CacheStorageCacheTest, |
| 1664 CacheStorageCacheTestP, | 1791 CacheStorageCacheTestP, |
| 1665 ::testing::Values(false, true)); | 1792 ::testing::Values(false, true)); |
| 1666 | 1793 |
| 1667 } // namespace content | 1794 } // namespace content |
| OLD | NEW |