Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 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 "components/precache/content/precache_manager.h" | 5 #include "components/precache/content/precache_manager.h" |
| 6 | 6 |
| 7 #include <stddef.h> | 7 #include <stddef.h> |
| 8 | 8 |
| 9 #include <map> | 9 #include <map> |
| 10 #include <memory> | |
| 10 #include <set> | 11 #include <set> |
| 11 #include <string> | 12 #include <string> |
| 12 | 13 |
| 13 #include "base/bind.h" | 14 #include "base/bind.h" |
| 14 #include "base/callback.h" | 15 #include "base/callback.h" |
| 15 #include "base/command_line.h" | 16 #include "base/command_line.h" |
| 16 #include "base/compiler_specific.h" | 17 #include "base/compiler_specific.h" |
| 18 #include "base/files/file_path.h" | |
| 19 #include "base/files/scoped_temp_dir.h" | |
| 17 #include "base/location.h" | 20 #include "base/location.h" |
| 21 #include "base/run_loop.h" | |
| 18 #include "base/single_thread_task_runner.h" | 22 #include "base/single_thread_task_runner.h" |
| 19 #include "base/test/histogram_tester.h" | 23 #include "base/test/histogram_tester.h" |
| 20 #include "base/threading/thread_task_runner_handle.h" | 24 #include "base/threading/thread_task_runner_handle.h" |
| 21 #include "components/history/core/browser/history_constants.h" | 25 #include "components/history/core/browser/history_constants.h" |
| 22 #include "components/history/core/browser/history_service.h" | 26 #include "components/history/core/browser/history_service.h" |
| 23 #include "components/history/core/browser/history_types.h" | 27 #include "components/history/core/browser/history_types.h" |
| 28 #include "components/precache/core/precache_database.h" | |
| 24 #include "components/precache/core/precache_switches.h" | 29 #include "components/precache/core/precache_switches.h" |
| 30 #include "components/precache/core/proto/unfinished_work.pb.h" | |
| 25 #include "content/public/browser/browser_thread.h" | 31 #include "content/public/browser/browser_thread.h" |
| 26 #include "content/public/test/test_browser_context.h" | 32 #include "content/public/test/test_browser_context.h" |
| 27 #include "content/public/test/test_browser_thread_bundle.h" | 33 #include "content/public/test/test_browser_thread_bundle.h" |
| 28 #include "net/http/http_status_code.h" | 34 #include "net/http/http_status_code.h" |
| 29 #include "net/url_request/test_url_fetcher_factory.h" | 35 #include "net/url_request/test_url_fetcher_factory.h" |
| 30 #include "net/url_request/url_request_status.h" | 36 #include "net/url_request/url_request_status.h" |
| 31 #include "net/url_request/url_request_test_util.h" | 37 #include "net/url_request/url_request_test_util.h" |
| 32 #include "testing/gmock/include/gmock/gmock.h" | 38 #include "testing/gmock/include/gmock/gmock.h" |
| 33 #include "testing/gtest/include/gtest/gtest.h" | 39 #include "testing/gtest/include/gtest/gtest.h" |
| 34 #include "url/gurl.h" | 40 #include "url/gurl.h" |
| 35 | 41 |
| 36 namespace precache { | 42 namespace precache { |
| 37 | 43 |
| 38 namespace { | 44 namespace { |
| 39 | 45 |
| 40 using ::testing::_; | 46 using ::testing::_; |
| 41 using ::testing::ContainerEq; | 47 using ::testing::ContainerEq; |
| 42 using ::testing::ElementsAre; | 48 using ::testing::ElementsAre; |
| 43 using ::testing::Invoke; | 49 using ::testing::Invoke; |
| 44 using ::testing::IsEmpty; | 50 using ::testing::IsEmpty; |
| 45 using ::testing::Pair; | 51 using ::testing::Pair; |
| 46 using ::testing::SaveArg; | 52 using ::testing::SaveArg; |
| 47 | 53 |
| 48 const char kConfigURL[] = "http://config-url.com"; | 54 const char kConfigURL[] = "http://config-url.com"; |
| 49 const char kManifestURLPrefix[] = "http://manifest-url-prefix.com/"; | 55 const char kManifestURLPrefix[] = "http://manifest-url-prefix.com/"; |
| 50 const char kGoodManifestURL[] = | 56 const char kGoodManifestURL[] = |
| 51 "http://manifest-url-prefix.com/good-manifest.com"; | 57 "http://manifest-url-prefix.com/good-manifest.com"; |
| 58 const char kEvilManifestURL[] = | |
| 59 "http://manifest-url-prefix.com/evil-manifest.com"; | |
| 52 | 60 |
| 53 class TestURLFetcherCallback { | 61 class TestURLFetcherCallback { |
| 54 public: | 62 public: |
| 55 std::unique_ptr<net::FakeURLFetcher> CreateURLFetcher( | 63 std::unique_ptr<net::FakeURLFetcher> CreateURLFetcher( |
| 56 const GURL& url, | 64 const GURL& url, |
| 57 net::URLFetcherDelegate* delegate, | 65 net::URLFetcherDelegate* delegate, |
| 58 const std::string& response_data, | 66 const std::string& response_data, |
| 59 net::HttpStatusCode response_code, | 67 net::HttpStatusCode response_code, |
| 60 net::URLRequestStatus::Status status) { | 68 net::URLRequestStatus::Status status) { |
| 61 std::unique_ptr<net::FakeURLFetcher> fetcher(new net::FakeURLFetcher( | 69 std::unique_ptr<net::FakeURLFetcher> fetcher(new net::FakeURLFetcher( |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 110 bool was_on_done_called() const { | 118 bool was_on_done_called() const { |
| 111 return was_on_done_called_; | 119 return was_on_done_called_; |
| 112 } | 120 } |
| 113 | 121 |
| 114 private: | 122 private: |
| 115 bool was_on_done_called_; | 123 bool was_on_done_called_; |
| 116 }; | 124 }; |
| 117 | 125 |
| 118 class PrecacheManagerUnderTest : public PrecacheManager { | 126 class PrecacheManagerUnderTest : public PrecacheManager { |
| 119 public: | 127 public: |
| 120 PrecacheManagerUnderTest(content::BrowserContext* browser_context, | 128 PrecacheManagerUnderTest( |
| 121 const sync_driver::SyncService* const sync_service, | 129 content::BrowserContext* browser_context, |
| 122 const history::HistoryService* const history_service) | 130 const sync_driver::SyncService* const sync_service, |
| 123 : PrecacheManager(browser_context, sync_service, history_service), | 131 const history::HistoryService* const history_service, |
| 124 control_group_(false) {} | 132 const base::FilePath& db_path, |
| 133 std::unique_ptr<PrecacheDatabase> precache_database) | |
| 134 : PrecacheManager( | |
| 135 browser_context, sync_service, history_service, | |
| 136 db_path, std::move(precache_database)), | |
| 137 control_group_(false) { | |
| 138 } | |
| 125 bool IsInExperimentGroup() const override { return !control_group_; } | 139 bool IsInExperimentGroup() const override { return !control_group_; } |
| 126 bool IsInControlGroup() const override { return control_group_; } | 140 bool IsInControlGroup() const override { return control_group_; } |
| 127 bool IsPrecachingAllowed() const override { return true; } | 141 bool IsPrecachingAllowed() const override { return true; } |
| 128 void SetInControlGroup(bool in_control_group) { | 142 void SetInControlGroup(bool in_control_group) { |
| 129 control_group_ = in_control_group; | 143 control_group_ = in_control_group; |
| 130 } | 144 } |
| 131 | 145 |
| 132 private: | 146 private: |
| 133 bool control_group_; | 147 bool control_group_; |
| 134 }; | 148 }; |
| 135 | 149 |
| 136 class PrecacheManagerTest : public testing::Test { | 150 class PrecacheManagerTest : public testing::Test { |
| 137 public: | 151 public: |
| 138 PrecacheManagerTest() | 152 PrecacheManagerTest() |
| 139 : precache_manager_(&browser_context_, | 153 : factory_(nullptr, |
| 140 nullptr /* sync_service */, | |
| 141 &history_service_), | |
| 142 factory_(nullptr, | |
| 143 base::Bind(&TestURLFetcherCallback::CreateURLFetcher, | 154 base::Bind(&TestURLFetcherCallback::CreateURLFetcher, |
| 144 base::Unretained(&url_callback_))) {} | 155 base::Unretained(&url_callback_))) {} |
| 145 | 156 |
| 146 ~PrecacheManagerTest() { | 157 ~PrecacheManagerTest() { |
| 147 // precache_manager_'s constructor releases a PrecacheDatabase and deletes | 158 // precache_manager_'s constructor releases a PrecacheDatabase and deletes |
| 148 // it on the DB thread. PrecacheDatabase already has a pending Init call | 159 // it on the DB thread. PrecacheDatabase already has a pending Init call |
| 149 // which will assert in debug builds because the directory passed to it is | 160 // which will assert in debug builds because the directory passed to it is |
| 150 // deleted. So manually ensure that the task is run before browser_context_ | 161 // deleted. So manually ensure that the task is run before browser_context_ |
| 151 // is destructed. | 162 // is destructed. |
| 152 base::MessageLoop::current()->RunUntilIdle(); | 163 base::MessageLoop::current()->RunUntilIdle(); |
| 153 } | 164 } |
| 154 | 165 |
| 155 protected: | 166 protected: |
| 156 void SetUp() override { | 167 void SetUp() override { |
| 157 base::CommandLine::ForCurrentProcess()->AppendSwitchASCII( | 168 base::CommandLine::ForCurrentProcess()->AppendSwitchASCII( |
| 158 switches::kPrecacheConfigSettingsURL, kConfigURL); | 169 switches::kPrecacheConfigSettingsURL, kConfigURL); |
| 159 base::CommandLine::ForCurrentProcess()->AppendSwitchASCII( | 170 base::CommandLine::ForCurrentProcess()->AppendSwitchASCII( |
| 160 switches::kPrecacheManifestURLPrefix, kManifestURLPrefix); | 171 switches::kPrecacheManifestURLPrefix, kManifestURLPrefix); |
| 172 std::unique_ptr<PrecacheDatabase> precache_database( | |
| 173 new PrecacheDatabase()); | |
| 174 precache_database_ = precache_database.get(); | |
| 175 | |
| 176 ASSERT_TRUE(scoped_temp_dir_.CreateUniqueTempDir()); | |
| 177 base::FilePath db_path = scoped_temp_dir_.path().Append( | |
| 178 base::FilePath(FILE_PATH_LITERAL("precache_database"))); | |
| 161 | 179 |
| 162 // Make the fetch of the precache configuration settings fail. Precaching | 180 // Make the fetch of the precache configuration settings fail. Precaching |
| 163 // should still complete normally in this case. | 181 // should still complete normally in this case. |
| 164 factory_.SetFakeResponse(GURL(kConfigURL), "", | 182 factory_.SetFakeResponse(GURL(kConfigURL), "", |
| 165 net::HTTP_INTERNAL_SERVER_ERROR, | 183 net::HTTP_INTERNAL_SERVER_ERROR, |
| 166 net::URLRequestStatus::FAILED); | 184 net::URLRequestStatus::FAILED); |
| 185 precache_manager_.reset( | |
| 186 new PrecacheManagerUnderTest( | |
| 187 &browser_context_, nullptr /* sync_service */, | |
| 188 &history_service_, db_path, std::move(precache_database))); | |
| 189 base::MessageLoop::current()->RunUntilIdle(); | |
| 167 } | 190 } |
| 168 | 191 |
| 169 // Must be declared first so that it is destroyed last. | 192 // Must be declared first so that it is destroyed last. |
| 170 content::TestBrowserThreadBundle test_browser_thread_bundle_; | 193 content::TestBrowserThreadBundle test_browser_thread_bundle_; |
| 194 base::ScopedTempDir scoped_temp_dir_; | |
| 195 PrecacheDatabase* precache_database_; | |
| 171 content::TestBrowserContext browser_context_; | 196 content::TestBrowserContext browser_context_; |
| 172 PrecacheManagerUnderTest precache_manager_; | 197 std::unique_ptr<PrecacheManagerUnderTest> precache_manager_; |
| 173 TestURLFetcherCallback url_callback_; | 198 TestURLFetcherCallback url_callback_; |
| 174 net::FakeURLFetcherFactory factory_; | 199 net::FakeURLFetcherFactory factory_; |
| 175 TestPrecacheCompletionCallback precache_callback_; | 200 TestPrecacheCompletionCallback precache_callback_; |
| 176 testing::NiceMock<MockHistoryService> history_service_; | 201 testing::NiceMock<MockHistoryService> history_service_; |
| 177 base::HistogramTester histograms_; | 202 base::HistogramTester histograms_; |
| 178 }; | 203 }; |
| 179 | 204 |
| 180 TEST_F(PrecacheManagerTest, StartAndFinishPrecaching) { | 205 TEST_F(PrecacheManagerTest, StartAndFinishPrecaching) { |
| 181 EXPECT_FALSE(precache_manager_.IsPrecaching()); | 206 EXPECT_FALSE(precache_manager_->IsPrecaching()); |
| 182 | 207 |
| 183 MockHistoryService::TopHostsCallback top_hosts_callback; | 208 MockHistoryService::TopHostsCallback top_hosts_callback; |
| 184 EXPECT_CALL(history_service_, TopHosts(NumTopHosts(), _)) | 209 EXPECT_CALL(history_service_, TopHosts(NumTopHosts(), _)) |
| 185 .WillOnce(SaveArg<1>(&top_hosts_callback)); | 210 .WillOnce(SaveArg<1>(&top_hosts_callback)); |
| 186 | 211 |
| 187 factory_.SetFakeResponse(GURL(kGoodManifestURL), "", net::HTTP_OK, | 212 factory_.SetFakeResponse(GURL(kGoodManifestURL), "", net::HTTP_OK, |
| 188 net::URLRequestStatus::SUCCESS); | 213 net::URLRequestStatus::SUCCESS); |
| 189 | 214 |
| 190 precache_manager_.StartPrecaching(precache_callback_.GetCallback()); | 215 precache_manager_->StartPrecaching(precache_callback_.GetCallback()); |
| 191 | 216 base::MessageLoop::current()->RunUntilIdle(); |
| 192 EXPECT_TRUE(precache_manager_.IsPrecaching()); | 217 EXPECT_TRUE(precache_manager_->IsPrecaching()); |
| 193 | 218 |
| 194 top_hosts_callback.Run( | 219 top_hosts_callback.Run( |
| 195 history::TopHostsList(1, std::make_pair("good-manifest.com", 1))); | 220 history::TopHostsList(1, std::make_pair("good-manifest.com", 1))); |
| 196 base::MessageLoop::current()->RunUntilIdle(); // For PrecacheFetcher. | 221 base::MessageLoop::current()->RunUntilIdle(); // For PrecacheFetcher. |
| 197 EXPECT_FALSE(precache_manager_.IsPrecaching()); | 222 EXPECT_FALSE(precache_manager_->IsPrecaching()); |
| 198 EXPECT_TRUE(precache_callback_.was_on_done_called()); | 223 EXPECT_TRUE(precache_callback_.was_on_done_called()); |
| 199 | 224 |
| 200 std::multiset<GURL> expected_requested_urls; | 225 std::multiset<GURL> expected_requested_urls; |
| 201 expected_requested_urls.insert(GURL(kConfigURL)); | 226 expected_requested_urls.insert(GURL(kConfigURL)); |
| 202 expected_requested_urls.insert(GURL(kGoodManifestURL)); | 227 expected_requested_urls.insert(GURL(kGoodManifestURL)); |
| 203 EXPECT_EQ(expected_requested_urls, url_callback_.requested_urls()); | 228 EXPECT_EQ(expected_requested_urls, url_callback_.requested_urls()); |
| 204 } | 229 } |
| 205 | 230 |
| 231 TEST_F(PrecacheManagerTest, StartAndFinishPrecachingWithUnfinishedHosts) { | |
| 232 std::unique_ptr<PrecacheUnfinishedWork> unfinished_work( | |
| 233 new PrecacheUnfinishedWork()); | |
| 234 unfinished_work->add_top_host()->set_hostname("evil-manifest.com"); | |
| 235 unfinished_work->set_start_time(base::Time::Now().ToInternalValue()); | |
| 236 precache_database_->SaveUnfinishedWork(std::move(unfinished_work)); | |
| 237 | |
| 238 EXPECT_FALSE(precache_manager_->IsPrecaching()); | |
| 239 | |
| 240 factory_.SetFakeResponse( | |
| 241 GURL(kEvilManifestURL), "", | |
| 242 net::HTTP_OK, net::URLRequestStatus::SUCCESS); | |
| 243 | |
| 244 precache_manager_->StartPrecaching(precache_callback_.GetCallback()); | |
| 245 EXPECT_TRUE(precache_manager_->IsPrecaching()); | |
| 246 | |
| 247 base::MessageLoop::current()->RunUntilIdle(); // For PrecacheFetcher. | |
| 248 EXPECT_FALSE(precache_manager_->IsPrecaching()); | |
| 249 EXPECT_TRUE(precache_callback_.was_on_done_called()); | |
| 250 | |
| 251 std::multiset<GURL> expected_requested_urls; | |
| 252 expected_requested_urls.insert(GURL(kConfigURL)); | |
| 253 expected_requested_urls.insert(GURL(kEvilManifestURL)); | |
| 254 EXPECT_EQ(expected_requested_urls, url_callback_.requested_urls()); | |
| 255 } | |
| 256 | |
| 257 TEST_F(PrecacheManagerTest, | |
| 258 StartAndCancelPrecachingBeforeUnfinishedWorkRetrieved) { | |
| 259 EXPECT_FALSE(precache_manager_->IsPrecaching()); | |
| 260 | |
| 261 precache_manager_->StartPrecaching(precache_callback_.GetCallback()); | |
| 262 EXPECT_TRUE(precache_manager_->IsPrecaching()); | |
| 263 precache_manager_->CancelPrecaching(); | |
| 264 EXPECT_FALSE(precache_manager_->IsPrecaching()); | |
| 265 | |
| 266 base::MessageLoop::current()->RunUntilIdle(); | |
| 267 EXPECT_FALSE(precache_callback_.was_on_done_called()); | |
| 268 } | |
| 269 | |
| 206 TEST_F(PrecacheManagerTest, StartAndCancelPrecachingBeforeTopHostsCompleted) { | 270 TEST_F(PrecacheManagerTest, StartAndCancelPrecachingBeforeTopHostsCompleted) { |
| 207 EXPECT_FALSE(precache_manager_.IsPrecaching()); | 271 EXPECT_FALSE(precache_manager_->IsPrecaching()); |
| 208 | 272 |
| 209 MockHistoryService::TopHostsCallback top_hosts_callback; | 273 MockHistoryService::TopHostsCallback top_hosts_callback; |
| 210 EXPECT_CALL(history_service_, TopHosts(NumTopHosts(), _)) | 274 EXPECT_CALL(history_service_, TopHosts(NumTopHosts(), _)) |
| 211 .WillOnce(SaveArg<1>(&top_hosts_callback)); | 275 .WillOnce(SaveArg<1>(&top_hosts_callback)); |
| 212 | 276 |
| 213 precache_manager_.SetInControlGroup(true); | 277 precache_manager_->StartPrecaching(precache_callback_.GetCallback()); |
| 214 precache_manager_.StartPrecaching(precache_callback_.GetCallback()); | 278 EXPECT_TRUE(precache_manager_->IsPrecaching()); |
| 215 EXPECT_TRUE(precache_manager_.IsPrecaching()); | |
| 216 | 279 |
| 217 precache_manager_.CancelPrecaching(); | 280 precache_manager_->CancelPrecaching(); |
| 218 EXPECT_FALSE(precache_manager_.IsPrecaching()); | 281 EXPECT_FALSE(precache_manager_->IsPrecaching()); |
| 282 base::MessageLoop::current()->RunUntilIdle(); | |
| 219 | 283 |
| 220 top_hosts_callback.Run( | 284 top_hosts_callback.Run( |
| 221 history::TopHostsList(1, std::make_pair("starting-url.com", 1))); | 285 history::TopHostsList(1, std::make_pair("starting-url.com", 1))); |
| 222 EXPECT_FALSE(precache_manager_.IsPrecaching()); | 286 base::MessageLoop::current()->RunUntilIdle(); |
| 287 EXPECT_FALSE(precache_manager_->IsPrecaching()); | |
| 223 EXPECT_FALSE(precache_callback_.was_on_done_called()); | 288 EXPECT_FALSE(precache_callback_.was_on_done_called()); |
| 224 } | 289 } |
| 225 | 290 |
| 226 TEST_F(PrecacheManagerTest, StartAndCancelPrecachingBeforeURLsReceived) { | 291 TEST_F(PrecacheManagerTest, StartAndCancelPrecachingBeforeURLsReceived) { |
| 227 EXPECT_FALSE(precache_manager_.IsPrecaching()); | 292 EXPECT_FALSE(precache_manager_->IsPrecaching()); |
| 228 | 293 |
| 229 MockHistoryService::TopHostsCallback top_hosts_callback; | 294 MockHistoryService::TopHostsCallback top_hosts_callback; |
| 230 EXPECT_CALL(history_service_, TopHosts(NumTopHosts(), _)) | 295 EXPECT_CALL(history_service_, TopHosts(NumTopHosts(), _)) |
| 231 .WillOnce(SaveArg<1>(&top_hosts_callback)); | 296 .WillOnce(SaveArg<1>(&top_hosts_callback)); |
| 232 | 297 |
| 233 precache_manager_.StartPrecaching(precache_callback_.GetCallback()); | 298 precache_manager_->StartPrecaching(precache_callback_.GetCallback()); |
| 234 EXPECT_TRUE(precache_manager_.IsPrecaching()); | 299 EXPECT_TRUE(precache_manager_->IsPrecaching()); |
| 235 | 300 |
| 236 precache_manager_.CancelPrecaching(); | 301 precache_manager_->CancelPrecaching(); |
| 237 EXPECT_FALSE(precache_manager_.IsPrecaching()); | 302 base::MessageLoop::current()->RunUntilIdle(); |
| 238 | 303 EXPECT_FALSE(precache_manager_->IsPrecaching()); |
| 239 top_hosts_callback.Run( | 304 top_hosts_callback.Run( |
| 240 history::TopHostsList(1, std::make_pair("starting-url.com", 1))); | 305 history::TopHostsList(1, std::make_pair("starting-url.com", 1))); |
| 241 base::MessageLoop::current()->RunUntilIdle(); // For PrecacheFetcher. | 306 base::MessageLoop::current()->RunUntilIdle(); // For PrecacheFetcher. |
| 242 EXPECT_FALSE(precache_manager_.IsPrecaching()); | 307 EXPECT_FALSE(precache_manager_->IsPrecaching()); |
| 243 EXPECT_FALSE(precache_callback_.was_on_done_called()); | 308 EXPECT_FALSE(precache_callback_.was_on_done_called()); |
| 244 EXPECT_TRUE(url_callback_.requested_urls().empty()); | 309 EXPECT_TRUE(url_callback_.requested_urls().empty()); |
| 245 } | 310 } |
| 246 | 311 |
| 247 TEST_F(PrecacheManagerTest, StartAndCancelPrecachingAfterURLsReceived) { | 312 TEST_F(PrecacheManagerTest, StartAndCancelPrecachingAfterURLsReceived) { |
| 248 EXPECT_FALSE(precache_manager_.IsPrecaching()); | 313 EXPECT_FALSE(precache_manager_->IsPrecaching()); |
| 314 | |
| 315 PrecacheManifest good_manifest; | |
| 316 good_manifest.add_resource()->set_url("http://good-resource.com"); | |
| 249 | 317 |
| 250 EXPECT_CALL(history_service_, TopHosts(NumTopHosts(), _)) | 318 EXPECT_CALL(history_service_, TopHosts(NumTopHosts(), _)) |
| 251 .WillOnce(ReturnHosts( | 319 .WillOnce(ReturnHosts( |
| 252 history::TopHostsList(1, std::make_pair("starting-url.com", 1)))); | 320 history::TopHostsList(1, std::make_pair("starting-url.com", 1)))); |
| 253 | 321 |
| 254 precache_manager_.StartPrecaching(precache_callback_.GetCallback()); | 322 precache_manager_->StartPrecaching(precache_callback_.GetCallback()); |
| 255 | 323 |
| 256 // Since the |history_service_| ran the callback immediately, Start() has | 324 EXPECT_TRUE(precache_manager_->IsPrecaching()); |
| 257 // been called on the PrecacheFetcher, and the precache config settings have | 325 // Run a task to get unfinished work, and to get hosts. |
| 258 // been requested. The response has not yet been received though, so | 326 for (int i = 0; i < 2; ++i) { |
| 259 // precaching is still in progress. | 327 base::RunLoop run_loop; |
| 260 EXPECT_TRUE(precache_manager_.IsPrecaching()); | 328 base::MessageLoop::current()->PostTask(FROM_HERE, run_loop.QuitClosure()); |
| 261 | 329 run_loop.Run(); |
| 262 precache_manager_.CancelPrecaching(); | 330 } |
| 263 EXPECT_FALSE(precache_manager_.IsPrecaching()); | 331 //base::MessageLoop::current()->RunUntilIdle(); |
| 332 precache_manager_->CancelPrecaching(); | |
| 333 EXPECT_FALSE(precache_manager_->IsPrecaching()); | |
| 264 | 334 |
| 265 base::MessageLoop::current()->RunUntilIdle(); // For PrecacheFetcher. | 335 base::MessageLoop::current()->RunUntilIdle(); // For PrecacheFetcher. |
| 266 EXPECT_FALSE(precache_manager_.IsPrecaching()); | 336 EXPECT_FALSE(precache_manager_->IsPrecaching()); |
| 267 EXPECT_FALSE(precache_callback_.was_on_done_called()); | 337 EXPECT_FALSE(precache_callback_.was_on_done_called()); |
| 268 | 338 |
| 269 // Even though the response for the precache config settings should not have | |
| 270 // been received, the request should still have been made. | |
| 271 std::multiset<GURL> expected_requested_urls; | 339 std::multiset<GURL> expected_requested_urls; |
| 272 expected_requested_urls.insert(GURL(kConfigURL)); | 340 expected_requested_urls.insert(GURL(kConfigURL)); |
| 273 EXPECT_EQ(expected_requested_urls, url_callback_.requested_urls()); | 341 EXPECT_EQ(expected_requested_urls, url_callback_.requested_urls()); |
| 274 } | 342 } |
| 275 | 343 |
| 276 TEST_F(PrecacheManagerTest, RecordStatsForFetchWithSizeZero) { | 344 TEST_F(PrecacheManagerTest, RecordStatsForFetchWithSizeZero) { |
| 277 // Fetches with size 0 should be ignored. | 345 // Fetches with size 0 should be ignored. |
| 278 precache_manager_.RecordStatsForFetch(GURL("http://url.com"), GURL(), | 346 precache_manager_->RecordStatsForFetch(GURL("http://url.com"), GURL(), |
| 279 base::TimeDelta(), base::Time(), 0, | 347 base::TimeDelta(), base::Time(), 0, |
| 280 false); | 348 false); |
| 281 base::MessageLoop::current()->RunUntilIdle(); | 349 base::MessageLoop::current()->RunUntilIdle(); |
| 282 EXPECT_THAT(histograms_.GetTotalCountsForPrefix("Precache."), IsEmpty()); | 350 EXPECT_THAT(histograms_.GetTotalCountsForPrefix("Precache."), IsEmpty()); |
| 283 } | 351 } |
| 284 | 352 |
| 285 TEST_F(PrecacheManagerTest, RecordStatsForFetchWithNonHTTP) { | 353 TEST_F(PrecacheManagerTest, RecordStatsForFetchWithNonHTTP) { |
| 286 // Fetches for URLs with schemes other than HTTP or HTTPS should be ignored. | 354 // Fetches for URLs with schemes other than HTTP or HTTPS should be ignored. |
| 287 precache_manager_.RecordStatsForFetch(GURL("ftp://ftp.com"), GURL(), | 355 precache_manager_->RecordStatsForFetch(GURL("ftp://ftp.com"), GURL(), |
| 288 base::TimeDelta(), base::Time(), 1000, | 356 base::TimeDelta(), base::Time(), 1000, |
| 289 false); | 357 false); |
| 290 base::MessageLoop::current()->RunUntilIdle(); | 358 base::MessageLoop::current()->RunUntilIdle(); |
| 291 EXPECT_THAT(histograms_.GetTotalCountsForPrefix("Precache."), IsEmpty()); | 359 EXPECT_THAT(histograms_.GetTotalCountsForPrefix("Precache."), IsEmpty()); |
| 292 } | 360 } |
| 293 | 361 |
| 294 TEST_F(PrecacheManagerTest, RecordStatsForFetchWithEmptyURL) { | 362 TEST_F(PrecacheManagerTest, RecordStatsForFetchWithEmptyURL) { |
| 295 // Fetches for empty URLs should be ignored. | 363 // Fetches for empty URLs should be ignored. |
| 296 precache_manager_.RecordStatsForFetch(GURL(), GURL(), base::TimeDelta(), | 364 precache_manager_->RecordStatsForFetch(GURL(), GURL(), base::TimeDelta(), |
| 297 base::Time(), 1000, false); | 365 base::Time(), 1000, false); |
| 298 base::MessageLoop::current()->RunUntilIdle(); | 366 base::MessageLoop::current()->RunUntilIdle(); |
| 299 EXPECT_THAT(histograms_.GetTotalCountsForPrefix("Precache."), IsEmpty()); | 367 EXPECT_THAT(histograms_.GetTotalCountsForPrefix("Precache."), IsEmpty()); |
| 300 } | 368 } |
| 301 | 369 |
| 302 TEST_F(PrecacheManagerTest, RecordStatsForFetchDuringPrecaching) { | 370 TEST_F(PrecacheManagerTest, RecordStatsForFetchDuringPrecaching) { |
| 303 EXPECT_CALL(history_service_, TopHosts(NumTopHosts(), _)) | 371 EXPECT_CALL(history_service_, TopHosts(NumTopHosts(), _)) |
| 304 .WillOnce(ReturnHosts(history::TopHostsList())); | 372 .WillOnce(ReturnHosts(history::TopHostsList())); |
| 305 | 373 |
| 306 precache_manager_.StartPrecaching(precache_callback_.GetCallback()); | 374 precache_manager_->StartPrecaching(precache_callback_.GetCallback()); |
| 307 | 375 |
| 308 EXPECT_TRUE(precache_manager_.IsPrecaching()); | 376 EXPECT_TRUE(precache_manager_->IsPrecaching()); |
| 309 precache_manager_.RecordStatsForFetch(GURL("http://url.com"), GURL(), | 377 precache_manager_->RecordStatsForFetch(GURL("http://url.com"), GURL(), |
| 310 base::TimeDelta(), base::Time(), 1000, | 378 base::TimeDelta(), base::Time(), 1000, |
| 311 false); | 379 false); |
| 312 | 380 base::MessageLoop::current()->RunUntilIdle(); |
| 313 precache_manager_.CancelPrecaching(); | 381 precache_manager_->CancelPrecaching(); |
| 314 | 382 |
| 315 // For PrecacheFetcher and RecordURLPrecached. | 383 // For PrecacheFetcher and RecordURLPrecached. |
| 316 base::MessageLoop::current()->RunUntilIdle(); | 384 base::MessageLoop::current()->RunUntilIdle(); |
| 317 EXPECT_THAT(histograms_.GetTotalCountsForPrefix("Precache."), | 385 EXPECT_THAT(histograms_.GetTotalCountsForPrefix("Precache."), |
| 318 ElementsAre(Pair("Precache.DownloadedPrecacheMotivated", 1), | 386 ElementsAre(Pair("Precache.DownloadedPrecacheMotivated", 1), |
| 319 Pair("Precache.Fetch.PercentCompleted", 1), | 387 Pair("Precache.Fetch.PercentCompleted", 1), |
| 320 Pair("Precache.Fetch.ResponseBytes.Network", 1), | 388 Pair("Precache.Fetch.ResponseBytes.Network", 1), |
| 321 Pair("Precache.Fetch.ResponseBytes.Total", 1), | 389 Pair("Precache.Fetch.ResponseBytes.Total", 1), |
| 322 Pair("Precache.Fetch.TimeToComplete", 1), | 390 Pair("Precache.Fetch.TimeToComplete", 1), |
| 323 Pair("Precache.Latency.Prefetch", 1))); | 391 Pair("Precache.Latency.Prefetch", 1))); |
| 324 } | 392 } |
| 325 | 393 |
| 326 TEST_F(PrecacheManagerTest, RecordStatsForFetchHTTP) { | 394 TEST_F(PrecacheManagerTest, RecordStatsForFetchHTTP) { |
| 327 precache_manager_.RecordStatsForFetch(GURL("http://http-url.com"), GURL(), | 395 precache_manager_->RecordStatsForFetch(GURL("http://http-url.com"), GURL(), |
| 328 base::TimeDelta(), base::Time(), 1000, | 396 base::TimeDelta(), base::Time(), 1000, |
| 329 false); | 397 false); |
| 330 base::MessageLoop::current()->RunUntilIdle(); | 398 base::MessageLoop::current()->RunUntilIdle(); |
| 331 | 399 |
| 332 EXPECT_THAT(histograms_.GetTotalCountsForPrefix("Precache."), | 400 EXPECT_THAT(histograms_.GetTotalCountsForPrefix("Precache."), |
| 333 ElementsAre(Pair("Precache.DownloadedNonPrecache", 1), | 401 ElementsAre(Pair("Precache.DownloadedNonPrecache", 1), |
| 334 Pair("Precache.Latency.NonPrefetch", 1), | 402 Pair("Precache.Latency.NonPrefetch", 1), |
| 335 Pair("Precache.Latency.NonPrefetch.NonTopHosts", 1))); | 403 Pair("Precache.Latency.NonPrefetch.NonTopHosts", 1))); |
| 336 } | 404 } |
| 337 | 405 |
| 338 TEST_F(PrecacheManagerTest, RecordStatsForFetchHTTPS) { | 406 TEST_F(PrecacheManagerTest, RecordStatsForFetchHTTPS) { |
| 339 precache_manager_.RecordStatsForFetch(GURL("https://https-url.com"), GURL(), | 407 precache_manager_->RecordStatsForFetch(GURL("https://https-url.com"), GURL(), |
| 340 base::TimeDelta(), base::Time(), 1000, | 408 base::TimeDelta(), base::Time(), 1000, |
| 341 false); | 409 false); |
| 342 base::MessageLoop::current()->RunUntilIdle(); | 410 base::MessageLoop::current()->RunUntilIdle(); |
| 343 | 411 |
| 344 EXPECT_THAT(histograms_.GetTotalCountsForPrefix("Precache."), | 412 EXPECT_THAT(histograms_.GetTotalCountsForPrefix("Precache."), |
| 345 ElementsAre(Pair("Precache.DownloadedNonPrecache", 1), | 413 ElementsAre(Pair("Precache.DownloadedNonPrecache", 1), |
| 346 Pair("Precache.Latency.NonPrefetch", 1), | 414 Pair("Precache.Latency.NonPrefetch", 1), |
| 347 Pair("Precache.Latency.NonPrefetch.NonTopHosts", 1))); | 415 Pair("Precache.Latency.NonPrefetch.NonTopHosts", 1))); |
| 348 } | 416 } |
| 349 | 417 |
| 350 TEST_F(PrecacheManagerTest, RecordStatsForFetchInTopHosts) { | 418 TEST_F(PrecacheManagerTest, RecordStatsForFetchInTopHosts) { |
| 351 EXPECT_CALL(history_service_, | 419 EXPECT_CALL(history_service_, |
| 352 HostRankIfAvailable(GURL("http://referrer.com"), _)) | 420 HostRankIfAvailable(GURL("http://referrer.com"), _)) |
| 353 .WillOnce(Invoke( | 421 .WillOnce(Invoke( |
| 354 [](const GURL& url, const base::Callback<void(int)>& callback) { | 422 [](const GURL& url, const base::Callback<void(int)>& callback) { |
| 355 callback.Run(0); | 423 callback.Run(0); |
| 356 })); | 424 })); |
| 357 precache_manager_.RecordStatsForFetch( | 425 precache_manager_->RecordStatsForFetch( |
| 358 GURL("http://http-url.com"), GURL("http://referrer.com"), | 426 GURL("http://http-url.com"), GURL("http://referrer.com"), |
| 359 base::TimeDelta(), base::Time(), 1000, false); | 427 base::TimeDelta(), base::Time(), 1000, false); |
| 360 base::MessageLoop::current()->RunUntilIdle(); | 428 base::MessageLoop::current()->RunUntilIdle(); |
| 361 | 429 |
| 362 EXPECT_THAT(histograms_.GetTotalCountsForPrefix("Precache."), | 430 EXPECT_THAT(histograms_.GetTotalCountsForPrefix("Precache."), |
| 363 ElementsAre(Pair("Precache.DownloadedNonPrecache", 1), | 431 ElementsAre(Pair("Precache.DownloadedNonPrecache", 1), |
| 364 Pair("Precache.Latency.NonPrefetch", 1), | 432 Pair("Precache.Latency.NonPrefetch", 1), |
| 365 Pair("Precache.Latency.NonPrefetch.TopHosts", 1))); | 433 Pair("Precache.Latency.NonPrefetch.TopHosts", 1))); |
| 366 } | 434 } |
| 367 | 435 |
| 368 TEST_F(PrecacheManagerTest, DeleteExpiredPrecacheHistory) { | 436 TEST_F(PrecacheManagerTest, DeleteExpiredPrecacheHistory) { |
| 369 // TODO(twifkak): Split this into multiple tests. | 437 // TODO(twifkak): Split this into multiple tests. |
| 370 base::HistogramTester::CountsMap expected_histogram_count_map; | 438 base::HistogramTester::CountsMap expected_histogram_count_map; |
| 371 | 439 |
| 372 // This test has to use Time::Now() because StartPrecaching uses Time::Now(). | 440 // This test has to use Time::Now() because StartPrecaching uses Time::Now(). |
| 373 const base::Time kCurrentTime = base::Time::Now(); | 441 const base::Time kCurrentTime = base::Time::Now(); |
| 374 EXPECT_CALL(history_service_, TopHosts(NumTopHosts(), _)) | 442 EXPECT_CALL(history_service_, TopHosts(NumTopHosts(), _)) |
| 375 .Times(2) | 443 .Times(2) |
| 376 .WillRepeatedly(ReturnHosts(history::TopHostsList())); | 444 .WillRepeatedly(ReturnHosts(history::TopHostsList())); |
| 377 | 445 |
| 378 precache_manager_.StartPrecaching(precache_callback_.GetCallback()); | 446 precache_manager_->StartPrecaching(precache_callback_.GetCallback()); |
| 379 EXPECT_TRUE(precache_manager_.IsPrecaching()); | 447 EXPECT_TRUE(precache_manager_->IsPrecaching()); |
| 380 | 448 |
| 381 // Precache a bunch of URLs, with different fetch times. | 449 // Precache a bunch of URLs, with different fetch times. |
| 382 precache_manager_.RecordStatsForFetch( | 450 precache_manager_->RecordStatsForFetch( |
| 383 GURL("http://old-fetch.com"), GURL(), base::TimeDelta(), | 451 GURL("http://old-fetch.com"), GURL(), base::TimeDelta(), |
| 384 kCurrentTime - base::TimeDelta::FromDays(61), 1000, false); | 452 kCurrentTime - base::TimeDelta::FromDays(61), 1000, false); |
| 385 precache_manager_.RecordStatsForFetch( | 453 precache_manager_->RecordStatsForFetch( |
| 386 GURL("http://recent-fetch.com"), GURL(), base::TimeDelta(), | 454 GURL("http://recent-fetch.com"), GURL(), base::TimeDelta(), |
| 387 kCurrentTime - base::TimeDelta::FromDays(59), 1000, false); | 455 kCurrentTime - base::TimeDelta::FromDays(59), 1000, false); |
| 388 precache_manager_.RecordStatsForFetch( | 456 precache_manager_->RecordStatsForFetch( |
| 389 GURL("http://yesterday-fetch.com"), GURL(), base::TimeDelta(), | 457 GURL("http://yesterday-fetch.com"), GURL(), base::TimeDelta(), |
| 390 kCurrentTime - base::TimeDelta::FromDays(1), 1000, false); | 458 kCurrentTime - base::TimeDelta::FromDays(1), 1000, false); |
| 391 expected_histogram_count_map["Precache.DownloadedPrecacheMotivated"] += 3; | 459 expected_histogram_count_map["Precache.DownloadedPrecacheMotivated"] += 3; |
| 392 expected_histogram_count_map["Precache.Fetch.PercentCompleted"]++; | 460 expected_histogram_count_map["Precache.Fetch.PercentCompleted"]++; |
| 393 expected_histogram_count_map["Precache.Fetch.ResponseBytes.Network"]++; | 461 expected_histogram_count_map["Precache.Fetch.ResponseBytes.Network"]++; |
| 394 expected_histogram_count_map["Precache.Fetch.ResponseBytes.Total"]++; | 462 expected_histogram_count_map["Precache.Fetch.ResponseBytes.Total"]++; |
| 395 expected_histogram_count_map["Precache.Fetch.TimeToComplete"]++; | 463 expected_histogram_count_map["Precache.Fetch.TimeToComplete"]++; |
| 396 expected_histogram_count_map["Precache.Latency.Prefetch"] += 3; | 464 expected_histogram_count_map["Precache.Latency.Prefetch"] += 3; |
| 465 base::MessageLoop::current()->RunUntilIdle(); | |
| 397 | 466 |
| 398 precache_manager_.CancelPrecaching(); | 467 precache_manager_->CancelPrecaching(); |
| 468 base::MessageLoop::current()->RunUntilIdle(); | |
| 469 | |
| 470 // Disable pause-resume. | |
| 471 precache_database_->DeleteUnfinishedWork(); | |
| 472 base::MessageLoop::current()->RunUntilIdle(); | |
| 473 | |
| 399 // For PrecacheFetcher and RecordURLPrecached. | 474 // For PrecacheFetcher and RecordURLPrecached. |
| 400 base::MessageLoop::current()->RunUntilIdle(); | 475 base::MessageLoop::current()->RunUntilIdle(); |
| 401 EXPECT_THAT(histograms_.GetTotalCountsForPrefix("Precache."), | 476 EXPECT_THAT(histograms_.GetTotalCountsForPrefix("Precache."), |
| 402 ContainerEq(expected_histogram_count_map)); | 477 ContainerEq(expected_histogram_count_map)); |
| 403 | 478 |
| 404 // The expired precache will be deleted during precaching this time. | 479 // The expired precache will be deleted during precaching this time. |
| 405 precache_manager_.StartPrecaching(precache_callback_.GetCallback()); | 480 precache_manager_->StartPrecaching(precache_callback_.GetCallback()); |
| 406 EXPECT_TRUE(precache_manager_.IsPrecaching()); | 481 EXPECT_TRUE(precache_manager_->IsPrecaching()); |
| 482 base::MessageLoop::current()->RunUntilIdle(); | |
| 483 | |
| 484 // The precache fetcher runs until done, which records these histograms, | |
| 485 // and then cancels precaching, which records these histograms again. | |
| 486 // In practice | |
| 407 expected_histogram_count_map["Precache.Fetch.PercentCompleted"]++; | 487 expected_histogram_count_map["Precache.Fetch.PercentCompleted"]++; |
| 408 expected_histogram_count_map["Precache.Fetch.ResponseBytes.Network"]++; | 488 expected_histogram_count_map["Precache.Fetch.ResponseBytes.Network"]++; |
| 409 expected_histogram_count_map["Precache.Fetch.ResponseBytes.Total"]++; | 489 expected_histogram_count_map["Precache.Fetch.ResponseBytes.Total"]++; |
| 410 | 490 //precache_manager_->CancelPrecaching(); |
|
sclittle
2016/05/20 21:57:07
nit: remove commented line?
bengr
2016/05/21 00:16:32
Done.
| |
| 411 precache_manager_.CancelPrecaching(); | |
| 412 // For PrecacheFetcher and RecordURLPrecached. | 491 // For PrecacheFetcher and RecordURLPrecached. |
| 413 base::MessageLoop::current()->RunUntilIdle(); | 492 base::MessageLoop::current()->RunUntilIdle(); |
| 414 EXPECT_FALSE(precache_manager_.IsPrecaching()); | 493 EXPECT_FALSE(precache_manager_->IsPrecaching()); |
| 415 | 494 |
| 416 // A fetch for the same URL as the expired precache was served from the cache, | 495 // A fetch for the same URL as the expired precache was served from the cache, |
| 417 // but it isn't reported as saved bytes because it had expired in the precache | 496 // but it isn't reported as saved bytes because it had expired in the precache |
| 418 // history. | 497 // history. |
| 419 precache_manager_.RecordStatsForFetch(GURL("http://old-fetch.com"), GURL(), | 498 precache_manager_->RecordStatsForFetch(GURL("http://old-fetch.com"), GURL(), |
| 420 base::TimeDelta(), kCurrentTime, 1000, | 499 base::TimeDelta(), kCurrentTime, 1000, |
| 421 true); | 500 true); |
| 422 expected_histogram_count_map["Precache.Fetch.TimeToComplete"]++; | 501 expected_histogram_count_map["Precache.Fetch.TimeToComplete"]++; |
| 423 expected_histogram_count_map["Precache.Latency.NonPrefetch"]++; | 502 expected_histogram_count_map["Precache.Latency.NonPrefetch"]++; |
| 424 expected_histogram_count_map["Precache.Latency.NonPrefetch.NonTopHosts"]++; | 503 expected_histogram_count_map["Precache.Latency.NonPrefetch.NonTopHosts"]++; |
| 425 | 504 |
| 426 base::MessageLoop::current()->RunUntilIdle(); | 505 base::MessageLoop::current()->RunUntilIdle(); |
| 427 EXPECT_THAT(histograms_.GetTotalCountsForPrefix("Precache."), | 506 EXPECT_THAT(histograms_.GetTotalCountsForPrefix("Precache."), |
| 428 ContainerEq(expected_histogram_count_map)); | 507 ContainerEq(expected_histogram_count_map)); |
| 429 | 508 |
| 430 // The other precaches should not have expired, so the following fetches from | 509 // The other precaches should not have expired, so the following fetches from |
| 431 // the cache should count as saved bytes. | 510 // the cache should count as saved bytes. |
| 432 precache_manager_.RecordStatsForFetch(GURL("http://recent-fetch.com"), GURL(), | 511 precache_manager_->RecordStatsForFetch(GURL("http://recent-fetch.com"), GURL() , |
| 433 base::TimeDelta(), kCurrentTime, 1000, | 512 base::TimeDelta(), kCurrentTime, 1000, |
| 434 true); | 513 true); |
| 435 precache_manager_.RecordStatsForFetch(GURL("http://yesterday-fetch.com"), | 514 precache_manager_->RecordStatsForFetch(GURL("http://yesterday-fetch.com"), |
| 436 GURL(), base::TimeDelta(), kCurrentTime, | 515 GURL(), base::TimeDelta(), kCurrentTime, |
| 437 1000, true); | 516 1000, true); |
| 438 expected_histogram_count_map["Precache.Latency.NonPrefetch"] += 2; | 517 expected_histogram_count_map["Precache.Latency.NonPrefetch"] += 2; |
| 439 expected_histogram_count_map["Precache.Latency.NonPrefetch.NonTopHosts"] += 2; | 518 expected_histogram_count_map["Precache.Latency.NonPrefetch.NonTopHosts"] += 2; |
| 440 expected_histogram_count_map["Precache.Saved"] += 2; | 519 expected_histogram_count_map["Precache.Saved"] += 2; |
| 441 | 520 |
| 442 base::MessageLoop::current()->RunUntilIdle(); | 521 base::MessageLoop::current()->RunUntilIdle(); |
| 443 EXPECT_THAT(histograms_.GetTotalCountsForPrefix("Precache."), | 522 EXPECT_THAT(histograms_.GetTotalCountsForPrefix("Precache."), |
| 444 ContainerEq(expected_histogram_count_map)); | 523 ContainerEq(expected_histogram_count_map)); |
| 445 } | 524 } |
| 446 | 525 |
| 447 } // namespace | 526 } // namespace |
| 448 | 527 |
| 449 } // namespace precache | 528 } // namespace precache |
| OLD | NEW |