| 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 <stddef.h> | 5 #include <stddef.h> |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 #include <set> | 8 #include <set> |
| 9 | 9 |
| 10 #include "base/command_line.h" | 10 #include "base/command_line.h" |
| (...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 65 const char kScriptDocumentWritePath[] = "/predictors/document_write.js"; | 65 const char kScriptDocumentWritePath[] = "/predictors/document_write.js"; |
| 66 const char kHtmlAppendChildPath[] = "/predictors/append_child.html"; | 66 const char kHtmlAppendChildPath[] = "/predictors/append_child.html"; |
| 67 const char kScriptAppendChildPath[] = "/predictors/append_child.js"; | 67 const char kScriptAppendChildPath[] = "/predictors/append_child.js"; |
| 68 const char kHtmlInnerHtmlPath[] = "/predictors/inner_html.html"; | 68 const char kHtmlInnerHtmlPath[] = "/predictors/inner_html.html"; |
| 69 const char kScriptInnerHtmlPath[] = "/predictors/inner_html.js"; | 69 const char kScriptInnerHtmlPath[] = "/predictors/inner_html.js"; |
| 70 const char kHtmlXHRPath[] = "/predictors/xhr.html"; | 70 const char kHtmlXHRPath[] = "/predictors/xhr.html"; |
| 71 const char kScriptXHRPath[] = "/predictors/xhr.js"; | 71 const char kScriptXHRPath[] = "/predictors/xhr.js"; |
| 72 const char kHtmlIframePath[] = "/predictors/html_iframe.html"; | 72 const char kHtmlIframePath[] = "/predictors/html_iframe.html"; |
| 73 const char kHtmlJavascriptRedirectPath[] = | 73 const char kHtmlJavascriptRedirectPath[] = |
| 74 "/predictors/javascript_redirect.html"; | 74 "/predictors/javascript_redirect.html"; |
| 75 const char kHtmlFcpOrderPath[] = "/predictors/subresource_fcp_order.html"; |
| 75 | 76 |
| 76 // Host, path. | 77 // Host, path. |
| 77 const char* kScript[2] = {kFooHost, kScriptPath}; | 78 const char* kScript[2] = {kFooHost, kScriptPath}; |
| 78 const char* kImage[2] = {kBarHost, kImagePath}; | 79 const char* kImage[2] = {kBarHost, kImagePath}; |
| 79 const char* kFont[2] = {kFooHost, kFontPath}; | 80 const char* kFont[2] = {kFooHost, kFontPath}; |
| 80 const char* kStyle[2] = {kBazHost, kStylePath}; | 81 const char* kStyle[2] = {kBazHost, kStylePath}; |
| 81 | 82 |
| 82 struct ResourceSummary { | 83 struct ResourceSummary { |
| 83 ResourceSummary() | 84 ResourceSummary() |
| 84 : version(0), | 85 : version(0), |
| 85 is_no_store(false), | 86 is_no_store(false), |
| 86 is_external(false), | 87 is_external(false), |
| 87 is_observable(true), | 88 is_observable(true), |
| 88 is_prohibited(false) {} | 89 is_prohibited(false) { |
| 90 request.before_first_contentful_paint = true; |
| 91 } |
| 89 | 92 |
| 90 ResourcePrefetchPredictor::URLRequestSummary request; | 93 ResourcePrefetchPredictor::URLRequestSummary request; |
| 91 // Allows to update HTTP ETag. | 94 // Allows to update HTTP ETag. |
| 92 size_t version; | 95 size_t version; |
| 93 // True iff "Cache-control: no-store" header is present. | 96 // True iff "Cache-control: no-store" header is present. |
| 94 bool is_no_store; | 97 bool is_no_store; |
| 95 // True iff a request for this resource must be ignored by the custom handler. | 98 // True iff a request for this resource must be ignored by the custom handler. |
| 96 bool is_external; | 99 bool is_external; |
| 97 // True iff the LearningObserver must observe this resource. | 100 // True iff the LearningObserver must observe this resource. |
| 98 bool is_observable; | 101 bool is_observable; |
| 99 // A request with |is_prohibited| set to true makes the test that originates | 102 // A request with |is_prohibited| set to true makes the test that originates |
| 100 // the request fail. | 103 // the request fail. |
| 101 bool is_prohibited; | 104 bool is_prohibited; |
| 105 // If set, the HTTP request handler will sleep for this long before |
| 106 // responding. |
| 107 base::TimeDelta delay; |
| 102 }; | 108 }; |
| 103 | 109 |
| 104 struct RedirectEdge { | 110 struct RedirectEdge { |
| 105 // This response code should be returned by previous url in the chain. | 111 // This response code should be returned by previous url in the chain. |
| 106 net::HttpStatusCode code; | 112 net::HttpStatusCode code; |
| 107 GURL url; | 113 GURL url; |
| 108 bool is_client_side; | 114 bool is_client_side; |
| 109 }; | 115 }; |
| 110 | 116 |
| 111 // Helper class to track and allow waiting for ResourcePrefetchPredictor | 117 // Helper class to track and allow waiting for ResourcePrefetchPredictor |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 163 } | 169 } |
| 164 | 170 |
| 165 // Fill a NavigationID with "empty" data that does not trigger | 171 // Fill a NavigationID with "empty" data that does not trigger |
| 166 // the is_valid DCHECK(). Allows comparing. | 172 // the is_valid DCHECK(). Allows comparing. |
| 167 void SetValidNavigationID(NavigationID* navigation_id) { | 173 void SetValidNavigationID(NavigationID* navigation_id) { |
| 168 navigation_id->tab_id = 0; | 174 navigation_id->tab_id = 0; |
| 169 navigation_id->main_frame_url = GURL("http://127.0.0.1"); | 175 navigation_id->main_frame_url = GURL("http://127.0.0.1"); |
| 170 } | 176 } |
| 171 | 177 |
| 172 void ModifySubresourceForComparison(URLRequestSummary* subresource, | 178 void ModifySubresourceForComparison(URLRequestSummary* subresource, |
| 173 bool match_navigation_id) { | 179 bool match_navigation_id, |
| 180 bool match_before_first_contentful_paint) { |
| 174 if (!match_navigation_id) | 181 if (!match_navigation_id) |
| 175 SetValidNavigationID(&subresource->navigation_id); | 182 SetValidNavigationID(&subresource->navigation_id); |
| 183 if (!match_before_first_contentful_paint) |
| 184 subresource->before_first_contentful_paint = true; |
| 176 if (subresource->resource_type == content::RESOURCE_TYPE_IMAGE && | 185 if (subresource->resource_type == content::RESOURCE_TYPE_IMAGE && |
| 177 subresource->priority == net::LOWEST) { | 186 subresource->priority == net::LOWEST) { |
| 178 // Fuzzy comparison for images because an image priority can be | 187 // Fuzzy comparison for images because an image priority can be |
| 179 // boosted during layout via | 188 // boosted during layout via |
| 180 // ResourceFetcher::updateAllImageResourcePriorities(). | 189 // ResourceFetcher::updateAllImageResourcePriorities(). |
| 181 subresource->priority = net::MEDIUM; | 190 subresource->priority = net::MEDIUM; |
| 182 } | 191 } |
| 183 } | 192 } |
| 184 | 193 |
| 185 // Does a custom comparison of subresources of URLRequestSummary | 194 // Does a custom comparison of subresources of URLRequestSummary |
| 186 // and fail the test if the expectation is not met. | 195 // and fail the test if the expectation is not met. |
| 187 void CompareSubresources(std::vector<URLRequestSummary> actual_subresources, | 196 void CompareSubresources(std::vector<URLRequestSummary> actual_subresources, |
| 188 std::vector<URLRequestSummary> expected_subresources, | 197 std::vector<URLRequestSummary> expected_subresources, |
| 189 bool match_navigation_id) { | 198 bool match_navigation_id, |
| 199 bool match_before_first_contentful_paint) { |
| 190 // Duplicate resources can be observed in a single navigation but | 200 // Duplicate resources can be observed in a single navigation but |
| 191 // ResourcePrefetchPredictor only cares about the first occurrence of each. | 201 // ResourcePrefetchPredictor only cares about the first occurrence of each. |
| 192 RemoveDuplicateSubresources(&actual_subresources); | 202 RemoveDuplicateSubresources(&actual_subresources); |
| 193 | 203 |
| 194 for (auto& subresource : actual_subresources) | 204 for (auto& subresource : actual_subresources) |
| 195 ModifySubresourceForComparison(&subresource, match_navigation_id); | 205 ModifySubresourceForComparison(&subresource, match_navigation_id, |
| 206 match_before_first_contentful_paint); |
| 196 for (auto& subresource : expected_subresources) | 207 for (auto& subresource : expected_subresources) |
| 197 ModifySubresourceForComparison(&subresource, match_navigation_id); | 208 ModifySubresourceForComparison(&subresource, match_navigation_id, |
| 209 match_before_first_contentful_paint); |
| 198 | 210 |
| 199 EXPECT_THAT(actual_subresources, | 211 EXPECT_THAT(actual_subresources, |
| 200 testing::UnorderedElementsAreArray(expected_subresources)); | 212 testing::UnorderedElementsAreArray(expected_subresources)); |
| 201 } | 213 } |
| 202 | 214 |
| 203 std::string CreateVersionedETag(size_t version, const std::string& path) { | 215 std::string CreateVersionedETag(size_t version, const std::string& path) { |
| 204 return base::StringPrintf("'%zu%s'", version, path.c_str()); | 216 return base::StringPrintf("'%zu%s'", version, path.c_str()); |
| 205 } | 217 } |
| 206 | 218 |
| 207 GURL GetRequestURL(const net::test_server::HttpRequest& request) { | 219 GURL GetRequestURL(const net::test_server::HttpRequest& request) { |
| (...skipping 19 matching lines...) Expand all Loading... |
| 227 // Helper class to track and allow waiting for a single OnNavigationLearned | 239 // Helper class to track and allow waiting for a single OnNavigationLearned |
| 228 // event. The information provided by this event is also used to verify that | 240 // event. The information provided by this event is also used to verify that |
| 229 // ResourcePrefetchPredictor works as expected. | 241 // ResourcePrefetchPredictor works as expected. |
| 230 class LearningObserver : public TestObserver { | 242 class LearningObserver : public TestObserver { |
| 231 public: | 243 public: |
| 232 using PageRequestSummary = ResourcePrefetchPredictor::PageRequestSummary; | 244 using PageRequestSummary = ResourcePrefetchPredictor::PageRequestSummary; |
| 233 | 245 |
| 234 LearningObserver(ResourcePrefetchPredictor* predictor, | 246 LearningObserver(ResourcePrefetchPredictor* predictor, |
| 235 const size_t expected_url_visit_count, | 247 const size_t expected_url_visit_count, |
| 236 const PageRequestSummary& expected_summary, | 248 const PageRequestSummary& expected_summary, |
| 237 bool match_navigation_id) | 249 bool match_navigation_id, |
| 250 bool match_before_first_contentful_paint) |
| 238 : TestObserver(predictor), | 251 : TestObserver(predictor), |
| 239 url_visit_count_(expected_url_visit_count), | 252 url_visit_count_(expected_url_visit_count), |
| 240 summary_(expected_summary), | 253 summary_(expected_summary), |
| 241 match_navigation_id_(match_navigation_id) {} | 254 match_navigation_id_(match_navigation_id), |
| 255 match_before_first_contentful_paint_( |
| 256 match_before_first_contentful_paint) {} |
| 242 | 257 |
| 243 // TestObserver: | 258 // TestObserver: |
| 244 void OnNavigationLearned(size_t url_visit_count, | 259 void OnNavigationLearned(size_t url_visit_count, |
| 245 const PageRequestSummary& summary) override { | 260 const PageRequestSummary& summary) override { |
| 246 EXPECT_EQ(url_visit_count, url_visit_count_); | 261 EXPECT_EQ(url_visit_count, url_visit_count_); |
| 247 EXPECT_EQ(summary.main_frame_url, summary_.main_frame_url); | 262 EXPECT_EQ(summary.main_frame_url, summary_.main_frame_url); |
| 248 EXPECT_EQ(summary.initial_url, summary_.initial_url); | 263 EXPECT_EQ(summary.initial_url, summary_.initial_url); |
| 249 for (const auto& resource : summary.subresource_requests) | 264 for (const auto& resource : summary.subresource_requests) |
| 250 current_navigation_ids_.insert(resource.navigation_id); | 265 current_navigation_ids_.insert(resource.navigation_id); |
| 251 CompareSubresources(summary.subresource_requests, | 266 CompareSubresources(summary.subresource_requests, |
| 252 summary_.subresource_requests, match_navigation_id_); | 267 summary_.subresource_requests, match_navigation_id_, |
| 268 match_before_first_contentful_paint_); |
| 253 run_loop_.Quit(); | 269 run_loop_.Quit(); |
| 254 } | 270 } |
| 255 | 271 |
| 256 void Wait() { run_loop_.Run(); } | 272 void Wait() { run_loop_.Run(); } |
| 257 | 273 |
| 258 std::set<NavigationID>& current_navigation_ids() { | 274 std::set<NavigationID>& current_navigation_ids() { |
| 259 return current_navigation_ids_; | 275 return current_navigation_ids_; |
| 260 } | 276 } |
| 261 | 277 |
| 262 private: | 278 private: |
| 263 base::RunLoop run_loop_; | 279 base::RunLoop run_loop_; |
| 264 size_t url_visit_count_; | 280 size_t url_visit_count_; |
| 265 PageRequestSummary summary_; | 281 PageRequestSummary summary_; |
| 266 bool match_navigation_id_; | 282 bool match_navigation_id_; |
| 283 bool match_before_first_contentful_paint_; |
| 267 std::set<NavigationID> current_navigation_ids_; | 284 std::set<NavigationID> current_navigation_ids_; |
| 268 | 285 |
| 269 DISALLOW_COPY_AND_ASSIGN(LearningObserver); | 286 DISALLOW_COPY_AND_ASSIGN(LearningObserver); |
| 270 }; | 287 }; |
| 271 | 288 |
| 272 // Helper class to track and allow waiting for a single OnPrefetchingFinished | 289 // Helper class to track and allow waiting for a single OnPrefetchingFinished |
| 273 // event. Checks also that {Start,Stop}Prefetching are called with the right | 290 // event. Checks also that {Start,Stop}Prefetching are called with the right |
| 274 // argument. | 291 // argument. |
| 275 class PrefetchingObserver : public TestObserver { | 292 class PrefetchingObserver : public TestObserver { |
| 276 public: | 293 public: |
| (...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 354 // URLs from the test server contain a port number. | 371 // URLs from the test server contain a port number. |
| 355 ResourcePrefetchPredictor::SetAllowPortInUrlsForTesting(true); | 372 ResourcePrefetchPredictor::SetAllowPortInUrlsForTesting(true); |
| 356 EnsurePredictorInitialized(); | 373 EnsurePredictorInitialized(); |
| 357 histogram_tester_.reset(new base::HistogramTester()); | 374 histogram_tester_.reset(new base::HistogramTester()); |
| 358 } | 375 } |
| 359 | 376 |
| 360 void TearDownOnMainThread() override { | 377 void TearDownOnMainThread() override { |
| 361 ResourcePrefetchPredictor::SetAllowPortInUrlsForTesting(false); | 378 ResourcePrefetchPredictor::SetAllowPortInUrlsForTesting(false); |
| 362 } | 379 } |
| 363 | 380 |
| 364 void TestLearningAndPrefetching(const GURL& main_frame_url) { | 381 void TestLearningAndPrefetching( |
| 382 const GURL& main_frame_url, |
| 383 bool match_before_first_contentful_paint = false) { |
| 365 // Navigate to |main_frame_url| and check all the expectations. | 384 // Navigate to |main_frame_url| and check all the expectations. |
| 366 NavigateToURLAndCheckSubresources(main_frame_url); | 385 NavigateToURLAndCheckSubresources(main_frame_url, |
| 386 WindowOpenDisposition::CURRENT_TAB, |
| 387 match_before_first_contentful_paint); |
| 367 ClearCache(); | 388 ClearCache(); |
| 368 // It is needed to have at least two resource hits to trigger prefetch. | 389 // It is needed to have at least two resource hits to trigger prefetch. |
| 369 NavigateToURLAndCheckSubresources(main_frame_url); | 390 NavigateToURLAndCheckSubresources(main_frame_url, |
| 391 WindowOpenDisposition::CURRENT_TAB, |
| 392 match_before_first_contentful_paint); |
| 370 ClearCache(); | 393 ClearCache(); |
| 371 // Prefetch all needed resources and change expectations so that all | 394 // Prefetch all needed resources and change expectations so that all |
| 372 // cacheable resources should be served from cache next navigation. | 395 // cacheable resources should be served from cache next navigation. |
| 373 PrefetchURL(main_frame_url); | 396 PrefetchURL(main_frame_url); |
| 374 // To be sure that the browser send no requests to the server after | 397 // To be sure that the browser send no requests to the server after |
| 375 // prefetching. | 398 // prefetching. |
| 376 NavigateToURLAndCheckSubresourcesAllCached(main_frame_url); | 399 NavigateToURLAndCheckSubresourcesAllCached(main_frame_url); |
| 377 } | 400 } |
| 378 | 401 |
| 379 void NavigateToURLAndCheckSubresourcesAllCached(const GURL& navigation_url) { | 402 void NavigateToURLAndCheckSubresourcesAllCached(const GURL& navigation_url) { |
| 380 for (auto& kv : resources_) { | 403 for (auto& kv : resources_) { |
| 381 if (kv.second.is_observable) | 404 if (kv.second.is_observable) |
| 382 kv.second.is_prohibited = true; | 405 kv.second.is_prohibited = true; |
| 383 } | 406 } |
| 384 NavigateToURLAndCheckSubresources(navigation_url); | 407 NavigateToURLAndCheckSubresources(navigation_url); |
| 385 for (auto& kv : resources_) { | 408 for (auto& kv : resources_) { |
| 386 if (kv.second.is_observable) | 409 if (kv.second.is_observable) |
| 387 kv.second.is_prohibited = false; | 410 kv.second.is_prohibited = false; |
| 388 } | 411 } |
| 389 } | 412 } |
| 390 | 413 |
| 391 void NavigateToURLAndCheckSubresources( | 414 void NavigateToURLAndCheckSubresources( |
| 392 const GURL& navigation_url, | 415 const GURL& navigation_url, |
| 393 WindowOpenDisposition disposition = WindowOpenDisposition::CURRENT_TAB) { | 416 WindowOpenDisposition disposition = WindowOpenDisposition::CURRENT_TAB, |
| 417 bool match_before_first_contentful_paint = false) { |
| 394 GURL initial_url = GetLastClientSideRedirectEndpoint(navigation_url); | 418 GURL initial_url = GetLastClientSideRedirectEndpoint(navigation_url); |
| 395 GURL main_frame_url = GetRedirectEndpoint(navigation_url); | 419 GURL main_frame_url = GetRedirectEndpoint(navigation_url); |
| 396 std::vector<URLRequestSummary> url_request_summaries; | 420 std::vector<URLRequestSummary> url_request_summaries; |
| 397 for (const auto& kv : resources_) { | 421 for (const auto& kv : resources_) { |
| 398 if (kv.second.is_observable) { | 422 if (kv.second.is_observable) { |
| 399 url_request_summaries.push_back( | 423 url_request_summaries.push_back( |
| 400 GetURLRequestSummaryForResource(main_frame_url, kv.second)); | 424 GetURLRequestSummaryForResource(main_frame_url, kv.second)); |
| 401 } | 425 } |
| 402 } | 426 } |
| 403 | 427 |
| 404 bool match_navigation_id = | 428 bool match_navigation_id = |
| 405 disposition == WindowOpenDisposition::CURRENT_TAB; | 429 disposition == WindowOpenDisposition::CURRENT_TAB; |
| 406 | 430 |
| 407 LearningObserver observer( | 431 LearningObserver observer( |
| 408 predictor_, UpdateAndGetVisitCount(initial_url), | 432 predictor_, UpdateAndGetVisitCount(initial_url), |
| 409 CreatePageRequestSummary(main_frame_url.spec(), initial_url.spec(), | 433 CreatePageRequestSummary(main_frame_url.spec(), initial_url.spec(), |
| 410 url_request_summaries), | 434 url_request_summaries), |
| 411 match_navigation_id); | 435 match_navigation_id, match_before_first_contentful_paint); |
| 412 ui_test_utils::NavigateToURLWithDisposition( | 436 ui_test_utils::NavigateToURLWithDisposition( |
| 413 browser(), navigation_url, disposition, | 437 browser(), navigation_url, disposition, |
| 414 ui_test_utils::BROWSER_TEST_NONE); | 438 ui_test_utils::BROWSER_TEST_NONE); |
| 415 observer.Wait(); | 439 observer.Wait(); |
| 416 | 440 |
| 417 for (auto& kv : resources_) { | 441 for (auto& kv : resources_) { |
| 418 if (kv.second.is_observable) | 442 if (kv.second.is_observable) |
| 419 kv.second.request.was_cached = true; | 443 kv.second.request.was_cached = true; |
| 420 } | 444 } |
| 421 for (const auto& nav : observer.current_navigation_ids()) | 445 for (const auto& nav : observer.current_navigation_ids()) |
| (...skipping 245 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 667 } | 691 } |
| 668 if (summary.request.always_revalidate) | 692 if (summary.request.always_revalidate) |
| 669 http_response->AddCustomHeader("Cache-Control", "no-cache"); | 693 http_response->AddCustomHeader("Cache-Control", "no-cache"); |
| 670 else | 694 else |
| 671 http_response->AddCustomHeader("Cache-Control", "max-age=2147483648"); | 695 http_response->AddCustomHeader("Cache-Control", "max-age=2147483648"); |
| 672 | 696 |
| 673 // Add some content, otherwise the prefetch size histogram rounds down to | 697 // Add some content, otherwise the prefetch size histogram rounds down to |
| 674 // 0kB. | 698 // 0kB. |
| 675 http_response->set_content(std::string(1024, ' ')); | 699 http_response->set_content(std::string(1024, ' ')); |
| 676 | 700 |
| 701 if (!summary.delay.is_zero()) |
| 702 base::PlatformThread::Sleep(summary.delay); |
| 703 |
| 677 return std::move(http_response); | 704 return std::move(http_response); |
| 678 } | 705 } |
| 679 | 706 |
| 680 // The custom handler for redirect requests from the browser to an | 707 // The custom handler for redirect requests from the browser to an |
| 681 // EmbeddedTestServer. Running on the EmbeddedTestServer IO thread. | 708 // EmbeddedTestServer. Running on the EmbeddedTestServer IO thread. |
| 682 // Finds the data to serve requests in |redirects_| map keyed by a request | 709 // Finds the data to serve requests in |redirects_| map keyed by a request |
| 683 // URL. | 710 // URL. |
| 684 std::unique_ptr<net::test_server::HttpResponse> HandleRedirectRequest( | 711 std::unique_ptr<net::test_server::HttpResponse> HandleRedirectRequest( |
| 685 const net::test_server::HttpRequest& request) const { | 712 const net::test_server::HttpRequest& request) const { |
| 686 std::map<GURL, RedirectEdge>::const_iterator redirect_it = | 713 std::map<GURL, RedirectEdge>::const_iterator redirect_it = |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 737 histogram_tester_->ExpectBucketCount( | 764 histogram_tester_->ExpectBucketCount( |
| 738 internal::kResourcePrefetchPredictorPrefetchHitsCountNotCached, 4, 1); | 765 internal::kResourcePrefetchPredictorPrefetchHitsCountNotCached, 4, 1); |
| 739 | 766 |
| 740 histogram_tester_->ExpectBucketCount( | 767 histogram_tester_->ExpectBucketCount( |
| 741 internal::kResourcePrefetchPredictorPrefetchMissesSize, 0, 1); | 768 internal::kResourcePrefetchPredictorPrefetchMissesSize, 0, 1); |
| 742 // Each request is ~1k, see HandleResourceRequest() above. | 769 // Each request is ~1k, see HandleResourceRequest() above. |
| 743 histogram_tester_->ExpectBucketCount( | 770 histogram_tester_->ExpectBucketCount( |
| 744 internal::kResourcePrefetchPredictorPrefetchHitsSize, 4, 1); | 771 internal::kResourcePrefetchPredictorPrefetchHitsSize, 4, 1); |
| 745 } | 772 } |
| 746 | 773 |
| 774 IN_PROC_BROWSER_TEST_F(ResourcePrefetchPredictorBrowserTest, |
| 775 SubresourceFcpOrder) { |
| 776 AddResource(GetURL(kStylePath), content::RESOURCE_TYPE_STYLESHEET, |
| 777 net::HIGHEST); |
| 778 AddResource(GetURL(kScriptPath), content::RESOURCE_TYPE_SCRIPT, net::MEDIUM); |
| 779 |
| 780 ResourceSummary* image = AddResource( |
| 781 GetURL(kImagePath), content::RESOURCE_TYPE_IMAGE, net::LOWEST); |
| 782 // Delay HTTP response to ensure enough time to receive notice of |
| 783 // firstContentfulPaint. |
| 784 image->delay = base::TimeDelta::FromMilliseconds(1500); |
| 785 image->request.before_first_contentful_paint = false; |
| 786 |
| 787 TestLearningAndPrefetching(GetURL(kHtmlFcpOrderPath), true); |
| 788 } |
| 789 |
| 747 IN_PROC_BROWSER_TEST_F(ResourcePrefetchPredictorBrowserTest, Redirect) { | 790 IN_PROC_BROWSER_TEST_F(ResourcePrefetchPredictorBrowserTest, Redirect) { |
| 748 GURL initial_url = GetURLWithHost(kFooHost, kRedirectPath); | 791 GURL initial_url = GetURLWithHost(kFooHost, kRedirectPath); |
| 749 GURL redirected_url = | 792 GURL redirected_url = |
| 750 GetPageURLWithReplacements(kBarHost, kHtmlSubresourcesPath); | 793 GetPageURLWithReplacements(kBarHost, kHtmlSubresourcesPath); |
| 751 AddRedirectChain(initial_url, | 794 AddRedirectChain(initial_url, |
| 752 {{net::HTTP_MOVED_PERMANENTLY, redirected_url}}); | 795 {{net::HTTP_MOVED_PERMANENTLY, redirected_url}}); |
| 753 AddResourcesFromSubresourceHtml(); | 796 AddResourcesFromSubresourceHtml(); |
| 754 TestLearningAndPrefetching(initial_url); | 797 TestLearningAndPrefetching(initial_url); |
| 755 } | 798 } |
| 756 | 799 |
| (...skipping 207 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 964 AddResourcesFromSubresourceHtml(); | 1007 AddResourcesFromSubresourceHtml(); |
| 965 | 1008 |
| 966 NavigateToURLAndCheckSubresources(initial_url); | 1009 NavigateToURLAndCheckSubresources(initial_url); |
| 967 ClearCache(); | 1010 ClearCache(); |
| 968 NavigateToURLAndCheckSubresources(initial_url); | 1011 NavigateToURLAndCheckSubresources(initial_url); |
| 969 ClearCache(); | 1012 ClearCache(); |
| 970 NavigateToURLAndCheckPrefetching(initial_url); | 1013 NavigateToURLAndCheckPrefetching(initial_url); |
| 971 } | 1014 } |
| 972 | 1015 |
| 973 } // namespace predictors | 1016 } // namespace predictors |
| OLD | NEW |