Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2016 The Chromium Authors. All rights reserved. | 1 // Copyright 2016 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 "base/command_line.h" | 5 #include "base/command_line.h" |
| 6 #include "chrome/browser/predictors/resource_prefetch_predictor.h" | 6 #include "chrome/browser/predictors/resource_prefetch_predictor.h" |
| 7 #include "chrome/browser/predictors/resource_prefetch_predictor_factory.h" | 7 #include "chrome/browser/predictors/resource_prefetch_predictor_factory.h" |
| 8 #include "chrome/browser/predictors/resource_prefetch_predictor_test_util.h" | 8 #include "chrome/browser/predictors/resource_prefetch_predictor_test_util.h" |
| 9 #include "chrome/browser/profiles/profile.h" | 9 #include "chrome/browser/profiles/profile.h" |
| 10 #include "chrome/browser/ui/browser.h" | 10 #include "chrome/browser/ui/browser.h" |
| 11 #include "chrome/browser/ui/browser_commands.h" | |
| 11 #include "chrome/browser/ui/tabs/tab_strip_model.h" | 12 #include "chrome/browser/ui/tabs/tab_strip_model.h" |
| 12 #include "chrome/common/chrome_switches.h" | 13 #include "chrome/common/chrome_switches.h" |
| 13 #include "chrome/test/base/in_process_browser_test.h" | 14 #include "chrome/test/base/in_process_browser_test.h" |
| 14 #include "chrome/test/base/ui_test_utils.h" | 15 #include "chrome/test/base/ui_test_utils.h" |
| 15 #include "content/public/browser/render_frame_host.h" | 16 #include "content/public/browser/render_frame_host.h" |
| 16 #include "content/public/browser/render_process_host.h" | 17 #include "content/public/browser/render_process_host.h" |
| 17 #include "net/test/embedded_test_server/http_request.h" | 18 #include "net/test/embedded_test_server/http_request.h" |
| 18 #include "net/test/embedded_test_server/http_response.h" | 19 #include "net/test/embedded_test_server/http_response.h" |
| 19 #include "testing/gmock/include/gmock/gmock.h" | 20 #include "testing/gmock/include/gmock/gmock.h" |
| 20 #include "testing/gtest/include/gtest/gtest.h" | 21 #include "testing/gtest/include/gtest/gtest.h" |
| (...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 105 }), | 106 }), |
| 106 subresources.end()); | 107 subresources.end()); |
| 107 return subresources; | 108 return subresources; |
| 108 } | 109 } |
| 109 | 110 |
| 110 } // namespace | 111 } // namespace |
| 111 | 112 |
| 112 // Helper class to track and allow waiting for ResourcePrefetchPredictor events. | 113 // Helper class to track and allow waiting for ResourcePrefetchPredictor events. |
| 113 // These events are also used to verify that ResourcePrefetchPredictor works as | 114 // These events are also used to verify that ResourcePrefetchPredictor works as |
| 114 // expected. | 115 // expected. |
| 115 class ResourcePrefetchPredictorTestObserver : public TestObserver { | 116 class LearningObserver : public TestObserver { |
| 116 public: | 117 public: |
| 117 using PageRequestSummary = ResourcePrefetchPredictor::PageRequestSummary; | 118 using PageRequestSummary = ResourcePrefetchPredictor::PageRequestSummary; |
| 118 | 119 |
| 119 explicit ResourcePrefetchPredictorTestObserver( | 120 explicit LearningObserver(ResourcePrefetchPredictor* predictor, |
| 120 ResourcePrefetchPredictor* predictor, | 121 const size_t expected_url_visit_count, |
| 121 const size_t expected_url_visit_count, | 122 const PageRequestSummary& expected_summary) |
| 122 const PageRequestSummary& expected_summary) | |
| 123 : TestObserver(predictor), | 123 : TestObserver(predictor), |
| 124 url_visit_count_(expected_url_visit_count), | 124 url_visit_count_(expected_url_visit_count), |
| 125 summary_(expected_summary) {} | 125 summary_(expected_summary) {} |
| 126 | 126 |
| 127 // TestObserver: | 127 // TestObserver: |
| 128 void OnNavigationLearned(size_t url_visit_count, | 128 void OnNavigationLearned(size_t url_visit_count, |
| 129 const PageRequestSummary& summary) override { | 129 const PageRequestSummary& summary) override { |
| 130 EXPECT_EQ(url_visit_count, url_visit_count_); | 130 EXPECT_EQ(url_visit_count, url_visit_count_); |
| 131 EXPECT_EQ(summary.main_frame_url, summary_.main_frame_url); | 131 EXPECT_EQ(summary.main_frame_url, summary_.main_frame_url); |
| 132 EXPECT_EQ(summary.initial_url, summary_.initial_url); | 132 EXPECT_EQ(summary.initial_url, summary_.initial_url); |
| 133 // Duplicate resources can be observed in a single navigation but | 133 // Duplicate resources can be observed in a single navigation but |
| 134 // ResourcePrefetchPredictor only cares about the first occurrence of each. | 134 // ResourcePrefetchPredictor only cares about the first occurrence of each. |
| 135 std::vector<ResourcePrefetchPredictor::URLRequestSummary> subresources = | 135 std::vector<ResourcePrefetchPredictor::URLRequestSummary> subresources = |
| 136 GetUniqueSubresources(summary); | 136 GetUniqueSubresources(summary); |
| 137 EXPECT_THAT(subresources, testing::UnorderedElementsAreArray( | 137 EXPECT_THAT(subresources, testing::UnorderedElementsAreArray( |
| 138 summary_.subresource_requests)); | 138 summary_.subresource_requests)); |
| 139 run_loop_.Quit(); | 139 run_loop_.Quit(); |
| 140 } | 140 } |
| 141 | 141 |
| 142 void Wait() { run_loop_.Run(); } | 142 void Wait() { run_loop_.Run(); } |
| 143 | 143 |
| 144 private: | 144 private: |
| 145 base::RunLoop run_loop_; | 145 base::RunLoop run_loop_; |
| 146 size_t url_visit_count_; | 146 size_t url_visit_count_; |
| 147 PageRequestSummary summary_; | 147 PageRequestSummary summary_; |
| 148 | 148 |
| 149 DISALLOW_COPY_AND_ASSIGN(ResourcePrefetchPredictorTestObserver); | 149 DISALLOW_COPY_AND_ASSIGN(LearningObserver); |
| 150 }; | |
| 151 | |
| 152 class PrefetchingObserver : public TestObserver { | |
| 153 public: | |
| 154 explicit PrefetchingObserver(ResourcePrefetchPredictor* predictor, | |
| 155 const GURL& expected_main_frame_url) | |
| 156 : TestObserver(predictor), main_frame_url_(expected_main_frame_url) {} | |
| 157 | |
| 158 // TestObserver: | |
| 159 void OnNavigationLearned(size_t url_visit_count, | |
| 160 const PageRequestSummary& summary) override { | |
| 161 ADD_FAILURE() << "Prefetching shouldn't activate learning"; | |
| 162 } | |
| 163 | |
| 164 void OnPrefetchingFinished(const GURL& main_frame_url) override { | |
| 165 EXPECT_EQ(main_frame_url_, main_frame_url); | |
| 166 run_loop_.Quit(); | |
| 167 } | |
| 168 | |
| 169 void Wait() { run_loop_.Run(); } | |
| 170 | |
| 171 private: | |
| 172 base::RunLoop run_loop_; | |
| 173 GURL main_frame_url_; | |
| 174 | |
| 175 DISALLOW_COPY_AND_ASSIGN(PrefetchingObserver); | |
| 150 }; | 176 }; |
| 151 | 177 |
| 152 class ResourcePrefetchPredictorBrowserTest : public InProcessBrowserTest { | 178 class ResourcePrefetchPredictorBrowserTest : public InProcessBrowserTest { |
| 153 protected: | 179 protected: |
| 154 using URLRequestSummary = ResourcePrefetchPredictor::URLRequestSummary; | 180 using URLRequestSummary = ResourcePrefetchPredictor::URLRequestSummary; |
| 155 | 181 |
| 156 void SetUpCommandLine(base::CommandLine* command_line) override { | 182 void SetUpCommandLine(base::CommandLine* command_line) override { |
| 157 command_line->AppendSwitchASCII( | 183 command_line->AppendSwitchASCII( |
| 158 switches::kSpeculativeResourcePrefetching, | 184 switches::kSpeculativeResourcePrefetching, |
| 159 switches::kSpeculativeResourcePrefetchingEnabled); | 185 switches::kSpeculativeResourcePrefetchingEnabled); |
| (...skipping 15 matching lines...) Expand all Loading... | |
| 175 | 201 |
| 176 void NavigateToURLAndCheckSubresources(const GURL& main_frame_url) { | 202 void NavigateToURLAndCheckSubresources(const GURL& main_frame_url) { |
| 177 GURL endpoint_url = GetRedirectEndpoint(main_frame_url); | 203 GURL endpoint_url = GetRedirectEndpoint(main_frame_url); |
| 178 std::vector<URLRequestSummary> url_request_summaries; | 204 std::vector<URLRequestSummary> url_request_summaries; |
| 179 for (const auto& kv : resources_) { | 205 for (const auto& kv : resources_) { |
| 180 if (kv.second.is_no_store || !kv.second.should_be_recorded) | 206 if (kv.second.is_no_store || !kv.second.should_be_recorded) |
| 181 continue; | 207 continue; |
| 182 url_request_summaries.push_back( | 208 url_request_summaries.push_back( |
| 183 GetURLRequestSummaryForResource(endpoint_url, kv.second)); | 209 GetURLRequestSummaryForResource(endpoint_url, kv.second)); |
| 184 } | 210 } |
| 185 ResourcePrefetchPredictorTestObserver observer( | 211 LearningObserver observer( |
| 186 predictor_, UpdateAndGetVisitCount(main_frame_url), | 212 predictor_, UpdateAndGetVisitCount(main_frame_url), |
| 187 CreatePageRequestSummary(endpoint_url.spec(), main_frame_url.spec(), | 213 CreatePageRequestSummary(endpoint_url.spec(), main_frame_url.spec(), |
| 188 url_request_summaries)); | 214 url_request_summaries)); |
| 189 ui_test_utils::NavigateToURL(browser(), main_frame_url); | 215 ui_test_utils::NavigateToURL(browser(), main_frame_url); |
| 190 observer.Wait(); | 216 observer.Wait(); |
| 217 for (auto& kv : resources_) { | |
| 218 if (!kv.second.is_no_store && kv.second.should_be_recorded) | |
| 219 kv.second.request.was_cached = true; | |
| 220 } | |
| 221 } | |
| 222 | |
| 223 void PrefetchURL(const GURL& main_frame_url) { | |
| 224 PrefetchingObserver observer(predictor_, main_frame_url); | |
| 225 predictor_->StartPrefetching(main_frame_url, PrefetchOrigin::NAVIGATION); | |
| 226 observer.Wait(); | |
| 227 for (auto& kv : resources_) { | |
| 228 if (!kv.second.is_no_store && kv.second.should_be_recorded) | |
| 229 kv.second.request.was_cached = true; | |
| 230 } | |
| 191 } | 231 } |
| 192 | 232 |
| 193 ResourceSummary* AddResource(const GURL& resource_url, | 233 ResourceSummary* AddResource(const GURL& resource_url, |
| 194 content::ResourceType resource_type, | 234 content::ResourceType resource_type, |
| 195 net::RequestPriority priority) { | 235 net::RequestPriority priority) { |
| 196 auto pair_and_whether_inserted = | 236 auto pair_and_whether_inserted = |
| 197 resources_.insert(std::make_pair(resource_url, ResourceSummary())); | 237 resources_.insert(std::make_pair(resource_url, ResourceSummary())); |
| 198 EXPECT_TRUE(pair_and_whether_inserted.second) << resource_url | 238 EXPECT_TRUE(pair_and_whether_inserted.second) << resource_url |
| 199 << " was inserted twice"; | 239 << " was inserted twice"; |
| 200 ResourceSummary* resource = &pair_and_whether_inserted.first->second; | 240 ResourceSummary* resource = &pair_and_whether_inserted.first->second; |
| (...skipping 25 matching lines...) Expand all Loading... | |
| 226 const std::vector<RedirectEdge>& redirect_chain) { | 266 const std::vector<RedirectEdge>& redirect_chain) { |
| 227 ASSERT_FALSE(redirect_chain.empty()); | 267 ASSERT_FALSE(redirect_chain.empty()); |
| 228 GURL current = initial_url; | 268 GURL current = initial_url; |
| 229 for (const auto& edge : redirect_chain) { | 269 for (const auto& edge : redirect_chain) { |
| 230 auto result = redirects_.insert(std::make_pair(current, edge)); | 270 auto result = redirects_.insert(std::make_pair(current, edge)); |
| 231 EXPECT_TRUE(result.second) << current << " already has a redirect."; | 271 EXPECT_TRUE(result.second) << current << " already has a redirect."; |
| 232 current = edge.url; | 272 current = edge.url; |
| 233 } | 273 } |
| 234 } | 274 } |
| 235 | 275 |
| 276 void ClearCache() { | |
| 277 chrome::ClearCache(browser()); | |
| 278 for (auto& kv : resources_) | |
| 279 kv.second.request.was_cached = false; | |
| 280 } | |
| 281 | |
| 236 // Shortcut for convenience. | 282 // Shortcut for convenience. |
| 237 GURL GetURL(const std::string& path) const { | 283 GURL GetURL(const std::string& path) const { |
| 238 return embedded_test_server()->GetURL(path); | 284 return embedded_test_server()->GetURL(path); |
| 239 } | 285 } |
| 240 | 286 |
| 241 void EnableHttpsServer() { | 287 void EnableHttpsServer() { |
| 242 ASSERT_FALSE(https_server_); | 288 ASSERT_FALSE(https_server_); |
| 243 https_server_ = base::MakeUnique<net::EmbeddedTestServer>( | 289 https_server_ = base::MakeUnique<net::EmbeddedTestServer>( |
| 244 net::EmbeddedTestServer::TYPE_HTTPS); | 290 net::EmbeddedTestServer::TYPE_HTTPS); |
| 245 https_server()->AddDefaultHandlers( | 291 https_server()->AddDefaultHandlers( |
| (...skipping 236 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 482 AddResource(GetURL(kImagePath2), content::RESOURCE_TYPE_IMAGE, net::LOWEST); | 528 AddResource(GetURL(kImagePath2), content::RESOURCE_TYPE_IMAGE, net::LOWEST); |
| 483 AddResource(GetURL(kStylePath2), content::RESOURCE_TYPE_STYLESHEET, | 529 AddResource(GetURL(kStylePath2), content::RESOURCE_TYPE_STYLESHEET, |
| 484 net::HIGHEST); | 530 net::HIGHEST); |
| 485 AddResource(GetURL(kScriptPath2), content::RESOURCE_TYPE_SCRIPT, net::MEDIUM); | 531 AddResource(GetURL(kScriptPath2), content::RESOURCE_TYPE_SCRIPT, net::MEDIUM); |
| 486 // Included from <iframe src="html_subresources.html"> and not recored. | 532 // Included from <iframe src="html_subresources.html"> and not recored. |
| 487 AddUnrecordedResources({GetURL(kImagePath), GetURL(kStylePath), | 533 AddUnrecordedResources({GetURL(kImagePath), GetURL(kStylePath), |
| 488 GetURL(kScriptPath), GetURL(kFontPath)}); | 534 GetURL(kScriptPath), GetURL(kFontPath)}); |
| 489 NavigateToURLAndCheckSubresources(GetURL(kHtmlIframePath)); | 535 NavigateToURLAndCheckSubresources(GetURL(kHtmlIframePath)); |
| 490 } | 536 } |
| 491 | 537 |
| 538 IN_PROC_BROWSER_TEST_F(ResourcePrefetchPredictorBrowserTest, | |
| 539 PrefetchingSimple) { | |
| 540 AddResource(GetURL(kImagePath), content::RESOURCE_TYPE_IMAGE, net::LOWEST); | |
| 541 AddResource(GetURL(kStylePath), content::RESOURCE_TYPE_STYLESHEET, | |
| 542 net::HIGHEST); | |
| 543 AddResource(GetURL(kScriptPath), content::RESOURCE_TYPE_SCRIPT, net::MEDIUM); | |
| 544 AddResource(GetURL(kFontPath), content::RESOURCE_TYPE_FONT_RESOURCE, | |
| 545 net::HIGHEST); | |
| 546 // We need to have at least two resource hits to trigger prefetch. | |
| 547 NavigateToURLAndCheckSubresources(GetURL(kHtmlSubresourcesPath)); | |
| 548 ClearCache(); | |
| 549 NavigateToURLAndCheckSubresources(GetURL(kHtmlSubresourcesPath)); | |
| 550 ClearCache(); | |
| 551 PrefetchURL(GetURL(kHtmlSubresourcesPath)); | |
| 552 NavigateToURLAndCheckSubresources(GetURL(kHtmlSubresourcesPath)); | |
|
alexilin
2016/12/06 12:44:17
Here we reuse interceptors of URLRequests that Res
| |
| 553 } | |
| 554 | |
| 492 } // namespace predictors | 555 } // namespace predictors |
| OLD | NEW |