| OLD | NEW |
| (Empty) |
| 1 // Copyright (c) 2015 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 <algorithm> | |
| 6 #include <memory> | |
| 7 #include <set> | |
| 8 #include <string> | |
| 9 #include <vector> | |
| 10 | |
| 11 #include "base/memory/ptr_util.h" | |
| 12 #include "base/strings/string_number_conversions.h" | |
| 13 #include "base/synchronization/waitable_event.h" | |
| 14 #include "base/threading/platform_thread.h" | |
| 15 #include "chrome/browser/browsing_data/cache_test_util.h" | |
| 16 #include "chrome/browser/profiles/profile.h" | |
| 17 #include "chrome/browser/ui/browser.h" | |
| 18 #include "chrome/test/base/in_process_browser_test.h" | |
| 19 #include "components/browsing_data/content/conditional_cache_deletion_helper.h" | |
| 20 #include "content/public/browser/browser_context.h" | |
| 21 #include "content/public/browser/browser_thread.h" | |
| 22 #include "content/public/browser/storage_partition.h" | |
| 23 #include "net/disk_cache/disk_cache.h" | |
| 24 #include "net/http/http_cache.h" | |
| 25 #include "net/url_request/url_request_context.h" | |
| 26 #include "net/url_request/url_request_context_getter.h" | |
| 27 | |
| 28 using browsing_data::ConditionalCacheDeletionHelper; | |
| 29 using content::BrowserThread; | |
| 30 | |
| 31 namespace { | |
| 32 | |
| 33 bool KeyIsEven(const disk_cache::Entry* entry) { | |
| 34 int key_as_int = 0; | |
| 35 base::StringToInt(entry->GetKey().c_str(), &key_as_int); | |
| 36 return (key_as_int % 2) == 0; | |
| 37 } | |
| 38 | |
| 39 bool HasHttpsExampleOrigin(const GURL& url) { | |
| 40 return url.GetOrigin() == "https://example.com/"; | |
| 41 } | |
| 42 | |
| 43 } // namespace | |
| 44 | |
| 45 class ConditionalCacheDeletionHelperBrowserTest : public InProcessBrowserTest { | |
| 46 public: | |
| 47 void SetUpOnMainThread() override { | |
| 48 cache_util_ = base::MakeUnique<CacheTestUtil>( | |
| 49 content::BrowserContext::GetDefaultStoragePartition( | |
| 50 browser()->profile())); | |
| 51 done_callback_ = | |
| 52 base::Bind(&ConditionalCacheDeletionHelperBrowserTest::DoneCallback, | |
| 53 base::Unretained(this)); | |
| 54 // UI and IO thread synchronization. | |
| 55 waitable_event_ = base::MakeUnique<base::WaitableEvent>( | |
| 56 base::WaitableEvent::ResetPolicy::AUTOMATIC, | |
| 57 base::WaitableEvent::InitialState::NOT_SIGNALED); | |
| 58 } | |
| 59 | |
| 60 void TearDownOnMainThread() override { cache_util_.reset(); } | |
| 61 | |
| 62 void DeleteEntries( | |
| 63 const base::Callback<bool(const disk_cache::Entry*)>& condition) { | |
| 64 DCHECK_CURRENTLY_ON(BrowserThread::IO); | |
| 65 auto* helper = | |
| 66 new ConditionalCacheDeletionHelper(cache_util_->backend(), condition); | |
| 67 | |
| 68 helper->DeleteAndDestroySelfWhenFinished(done_callback_); | |
| 69 } | |
| 70 | |
| 71 void CompareRemainingKeys(std::set<std::string> expected_set) { | |
| 72 std::vector<std::string> remaining_keys = cache_util_->GetEntryKeys(); | |
| 73 std::sort(remaining_keys.begin(), remaining_keys.end()); | |
| 74 std::vector<std::string> expected; | |
| 75 expected.assign(expected_set.begin(), expected_set.end()); | |
| 76 EXPECT_EQ(expected, remaining_keys); | |
| 77 } | |
| 78 | |
| 79 void DoneCallback(int value) { | |
| 80 DCHECK_GE(value, 0); // Negative values represent an error. | |
| 81 DCHECK_CURRENTLY_ON(BrowserThread::IO); | |
| 82 waitable_event_->Signal(); | |
| 83 } | |
| 84 | |
| 85 void WaitForTasksOnIOThread() { | |
| 86 DCHECK_CURRENTLY_ON(BrowserThread::UI); | |
| 87 waitable_event_->Wait(); | |
| 88 } | |
| 89 | |
| 90 CacheTestUtil* GetCacheTestUtil() { return cache_util_.get(); } | |
| 91 | |
| 92 private: | |
| 93 base::Callback<void(int)> done_callback_; | |
| 94 std::unique_ptr<CacheTestUtil> cache_util_; | |
| 95 std::unique_ptr<base::WaitableEvent> waitable_event_; | |
| 96 }; | |
| 97 | |
| 98 // Tests that ConditionalCacheDeletionHelper only deletes those cache entries | |
| 99 // that match the condition. | |
| 100 IN_PROC_BROWSER_TEST_F(ConditionalCacheDeletionHelperBrowserTest, Condition) { | |
| 101 // Create 5 entries. | |
| 102 std::set<std::string> keys = {"123", "47", "56", "81", "42"}; | |
| 103 | |
| 104 GetCacheTestUtil()->CreateCacheEntries(keys); | |
| 105 | |
| 106 // Delete the entries whose keys are even numbers. | |
| 107 BrowserThread::PostTask( | |
| 108 BrowserThread::IO, FROM_HERE, | |
| 109 base::Bind(&ConditionalCacheDeletionHelperBrowserTest::DeleteEntries, | |
| 110 base::Unretained(this), | |
| 111 base::Bind(&KeyIsEven))); | |
| 112 WaitForTasksOnIOThread(); | |
| 113 | |
| 114 // Expect that the keys with values 56 and 42 were deleted. | |
| 115 keys.erase("56"); | |
| 116 keys.erase("42"); | |
| 117 CompareRemainingKeys(keys); | |
| 118 } | |
| 119 | |
| 120 // Tests that ConditionalCacheDeletionHelper correctly constructs a condition | |
| 121 // for time and URL. | |
| 122 // | |
| 123 // Note: This test depends on the timing in cache backends and can be flaky | |
| 124 // if those backends are slow. If this turns out to be a problem, consider | |
| 125 // increasing the |timeout_ms| constant. | |
| 126 // | |
| 127 // Flakily timing out on Mac 10.11 (crbug.com/646119) and flakily | |
| 128 // failing on Linux/ChromeOS (crbug.com/624836). | |
| 129 #if defined(OS_MACOSX) || defined(OS_LINUX) || defined(OS_CHROMEOS) | |
| 130 #define MAYBE_TimeAndURL DISABLED_TimeAndURL | |
| 131 #else | |
| 132 #define MAYBE_TimeAndURL TimeAndURL | |
| 133 #endif | |
| 134 IN_PROC_BROWSER_TEST_F(ConditionalCacheDeletionHelperBrowserTest, | |
| 135 MAYBE_TimeAndURL) { | |
| 136 const int64_t timeout_ms = 1; | |
| 137 | |
| 138 // Create some entries. | |
| 139 std::set<std::string> keys; | |
| 140 keys.insert("https://google.com/index.html"); | |
| 141 keys.insert("https://example.com/foo/bar/icon.png"); | |
| 142 keys.insert("http://chrome.com"); | |
| 143 | |
| 144 GetCacheTestUtil()->CreateCacheEntries(keys); | |
| 145 | |
| 146 // Wait |timeout_ms| milliseconds for the cache to write the entries. | |
| 147 // This assures that future entries will have timestamps strictly greater than | |
| 148 // the ones we just added. | |
| 149 base::PlatformThread::Sleep(base::TimeDelta::FromMilliseconds(timeout_ms)); | |
| 150 base::Time now = base::Time::Now(); | |
| 151 | |
| 152 // Create a few more entries with a later timestamp. | |
| 153 std::set<std::string> newer_keys; | |
| 154 newer_keys.insert("https://google.com/"); | |
| 155 newer_keys.insert("https://example.com/foo/bar/icon2.png"); | |
| 156 newer_keys.insert("https://example.com/foo/bar/icon3.png"); | |
| 157 newer_keys.insert("http://example.com/foo/bar/icon4.png"); | |
| 158 | |
| 159 GetCacheTestUtil()->CreateCacheEntries(newer_keys); | |
| 160 | |
| 161 // Create a condition for entries with the "https://example.com" origin | |
| 162 // created after waiting. | |
| 163 base::Callback<bool(const disk_cache::Entry*)> condition = | |
| 164 ConditionalCacheDeletionHelper::CreateURLAndTimeCondition( | |
| 165 base::Bind(&HasHttpsExampleOrigin), now, base::Time::Max()); | |
| 166 | |
| 167 // Delete the entries. | |
| 168 BrowserThread::PostTask( | |
| 169 BrowserThread::IO, FROM_HERE, | |
| 170 base::Bind(&ConditionalCacheDeletionHelperBrowserTest::DeleteEntries, | |
| 171 base::Unretained(this), | |
| 172 base::ConstRef(condition))); | |
| 173 WaitForTasksOnIOThread(); | |
| 174 | |
| 175 // Expect that only "icon2.png" and "icon3.png" were deleted. | |
| 176 keys.insert(newer_keys.begin(), newer_keys.end()); | |
| 177 keys.erase("https://example.com/foo/bar/icon2.png"); | |
| 178 keys.erase("https://example.com/foo/bar/icon3.png"); | |
| 179 CompareRemainingKeys(keys); | |
| 180 } | |
| OLD | NEW |