| Index: chrome/browser/predictors/resource_prefetch_predictor_browsertest.cc
|
| diff --git a/chrome/browser/predictors/resource_prefetch_predictor_browsertest.cc b/chrome/browser/predictors/resource_prefetch_predictor_browsertest.cc
|
| index c9ab1bf7d49b80fd04537fa57badfb65b8920df9..9d05495b5e0ab1a60c556fbc28d4b039f416a34a 100644
|
| --- a/chrome/browser/predictors/resource_prefetch_predictor_browsertest.cc
|
| +++ b/chrome/browser/predictors/resource_prefetch_predictor_browsertest.cc
|
| @@ -8,12 +8,12 @@
|
| #include "chrome/browser/predictors/resource_prefetch_predictor_test_util.h"
|
| #include "chrome/browser/profiles/profile.h"
|
| #include "chrome/browser/ui/browser.h"
|
| +#include "chrome/browser/ui/browser_commands.h"
|
| #include "chrome/browser/ui/tabs/tab_strip_model.h"
|
| #include "chrome/common/chrome_switches.h"
|
| #include "chrome/test/base/in_process_browser_test.h"
|
| #include "chrome/test/base/ui_test_utils.h"
|
| -#include "content/public/browser/render_frame_host.h"
|
| -#include "content/public/browser/render_process_host.h"
|
| +#include "net/dns/mock_host_resolver.h"
|
| #include "net/test/embedded_test_server/http_request.h"
|
| #include "net/test/embedded_test_server/http_response.h"
|
| #include "testing/gmock/include/gmock/gmock.h"
|
| @@ -91,6 +91,12 @@ class InitializationObserver : public TestObserver {
|
| using PageRequestSummary = ResourcePrefetchPredictor::PageRequestSummary;
|
| using URLRequestSummary = ResourcePrefetchPredictor::URLRequestSummary;
|
|
|
| +struct ResourceComparisonParameters {
|
| + bool match_navigation_id;
|
| +
|
| + ResourceComparisonParameters() : match_navigation_id(true) {}
|
| +};
|
| +
|
| void RemoveDuplicateSubresources(std::vector<URLRequestSummary>* subresources) {
|
| std::stable_sort(subresources->begin(), subresources->end(),
|
| [](const URLRequestSummary& x, const URLRequestSummary& y) {
|
| @@ -107,14 +113,14 @@ void RemoveDuplicateSubresources(std::vector<URLRequestSummary>* subresources) {
|
| // Fill a NavigationID with "empty" data that does not trigger
|
| // the is_valid DCHECK(). Allows comparing.
|
| void SetValidNavigationID(NavigationID* navigation_id) {
|
| - navigation_id->render_process_id = 0;
|
| - navigation_id->render_frame_id = 0;
|
| + navigation_id->session_id.set_id(0);
|
| navigation_id->main_frame_url = GURL("http://127.0.0.1");
|
| }
|
|
|
| -void ModifySubresourceForComparison(URLRequestSummary* subresource,
|
| - bool match_navigation_id) {
|
| - if (!match_navigation_id)
|
| +void ModifySubresourceForComparison(
|
| + URLRequestSummary* subresource,
|
| + const ResourceComparisonParameters& params) {
|
| + if (!params.match_navigation_id)
|
| SetValidNavigationID(&subresource->navigation_id);
|
| if (subresource->resource_type == content::RESOURCE_TYPE_IMAGE &&
|
| subresource->priority == net::LOWEST) {
|
| @@ -129,15 +135,15 @@ void ModifySubresourceForComparison(URLRequestSummary* subresource,
|
| // and fail the test if the expectation is not met.
|
| void CompareSubresources(std::vector<URLRequestSummary> actual_subresources,
|
| std::vector<URLRequestSummary> expected_subresources,
|
| - bool match_navigation_id) {
|
| + const ResourceComparisonParameters& params) {
|
| // Duplicate resources can be observed in a single navigation but
|
| // ResourcePrefetchPredictor only cares about the first occurrence of each.
|
| RemoveDuplicateSubresources(&actual_subresources);
|
|
|
| for (auto& subresource : actual_subresources)
|
| - ModifySubresourceForComparison(&subresource, match_navigation_id);
|
| + ModifySubresourceForComparison(&subresource, params);
|
| for (auto& subresource : expected_subresources)
|
| - ModifySubresourceForComparison(&subresource, match_navigation_id);
|
| + ModifySubresourceForComparison(&subresource, params);
|
|
|
| EXPECT_THAT(actual_subresources,
|
| testing::UnorderedElementsAreArray(expected_subresources));
|
| @@ -156,11 +162,11 @@ class ResourcePrefetchPredictorTestObserver : public TestObserver {
|
| ResourcePrefetchPredictor* predictor,
|
| const size_t expected_url_visit_count,
|
| const PageRequestSummary& expected_summary,
|
| - bool match_navigation_id)
|
| + const ResourceComparisonParameters& resource_comparison_params)
|
| : TestObserver(predictor),
|
| url_visit_count_(expected_url_visit_count),
|
| summary_(expected_summary),
|
| - match_navigation_id_(match_navigation_id) {}
|
| + resource_comparison_params_(resource_comparison_params) {}
|
|
|
| // TestObserver:
|
| void OnNavigationLearned(size_t url_visit_count,
|
| @@ -168,18 +174,26 @@ class ResourcePrefetchPredictorTestObserver : public TestObserver {
|
| EXPECT_EQ(url_visit_count, url_visit_count_);
|
| EXPECT_EQ(summary.main_frame_url, summary_.main_frame_url);
|
| EXPECT_EQ(summary.initial_url, summary_.initial_url);
|
| + for (const auto& resource : summary.subresource_requests)
|
| + ++current_navigation_ids_[resource.navigation_id];
|
| CompareSubresources(summary.subresource_requests,
|
| - summary_.subresource_requests, match_navigation_id_);
|
| + summary_.subresource_requests,
|
| + resource_comparison_params_);
|
| run_loop_.Quit();
|
| }
|
|
|
| void Wait() { run_loop_.Run(); }
|
|
|
| + std::map<NavigationID, int>* GetNavigationIds() {
|
| + return ¤t_navigation_ids_;
|
| + }
|
| +
|
| private:
|
| base::RunLoop run_loop_;
|
| size_t url_visit_count_;
|
| PageRequestSummary summary_;
|
| - bool match_navigation_id_;
|
| + ResourceComparisonParameters resource_comparison_params_;
|
| + std::map<NavigationID, int> current_navigation_ids_;
|
|
|
| DISALLOW_COPY_AND_ASSIGN(ResourcePrefetchPredictorTestObserver);
|
| };
|
| @@ -195,6 +209,10 @@ class ResourcePrefetchPredictorBrowserTest : public InProcessBrowserTest {
|
| }
|
|
|
| void SetUpOnMainThread() override {
|
| + SetCurrentHostName("127.0.0.1");
|
| + host_resolver()->AddRule("*", "127.0.0.1");
|
| + embedded_test_server()->AddDefaultHandlers(
|
| + base::FilePath(FILE_PATH_LITERAL("chrome/test/data")));
|
| embedded_test_server()->RegisterRequestHandler(
|
| base::Bind(&ResourcePrefetchPredictorBrowserTest::HandleRedirectRequest,
|
| base::Unretained(this)));
|
| @@ -219,15 +237,26 @@ class ResourcePrefetchPredictorBrowserTest : public InProcessBrowserTest {
|
| url_request_summaries.push_back(
|
| GetURLRequestSummaryForResource(endpoint_url, kv.second));
|
| }
|
| +
|
| + ResourceComparisonParameters resource_comparison_params;
|
| + if (disposition != WindowOpenDisposition::CURRENT_TAB)
|
| + resource_comparison_params.match_navigation_id = false;
|
| +
|
| ResourcePrefetchPredictorTestObserver observer(
|
| predictor_, UpdateAndGetVisitCount(main_frame_url),
|
| CreatePageRequestSummary(endpoint_url.spec(), main_frame_url.spec(),
|
| url_request_summaries),
|
| - true); // Matching navigation id by default
|
| + resource_comparison_params);
|
| ui_test_utils::NavigateToURLWithDisposition(
|
| browser(), main_frame_url, disposition,
|
| ui_test_utils::BROWSER_TEST_NONE);
|
| observer.Wait();
|
| + for (auto& kv : resources_) {
|
| + if (!kv.second.is_no_store && kv.second.should_be_recorded)
|
| + kv.second.request.was_cached = true;
|
| + }
|
| + for (const auto& nav : *observer.GetNavigationIds())
|
| + ++navigation_id_history_[nav.first];
|
| }
|
|
|
| ResourceSummary* AddResource(const GURL& resource_url,
|
| @@ -273,9 +302,17 @@ class ResourcePrefetchPredictorBrowserTest : public InProcessBrowserTest {
|
| }
|
| }
|
|
|
| + void ClearResources() { resources_.clear(); }
|
| +
|
| + void ClearCache() {
|
| + chrome::ClearCache(browser());
|
| + for (auto& kv : resources_)
|
| + kv.second.request.was_cached = false;
|
| + }
|
| +
|
| // Shortcut for convenience.
|
| GURL GetURL(const std::string& path) const {
|
| - return embedded_test_server()->GetURL(path);
|
| + return embedded_test_server()->GetURL(current_host_name_, path);
|
| }
|
|
|
| void EnableHttpsServer() {
|
| @@ -301,6 +338,12 @@ class ResourcePrefetchPredictorBrowserTest : public InProcessBrowserTest {
|
|
|
| net::EmbeddedTestServer* https_server() { return https_server_.get(); }
|
|
|
| + void SetCurrentHostName(const std::string& new_host) {
|
| + current_host_name_ = new_host;
|
| + }
|
| +
|
| + unsigned int GetHistoryCount() { return navigation_id_history_.size(); }
|
| +
|
| private:
|
| // ResourcePrefetchPredictor needs to be initialized before the navigation
|
| // happens otherwise this navigation will be ignored by predictor.
|
| @@ -324,10 +367,8 @@ class ResourcePrefetchPredictorBrowserTest : public InProcessBrowserTest {
|
| URLRequestSummary summary(resource_summary.request);
|
| content::WebContents* web_contents =
|
| browser()->tab_strip_model()->GetActiveWebContents();
|
| - int process_id = web_contents->GetRenderProcessHost()->GetID();
|
| - int frame_id = web_contents->GetMainFrame()->GetRoutingID();
|
| summary.navigation_id =
|
| - CreateNavigationID(process_id, frame_id, main_frame_url.spec());
|
| + NavigationID(web_contents, main_frame_url, base::TimeTicks::Now());
|
| return summary;
|
| }
|
|
|
| @@ -344,7 +385,12 @@ class ResourcePrefetchPredictorBrowserTest : public InProcessBrowserTest {
|
|
|
| std::unique_ptr<net::test_server::HttpResponse> HandleResourceRequest(
|
| const net::test_server::HttpRequest& request) const {
|
| - auto resource_it = resources_.find(request.GetURL());
|
| + GURL resource_url = request.GetURL();
|
| + GURL::Replacements replace_host;
|
| + replace_host.SetHostStr(current_host_name_);
|
| + resource_url = resource_url.ReplaceComponents(replace_host);
|
| +
|
| + auto resource_it = resources_.find(resource_url);
|
| if (resource_it == resources_.end())
|
| return nullptr;
|
|
|
| @@ -390,11 +436,26 @@ class ResourcePrefetchPredictorBrowserTest : public InProcessBrowserTest {
|
| return ++visit_count_[main_frame_url];
|
| }
|
|
|
| + std::string current_host_name_;
|
| ResourcePrefetchPredictor* predictor_;
|
| std::unique_ptr<net::EmbeddedTestServer> https_server_;
|
| std::map<GURL, ResourceSummary> resources_;
|
| std::map<GURL, RedirectEdge> redirects_;
|
| std::map<GURL, size_t> visit_count_;
|
| + std::map<NavigationID, int> navigation_id_history_;
|
| +};
|
| +
|
| +// TODO(ahemery): Remove when https://codereview.chromium.org/2553083002/
|
| +// is landed by Alex. LearningObserver should be used by default.
|
| +// His change will disable actual prefetching by default
|
| +class ResourcePrefetchPredictorLearningBrowserTest
|
| + : public ResourcePrefetchPredictorBrowserTest {
|
| + protected:
|
| + void SetUpCommandLine(base::CommandLine* command_line) override {
|
| + command_line->AppendSwitchASCII(
|
| + switches::kSpeculativeResourcePrefetching,
|
| + switches::kSpeculativeResourcePrefetchingLearning);
|
| + }
|
| };
|
|
|
| IN_PROC_BROWSER_TEST_F(ResourcePrefetchPredictorBrowserTest, LearningSimple) {
|
| @@ -529,4 +590,54 @@ IN_PROC_BROWSER_TEST_F(ResourcePrefetchPredictorBrowserTest,
|
| NavigateToURLAndCheckSubresources(GetURL(kHtmlIframePath));
|
| }
|
|
|
| +IN_PROC_BROWSER_TEST_F(ResourcePrefetchPredictorBrowserTest,
|
| + CrossSiteLearning) {
|
| + SetCurrentHostName("foo.com");
|
| + AddResource(GetURL(kImagePath), content::RESOURCE_TYPE_IMAGE, net::LOWEST);
|
| + AddResource(GetURL(kStylePath), content::RESOURCE_TYPE_STYLESHEET,
|
| + net::HIGHEST);
|
| + AddResource(GetURL(kScriptPath), content::RESOURCE_TYPE_SCRIPT, net::MEDIUM);
|
| + AddResource(GetURL(kFontPath), content::RESOURCE_TYPE_FONT_RESOURCE,
|
| + net::HIGHEST);
|
| + NavigateToURLAndCheckSubresources(GetURL(kHtmlSubresourcesPath));
|
| + ClearResources();
|
| +
|
| + SetCurrentHostName("bar.com");
|
| + AddResource(GetURL(kImagePath), content::RESOURCE_TYPE_IMAGE, net::LOWEST);
|
| + AddResource(GetURL(kStylePath), content::RESOURCE_TYPE_STYLESHEET,
|
| + net::HIGHEST);
|
| + AddResource(GetURL(kScriptPath), content::RESOURCE_TYPE_SCRIPT, net::MEDIUM);
|
| + AddResource(GetURL(kFontPath), content::RESOURCE_TYPE_FONT_RESOURCE,
|
| + net::HIGHEST);
|
| +
|
| + NavigateToURLAndCheckSubresources(GetURL(kHtmlSubresourcesPath));
|
| +}
|
| +
|
| +IN_PROC_BROWSER_TEST_F(ResourcePrefetchPredictorLearningBrowserTest,
|
| + TabIdBehavingAsExpected) {
|
| + AddResource(GetURL(kImagePath), content::RESOURCE_TYPE_IMAGE, net::LOWEST);
|
| + AddResource(GetURL(kStylePath), content::RESOURCE_TYPE_STYLESHEET,
|
| + net::HIGHEST);
|
| + AddResource(GetURL(kScriptPath), content::RESOURCE_TYPE_SCRIPT, net::MEDIUM);
|
| + AddResource(GetURL(kFontPath), content::RESOURCE_TYPE_FONT_RESOURCE,
|
| + net::HIGHEST);
|
| + NavigateToURLAndCheckSubresources(GetURL(kHtmlSubresourcesPath));
|
| + EXPECT_EQ(GetHistoryCount(), 1U);
|
| + ClearCache();
|
| + NavigateToURLAndCheckSubresources(GetURL(kHtmlSubresourcesPath));
|
| + EXPECT_EQ(GetHistoryCount(), 1U);
|
| + ClearCache();
|
| + NavigateToURLAndCheckSubresources(GetURL(kHtmlSubresourcesPath),
|
| + WindowOpenDisposition::NEW_FOREGROUND_TAB);
|
| + EXPECT_EQ(GetHistoryCount(), 2U);
|
| + ClearCache();
|
| + NavigateToURLAndCheckSubresources(GetURL(kHtmlSubresourcesPath),
|
| + WindowOpenDisposition::NEW_WINDOW);
|
| + EXPECT_EQ(GetHistoryCount(), 3U);
|
| + ClearCache();
|
| + NavigateToURLAndCheckSubresources(GetURL(kHtmlSubresourcesPath),
|
| + WindowOpenDisposition::NEW_POPUP);
|
| + EXPECT_EQ(GetHistoryCount(), 4U);
|
| +}
|
| +
|
| } // namespace predictors
|
|
|