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

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

Issue 1989363007: Move predictor dns unit tests to browser tests (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: 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
« no previous file with comments | « chrome/browser/net/predictor.cc ('k') | chrome/browser/net/predictor_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 #include <set>
10 11
11 #include "base/base64.h" 12 #include "base/base64.h"
12 #include "base/bind.h" 13 #include "base/bind.h"
13 #include "base/callback.h" 14 #include "base/callback.h"
14 #include "base/command_line.h" 15 #include "base/command_line.h"
15 #include "base/json/json_string_value_serializer.h" 16 #include "base/json/json_string_value_serializer.h"
16 #include "base/macros.h" 17 #include "base/macros.h"
17 #include "base/memory/ptr_util.h" 18 #include "base/memory/ptr_util.h"
18 #include "base/memory/ref_counted.h" 19 #include "base/memory/ref_counted.h"
19 #include "base/synchronization/lock.h" 20 #include "base/synchronization/lock.h"
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
76 if (request.GetURL().path() != path) 77 if (request.GetURL().path() != path)
77 return nullptr; 78 return nullptr;
78 std::unique_ptr<net::test_server::BasicHttpResponse> response( 79 std::unique_ptr<net::test_server::BasicHttpResponse> response(
79 new net::test_server::BasicHttpResponse); 80 new net::test_server::BasicHttpResponse);
80 response->set_code(net::HTTP_MOVED_PERMANENTLY); 81 response->set_code(net::HTTP_MOVED_PERMANENTLY);
81 response->AddCustomHeader("Location", redirect_url.spec()); 82 response->AddCustomHeader("Location", redirect_url.spec());
82 return std::move(response); 83 return std::move(response);
83 } 84 }
84 85
85 const char kBlinkPreconnectFeature[] = "LinkPreconnect"; 86 const char kBlinkPreconnectFeature[] = "LinkPreconnect";
86 const char kChromiumHostname[] = "chromium.org"; 87 const char kChromiumHost[] = "http://chromium.org";
eroman 2016/05/27 00:56:38 nit: Can you call this a "url" or "origin" now?
Charlie Harrison 2016/05/27 11:55:53 Done.
87 const char kInvalidLongHostname[] = "illegally-long-hostname-over-255-" 88 const char kInvalidLongHost[] =
eroman 2016/05/27 00:56:38 same
Charlie Harrison 2016/05/27 11:55:53 Done.
88 "characters-should-not-send-an-ipc-message-to-the-browser-" 89 "http://"
89 "0000000000000000000000000000000000000000000000000000000000000000000000000" 90 "illegally-long-hostname-over-255-characters-should-not-send-an-ipc-"
90 "0000000000000000000000000000000000000000000000000000000000000000000000000" 91 "message-to-the-browser-"
91 "000000000000000000000000000000000000000000000000000000.org"; 92 "00000000000000000000000000000000000000000000000000000000000000000000000000"
93 "00000000000000000000000000000000000000000000000000000000000000000000000000"
94 "0000000000000000000000000000000000000000000000000000.org";
92 95
93 // Gets notified by the EmbeddedTestServer on incoming connections being 96 // Gets notified by the EmbeddedTestServer on incoming connections being
94 // accepted or read from, keeps track of them and exposes that info to 97 // accepted or read from, keeps track of them and exposes that info to
95 // the tests. 98 // the tests.
96 // A port being reused is currently considered an error. If a test 99 // A port being reused is currently considered an error. If a test
97 // needs to verify multiple connections are opened in sequence, that will need 100 // needs to verify multiple connections are opened in sequence, that will need
98 // to be changed. 101 // to be changed.
99 class ConnectionListener 102 class ConnectionListener
100 : public net::test_server::EmbeddedTestServerConnectionListener { 103 : public net::test_server::EmbeddedTestServerConnectionListener {
101 public: 104 public:
(...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after
238 241
239 // If |num_accepted_connections_needed_| is non zero, then the object is 242 // If |num_accepted_connections_needed_| is non zero, then the object is
240 // waiting for |num_accepted_connections_needed_| sockets to be accepted 243 // waiting for |num_accepted_connections_needed_| sockets to be accepted
241 // before quitting the |num_accepted_connections_loop_|. 244 // before quitting the |num_accepted_connections_loop_|.
242 size_t num_accepted_connections_needed_; 245 size_t num_accepted_connections_needed_;
243 base::RunLoop* num_accepted_connections_loop_; 246 base::RunLoop* num_accepted_connections_loop_;
244 247
245 DISALLOW_COPY_AND_ASSIGN(ConnectionListener); 248 DISALLOW_COPY_AND_ASSIGN(ConnectionListener);
246 }; 249 };
247 250
248 // Records a history of all hostnames for which resolving has been requested,
249 // and immediately fails the resolution requests themselves.
250 class HostResolutionRequestRecorder : public net::HostResolverProc {
251 public:
252 HostResolutionRequestRecorder()
253 : HostResolverProc(NULL),
254 is_waiting_for_hostname_(false) {
255 }
256
257 int Resolve(const std::string& host,
258 net::AddressFamily address_family,
259 net::HostResolverFlags host_resolver_flags,
260 net::AddressList* addrlist,
261 int* os_error) override {
262 BrowserThread::PostTask(
263 BrowserThread::UI,
264 FROM_HERE,
265 base::Bind(&HostResolutionRequestRecorder::AddToHistory,
266 base::Unretained(this),
267 host));
268 return net::ERR_NAME_NOT_RESOLVED;
269 }
270
271 int RequestedHostnameCount() const {
272 return requested_hostnames_.size();
273 }
274
275 bool HasHostBeenRequested(const std::string& hostname) const {
276 DCHECK_CURRENTLY_ON(BrowserThread::UI);
277 return std::find(requested_hostnames_.begin(),
278 requested_hostnames_.end(),
279 hostname) != requested_hostnames_.end();
280 }
281
282 void WaitUntilHostHasBeenRequested(const std::string& hostname) {
283 DCHECK_CURRENTLY_ON(BrowserThread::UI);
284 DCHECK(!is_waiting_for_hostname_);
285 if (HasHostBeenRequested(hostname))
286 return;
287 waiting_for_hostname_ = hostname;
288 is_waiting_for_hostname_ = true;
289 content::RunMessageLoop();
290 }
291
292 private:
293 ~HostResolutionRequestRecorder() override {}
294
295 void AddToHistory(const std::string& hostname) {
296 DCHECK_CURRENTLY_ON(BrowserThread::UI);
297 requested_hostnames_.push_back(hostname);
298 if (is_waiting_for_hostname_ && waiting_for_hostname_ == hostname) {
299 is_waiting_for_hostname_ = false;
300 waiting_for_hostname_.clear();
301 base::MessageLoop::current()->QuitWhenIdle();
302 }
303 }
304
305 // The hostname which WaitUntilHostHasBeenRequested is currently waiting for
306 // to be requested.
307 std::string waiting_for_hostname_;
308
309 // Whether WaitUntilHostHasBeenRequested is waiting for a hostname to be
310 // requested and thus is running a nested message loop.
311 bool is_waiting_for_hostname_;
312
313 // A list of hostnames for which resolution has already been requested. Only
314 // to be accessed from the UI thread.
315 std::vector<std::string> requested_hostnames_;
316
317 DISALLOW_COPY_AND_ASSIGN(HostResolutionRequestRecorder);
318 };
319
320 // This class intercepts URLRequests and responds with the URLRequestJob* 251 // This class intercepts URLRequests and responds with the URLRequestJob*
321 // callback provided by the constructor. Note that the port of the URL must 252 // callback provided by the constructor. Note that the port of the URL must
322 // match the port given in the constructor. 253 // match the port given in the constructor.
323 class MatchingPortRequestInterceptor : public net::URLRequestInterceptor { 254 class MatchingPortRequestInterceptor : public net::URLRequestInterceptor {
324 public: 255 public:
325 typedef base::Callback<net::URLRequestJob*(net::URLRequest*, 256 typedef base::Callback<net::URLRequestJob*(net::URLRequest*,
326 net::NetworkDelegate*)> 257 net::NetworkDelegate*)>
327 CreateJobCallback; 258 CreateJobCallback;
328 259
329 MatchingPortRequestInterceptor( 260 MatchingPortRequestInterceptor(
(...skipping 25 matching lines...) Expand all
355 // two. 286 // two.
356 class CrossSitePredictorObserver 287 class CrossSitePredictorObserver
357 : public chrome_browser_net::PredictorObserver { 288 : public chrome_browser_net::PredictorObserver {
358 public: 289 public:
359 CrossSitePredictorObserver(const GURL& source_host, 290 CrossSitePredictorObserver(const GURL& source_host,
360 const GURL& cross_site_host) 291 const GURL& cross_site_host)
361 : source_host_(source_host), 292 : source_host_(source_host),
362 cross_site_host_(cross_site_host), 293 cross_site_host_(cross_site_host),
363 cross_site_learned_(0), 294 cross_site_learned_(0),
364 cross_site_preconnected_(0), 295 cross_site_preconnected_(0),
365 same_site_preconnected_(0) {} 296 same_site_preconnected_(0),
297 dns_run_loop_(nullptr) {}
366 298
367 void OnPreconnectUrl( 299 void OnPreconnectUrl(
368 const GURL& original_url, 300 const GURL& original_url,
369 const GURL& first_party_for_cookies, 301 const GURL& first_party_for_cookies,
370 chrome_browser_net::UrlInfo::ResolutionMotivation motivation, 302 chrome_browser_net::UrlInfo::ResolutionMotivation motivation,
371 int count) override { 303 int count) override {
372 base::AutoLock lock(lock_); 304 base::AutoLock lock(lock_);
373 if (original_url == cross_site_host_) { 305 if (original_url == cross_site_host_) {
374 cross_site_preconnected_ = std::max(cross_site_preconnected_, count); 306 cross_site_preconnected_ = std::max(cross_site_preconnected_, count);
375 } else if (original_url == source_host_) { 307 } else if (original_url == source_host_) {
(...skipping 19 matching lines...) Expand all
395 // Same site learned. Branch retained for clarity. 327 // Same site learned. Branch retained for clarity.
396 } else if (!(referring_url == cross_site_host_ && 328 } else if (!(referring_url == cross_site_host_ &&
397 target_url == cross_site_host_)) { 329 target_url == cross_site_host_)) {
398 ADD_FAILURE() << "Learned " << referring_url << " => " << target_url 330 ADD_FAILURE() << "Learned " << referring_url << " => " << target_url
399 << " when should only be learning the source host: " 331 << " when should only be learning the source host: "
400 << source_host_ 332 << source_host_
401 << " or the cross site host: " << cross_site_host_; 333 << " or the cross site host: " << cross_site_host_;
402 } 334 }
403 } 335 }
404 336
337 void OnDnsLookupFinished(const GURL& url, bool found) override {
338 base::AutoLock lock(lock_);
339 if (found) {
340 successful_dns_lookups_.insert(url);
341 } else {
342 unsuccessful_dns_lookups_.insert(url);
343 }
344 CheckForWaitingLoop();
345 }
346
405 void ResetCounts() { 347 void ResetCounts() {
406 base::AutoLock lock(lock_); 348 base::AutoLock lock(lock_);
407 cross_site_learned_ = 0; 349 cross_site_learned_ = 0;
408 cross_site_preconnected_ = 0; 350 cross_site_preconnected_ = 0;
409 same_site_preconnected_ = 0; 351 same_site_preconnected_ = 0;
410 } 352 }
411 353
412 int CrossSiteLearned() { 354 int CrossSiteLearned() {
413 base::AutoLock lock(lock_); 355 base::AutoLock lock(lock_);
414 return cross_site_learned_; 356 return cross_site_learned_;
415 } 357 }
416 358
417 int CrossSitePreconnected() { 359 int CrossSitePreconnected() {
418 base::AutoLock lock(lock_); 360 base::AutoLock lock(lock_);
419 return cross_site_preconnected_; 361 return cross_site_preconnected_;
420 } 362 }
421 363
422 int SameSitePreconnected() { 364 int SameSitePreconnected() {
423 base::AutoLock lock(lock_); 365 base::AutoLock lock(lock_);
424 return same_site_preconnected_; 366 return same_site_preconnected_;
425 } 367 }
426 368
369 // Spins a run loop until |url| is added to one of the lookup maps.
370 void WaitUntilHostLookedUp(const GURL& url) {
371 DCHECK_CURRENTLY_ON(BrowserThread::UI);
372 base::RunLoop run_loop;
373 {
374 base::AutoLock lock(lock_);
375 DCHECK(waiting_on_dns_.is_empty());
376 DCHECK(!dns_run_loop_);
377 waiting_on_dns_ = url;
378 dns_run_loop_ = &run_loop;
379 CheckForWaitingLoop();
380 }
381 run_loop.Run();
382 }
383
384 bool HasHostBeenLookedUpLocked(const GURL& url) {
385 lock_.AssertAcquired();
386 return successful_dns_lookups_.find(url) != successful_dns_lookups_.end() ||
eroman 2016/05/27 00:56:38 optional: can use ContainsKey() to simplify the va
Charlie Harrison 2016/05/27 11:55:52 Done.
387 unsuccessful_dns_lookups_.find(url) !=
388 unsuccessful_dns_lookups_.end();
389 }
390
391 bool HasHostBeenLookedUp(const GURL& url) {
392 base::AutoLock lock(lock_);
393 return HasHostBeenLookedUpLocked(url);
394 }
395
396 void CheckForWaitingLoop() {
397 lock_.AssertAcquired();
398 if (waiting_on_dns_.is_empty())
399 return;
400 if (!HasHostBeenLookedUpLocked(waiting_on_dns_))
401 return;
402 DCHECK(dns_run_loop_);
403 DCHECK(task_runner_);
404 waiting_on_dns_ = GURL();
405 task_runner_->PostTask(FROM_HERE, dns_run_loop_->QuitClosure());
406 dns_run_loop_ = nullptr;
407 }
408
409 size_t TotalHostsLookedUp() {
410 base::AutoLock lock(lock_);
411 return successful_dns_lookups_.size() + unsuccessful_dns_lookups_.size();
412 }
413
414 // Note: this method expects the URL to have been looked up.
415 bool HostFound(const GURL& url) {
416 base::AutoLock lock(lock_);
417 EXPECT_TRUE(HasHostBeenLookedUpLocked(url)) << "Expected to have looked up"
eroman 2016/05/27 00:56:38 nit: add a space at the end of the string.
Charlie Harrison 2016/05/27 11:55:53 Done.
418 << url.spec();
419 return successful_dns_lookups_.find(url) != successful_dns_lookups_.end();
420 }
421
422 void set_task_runner(
423 scoped_refptr<base::SingleThreadTaskRunner> task_runner) {
424 task_runner_.swap(task_runner);
425 }
426
427 private: 427 private:
428 const GURL source_host_; 428 const GURL source_host_;
429 const GURL cross_site_host_; 429 const GURL cross_site_host_;
430 430
431 GURL waiting_on_dns_;
432
433 scoped_refptr<base::SingleThreadTaskRunner> task_runner_;
434
431 // Protects all following members. They are read and updated from different 435 // Protects all following members. They are read and updated from different
432 // threads. 436 // threads.
433 base::Lock lock_; 437 base::Lock lock_;
434 438
435 int cross_site_learned_; 439 int cross_site_learned_;
436 int cross_site_preconnected_; 440 int cross_site_preconnected_;
437 int same_site_preconnected_; 441 int same_site_preconnected_;
438 442
443 std::set<GURL> successful_dns_lookups_;
444 std::set<GURL> unsuccessful_dns_lookups_;
445 base::RunLoop* dns_run_loop_;
446
439 DISALLOW_COPY_AND_ASSIGN(CrossSitePredictorObserver); 447 DISALLOW_COPY_AND_ASSIGN(CrossSitePredictorObserver);
440 }; 448 };
441 449
442 } // namespace 450 } // namespace
443 451
444 namespace chrome_browser_net { 452 namespace chrome_browser_net {
445 453
446 class PredictorBrowserTest : public InProcessBrowserTest { 454 class PredictorBrowserTest : public InProcessBrowserTest {
447 public: 455 public:
448 PredictorBrowserTest() 456 PredictorBrowserTest()
449 : startup_url_("http://host1:1"), 457 : startup_url_("http://host1/"),
450 referring_url_("http://host2:1"), 458 referring_url_("http://host2/"),
451 target_url_("http://host3:1"), 459 target_url_("http://host3/"),
452 host_resolution_request_recorder_(new HostResolutionRequestRecorder), 460 rule_based_resolver_proc_(new net::RuleBasedHostResolverProc(nullptr)),
453 cross_site_test_server_(new net::EmbeddedTestServer()) {} 461 cross_site_test_server_(new net::EmbeddedTestServer()) {
462 rule_based_resolver_proc_->AddRuleWithLatency("www.example.test",
463 "127.0.0.1", 50);
464 rule_based_resolver_proc_->AddRuleWithLatency("gmail.google.com",
465 "127.0.0.1", 70);
466 rule_based_resolver_proc_->AddRuleWithLatency("mail.google.com",
467 "127.0.0.1", 44);
468 rule_based_resolver_proc_->AddRuleWithLatency("gmail.com", "127.0.0.1", 63);
469 rule_based_resolver_proc_->AddSimulatedFailure("*.notfound");
470 rule_based_resolver_proc_->AddRuleWithLatency("delay.google.com",
471 "127.0.0.1", 1000 * 60);
472 }
454 473
455 protected: 474 protected:
456 void SetUpInProcessBrowserTestFixture() override { 475 void SetUpInProcessBrowserTestFixture() override {
457 scoped_host_resolver_proc_.reset(new net::ScopedDefaultHostResolverProc( 476 scoped_host_resolver_proc_.reset(new net::ScopedDefaultHostResolverProc(
458 host_resolution_request_recorder_.get())); 477 rule_based_resolver_proc_.get()));
459 InProcessBrowserTest::SetUpInProcessBrowserTestFixture(); 478 InProcessBrowserTest::SetUpInProcessBrowserTestFixture();
460 } 479 }
461 480
462 void SetUpCommandLine(base::CommandLine* command_line) override { 481 void SetUpCommandLine(base::CommandLine* command_line) override {
463 command_line->AppendSwitch( 482 command_line->AppendSwitch(
464 switches::kEnableExperimentalWebPlatformFeatures); 483 switches::kEnableExperimentalWebPlatformFeatures);
465 command_line->AppendSwitchASCII( 484 command_line->AppendSwitchASCII(
466 switches::kEnableBlinkFeatures, kBlinkPreconnectFeature); 485 switches::kEnableBlinkFeatures, kBlinkPreconnectFeature);
467 command_line->AppendSwitchASCII(switches::kEnableFeatures, 486 command_line->AppendSwitchASCII(switches::kEnableFeatures,
468 "PreconnectMore"); 487 "PreconnectMore");
488 command_line->AppendSwitchASCII(switches::kEnableFeatures,
489 "UsePredictorDNSQueue");
469 } 490 }
470 491
471 void SetUpOnMainThread() override { 492 void SetUpOnMainThread() override {
472 DCHECK_CURRENTLY_ON(BrowserThread::UI); 493 DCHECK_CURRENTLY_ON(BrowserThread::UI);
473 task_runner_ = base::ThreadTaskRunnerHandle::Get(); 494 task_runner_ = base::ThreadTaskRunnerHandle::Get();
474 cross_site_test_server_->ServeFilesFromSourceDirectory("chrome/test/data/"); 495 cross_site_test_server_->ServeFilesFromSourceDirectory("chrome/test/data/");
475 496
476 connection_listener_.reset(new ConnectionListener()); 497 connection_listener_.reset(new ConnectionListener());
477 cross_site_connection_listener_.reset(new ConnectionListener()); 498 cross_site_connection_listener_.reset(new ConnectionListener());
478 embedded_test_server()->SetConnectionListener(connection_listener_.get()); 499 embedded_test_server()->SetConnectionListener(connection_listener_.get());
479 cross_site_test_server_->SetConnectionListener( 500 cross_site_test_server_->SetConnectionListener(
480 cross_site_connection_listener_.get()); 501 cross_site_connection_listener_.get());
481 ASSERT_TRUE(embedded_test_server()->Start()); 502 ASSERT_TRUE(embedded_test_server()->Start());
482 ASSERT_TRUE(cross_site_test_server_->Start()); 503 ASSERT_TRUE(cross_site_test_server_->Start());
483 504
484 embedded_test_server()->RegisterRequestHandler( 505 embedded_test_server()->RegisterRequestHandler(
485 base::Bind(&RedirectForPathHandler, "/", 506 base::Bind(&RedirectForPathHandler, "/",
486 cross_site_test_server()->GetURL("/title1.html"))); 507 cross_site_test_server()->GetURL("/title1.html")));
487 508
488 predictor()->SetPreconnectEnabledForTest(true); 509 predictor()->SetPreconnectEnabledForTest(true);
489 InstallPredictorObserver(embedded_test_server()->base_url(), 510 InstallPredictorObserver(embedded_test_server()->base_url(),
490 cross_site_test_server()->base_url()); 511 cross_site_test_server()->base_url());
512 observer()->set_task_runner(task_runner_);
491 StartInterceptingCrossSiteOnUI(); 513 StartInterceptingCrossSiteOnUI();
492 } 514 }
493 515
494 // Intercepts all requests to the specified host and returns a response with 516 // 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 517 // 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 518 // server, to avoid any races related to socket accounting. Note, the
497 // interceptor also looks at the port, to differentiate between the 519 // interceptor also looks at the port, to differentiate between the
498 // two test servers. 520 // two test servers.
499 static void StartInterceptingHost(const GURL& url) { 521 static void StartInterceptingHost(const GURL& url) {
500 DCHECK_CURRENTLY_ON(BrowserThread::IO); 522 DCHECK_CURRENTLY_ON(BrowserThread::IO);
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
566 } 588 }
567 589
568 void GetListFromPrefsAsString(const char* list_path, 590 void GetListFromPrefsAsString(const char* list_path,
569 std::string* value_as_string) const { 591 std::string* value_as_string) const {
570 PrefService* prefs = browser()->profile()->GetPrefs(); 592 PrefService* prefs = browser()->profile()->GetPrefs();
571 const base::ListValue* list_value = prefs->GetList(list_path); 593 const base::ListValue* list_value = prefs->GetList(list_path);
572 JSONStringValueSerializer serializer(value_as_string); 594 JSONStringValueSerializer serializer(value_as_string);
573 serializer.Serialize(*list_value); 595 serializer.Serialize(*list_value);
574 } 596 }
575 597
576 bool HasHostBeenRequested(const std::string& hostname) const { 598 void WaitUntilHostsLookedUp(const network_hints::UrlList& names) {
577 return host_resolution_request_recorder_->HasHostBeenRequested(hostname); 599 for (const GURL& url : names)
600 observer()->WaitUntilHostLookedUp(url);
578 } 601 }
579 602
580 void WaitUntilHostHasBeenRequested(const std::string& hostname) { 603 void FloodResolveRequestsOnUIThread(const network_hints::UrlList& names) {
581 host_resolution_request_recorder_->WaitUntilHostHasBeenRequested(hostname); 604 DCHECK_CURRENTLY_ON(BrowserThread::UI);
605 BrowserThread::PostTask(
606 BrowserThread::IO, FROM_HERE,
607 base::Bind(&PredictorBrowserTest::FloodResolveRequests, this, names));
582 } 608 }
583 609
584 int RequestedHostnameCount() const { 610 void FloodResolveRequests(const network_hints::UrlList& names) {
585 return host_resolution_request_recorder_->RequestedHostnameCount(); 611 DCHECK_CURRENTLY_ON(BrowserThread::IO);
612 for (int i = 0; i < 10; i++) {
613 predictor()->DnsPrefetchMotivatedList(names,
614 UrlInfo::PAGE_SCAN_MOTIVATED);
615 }
586 } 616 }
587 617
588 net::EmbeddedTestServer* cross_site_test_server() { 618 net::EmbeddedTestServer* cross_site_test_server() {
589 return cross_site_test_server_.get(); 619 return cross_site_test_server_.get();
590 } 620 }
591 621
592 Predictor* predictor() { return browser()->profile()->GetNetworkPredictor(); } 622 Predictor* predictor() { return browser()->profile()->GetNetworkPredictor(); }
593 623
594 void InstallPredictorObserver(const GURL& source_host, 624 void InstallPredictorObserver(const GURL& source_host,
595 const GURL& cross_site_host) { 625 const GURL& cross_site_host) {
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
632 base::Unretained(this)), 662 base::Unretained(this)),
633 run_loop.QuitClosure()); 663 run_loop.QuitClosure());
634 run_loop.Run(); 664 run_loop.Run();
635 } 665 }
636 666
637 void FlushServerSocketsOnUIThread(net::EmbeddedTestServer* test_server) { 667 void FlushServerSocketsOnUIThread(net::EmbeddedTestServer* test_server) {
638 DCHECK_CURRENTLY_ON(BrowserThread::UI); 668 DCHECK_CURRENTLY_ON(BrowserThread::UI);
639 EXPECT_TRUE(test_server->FlushAllSocketsAndConnectionsOnUIThread()); 669 EXPECT_TRUE(test_server->FlushAllSocketsAndConnectionsOnUIThread());
640 } 670 }
641 671
672 // Note this method also expects that all the urls (found or not) were looked
673 // up.
674 void ExpectFoundUrls(
675 const network_hints::UrlList& found_names,
676 const network_hints::UrlList& not_found_names) {
677 for (const auto& name : found_names) {
678 EXPECT_TRUE(observer()->HostFound(name)) << "Expected to have found "
679 << name.spec();
680 }
681 for (const auto& name : not_found_names) {
682 EXPECT_FALSE(observer()->HostFound(name)) << "Did not expect to find "
683 << name.spec();
684 }
685 }
686
687 // This method verifies that |url| is in the predictors |results_| map. This
eroman 2016/05/27 00:56:38 nit: predictors --> predictor's
Charlie Harrison 2016/05/27 11:55:52 Done.
688 // is used for pending lookups, and lookups performed before the observer is
689 // attached.
690 void ExpectUrlRequestedFromPredictorOnUIThread(const GURL& url) {
691 DCHECK_CURRENTLY_ON(BrowserThread::UI);
692 BrowserThread::PostTask(
693 BrowserThread::IO, FROM_HERE,
694 base::Bind(&PredictorBrowserTest::ExpectUrlRequestedFromPredictor,
695 base::Unretained(this), url));
696 }
697
698 void ExpectUrlRequestedFromPredictor(const GURL& url) {
699 EXPECT_NE(predictor()->results_.find(url), predictor()->results_.end());
700 }
701
702 void DiscardAllResultsOnUIThread() {
703 BrowserThread::PostTask(BrowserThread::IO, FROM_HERE,
704 base::Bind(&Predictor::DiscardAllResults,
705 base::Unretained(predictor())));
706 }
707
708 void ExpectValidPeakPendingLookupsOnUI(size_t num_names_requested) {
709 BrowserThread::PostTask(
710 BrowserThread::IO, FROM_HERE,
711 base::Bind(&PredictorBrowserTest::ExpectValidPeakPendingLookups,
712 base::Unretained(this), num_names_requested));
713 }
714
715 void ExpectValidPeakPendingLookups(size_t num_names_requested) {
716 DCHECK_CURRENTLY_ON(BrowserThread::IO);
717 EXPECT_LE(predictor()->peak_pending_lookups_, num_names_requested);
718 EXPECT_LE(predictor()->peak_pending_lookups_,
719 predictor()->max_concurrent_dns_lookups());
720 }
721
642 CrossSitePredictorObserver* observer() { return observer_.get(); } 722 CrossSitePredictorObserver* observer() { return observer_.get(); }
643 723
644 // Navigate to an html file on embedded_test_server and tell it to request 724 // Navigate to an html file on embedded_test_server and tell it to request
645 // |num_cors| resources from the cross_site_test_server. It then waits for 725 // |num_cors| resources from the cross_site_test_server. It then waits for
646 // those requests to complete. Note that "cors" here means using cors-mode in 726 // those requests to complete. Note that "cors" here means using cors-mode in
647 // correspondence with the fetch spec. 727 // correspondence with the fetch spec.
648 void NavigateToCrossSiteHtmlUrl(int num_cors, const char* file_suffix) { 728 void NavigateToCrossSiteHtmlUrl(int num_cors, const char* file_suffix) {
649 DCHECK_CURRENTLY_ON(BrowserThread::UI); 729 DCHECK_CURRENTLY_ON(BrowserThread::UI);
650 const GURL& base_url = cross_site_test_server()->base_url(); 730 const GURL& base_url = cross_site_test_server()->base_url();
651 std::string path = base::StringPrintf( 731 std::string path = base::StringPrintf(
(...skipping 10 matching lines...) Expand all
662 EXPECT_TRUE(result); 742 EXPECT_TRUE(result);
663 } 743 }
664 744
665 const GURL startup_url_; 745 const GURL startup_url_;
666 const GURL referring_url_; 746 const GURL referring_url_;
667 const GURL target_url_; 747 const GURL target_url_;
668 std::unique_ptr<ConnectionListener> connection_listener_; 748 std::unique_ptr<ConnectionListener> connection_listener_;
669 std::unique_ptr<ConnectionListener> cross_site_connection_listener_; 749 std::unique_ptr<ConnectionListener> cross_site_connection_listener_;
670 750
671 private: 751 private:
672 scoped_refptr<HostResolutionRequestRecorder> 752 scoped_refptr<net::RuleBasedHostResolverProc> rule_based_resolver_proc_;
673 host_resolution_request_recorder_;
674 std::unique_ptr<net::ScopedDefaultHostResolverProc> 753 std::unique_ptr<net::ScopedDefaultHostResolverProc>
675 scoped_host_resolver_proc_; 754 scoped_host_resolver_proc_;
676 std::unique_ptr<net::EmbeddedTestServer> cross_site_test_server_; 755 std::unique_ptr<net::EmbeddedTestServer> cross_site_test_server_;
677 std::unique_ptr<CrossSitePredictorObserver> observer_; 756 std::unique_ptr<CrossSitePredictorObserver> observer_;
678 scoped_refptr<base::SingleThreadTaskRunner> task_runner_; 757 scoped_refptr<base::SingleThreadTaskRunner> task_runner_;
679 }; 758 };
680 759
760 IN_PROC_BROWSER_TEST_F(PredictorBrowserTest, SingleLookupTest) {
761 DiscardAllResultsOnUIThread();
762 GURL goog("http://www.example.test/");
eroman 2016/05/27 00:56:38 probably better to call this "url" -- not actually
Charlie Harrison 2016/05/27 11:55:53 Done.
763
764 // Try to flood the predictor with many concurrent requests.
765 network_hints::UrlList names{goog};
766 FloodResolveRequestsOnUIThread(names);
767 observer()->WaitUntilHostLookedUp(goog);
768 EXPECT_TRUE(observer()->HostFound(goog));
769 ExpectValidPeakPendingLookupsOnUI(1u);
770 }
771
772 IN_PROC_BROWSER_TEST_F(PredictorBrowserTest, ConcurrentLookupTest) {
773 DiscardAllResultsOnUIThread();
774 GURL goog("http://www.example.test"), goog2("http://gmail.google.com"),
eroman 2016/05/27 00:56:38 same here -- at least for one of them.
Charlie Harrison 2016/05/27 11:55:53 Done.
775 goog3("http://mail.google.com"), goog4("http://gmail.com");
776 GURL bad1("http://bad1.notfound"), bad2("http://bad2.notfound");
777
778 UrlList found_names{goog, goog3, goog2, goog4, goog};
779 UrlList not_found_names{bad1, bad2};
780 FloodResolveRequestsOnUIThread(found_names);
781 FloodResolveRequestsOnUIThread(not_found_names);
782
783 WaitUntilHostsLookedUp(found_names);
784 WaitUntilHostsLookedUp(not_found_names);
785 ExpectFoundUrls(found_names, not_found_names);
786 ExpectValidPeakPendingLookupsOnUI(found_names.size() +
787 not_found_names.size());
788 }
789
790 IN_PROC_BROWSER_TEST_F(PredictorBrowserTest, MassiveConcurrentLookupTest) {
791 DiscardAllResultsOnUIThread();
792 UrlList not_found_names;
793 for (int i = 0; i < 100; i++) {
794 not_found_names.push_back(
795 GURL(base::StringPrintf("http://host%d.notfound:80", i)));
796 }
797 FloodResolveRequestsOnUIThread(not_found_names);
798
799 WaitUntilHostsLookedUp(not_found_names);
800 ExpectFoundUrls(network_hints::UrlList(), not_found_names);
801 ExpectValidPeakPendingLookupsOnUI(not_found_names.size());
802 }
803
804 IN_PROC_BROWSER_TEST_F(PredictorBrowserTest,
805 ShutdownWhenResolutionIsPendingTest) {
806 GURL delayed_url("http://delay.google.com:80");
807 UrlList names{delayed_url};
808
809 // Flood with delayed requests, then wait.
810 FloodResolveRequestsOnUIThread(names);
811 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
812 FROM_HERE, base::MessageLoop::QuitWhenIdleClosure(),
813 base::TimeDelta::FromMilliseconds(500));
814 base::MessageLoop::current()->Run();
815
816 ExpectUrlRequestedFromPredictor(delayed_url);
817 EXPECT_FALSE(observer()->HasHostBeenLookedUp(delayed_url));
818 }
819
681 IN_PROC_BROWSER_TEST_F(PredictorBrowserTest, SimplePreconnectOne) { 820 IN_PROC_BROWSER_TEST_F(PredictorBrowserTest, SimplePreconnectOne) {
682 predictor()->PreconnectUrl( 821 predictor()->PreconnectUrl(
683 embedded_test_server()->base_url(), GURL(), 822 embedded_test_server()->base_url(), GURL(),
684 UrlInfo::ResolutionMotivation::EARLY_LOAD_MOTIVATED, 823 UrlInfo::ResolutionMotivation::EARLY_LOAD_MOTIVATED,
685 false /* allow credentials */, 1); 824 false /* allow credentials */, 1);
686 connection_listener_->WaitForAcceptedConnectionsOnUI(1u); 825 connection_listener_->WaitForAcceptedConnectionsOnUI(1u);
687 } 826 }
688 827
689 IN_PROC_BROWSER_TEST_F(PredictorBrowserTest, SimplePreconnectTwo) { 828 IN_PROC_BROWSER_TEST_F(PredictorBrowserTest, SimplePreconnectTwo) {
690 predictor()->PreconnectUrl( 829 predictor()->PreconnectUrl(
(...skipping 430 matching lines...) Expand 10 before | Expand all | Expand 10 after
1121 GetListFromPrefsAsString(prefs::kDnsPrefetchingHostReferralList, 1260 GetListFromPrefsAsString(prefs::kDnsPrefetchingHostReferralList,
1122 &cleared_referral_list); 1261 &cleared_referral_list);
1123 1262
1124 EXPECT_THAT(cleared_startup_list, Not(HasSubstr(startup_url_.host()))); 1263 EXPECT_THAT(cleared_startup_list, Not(HasSubstr(startup_url_.host())));
1125 EXPECT_THAT(cleared_referral_list, Not(HasSubstr(referring_url_.host()))); 1264 EXPECT_THAT(cleared_referral_list, Not(HasSubstr(referring_url_.host())));
1126 EXPECT_THAT(cleared_referral_list, Not(HasSubstr(target_url_.host()))); 1265 EXPECT_THAT(cleared_referral_list, Not(HasSubstr(target_url_.host())));
1127 1266
1128 // But also make sure this data has been first loaded into the Predictor, by 1267 // But also make sure this data has been first loaded into the Predictor, by
1129 // inspecting that the Predictor starts making the expected hostname requests. 1268 // inspecting that the Predictor starts making the expected hostname requests.
1130 PrepareFrameSubresources(referring_url_); 1269 PrepareFrameSubresources(referring_url_);
1131 WaitUntilHostHasBeenRequested(startup_url_.host()); 1270 observer()->WaitUntilHostLookedUp(target_url_);
1132 WaitUntilHostHasBeenRequested(target_url_.host()); 1271
1272 // Verify that both urls were requested by the predictor. Note that the
1273 // startup URL may be requested before the observer attaches itself.
1274 ExpectUrlRequestedFromPredictor(startup_url_);
1275 EXPECT_FALSE(observer()->HostFound(target_url_));
1133 } 1276 }
1134 1277
1135 // Flaky on Windows: http://crbug.com/469120 1278 IN_PROC_BROWSER_TEST_F(PredictorBrowserTest, DnsPrefetch) {
1136 #if defined(OS_WIN) 1279 // Navigate once to make sure all initial hostnames are requested.
1137 #define MAYBE_DnsPrefetch DISABLED_DnsPrefetch 1280 ui_test_utils::NavigateToURL(browser(),
1138 #else 1281 embedded_test_server()->GetURL("/title1.html"));
1139 #define MAYBE_DnsPrefetch DnsPrefetch 1282
1140 #endif 1283 size_t hosts_looked_up_before_load = observer()->TotalHostsLookedUp();
1141 IN_PROC_BROWSER_TEST_F(PredictorBrowserTest, MAYBE_DnsPrefetch) { 1284
1142 int hostnames_requested_before_load = RequestedHostnameCount(); 1285 ui_test_utils::NavigateToURL(browser(), embedded_test_server()->GetURL(
1143 ui_test_utils::NavigateToURL( 1286 "/predictor/dns_prefetch.html"));
1144 browser(), 1287 observer()->WaitUntilHostLookedUp(GURL(kChromiumHost));
1145 GURL(embedded_test_server()->GetURL("/predictor/dns_prefetch.html"))); 1288 ASSERT_FALSE(observer()->HasHostBeenLookedUp(GURL(kInvalidLongHost)));
1146 WaitUntilHostHasBeenRequested(kChromiumHostname); 1289
1147 ASSERT_FALSE(HasHostBeenRequested(kInvalidLongHostname)); 1290 EXPECT_FALSE(observer()->HostFound(GURL(kChromiumHost)));
1148 ASSERT_EQ(hostnames_requested_before_load + 1, RequestedHostnameCount()); 1291 ASSERT_EQ(hosts_looked_up_before_load + 1, observer()->TotalHostsLookedUp());
1149 } 1292 }
1150 1293
1151 // Tests that preconnect warms up a socket connection to a test server. 1294 // Tests that preconnect warms up a socket connection to a test server.
1152 // Note: This test uses a data URI to serve the preconnect hint, to make sure 1295 // Note: This test uses a data URI to serve the preconnect hint, to make sure
1153 // that the network stack doesn't just re-use its connection to the test server. 1296 // that the network stack doesn't just re-use its connection to the test server.
1154 IN_PROC_BROWSER_TEST_F(PredictorBrowserTest, PreconnectNonCORS) { 1297 IN_PROC_BROWSER_TEST_F(PredictorBrowserTest, PreconnectNonCORS) {
1155 GURL preconnect_url = embedded_test_server()->base_url(); 1298 GURL preconnect_url = embedded_test_server()->base_url();
1156 std::string preconnect_content = 1299 std::string preconnect_content =
1157 "<link rel=\"preconnect\" href=\"" + preconnect_url.spec() + "\">"; 1300 "<link rel=\"preconnect\" href=\"" + preconnect_url.spec() + "\">";
1158 NavigateToDataURLWithContent(preconnect_content); 1301 NavigateToDataURLWithContent(preconnect_content);
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after
1249 // Second navigation to content with an img. 1392 // Second navigation to content with an img.
1250 std::string img_content = 1393 std::string img_content =
1251 "<img src=\"" + preconnect_url.spec() + "test.gif\">"; 1394 "<img src=\"" + preconnect_url.spec() + "test.gif\">";
1252 NavigateToDataURLWithContent(img_content); 1395 NavigateToDataURLWithContent(img_content);
1253 connection_listener_->WaitUntilFirstConnectionRead(); 1396 connection_listener_->WaitUntilFirstConnectionRead();
1254 EXPECT_EQ(2u, connection_listener_->GetAcceptedSocketCount()); 1397 EXPECT_EQ(2u, connection_listener_->GetAcceptedSocketCount());
1255 EXPECT_EQ(1u, connection_listener_->GetReadSocketCount()); 1398 EXPECT_EQ(1u, connection_listener_->GetReadSocketCount());
1256 } 1399 }
1257 1400
1258 } // namespace chrome_browser_net 1401 } // namespace chrome_browser_net
OLDNEW
« no previous file with comments | « chrome/browser/net/predictor.cc ('k') | chrome/browser/net/predictor_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698