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 "chrome/browser/predictors/resource_prefetch_predictor.h" | 5 #include "chrome/browser/predictors/resource_prefetch_predictor.h" |
6 | 6 |
7 #include <iostream> | 7 #include <iostream> |
8 #include <memory> | 8 #include <memory> |
9 #include <utility> | 9 #include <utility> |
10 | 10 |
11 #include "base/memory/ptr_util.h" | 11 #include "base/memory/ptr_util.h" |
12 #include "base/memory/ref_counted.h" | 12 #include "base/memory/ref_counted.h" |
13 #include "base/run_loop.h" | 13 #include "base/run_loop.h" |
14 #include "base/test/histogram_tester.h" | 14 #include "base/test/histogram_tester.h" |
15 #include "base/time/time.h" | 15 #include "base/time/time.h" |
16 #include "chrome/browser/history/history_service_factory.h" | 16 #include "chrome/browser/history/history_service_factory.h" |
17 #include "chrome/browser/predictors/resource_prefetch_predictor_tables.h" | 17 #include "chrome/browser/predictors/resource_prefetch_predictor_tables.h" |
18 #include "chrome/browser/predictors/resource_prefetch_predictor_test_util.h" | 18 #include "chrome/browser/predictors/resource_prefetch_predictor_test_util.h" |
19 #include "chrome/browser/predictors/resource_prefetcher_manager.h" | |
19 #include "chrome/test/base/testing_profile.h" | 20 #include "chrome/test/base/testing_profile.h" |
20 #include "components/history/core/browser/history_service.h" | 21 #include "components/history/core/browser/history_service.h" |
21 #include "components/history/core/browser/history_types.h" | 22 #include "components/history/core/browser/history_types.h" |
22 #include "components/sessions/core/session_id.h" | 23 #include "components/sessions/core/session_id.h" |
23 #include "content/public/browser/resource_request_info.h" | 24 #include "content/public/browser/resource_request_info.h" |
24 #include "content/public/test/test_browser_thread_bundle.h" | 25 #include "content/public/test/test_browser_thread_bundle.h" |
25 #include "net/http/http_response_headers.h" | 26 #include "net/http/http_response_headers.h" |
26 #include "net/url_request/url_request_context.h" | 27 #include "net/url_request/url_request_context.h" |
27 #include "net/url_request/url_request_job.h" | 28 #include "net/url_request/url_request_job.h" |
28 #include "net/url_request/url_request_test_util.h" | 29 #include "net/url_request/url_request_test_util.h" |
29 #include "testing/gmock/include/gmock/gmock.h" | 30 #include "testing/gmock/include/gmock/gmock.h" |
30 #include "testing/gtest/include/gtest/gtest.h" | 31 #include "testing/gtest/include/gtest/gtest.h" |
31 | 32 |
32 using testing::ContainerEq; | 33 using testing::ContainerEq; |
33 using testing::Pointee; | 34 using testing::Pointee; |
34 using testing::SetArgPointee; | 35 using testing::SetArgPointee; |
35 using testing::StrictMock; | 36 using testing::StrictMock; |
36 using testing::UnorderedElementsAre; | 37 using testing::UnorderedElementsAre; |
37 | 38 |
38 namespace predictors { | 39 namespace predictors { |
39 | 40 |
41 namespace { | |
42 constexpr int kDefaultMode = LoadingPredictorConfig::LEARNING | | |
43 LoadingPredictorConfig::PREFETCHING_FOR_EXTERNAL; | |
44 } // namespace | |
45 | |
40 using URLRequestSummary = ResourcePrefetchPredictor::URLRequestSummary; | 46 using URLRequestSummary = ResourcePrefetchPredictor::URLRequestSummary; |
41 using PageRequestSummary = ResourcePrefetchPredictor::PageRequestSummary; | 47 using PageRequestSummary = ResourcePrefetchPredictor::PageRequestSummary; |
42 using PrefetchDataMap = ResourcePrefetchPredictorTables::PrefetchDataMap; | 48 using PrefetchDataMap = ResourcePrefetchPredictorTables::PrefetchDataMap; |
43 using RedirectDataMap = ResourcePrefetchPredictorTables::RedirectDataMap; | 49 using RedirectDataMap = ResourcePrefetchPredictorTables::RedirectDataMap; |
44 using ManifestDataMap = ResourcePrefetchPredictorTables::ManifestDataMap; | 50 using ManifestDataMap = ResourcePrefetchPredictorTables::ManifestDataMap; |
45 using OriginDataMap = ResourcePrefetchPredictorTables::OriginDataMap; | 51 using OriginDataMap = ResourcePrefetchPredictorTables::OriginDataMap; |
46 | 52 |
47 scoped_refptr<net::HttpResponseHeaders> MakeResponseHeaders( | 53 scoped_refptr<net::HttpResponseHeaders> MakeResponseHeaders( |
48 const char* headers) { | 54 const char* headers) { |
49 return make_scoped_refptr(new net::HttpResponseHeaders( | 55 return make_scoped_refptr(new net::HttpResponseHeaders( |
(...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
167 explicit MockResourcePrefetchPredictorObserver( | 173 explicit MockResourcePrefetchPredictorObserver( |
168 ResourcePrefetchPredictor* predictor) | 174 ResourcePrefetchPredictor* predictor) |
169 : TestObserver(predictor) {} | 175 : TestObserver(predictor) {} |
170 | 176 |
171 MOCK_METHOD2( | 177 MOCK_METHOD2( |
172 OnNavigationLearned, | 178 OnNavigationLearned, |
173 void(size_t url_visit_count, | 179 void(size_t url_visit_count, |
174 const ResourcePrefetchPredictor::PageRequestSummary& summary)); | 180 const ResourcePrefetchPredictor::PageRequestSummary& summary)); |
175 }; | 181 }; |
176 | 182 |
183 // Does nothing when a prefetch starts. | |
184 class MockResourcePrefetcherManager : public ResourcePrefetcherManager { | |
185 public: | |
186 using ResourcePrefetcherManager::ResourcePrefetcherManager; | |
187 MOCK_METHOD2(MaybeAddPrefetch, | |
188 void(const GURL& main_frame_url, const std::vector<GURL>& urls)); | |
189 | |
190 protected: | |
191 ~MockResourcePrefetcherManager() {} | |
192 | |
193 private: | |
194 DISALLOW_COPY_AND_ASSIGN(MockResourcePrefetcherManager); | |
195 }; | |
196 | |
177 class ResourcePrefetchPredictorTest : public testing::Test { | 197 class ResourcePrefetchPredictorTest : public testing::Test { |
178 public: | 198 public: |
179 ResourcePrefetchPredictorTest(); | 199 ResourcePrefetchPredictorTest(); |
180 ~ResourcePrefetchPredictorTest() override; | 200 ~ResourcePrefetchPredictorTest() override; |
181 void SetUp() override; | 201 void SetUp() override; |
182 void TearDown() override; | 202 void TearDown() override; |
183 | 203 |
184 protected: | 204 protected: |
185 void AddUrlToHistory(const std::string& url, int visit_count) { | 205 void AddUrlToHistory(const std::string& url, int visit_count) { |
186 HistoryServiceFactory::GetForProfile(profile_.get(), | 206 HistoryServiceFactory::GetForProfile(profile_.get(), |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
220 false, true, content::PREVIEWS_OFF); | 240 false, true, content::PREVIEWS_OFF); |
221 request->Start(); | 241 request->Start(); |
222 return request; | 242 return request; |
223 } | 243 } |
224 | 244 |
225 void InitializePredictor() { | 245 void InitializePredictor() { |
226 predictor_->StartInitialization(); | 246 predictor_->StartInitialization(); |
227 base::RunLoop loop; | 247 base::RunLoop loop; |
228 loop.RunUntilIdle(); // Runs the DB lookup. | 248 loop.RunUntilIdle(); // Runs the DB lookup. |
229 profile_->BlockUntilHistoryProcessesPendingRequests(); | 249 profile_->BlockUntilHistoryProcessesPendingRequests(); |
250 | |
251 mock_prefetch_manager_ = nullptr; | |
252 if (predictor_->prefetch_manager_) { | |
253 mock_prefetch_manager_ = new StrictMock<MockResourcePrefetcherManager>( | |
254 predictor_.get(), predictor_->config_, | |
255 predictor_->profile_->GetRequestContext()); | |
256 predictor_->set_mock_resource_prefetcher_manager(mock_prefetch_manager_); | |
257 } | |
230 } | 258 } |
231 | 259 |
232 void ResetPredictor() { | 260 void ResetPredictor(int mode = kDefaultMode) { |
alexilin
2017/05/23 11:01:39
It changes the current behavior of tests. Why not
Benoit L
2017/05/29 16:45:14
Done.
| |
233 LoadingPredictorConfig config; | 261 LoadingPredictorConfig config; |
234 config.max_urls_to_track = 3; | 262 config.max_urls_to_track = 3; |
235 config.max_hosts_to_track = 2; | 263 config.max_hosts_to_track = 2; |
236 config.min_url_visit_count = 2; | 264 config.min_url_visit_count = 2; |
237 config.max_resources_per_entry = 4; | 265 config.max_resources_per_entry = 4; |
238 config.max_consecutive_misses = 2; | 266 config.max_consecutive_misses = 2; |
239 config.max_redirect_consecutive_misses = 2; | 267 config.max_redirect_consecutive_misses = 2; |
240 config.min_resource_confidence_to_trigger_prefetch = 0.5; | 268 config.min_resource_confidence_to_trigger_prefetch = 0.5; |
241 config.is_url_learning_enabled = true; | 269 config.is_url_learning_enabled = true; |
242 config.is_manifests_enabled = true; | 270 config.is_manifests_enabled = true; |
243 config.is_origin_learning_enabled = true; | 271 config.is_origin_learning_enabled = true; |
272 config.mode = mode; | |
244 | 273 |
245 config.mode |= LoadingPredictorConfig::LEARNING; | 274 predictor_ = |
246 predictor_.reset(new ResourcePrefetchPredictor(config, profile_.get())); | 275 base::MakeUnique<ResourcePrefetchPredictor>(config, profile_.get()); |
247 predictor_->set_mock_tables(mock_tables_); | 276 predictor_->set_mock_tables(mock_tables_); |
248 } | 277 } |
249 | 278 |
250 void InitializeSampleData(); | 279 void InitializeSampleData(); |
251 void TestRedirectStatusHistogram( | 280 void TestRedirectStatusHistogram( |
252 const std::string& predictor_initial_key, | 281 const std::string& predictor_initial_key, |
253 const std::string& predictor_key, | 282 const std::string& predictor_key, |
254 const std::string& navigation_initial_url, | 283 const std::string& navigation_initial_url, |
255 const std::string& navigation_url, | 284 const std::string& navigation_url, |
256 ResourcePrefetchPredictor::RedirectStatus expected_status); | 285 ResourcePrefetchPredictor::RedirectStatus expected_status); |
257 | 286 |
258 content::TestBrowserThreadBundle thread_bundle_; | 287 content::TestBrowserThreadBundle thread_bundle_; |
259 std::unique_ptr<TestingProfile> profile_; | 288 std::unique_ptr<TestingProfile> profile_; |
260 net::TestURLRequestContext url_request_context_; | 289 net::TestURLRequestContext url_request_context_; |
261 | 290 |
262 std::unique_ptr<ResourcePrefetchPredictor> predictor_; | 291 std::unique_ptr<ResourcePrefetchPredictor> predictor_; |
263 scoped_refptr<StrictMock<MockResourcePrefetchPredictorTables>> mock_tables_; | 292 scoped_refptr<StrictMock<MockResourcePrefetchPredictorTables>> mock_tables_; |
293 scoped_refptr<StrictMock<MockResourcePrefetcherManager>> | |
294 mock_prefetch_manager_; | |
264 | 295 |
265 PrefetchDataMap test_url_data_; | 296 PrefetchDataMap test_url_data_; |
266 PrefetchDataMap test_host_data_; | 297 PrefetchDataMap test_host_data_; |
267 RedirectDataMap test_url_redirect_data_; | 298 RedirectDataMap test_url_redirect_data_; |
268 RedirectDataMap test_host_redirect_data_; | 299 RedirectDataMap test_host_redirect_data_; |
269 ManifestDataMap test_manifest_data_; | 300 ManifestDataMap test_manifest_data_; |
270 OriginDataMap test_origin_data_; | 301 OriginDataMap test_origin_data_; |
271 | 302 |
272 MockURLRequestJobFactory url_request_job_factory_; | 303 MockURLRequestJobFactory url_request_job_factory_; |
273 EmptyURLRequestDelegate url_request_delegate_; | 304 EmptyURLRequestDelegate url_request_delegate_; |
(...skipping 1814 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2088 | 2119 |
2089 TEST_F(ResourcePrefetchPredictorTest, | 2120 TEST_F(ResourcePrefetchPredictorTest, |
2090 TestRedirectStatusRedirectCorrectlyPredicted) { | 2121 TestRedirectStatusRedirectCorrectlyPredicted) { |
2091 TestRedirectStatusHistogram( | 2122 TestRedirectStatusHistogram( |
2092 "google.com", "www.google.com", "http://google.com?query=cats", | 2123 "google.com", "www.google.com", "http://google.com?query=cats", |
2093 "http://www.google.com?query=cats", | 2124 "http://www.google.com?query=cats", |
2094 ResourcePrefetchPredictor::RedirectStatus::REDIRECT_CORRECTLY_PREDICTED); | 2125 ResourcePrefetchPredictor::RedirectStatus::REDIRECT_CORRECTLY_PREDICTED); |
2095 } | 2126 } |
2096 | 2127 |
2097 TEST_F(ResourcePrefetchPredictorTest, TestPrefetchingDurationHistogram) { | 2128 TEST_F(ResourcePrefetchPredictorTest, TestPrefetchingDurationHistogram) { |
2098 // Prefetching duration for an url without resources in the database | 2129 // Fill the database to record a duration. |
alexilin
2017/05/23 11:01:39
Why changing this test?
We wanted to record prefet
| |
2099 // shouldn't be recorded. | 2130 for (const auto& kv : test_host_data_) |
alexilin
2017/05/23 11:01:39
nit:
predictor_->host_table_cache_ = test_host_dat
| |
2100 const std::string main_frame_url = "http://google.com/?query=cats"; | 2131 predictor_->host_table_cache_->insert(kv); |
2101 predictor_->StartPrefetching(GURL(main_frame_url), HintOrigin::EXTERNAL); | |
2102 predictor_->StopPrefetching(GURL(main_frame_url)); | |
2103 histogram_tester_->ExpectTotalCount( | |
2104 internal::kResourcePrefetchPredictorPrefetchingDurationHistogram, 0); | |
2105 | 2132 |
2106 // Fill the database to record a duration. | 2133 using testing::_; |
2107 PrefetchData google = CreatePrefetchData("google.com", 1); | 2134 EXPECT_CALL(*mock_prefetch_manager_.get(), MaybeAddPrefetch(_, _)); |
2108 InitializeResourceData( | |
2109 google.add_resources(), "https://cdn.google.com/script.js", | |
2110 content::RESOURCE_TYPE_SCRIPT, 10, 0, 1, 2.1, net::MEDIUM, false, false); | |
2111 predictor_->host_table_cache_->insert( | |
2112 std::make_pair(google.primary_key(), google)); | |
2113 | 2135 |
2114 predictor_->StartPrefetching(GURL(main_frame_url), HintOrigin::EXTERNAL); | 2136 const GURL url = GURL("http://www.facebook.com/cats"); |
2115 predictor_->StopPrefetching(GURL(main_frame_url)); | 2137 predictor_->StartPrefetching(url, HintOrigin::EXTERNAL); |
2138 predictor_->StopPrefetching(url); | |
2116 histogram_tester_->ExpectTotalCount( | 2139 histogram_tester_->ExpectTotalCount( |
2117 internal::kResourcePrefetchPredictorPrefetchingDurationHistogram, 1); | 2140 internal::kResourcePrefetchPredictorPrefetchingDurationHistogram, 1); |
2118 } | 2141 } |
2119 | 2142 |
2120 TEST_F(ResourcePrefetchPredictorTest, TestRecordFirstContentfulPaint) { | 2143 TEST_F(ResourcePrefetchPredictorTest, TestRecordFirstContentfulPaint) { |
2121 using testing::_; | 2144 using testing::_; |
2122 EXPECT_CALL(*mock_tables_.get(), UpdateRedirectData(_, _)); | 2145 EXPECT_CALL(*mock_tables_.get(), UpdateRedirectData(_, _)); |
2123 EXPECT_CALL(*mock_tables_.get(), UpdateOriginData(_)); | 2146 EXPECT_CALL(*mock_tables_.get(), UpdateOriginData(_)); |
2124 | 2147 |
2125 auto res1_time = base::TimeTicks::FromInternalValue(1); | 2148 auto res1_time = base::TimeTicks::FromInternalValue(1); |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2163 content::RESOURCE_TYPE_SCRIPT, 1, 0, 0, 3.0, | 2186 content::RESOURCE_TYPE_SCRIPT, 1, 0, 0, 3.0, |
2164 net::MEDIUM, false, false); | 2187 net::MEDIUM, false, false); |
2165 resource3_rd->set_before_first_contentful_paint(false); | 2188 resource3_rd->set_before_first_contentful_paint(false); |
2166 EXPECT_CALL(*mock_tables_.get(), | 2189 EXPECT_CALL(*mock_tables_.get(), |
2167 UpdateResourceData(host_data, PREFETCH_KEY_TYPE_HOST)); | 2190 UpdateResourceData(host_data, PREFETCH_KEY_TYPE_HOST)); |
2168 | 2191 |
2169 predictor_->RecordMainFrameLoadComplete(main_frame.navigation_id); | 2192 predictor_->RecordMainFrameLoadComplete(main_frame.navigation_id); |
2170 profile_->BlockUntilHistoryProcessesPendingRequests(); | 2193 profile_->BlockUntilHistoryProcessesPendingRequests(); |
2171 } | 2194 } |
2172 | 2195 |
2196 TEST_F(ResourcePrefetchPredictorTest, TestCanPrefetchUrlForOrigin) { | |
2197 for (const auto& kv : test_host_data_) | |
alexilin
2017/05/23 11:01:39
ditto
| |
2198 predictor_->host_table_cache_->insert(kv); | |
2199 | |
2200 const GURL url = GURL("http://www.facebook.com/cats"); | |
2201 EXPECT_TRUE(predictor_->CanPrefetchUrlForOrigin(url, HintOrigin::EXTERNAL)); | |
2202 | |
2203 // Unknown host. | |
2204 EXPECT_FALSE(predictor_->CanPrefetchUrlForOrigin(GURL("https://unknown.com"), | |
2205 HintOrigin::EXTERNAL)); | |
2206 // Wrong origin. | |
2207 EXPECT_FALSE( | |
2208 predictor_->CanPrefetchUrlForOrigin(url, HintOrigin::NAVIGATION)); | |
2209 | |
2210 // Prefetching not enabled. | |
2211 EXPECT_CALL(*mock_tables_.get(), | |
2212 GetAllData(Pointee(ContainerEq(PrefetchDataMap())), | |
2213 Pointee(ContainerEq(PrefetchDataMap())), | |
2214 Pointee(ContainerEq(RedirectDataMap())), | |
2215 Pointee(ContainerEq(RedirectDataMap())), | |
2216 Pointee(ContainerEq(ManifestDataMap())), | |
2217 Pointee(ContainerEq(OriginDataMap())))); | |
2218 ResetPredictor(LoadingPredictorConfig::LEARNING); | |
2219 InitializePredictor(); | |
2220 for (const auto& kv : test_host_data_) | |
alexilin
2017/05/23 11:01:39
ditto
| |
2221 predictor_->host_table_cache_->insert(kv); | |
2222 | |
2223 EXPECT_FALSE(predictor_->CanPrefetchUrlForOrigin(url, HintOrigin::EXTERNAL)); | |
2224 } | |
2225 | |
2173 } // namespace predictors | 2226 } // namespace predictors |
OLD | NEW |