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/tabs/tab_strip_model.h" | 11 #include "chrome/browser/ui/tabs/tab_strip_model.h" |
| 12 #include "chrome/common/chrome_switches.h" | 12 #include "chrome/common/chrome_switches.h" |
| 13 #include "chrome/test/base/in_process_browser_test.h" | 13 #include "chrome/test/base/in_process_browser_test.h" |
| 14 #include "chrome/test/base/ui_test_utils.h" | 14 #include "chrome/test/base/ui_test_utils.h" |
| 15 #include "content/public/browser/render_frame_host.h" | 15 #include "content/public/browser/render_frame_host.h" |
| 16 #include "content/public/browser/render_process_host.h" | 16 #include "content/public/browser/render_process_host.h" |
| 17 #include "net/test/embedded_test_server/http_request.h" | 17 #include "net/test/embedded_test_server/http_request.h" |
| 18 #include "net/test/embedded_test_server/http_response.h" | 18 #include "net/test/embedded_test_server/http_response.h" |
| 19 #include "testing/gmock/include/gmock/gmock.h" | 19 #include "testing/gmock/include/gmock/gmock.h" |
| 20 #include "testing/gtest/include/gtest/gtest.h" | 20 #include "testing/gtest/include/gtest/gtest.h" |
| 21 | 21 |
| 22 namespace predictors { | 22 namespace predictors { |
| 23 | 23 |
| 24 static const char kImageUrl[] = "/predictors/image.png"; | 24 static const char kImagePath[] = "/predictors/image.png"; |
| 25 static const char kStyleUrl[] = "/predictors/style.css"; | 25 static const char kStylePath[] = "/predictors/style.css"; |
| 26 static const char kScriptUrl[] = "/predictors/script.js"; | 26 static const char kScriptPath[] = "/predictors/script.js"; |
| 27 static const char kFontUrl[] = "/predictors/font.ttf"; | 27 static const char kFontPath[] = "/predictors/font.ttf"; |
| 28 static const char kHtmlSubresourcesUrl[] = "/predictors/html_subresources.html"; | 28 static const char kHtmlSubresourcesPath[] = |
| 29 "/predictors/html_subresources.html"; | |
| 30 static const char kRedirectPath[] = "/predictors/redirect.html"; | |
| 31 static const char kRedirectPath2[] = "/predictors/redirect2.html"; | |
| 32 static const char kRedirectPath3[] = "/predictors/redirect3.html"; | |
| 29 | 33 |
| 30 struct ResourceSummary { | 34 struct ResourceSummary { |
| 31 ResourceSummary() : is_no_store(false), version(0) {} | 35 ResourceSummary() : is_no_store(false), version(0) {} |
| 32 | 36 |
| 33 ResourcePrefetchPredictor::URLRequestSummary request; | 37 ResourcePrefetchPredictor::URLRequestSummary request; |
| 34 std::string content; | 38 std::string content; |
| 35 bool is_no_store; | 39 bool is_no_store; |
| 36 size_t version; | 40 size_t version; |
| 37 }; | 41 }; |
| 38 | 42 |
| 43 struct RedirectEdge { | |
| 44 net::HttpStatusCode code; | |
|
pasko
2016/11/22 15:42:14
Makes sense to clarify in the comment whether it i
alexilin
2016/11/22 16:12:36
Done.
| |
| 45 GURL url; | |
| 46 }; | |
| 47 | |
| 39 class InitializationObserver : public TestObserver { | 48 class InitializationObserver : public TestObserver { |
| 40 public: | 49 public: |
| 41 explicit InitializationObserver(ResourcePrefetchPredictor* predictor) | 50 explicit InitializationObserver(ResourcePrefetchPredictor* predictor) |
| 42 : TestObserver(predictor) {} | 51 : TestObserver(predictor) {} |
| 43 | 52 |
| 44 void OnPredictorInitialized() override { run_loop_.Quit(); } | 53 void OnPredictorInitialized() override { run_loop_.Quit(); } |
| 45 | 54 |
| 46 void Wait() { run_loop_.Run(); } | 55 void Wait() { run_loop_.Run(); } |
| 47 | 56 |
| 48 private: | 57 private: |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 92 public: | 101 public: |
| 93 using URLRequestSummary = ResourcePrefetchPredictor::URLRequestSummary; | 102 using URLRequestSummary = ResourcePrefetchPredictor::URLRequestSummary; |
| 94 | 103 |
| 95 void SetUpCommandLine(base::CommandLine* command_line) override { | 104 void SetUpCommandLine(base::CommandLine* command_line) override { |
| 96 command_line->AppendSwitchASCII( | 105 command_line->AppendSwitchASCII( |
| 97 switches::kSpeculativeResourcePrefetching, | 106 switches::kSpeculativeResourcePrefetching, |
| 98 switches::kSpeculativeResourcePrefetchingEnabled); | 107 switches::kSpeculativeResourcePrefetchingEnabled); |
| 99 } | 108 } |
| 100 | 109 |
| 101 void SetUpOnMainThread() override { | 110 void SetUpOnMainThread() override { |
| 102 embedded_test_server()->RegisterRequestHandler( | 111 embedded_test_server()->RegisterRequestHandler(base::Bind( |
| 103 base::Bind(&ResourcePrefetchPredictorBrowserTest::HandleRequest, | 112 &ResourcePrefetchPredictorBrowserTest::HandleRedirectRequest, |
| 104 base::Unretained(this))); | 113 base::Unretained(this), base::Unretained(embedded_test_server()))); |
| 114 embedded_test_server()->RegisterRequestHandler(base::Bind( | |
| 115 &ResourcePrefetchPredictorBrowserTest::HandleResourceRequest, | |
| 116 base::Unretained(this), base::Unretained(embedded_test_server()))); | |
| 105 ASSERT_TRUE(embedded_test_server()->Start()); | 117 ASSERT_TRUE(embedded_test_server()->Start()); |
| 106 predictor_ = | 118 predictor_ = |
| 107 ResourcePrefetchPredictorFactory::GetForProfile(browser()->profile()); | 119 ResourcePrefetchPredictorFactory::GetForProfile(browser()->profile()); |
| 108 ASSERT_TRUE(predictor_); | 120 ASSERT_TRUE(predictor_); |
| 109 EnsurePredictorInitialized(); | 121 EnsurePredictorInitialized(); |
| 110 } | 122 } |
| 111 | 123 |
| 112 void NavigateToURLAndCheckSubresources( | 124 void NavigateToURLAndCheckSubresources(const GURL& main_frame_url) { |
| 113 const std::string& main_frame_relative) { | 125 GURL endpoint_url = GetRedirectEndpoint(main_frame_url); |
| 114 GURL main_frame_absolute = | |
| 115 embedded_test_server()->GetURL(main_frame_relative); | |
| 116 std::vector<URLRequestSummary> url_request_summaries; | 126 std::vector<URLRequestSummary> url_request_summaries; |
| 117 for (const auto& kv : resources_) { | 127 for (const auto& kv : resources_) { |
| 118 if (kv.second.is_no_store) | 128 if (kv.second.is_no_store) |
| 119 continue; | 129 continue; |
| 120 url_request_summaries.push_back( | 130 url_request_summaries.push_back( |
| 121 GetURLRequestSummaryForResource(main_frame_absolute, kv.second)); | 131 GetURLRequestSummaryForResource(endpoint_url, kv.second)); |
| 122 } | 132 } |
| 123 ResourcePrefetchPredictorTestObserver observer( | 133 ResourcePrefetchPredictorTestObserver observer( |
| 124 predictor_, UpdateAndGetVisitCount(main_frame_relative), | 134 predictor_, UpdateAndGetVisitCount(main_frame_url), |
| 125 CreatePageRequestSummary(main_frame_absolute.spec(), | 135 CreatePageRequestSummary(endpoint_url.spec(), main_frame_url.spec(), |
| 126 main_frame_absolute.spec(), | |
| 127 url_request_summaries)); | 136 url_request_summaries)); |
| 128 ui_test_utils::NavigateToURL(browser(), main_frame_absolute); | 137 ui_test_utils::NavigateToURL(browser(), main_frame_url); |
| 129 observer.Wait(); | 138 observer.Wait(); |
| 130 } | 139 } |
| 131 | 140 |
| 132 ResourceSummary* AddResource(const std::string& relative_url, | 141 ResourceSummary* AddResource(const GURL& resource_url, |
| 133 content::ResourceType resource_type, | 142 content::ResourceType resource_type, |
| 134 net::RequestPriority priority) { | 143 net::RequestPriority priority) { |
| 135 ResourceSummary resource; | 144 auto pair_and_whether_inserted = |
| 136 resource.request.resource_url = | 145 resources_.insert(std::make_pair(resource_url, ResourceSummary())); |
| 137 embedded_test_server()->GetURL(relative_url); | 146 EXPECT_TRUE(pair_and_whether_inserted.second) << resource_url |
| 138 resource.request.resource_type = resource_type; | 147 << " was inserted twice"; |
| 139 resource.request.priority = priority; | 148 ResourceSummary* resource = &pair_and_whether_inserted.first->second; |
| 140 auto result = resources_.insert(std::make_pair(relative_url, resource)); | 149 resource->request.resource_url = resource_url; |
| 141 return &(result.first->second); | 150 resource->request.resource_type = resource_type; |
| 151 resource->request.priority = priority; | |
| 152 resource->request.has_validators = true; | |
| 153 return resource; | |
| 142 } | 154 } |
| 143 | 155 |
| 156 void AddRedirectChain(const GURL& initial_url, | |
| 157 const std::vector<RedirectEdge>& redirect_chain) { | |
| 158 ASSERT_FALSE(redirect_chain.empty()); | |
| 159 GURL current = initial_url; | |
| 160 for (const auto& edge : redirect_chain) { | |
| 161 auto result = redirects_.insert(std::make_pair(current, edge)); | |
| 162 EXPECT_TRUE(result.second) << current << " already has a redirect."; | |
| 163 current = edge.url; | |
| 164 } | |
| 165 } | |
| 166 | |
| 167 // Shortcut for convenience. | |
| 168 GURL GetURL(const std::string& path) const { | |
| 169 return embedded_test_server()->GetURL(path); | |
| 170 } | |
| 171 | |
| 172 void EnableHttpsServer() { | |
| 173 ASSERT_FALSE(https_server_); | |
| 174 https_server_ = base::MakeUnique<net::EmbeddedTestServer>( | |
| 175 net::EmbeddedTestServer::TYPE_HTTPS); | |
| 176 https_server()->AddDefaultHandlers( | |
| 177 base::FilePath(FILE_PATH_LITERAL("chrome/test/data"))); | |
| 178 https_server()->RegisterRequestHandler( | |
| 179 base::Bind(&ResourcePrefetchPredictorBrowserTest::HandleRedirectRequest, | |
| 180 base::Unretained(this), base::Unretained(https_server()))); | |
| 181 https_server()->RegisterRequestHandler( | |
| 182 base::Bind(&ResourcePrefetchPredictorBrowserTest::HandleResourceRequest, | |
| 183 base::Unretained(this), base::Unretained(https_server()))); | |
| 184 ASSERT_TRUE(https_server()->Start()); | |
| 185 } | |
| 186 | |
| 187 protected: | |
| 188 // Returns the embedded test server working over HTTPS. Must be enabled by | |
| 189 // calling EnableHttpsServer() before use. | |
| 190 const net::EmbeddedTestServer* https_server() const { | |
| 191 return https_server_.get(); | |
| 192 } | |
| 193 | |
| 194 net::EmbeddedTestServer* https_server() { return https_server_.get(); } | |
| 195 | |
| 144 private: | 196 private: |
| 145 // ResourcePrefetchPredictor needs to be initialized before the navigation | 197 // ResourcePrefetchPredictor needs to be initialized before the navigation |
| 146 // happens otherwise this navigation will be ignored by predictor. | 198 // happens otherwise this navigation will be ignored by predictor. |
| 147 void EnsurePredictorInitialized() { | 199 void EnsurePredictorInitialized() { |
| 148 if (predictor_->initialization_state_ == | 200 if (predictor_->initialization_state_ == |
| 149 ResourcePrefetchPredictor::INITIALIZED) { | 201 ResourcePrefetchPredictor::INITIALIZED) { |
| 150 return; | 202 return; |
| 151 } | 203 } |
| 152 | 204 |
| 153 InitializationObserver observer(predictor_); | 205 InitializationObserver observer(predictor_); |
| 154 if (predictor_->initialization_state_ == | 206 if (predictor_->initialization_state_ == |
| 155 ResourcePrefetchPredictor::NOT_INITIALIZED) { | 207 ResourcePrefetchPredictor::NOT_INITIALIZED) { |
| 156 predictor_->StartInitialization(); | 208 predictor_->StartInitialization(); |
| 157 } | 209 } |
| 158 observer.Wait(); | 210 observer.Wait(); |
| 159 } | 211 } |
| 160 | 212 |
| 161 URLRequestSummary GetURLRequestSummaryForResource( | 213 URLRequestSummary GetURLRequestSummaryForResource( |
| 162 const GURL& main_frame_url, | 214 const GURL& main_frame_url, |
| 163 const ResourceSummary& resource_summary) { | 215 const ResourceSummary& resource_summary) const { |
| 164 URLRequestSummary summary(resource_summary.request); | 216 URLRequestSummary summary(resource_summary.request); |
| 165 content::WebContents* web_contents = | 217 content::WebContents* web_contents = |
| 166 browser()->tab_strip_model()->GetActiveWebContents(); | 218 browser()->tab_strip_model()->GetActiveWebContents(); |
| 167 int process_id = web_contents->GetRenderProcessHost()->GetID(); | 219 int process_id = web_contents->GetRenderProcessHost()->GetID(); |
| 168 int frame_id = web_contents->GetMainFrame()->GetRoutingID(); | 220 int frame_id = web_contents->GetMainFrame()->GetRoutingID(); |
| 169 summary.navigation_id = | 221 summary.navigation_id = |
| 170 CreateNavigationID(process_id, frame_id, main_frame_url.spec()); | 222 CreateNavigationID(process_id, frame_id, main_frame_url.spec()); |
| 171 return summary; | 223 return summary; |
| 172 } | 224 } |
| 173 | 225 |
| 174 std::unique_ptr<net::test_server::HttpResponse> HandleRequest( | 226 GURL GetRedirectEndpoint(const GURL& initial_url) const { |
| 175 const net::test_server::HttpRequest& request) { | 227 GURL current = initial_url; |
| 176 auto resource_it = resources_.find(request.relative_url); | 228 while (true) { |
| 229 auto it = redirects_.find(current); | |
| 230 if (it == redirects_.end()) | |
| 231 break; | |
| 232 current = it->second.url; | |
| 233 } | |
| 234 return current; | |
| 235 } | |
| 236 | |
| 237 std::unique_ptr<net::test_server::HttpResponse> HandleResourceRequest( | |
| 238 const net::test_server::EmbeddedTestServer* server, | |
| 239 const net::test_server::HttpRequest& request) const { | |
| 240 auto resource_it = resources_.find(server->GetURL(request.relative_url)); | |
| 177 if (resource_it == resources_.end()) | 241 if (resource_it == resources_.end()) |
| 178 return nullptr; | 242 return nullptr; |
| 179 | 243 |
| 180 const ResourceSummary& summary = resource_it->second; | 244 const ResourceSummary& summary = resource_it->second; |
| 181 auto http_response = | 245 auto http_response = |
| 182 base::MakeUnique<net::test_server::BasicHttpResponse>(); | 246 base::MakeUnique<net::test_server::BasicHttpResponse>(); |
| 183 http_response->set_code(net::HTTP_OK); | 247 http_response->set_code(net::HTTP_OK); |
| 184 if (!summary.request.mime_type.empty()) | 248 if (!summary.request.mime_type.empty()) |
| 185 http_response->set_content_type(summary.request.mime_type); | 249 http_response->set_content_type(summary.request.mime_type); |
| 186 http_response->set_content(summary.content); | 250 if (!summary.content.empty()) |
| 251 http_response->set_content(summary.content); | |
| 187 if (summary.is_no_store) | 252 if (summary.is_no_store) |
| 188 http_response->AddCustomHeader("Cache-Control", "no-store"); | 253 http_response->AddCustomHeader("Cache-Control", "no-store"); |
| 189 if (summary.request.has_validators) { | 254 if (summary.request.has_validators) { |
| 190 http_response->AddCustomHeader( | 255 http_response->AddCustomHeader( |
| 191 "ETag", base::StringPrintf("'%zu%s'", summary.version, | 256 "ETag", base::StringPrintf("'%zu%s'", summary.version, |
| 192 request.relative_url.c_str())); | 257 request.relative_url.c_str())); |
| 193 } | 258 } |
| 194 if (summary.request.always_revalidate) | 259 if (summary.request.always_revalidate) |
| 195 http_response->AddCustomHeader("Cache-Control", "no-cache"); | 260 http_response->AddCustomHeader("Cache-Control", "no-cache"); |
| 196 else | 261 else |
| 197 http_response->AddCustomHeader("Cache-Control", "max-age=2147483648"); | 262 http_response->AddCustomHeader("Cache-Control", "max-age=2147483648"); |
| 198 return std::move(http_response); | 263 return std::move(http_response); |
| 199 } | 264 } |
| 200 | 265 |
| 201 size_t UpdateAndGetVisitCount(const std::string& main_frame_relative) { | 266 std::unique_ptr<net::test_server::HttpResponse> HandleRedirectRequest( |
| 202 return ++visit_count_[main_frame_relative]; | 267 const net::test_server::EmbeddedTestServer* server, |
| 268 const net::test_server::HttpRequest& request) const { | |
| 269 auto redirect_it = redirects_.find(server->GetURL(request.relative_url)); | |
| 270 if (redirect_it == redirects_.end()) | |
| 271 return nullptr; | |
| 272 | |
| 273 auto http_response = | |
| 274 base::MakeUnique<net::test_server::BasicHttpResponse>(); | |
| 275 http_response->set_code(redirect_it->second.code); | |
| 276 http_response->AddCustomHeader("Location", redirect_it->second.url.spec()); | |
| 277 return std::move(http_response); | |
| 278 } | |
| 279 | |
| 280 size_t UpdateAndGetVisitCount(const GURL& main_frame_url) { | |
| 281 return ++visit_count_[main_frame_url]; | |
| 203 } | 282 } |
| 204 | 283 |
| 205 ResourcePrefetchPredictor* predictor_; | 284 ResourcePrefetchPredictor* predictor_; |
| 206 std::map<std::string, ResourceSummary> resources_; | 285 std::unique_ptr<net::EmbeddedTestServer> https_server_; |
| 207 std::map<std::string, size_t> visit_count_; | 286 std::map<GURL, ResourceSummary> resources_; |
| 287 std::map<GURL, RedirectEdge> redirects_; | |
| 288 std::map<GURL, size_t> visit_count_; | |
| 208 }; | 289 }; |
| 209 | 290 |
| 210 IN_PROC_BROWSER_TEST_F(ResourcePrefetchPredictorBrowserTest, LearningSimple) { | 291 IN_PROC_BROWSER_TEST_F(ResourcePrefetchPredictorBrowserTest, LearningSimple) { |
| 211 // These resources have default priorities that correspond to | 292 // These resources have default priorities that correspond to |
| 212 // blink::typeToPriority function. | 293 // blink::typeToPriority function. |
| 213 AddResource(kImageUrl, content::RESOURCE_TYPE_IMAGE, net::LOWEST); | 294 AddResource(GetURL(kImagePath), content::RESOURCE_TYPE_IMAGE, net::LOWEST); |
| 214 AddResource(kStyleUrl, content::RESOURCE_TYPE_STYLESHEET, net::HIGHEST); | 295 AddResource(GetURL(kStylePath), content::RESOURCE_TYPE_STYLESHEET, |
| 215 AddResource(kScriptUrl, content::RESOURCE_TYPE_SCRIPT, net::MEDIUM); | 296 net::HIGHEST); |
| 216 AddResource(kFontUrl, content::RESOURCE_TYPE_FONT_RESOURCE, net::HIGHEST); | 297 AddResource(GetURL(kScriptPath), content::RESOURCE_TYPE_SCRIPT, net::MEDIUM); |
| 217 NavigateToURLAndCheckSubresources(kHtmlSubresourcesUrl); | 298 AddResource(GetURL(kFontPath), content::RESOURCE_TYPE_FONT_RESOURCE, |
| 299 net::HIGHEST); | |
| 300 NavigateToURLAndCheckSubresources(GetURL(kHtmlSubresourcesPath)); | |
| 301 } | |
| 302 | |
| 303 IN_PROC_BROWSER_TEST_F(ResourcePrefetchPredictorBrowserTest, | |
| 304 LearningAfterRedirect) { | |
| 305 AddRedirectChain(GetURL(kRedirectPath), {{net::HTTP_MOVED_PERMANENTLY, | |
| 306 GetURL(kHtmlSubresourcesPath)}}); | |
| 307 AddResource(GetURL(kImagePath), content::RESOURCE_TYPE_IMAGE, net::LOWEST); | |
| 308 AddResource(GetURL(kStylePath), content::RESOURCE_TYPE_STYLESHEET, | |
| 309 net::HIGHEST); | |
| 310 AddResource(GetURL(kScriptPath), content::RESOURCE_TYPE_SCRIPT, net::MEDIUM); | |
| 311 AddResource(GetURL(kFontPath), content::RESOURCE_TYPE_FONT_RESOURCE, | |
| 312 net::HIGHEST); | |
| 313 NavigateToURLAndCheckSubresources(GetURL(kRedirectPath)); | |
| 314 } | |
| 315 | |
| 316 IN_PROC_BROWSER_TEST_F(ResourcePrefetchPredictorBrowserTest, | |
| 317 LearningAfterRedirectChain) { | |
| 318 AddRedirectChain(GetURL(kRedirectPath), | |
| 319 {{net::HTTP_FOUND, GetURL(kRedirectPath2)}, | |
| 320 {net::HTTP_MOVED_PERMANENTLY, GetURL(kRedirectPath3)}, | |
| 321 {net::HTTP_FOUND, GetURL(kHtmlSubresourcesPath)}}); | |
| 322 AddResource(GetURL(kImagePath), content::RESOURCE_TYPE_IMAGE, net::LOWEST); | |
| 323 AddResource(GetURL(kStylePath), content::RESOURCE_TYPE_STYLESHEET, | |
| 324 net::HIGHEST); | |
| 325 AddResource(GetURL(kScriptPath), content::RESOURCE_TYPE_SCRIPT, net::MEDIUM); | |
| 326 AddResource(GetURL(kFontPath), content::RESOURCE_TYPE_FONT_RESOURCE, | |
| 327 net::HIGHEST); | |
| 328 NavigateToURLAndCheckSubresources(GetURL(kRedirectPath)); | |
| 329 } | |
| 330 | |
| 331 IN_PROC_BROWSER_TEST_F(ResourcePrefetchPredictorBrowserTest, | |
| 332 LearningAfterHttpToHttpsRedirect) { | |
| 333 EnableHttpsServer(); | |
| 334 AddRedirectChain(GetURL(kRedirectPath), | |
| 335 {{net::HTTP_FOUND, https_server()->GetURL(kRedirectPath2)}, | |
| 336 {net::HTTP_MOVED_PERMANENTLY, | |
| 337 https_server()->GetURL(kHtmlSubresourcesPath)}}); | |
| 338 AddResource(https_server()->GetURL(kImagePath), content::RESOURCE_TYPE_IMAGE, | |
| 339 net::LOWEST); | |
| 340 AddResource(https_server()->GetURL(kStylePath), | |
| 341 content::RESOURCE_TYPE_STYLESHEET, net::HIGHEST); | |
| 342 AddResource(https_server()->GetURL(kScriptPath), | |
| 343 content::RESOURCE_TYPE_SCRIPT, net::MEDIUM); | |
| 344 AddResource(https_server()->GetURL(kFontPath), | |
| 345 content::RESOURCE_TYPE_FONT_RESOURCE, net::HIGHEST); | |
| 346 NavigateToURLAndCheckSubresources(GetURL(kRedirectPath)); | |
| 218 } | 347 } |
| 219 | 348 |
| 220 } // namespace predictors | 349 } // namespace predictors |
| OLD | NEW |