Adding instrumentation to locate the source of jankiness.
[chromium-blink-merge.git] / chrome / browser / net / dns_probe_browsertest.cc
blob5363f67938c435ddeefa84d04879be59ee29670e
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.
5 #include <set>
7 #include "base/bind.h"
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/io_thread.h"
16 #include "chrome/browser/net/dns_probe_test_util.h"
17 #include "chrome/browser/net/net_error_tab_helper.h"
18 #include "chrome/browser/net/url_request_mock_util.h"
19 #include "chrome/browser/profiles/profile.h"
20 #include "chrome/browser/ui/browser.h"
21 #include "chrome/browser/ui/browser_commands.h"
22 #include "chrome/browser/ui/tabs/tab_strip_model.h"
23 #include "chrome/common/chrome_paths.h"
24 #include "chrome/common/pref_names.h"
25 #include "chrome/test/base/in_process_browser_test.h"
26 #include "chrome/test/base/ui_test_utils.h"
27 #include "components/error_page/common/net_error_info.h"
28 #include "components/google/core/browser/google_util.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 "net/base/net_errors.h"
34 #include "net/dns/dns_test_util.h"
35 #include "net/test/url_request/url_request_failed_job.h"
36 #include "net/test/url_request/url_request_mock_http_job.h"
37 #include "net/url_request/url_request_filter.h"
38 #include "net/url_request/url_request_interceptor.h"
39 #include "net/url_request/url_request_job.h"
41 using base::Bind;
42 using base::Callback;
43 using base::Closure;
44 using base::ConstRef;
45 using base::FilePath;
46 using base::MessageLoop;
47 using base::Unretained;
48 using chrome_common_net::DnsProbeStatus;
49 using content::BrowserThread;
50 using net::URLRequestFailedJob;
51 using net::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::URLRequestInterceptor;
59 using net::URLRequestJob;
60 using ui_test_utils::NavigateToURL;
61 using ui_test_utils::NavigateToURLBlockUntilNavigationsComplete;
63 namespace chrome_browser_net {
65 namespace {
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
69 // another thread.
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 {
78 public:
79 DelayingDnsProbeService() {}
81 ~DelayingDnsProbeService() override { EXPECT_TRUE(delayed_probes_.empty()); }
83 void ProbeDns(const ProbeCallback& callback) override {
84 delayed_probes_.push_back(callback);
87 void StartDelayedProbes() {
88 CHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
90 std::vector<ProbeCallback> probes;
91 probes.swap(delayed_probes_);
93 for (std::vector<ProbeCallback>::const_iterator i = probes.begin();
94 i != probes.end(); ++i) {
95 DnsProbeService::ProbeDns(*i);
99 int delayed_probe_count() const {
100 CHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
101 return delayed_probes_.size();
104 private:
105 std::vector<ProbeCallback> delayed_probes_;
108 FilePath GetMockLinkDoctorFilePath() {
109 FilePath root_http;
110 PathService::Get(chrome::DIR_TEST_DATA, &root_http);
111 return root_http.AppendASCII("mock-link-doctor.json");
114 // A request that can be delayed until Resume() is called. Can also run a
115 // callback if destroyed without being resumed. Resume can be called either
116 // before or after a the request is started.
117 class DelayableRequest {
118 public:
119 // Called by a DelayableRequest if it was set to be delayed, and has been
120 // destroyed without Undelay being called.
121 typedef base::Callback<void(DelayableRequest* request)> DestructionCallback;
123 virtual void Resume() = 0;
125 protected:
126 virtual ~DelayableRequest() {}
129 class DelayableURLRequestFailedJob : public URLRequestFailedJob,
130 public DelayableRequest {
131 public:
132 // |destruction_callback| is only called if a delayed request is destroyed
133 // without being resumed.
134 DelayableURLRequestFailedJob(net::URLRequest* request,
135 net::NetworkDelegate* network_delegate,
136 int net_error,
137 bool should_delay,
138 const DestructionCallback& destruction_callback)
139 : URLRequestFailedJob(request, network_delegate, net_error),
140 should_delay_(should_delay),
141 start_delayed_(false),
142 destruction_callback_(destruction_callback) {}
144 void Start() override {
145 if (should_delay_) {
146 DCHECK(!start_delayed_);
147 start_delayed_ = true;
148 return;
150 URLRequestFailedJob::Start();
153 void Resume() override {
154 DCHECK(should_delay_);
155 should_delay_ = false;
156 if (start_delayed_) {
157 start_delayed_ = false;
158 Start();
162 private:
163 ~DelayableURLRequestFailedJob() override {
164 if (should_delay_)
165 destruction_callback_.Run(this);
168 bool should_delay_;
169 bool start_delayed_;
170 const DestructionCallback destruction_callback_;
173 class DelayableURLRequestMockHTTPJob : public URLRequestMockHTTPJob,
174 public DelayableRequest {
175 public:
176 DelayableURLRequestMockHTTPJob(
177 net::URLRequest* request,
178 net::NetworkDelegate* network_delegate,
179 const base::FilePath& file_path,
180 bool should_delay,
181 const DestructionCallback& destruction_callback)
182 : URLRequestMockHTTPJob(
183 request,
184 network_delegate,
185 file_path,
186 BrowserThread::GetBlockingPool()->GetTaskRunnerWithShutdownBehavior(
187 base::SequencedWorkerPool::SKIP_ON_SHUTDOWN)),
188 should_delay_(should_delay),
189 start_delayed_(false),
190 destruction_callback_(destruction_callback) {}
192 void Start() override {
193 if (should_delay_) {
194 DCHECK(!start_delayed_);
195 start_delayed_ = true;
196 return;
198 URLRequestMockHTTPJob::Start();
201 void Resume() override {
202 DCHECK(should_delay_);
203 should_delay_ = false;
204 if (start_delayed_) {
205 start_delayed_ = false;
206 Start();
210 private:
211 ~DelayableURLRequestMockHTTPJob() override {
212 if (should_delay_)
213 destruction_callback_.Run(this);
216 bool should_delay_;
217 bool start_delayed_;
218 const DestructionCallback destruction_callback_;
221 // Interceptor for navigation correction requests. Can cause requests to
222 // fail with an error, and/or delay a request until a test allows to continue.
223 // Also can run a callback when a delayed request is cancelled.
224 class BreakableCorrectionInterceptor : public URLRequestInterceptor {
225 public:
226 explicit BreakableCorrectionInterceptor(
227 const FilePath& mock_corrections_file_path)
228 : mock_corrections_file_path_(mock_corrections_file_path),
229 net_error_(net::OK),
230 delay_requests_(false),
231 on_request_destroyed_callback_(
232 base::Bind(&BreakableCorrectionInterceptor::OnRequestDestroyed,
233 base::Unretained(this))) {
236 ~BreakableCorrectionInterceptor() override {
237 // All delayed requests should have been resumed or cancelled by this point.
238 EXPECT_TRUE(delayed_requests_.empty());
241 URLRequestJob* MaybeInterceptRequest(
242 URLRequest* request,
243 NetworkDelegate* network_delegate) const override {
244 if (net_error_ != net::OK) {
245 DelayableURLRequestFailedJob* job =
246 new DelayableURLRequestFailedJob(
247 request, network_delegate, net_error_, delay_requests_,
248 on_request_destroyed_callback_);
249 if (delay_requests_)
250 delayed_requests_.insert(job);
251 return job;
252 } else {
253 DelayableURLRequestMockHTTPJob* job =
254 new DelayableURLRequestMockHTTPJob(
255 request, network_delegate, mock_corrections_file_path_,
256 delay_requests_, on_request_destroyed_callback_);
257 if (delay_requests_)
258 delayed_requests_.insert(job);
259 return job;
263 void set_net_error(int net_error) { net_error_ = net_error; }
265 void SetDelayRequests(bool delay_requests) {
266 delay_requests_ = delay_requests;
268 // Resume all delayed requests if no longer delaying requests.
269 if (!delay_requests) {
270 while (!delayed_requests_.empty()) {
271 DelayableRequest* request = *delayed_requests_.begin();
272 delayed_requests_.erase(request);
273 request->Resume();
278 // Runs |callback| once all delayed requests have been destroyed. Does not
279 // wait for delayed requests that have been resumed.
280 void SetRequestDestructionCallback(const base::Closure& callback) {
281 ASSERT_TRUE(delayed_request_destruction_callback_.is_null());
282 if (delayed_requests_.empty()) {
283 callback.Run();
284 return;
286 delayed_request_destruction_callback_ = callback;
289 void OnRequestDestroyed(DelayableRequest* request) {
290 ASSERT_EQ(1u, delayed_requests_.count(request));
291 delayed_requests_.erase(request);
292 if (delayed_requests_.empty() &&
293 !delayed_request_destruction_callback_.is_null()) {
294 delayed_request_destruction_callback_.Run();
295 delayed_request_destruction_callback_.Reset();
299 private:
300 const FilePath mock_corrections_file_path_;
301 int net_error_;
302 bool delay_requests_;
304 // Called when a request is destroyed. Memeber variable because
305 // MaybeCreateJob is "const", so calling base::Bind in that function does
306 // not work well.
307 const DelayableRequest::DestructionCallback on_request_destroyed_callback_;
309 // Mutable is needed because MaybeCreateJob is const.
310 mutable std::set<DelayableRequest*> delayed_requests_;
312 base::Closure delayed_request_destruction_callback_;
315 class DnsProbeBrowserTestIOThreadHelper {
316 public:
317 DnsProbeBrowserTestIOThreadHelper();
319 void SetUpOnIOThread(IOThread* io_thread);
320 void CleanUpOnIOThreadAndDeleteHelper();
322 void SetMockDnsClientRules(MockDnsClientRule::Result system_good_result,
323 MockDnsClientRule::Result public_good_result);
324 void SetCorrectionServiceNetError(int net_error);
325 void SetCorrectionServiceDelayRequests(bool delay_requests);
326 void SetRequestDestructionCallback(const base::Closure& callback);
327 void StartDelayedProbes(int expected_delayed_probe_count);
329 private:
330 IOThread* io_thread_;
331 DnsProbeService* original_dns_probe_service_;
332 DelayingDnsProbeService* delaying_dns_probe_service_;
333 BreakableCorrectionInterceptor* interceptor_;
334 FilePath mock_corrections_file_path_;
337 DnsProbeBrowserTestIOThreadHelper::DnsProbeBrowserTestIOThreadHelper()
338 : io_thread_(NULL),
339 original_dns_probe_service_(NULL),
340 delaying_dns_probe_service_(NULL),
341 interceptor_(NULL),
342 mock_corrections_file_path_(GetMockLinkDoctorFilePath()) {}
344 void DnsProbeBrowserTestIOThreadHelper::SetUpOnIOThread(IOThread* io_thread) {
345 CHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
346 CHECK(io_thread);
347 CHECK(!io_thread_);
348 CHECK(!original_dns_probe_service_);
349 CHECK(!delaying_dns_probe_service_);
350 CHECK(!interceptor_);
352 io_thread_ = io_thread;
354 delaying_dns_probe_service_ = new DelayingDnsProbeService();
356 IOThread::Globals* globals = io_thread_->globals();
357 original_dns_probe_service_ = globals->dns_probe_service.release();
358 globals->dns_probe_service.reset(delaying_dns_probe_service_);
360 URLRequestFailedJob::AddUrlHandler();
362 interceptor_ =
363 new BreakableCorrectionInterceptor(mock_corrections_file_path_);
364 URLRequestFilter::GetInstance()->AddUrlInterceptor(
365 LinkDoctorBaseURL(), scoped_ptr<URLRequestInterceptor>(interceptor_));
368 void DnsProbeBrowserTestIOThreadHelper::CleanUpOnIOThreadAndDeleteHelper() {
369 CHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
371 URLRequestFilter::GetInstance()->ClearHandlers();
373 IOThread::Globals* globals = io_thread_->globals();
374 scoped_ptr<DnsProbeService> delaying_dns_probe_service(
375 globals->dns_probe_service.release());
376 globals->dns_probe_service.reset(original_dns_probe_service_);
378 CHECK_EQ(delaying_dns_probe_service_, delaying_dns_probe_service.get());
380 delete this;
383 void DnsProbeBrowserTestIOThreadHelper::SetMockDnsClientRules(
384 MockDnsClientRule::Result system_result,
385 MockDnsClientRule::Result public_result) {
386 CHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
388 DnsProbeService* service = io_thread_->globals()->dns_probe_service.get();
389 service->SetSystemClientForTesting(
390 CreateMockDnsClientForProbes(system_result));
391 service->SetPublicClientForTesting(
392 CreateMockDnsClientForProbes(public_result));
395 void DnsProbeBrowserTestIOThreadHelper::SetCorrectionServiceNetError(
396 int net_error) {
397 CHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
399 interceptor_->set_net_error(net_error);
402 void DnsProbeBrowserTestIOThreadHelper::SetCorrectionServiceDelayRequests(
403 bool delay_requests) {
404 CHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
406 interceptor_->SetDelayRequests(delay_requests);
409 void DnsProbeBrowserTestIOThreadHelper::SetRequestDestructionCallback(
410 const base::Closure& callback) {
411 CHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
413 interceptor_->SetRequestDestructionCallback(callback);
416 void DnsProbeBrowserTestIOThreadHelper::StartDelayedProbes(
417 int expected_delayed_probe_count) {
418 CHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
420 CHECK(delaying_dns_probe_service_);
422 int actual_delayed_probe_count =
423 delaying_dns_probe_service_->delayed_probe_count();
424 EXPECT_EQ(expected_delayed_probe_count, actual_delayed_probe_count);
426 delaying_dns_probe_service_->StartDelayedProbes();
429 class DnsProbeBrowserTest : public InProcessBrowserTest {
430 public:
431 DnsProbeBrowserTest();
432 ~DnsProbeBrowserTest() override;
434 void SetUpOnMainThread() override;
435 void TearDownOnMainThread() override;
437 protected:
438 // Sets the browser object that other methods apply to, and that has the
439 // DnsProbeStatus messages of its currently active tab monitored.
440 void SetActiveBrowser(Browser* browser);
442 void SetCorrectionServiceBroken(bool broken);
443 void SetCorrectionServiceDelayRequests(bool delay_requests);
444 void WaitForDelayedRequestDestruction();
445 void SetMockDnsClientRules(MockDnsClientRule::Result system_result,
446 MockDnsClientRule::Result public_result);
448 // These functions are often used to wait for two navigations because two
449 // pages are loaded when navigation corrections are enabled: a blank page, so
450 // the user stops seeing the previous page, and then the error page, either
451 // with navigation corrections or without them (If the request failed).
452 void NavigateToDnsError(int num_navigations);
453 void NavigateToOtherError(int num_navigations);
455 void StartDelayedProbes(int expected_delayed_probe_count);
456 DnsProbeStatus WaitForSentStatus();
457 int pending_status_count() const { return dns_probe_status_queue_.size(); }
459 std::string Title();
460 bool PageContains(const std::string& expected);
462 // Checks that the local error page is being displayed, without navigation
463 // corrections, and with the specified status text. The status text should be
464 // either a network error or DNS probe status.
465 void ExpectDisplayingLocalErrorPage(const std::string& status_text);
467 // Checks that an error page with mock navigation corrections is being
468 // displayed, with the specified status text. The status text should be either
469 // a network error or DNS probe status.
470 void ExpectDisplayingCorrections(const std::string& status_text);
472 private:
473 void OnDnsProbeStatusSent(DnsProbeStatus dns_probe_status);
475 DnsProbeBrowserTestIOThreadHelper* helper_;
477 // Browser that methods apply to.
478 Browser* active_browser_;
479 // Helper that current has its DnsProbeStatus messages monitored.
480 NetErrorTabHelper* monitored_tab_helper_;
482 bool awaiting_dns_probe_status_;
483 // Queue of statuses received but not yet consumed by WaitForSentStatus().
484 std::list<DnsProbeStatus> dns_probe_status_queue_;
487 DnsProbeBrowserTest::DnsProbeBrowserTest()
488 : helper_(new DnsProbeBrowserTestIOThreadHelper()),
489 active_browser_(NULL),
490 monitored_tab_helper_(NULL),
491 awaiting_dns_probe_status_(false) {
494 DnsProbeBrowserTest::~DnsProbeBrowserTest() {
495 // No tests should have any unconsumed probe statuses.
496 EXPECT_EQ(0, pending_status_count());
499 void DnsProbeBrowserTest::SetUpOnMainThread() {
500 NetErrorTabHelper::set_state_for_testing(
501 NetErrorTabHelper::TESTING_DEFAULT);
503 browser()->profile()->GetPrefs()->SetBoolean(
504 prefs::kAlternateErrorPagesEnabled, true);
506 BrowserThread::PostTask(
507 BrowserThread::IO, FROM_HERE,
508 Bind(&DnsProbeBrowserTestIOThreadHelper::SetUpOnIOThread,
509 Unretained(helper_),
510 g_browser_process->io_thread()));
512 SetActiveBrowser(browser());
515 void DnsProbeBrowserTest::TearDownOnMainThread() {
516 BrowserThread::PostTask(
517 BrowserThread::IO, FROM_HERE,
518 Bind(&DnsProbeBrowserTestIOThreadHelper::CleanUpOnIOThreadAndDeleteHelper,
519 Unretained(helper_)));
521 NetErrorTabHelper::set_state_for_testing(
522 NetErrorTabHelper::TESTING_DEFAULT);
525 void DnsProbeBrowserTest::SetActiveBrowser(Browser* browser) {
526 // If currently watching a NetErrorTabHelper, stop doing so before start
527 // watching another.
528 if (monitored_tab_helper_) {
529 monitored_tab_helper_->set_dns_probe_status_snoop_callback_for_testing(
530 NetErrorTabHelper::DnsProbeStatusSnoopCallback());
532 active_browser_ = browser;
533 monitored_tab_helper_ = NetErrorTabHelper::FromWebContents(
534 active_browser_->tab_strip_model()->GetActiveWebContents());
535 monitored_tab_helper_->set_dns_probe_status_snoop_callback_for_testing(
536 Bind(&DnsProbeBrowserTest::OnDnsProbeStatusSent, Unretained(this)));
539 void DnsProbeBrowserTest::SetCorrectionServiceBroken(bool broken) {
540 int net_error = broken ? net::ERR_NAME_NOT_RESOLVED : net::OK;
542 BrowserThread::PostTask(
543 BrowserThread::IO, FROM_HERE,
544 Bind(&DnsProbeBrowserTestIOThreadHelper::SetCorrectionServiceNetError,
545 Unretained(helper_),
546 net_error));
549 void DnsProbeBrowserTest::SetCorrectionServiceDelayRequests(
550 bool delay_requests) {
551 BrowserThread::PostTask(
552 BrowserThread::IO, FROM_HERE,
553 Bind(&DnsProbeBrowserTestIOThreadHelper::
554 SetCorrectionServiceDelayRequests,
555 Unretained(helper_),
556 delay_requests));
559 void DnsProbeBrowserTest::WaitForDelayedRequestDestruction() {
560 base::RunLoop run_loop;
561 BrowserThread::PostTask(
562 BrowserThread::IO, FROM_HERE,
563 Bind(&DnsProbeBrowserTestIOThreadHelper::SetRequestDestructionCallback,
564 Unretained(helper_),
565 base::Bind(&RunClosureOnUIThread,
566 run_loop.QuitClosure())));
567 run_loop.Run();
570 void DnsProbeBrowserTest::NavigateToDnsError(int num_navigations) {
571 NavigateToURLBlockUntilNavigationsComplete(
572 active_browser_,
573 URLRequestFailedJob::GetMockHttpUrl(net::ERR_NAME_NOT_RESOLVED),
574 num_navigations);
577 void DnsProbeBrowserTest::NavigateToOtherError(int num_navigations) {
578 NavigateToURLBlockUntilNavigationsComplete(
579 active_browser_,
580 URLRequestFailedJob::GetMockHttpUrl(net::ERR_CONNECTION_REFUSED),
581 num_navigations);
584 void DnsProbeBrowserTest::SetMockDnsClientRules(
585 MockDnsClientRule::Result system_result,
586 MockDnsClientRule::Result public_result) {
587 BrowserThread::PostTask(
588 BrowserThread::IO, FROM_HERE,
589 Bind(&DnsProbeBrowserTestIOThreadHelper::SetMockDnsClientRules,
590 Unretained(helper_),
591 system_result,
592 public_result));
595 void DnsProbeBrowserTest::StartDelayedProbes(
596 int expected_delayed_probe_count) {
597 BrowserThread::PostTask(
598 BrowserThread::IO, FROM_HERE,
599 Bind(&DnsProbeBrowserTestIOThreadHelper::StartDelayedProbes,
600 Unretained(helper_),
601 expected_delayed_probe_count));
604 DnsProbeStatus DnsProbeBrowserTest::WaitForSentStatus() {
605 CHECK(!awaiting_dns_probe_status_);
606 while (dns_probe_status_queue_.empty()) {
607 awaiting_dns_probe_status_ = true;
608 MessageLoop::current()->Run();
609 awaiting_dns_probe_status_ = false;
612 CHECK(!dns_probe_status_queue_.empty());
613 DnsProbeStatus status = dns_probe_status_queue_.front();
614 dns_probe_status_queue_.pop_front();
615 return status;
618 // Check title by roundtripping to renderer, to make sure any probe results
619 // sent before this have been applied.
620 std::string DnsProbeBrowserTest::Title() {
621 std::string title;
623 WebContents* contents =
624 active_browser_->tab_strip_model()->GetActiveWebContents();
626 bool rv = content::ExecuteScriptAndExtractString(
627 contents,
628 "domAutomationController.send(document.title);",
629 &title);
630 if (!rv)
631 return "";
633 return title;
636 // Check text by roundtripping to renderer, to make sure any probe results
637 // sent before this have been applied.
638 bool DnsProbeBrowserTest::PageContains(const std::string& expected) {
639 std::string text_content;
641 bool rv = content::ExecuteScriptAndExtractString(
642 active_browser_->tab_strip_model()->GetActiveWebContents(),
643 "domAutomationController.send(document.body.textContent);",
644 &text_content);
645 if (!rv)
646 return false;
648 return text_content.find(expected) != std::string::npos;
651 void DnsProbeBrowserTest::ExpectDisplayingLocalErrorPage(
652 const std::string& status_text) {
653 EXPECT_FALSE(PageContains("http://correction1/"));
654 EXPECT_FALSE(PageContains("http://correction2/"));
655 EXPECT_TRUE(PageContains(status_text));
658 void DnsProbeBrowserTest::ExpectDisplayingCorrections(
659 const std::string& status_text) {
660 EXPECT_TRUE(PageContains("http://correction1/"));
661 EXPECT_TRUE(PageContains("http://correction2/"));
662 EXPECT_TRUE(PageContains(status_text));
665 void DnsProbeBrowserTest::OnDnsProbeStatusSent(
666 DnsProbeStatus dns_probe_status) {
667 dns_probe_status_queue_.push_back(dns_probe_status);
668 if (awaiting_dns_probe_status_)
669 MessageLoop::current()->Quit();
672 // Make sure probes don't break non-DNS error pages when corrections load.
673 IN_PROC_BROWSER_TEST_F(DnsProbeBrowserTest, OtherErrorWithCorrectionsSuccess) {
674 SetCorrectionServiceBroken(false);
676 NavigateToOtherError(2);
677 ExpectDisplayingCorrections("ERR_CONNECTION_REFUSED");
680 // Make sure probes don't break non-DNS error pages when corrections failed to
681 // load.
682 IN_PROC_BROWSER_TEST_F(DnsProbeBrowserTest, OtherErrorWithCorrectionsFailure) {
683 SetCorrectionServiceBroken(true);
685 NavigateToOtherError(2);
686 ExpectDisplayingLocalErrorPage("ERR_CONNECTION_REFUSED");
689 // Make sure probes don't break DNS error pages when corrections load.
690 IN_PROC_BROWSER_TEST_F(DnsProbeBrowserTest,
691 NxdomainProbeResultWithWorkingCorrections) {
692 SetCorrectionServiceBroken(false);
693 SetMockDnsClientRules(MockDnsClientRule::OK, MockDnsClientRule::OK);
695 NavigateToDnsError(2);
696 ExpectDisplayingCorrections("ERR_NAME_NOT_RESOLVED");
698 // One status for committing a blank page before the corrections, and one for
699 // when the error page with corrections is committed.
700 EXPECT_EQ(chrome_common_net::DNS_PROBE_STARTED, WaitForSentStatus());
701 EXPECT_EQ(chrome_common_net::DNS_PROBE_STARTED, WaitForSentStatus());
702 EXPECT_EQ(0, pending_status_count());
703 ExpectDisplayingCorrections("ERR_NAME_NOT_RESOLVED");
705 StartDelayedProbes(1);
707 EXPECT_EQ(chrome_common_net::DNS_PROBE_FINISHED_NXDOMAIN,
708 WaitForSentStatus());
709 EXPECT_EQ(0, pending_status_count());
710 ExpectDisplayingCorrections("ERR_NAME_NOT_RESOLVED");
713 // Make sure probes don't break corrections when probes complete before the
714 // corrections load.
715 IN_PROC_BROWSER_TEST_F(DnsProbeBrowserTest,
716 NxdomainProbeResultWithWorkingSlowCorrections) {
717 SetCorrectionServiceBroken(false);
718 SetCorrectionServiceDelayRequests(true);
719 SetMockDnsClientRules(MockDnsClientRule::OK, MockDnsClientRule::OK);
721 NavigateToDnsError(1);
722 // A blank page should be displayed while the corrections are loaded.
723 EXPECT_EQ("", Title());
725 // A single probe should be triggered by the error page load, and it should
726 // be ignored.
727 EXPECT_EQ(chrome_common_net::DNS_PROBE_STARTED, WaitForSentStatus());
728 EXPECT_EQ(0, pending_status_count());
729 EXPECT_EQ("", Title());
731 StartDelayedProbes(1);
732 EXPECT_EQ(chrome_common_net::DNS_PROBE_FINISHED_NXDOMAIN,
733 WaitForSentStatus());
734 EXPECT_EQ(0, pending_status_count());
735 EXPECT_EQ("", Title());
737 content::TestNavigationObserver observer(
738 browser()->tab_strip_model()->GetActiveWebContents(), 1);
739 // The corrections finish loading.
740 SetCorrectionServiceDelayRequests(false);
741 // Wait for it to commit.
742 observer.Wait();
743 ExpectDisplayingCorrections("ERR_NAME_NOT_RESOLVED");
745 // Committing the corections page should trigger sending the probe result
746 // again.
747 EXPECT_EQ(chrome_common_net::DNS_PROBE_FINISHED_NXDOMAIN,
748 WaitForSentStatus());
749 ExpectDisplayingCorrections("ERR_NAME_NOT_RESOLVED");
752 // Make sure probes update DNS error page properly when they're supposed to.
753 IN_PROC_BROWSER_TEST_F(DnsProbeBrowserTest,
754 NoInternetProbeResultWithBrokenCorrections) {
755 SetCorrectionServiceBroken(true);
756 SetMockDnsClientRules(MockDnsClientRule::TIMEOUT,
757 MockDnsClientRule::TIMEOUT);
759 NavigateToDnsError(2);
761 EXPECT_EQ(chrome_common_net::DNS_PROBE_STARTED, WaitForSentStatus());
762 EXPECT_EQ(chrome_common_net::DNS_PROBE_STARTED, WaitForSentStatus());
764 // Checking the page runs the RunLoop, so make sure nothing hairy happens.
765 EXPECT_EQ(0, pending_status_count());
766 ExpectDisplayingLocalErrorPage("DNS_PROBE_STARTED");
767 EXPECT_EQ(0, pending_status_count());
769 StartDelayedProbes(1);
771 EXPECT_EQ(chrome_common_net::DNS_PROBE_FINISHED_NO_INTERNET,
772 WaitForSentStatus());
774 // Checking the page runs the RunLoop, so make sure nothing hairy happens.
775 EXPECT_EQ(0, pending_status_count());
776 ExpectDisplayingLocalErrorPage("DNS_PROBE_FINISHED_NO_INTERNET");
779 // Make sure probes don't break corrections when probes complete before the
780 // corrections request returns an error.
781 IN_PROC_BROWSER_TEST_F(DnsProbeBrowserTest,
782 NoInternetProbeResultWithSlowBrokenCorrections) {
783 SetCorrectionServiceBroken(true);
784 SetCorrectionServiceDelayRequests(true);
785 SetMockDnsClientRules(MockDnsClientRule::TIMEOUT,
786 MockDnsClientRule::TIMEOUT);
788 NavigateToDnsError(1);
789 // A blank page should be displayed while the corrections load.
790 EXPECT_EQ("", Title());
792 // A single probe should be triggered by the error page load, and it should
793 // be ignored.
794 EXPECT_EQ(chrome_common_net::DNS_PROBE_STARTED, WaitForSentStatus());
795 EXPECT_EQ(0, pending_status_count());
796 EXPECT_EQ("", Title());
798 StartDelayedProbes(1);
799 EXPECT_EQ(chrome_common_net::DNS_PROBE_FINISHED_NO_INTERNET,
800 WaitForSentStatus());
801 EXPECT_EQ("", Title());
802 EXPECT_EQ(0, pending_status_count());
804 content::TestNavigationObserver observer(
805 browser()->tab_strip_model()->GetActiveWebContents(), 1);
806 // The corrections request fails.
807 SetCorrectionServiceDelayRequests(false);
808 // Wait for the DNS error page to load instead.
809 observer.Wait();
810 // The page committing should result in sending the probe results again.
811 EXPECT_EQ(chrome_common_net::DNS_PROBE_FINISHED_NO_INTERNET,
812 WaitForSentStatus());
814 EXPECT_EQ(0, pending_status_count());
815 ExpectDisplayingLocalErrorPage("DNS_PROBE_FINISHED_NO_INTERNET");
818 // Double-check to make sure sync failures don't explode.
819 IN_PROC_BROWSER_TEST_F(DnsProbeBrowserTest, SyncFailureWithBrokenCorrections) {
820 SetCorrectionServiceBroken(true);
821 SetMockDnsClientRules(MockDnsClientRule::FAIL, MockDnsClientRule::FAIL);
823 NavigateToDnsError(2);
825 EXPECT_EQ(chrome_common_net::DNS_PROBE_STARTED, WaitForSentStatus());
826 EXPECT_EQ(chrome_common_net::DNS_PROBE_STARTED, WaitForSentStatus());
828 // Checking the page runs the RunLoop, so make sure nothing hairy happens.
829 EXPECT_EQ(0, pending_status_count());
830 ExpectDisplayingLocalErrorPage("DNS_PROBE_STARTED");
831 EXPECT_EQ(0, pending_status_count());
833 StartDelayedProbes(1);
835 EXPECT_EQ(chrome_common_net::DNS_PROBE_FINISHED_INCONCLUSIVE,
836 WaitForSentStatus());
838 // Checking the page runs the RunLoop, so make sure nothing hairy happens.
839 EXPECT_EQ(0, pending_status_count());
840 ExpectDisplayingLocalErrorPage("ERR_NAME_NOT_RESOLVED");
841 EXPECT_EQ(0, pending_status_count());
844 // Test that pressing the stop button cancels loading corrections.
845 // TODO(mmenke): Add a test for the cross process navigation case.
846 // TODO(mmenke): This test could flakily pass due to the timeout on downloading
847 // the corrections. Disable that timeout for browser tests.
848 IN_PROC_BROWSER_TEST_F(DnsProbeBrowserTest, CorrectionsLoadStopped) {
849 SetCorrectionServiceDelayRequests(true);
850 SetCorrectionServiceBroken(true);
851 SetMockDnsClientRules(MockDnsClientRule::TIMEOUT, MockDnsClientRule::TIMEOUT);
853 NavigateToDnsError(1);
855 EXPECT_EQ(chrome_common_net::DNS_PROBE_STARTED, WaitForSentStatus());
856 StartDelayedProbes(1);
857 EXPECT_EQ(chrome_common_net::DNS_PROBE_FINISHED_NO_INTERNET,
858 WaitForSentStatus());
860 EXPECT_EQ("", Title());
861 EXPECT_EQ(0, pending_status_count());
863 chrome::Stop(browser());
864 WaitForDelayedRequestDestruction();
866 // End up displaying a blank page.
867 EXPECT_EQ("", Title());
870 // Test that pressing the stop button cancels the load of corrections, and
871 // receiving a probe result afterwards does not swap in a DNS error page.
872 IN_PROC_BROWSER_TEST_F(DnsProbeBrowserTest, CorrectionsLoadStoppedSlowProbe) {
873 SetCorrectionServiceDelayRequests(true);
874 SetCorrectionServiceBroken(true);
875 SetMockDnsClientRules(MockDnsClientRule::TIMEOUT, MockDnsClientRule::TIMEOUT);
877 NavigateToDnsError(1);
879 EXPECT_EQ(chrome_common_net::DNS_PROBE_STARTED, WaitForSentStatus());
881 EXPECT_EQ("", Title());
882 EXPECT_EQ(0, pending_status_count());
884 chrome::Stop(browser());
885 WaitForDelayedRequestDestruction();
887 EXPECT_EQ("", Title());
888 EXPECT_EQ(0, pending_status_count());
890 StartDelayedProbes(1);
891 EXPECT_EQ(chrome_common_net::DNS_PROBE_FINISHED_NO_INTERNET,
892 WaitForSentStatus());
894 EXPECT_EQ("", Title());
897 // Make sure probes don't run for subframe DNS errors.
898 IN_PROC_BROWSER_TEST_F(DnsProbeBrowserTest, NoProbeInSubframe) {
899 SetCorrectionServiceBroken(false);
901 const FilePath::CharType kIframeDnsErrorHtmlName[] =
902 FILE_PATH_LITERAL("iframe_dns_error.html");
904 NavigateToURL(
905 browser(),
906 URLRequestMockHTTPJob::GetMockUrl(FilePath(kIframeDnsErrorHtmlName)));
908 // By the time NavigateToURL returns, the browser will have seen the failed
909 // provisional load. If a probe was started (or considered but not run),
910 // then the NetErrorTabHelper would have sent a NetErrorInfo message. Thus,
911 // if one hasn't been sent by now, the NetErrorTabHelper has not (and won't)
912 // start a probe for this DNS error.
913 EXPECT_EQ(0, pending_status_count());
916 // Make sure browser sends NOT_RUN properly when probes are disabled.
917 IN_PROC_BROWSER_TEST_F(DnsProbeBrowserTest, ProbesDisabled) {
918 // Disable probes (And corrections).
919 browser()->profile()->GetPrefs()->SetBoolean(
920 prefs::kAlternateErrorPagesEnabled, false);
922 SetCorrectionServiceBroken(true);
923 SetMockDnsClientRules(MockDnsClientRule::TIMEOUT, MockDnsClientRule::TIMEOUT);
925 NavigateToDnsError(1);
927 EXPECT_EQ(chrome_common_net::DNS_PROBE_NOT_RUN, WaitForSentStatus());
929 // Checking the page runs the RunLoop, so make sure nothing hairy happens.
930 EXPECT_EQ(0, pending_status_count());
931 ExpectDisplayingLocalErrorPage("ERR_NAME_NOT_RESOLVED");
934 // Test the case that corrections are disabled, but DNS probes are enabled.
935 // This is the case with Chromium builds.
936 IN_PROC_BROWSER_TEST_F(DnsProbeBrowserTest, CorrectionsDisabled) {
937 // Disable corrections.
938 browser()->profile()->GetPrefs()->SetBoolean(
939 prefs::kAlternateErrorPagesEnabled, false);
940 // Requests to the correction service should work if any are made, so the test
941 // fails if that happens unexpectedly.
942 SetCorrectionServiceBroken(false);
943 // Normally disabling corrections disables DNS probes, so force DNS probes
944 // to be enabled.
945 NetErrorTabHelper::set_state_for_testing(
946 NetErrorTabHelper::TESTING_FORCE_ENABLED);
948 SetMockDnsClientRules(MockDnsClientRule::FAIL, MockDnsClientRule::FAIL);
950 // Just one commit and one sent status, since corrections are disabled.
951 NavigateToDnsError(1);
952 EXPECT_EQ(chrome_common_net::DNS_PROBE_STARTED, WaitForSentStatus());
954 // Checking the page runs the RunLoop, so make sure nothing hairy happens.
955 EXPECT_EQ(0, pending_status_count());
956 ExpectDisplayingLocalErrorPage("DNS_PROBE_STARTED");
957 EXPECT_EQ(0, pending_status_count());
959 StartDelayedProbes(1);
961 EXPECT_EQ(chrome_common_net::DNS_PROBE_FINISHED_INCONCLUSIVE,
962 WaitForSentStatus());
963 EXPECT_EQ(0, pending_status_count());
964 ExpectDisplayingLocalErrorPage("ERR_NAME_NOT_RESOLVED");
967 // Test incognito mode. Corrections should be disabled, but DNS probes are
968 // still enabled.
969 IN_PROC_BROWSER_TEST_F(DnsProbeBrowserTest, Incognito) {
970 // Requests to the correction service should work if any are made, so the test
971 // will fail if one is requested unexpectedly.
972 SetCorrectionServiceBroken(false);
974 Browser* incognito = CreateIncognitoBrowser();
975 SetActiveBrowser(incognito);
977 SetMockDnsClientRules(MockDnsClientRule::FAIL, MockDnsClientRule::FAIL);
979 // Just one commit and one sent status, since the corrections are disabled.
980 NavigateToDnsError(1);
981 EXPECT_EQ(chrome_common_net::DNS_PROBE_STARTED, WaitForSentStatus());
983 // Checking the page runs the RunLoop, so make sure nothing hairy happens.
984 EXPECT_EQ(0, pending_status_count());
985 ExpectDisplayingLocalErrorPage("DNS_PROBE_STARTED");
986 EXPECT_EQ(0, pending_status_count());
988 StartDelayedProbes(1);
990 EXPECT_EQ(chrome_common_net::DNS_PROBE_FINISHED_INCONCLUSIVE,
991 WaitForSentStatus());
992 EXPECT_EQ(0, pending_status_count());
993 ExpectDisplayingLocalErrorPage("ERR_NAME_NOT_RESOLVED");
996 } // namespace
998 } // namespace chrome_browser_net