| 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 <set> | 7 #include <set> |
| 8 | 8 |
| 9 #include "base/command_line.h" | 9 #include "base/command_line.h" |
| 10 #include "base/memory/ptr_util.h" | 10 #include "base/memory/ptr_util.h" |
| 11 #include "base/strings/string_util.h" | 11 #include "base/strings/string_util.h" |
| 12 #include "base/test/histogram_tester.h" |
| 12 #include "chrome/browser/browsing_data/browsing_data_helper.h" | 13 #include "chrome/browser/browsing_data/browsing_data_helper.h" |
| 13 #include "chrome/browser/browsing_data/browsing_data_remover.h" | 14 #include "chrome/browser/browsing_data/browsing_data_remover.h" |
| 14 #include "chrome/browser/browsing_data/browsing_data_remover_factory.h" | 15 #include "chrome/browser/browsing_data/browsing_data_remover_factory.h" |
| 15 #include "chrome/browser/predictors/resource_prefetch_predictor.h" | 16 #include "chrome/browser/predictors/resource_prefetch_predictor.h" |
| 16 #include "chrome/browser/predictors/resource_prefetch_predictor_factory.h" | 17 #include "chrome/browser/predictors/resource_prefetch_predictor_factory.h" |
| 17 #include "chrome/browser/predictors/resource_prefetch_predictor_test_util.h" | 18 #include "chrome/browser/predictors/resource_prefetch_predictor_test_util.h" |
| 18 #include "chrome/browser/profiles/profile.h" | 19 #include "chrome/browser/profiles/profile.h" |
| 19 #include "chrome/browser/ui/browser.h" | 20 #include "chrome/browser/ui/browser.h" |
| 20 #include "chrome/browser/ui/tabs/tab_strip_model.h" | 21 #include "chrome/browser/ui/tabs/tab_strip_model.h" |
| 21 #include "chrome/common/chrome_switches.h" | 22 #include "chrome/common/chrome_switches.h" |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 69 | 70 |
| 70 struct ResourceSummary { | 71 struct ResourceSummary { |
| 71 ResourceSummary() | 72 ResourceSummary() |
| 72 : version(0), | 73 : version(0), |
| 73 is_no_store(false), | 74 is_no_store(false), |
| 74 is_external(false), | 75 is_external(false), |
| 75 is_observable(true), | 76 is_observable(true), |
| 76 is_prohibited(false) {} | 77 is_prohibited(false) {} |
| 77 | 78 |
| 78 ResourcePrefetchPredictor::URLRequestSummary request; | 79 ResourcePrefetchPredictor::URLRequestSummary request; |
| 79 std::string content; | |
| 80 // Allows to update HTTP ETag. | 80 // Allows to update HTTP ETag. |
| 81 size_t version; | 81 size_t version; |
| 82 // True iff "Cache-control: no-store" header is present. | 82 // True iff "Cache-control: no-store" header is present. |
| 83 bool is_no_store; | 83 bool is_no_store; |
| 84 // True iff a request for this resource must be ignored by the custom handler. | 84 // True iff a request for this resource must be ignored by the custom handler. |
| 85 bool is_external; | 85 bool is_external; |
| 86 // True iff the LearningObserver must observe this resource. | 86 // True iff the LearningObserver must observe this resource. |
| 87 bool is_observable; | 87 bool is_observable; |
| 88 // A request with |is_prohibited| set to true makes the test that originates | 88 // A request with |is_prohibited| set to true makes the test that originates |
| 89 // the request fail. | 89 // the request fail. |
| (...skipping 220 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 310 base::Bind(&ResourcePrefetchPredictorBrowserTest::HandleResourceRequest, | 310 base::Bind(&ResourcePrefetchPredictorBrowserTest::HandleResourceRequest, |
| 311 base::Unretained(this))); | 311 base::Unretained(this))); |
| 312 embedded_test_server()->RegisterRequestMonitor(base::Bind( | 312 embedded_test_server()->RegisterRequestMonitor(base::Bind( |
| 313 &ResourcePrefetchPredictorBrowserTest::MonitorResourceRequest, | 313 &ResourcePrefetchPredictorBrowserTest::MonitorResourceRequest, |
| 314 base::Unretained(this))); | 314 base::Unretained(this))); |
| 315 ASSERT_TRUE(embedded_test_server()->Start()); | 315 ASSERT_TRUE(embedded_test_server()->Start()); |
| 316 predictor_ = | 316 predictor_ = |
| 317 ResourcePrefetchPredictorFactory::GetForProfile(browser()->profile()); | 317 ResourcePrefetchPredictorFactory::GetForProfile(browser()->profile()); |
| 318 ASSERT_TRUE(predictor_); | 318 ASSERT_TRUE(predictor_); |
| 319 EnsurePredictorInitialized(); | 319 EnsurePredictorInitialized(); |
| 320 histogram_tester_.reset(new base::HistogramTester()); |
| 320 } | 321 } |
| 321 | 322 |
| 322 void TestLearningAndPrefetching(const GURL& main_frame_url) { | 323 void TestLearningAndPrefetching(const GURL& main_frame_url) { |
| 323 // Navigate to |main_frame_url| and check all the expectations. | 324 // Navigate to |main_frame_url| and check all the expectations. |
| 324 NavigateToURLAndCheckSubresources(main_frame_url); | 325 NavigateToURLAndCheckSubresources(main_frame_url); |
| 325 ClearCache(); | 326 ClearCache(); |
| 326 // It is needed to have at least two resource hits to trigger prefetch. | 327 // It is needed to have at least two resource hits to trigger prefetch. |
| 327 NavigateToURLAndCheckSubresources(main_frame_url); | 328 NavigateToURLAndCheckSubresources(main_frame_url); |
| 328 ClearCache(); | 329 ClearCache(); |
| 329 // Prefetch all needed resources and change expectations so that all | 330 // Prefetch all needed resources and change expectations so that all |
| (...skipping 150 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 480 const net::EmbeddedTestServer* https_server() const { | 481 const net::EmbeddedTestServer* https_server() const { |
| 481 return https_server_.get(); | 482 return https_server_.get(); |
| 482 } | 483 } |
| 483 | 484 |
| 484 net::EmbeddedTestServer* https_server() { return https_server_.get(); } | 485 net::EmbeddedTestServer* https_server() { return https_server_.get(); } |
| 485 | 486 |
| 486 size_t navigation_ids_history_size() const { | 487 size_t navigation_ids_history_size() const { |
| 487 return navigation_id_history_.size(); | 488 return navigation_id_history_.size(); |
| 488 } | 489 } |
| 489 | 490 |
| 491 std::unique_ptr<base::HistogramTester> histogram_tester_; |
| 492 |
| 490 private: | 493 private: |
| 491 // ResourcePrefetchPredictor needs to be initialized before the navigation | 494 // ResourcePrefetchPredictor needs to be initialized before the navigation |
| 492 // happens otherwise this navigation will be ignored by predictor. | 495 // happens otherwise this navigation will be ignored by predictor. |
| 493 void EnsurePredictorInitialized() { | 496 void EnsurePredictorInitialized() { |
| 494 if (predictor_->initialization_state_ == | 497 if (predictor_->initialization_state_ == |
| 495 ResourcePrefetchPredictor::INITIALIZED) { | 498 ResourcePrefetchPredictor::INITIALIZED) { |
| 496 return; | 499 return; |
| 497 } | 500 } |
| 498 | 501 |
| 499 InitializationObserver observer(predictor_); | 502 InitializationObserver observer(predictor_); |
| (...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 579 if (request.headers.find("If-None-Match") != request.headers.end() && | 582 if (request.headers.find("If-None-Match") != request.headers.end() && |
| 580 request.headers.at("If-None-Match") == | 583 request.headers.at("If-None-Match") == |
| 581 CreateVersionedETag(summary.version, request.relative_url)) { | 584 CreateVersionedETag(summary.version, request.relative_url)) { |
| 582 http_response->set_code(net::HTTP_NOT_MODIFIED); | 585 http_response->set_code(net::HTTP_NOT_MODIFIED); |
| 583 } else { | 586 } else { |
| 584 http_response->set_code(net::HTTP_OK); | 587 http_response->set_code(net::HTTP_OK); |
| 585 } | 588 } |
| 586 | 589 |
| 587 if (!summary.request.mime_type.empty()) | 590 if (!summary.request.mime_type.empty()) |
| 588 http_response->set_content_type(summary.request.mime_type); | 591 http_response->set_content_type(summary.request.mime_type); |
| 589 if (!summary.content.empty()) | |
| 590 http_response->set_content(summary.content); | |
| 591 if (summary.is_no_store) | 592 if (summary.is_no_store) |
| 592 http_response->AddCustomHeader("Cache-Control", "no-store"); | 593 http_response->AddCustomHeader("Cache-Control", "no-store"); |
| 593 if (summary.request.has_validators) { | 594 if (summary.request.has_validators) { |
| 594 http_response->AddCustomHeader( | 595 http_response->AddCustomHeader( |
| 595 "ETag", CreateVersionedETag(summary.version, request.relative_url)); | 596 "ETag", CreateVersionedETag(summary.version, request.relative_url)); |
| 596 } | 597 } |
| 597 if (summary.request.always_revalidate) | 598 if (summary.request.always_revalidate) |
| 598 http_response->AddCustomHeader("Cache-Control", "no-cache"); | 599 http_response->AddCustomHeader("Cache-Control", "no-cache"); |
| 599 else | 600 else |
| 600 http_response->AddCustomHeader("Cache-Control", "max-age=2147483648"); | 601 http_response->AddCustomHeader("Cache-Control", "max-age=2147483648"); |
| 601 | 602 |
| 603 // Add some content, otherwise the prefetch size histogram rounds down to |
| 604 // 0kB. |
| 605 http_response->set_content(std::string(1024, ' ')); |
| 606 |
| 602 return std::move(http_response); | 607 return std::move(http_response); |
| 603 } | 608 } |
| 604 | 609 |
| 605 // The custom handler for redirect requests from the browser to an | 610 // The custom handler for redirect requests from the browser to an |
| 606 // EmbeddedTestServer. Running on the EmbeddedTestServer IO thread. | 611 // EmbeddedTestServer. Running on the EmbeddedTestServer IO thread. |
| 607 // Finds the data to serve requests in |redirects_| map keyed by a request | 612 // Finds the data to serve requests in |redirects_| map keyed by a request |
| 608 // URL. | 613 // URL. |
| 609 std::unique_ptr<net::test_server::HttpResponse> HandleRedirectRequest( | 614 std::unique_ptr<net::test_server::HttpResponse> HandleRedirectRequest( |
| 610 const net::test_server::HttpRequest& request) const { | 615 const net::test_server::HttpRequest& request) const { |
| 611 std::map<GURL, RedirectEdge>::const_iterator redirect_it = | 616 std::map<GURL, RedirectEdge>::const_iterator redirect_it = |
| (...skipping 23 matching lines...) Expand all Loading... |
| 635 IN_PROC_BROWSER_TEST_F(ResourcePrefetchPredictorBrowserTest, Simple) { | 640 IN_PROC_BROWSER_TEST_F(ResourcePrefetchPredictorBrowserTest, Simple) { |
| 636 // These resources have default priorities that correspond to | 641 // These resources have default priorities that correspond to |
| 637 // blink::typeToPriority function. | 642 // blink::typeToPriority function. |
| 638 AddResource(GetURL(kImagePath), content::RESOURCE_TYPE_IMAGE, net::LOWEST); | 643 AddResource(GetURL(kImagePath), content::RESOURCE_TYPE_IMAGE, net::LOWEST); |
| 639 AddResource(GetURL(kStylePath), content::RESOURCE_TYPE_STYLESHEET, | 644 AddResource(GetURL(kStylePath), content::RESOURCE_TYPE_STYLESHEET, |
| 640 net::HIGHEST); | 645 net::HIGHEST); |
| 641 AddResource(GetURL(kScriptPath), content::RESOURCE_TYPE_SCRIPT, net::MEDIUM); | 646 AddResource(GetURL(kScriptPath), content::RESOURCE_TYPE_SCRIPT, net::MEDIUM); |
| 642 AddResource(GetURL(kFontPath), content::RESOURCE_TYPE_FONT_RESOURCE, | 647 AddResource(GetURL(kFontPath), content::RESOURCE_TYPE_FONT_RESOURCE, |
| 643 net::HIGHEST); | 648 net::HIGHEST); |
| 644 TestLearningAndPrefetching(GetURL(kHtmlSubresourcesPath)); | 649 TestLearningAndPrefetching(GetURL(kHtmlSubresourcesPath)); |
| 650 |
| 651 // The local cache is cleared. |
| 652 histogram_tester_->ExpectBucketCount( |
| 653 internal::kResourcePrefetchPredictorPrefetchMissesCountCached, 0, 1); |
| 654 histogram_tester_->ExpectBucketCount( |
| 655 internal::kResourcePrefetchPredictorPrefetchMissesCountNotCached, 0, 1); |
| 656 histogram_tester_->ExpectBucketCount( |
| 657 internal::kResourcePrefetchPredictorPrefetchHitsCountCached, 0, 1); |
| 658 histogram_tester_->ExpectBucketCount( |
| 659 internal::kResourcePrefetchPredictorPrefetchHitsCountNotCached, 4, 1); |
| 660 |
| 661 histogram_tester_->ExpectBucketCount( |
| 662 internal::kResourcePrefetchPredictorPrefetchMissesSize, 0, 1); |
| 663 // Each request is ~1k, see HandleResourceRequest() above. |
| 664 histogram_tester_->ExpectBucketCount( |
| 665 internal::kResourcePrefetchPredictorPrefetchHitsSize, 4, 1); |
| 645 } | 666 } |
| 646 | 667 |
| 647 IN_PROC_BROWSER_TEST_F(ResourcePrefetchPredictorBrowserTest, Redirect) { | 668 IN_PROC_BROWSER_TEST_F(ResourcePrefetchPredictorBrowserTest, Redirect) { |
| 648 GURL initial_url = embedded_test_server()->GetURL(kFooHost, kRedirectPath); | 669 GURL initial_url = embedded_test_server()->GetURL(kFooHost, kRedirectPath); |
| 649 AddRedirectChain(initial_url, {{net::HTTP_MOVED_PERMANENTLY, | 670 AddRedirectChain(initial_url, {{net::HTTP_MOVED_PERMANENTLY, |
| 650 GetURL(kHtmlSubresourcesPath)}}); | 671 GetURL(kHtmlSubresourcesPath)}}); |
| 651 AddResource(GetURL(kImagePath), content::RESOURCE_TYPE_IMAGE, net::LOWEST); | 672 AddResource(GetURL(kImagePath), content::RESOURCE_TYPE_IMAGE, net::LOWEST); |
| 652 AddResource(GetURL(kStylePath), content::RESOURCE_TYPE_STYLESHEET, | 673 AddResource(GetURL(kStylePath), content::RESOURCE_TYPE_STYLESHEET, |
| 653 net::HIGHEST); | 674 net::HIGHEST); |
| 654 AddResource(GetURL(kScriptPath), content::RESOURCE_TYPE_SCRIPT, net::MEDIUM); | 675 AddResource(GetURL(kScriptPath), content::RESOURCE_TYPE_SCRIPT, net::MEDIUM); |
| (...skipping 217 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 872 TryToPrefetchURL(initial_url); | 893 TryToPrefetchURL(initial_url); |
| 873 NavigateToURLAndCheckSubresources(initial_url); | 894 NavigateToURLAndCheckSubresources(initial_url); |
| 874 ClearCache(); | 895 ClearCache(); |
| 875 // But the predictor database contains all subresources for the endpoint url | 896 // But the predictor database contains all subresources for the endpoint url |
| 876 // so this prefetch works. | 897 // so this prefetch works. |
| 877 PrefetchURL(GetURL(kHtmlSubresourcesPath)); | 898 PrefetchURL(GetURL(kHtmlSubresourcesPath)); |
| 878 NavigateToURLAndCheckSubresourcesAllCached(GetURL(kHtmlSubresourcesPath)); | 899 NavigateToURLAndCheckSubresourcesAllCached(GetURL(kHtmlSubresourcesPath)); |
| 879 } | 900 } |
| 880 | 901 |
| 881 } // namespace predictors | 902 } // namespace predictors |
| OLD | NEW |