Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(79)

Side by Side Diff: chrome/browser/predictors/resource_prefetch_predictor_browsertest.cc

Issue 2755093002: predictors: Mark before_first_contentful_paint for resources fetched before fcp. (Closed)
Patch Set: Bump kDatabaseVersion Created 3 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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 <algorithm> 7 #include <algorithm>
8 #include <set> 8 #include <set>
9 9
10 #include "base/command_line.h" 10 #include "base/command_line.h"
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
65 const char kScriptDocumentWritePath[] = "/predictors/document_write.js"; 65 const char kScriptDocumentWritePath[] = "/predictors/document_write.js";
66 const char kHtmlAppendChildPath[] = "/predictors/append_child.html"; 66 const char kHtmlAppendChildPath[] = "/predictors/append_child.html";
67 const char kScriptAppendChildPath[] = "/predictors/append_child.js"; 67 const char kScriptAppendChildPath[] = "/predictors/append_child.js";
68 const char kHtmlInnerHtmlPath[] = "/predictors/inner_html.html"; 68 const char kHtmlInnerHtmlPath[] = "/predictors/inner_html.html";
69 const char kScriptInnerHtmlPath[] = "/predictors/inner_html.js"; 69 const char kScriptInnerHtmlPath[] = "/predictors/inner_html.js";
70 const char kHtmlXHRPath[] = "/predictors/xhr.html"; 70 const char kHtmlXHRPath[] = "/predictors/xhr.html";
71 const char kScriptXHRPath[] = "/predictors/xhr.js"; 71 const char kScriptXHRPath[] = "/predictors/xhr.js";
72 const char kHtmlIframePath[] = "/predictors/html_iframe.html"; 72 const char kHtmlIframePath[] = "/predictors/html_iframe.html";
73 const char kHtmlJavascriptRedirectPath[] = 73 const char kHtmlJavascriptRedirectPath[] =
74 "/predictors/javascript_redirect.html"; 74 "/predictors/javascript_redirect.html";
75 const char kHtmlFcpOrderPath[] = "/predictors/subresource_fcp_order.html";
75 76
76 // Host, path. 77 // Host, path.
77 const char* kScript[2] = {kFooHost, kScriptPath}; 78 const char* kScript[2] = {kFooHost, kScriptPath};
78 const char* kImage[2] = {kBarHost, kImagePath}; 79 const char* kImage[2] = {kBarHost, kImagePath};
79 const char* kFont[2] = {kFooHost, kFontPath}; 80 const char* kFont[2] = {kFooHost, kFontPath};
80 const char* kStyle[2] = {kBazHost, kStylePath}; 81 const char* kStyle[2] = {kBazHost, kStylePath};
81 82
82 struct ResourceSummary { 83 struct ResourceSummary {
83 ResourceSummary() 84 ResourceSummary()
84 : version(0), 85 : version(0),
85 is_no_store(false), 86 is_no_store(false),
86 is_external(false), 87 is_external(false),
87 is_observable(true), 88 is_observable(true),
88 is_prohibited(false) {} 89 is_prohibited(false) {
90 request.before_first_contentful_paint = true;
91 }
89 92
90 ResourcePrefetchPredictor::URLRequestSummary request; 93 ResourcePrefetchPredictor::URLRequestSummary request;
91 // Allows to update HTTP ETag. 94 // Allows to update HTTP ETag.
92 size_t version; 95 size_t version;
93 // True iff "Cache-control: no-store" header is present. 96 // True iff "Cache-control: no-store" header is present.
94 bool is_no_store; 97 bool is_no_store;
95 // True iff a request for this resource must be ignored by the custom handler. 98 // True iff a request for this resource must be ignored by the custom handler.
96 bool is_external; 99 bool is_external;
97 // True iff the LearningObserver must observe this resource. 100 // True iff the LearningObserver must observe this resource.
98 bool is_observable; 101 bool is_observable;
99 // A request with |is_prohibited| set to true makes the test that originates 102 // A request with |is_prohibited| set to true makes the test that originates
100 // the request fail. 103 // the request fail.
101 bool is_prohibited; 104 bool is_prohibited;
105 // If set, the HTTP request handler will sleep for this long before
106 // responding.
107 base::TimeDelta delay;
102 }; 108 };
103 109
104 struct RedirectEdge { 110 struct RedirectEdge {
105 // This response code should be returned by previous url in the chain. 111 // This response code should be returned by previous url in the chain.
106 net::HttpStatusCode code; 112 net::HttpStatusCode code;
107 GURL url; 113 GURL url;
108 bool is_client_side; 114 bool is_client_side;
109 }; 115 };
110 116
111 // Helper class to track and allow waiting for ResourcePrefetchPredictor 117 // Helper class to track and allow waiting for ResourcePrefetchPredictor
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
163 } 169 }
164 170
165 // Fill a NavigationID with "empty" data that does not trigger 171 // Fill a NavigationID with "empty" data that does not trigger
166 // the is_valid DCHECK(). Allows comparing. 172 // the is_valid DCHECK(). Allows comparing.
167 void SetValidNavigationID(NavigationID* navigation_id) { 173 void SetValidNavigationID(NavigationID* navigation_id) {
168 navigation_id->tab_id = 0; 174 navigation_id->tab_id = 0;
169 navigation_id->main_frame_url = GURL("http://127.0.0.1"); 175 navigation_id->main_frame_url = GURL("http://127.0.0.1");
170 } 176 }
171 177
172 void ModifySubresourceForComparison(URLRequestSummary* subresource, 178 void ModifySubresourceForComparison(URLRequestSummary* subresource,
173 bool match_navigation_id) { 179 bool match_navigation_id,
180 bool match_before_first_contentful_paint) {
174 if (!match_navigation_id) 181 if (!match_navigation_id)
175 SetValidNavigationID(&subresource->navigation_id); 182 SetValidNavigationID(&subresource->navigation_id);
183 if (!match_before_first_contentful_paint)
184 subresource->before_first_contentful_paint = true;
176 if (subresource->resource_type == content::RESOURCE_TYPE_IMAGE && 185 if (subresource->resource_type == content::RESOURCE_TYPE_IMAGE &&
177 subresource->priority == net::LOWEST) { 186 subresource->priority == net::LOWEST) {
178 // Fuzzy comparison for images because an image priority can be 187 // Fuzzy comparison for images because an image priority can be
179 // boosted during layout via 188 // boosted during layout via
180 // ResourceFetcher::updateAllImageResourcePriorities(). 189 // ResourceFetcher::updateAllImageResourcePriorities().
181 subresource->priority = net::MEDIUM; 190 subresource->priority = net::MEDIUM;
182 } 191 }
183 } 192 }
184 193
185 // Does a custom comparison of subresources of URLRequestSummary 194 // Does a custom comparison of subresources of URLRequestSummary
186 // and fail the test if the expectation is not met. 195 // and fail the test if the expectation is not met.
187 void CompareSubresources(std::vector<URLRequestSummary> actual_subresources, 196 void CompareSubresources(std::vector<URLRequestSummary> actual_subresources,
188 std::vector<URLRequestSummary> expected_subresources, 197 std::vector<URLRequestSummary> expected_subresources,
189 bool match_navigation_id) { 198 bool match_navigation_id,
199 bool match_before_first_contentful_paint) {
190 // Duplicate resources can be observed in a single navigation but 200 // Duplicate resources can be observed in a single navigation but
191 // ResourcePrefetchPredictor only cares about the first occurrence of each. 201 // ResourcePrefetchPredictor only cares about the first occurrence of each.
192 RemoveDuplicateSubresources(&actual_subresources); 202 RemoveDuplicateSubresources(&actual_subresources);
193 203
194 for (auto& subresource : actual_subresources) 204 for (auto& subresource : actual_subresources)
195 ModifySubresourceForComparison(&subresource, match_navigation_id); 205 ModifySubresourceForComparison(&subresource, match_navigation_id,
206 match_before_first_contentful_paint);
196 for (auto& subresource : expected_subresources) 207 for (auto& subresource : expected_subresources)
197 ModifySubresourceForComparison(&subresource, match_navigation_id); 208 ModifySubresourceForComparison(&subresource, match_navigation_id,
209 match_before_first_contentful_paint);
198 210
199 EXPECT_THAT(actual_subresources, 211 EXPECT_THAT(actual_subresources,
200 testing::UnorderedElementsAreArray(expected_subresources)); 212 testing::UnorderedElementsAreArray(expected_subresources));
201 } 213 }
202 214
203 std::string CreateVersionedETag(size_t version, const std::string& path) { 215 std::string CreateVersionedETag(size_t version, const std::string& path) {
204 return base::StringPrintf("'%zu%s'", version, path.c_str()); 216 return base::StringPrintf("'%zu%s'", version, path.c_str());
205 } 217 }
206 218
207 GURL GetRequestURL(const net::test_server::HttpRequest& request) { 219 GURL GetRequestURL(const net::test_server::HttpRequest& request) {
(...skipping 19 matching lines...) Expand all
227 // Helper class to track and allow waiting for a single OnNavigationLearned 239 // Helper class to track and allow waiting for a single OnNavigationLearned
228 // event. The information provided by this event is also used to verify that 240 // event. The information provided by this event is also used to verify that
229 // ResourcePrefetchPredictor works as expected. 241 // ResourcePrefetchPredictor works as expected.
230 class LearningObserver : public TestObserver { 242 class LearningObserver : public TestObserver {
231 public: 243 public:
232 using PageRequestSummary = ResourcePrefetchPredictor::PageRequestSummary; 244 using PageRequestSummary = ResourcePrefetchPredictor::PageRequestSummary;
233 245
234 LearningObserver(ResourcePrefetchPredictor* predictor, 246 LearningObserver(ResourcePrefetchPredictor* predictor,
235 const size_t expected_url_visit_count, 247 const size_t expected_url_visit_count,
236 const PageRequestSummary& expected_summary, 248 const PageRequestSummary& expected_summary,
237 bool match_navigation_id) 249 bool match_navigation_id,
250 bool match_before_first_contentful_paint)
238 : TestObserver(predictor), 251 : TestObserver(predictor),
239 url_visit_count_(expected_url_visit_count), 252 url_visit_count_(expected_url_visit_count),
240 summary_(expected_summary), 253 summary_(expected_summary),
241 match_navigation_id_(match_navigation_id) {} 254 match_navigation_id_(match_navigation_id),
255 match_before_first_contentful_paint_(
256 match_before_first_contentful_paint) {}
242 257
243 // TestObserver: 258 // TestObserver:
244 void OnNavigationLearned(size_t url_visit_count, 259 void OnNavigationLearned(size_t url_visit_count,
245 const PageRequestSummary& summary) override { 260 const PageRequestSummary& summary) override {
246 EXPECT_EQ(url_visit_count, url_visit_count_); 261 EXPECT_EQ(url_visit_count, url_visit_count_);
247 EXPECT_EQ(summary.main_frame_url, summary_.main_frame_url); 262 EXPECT_EQ(summary.main_frame_url, summary_.main_frame_url);
248 EXPECT_EQ(summary.initial_url, summary_.initial_url); 263 EXPECT_EQ(summary.initial_url, summary_.initial_url);
249 for (const auto& resource : summary.subresource_requests) 264 for (const auto& resource : summary.subresource_requests)
250 current_navigation_ids_.insert(resource.navigation_id); 265 current_navigation_ids_.insert(resource.navigation_id);
251 CompareSubresources(summary.subresource_requests, 266 CompareSubresources(summary.subresource_requests,
252 summary_.subresource_requests, match_navigation_id_); 267 summary_.subresource_requests, match_navigation_id_,
268 match_before_first_contentful_paint_);
253 run_loop_.Quit(); 269 run_loop_.Quit();
254 } 270 }
255 271
256 void Wait() { run_loop_.Run(); } 272 void Wait() { run_loop_.Run(); }
257 273
258 std::set<NavigationID>& current_navigation_ids() { 274 std::set<NavigationID>& current_navigation_ids() {
259 return current_navigation_ids_; 275 return current_navigation_ids_;
260 } 276 }
261 277
262 private: 278 private:
263 base::RunLoop run_loop_; 279 base::RunLoop run_loop_;
264 size_t url_visit_count_; 280 size_t url_visit_count_;
265 PageRequestSummary summary_; 281 PageRequestSummary summary_;
266 bool match_navigation_id_; 282 bool match_navigation_id_;
283 bool match_before_first_contentful_paint_;
267 std::set<NavigationID> current_navigation_ids_; 284 std::set<NavigationID> current_navigation_ids_;
268 285
269 DISALLOW_COPY_AND_ASSIGN(LearningObserver); 286 DISALLOW_COPY_AND_ASSIGN(LearningObserver);
270 }; 287 };
271 288
272 // Helper class to track and allow waiting for a single OnPrefetchingFinished 289 // Helper class to track and allow waiting for a single OnPrefetchingFinished
273 // event. Checks also that {Start,Stop}Prefetching are called with the right 290 // event. Checks also that {Start,Stop}Prefetching are called with the right
274 // argument. 291 // argument.
275 class PrefetchingObserver : public TestObserver { 292 class PrefetchingObserver : public TestObserver {
276 public: 293 public:
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after
354 // URLs from the test server contain a port number. 371 // URLs from the test server contain a port number.
355 ResourcePrefetchPredictor::SetAllowPortInUrlsForTesting(true); 372 ResourcePrefetchPredictor::SetAllowPortInUrlsForTesting(true);
356 EnsurePredictorInitialized(); 373 EnsurePredictorInitialized();
357 histogram_tester_.reset(new base::HistogramTester()); 374 histogram_tester_.reset(new base::HistogramTester());
358 } 375 }
359 376
360 void TearDownOnMainThread() override { 377 void TearDownOnMainThread() override {
361 ResourcePrefetchPredictor::SetAllowPortInUrlsForTesting(false); 378 ResourcePrefetchPredictor::SetAllowPortInUrlsForTesting(false);
362 } 379 }
363 380
364 void TestLearningAndPrefetching(const GURL& main_frame_url) { 381 void TestLearningAndPrefetching(
382 const GURL& main_frame_url,
383 bool match_before_first_contentful_paint = false) {
365 // Navigate to |main_frame_url| and check all the expectations. 384 // Navigate to |main_frame_url| and check all the expectations.
366 NavigateToURLAndCheckSubresources(main_frame_url); 385 NavigateToURLAndCheckSubresources(main_frame_url,
386 WindowOpenDisposition::CURRENT_TAB,
387 match_before_first_contentful_paint);
367 ClearCache(); 388 ClearCache();
368 // It is needed to have at least two resource hits to trigger prefetch. 389 // It is needed to have at least two resource hits to trigger prefetch.
369 NavigateToURLAndCheckSubresources(main_frame_url); 390 NavigateToURLAndCheckSubresources(main_frame_url,
391 WindowOpenDisposition::CURRENT_TAB,
392 match_before_first_contentful_paint);
370 ClearCache(); 393 ClearCache();
371 // Prefetch all needed resources and change expectations so that all 394 // Prefetch all needed resources and change expectations so that all
372 // cacheable resources should be served from cache next navigation. 395 // cacheable resources should be served from cache next navigation.
373 PrefetchURL(main_frame_url); 396 PrefetchURL(main_frame_url);
374 // To be sure that the browser send no requests to the server after 397 // To be sure that the browser send no requests to the server after
375 // prefetching. 398 // prefetching.
376 NavigateToURLAndCheckSubresourcesAllCached(main_frame_url); 399 NavigateToURLAndCheckSubresourcesAllCached(main_frame_url);
377 } 400 }
378 401
379 void NavigateToURLAndCheckSubresourcesAllCached(const GURL& navigation_url) { 402 void NavigateToURLAndCheckSubresourcesAllCached(const GURL& navigation_url) {
380 for (auto& kv : resources_) { 403 for (auto& kv : resources_) {
381 if (kv.second.is_observable) 404 if (kv.second.is_observable)
382 kv.second.is_prohibited = true; 405 kv.second.is_prohibited = true;
383 } 406 }
384 NavigateToURLAndCheckSubresources(navigation_url); 407 NavigateToURLAndCheckSubresources(navigation_url);
385 for (auto& kv : resources_) { 408 for (auto& kv : resources_) {
386 if (kv.second.is_observable) 409 if (kv.second.is_observable)
387 kv.second.is_prohibited = false; 410 kv.second.is_prohibited = false;
388 } 411 }
389 } 412 }
390 413
391 void NavigateToURLAndCheckSubresources( 414 void NavigateToURLAndCheckSubresources(
392 const GURL& navigation_url, 415 const GURL& navigation_url,
393 WindowOpenDisposition disposition = WindowOpenDisposition::CURRENT_TAB) { 416 WindowOpenDisposition disposition = WindowOpenDisposition::CURRENT_TAB,
417 bool match_before_first_contentful_paint = false) {
394 GURL initial_url = GetLastClientSideRedirectEndpoint(navigation_url); 418 GURL initial_url = GetLastClientSideRedirectEndpoint(navigation_url);
395 GURL main_frame_url = GetRedirectEndpoint(navigation_url); 419 GURL main_frame_url = GetRedirectEndpoint(navigation_url);
396 std::vector<URLRequestSummary> url_request_summaries; 420 std::vector<URLRequestSummary> url_request_summaries;
397 for (const auto& kv : resources_) { 421 for (const auto& kv : resources_) {
398 if (kv.second.is_observable) { 422 if (kv.second.is_observable) {
399 url_request_summaries.push_back( 423 url_request_summaries.push_back(
400 GetURLRequestSummaryForResource(main_frame_url, kv.second)); 424 GetURLRequestSummaryForResource(main_frame_url, kv.second));
401 } 425 }
402 } 426 }
403 427
404 bool match_navigation_id = 428 bool match_navigation_id =
405 disposition == WindowOpenDisposition::CURRENT_TAB; 429 disposition == WindowOpenDisposition::CURRENT_TAB;
406 430
407 LearningObserver observer( 431 LearningObserver observer(
408 predictor_, UpdateAndGetVisitCount(initial_url), 432 predictor_, UpdateAndGetVisitCount(initial_url),
409 CreatePageRequestSummary(main_frame_url.spec(), initial_url.spec(), 433 CreatePageRequestSummary(main_frame_url.spec(), initial_url.spec(),
410 url_request_summaries), 434 url_request_summaries),
411 match_navigation_id); 435 match_navigation_id, match_before_first_contentful_paint);
412 ui_test_utils::NavigateToURLWithDisposition( 436 ui_test_utils::NavigateToURLWithDisposition(
413 browser(), navigation_url, disposition, 437 browser(), navigation_url, disposition,
414 ui_test_utils::BROWSER_TEST_NONE); 438 ui_test_utils::BROWSER_TEST_NONE);
415 observer.Wait(); 439 observer.Wait();
416 440
417 for (auto& kv : resources_) { 441 for (auto& kv : resources_) {
418 if (kv.second.is_observable) 442 if (kv.second.is_observable)
419 kv.second.request.was_cached = true; 443 kv.second.request.was_cached = true;
420 } 444 }
421 for (const auto& nav : observer.current_navigation_ids()) 445 for (const auto& nav : observer.current_navigation_ids())
(...skipping 245 matching lines...) Expand 10 before | Expand all | Expand 10 after
667 } 691 }
668 if (summary.request.always_revalidate) 692 if (summary.request.always_revalidate)
669 http_response->AddCustomHeader("Cache-Control", "no-cache"); 693 http_response->AddCustomHeader("Cache-Control", "no-cache");
670 else 694 else
671 http_response->AddCustomHeader("Cache-Control", "max-age=2147483648"); 695 http_response->AddCustomHeader("Cache-Control", "max-age=2147483648");
672 696
673 // Add some content, otherwise the prefetch size histogram rounds down to 697 // Add some content, otherwise the prefetch size histogram rounds down to
674 // 0kB. 698 // 0kB.
675 http_response->set_content(std::string(1024, ' ')); 699 http_response->set_content(std::string(1024, ' '));
676 700
701 if (!summary.delay.is_zero())
702 base::PlatformThread::Sleep(summary.delay);
703
677 return std::move(http_response); 704 return std::move(http_response);
678 } 705 }
679 706
680 // The custom handler for redirect requests from the browser to an 707 // The custom handler for redirect requests from the browser to an
681 // EmbeddedTestServer. Running on the EmbeddedTestServer IO thread. 708 // EmbeddedTestServer. Running on the EmbeddedTestServer IO thread.
682 // Finds the data to serve requests in |redirects_| map keyed by a request 709 // Finds the data to serve requests in |redirects_| map keyed by a request
683 // URL. 710 // URL.
684 std::unique_ptr<net::test_server::HttpResponse> HandleRedirectRequest( 711 std::unique_ptr<net::test_server::HttpResponse> HandleRedirectRequest(
685 const net::test_server::HttpRequest& request) const { 712 const net::test_server::HttpRequest& request) const {
686 std::map<GURL, RedirectEdge>::const_iterator redirect_it = 713 std::map<GURL, RedirectEdge>::const_iterator redirect_it =
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
737 histogram_tester_->ExpectBucketCount( 764 histogram_tester_->ExpectBucketCount(
738 internal::kResourcePrefetchPredictorPrefetchHitsCountNotCached, 4, 1); 765 internal::kResourcePrefetchPredictorPrefetchHitsCountNotCached, 4, 1);
739 766
740 histogram_tester_->ExpectBucketCount( 767 histogram_tester_->ExpectBucketCount(
741 internal::kResourcePrefetchPredictorPrefetchMissesSize, 0, 1); 768 internal::kResourcePrefetchPredictorPrefetchMissesSize, 0, 1);
742 // Each request is ~1k, see HandleResourceRequest() above. 769 // Each request is ~1k, see HandleResourceRequest() above.
743 histogram_tester_->ExpectBucketCount( 770 histogram_tester_->ExpectBucketCount(
744 internal::kResourcePrefetchPredictorPrefetchHitsSize, 4, 1); 771 internal::kResourcePrefetchPredictorPrefetchHitsSize, 4, 1);
745 } 772 }
746 773
774 IN_PROC_BROWSER_TEST_F(ResourcePrefetchPredictorBrowserTest,
775 SubresourceFcpOrder) {
776 AddResource(GetURL(kStylePath), content::RESOURCE_TYPE_STYLESHEET,
777 net::HIGHEST);
778 AddResource(GetURL(kScriptPath), content::RESOURCE_TYPE_SCRIPT, net::MEDIUM);
779
780 ResourceSummary* image = AddResource(
781 GetURL(kImagePath), content::RESOURCE_TYPE_IMAGE, net::LOWEST);
782 // Delay HTTP response to ensure enough time to receive notice of
783 // firstContentfulPaint.
784 image->delay = base::TimeDelta::FromMilliseconds(1500);
785 image->request.before_first_contentful_paint = false;
786
787 TestLearningAndPrefetching(GetURL(kHtmlFcpOrderPath), true);
788 }
789
747 IN_PROC_BROWSER_TEST_F(ResourcePrefetchPredictorBrowserTest, Redirect) { 790 IN_PROC_BROWSER_TEST_F(ResourcePrefetchPredictorBrowserTest, Redirect) {
748 GURL initial_url = GetURLWithHost(kFooHost, kRedirectPath); 791 GURL initial_url = GetURLWithHost(kFooHost, kRedirectPath);
749 GURL redirected_url = 792 GURL redirected_url =
750 GetPageURLWithReplacements(kBarHost, kHtmlSubresourcesPath); 793 GetPageURLWithReplacements(kBarHost, kHtmlSubresourcesPath);
751 AddRedirectChain(initial_url, 794 AddRedirectChain(initial_url,
752 {{net::HTTP_MOVED_PERMANENTLY, redirected_url}}); 795 {{net::HTTP_MOVED_PERMANENTLY, redirected_url}});
753 AddResourcesFromSubresourceHtml(); 796 AddResourcesFromSubresourceHtml();
754 TestLearningAndPrefetching(initial_url); 797 TestLearningAndPrefetching(initial_url);
755 } 798 }
756 799
(...skipping 207 matching lines...) Expand 10 before | Expand all | Expand 10 after
964 AddResourcesFromSubresourceHtml(); 1007 AddResourcesFromSubresourceHtml();
965 1008
966 NavigateToURLAndCheckSubresources(initial_url); 1009 NavigateToURLAndCheckSubresources(initial_url);
967 ClearCache(); 1010 ClearCache();
968 NavigateToURLAndCheckSubresources(initial_url); 1011 NavigateToURLAndCheckSubresources(initial_url);
969 ClearCache(); 1012 ClearCache();
970 NavigateToURLAndCheckPrefetching(initial_url); 1013 NavigateToURLAndCheckPrefetching(initial_url);
971 } 1014 }
972 1015
973 } // namespace predictors 1016 } // namespace predictors
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698