Chromium Code Reviews| 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 ab06012517352d5248c1011db73166607aab2b43..a361013b5dc07bff2b2828f0feb0ee5cbaa5cba7 100644 |
| --- a/chrome/browser/predictors/resource_prefetch_predictor_browsertest.cc |
| +++ b/chrome/browser/predictors/resource_prefetch_predictor_browsertest.cc |
| @@ -21,11 +21,15 @@ |
| namespace predictors { |
| -static const char kImageUrl[] = "/predictors/image.png"; |
| -static const char kStyleUrl[] = "/predictors/style.css"; |
| -static const char kScriptUrl[] = "/predictors/script.js"; |
| -static const char kFontUrl[] = "/predictors/font.ttf"; |
| -static const char kHtmlSubresourcesUrl[] = "/predictors/html_subresources.html"; |
| +static const char kImagePath[] = "/predictors/image.png"; |
| +static const char kStylePath[] = "/predictors/style.css"; |
| +static const char kScriptPath[] = "/predictors/script.js"; |
| +static const char kFontPath[] = "/predictors/font.ttf"; |
| +static const char kHtmlSubresourcesPath[] = |
| + "/predictors/html_subresources.html"; |
| +static const char kRedirectPath[] = "/predictors/redirect.html"; |
| +static const char kRedirectPath2[] = "/predictors/redirect2.html"; |
| +static const char kRedirectPath3[] = "/predictors/redirect3.html"; |
| struct ResourceSummary { |
| ResourceSummary() : is_no_store(false), version(0) {} |
| @@ -36,6 +40,11 @@ struct ResourceSummary { |
| size_t version; |
| }; |
| +struct RedirectEdge { |
| + net::HttpStatusCode code; |
| + GURL url; |
| +}; |
| + |
| class InitializationObserver : public TestObserver { |
| public: |
| explicit InitializationObserver(ResourcePrefetchPredictor* predictor) |
| @@ -99,9 +108,12 @@ class ResourcePrefetchPredictorBrowserTest : public InProcessBrowserTest { |
| } |
| void SetUpOnMainThread() override { |
| - embedded_test_server()->RegisterRequestHandler( |
| - base::Bind(&ResourcePrefetchPredictorBrowserTest::HandleRequest, |
| - base::Unretained(this))); |
| + embedded_test_server()->RegisterRequestHandler(base::Bind( |
| + &ResourcePrefetchPredictorBrowserTest::HandleRedirectRequest, |
| + base::Unretained(this), base::Unretained(embedded_test_server()))); |
| + embedded_test_server()->RegisterRequestHandler(base::Bind( |
| + &ResourcePrefetchPredictorBrowserTest::HandleResourceRequest, |
| + base::Unretained(this), base::Unretained(embedded_test_server()))); |
| ASSERT_TRUE(embedded_test_server()->Start()); |
| predictor_ = |
| ResourcePrefetchPredictorFactory::GetForProfile(browser()->profile()); |
| @@ -109,38 +121,75 @@ class ResourcePrefetchPredictorBrowserTest : public InProcessBrowserTest { |
| EnsurePredictorInitialized(); |
| } |
| - void NavigateToURLAndCheckSubresources( |
| - const std::string& main_frame_relative) { |
| - GURL main_frame_absolute = |
| - embedded_test_server()->GetURL(main_frame_relative); |
| + void NavigateToURLAndCheckSubresources(const GURL& main_frame_url) { |
| + GURL endpoint_url = GetRedirectEndpoint(main_frame_url); |
| std::vector<URLRequestSummary> url_request_summaries; |
| for (const auto& kv : resources_) { |
| if (kv.second.is_no_store) |
| continue; |
| url_request_summaries.push_back( |
| - GetURLRequestSummaryForResource(main_frame_absolute, kv.second)); |
| + GetURLRequestSummaryForResource(endpoint_url, kv.second)); |
| } |
| ResourcePrefetchPredictorTestObserver observer( |
| - predictor_, UpdateAndGetVisitCount(main_frame_relative), |
| - CreatePageRequestSummary(main_frame_absolute.spec(), |
| - main_frame_absolute.spec(), |
| + predictor_, UpdateAndGetVisitCount(main_frame_url), |
| + CreatePageRequestSummary(endpoint_url.spec(), main_frame_url.spec(), |
| url_request_summaries)); |
| - ui_test_utils::NavigateToURL(browser(), main_frame_absolute); |
| + ui_test_utils::NavigateToURL(browser(), main_frame_url); |
| observer.Wait(); |
| } |
| - ResourceSummary* AddResource(const std::string& relative_url, |
| + ResourceSummary* AddResource(const GURL& resource_url, |
| content::ResourceType resource_type, |
| net::RequestPriority priority) { |
| ResourceSummary resource; |
| - resource.request.resource_url = |
| - embedded_test_server()->GetURL(relative_url); |
| + resource.request.resource_url = resource_url; |
| resource.request.resource_type = resource_type; |
| resource.request.priority = priority; |
| - auto result = resources_.insert(std::make_pair(relative_url, resource)); |
| + resource.request.has_validators = true; |
| + auto result = resources_.insert(std::make_pair(resource_url, resource)); |
| return &(result.first->second); |
| } |
| + void AddRedirectChain(const GURL& initial_url, |
| + const std::vector<RedirectEdge>& redirect_chain) { |
| + ASSERT_FALSE(redirect_chain.empty()); |
| + const GURL* current = &initial_url; |
|
Benoit L
2016/11/22 10:58:28
Per offline discussion, this is slightly convolute
alexilin
2016/11/22 11:04:29
Done.
|
| + for (const auto& edge : redirect_chain) { |
| + auto result = redirects_.insert(std::make_pair(*current, edge)); |
| + ASSERT_TRUE(result.second) << *current << " already has a redirect."; |
| + current = &(edge.url); |
| + } |
| + } |
| + |
| + // Simply shortcut for convenience. |
|
Benoit L
2016/11/22 10:58:28
nit: s/Simply//
alexilin
2016/11/22 11:04:29
Done.
|
| + GURL GetURL(const std::string& path) const { |
| + return embedded_test_server()->GetURL(path); |
| + } |
| + |
| + void EnableHttpsServer() { |
| + ASSERT_FALSE(https_server_); |
| + https_server_ = base::MakeUnique<net::EmbeddedTestServer>( |
| + net::EmbeddedTestServer::TYPE_HTTPS); |
| + https_server()->AddDefaultHandlers( |
| + base::FilePath(FILE_PATH_LITERAL("chrome/test/data"))); |
| + https_server()->RegisterRequestHandler( |
| + base::Bind(&ResourcePrefetchPredictorBrowserTest::HandleRedirectRequest, |
| + base::Unretained(this), base::Unretained(https_server()))); |
| + https_server()->RegisterRequestHandler( |
| + base::Bind(&ResourcePrefetchPredictorBrowserTest::HandleResourceRequest, |
| + base::Unretained(this), base::Unretained(https_server()))); |
| + ASSERT_TRUE(https_server()->Start()); |
| + } |
| + |
| + protected: |
| + // Returns the embedded test server working over HTTPS. Must be enabled by |
| + // calling EnableHttpsServer() before use. |
| + const net::EmbeddedTestServer* https_server() const { |
| + return https_server_.get(); |
| + } |
| + |
| + net::EmbeddedTestServer* https_server() { return https_server_.get(); } |
| + |
| private: |
| // ResourcePrefetchPredictor needs to be initialized before the navigation |
| // happens otherwise this navigation will be ignored by predictor. |
| @@ -160,7 +209,7 @@ class ResourcePrefetchPredictorBrowserTest : public InProcessBrowserTest { |
| URLRequestSummary GetURLRequestSummaryForResource( |
| const GURL& main_frame_url, |
| - const ResourceSummary& resource_summary) { |
| + const ResourceSummary& resource_summary) const { |
| URLRequestSummary summary(resource_summary.request); |
| content::WebContents* web_contents = |
| browser()->tab_strip_model()->GetActiveWebContents(); |
| @@ -171,9 +220,19 @@ class ResourcePrefetchPredictorBrowserTest : public InProcessBrowserTest { |
| return summary; |
| } |
| - std::unique_ptr<net::test_server::HttpResponse> HandleRequest( |
| - const net::test_server::HttpRequest& request) { |
| - auto resource_it = resources_.find(request.relative_url); |
| + GURL GetRedirectEndpoint(const GURL& initial_url) const { |
| + const GURL* current = &initial_url; |
| + for (auto it = redirects_.find(*current); it != redirects_.end(); |
| + it = redirects_.find(*current)) { |
| + current = &(it->second.url); |
| + } |
| + return *current; |
| + } |
| + |
| + std::unique_ptr<net::test_server::HttpResponse> HandleResourceRequest( |
| + const net::test_server::EmbeddedTestServer* server, |
| + const net::test_server::HttpRequest& request) const { |
| + auto resource_it = resources_.find(server->GetURL(request.relative_url)); |
| if (resource_it == resources_.end()) |
| return nullptr; |
| @@ -183,7 +242,8 @@ class ResourcePrefetchPredictorBrowserTest : public InProcessBrowserTest { |
| http_response->set_code(net::HTTP_OK); |
| if (!summary.request.mime_type.empty()) |
| http_response->set_content_type(summary.request.mime_type); |
| - http_response->set_content(summary.content); |
| + if (!summary.content.empty()) |
| + http_response->set_content(summary.content); |
| if (summary.is_no_store) |
| http_response->AddCustomHeader("Cache-Control", "no-store"); |
| if (summary.request.has_validators) { |
| @@ -198,23 +258,87 @@ class ResourcePrefetchPredictorBrowserTest : public InProcessBrowserTest { |
| return std::move(http_response); |
| } |
| - size_t UpdateAndGetVisitCount(const std::string& main_frame_relative) { |
| - return ++visit_count_[main_frame_relative]; |
| + std::unique_ptr<net::test_server::HttpResponse> HandleRedirectRequest( |
| + const net::test_server::EmbeddedTestServer* server, |
| + const net::test_server::HttpRequest& request) const { |
| + auto redirect_it = redirects_.find(server->GetURL(request.relative_url)); |
| + if (redirect_it == redirects_.end()) |
| + return nullptr; |
| + |
| + auto http_response = |
| + base::MakeUnique<net::test_server::BasicHttpResponse>(); |
| + http_response->set_code(redirect_it->second.code); |
| + http_response->AddCustomHeader("Location", redirect_it->second.url.spec()); |
| + return std::move(http_response); |
| + } |
| + |
| + size_t UpdateAndGetVisitCount(const GURL& main_frame_url) { |
| + return ++visit_count_[main_frame_url]; |
| } |
| ResourcePrefetchPredictor* predictor_; |
| - std::map<std::string, ResourceSummary> resources_; |
| - std::map<std::string, size_t> visit_count_; |
| + std::unique_ptr<net::EmbeddedTestServer> https_server_; |
| + std::map<GURL, ResourceSummary> resources_; |
| + std::map<GURL, RedirectEdge> redirects_; |
| + std::map<GURL, size_t> visit_count_; |
| }; |
| IN_PROC_BROWSER_TEST_F(ResourcePrefetchPredictorBrowserTest, LearningSimple) { |
| // These resources have default priorities that correspond to |
| // blink::typeToPriority function. |
| - AddResource(kImageUrl, content::RESOURCE_TYPE_IMAGE, net::LOWEST); |
| - AddResource(kStyleUrl, content::RESOURCE_TYPE_STYLESHEET, net::HIGHEST); |
| - AddResource(kScriptUrl, content::RESOURCE_TYPE_SCRIPT, net::MEDIUM); |
| - AddResource(kFontUrl, content::RESOURCE_TYPE_FONT_RESOURCE, net::HIGHEST); |
| - NavigateToURLAndCheckSubresources(kHtmlSubresourcesUrl); |
| + 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(ResourcePrefetchPredictorBrowserTest, |
| + LearningAfterRedirect) { |
| + AddRedirectChain(GetURL(kRedirectPath), {{net::HTTP_MOVED_PERMANENTLY, |
| + GetURL(kHtmlSubresourcesPath)}}); |
| + 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(kRedirectPath)); |
| +} |
| + |
| +IN_PROC_BROWSER_TEST_F(ResourcePrefetchPredictorBrowserTest, |
| + LearningAfterRedirectChain) { |
| + AddRedirectChain(GetURL(kRedirectPath), |
| + {{net::HTTP_FOUND, GetURL(kRedirectPath2)}, |
| + {net::HTTP_MOVED_PERMANENTLY, GetURL(kRedirectPath3)}, |
| + {net::HTTP_FOUND, GetURL(kHtmlSubresourcesPath)}}); |
| + 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(kRedirectPath)); |
| +} |
| + |
| +IN_PROC_BROWSER_TEST_F(ResourcePrefetchPredictorBrowserTest, |
| + LearningAfterHttpToHttpsRedirect) { |
| + EnableHttpsServer(); |
| + AddRedirectChain(GetURL(kRedirectPath), |
| + {{net::HTTP_FOUND, https_server()->GetURL(kRedirectPath2)}, |
| + {net::HTTP_MOVED_PERMANENTLY, |
| + https_server()->GetURL(kHtmlSubresourcesPath)}}); |
| + AddResource(https_server()->GetURL(kImagePath), content::RESOURCE_TYPE_IMAGE, |
| + net::LOWEST); |
| + AddResource(https_server()->GetURL(kStylePath), |
| + content::RESOURCE_TYPE_STYLESHEET, net::HIGHEST); |
| + AddResource(https_server()->GetURL(kScriptPath), |
| + content::RESOURCE_TYPE_SCRIPT, net::MEDIUM); |
| + AddResource(https_server()->GetURL(kFontPath), |
| + content::RESOURCE_TYPE_FONT_RESOURCE, net::HIGHEST); |
| + NavigateToURLAndCheckSubresources(GetURL(kRedirectPath)); |
| } |
| } // namespace predictors |