1 // Copyright 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
8 #include "base/memory/scoped_ptr.h"
9 #include "base/message_loop/message_loop.h"
10 #include "base/path_service.h"
11 #include "base/prefs/pref_service.h"
12 #include "base/run_loop.h"
13 #include "base/threading/thread_restrictions.h"
14 #include "chrome/browser/browser_process.h"
15 #include "chrome/browser/google/google_util.h"
16 #include "chrome/browser/io_thread.h"
17 #include "chrome/browser/net/dns_probe_test_util.h"
18 #include "chrome/browser/net/net_error_tab_helper.h"
19 #include "chrome/browser/net/url_request_mock_util.h"
20 #include "chrome/browser/profiles/profile.h"
21 #include "chrome/browser/ui/browser.h"
22 #include "chrome/browser/ui/browser_commands.h"
23 #include "chrome/browser/ui/tabs/tab_strip_model.h"
24 #include "chrome/common/chrome_paths.h"
25 #include "chrome/common/net/net_error_info.h"
26 #include "chrome/common/pref_names.h"
27 #include "chrome/test/base/in_process_browser_test.h"
28 #include "chrome/test/base/ui_test_utils.h"
29 #include "content/public/browser/browser_thread.h"
30 #include "content/public/browser/web_contents.h"
31 #include "content/public/test/browser_test_utils.h"
32 #include "content/public/test/test_navigation_observer.h"
33 #include "content/test/net/url_request_failed_job.h"
34 #include "content/test/net/url_request_mock_http_job.h"
35 #include "net/base/net_errors.h"
36 #include "net/dns/dns_test_util.h"
37 #include "net/url_request/url_request_filter.h"
38 #include "net/url_request/url_request_job.h"
39 #include "net/url_request/url_request_job_factory.h"
46 using base::MessageLoop
;
47 using base::Unretained
;
48 using chrome_common_net::DnsProbeStatus
;
49 using content::BrowserThread
;
50 using content::URLRequestFailedJob
;
51 using content::URLRequestMockHTTPJob
;
52 using content::WebContents
;
53 using google_util::LinkDoctorBaseURL
;
54 using net::MockDnsClientRule
;
55 using net::NetworkDelegate
;
56 using net::URLRequest
;
57 using net::URLRequestFilter
;
58 using net::URLRequestJob
;
59 using net::URLRequestJobFactory
;
60 using ui_test_utils::NavigateToURL
;
61 using ui_test_utils::NavigateToURLBlockUntilNavigationsComplete
;
63 namespace chrome_browser_net
{
67 // Postable function to run a Closure on the UI thread. Since
68 // BrowserThread::PostTask returns a bool, it can't directly be posted to
70 void RunClosureOnUIThread(const base::Closure
& closure
) {
71 BrowserThread::PostTask(BrowserThread::UI
, FROM_HERE
, closure
);
74 // Wraps DnsProbeService and delays callbacks until someone calls
75 // CallDelayedCallbacks. This allows the DnsProbeBrowserTest to enforce a
76 // stricter ordering of events.
77 class DelayingDnsProbeService
: public DnsProbeService
{
79 DelayingDnsProbeService() {}
81 virtual ~DelayingDnsProbeService() {
82 EXPECT_TRUE(delayed_probes_
.empty());
85 virtual void ProbeDns(const ProbeCallback
& callback
) OVERRIDE
{
86 delayed_probes_
.push_back(callback
);
89 void StartDelayedProbes() {
90 CHECK(BrowserThread::CurrentlyOn(BrowserThread::IO
));
92 std::vector
<ProbeCallback
> probes
;
93 probes
.swap(delayed_probes_
);
95 for (std::vector
<ProbeCallback
>::const_iterator i
= probes
.begin();
96 i
!= probes
.end(); ++i
) {
97 DnsProbeService::ProbeDns(*i
);
101 int delayed_probe_count() const {
102 CHECK(BrowserThread::CurrentlyOn(BrowserThread::IO
));
103 return delayed_probes_
.size();
107 std::vector
<ProbeCallback
> delayed_probes_
;
110 FilePath
GetMockLinkDoctorFilePath() {
112 PathService::Get(chrome::DIR_TEST_DATA
, &root_http
);
113 return root_http
.AppendASCII("mock-link-doctor.html");
116 // A request that can be delayed until Resume() is called. Can also run a
117 // callback if destroyed without being resumed. Resume can be called either
118 // before or after a the request is started.
119 class DelayableRequest
{
121 // Called by a DelayableRequest if it was set to be delayed, and has been
122 // destroyed without Undelay being called.
123 typedef base::Callback
<void(DelayableRequest
* request
)> DestructionCallback
;
125 virtual void Resume() = 0;
128 virtual ~DelayableRequest() {}
131 class DelayableURLRequestFailedJob
: public URLRequestFailedJob
,
132 public DelayableRequest
{
134 // |destruction_callback| is only called if a delayed request is destroyed
135 // without being resumed.
136 DelayableURLRequestFailedJob(net::URLRequest
* request
,
137 net::NetworkDelegate
* network_delegate
,
140 const DestructionCallback
& destruction_callback
)
141 : URLRequestFailedJob(request
, network_delegate
, net_error
),
142 should_delay_(should_delay
),
143 start_delayed_(false),
144 destruction_callback_(destruction_callback
) {}
146 virtual void Start() OVERRIDE
{
148 DCHECK(!start_delayed_
);
149 start_delayed_
= true;
152 URLRequestFailedJob::Start();
155 virtual void Resume() OVERRIDE
{
156 DCHECK(should_delay_
);
157 should_delay_
= false;
158 if (start_delayed_
) {
159 start_delayed_
= false;
165 virtual ~DelayableURLRequestFailedJob() {
167 destruction_callback_
.Run(this);
172 const DestructionCallback destruction_callback_
;
175 class DelayableURLRequestMockHTTPJob
: public URLRequestMockHTTPJob
,
176 public DelayableRequest
{
178 DelayableURLRequestMockHTTPJob(
179 net::URLRequest
* request
,
180 net::NetworkDelegate
* network_delegate
,
181 const base::FilePath
& file_path
,
183 const DestructionCallback
& destruction_callback
)
184 : URLRequestMockHTTPJob(request
, network_delegate
, file_path
),
185 should_delay_(should_delay
),
186 start_delayed_(false),
187 destruction_callback_(destruction_callback
) {}
189 virtual void Start() OVERRIDE
{
191 DCHECK(!start_delayed_
);
192 start_delayed_
= true;
195 URLRequestMockHTTPJob::Start();
198 virtual void Resume() OVERRIDE
{
199 DCHECK(should_delay_
);
200 should_delay_
= false;
201 if (start_delayed_
) {
202 start_delayed_
= false;
208 virtual ~DelayableURLRequestMockHTTPJob() {
210 destruction_callback_
.Run(this);
215 const DestructionCallback destruction_callback_
;
218 // ProtocolHandler for Link Doctor requests. Can cause requests to fail with
219 // an error, and/or delay a request until a test allows to continue. Also can
220 // run a callback when a delayed request is cancelled.
221 class BreakableLinkDoctorProtocolHandler
222 : public URLRequestJobFactory::ProtocolHandler
{
224 explicit BreakableLinkDoctorProtocolHandler(
225 const FilePath
& mock_link_doctor_file_path
)
226 : mock_link_doctor_file_path_(mock_link_doctor_file_path
),
228 delay_requests_(false),
229 on_request_destroyed_callback_(
230 base::Bind(&BreakableLinkDoctorProtocolHandler::OnRequestDestroyed
,
231 base::Unretained(this))) {
234 virtual ~BreakableLinkDoctorProtocolHandler() {
235 // All delayed requests should have been resumed or cancelled by this point.
236 EXPECT_TRUE(delayed_requests_
.empty());
239 virtual URLRequestJob
* MaybeCreateJob(
241 NetworkDelegate
* network_delegate
) const OVERRIDE
{
242 if (net_error_
!= net::OK
) {
243 DelayableURLRequestFailedJob
* job
=
244 new DelayableURLRequestFailedJob(
245 request
, network_delegate
, net_error_
, delay_requests_
,
246 on_request_destroyed_callback_
);
248 delayed_requests_
.insert(job
);
251 DelayableURLRequestMockHTTPJob
* job
=
252 new DelayableURLRequestMockHTTPJob(
253 request
, network_delegate
, mock_link_doctor_file_path_
,
254 delay_requests_
, on_request_destroyed_callback_
);
256 delayed_requests_
.insert(job
);
261 void set_net_error(int net_error
) { net_error_
= net_error
; }
263 void SetDelayRequests(bool delay_requests
) {
264 delay_requests_
= delay_requests
;
266 // Resume all delayed requests if no longer delaying requests.
267 if (!delay_requests
) {
268 while (!delayed_requests_
.empty()) {
269 DelayableRequest
* request
= *delayed_requests_
.begin();
270 delayed_requests_
.erase(request
);
276 // Runs |callback| once all delayed requests have been destroyed. Does not
277 // wait for delayed requests that have been resumed.
278 void SetRequestDestructionCallback(const base::Closure
& callback
) {
279 ASSERT_TRUE(delayed_request_destruction_callback_
.is_null());
280 if (delayed_requests_
.empty()) {
284 delayed_request_destruction_callback_
= callback
;
287 void OnRequestDestroyed(DelayableRequest
* request
) {
288 ASSERT_EQ(1u, delayed_requests_
.count(request
));
289 delayed_requests_
.erase(request
);
290 if (delayed_requests_
.empty() &&
291 !delayed_request_destruction_callback_
.is_null()) {
292 delayed_request_destruction_callback_
.Run();
293 delayed_request_destruction_callback_
.Reset();
298 const FilePath mock_link_doctor_file_path_
;
300 bool delay_requests_
;
302 // Called when a request is destroyed. Memeber variable because
303 // MaybeCreateJob is "const", so calling base::Bind in that function does
305 const DelayableRequest::DestructionCallback on_request_destroyed_callback_
;
307 // Mutable is needed because MaybeCreateJob is const.
308 mutable std::set
<DelayableRequest
*> delayed_requests_
;
310 base::Closure delayed_request_destruction_callback_
;
313 class DnsProbeBrowserTestIOThreadHelper
{
315 DnsProbeBrowserTestIOThreadHelper();
317 void SetUpOnIOThread(IOThread
* io_thread
);
318 void CleanUpOnIOThreadAndDeleteHelper();
320 void SetMockDnsClientRules(MockDnsClientRule::Result system_good_result
,
321 MockDnsClientRule::Result public_good_result
);
322 void SetLinkDoctorNetError(int link_doctor_net_error
);
323 void SetLinkDoctorDelayRequests(bool delay_requests
);
324 void SetRequestDestructionCallback(const base::Closure
& callback
);
325 void StartDelayedProbes(int expected_delayed_probe_count
);
328 IOThread
* io_thread_
;
329 DnsProbeService
* original_dns_probe_service_
;
330 DelayingDnsProbeService
* delaying_dns_probe_service_
;
331 BreakableLinkDoctorProtocolHandler
* protocol_handler_
;
332 FilePath mock_link_doctor_file_path_
;
335 DnsProbeBrowserTestIOThreadHelper::DnsProbeBrowserTestIOThreadHelper()
337 original_dns_probe_service_(NULL
),
338 delaying_dns_probe_service_(NULL
),
339 protocol_handler_(NULL
),
340 mock_link_doctor_file_path_(GetMockLinkDoctorFilePath()) {}
342 void DnsProbeBrowserTestIOThreadHelper::SetUpOnIOThread(IOThread
* io_thread
) {
343 CHECK(BrowserThread::CurrentlyOn(BrowserThread::IO
));
346 CHECK(!original_dns_probe_service_
);
347 CHECK(!delaying_dns_probe_service_
);
348 CHECK(!protocol_handler_
);
350 io_thread_
= io_thread
;
352 delaying_dns_probe_service_
= new DelayingDnsProbeService();
354 IOThread::Globals
* globals
= io_thread_
->globals();
355 original_dns_probe_service_
= globals
->dns_probe_service
.release();
356 globals
->dns_probe_service
.reset(delaying_dns_probe_service_
);
358 URLRequestFailedJob::AddUrlHandler();
360 scoped_ptr
<URLRequestJobFactory::ProtocolHandler
> protocol_handler(
361 new BreakableLinkDoctorProtocolHandler(mock_link_doctor_file_path_
));
363 static_cast<BreakableLinkDoctorProtocolHandler
*>(protocol_handler
.get());
364 const GURL link_doctor_base_url
= LinkDoctorBaseURL();
365 const std::string link_doctor_host
= link_doctor_base_url
.host();
366 URLRequestFilter::GetInstance()->AddHostnameProtocolHandler(
367 "http", link_doctor_host
, protocol_handler
.Pass());
370 void DnsProbeBrowserTestIOThreadHelper::CleanUpOnIOThreadAndDeleteHelper() {
371 CHECK(BrowserThread::CurrentlyOn(BrowserThread::IO
));
373 URLRequestFilter::GetInstance()->ClearHandlers();
375 IOThread::Globals
* globals
= io_thread_
->globals();
376 scoped_ptr
<DnsProbeService
> delaying_dns_probe_service(
377 globals
->dns_probe_service
.release());
378 globals
->dns_probe_service
.reset(original_dns_probe_service_
);
380 CHECK_EQ(delaying_dns_probe_service_
, delaying_dns_probe_service
.get());
385 void DnsProbeBrowserTestIOThreadHelper::SetMockDnsClientRules(
386 MockDnsClientRule::Result system_result
,
387 MockDnsClientRule::Result public_result
) {
388 CHECK(BrowserThread::CurrentlyOn(BrowserThread::IO
));
390 DnsProbeService
* service
= io_thread_
->globals()->dns_probe_service
.get();
391 service
->SetSystemClientForTesting(
392 CreateMockDnsClientForProbes(system_result
));
393 service
->SetPublicClientForTesting(
394 CreateMockDnsClientForProbes(public_result
));
397 void DnsProbeBrowserTestIOThreadHelper::SetLinkDoctorNetError(
398 int link_doctor_net_error
) {
399 CHECK(BrowserThread::CurrentlyOn(BrowserThread::IO
));
401 protocol_handler_
->set_net_error(link_doctor_net_error
);
404 void DnsProbeBrowserTestIOThreadHelper::SetLinkDoctorDelayRequests(
405 bool delay_requests
) {
406 CHECK(BrowserThread::CurrentlyOn(BrowserThread::IO
));
408 protocol_handler_
->SetDelayRequests(delay_requests
);
411 void DnsProbeBrowserTestIOThreadHelper::SetRequestDestructionCallback(
412 const base::Closure
& callback
) {
413 CHECK(BrowserThread::CurrentlyOn(BrowserThread::IO
));
415 protocol_handler_
->SetRequestDestructionCallback(callback
);
418 void DnsProbeBrowserTestIOThreadHelper::StartDelayedProbes(
419 int expected_delayed_probe_count
) {
420 CHECK(BrowserThread::CurrentlyOn(BrowserThread::IO
));
422 CHECK(delaying_dns_probe_service_
);
424 int actual_delayed_probe_count
=
425 delaying_dns_probe_service_
->delayed_probe_count();
426 EXPECT_EQ(expected_delayed_probe_count
, actual_delayed_probe_count
);
428 delaying_dns_probe_service_
->StartDelayedProbes();
431 class DnsProbeBrowserTest
: public InProcessBrowserTest
{
433 DnsProbeBrowserTest();
434 virtual ~DnsProbeBrowserTest();
436 virtual void SetUpOnMainThread() OVERRIDE
;
437 virtual void CleanUpOnMainThread() OVERRIDE
;
440 // Sets the browser object that other methods apply to, and that has the
441 // DnsProbeStatus messages of its currently active tab monitored.
442 void SetActiveBrowser(Browser
* browser
);
444 void SetLinkDoctorBroken(bool broken
);
445 void SetLinkDoctorDelayRequests(bool delay_requests
);
446 void WaitForDelayedRequestDestruction();
447 void SetMockDnsClientRules(MockDnsClientRule::Result system_result
,
448 MockDnsClientRule::Result public_result
);
450 // These functions are often used to wait for two navigations because the Link
451 // Doctor loads two pages: a blank page, so the user stops seeing the previous
452 // page, and then either the Link Doctor page or a regular error page. Often
453 // need to wait for both to finish in a row.
454 void NavigateToDnsError(int num_navigations
);
455 void NavigateToOtherError(int num_navigations
);
457 void StartDelayedProbes(int expected_delayed_probe_count
);
458 DnsProbeStatus
WaitForSentStatus();
459 int pending_status_count() const { return dns_probe_status_queue_
.size(); }
462 bool PageContains(const std::string
& expected
);
465 void OnDnsProbeStatusSent(DnsProbeStatus dns_probe_status
);
467 DnsProbeBrowserTestIOThreadHelper
* helper_
;
469 // Browser that methods apply to.
470 Browser
* active_browser_
;
471 // Helper that current has its DnsProbeStatus messages monitored.
472 NetErrorTabHelper
* monitored_tab_helper_
;
474 bool awaiting_dns_probe_status_
;
475 // Queue of statuses received but not yet consumed by WaitForSentStatus().
476 std::list
<DnsProbeStatus
> dns_probe_status_queue_
;
479 DnsProbeBrowserTest::DnsProbeBrowserTest()
480 : helper_(new DnsProbeBrowserTestIOThreadHelper()),
481 active_browser_(NULL
),
482 monitored_tab_helper_(NULL
),
483 awaiting_dns_probe_status_(false) {
486 DnsProbeBrowserTest::~DnsProbeBrowserTest() {
487 // No tests should have any unconsumed probe statuses.
488 EXPECT_EQ(0, pending_status_count());
491 void DnsProbeBrowserTest::SetUpOnMainThread() {
492 NetErrorTabHelper::set_state_for_testing(
493 NetErrorTabHelper::TESTING_DEFAULT
);
495 browser()->profile()->GetPrefs()->SetBoolean(
496 prefs::kAlternateErrorPagesEnabled
, true);
498 BrowserThread::PostTask(
499 BrowserThread::IO
, FROM_HERE
,
500 Bind(&DnsProbeBrowserTestIOThreadHelper::SetUpOnIOThread
,
502 g_browser_process
->io_thread()));
504 SetActiveBrowser(browser());
507 void DnsProbeBrowserTest::CleanUpOnMainThread() {
508 BrowserThread::PostTask(
509 BrowserThread::IO
, FROM_HERE
,
510 Bind(&DnsProbeBrowserTestIOThreadHelper::CleanUpOnIOThreadAndDeleteHelper
,
511 Unretained(helper_
)));
513 NetErrorTabHelper::set_state_for_testing(
514 NetErrorTabHelper::TESTING_DEFAULT
);
517 void DnsProbeBrowserTest::SetActiveBrowser(Browser
* browser
) {
518 // If currently watching a NetErrorTabHelper, stop doing so before start
520 if (monitored_tab_helper_
) {
521 monitored_tab_helper_
->set_dns_probe_status_snoop_callback_for_testing(
522 NetErrorTabHelper::DnsProbeStatusSnoopCallback());
524 active_browser_
= browser
;
525 monitored_tab_helper_
= NetErrorTabHelper::FromWebContents(
526 active_browser_
->tab_strip_model()->GetActiveWebContents());
527 monitored_tab_helper_
->set_dns_probe_status_snoop_callback_for_testing(
528 Bind(&DnsProbeBrowserTest::OnDnsProbeStatusSent
, Unretained(this)));
531 void DnsProbeBrowserTest::SetLinkDoctorBroken(bool broken
) {
532 int net_error
= broken
? net::ERR_NAME_NOT_RESOLVED
: net::OK
;
534 BrowserThread::PostTask(
535 BrowserThread::IO
, FROM_HERE
,
536 Bind(&DnsProbeBrowserTestIOThreadHelper::SetLinkDoctorNetError
,
541 void DnsProbeBrowserTest::SetLinkDoctorDelayRequests(bool delay_requests
) {
542 BrowserThread::PostTask(
543 BrowserThread::IO
, FROM_HERE
,
544 Bind(&DnsProbeBrowserTestIOThreadHelper::SetLinkDoctorDelayRequests
,
549 void DnsProbeBrowserTest::WaitForDelayedRequestDestruction() {
550 base::RunLoop run_loop
;
551 BrowserThread::PostTask(
552 BrowserThread::IO
, FROM_HERE
,
553 Bind(&DnsProbeBrowserTestIOThreadHelper::SetRequestDestructionCallback
,
555 base::Bind(&RunClosureOnUIThread
,
556 run_loop
.QuitClosure())));
560 void DnsProbeBrowserTest::NavigateToDnsError(int num_navigations
) {
561 NavigateToURLBlockUntilNavigationsComplete(
563 URLRequestFailedJob::GetMockHttpUrl(net::ERR_NAME_NOT_RESOLVED
),
567 void DnsProbeBrowserTest::NavigateToOtherError(int num_navigations
) {
568 NavigateToURLBlockUntilNavigationsComplete(
570 URLRequestFailedJob::GetMockHttpUrl(net::ERR_CONNECTION_REFUSED
),
574 void DnsProbeBrowserTest::SetMockDnsClientRules(
575 MockDnsClientRule::Result system_result
,
576 MockDnsClientRule::Result public_result
) {
577 BrowserThread::PostTask(
578 BrowserThread::IO
, FROM_HERE
,
579 Bind(&DnsProbeBrowserTestIOThreadHelper::SetMockDnsClientRules
,
585 void DnsProbeBrowserTest::StartDelayedProbes(
586 int expected_delayed_probe_count
) {
587 BrowserThread::PostTask(
588 BrowserThread::IO
, FROM_HERE
,
589 Bind(&DnsProbeBrowserTestIOThreadHelper::StartDelayedProbes
,
591 expected_delayed_probe_count
));
594 DnsProbeStatus
DnsProbeBrowserTest::WaitForSentStatus() {
595 CHECK(!awaiting_dns_probe_status_
);
596 while (dns_probe_status_queue_
.empty()) {
597 awaiting_dns_probe_status_
= true;
598 MessageLoop::current()->Run();
599 awaiting_dns_probe_status_
= false;
602 CHECK(!dns_probe_status_queue_
.empty());
603 DnsProbeStatus status
= dns_probe_status_queue_
.front();
604 dns_probe_status_queue_
.pop_front();
608 // Check title by roundtripping to renderer, to make sure any probe results
609 // sent before this have been applied.
610 std::string
DnsProbeBrowserTest::Title() {
613 WebContents
* contents
=
614 active_browser_
->tab_strip_model()->GetActiveWebContents();
616 bool rv
= content::ExecuteScriptAndExtractString(
618 "domAutomationController.send(document.title);",
626 // Check text by roundtripping to renderer, to make sure any probe results
627 // sent before this have been applied.
628 bool DnsProbeBrowserTest::PageContains(const std::string
& expected
) {
629 std::string text_content
;
631 bool rv
= content::ExecuteScriptAndExtractString(
632 active_browser_
->tab_strip_model()->GetActiveWebContents(),
633 "domAutomationController.send(document.body.textContent);",
638 return text_content
.find(expected
) != std::string::npos
;
641 void DnsProbeBrowserTest::OnDnsProbeStatusSent(
642 DnsProbeStatus dns_probe_status
) {
643 dns_probe_status_queue_
.push_back(dns_probe_status
);
644 if (awaiting_dns_probe_status_
)
645 MessageLoop::current()->Quit();
648 // Make sure probes don't break non-DNS error pages when Link Doctor loads.
649 IN_PROC_BROWSER_TEST_F(DnsProbeBrowserTest
, OtherErrorWithWorkingLinkDoctor
) {
650 SetLinkDoctorBroken(false);
652 NavigateToOtherError(2);
653 EXPECT_EQ("Mock Link Doctor", Title());
656 // Make sure probes don't break non-DNS error pages when Link Doctor doesn't
658 IN_PROC_BROWSER_TEST_F(DnsProbeBrowserTest
, OtherErrorWithBrokenLinkDoctor
) {
659 SetLinkDoctorBroken(true);
661 NavigateToOtherError(2);
662 EXPECT_TRUE(PageContains("CONNECTION_REFUSED"));
665 // Make sure probes don't break DNS error pages when Link doctor loads.
666 IN_PROC_BROWSER_TEST_F(DnsProbeBrowserTest
,
667 NxdomainProbeResultWithWorkingLinkDoctor
) {
668 SetLinkDoctorBroken(false);
669 SetMockDnsClientRules(MockDnsClientRule::OK
, MockDnsClientRule::OK
);
671 NavigateToDnsError(2);
672 EXPECT_EQ("Mock Link Doctor", Title());
674 // One status for committing a blank page before the Link Doctor, and one for
675 // when the Link Doctor is committed.
676 EXPECT_EQ(chrome_common_net::DNS_PROBE_STARTED
, WaitForSentStatus());
677 EXPECT_EQ(chrome_common_net::DNS_PROBE_STARTED
, WaitForSentStatus());
678 EXPECT_EQ(0, pending_status_count());
679 EXPECT_EQ("Mock Link Doctor", Title());
681 StartDelayedProbes(1);
683 EXPECT_EQ(chrome_common_net::DNS_PROBE_FINISHED_NXDOMAIN
,
684 WaitForSentStatus());
685 EXPECT_EQ(0, pending_status_count());
686 EXPECT_EQ("Mock Link Doctor", Title());
689 // Make sure probes don't break Link Doctor when probes complete before the
690 // Link Doctor loads.
691 IN_PROC_BROWSER_TEST_F(DnsProbeBrowserTest
,
692 NxdomainProbeResultWithWorkingSlowLinkDoctor
) {
693 SetLinkDoctorBroken(false);
694 SetLinkDoctorDelayRequests(true);
695 SetMockDnsClientRules(MockDnsClientRule::OK
, MockDnsClientRule::OK
);
697 NavigateToDnsError(1);
698 // A blank page should be displayed while the Link Doctor page loads.
699 EXPECT_EQ("", Title());
701 // A single probe should be triggered by the error page load, and it should
703 EXPECT_EQ(chrome_common_net::DNS_PROBE_STARTED
, WaitForSentStatus());
704 EXPECT_EQ(0, pending_status_count());
705 EXPECT_EQ("", Title());
707 StartDelayedProbes(1);
708 EXPECT_EQ(chrome_common_net::DNS_PROBE_FINISHED_NXDOMAIN
,
709 WaitForSentStatus());
710 EXPECT_EQ(0, pending_status_count());
711 EXPECT_EQ("", Title());
713 content::TestNavigationObserver
observer(
714 browser()->tab_strip_model()->GetActiveWebContents(), 1);
715 // The Link Doctor page finishes loading.
716 SetLinkDoctorDelayRequests(false);
717 // Wait for it to commit.
719 EXPECT_EQ("Mock Link Doctor", Title());
721 // Committing the Link Doctor page should trigger sending the probe result
723 EXPECT_EQ(chrome_common_net::DNS_PROBE_FINISHED_NXDOMAIN
,
724 WaitForSentStatus());
725 EXPECT_EQ("Mock Link Doctor", Title());
728 // Make sure probes update DNS error page properly when they're supposed to.
729 IN_PROC_BROWSER_TEST_F(DnsProbeBrowserTest
,
730 NoInternetProbeResultWithBrokenLinkDoctor
) {
731 SetLinkDoctorBroken(true);
732 SetMockDnsClientRules(MockDnsClientRule::TIMEOUT
,
733 MockDnsClientRule::TIMEOUT
);
735 NavigateToDnsError(2);
737 EXPECT_EQ(chrome_common_net::DNS_PROBE_STARTED
, WaitForSentStatus());
738 EXPECT_EQ(chrome_common_net::DNS_PROBE_STARTED
, WaitForSentStatus());
740 // PageContains runs the RunLoop, so make sure nothing hairy happens.
741 EXPECT_EQ(0, pending_status_count());
742 EXPECT_TRUE(PageContains("DNS_PROBE_STARTED"));
743 EXPECT_EQ(0, pending_status_count());
745 StartDelayedProbes(1);
747 EXPECT_EQ(chrome_common_net::DNS_PROBE_FINISHED_NO_INTERNET
,
748 WaitForSentStatus());
750 // PageContains runs the RunLoop, so make sure nothing hairy happens.
751 EXPECT_EQ(0, pending_status_count());
752 EXPECT_TRUE(PageContains("DNS_PROBE_FINISHED_NO_INTERNET"));
755 // Make sure probes don't break Link Doctor when probes complete before the
756 // Link Doctor request returns an error.
757 IN_PROC_BROWSER_TEST_F(DnsProbeBrowserTest
,
758 NoInternetProbeResultWithSlowBrokenLinkDoctor
) {
759 SetLinkDoctorBroken(true);
760 SetLinkDoctorDelayRequests(true);
761 SetMockDnsClientRules(MockDnsClientRule::TIMEOUT
,
762 MockDnsClientRule::TIMEOUT
);
764 NavigateToDnsError(1);
765 // A blank page should be displayed while the Link Doctor page loads.
766 EXPECT_EQ("", Title());
768 // A single probe should be triggered by the error page load, and it should
770 EXPECT_EQ(chrome_common_net::DNS_PROBE_STARTED
, WaitForSentStatus());
771 EXPECT_EQ(0, pending_status_count());
772 EXPECT_EQ("", Title());
774 StartDelayedProbes(1);
775 EXPECT_EQ(chrome_common_net::DNS_PROBE_FINISHED_NO_INTERNET
,
776 WaitForSentStatus());
777 EXPECT_EQ("", Title());
778 EXPECT_EQ(0, pending_status_count());
780 content::TestNavigationObserver
observer(
781 browser()->tab_strip_model()->GetActiveWebContents(), 1);
782 // The Link Doctor request fails.
783 SetLinkDoctorDelayRequests(false);
784 // Wait for the DNS error page to load instead.
786 // The page committing should result in sending the probe results again.
787 EXPECT_EQ(chrome_common_net::DNS_PROBE_FINISHED_NO_INTERNET
,
788 WaitForSentStatus());
790 EXPECT_EQ(0, pending_status_count());
791 EXPECT_TRUE(PageContains("DNS_PROBE_FINISHED_NO_INTERNET"));
794 // Double-check to make sure sync failures don't explode.
795 IN_PROC_BROWSER_TEST_F(DnsProbeBrowserTest
, SyncFailureWithBrokenLinkDoctor
) {
796 SetLinkDoctorBroken(true);
797 SetMockDnsClientRules(MockDnsClientRule::FAIL
, MockDnsClientRule::FAIL
);
799 NavigateToDnsError(2);
801 EXPECT_EQ(chrome_common_net::DNS_PROBE_STARTED
, WaitForSentStatus());
802 EXPECT_EQ(chrome_common_net::DNS_PROBE_STARTED
, WaitForSentStatus());
804 // PageContains runs the RunLoop, so make sure nothing hairy happens.
805 EXPECT_EQ(0, pending_status_count());
806 EXPECT_TRUE(PageContains("DNS_PROBE_STARTED"));
807 EXPECT_EQ(0, pending_status_count());
809 StartDelayedProbes(1);
811 EXPECT_EQ(chrome_common_net::DNS_PROBE_FINISHED_INCONCLUSIVE
,
812 WaitForSentStatus());
814 // PageContains runs the RunLoop, so make sure nothing hairy happens.
815 EXPECT_EQ(0, pending_status_count());
816 EXPECT_TRUE(PageContains("NAME_NOT_RESOLVED"));
817 EXPECT_EQ(0, pending_status_count());
820 // Test that pressing the stop button cancels loading the Link Doctor page.
821 // TODO(mmenke): Add a test for the cross process navigation case.
822 // TODO(mmenke): This test could flakily pass due to the timeout on downloading
823 // the Link Doctor page. Disable that timeout for browser tests.
824 IN_PROC_BROWSER_TEST_F(DnsProbeBrowserTest
, LinkDoctorLoadStopped
) {
825 SetLinkDoctorDelayRequests(true);
826 SetLinkDoctorBroken(true);
827 SetMockDnsClientRules(MockDnsClientRule::TIMEOUT
, MockDnsClientRule::TIMEOUT
);
829 NavigateToDnsError(1);
831 EXPECT_EQ(chrome_common_net::DNS_PROBE_STARTED
, WaitForSentStatus());
832 StartDelayedProbes(1);
833 EXPECT_EQ(chrome_common_net::DNS_PROBE_FINISHED_NO_INTERNET
,
834 WaitForSentStatus());
836 EXPECT_EQ("", Title());
837 EXPECT_EQ(0, pending_status_count());
839 chrome::Stop(browser());
840 WaitForDelayedRequestDestruction();
842 // End up displaying a blank page.
843 EXPECT_EQ("", Title());
846 // Test that pressing the stop button cancels the load of the Link Doctor error
847 // page, and receiving a probe result afterwards does not swap in a DNS error
849 IN_PROC_BROWSER_TEST_F(DnsProbeBrowserTest
, LinkDoctorLoadStoppedSlowProbe
) {
850 SetLinkDoctorDelayRequests(true);
851 SetLinkDoctorBroken(true);
852 SetMockDnsClientRules(MockDnsClientRule::TIMEOUT
, MockDnsClientRule::TIMEOUT
);
854 NavigateToDnsError(1);
856 EXPECT_EQ(chrome_common_net::DNS_PROBE_STARTED
, WaitForSentStatus());
858 EXPECT_EQ("", Title());
859 EXPECT_EQ(0, pending_status_count());
861 chrome::Stop(browser());
862 WaitForDelayedRequestDestruction();
864 EXPECT_EQ("", Title());
865 EXPECT_EQ(0, pending_status_count());
867 StartDelayedProbes(1);
868 EXPECT_EQ(chrome_common_net::DNS_PROBE_FINISHED_NO_INTERNET
,
869 WaitForSentStatus());
871 EXPECT_EQ("", Title());
874 // Make sure probes don't run for subframe DNS errors.
875 IN_PROC_BROWSER_TEST_F(DnsProbeBrowserTest
, NoProbeInSubframe
) {
876 SetLinkDoctorBroken(false);
878 const FilePath::CharType kIframeDnsErrorHtmlName
[] =
879 FILE_PATH_LITERAL("iframe_dns_error.html");
883 URLRequestMockHTTPJob::GetMockUrl(FilePath(kIframeDnsErrorHtmlName
)));
885 // By the time NavigateToURL returns, the browser will have seen the failed
886 // provisional load. If a probe was started (or considered but not run),
887 // then the NetErrorTabHelper would have sent a NetErrorInfo message. Thus,
888 // if one hasn't been sent by now, the NetErrorTabHelper has not (and won't)
889 // start a probe for this DNS error.
890 EXPECT_EQ(0, pending_status_count());
893 // Make sure browser sends NOT_RUN properly when probes are disabled.
894 IN_PROC_BROWSER_TEST_F(DnsProbeBrowserTest
, ProbesDisabled
) {
895 // Disable probes (And Link Doctor).
896 browser()->profile()->GetPrefs()->SetBoolean(
897 prefs::kAlternateErrorPagesEnabled
, false);
899 SetLinkDoctorBroken(true);
900 SetMockDnsClientRules(MockDnsClientRule::TIMEOUT
, MockDnsClientRule::TIMEOUT
);
902 NavigateToDnsError(1);
904 EXPECT_EQ(chrome_common_net::DNS_PROBE_NOT_RUN
, WaitForSentStatus());
906 // PageContains runs the RunLoop, so make sure nothing hairy happens.
907 EXPECT_EQ(0, pending_status_count());
908 EXPECT_TRUE(PageContains("NAME_NOT_RESOLVED"));
911 // Test the case that Link Doctor is disabled, but DNS probes are enabled. This
912 // is the case with Chromium builds.
913 IN_PROC_BROWSER_TEST_F(DnsProbeBrowserTest
, LinkDoctorDisabled
) {
914 // Disable Link Doctor.
915 browser()->profile()->GetPrefs()->SetBoolean(
916 prefs::kAlternateErrorPagesEnabled
, false);
917 // Requests to the Link Doctor should work if any are made, so the test fails
918 // if that happens unexpectedly.
919 SetLinkDoctorBroken(false);
920 // Normally disabling the LinkDoctor disables DNS probes, so force DNS probes
922 NetErrorTabHelper::set_state_for_testing(
923 NetErrorTabHelper::TESTING_FORCE_ENABLED
);
925 SetMockDnsClientRules(MockDnsClientRule::FAIL
, MockDnsClientRule::FAIL
);
927 // Just one commit and one sent status, since the Link Doctor is disabled.
928 NavigateToDnsError(1);
929 EXPECT_EQ(chrome_common_net::DNS_PROBE_STARTED
, WaitForSentStatus());
931 // PageContains runs the RunLoop, so make sure nothing hairy happens.
932 EXPECT_EQ(0, pending_status_count());
933 EXPECT_TRUE(PageContains("DNS_PROBE_STARTED"));
934 EXPECT_EQ(0, pending_status_count());
936 StartDelayedProbes(1);
938 EXPECT_EQ(chrome_common_net::DNS_PROBE_FINISHED_INCONCLUSIVE
,
939 WaitForSentStatus());
940 EXPECT_EQ(0, pending_status_count());
941 EXPECT_TRUE(PageContains("NAME_NOT_RESOLVED"));
944 // Test incognito mode. Link Doctor should be disabled, but DNS probes are
946 IN_PROC_BROWSER_TEST_F(DnsProbeBrowserTest
, Incognito
) {
947 // Requests to the Link Doctor should work if any are made, so the test will
948 // fail if one is requested unexpectedly.
949 SetLinkDoctorBroken(false);
951 Browser
* incognito
= CreateIncognitoBrowser();
952 SetActiveBrowser(incognito
);
954 SetMockDnsClientRules(MockDnsClientRule::FAIL
, MockDnsClientRule::FAIL
);
956 // Just one commit and one sent status, since the Link Doctor is disabled.
957 NavigateToDnsError(1);
958 EXPECT_EQ(chrome_common_net::DNS_PROBE_STARTED
, WaitForSentStatus());
960 // PageContains runs the RunLoop, so make sure nothing hairy happens.
961 EXPECT_EQ(0, pending_status_count());
962 EXPECT_TRUE(PageContains("DNS_PROBE_STARTED"));
963 EXPECT_EQ(0, pending_status_count());
965 StartDelayedProbes(1);
967 EXPECT_EQ(chrome_common_net::DNS_PROBE_FINISHED_INCONCLUSIVE
,
968 WaitForSentStatus());
969 EXPECT_EQ(0, pending_status_count());
970 EXPECT_TRUE(PageContains("NAME_NOT_RESOLVED"));
975 } // namespace chrome_browser_net