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; | |
| 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 ResourceSummary resource; |
| 136 resource.request.resource_url = | 145 resource.request.resource_url = resource_url; |
| 137 embedded_test_server()->GetURL(relative_url); | |
| 138 resource.request.resource_type = resource_type; | 146 resource.request.resource_type = resource_type; |
| 139 resource.request.priority = priority; | 147 resource.request.priority = priority; |
| 140 auto result = resources_.insert(std::make_pair(relative_url, resource)); | 148 resource.request.has_validators = true; |
| 149 auto result = resources_.insert(std::make_pair(resource_url, resource)); | |
| 141 return &(result.first->second); | 150 return &(result.first->second); |
| 142 } | 151 } |
| 143 | 152 |
| 153 void AddRedirectChain(const GURL& initial_url, | |
| 154 const std::vector<RedirectEdge>& redirect_chain) { | |
| 155 ASSERT_FALSE(redirect_chain.empty()); | |
| 156 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.
| |
| 157 for (const auto& edge : redirect_chain) { | |
| 158 auto result = redirects_.insert(std::make_pair(*current, edge)); | |
| 159 ASSERT_TRUE(result.second) << *current << " already has a redirect."; | |
| 160 current = &(edge.url); | |
| 161 } | |
| 162 } | |
| 163 | |
| 164 // Simply shortcut for convenience. | |
|
Benoit L
2016/11/22 10:58:28
nit: s/Simply//
alexilin
2016/11/22 11:04:29
Done.
| |
| 165 GURL GetURL(const std::string& path) const { | |
| 166 return embedded_test_server()->GetURL(path); | |
| 167 } | |
| 168 | |
| 169 void EnableHttpsServer() { | |
| 170 ASSERT_FALSE(https_server_); | |
| 171 https_server_ = base::MakeUnique<net::EmbeddedTestServer>( | |
| 172 net::EmbeddedTestServer::TYPE_HTTPS); | |
| 173 https_server()->AddDefaultHandlers( | |
| 174 base::FilePath(FILE_PATH_LITERAL("chrome/test/data"))); | |
| 175 https_server()->RegisterRequestHandler( | |
| 176 base::Bind(&ResourcePrefetchPredictorBrowserTest::HandleRedirectRequest, | |
| 177 base::Unretained(this), base::Unretained(https_server()))); | |
| 178 https_server()->RegisterRequestHandler( | |
| 179 base::Bind(&ResourcePrefetchPredictorBrowserTest::HandleResourceRequest, | |
| 180 base::Unretained(this), base::Unretained(https_server()))); | |
| 181 ASSERT_TRUE(https_server()->Start()); | |
| 182 } | |
| 183 | |
| 184 protected: | |
| 185 // Returns the embedded test server working over HTTPS. Must be enabled by | |
| 186 // calling EnableHttpsServer() before use. | |
| 187 const net::EmbeddedTestServer* https_server() const { | |
| 188 return https_server_.get(); | |
| 189 } | |
| 190 | |
| 191 net::EmbeddedTestServer* https_server() { return https_server_.get(); } | |
| 192 | |
| 144 private: | 193 private: |
| 145 // ResourcePrefetchPredictor needs to be initialized before the navigation | 194 // ResourcePrefetchPredictor needs to be initialized before the navigation |
| 146 // happens otherwise this navigation will be ignored by predictor. | 195 // happens otherwise this navigation will be ignored by predictor. |
| 147 void EnsurePredictorInitialized() { | 196 void EnsurePredictorInitialized() { |
| 148 if (predictor_->initialization_state_ == | 197 if (predictor_->initialization_state_ == |
| 149 ResourcePrefetchPredictor::INITIALIZED) { | 198 ResourcePrefetchPredictor::INITIALIZED) { |
| 150 return; | 199 return; |
| 151 } | 200 } |
| 152 | 201 |
| 153 InitializationObserver observer(predictor_); | 202 InitializationObserver observer(predictor_); |
| 154 if (predictor_->initialization_state_ == | 203 if (predictor_->initialization_state_ == |
| 155 ResourcePrefetchPredictor::NOT_INITIALIZED) { | 204 ResourcePrefetchPredictor::NOT_INITIALIZED) { |
| 156 predictor_->StartInitialization(); | 205 predictor_->StartInitialization(); |
| 157 } | 206 } |
| 158 observer.Wait(); | 207 observer.Wait(); |
| 159 } | 208 } |
| 160 | 209 |
| 161 URLRequestSummary GetURLRequestSummaryForResource( | 210 URLRequestSummary GetURLRequestSummaryForResource( |
| 162 const GURL& main_frame_url, | 211 const GURL& main_frame_url, |
| 163 const ResourceSummary& resource_summary) { | 212 const ResourceSummary& resource_summary) const { |
| 164 URLRequestSummary summary(resource_summary.request); | 213 URLRequestSummary summary(resource_summary.request); |
| 165 content::WebContents* web_contents = | 214 content::WebContents* web_contents = |
| 166 browser()->tab_strip_model()->GetActiveWebContents(); | 215 browser()->tab_strip_model()->GetActiveWebContents(); |
| 167 int process_id = web_contents->GetRenderProcessHost()->GetID(); | 216 int process_id = web_contents->GetRenderProcessHost()->GetID(); |
| 168 int frame_id = web_contents->GetMainFrame()->GetRoutingID(); | 217 int frame_id = web_contents->GetMainFrame()->GetRoutingID(); |
| 169 summary.navigation_id = | 218 summary.navigation_id = |
| 170 CreateNavigationID(process_id, frame_id, main_frame_url.spec()); | 219 CreateNavigationID(process_id, frame_id, main_frame_url.spec()); |
| 171 return summary; | 220 return summary; |
| 172 } | 221 } |
| 173 | 222 |
| 174 std::unique_ptr<net::test_server::HttpResponse> HandleRequest( | 223 GURL GetRedirectEndpoint(const GURL& initial_url) const { |
| 175 const net::test_server::HttpRequest& request) { | 224 const GURL* current = &initial_url; |
| 176 auto resource_it = resources_.find(request.relative_url); | 225 for (auto it = redirects_.find(*current); it != redirects_.end(); |
| 226 it = redirects_.find(*current)) { | |
| 227 current = &(it->second.url); | |
| 228 } | |
| 229 return *current; | |
| 230 } | |
| 231 | |
| 232 std::unique_ptr<net::test_server::HttpResponse> HandleResourceRequest( | |
| 233 const net::test_server::EmbeddedTestServer* server, | |
| 234 const net::test_server::HttpRequest& request) const { | |
| 235 auto resource_it = resources_.find(server->GetURL(request.relative_url)); | |
| 177 if (resource_it == resources_.end()) | 236 if (resource_it == resources_.end()) |
| 178 return nullptr; | 237 return nullptr; |
| 179 | 238 |
| 180 const ResourceSummary& summary = resource_it->second; | 239 const ResourceSummary& summary = resource_it->second; |
| 181 auto http_response = | 240 auto http_response = |
| 182 base::MakeUnique<net::test_server::BasicHttpResponse>(); | 241 base::MakeUnique<net::test_server::BasicHttpResponse>(); |
| 183 http_response->set_code(net::HTTP_OK); | 242 http_response->set_code(net::HTTP_OK); |
| 184 if (!summary.request.mime_type.empty()) | 243 if (!summary.request.mime_type.empty()) |
| 185 http_response->set_content_type(summary.request.mime_type); | 244 http_response->set_content_type(summary.request.mime_type); |
| 186 http_response->set_content(summary.content); | 245 if (!summary.content.empty()) |
| 246 http_response->set_content(summary.content); | |
| 187 if (summary.is_no_store) | 247 if (summary.is_no_store) |
| 188 http_response->AddCustomHeader("Cache-Control", "no-store"); | 248 http_response->AddCustomHeader("Cache-Control", "no-store"); |
| 189 if (summary.request.has_validators) { | 249 if (summary.request.has_validators) { |
| 190 http_response->AddCustomHeader( | 250 http_response->AddCustomHeader( |
| 191 "ETag", base::StringPrintf("'%zu%s'", summary.version, | 251 "ETag", base::StringPrintf("'%zu%s'", summary.version, |
| 192 request.relative_url.c_str())); | 252 request.relative_url.c_str())); |
| 193 } | 253 } |
| 194 if (summary.request.always_revalidate) | 254 if (summary.request.always_revalidate) |
| 195 http_response->AddCustomHeader("Cache-Control", "no-cache"); | 255 http_response->AddCustomHeader("Cache-Control", "no-cache"); |
| 196 else | 256 else |
| 197 http_response->AddCustomHeader("Cache-Control", "max-age=2147483648"); | 257 http_response->AddCustomHeader("Cache-Control", "max-age=2147483648"); |
| 198 return std::move(http_response); | 258 return std::move(http_response); |
| 199 } | 259 } |
| 200 | 260 |
| 201 size_t UpdateAndGetVisitCount(const std::string& main_frame_relative) { | 261 std::unique_ptr<net::test_server::HttpResponse> HandleRedirectRequest( |
| 202 return ++visit_count_[main_frame_relative]; | 262 const net::test_server::EmbeddedTestServer* server, |
| 263 const net::test_server::HttpRequest& request) const { | |
| 264 auto redirect_it = redirects_.find(server->GetURL(request.relative_url)); | |
| 265 if (redirect_it == redirects_.end()) | |
| 266 return nullptr; | |
| 267 | |
| 268 auto http_response = | |
| 269 base::MakeUnique<net::test_server::BasicHttpResponse>(); | |
| 270 http_response->set_code(redirect_it->second.code); | |
| 271 http_response->AddCustomHeader("Location", redirect_it->second.url.spec()); | |
| 272 return std::move(http_response); | |
| 273 } | |
| 274 | |
| 275 size_t UpdateAndGetVisitCount(const GURL& main_frame_url) { | |
| 276 return ++visit_count_[main_frame_url]; | |
| 203 } | 277 } |
| 204 | 278 |
| 205 ResourcePrefetchPredictor* predictor_; | 279 ResourcePrefetchPredictor* predictor_; |
| 206 std::map<std::string, ResourceSummary> resources_; | 280 std::unique_ptr<net::EmbeddedTestServer> https_server_; |
| 207 std::map<std::string, size_t> visit_count_; | 281 std::map<GURL, ResourceSummary> resources_; |
| 282 std::map<GURL, RedirectEdge> redirects_; | |
| 283 std::map<GURL, size_t> visit_count_; | |
| 208 }; | 284 }; |
| 209 | 285 |
| 210 IN_PROC_BROWSER_TEST_F(ResourcePrefetchPredictorBrowserTest, LearningSimple) { | 286 IN_PROC_BROWSER_TEST_F(ResourcePrefetchPredictorBrowserTest, LearningSimple) { |
| 211 // These resources have default priorities that correspond to | 287 // These resources have default priorities that correspond to |
| 212 // blink::typeToPriority function. | 288 // blink::typeToPriority function. |
| 213 AddResource(kImageUrl, content::RESOURCE_TYPE_IMAGE, net::LOWEST); | 289 AddResource(GetURL(kImagePath), content::RESOURCE_TYPE_IMAGE, net::LOWEST); |
| 214 AddResource(kStyleUrl, content::RESOURCE_TYPE_STYLESHEET, net::HIGHEST); | 290 AddResource(GetURL(kStylePath), content::RESOURCE_TYPE_STYLESHEET, |
| 215 AddResource(kScriptUrl, content::RESOURCE_TYPE_SCRIPT, net::MEDIUM); | 291 net::HIGHEST); |
| 216 AddResource(kFontUrl, content::RESOURCE_TYPE_FONT_RESOURCE, net::HIGHEST); | 292 AddResource(GetURL(kScriptPath), content::RESOURCE_TYPE_SCRIPT, net::MEDIUM); |
| 217 NavigateToURLAndCheckSubresources(kHtmlSubresourcesUrl); | 293 AddResource(GetURL(kFontPath), content::RESOURCE_TYPE_FONT_RESOURCE, |
| 294 net::HIGHEST); | |
| 295 NavigateToURLAndCheckSubresources(GetURL(kHtmlSubresourcesPath)); | |
| 296 } | |
| 297 | |
| 298 IN_PROC_BROWSER_TEST_F(ResourcePrefetchPredictorBrowserTest, | |
| 299 LearningAfterRedirect) { | |
| 300 AddRedirectChain(GetURL(kRedirectPath), {{net::HTTP_MOVED_PERMANENTLY, | |
| 301 GetURL(kHtmlSubresourcesPath)}}); | |
| 302 AddResource(GetURL(kImagePath), content::RESOURCE_TYPE_IMAGE, net::LOWEST); | |
| 303 AddResource(GetURL(kStylePath), content::RESOURCE_TYPE_STYLESHEET, | |
| 304 net::HIGHEST); | |
| 305 AddResource(GetURL(kScriptPath), content::RESOURCE_TYPE_SCRIPT, net::MEDIUM); | |
| 306 AddResource(GetURL(kFontPath), content::RESOURCE_TYPE_FONT_RESOURCE, | |
| 307 net::HIGHEST); | |
| 308 NavigateToURLAndCheckSubresources(GetURL(kRedirectPath)); | |
| 309 } | |
| 310 | |
| 311 IN_PROC_BROWSER_TEST_F(ResourcePrefetchPredictorBrowserTest, | |
| 312 LearningAfterRedirectChain) { | |
| 313 AddRedirectChain(GetURL(kRedirectPath), | |
| 314 {{net::HTTP_FOUND, GetURL(kRedirectPath2)}, | |
| 315 {net::HTTP_MOVED_PERMANENTLY, GetURL(kRedirectPath3)}, | |
| 316 {net::HTTP_FOUND, GetURL(kHtmlSubresourcesPath)}}); | |
| 317 AddResource(GetURL(kImagePath), content::RESOURCE_TYPE_IMAGE, net::LOWEST); | |
| 318 AddResource(GetURL(kStylePath), content::RESOURCE_TYPE_STYLESHEET, | |
| 319 net::HIGHEST); | |
| 320 AddResource(GetURL(kScriptPath), content::RESOURCE_TYPE_SCRIPT, net::MEDIUM); | |
| 321 AddResource(GetURL(kFontPath), content::RESOURCE_TYPE_FONT_RESOURCE, | |
| 322 net::HIGHEST); | |
| 323 NavigateToURLAndCheckSubresources(GetURL(kRedirectPath)); | |
| 324 } | |
| 325 | |
| 326 IN_PROC_BROWSER_TEST_F(ResourcePrefetchPredictorBrowserTest, | |
| 327 LearningAfterHttpToHttpsRedirect) { | |
| 328 EnableHttpsServer(); | |
| 329 AddRedirectChain(GetURL(kRedirectPath), | |
| 330 {{net::HTTP_FOUND, https_server()->GetURL(kRedirectPath2)}, | |
| 331 {net::HTTP_MOVED_PERMANENTLY, | |
| 332 https_server()->GetURL(kHtmlSubresourcesPath)}}); | |
| 333 AddResource(https_server()->GetURL(kImagePath), content::RESOURCE_TYPE_IMAGE, | |
| 334 net::LOWEST); | |
| 335 AddResource(https_server()->GetURL(kStylePath), | |
| 336 content::RESOURCE_TYPE_STYLESHEET, net::HIGHEST); | |
| 337 AddResource(https_server()->GetURL(kScriptPath), | |
| 338 content::RESOURCE_TYPE_SCRIPT, net::MEDIUM); | |
| 339 AddResource(https_server()->GetURL(kFontPath), | |
| 340 content::RESOURCE_TYPE_FONT_RESOURCE, net::HIGHEST); | |
| 341 NavigateToURLAndCheckSubresources(GetURL(kRedirectPath)); | |
| 218 } | 342 } |
| 219 | 343 |
| 220 } // namespace predictors | 344 } // namespace predictors |
| OLD | NEW |