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 "chrome/browser/net/net_error_tab_helper.h"
7 #include "chrome/common/render_messages.h"
8 #include "chrome/test/base/chrome_render_view_host_test_harness.h"
9 #include "components/error_page/common/net_error_info.h"
10 #include "content/public/browser/browser_thread.h"
11 #include "content/public/test/test_renderer_host.h"
12 #include "net/base/net_errors.h"
13 #include "testing/gtest/include/gtest/gtest.h"
14 #include "ui/base/page_transition_types.h"
16 using chrome_browser_net::NetErrorTabHelper
;
17 using error_page::DnsProbeStatus
;
19 class TestNetErrorTabHelper
: public NetErrorTabHelper
{
21 explicit TestNetErrorTabHelper(content::WebContents
* web_contents
)
22 : NetErrorTabHelper(web_contents
),
23 mock_probe_running_(false),
24 last_status_sent_(error_page::DNS_PROBE_MAX
),
26 times_diagnostics_dialog_invoked_(0) {}
28 void FinishProbe(DnsProbeStatus status
) {
29 EXPECT_TRUE(mock_probe_running_
);
30 OnDnsProbeFinished(status
);
31 mock_probe_running_
= false;
34 bool mock_probe_running() const { return mock_probe_running_
; }
35 DnsProbeStatus
last_status_sent() const { return last_status_sent_
; }
36 int mock_sent_count() const { return mock_sent_count_
; }
38 const std::string
& network_diagnostics_url() const {
39 return network_diagnostics_url_
;
42 int times_diagnostics_dialog_invoked() const {
43 return times_diagnostics_dialog_invoked_
;
47 // NetErrorTabHelper implementation:
49 void StartDnsProbe() override
{
50 EXPECT_FALSE(mock_probe_running_
);
51 mock_probe_running_
= true;
54 void SendInfo() override
{
55 last_status_sent_
= dns_probe_status();
59 void RunNetworkDiagnosticsHelper(const std::string
& sanitized_url
) override
{
60 network_diagnostics_url_
= sanitized_url
;
61 times_diagnostics_dialog_invoked_
++;
64 bool mock_probe_running_
;
65 DnsProbeStatus last_status_sent_
;
67 std::string network_diagnostics_url_
;
68 int times_diagnostics_dialog_invoked_
;
71 class NetErrorTabHelperTest
: public ChromeRenderViewHostTestHarness
{
73 enum MainFrame
{ SUB_FRAME
, MAIN_FRAME
};
74 enum ErrorPage
{ NORMAL_PAGE
, ERROR_PAGE
};
75 enum ErrorType
{ DNS_ERROR
, OTHER_ERROR
};
77 void SetUp() override
{
78 ChromeRenderViewHostTestHarness::SetUp();
80 // This will simulate the initialization of the RenderFrame in the renderer
81 // process. This is needed because WebContents does not initialize a
82 // RenderFrame on construction, and the tests expect one to exist.
83 content::RenderFrameHostTester::For(main_rfh())
84 ->InitializeRenderFrameIfNeeded();
86 subframe_
= content::RenderFrameHostTester::For(main_rfh())
87 ->AppendChild("subframe");
89 tab_helper_
.reset(new TestNetErrorTabHelper(web_contents()));
90 NetErrorTabHelper::set_state_for_testing(
91 NetErrorTabHelper::TESTING_FORCE_ENABLED
);
94 void TearDown() override
{
95 // Have to shut down the helper before the profile.
97 ChromeRenderViewHostTestHarness::TearDown();
100 void StartProvisionalLoad(MainFrame main_frame
, ErrorPage error_page
) {
101 tab_helper_
->DidStartProvisionalLoadForFrame(
102 (main_frame
== MAIN_FRAME
) ? main_rfh() : subframe_
,
103 bogus_url_
, // validated_url
104 (error_page
== ERROR_PAGE
),
105 false); // is_iframe_srcdoc
108 void CommitProvisionalLoad(MainFrame main_frame
) {
109 tab_helper_
->DidCommitProvisionalLoadForFrame(
110 (main_frame
== MAIN_FRAME
) ? main_rfh() : subframe_
,
112 ui::PAGE_TRANSITION_TYPED
);
115 void FailProvisionalLoad(MainFrame main_frame
, ErrorType error_type
) {
118 if (error_type
== DNS_ERROR
)
119 net_error
= net::ERR_NAME_NOT_RESOLVED
;
121 net_error
= net::ERR_TIMED_OUT
;
123 tab_helper_
->DidFailProvisionalLoad(
124 (main_frame
== MAIN_FRAME
) ? main_rfh() : subframe_
,
125 bogus_url_
, // validated_url
131 void FinishProbe(DnsProbeStatus status
) { tab_helper_
->FinishProbe(status
); }
133 bool probe_running() { return tab_helper_
->mock_probe_running(); }
134 DnsProbeStatus
last_status_sent() { return tab_helper_
->last_status_sent(); }
135 int sent_count() { return tab_helper_
->mock_sent_count(); }
137 TestNetErrorTabHelper
* tab_helper() { return tab_helper_
.get(); }
140 content::RenderFrameHost
* subframe_
;
141 scoped_ptr
<TestNetErrorTabHelper
> tab_helper_
;
145 TEST_F(NetErrorTabHelperTest
, Null
) {
146 EXPECT_FALSE(probe_running());
149 TEST_F(NetErrorTabHelperTest
, MainFrameNonDnsError
) {
150 StartProvisionalLoad(MAIN_FRAME
, NORMAL_PAGE
);
151 FailProvisionalLoad(MAIN_FRAME
, OTHER_ERROR
);
152 EXPECT_FALSE(probe_running());
153 EXPECT_EQ(0, sent_count());
156 TEST_F(NetErrorTabHelperTest
, NonMainFrameDnsError
) {
157 StartProvisionalLoad(SUB_FRAME
, NORMAL_PAGE
);
158 FailProvisionalLoad(SUB_FRAME
, DNS_ERROR
);
159 EXPECT_FALSE(probe_running());
160 EXPECT_EQ(0, sent_count());
163 // Test complete DNS error page loads. Note that the helper can see two error
164 // page loads: Link Doctor loads an empty HTML page so the user knows something
165 // is going on, then fails over to the normal error page if and when Link
166 // Doctor fails to load or declines to provide a page.
168 TEST_F(NetErrorTabHelperTest
, ProbeResponseBeforeFirstCommit
) {
169 StartProvisionalLoad(MAIN_FRAME
, NORMAL_PAGE
);
170 FailProvisionalLoad(MAIN_FRAME
, DNS_ERROR
);
171 EXPECT_TRUE(probe_running());
172 EXPECT_EQ(0, sent_count());
174 StartProvisionalLoad(MAIN_FRAME
, ERROR_PAGE
);
175 EXPECT_TRUE(probe_running());
176 EXPECT_EQ(0, sent_count());
178 FinishProbe(error_page::DNS_PROBE_FINISHED_NXDOMAIN
);
179 EXPECT_FALSE(probe_running());
180 EXPECT_EQ(0, sent_count());
182 CommitProvisionalLoad(MAIN_FRAME
);
183 EXPECT_FALSE(probe_running());
184 EXPECT_EQ(1, sent_count());
185 EXPECT_EQ(error_page::DNS_PROBE_FINISHED_NXDOMAIN
, last_status_sent());
187 StartProvisionalLoad(MAIN_FRAME
, ERROR_PAGE
);
188 EXPECT_FALSE(probe_running());
189 EXPECT_EQ(1, sent_count());
191 CommitProvisionalLoad(MAIN_FRAME
);
192 EXPECT_FALSE(probe_running());
193 EXPECT_EQ(2, sent_count());
194 EXPECT_EQ(error_page::DNS_PROBE_FINISHED_NXDOMAIN
, last_status_sent());
197 TEST_F(NetErrorTabHelperTest
, ProbeResponseBetweenFirstAndSecondCommit
) {
198 StartProvisionalLoad(MAIN_FRAME
, NORMAL_PAGE
);
199 FailProvisionalLoad(MAIN_FRAME
, DNS_ERROR
);
200 EXPECT_TRUE(probe_running());
201 EXPECT_EQ(0, sent_count());
203 StartProvisionalLoad(MAIN_FRAME
, ERROR_PAGE
);
204 EXPECT_TRUE(probe_running());
205 EXPECT_EQ(0, sent_count());
207 CommitProvisionalLoad(MAIN_FRAME
);
208 EXPECT_TRUE(probe_running());
209 EXPECT_EQ(1, sent_count());
210 EXPECT_EQ(error_page::DNS_PROBE_STARTED
, last_status_sent());
212 FinishProbe(error_page::DNS_PROBE_FINISHED_NXDOMAIN
);
213 EXPECT_FALSE(probe_running());
214 EXPECT_EQ(2, sent_count());
215 EXPECT_EQ(error_page::DNS_PROBE_FINISHED_NXDOMAIN
, last_status_sent());
217 StartProvisionalLoad(MAIN_FRAME
, ERROR_PAGE
);
218 EXPECT_FALSE(probe_running());
219 EXPECT_EQ(2, sent_count());
221 CommitProvisionalLoad(MAIN_FRAME
);
222 EXPECT_FALSE(probe_running());
223 EXPECT_EQ(3, sent_count());
224 EXPECT_EQ(error_page::DNS_PROBE_FINISHED_NXDOMAIN
, last_status_sent());
227 TEST_F(NetErrorTabHelperTest
, ProbeResponseAfterSecondCommit
) {
228 StartProvisionalLoad(MAIN_FRAME
, NORMAL_PAGE
);
229 FailProvisionalLoad(MAIN_FRAME
, DNS_ERROR
);
230 EXPECT_TRUE(probe_running());
231 EXPECT_EQ(0, sent_count());
233 StartProvisionalLoad(MAIN_FRAME
, ERROR_PAGE
);
234 EXPECT_TRUE(probe_running());
235 EXPECT_EQ(0, sent_count());
237 CommitProvisionalLoad(MAIN_FRAME
);
238 EXPECT_TRUE(probe_running());
239 EXPECT_EQ(1, sent_count());
240 EXPECT_EQ(error_page::DNS_PROBE_STARTED
, last_status_sent());
242 StartProvisionalLoad(MAIN_FRAME
, ERROR_PAGE
);
243 EXPECT_TRUE(probe_running());
244 EXPECT_EQ(1, sent_count());
246 CommitProvisionalLoad(MAIN_FRAME
);
247 EXPECT_TRUE(probe_running());
248 EXPECT_EQ(2, sent_count());
249 EXPECT_EQ(error_page::DNS_PROBE_STARTED
, last_status_sent());
251 FinishProbe(error_page::DNS_PROBE_FINISHED_NXDOMAIN
);
252 EXPECT_FALSE(probe_running());
253 EXPECT_EQ(3, sent_count());
254 EXPECT_EQ(error_page::DNS_PROBE_FINISHED_NXDOMAIN
, last_status_sent());
257 // Send result even if a new page load has started; the error page is still
258 // visible, and the user might cancel the load.
259 TEST_F(NetErrorTabHelperTest
, ProbeResponseAfterNewStart
) {
260 StartProvisionalLoad(MAIN_FRAME
, NORMAL_PAGE
);
261 FailProvisionalLoad(MAIN_FRAME
, DNS_ERROR
);
262 EXPECT_TRUE(probe_running());
263 EXPECT_EQ(0, sent_count());
265 StartProvisionalLoad(MAIN_FRAME
, ERROR_PAGE
);
266 EXPECT_TRUE(probe_running());
267 EXPECT_EQ(0, sent_count());
269 CommitProvisionalLoad(MAIN_FRAME
);
270 EXPECT_TRUE(probe_running());
271 EXPECT_EQ(1, sent_count());
272 EXPECT_EQ(error_page::DNS_PROBE_STARTED
, last_status_sent());
274 StartProvisionalLoad(MAIN_FRAME
, ERROR_PAGE
);
275 EXPECT_TRUE(probe_running());
276 EXPECT_EQ(1, sent_count());
278 CommitProvisionalLoad(MAIN_FRAME
);
279 EXPECT_TRUE(probe_running());
280 EXPECT_EQ(2, sent_count());
281 EXPECT_EQ(error_page::DNS_PROBE_STARTED
, last_status_sent());
283 StartProvisionalLoad(MAIN_FRAME
, NORMAL_PAGE
);
284 EXPECT_TRUE(probe_running());
285 EXPECT_EQ(2, sent_count());
287 FinishProbe(error_page::DNS_PROBE_FINISHED_NXDOMAIN
);
288 EXPECT_FALSE(probe_running());
289 EXPECT_EQ(3, sent_count());
290 EXPECT_EQ(error_page::DNS_PROBE_FINISHED_NXDOMAIN
, last_status_sent());
293 // Don't send result if a new page has committed; the result would go to the
294 // wrong page, and the error page is gone anyway.
295 TEST_F(NetErrorTabHelperTest
, ProbeResponseAfterNewCommit
) {
296 StartProvisionalLoad(MAIN_FRAME
, NORMAL_PAGE
);
297 FailProvisionalLoad(MAIN_FRAME
, DNS_ERROR
);
298 EXPECT_TRUE(probe_running());
299 EXPECT_EQ(0, sent_count());
301 StartProvisionalLoad(MAIN_FRAME
, ERROR_PAGE
);
302 EXPECT_TRUE(probe_running());
303 EXPECT_EQ(0, sent_count());
305 CommitProvisionalLoad(MAIN_FRAME
);
306 EXPECT_TRUE(probe_running());
307 EXPECT_EQ(1, sent_count());
308 EXPECT_EQ(error_page::DNS_PROBE_STARTED
, last_status_sent());
310 StartProvisionalLoad(MAIN_FRAME
, ERROR_PAGE
);
311 EXPECT_TRUE(probe_running());
312 EXPECT_EQ(1, sent_count());
314 CommitProvisionalLoad(MAIN_FRAME
);
315 EXPECT_TRUE(probe_running());
316 EXPECT_EQ(2, sent_count());
317 EXPECT_EQ(error_page::DNS_PROBE_STARTED
, last_status_sent());
319 StartProvisionalLoad(MAIN_FRAME
, NORMAL_PAGE
);
320 EXPECT_TRUE(probe_running());
321 EXPECT_EQ(2, sent_count());
323 CommitProvisionalLoad(MAIN_FRAME
);
324 EXPECT_TRUE(probe_running());
325 EXPECT_EQ(2, sent_count());
327 FinishProbe(error_page::DNS_PROBE_FINISHED_NXDOMAIN
);
328 EXPECT_FALSE(probe_running());
329 EXPECT_EQ(2, sent_count());
332 TEST_F(NetErrorTabHelperTest
, MultipleDnsErrorsWithProbesWithoutErrorPages
) {
333 StartProvisionalLoad(MAIN_FRAME
, NORMAL_PAGE
);
334 FailProvisionalLoad(MAIN_FRAME
, DNS_ERROR
);
335 EXPECT_TRUE(probe_running());
336 EXPECT_EQ(0, sent_count());
338 FinishProbe(error_page::DNS_PROBE_FINISHED_NXDOMAIN
);
339 EXPECT_FALSE(probe_running());
340 EXPECT_EQ(0, sent_count());
342 StartProvisionalLoad(MAIN_FRAME
, NORMAL_PAGE
);
343 FailProvisionalLoad(MAIN_FRAME
, DNS_ERROR
);
344 EXPECT_TRUE(probe_running());
345 EXPECT_EQ(0, sent_count());
347 FinishProbe(error_page::DNS_PROBE_FINISHED_NO_INTERNET
);
348 EXPECT_FALSE(probe_running());
349 EXPECT_EQ(0, sent_count());
352 TEST_F(NetErrorTabHelperTest
, MultipleDnsErrorsWithProbesAndErrorPages
) {
353 StartProvisionalLoad(MAIN_FRAME
, NORMAL_PAGE
);
354 FailProvisionalLoad(MAIN_FRAME
, DNS_ERROR
);
355 EXPECT_TRUE(probe_running());
356 EXPECT_EQ(0, sent_count());
358 StartProvisionalLoad(MAIN_FRAME
, ERROR_PAGE
);
359 CommitProvisionalLoad(MAIN_FRAME
);
360 EXPECT_TRUE(probe_running());
361 EXPECT_EQ(1, sent_count());
362 EXPECT_EQ(error_page::DNS_PROBE_STARTED
, last_status_sent());
364 FinishProbe(error_page::DNS_PROBE_FINISHED_NXDOMAIN
);
365 EXPECT_FALSE(probe_running());
366 EXPECT_EQ(2, sent_count());
367 EXPECT_EQ(error_page::DNS_PROBE_FINISHED_NXDOMAIN
, last_status_sent());
369 StartProvisionalLoad(MAIN_FRAME
, NORMAL_PAGE
);
370 FailProvisionalLoad(MAIN_FRAME
, DNS_ERROR
);
371 EXPECT_TRUE(probe_running());
372 EXPECT_EQ(2, sent_count());
374 StartProvisionalLoad(MAIN_FRAME
, ERROR_PAGE
);
375 CommitProvisionalLoad(MAIN_FRAME
);
376 EXPECT_TRUE(probe_running());
377 EXPECT_EQ(3, sent_count());
378 EXPECT_EQ(error_page::DNS_PROBE_STARTED
, last_status_sent());
380 FinishProbe(error_page::DNS_PROBE_FINISHED_NO_INTERNET
);
381 EXPECT_FALSE(probe_running());
382 EXPECT_EQ(4, sent_count());
383 EXPECT_EQ(error_page::DNS_PROBE_FINISHED_NO_INTERNET
,
387 // If multiple DNS errors occur in a row before a probe result, don't start
389 TEST_F(NetErrorTabHelperTest
, CoalesceFailures
) {
390 StartProvisionalLoad(MAIN_FRAME
, NORMAL_PAGE
);
391 FailProvisionalLoad(MAIN_FRAME
, DNS_ERROR
);
392 StartProvisionalLoad(MAIN_FRAME
, ERROR_PAGE
);
393 CommitProvisionalLoad(MAIN_FRAME
);
394 EXPECT_TRUE(probe_running());
395 EXPECT_EQ(1, sent_count());
396 EXPECT_EQ(error_page::DNS_PROBE_STARTED
, last_status_sent());
398 StartProvisionalLoad(MAIN_FRAME
, NORMAL_PAGE
);
399 FailProvisionalLoad(MAIN_FRAME
, DNS_ERROR
);
400 StartProvisionalLoad(MAIN_FRAME
, ERROR_PAGE
);
401 CommitProvisionalLoad(MAIN_FRAME
);
402 EXPECT_TRUE(probe_running());
403 EXPECT_EQ(2, sent_count());
404 EXPECT_EQ(error_page::DNS_PROBE_STARTED
, last_status_sent());
406 StartProvisionalLoad(MAIN_FRAME
, NORMAL_PAGE
);
407 FailProvisionalLoad(MAIN_FRAME
, DNS_ERROR
);
408 StartProvisionalLoad(MAIN_FRAME
, ERROR_PAGE
);
409 CommitProvisionalLoad(MAIN_FRAME
);
410 EXPECT_TRUE(probe_running());
411 EXPECT_EQ(3, sent_count());
412 EXPECT_EQ(error_page::DNS_PROBE_STARTED
, last_status_sent());
414 FinishProbe(error_page::DNS_PROBE_FINISHED_NXDOMAIN
);
415 EXPECT_FALSE(probe_running());
416 EXPECT_EQ(4, sent_count());
417 EXPECT_EQ(error_page::DNS_PROBE_FINISHED_NXDOMAIN
, last_status_sent());
420 // Makes sure that URLs are sanitized before running the platform network
422 TEST_F(NetErrorTabHelperTest
, SanitizeDiagnosticsUrl
) {
423 content::RenderFrameHost
* rfh
= web_contents()->GetMainFrame();
424 rfh
->OnMessageReceived(ChromeViewHostMsg_RunNetworkDiagnostics(
426 GURL("http://foo:bar@somewhere:123/hats?for#goats")));
427 EXPECT_EQ("http://somewhere:123/",
428 tab_helper()->network_diagnostics_url());
429 EXPECT_EQ(1, tab_helper()->times_diagnostics_dialog_invoked());
432 // Makes sure that diagnostics aren't run on invalid URLs or URLs with
433 // non-HTTP/HTTPS schemes.
434 TEST_F(NetErrorTabHelperTest
, NoDiagnosticsForNonHttpSchemes
) {
435 const char* kUrls
[] = {
444 for (const char* url
: kUrls
) {
445 content::RenderFrameHost
* rfh
= web_contents()->GetMainFrame();
446 rfh
->OnMessageReceived(ChromeViewHostMsg_RunNetworkDiagnostics(
447 rfh
->GetRoutingID(), GURL(url
)));
448 EXPECT_EQ(0, tab_helper()->times_diagnostics_dialog_invoked());