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

Side by Side Diff: chrome/browser/net/predictor_browsertest.cc

Issue 1857383002: Refactor net predictor to use ResourceThrottles (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: mmenke@ review + additional test Created 4 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 (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 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 #include <stdint.h> 6 #include <stdint.h>
7 7
8 #include <algorithm> 8 #include <algorithm>
9 #include <memory> 9 #include <memory>
10 10
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
60 net::NetworkDelegate* delegate) { 60 net::NetworkDelegate* delegate) {
61 const char kPlainTextHeaders[] = 61 const char kPlainTextHeaders[] =
62 "HTTP/1.1 200 OK\n" 62 "HTTP/1.1 200 OK\n"
63 "Content-Type: text/plain\n" 63 "Content-Type: text/plain\n"
64 "Access-Control-Allow-Origin: *\n" 64 "Access-Control-Allow-Origin: *\n"
65 "\n"; 65 "\n";
66 return new net::URLRequestTestJob(request, delegate, kPlainTextHeaders, "", 66 return new net::URLRequestTestJob(request, delegate, kPlainTextHeaders, "",
67 true); 67 true);
68 } 68 }
69 69
70 net::URLRequestJob* CreateRedirectRequestJob(std::string location,
71 net::URLRequest* request,
72 net::NetworkDelegate* delegate) {
73 char kPlainTextHeaders[] =
74 "HTTP/1.1 302 \n"
75 "Location: %s\n"
76 "Access-Control-Allow-Origin: *\n"
77 "\n";
78 return new net::URLRequestTestJob(
79 request, delegate,
80 base::StringPrintf(kPlainTextHeaders, location.c_str()), "", true);
81 }
82
83
mmenke 2016/05/24 20:27:34 Here's another extra line break for you to remove.
Charlie Harrison 2016/05/24 21:43:22 Done.
70 // Override the test server to redirect requests matching some path. This is 84 // Override the test server to redirect requests matching some path. This is
71 // used because the predictor only learns simple redirects with a path of "/" 85 // used because the predictor only learns simple redirects with a path of "/"
72 std::unique_ptr<net::test_server::HttpResponse> RedirectForPathHandler( 86 std::unique_ptr<net::test_server::HttpResponse> RedirectForPathHandler(
73 const std::string& path, 87 const std::string& path,
74 const GURL& redirect_url, 88 const GURL& redirect_url,
75 const net::test_server::HttpRequest& request) { 89 const net::test_server::HttpRequest& request) {
76 if (request.GetURL().path() != path) 90 if (request.GetURL().path() != path)
77 return nullptr; 91 return nullptr;
78 std::unique_ptr<net::test_server::BasicHttpResponse> response( 92 std::unique_ptr<net::test_server::BasicHttpResponse> response(
79 new net::test_server::BasicHttpResponse); 93 new net::test_server::BasicHttpResponse);
(...skipping 275 matching lines...) Expand 10 before | Expand all | Expand 10 after
355 // two. 369 // two.
356 class CrossSitePredictorObserver 370 class CrossSitePredictorObserver
357 : public chrome_browser_net::PredictorObserver { 371 : public chrome_browser_net::PredictorObserver {
358 public: 372 public:
359 CrossSitePredictorObserver(const GURL& source_host, 373 CrossSitePredictorObserver(const GURL& source_host,
360 const GURL& cross_site_host) 374 const GURL& cross_site_host)
361 : source_host_(source_host), 375 : source_host_(source_host),
362 cross_site_host_(cross_site_host), 376 cross_site_host_(cross_site_host),
363 cross_site_learned_(0), 377 cross_site_learned_(0),
364 cross_site_preconnected_(0), 378 cross_site_preconnected_(0),
365 same_site_preconnected_(0) {} 379 same_site_preconnected_(0),
380 strict_learning_checking_(true) {}
366 381
367 void OnPreconnectUrl( 382 void OnPreconnectUrl(
368 const GURL& original_url, 383 const GURL& original_url,
369 const GURL& first_party_for_cookies, 384 const GURL& first_party_for_cookies,
370 chrome_browser_net::UrlInfo::ResolutionMotivation motivation, 385 chrome_browser_net::UrlInfo::ResolutionMotivation motivation,
371 int count) override { 386 int count) override {
372 base::AutoLock lock(lock_); 387 base::AutoLock lock(lock_);
373 if (original_url == cross_site_host_) { 388 if (original_url == cross_site_host_) {
374 cross_site_preconnected_ = std::max(cross_site_preconnected_, count); 389 cross_site_preconnected_ = std::max(cross_site_preconnected_, count);
375 } else if (original_url == source_host_) { 390 } else if (original_url == source_host_) {
(...skipping 10 matching lines...) Expand all
386 const GURL& target_url) override { 401 const GURL& target_url) override {
387 base::AutoLock lock(lock_); 402 base::AutoLock lock(lock_);
388 // There are three possibilities: 403 // There are three possibilities:
389 // source => target 404 // source => target
390 // source => source 405 // source => source
391 // target => target 406 // target => target
392 if (referring_url == source_host_ && target_url == cross_site_host_) { 407 if (referring_url == source_host_ && target_url == cross_site_host_) {
393 cross_site_learned_++; 408 cross_site_learned_++;
394 } else if (referring_url == source_host_ && target_url == source_host_) { 409 } else if (referring_url == source_host_ && target_url == source_host_) {
395 // Same site learned. Branch retained for clarity. 410 // Same site learned. Branch retained for clarity.
396 } else if (!(referring_url == cross_site_host_ && 411 } else if (strict_learning_checking_ &&
412 !(referring_url == cross_site_host_ &&
397 target_url == cross_site_host_)) { 413 target_url == cross_site_host_)) {
398 ADD_FAILURE() << "Learned " << referring_url << " => " << target_url 414 ADD_FAILURE() << "Learned " << referring_url << " => " << target_url
399 << " when should only be learning the source host: " 415 << " when should only be learning the source host: "
400 << source_host_ 416 << source_host_
401 << " or the cross site host: " << cross_site_host_; 417 << " or the cross site host: " << cross_site_host_;
402 } 418 }
403 } 419 }
404 420
405 void ResetCounts() { 421 void ResetCounts() {
406 base::AutoLock lock(lock_); 422 base::AutoLock lock(lock_);
(...skipping 10 matching lines...) Expand all
417 int CrossSitePreconnected() { 433 int CrossSitePreconnected() {
418 base::AutoLock lock(lock_); 434 base::AutoLock lock(lock_);
419 return cross_site_preconnected_; 435 return cross_site_preconnected_;
420 } 436 }
421 437
422 int SameSitePreconnected() { 438 int SameSitePreconnected() {
423 base::AutoLock lock(lock_); 439 base::AutoLock lock(lock_);
424 return same_site_preconnected_; 440 return same_site_preconnected_;
425 } 441 }
426 442
443 void SetStrictLearningChecking(bool strict) {
444 base::AutoLock lock(lock_);
445 strict_learning_checking_ = strict;
446 }
447
427 private: 448 private:
428 const GURL source_host_; 449 const GURL source_host_;
429 const GURL cross_site_host_; 450 const GURL cross_site_host_;
430 451
431 // Protects all following members. They are read and updated from different 452 // Protects all following members. They are read and updated from different
432 // threads. 453 // threads.
433 base::Lock lock_; 454 base::Lock lock_;
434 455
435 int cross_site_learned_; 456 int cross_site_learned_;
436 int cross_site_preconnected_; 457 int cross_site_preconnected_;
437 int same_site_preconnected_; 458 int same_site_preconnected_;
438 459
460 // This member can be set to optionally allow url learning other than from
461 // source => source, source => target, or target => target.
462 bool strict_learning_checking_;
463
439 DISALLOW_COPY_AND_ASSIGN(CrossSitePredictorObserver); 464 DISALLOW_COPY_AND_ASSIGN(CrossSitePredictorObserver);
440 }; 465 };
441 466
442 } // namespace 467 } // namespace
443 468
444 namespace chrome_browser_net { 469 namespace chrome_browser_net {
445 470
446 class PredictorBrowserTest : public InProcessBrowserTest { 471 class PredictorBrowserTest : public InProcessBrowserTest {
447 public: 472 public:
448 PredictorBrowserTest() 473 PredictorBrowserTest()
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
484 embedded_test_server()->RegisterRequestHandler( 509 embedded_test_server()->RegisterRequestHandler(
485 base::Bind(&RedirectForPathHandler, "/", 510 base::Bind(&RedirectForPathHandler, "/",
486 cross_site_test_server()->GetURL("/title1.html"))); 511 cross_site_test_server()->GetURL("/title1.html")));
487 512
488 predictor()->SetPreconnectEnabledForTest(true); 513 predictor()->SetPreconnectEnabledForTest(true);
489 InstallPredictorObserver(embedded_test_server()->base_url(), 514 InstallPredictorObserver(embedded_test_server()->base_url(),
490 cross_site_test_server()->base_url()); 515 cross_site_test_server()->base_url());
491 StartInterceptingCrossSiteOnUI(); 516 StartInterceptingCrossSiteOnUI();
492 } 517 }
493 518
519 static void StartInterceptingHostWithCreateJobCallback(
520 const GURL& url,
521 const MatchingPortRequestInterceptor::CreateJobCallback& callback) {
522 DCHECK_CURRENTLY_ON(BrowserThread::IO);
523 net::URLRequestFilter::GetInstance()->AddHostnameInterceptor(
524 url.scheme(), url.host(),
525 base::WrapUnique(new MatchingPortRequestInterceptor(
526 url.EffectiveIntPort(), callback)));
527 }
528
529
Charlie Harrison 2016/05/23 21:13:32 Will remove this line.
Charlie Harrison 2016/05/24 21:43:22 Done.
530 static void StopInterceptingHost(const GURL& url) {
531 DCHECK_CURRENTLY_ON(BrowserThread::IO);
532 net::URLRequestFilter::GetInstance()->RemoveHostnameHandler(url.scheme(),
533 url.host());
534 }
535
494 // Intercepts all requests to the specified host and returns a response with 536 // Intercepts all requests to the specified host and returns a response with
495 // an empty body. Needed to prevent requests from actually going to the test 537 // an empty body. Needed to prevent requests from actually going to the test
496 // server, to avoid any races related to socket accounting. Note, the 538 // server, to avoid any races related to socket accounting. Note, the
497 // interceptor also looks at the port, to differentiate between the 539 // interceptor also looks at the port, to differentiate between the
498 // two test servers. 540 // two test servers.
499 static void StartInterceptingHost(const GURL& url) {
500 DCHECK_CURRENTLY_ON(BrowserThread::IO);
501 net::URLRequestFilter::GetInstance()->AddHostnameInterceptor(
502 url.scheme(), url.host(),
503 base::WrapUnique(new MatchingPortRequestInterceptor(
504 url.EffectiveIntPort(), base::Bind(&CreateEmptyBodyRequestJob))));
505 }
506
507 static void StopInterceptingHost(const GURL& url) {
508 DCHECK_CURRENTLY_ON(BrowserThread::IO);
509 net::URLRequestFilter::GetInstance()->RemoveHostnameHandler(url.scheme(),
510 url.host());
511 }
512
513 void StartInterceptingCrossSiteOnUI() { 541 void StartInterceptingCrossSiteOnUI() {
514 DCHECK_CURRENTLY_ON(BrowserThread::UI); 542 DCHECK_CURRENTLY_ON(BrowserThread::UI);
515 content::BrowserThread::PostTask( 543 content::BrowserThread::PostTask(
516 content::BrowserThread::IO, FROM_HERE, 544 content::BrowserThread::IO, FROM_HERE,
517 base::Bind(&PredictorBrowserTest::StartInterceptingHost, 545 base::Bind(
518 cross_site_test_server()->base_url())); 546 &PredictorBrowserTest::StartInterceptingHostWithCreateJobCallback,
547 cross_site_test_server()->base_url(),
548 base::Bind(&CreateEmptyBodyRequestJob)));
519 } 549 }
520 550
521 void StopInterceptingCrossSiteOnUI() { 551 void StopInterceptingCrossSiteOnUI() {
522 DCHECK_CURRENTLY_ON(BrowserThread::UI); 552 DCHECK_CURRENTLY_ON(BrowserThread::UI);
523 content::BrowserThread::PostTask( 553 content::BrowserThread::PostTask(
524 content::BrowserThread::IO, FROM_HERE, 554 content::BrowserThread::IO, FROM_HERE,
525 base::Bind(&PredictorBrowserTest::StopInterceptingHost, 555 base::Bind(&PredictorBrowserTest::StopInterceptingHost,
526 cross_site_test_server()->base_url())); 556 cross_site_test_server()->base_url()));
527 } 557 }
528 558
(...skipping 241 matching lines...) Expand 10 before | Expand all | Expand 10 after
770 // embedded test servers have the same host_piece, an extra preconnect is 800 // embedded test servers have the same host_piece, an extra preconnect is
771 // issued. This results in ceil(2.33) + 1 = 4 preconnects. 801 // issued. This results in ceil(2.33) + 1 = 4 preconnects.
772 ui_test_utils::NavigateToURL(browser(), 802 ui_test_utils::NavigateToURL(browser(),
773 embedded_test_server()->GetURL("/title1.html")); 803 embedded_test_server()->GetURL("/title1.html"));
774 // Just check that predictor has initiated preconnects to the cross site test 804 // Just check that predictor has initiated preconnects to the cross site test
775 // server. It's tricky to reset the connections to the test server, and 805 // server. It's tricky to reset the connections to the test server, and
776 // sockets can be reused. 806 // sockets can be reused.
777 EXPECT_EQ(4, observer()->CrossSitePreconnected()); 807 EXPECT_EQ(4, observer()->CrossSitePreconnected());
778 } 808 }
779 809
810 // 1. Navigate to A.com learning B.com
811 // 2. Navigate to B.com with subresource from C.com redirecting to A.com.
812 // 3. Assert that the redirect does not cause us to preconnect to B.com (via
813 // A.com).
814 IN_PROC_BROWSER_TEST_F(PredictorBrowserTest, DontPredictBasedOnSubresources) {
815 std::unique_ptr<net::EmbeddedTestServer> redirector =
816 base::WrapUnique(new net::EmbeddedTestServer());
817 redirector->ServeFilesFromSourceDirectory("chrome/test/data/");
mmenke 2016/05/24 20:27:34 I don't think we actually need a test server here,
Charlie Harrison 2016/05/24 21:43:22 Right. Done.
818 ASSERT_TRUE(redirector->Start());
819
820 NavigateToCrossSiteHtmlUrl(1 /* num_cors */, "" /* file_suffix */);
821 EXPECT_EQ(1, observer()->CrossSiteLearned());
822
823 EXPECT_EQ(0u, cross_site_connection_listener_->GetAcceptedSocketCount());
824
825 // Stop intercepting so that the test can actually navigate to the cross site
826 // server.
827 StopInterceptingCrossSiteOnUI();
828
829 // All requests to the redirector server should redirect to the
mmenke 2016/05/24 20:27:34 -"the"? There are multiple embedded test servers
Charlie Harrison 2016/05/24 21:43:22 Done.
830 // embedded_test_server_.
831 content::BrowserThread::PostTask(
832 content::BrowserThread::IO, FROM_HERE,
833 base::Bind(
834 &PredictorBrowserTest::StartInterceptingHostWithCreateJobCallback,
835 redirector->base_url(),
836 base::Bind(
837 &CreateRedirectRequestJob,
838 embedded_test_server()->GetURL("/predictor/empty.js").spec())));
839
840 // Reduce the strictness, because the below logic causes the predictor to
841 // learn cross_site_test_server_ => redirector, as well as
842 // cross_site_test_server_ => embedded_test_server_ (via referrer header).
843 observer()->SetStrictLearningChecking(false);
844
845 GURL redirecting_url = cross_site_test_server()->GetURL(base::StringPrintf(
846 "/predictor/"
847 "predictor_cross_site.html?subresourceHost=%s&numCORSResources=1",
848 redirector->base_url().spec().c_str()));
849 ui_test_utils::NavigateToURL(browser(), redirecting_url);
850 bool result = false;
851 EXPECT_TRUE(content::ExecuteScriptAndExtractBool(
852 browser()->tab_strip_model()->GetActiveWebContents(),
853 "startFetchesAndWaitForReply()", &result));
854 EXPECT_TRUE(result);
855
856 // The number of preconnects should not increase.
857 EXPECT_EQ(1, observer()->CrossSitePreconnected());
mmenke 2016/05/24 20:27:34 Hrm...Should we make a subframe test that matches
Charlie Harrison 2016/05/24 21:43:22 Done. I also fixed this test up a little.
858 }
859
780 // Expect that the predictor correctly predicts subframe navigations. 860 // Expect that the predictor correctly predicts subframe navigations.
781 IN_PROC_BROWSER_TEST_F(PredictorBrowserTest, SubframeCrossSitePrediction) { 861 IN_PROC_BROWSER_TEST_F(PredictorBrowserTest, SubframeCrossSitePrediction) {
782 ui_test_utils::NavigateToURL( 862 ui_test_utils::NavigateToURL(
783 browser(), embedded_test_server()->GetURL( 863 browser(), embedded_test_server()->GetURL(
784 "/predictor/predictor_cross_site_subframe_nav.html")); 864 "/predictor/predictor_cross_site_subframe_nav.html"));
785 bool result = false; 865 bool result = false;
786 EXPECT_TRUE(content::ExecuteScriptAndExtractBool( 866 EXPECT_TRUE(content::ExecuteScriptAndExtractBool(
787 browser()->tab_strip_model()->GetActiveWebContents(), 867 browser()->tab_strip_model()->GetActiveWebContents(),
788 base::StringPrintf( 868 base::StringPrintf(
789 "navigateSubframe('%s')", 869 "navigateSubframe('%s')",
(...skipping 459 matching lines...) Expand 10 before | Expand all | Expand 10 after
1249 // Second navigation to content with an img. 1329 // Second navigation to content with an img.
1250 std::string img_content = 1330 std::string img_content =
1251 "<img src=\"" + preconnect_url.spec() + "test.gif\">"; 1331 "<img src=\"" + preconnect_url.spec() + "test.gif\">";
1252 NavigateToDataURLWithContent(img_content); 1332 NavigateToDataURLWithContent(img_content);
1253 connection_listener_->WaitUntilFirstConnectionRead(); 1333 connection_listener_->WaitUntilFirstConnectionRead();
1254 EXPECT_EQ(2u, connection_listener_->GetAcceptedSocketCount()); 1334 EXPECT_EQ(2u, connection_listener_->GetAcceptedSocketCount());
1255 EXPECT_EQ(1u, connection_listener_->GetReadSocketCount()); 1335 EXPECT_EQ(1u, connection_listener_->GetReadSocketCount());
1256 } 1336 }
1257 1337
1258 } // namespace chrome_browser_net 1338 } // namespace chrome_browser_net
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698