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 chrome_common_net::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_(chrome_common_net::DNS_PROBE_MAX
),
25 mock_sent_count_(0) {}
27 void FinishProbe(DnsProbeStatus status
) {
28 EXPECT_TRUE(mock_probe_running_
);
29 OnDnsProbeFinished(status
);
30 mock_probe_running_
= false;
33 bool mock_probe_running() const { return mock_probe_running_
; }
34 DnsProbeStatus
last_status_sent() const { return last_status_sent_
; }
35 int mock_sent_count() const { return mock_sent_count_
; }
37 const GURL
& network_diagnostics_url() const {
38 return network_diagnostics_url_
;
42 // NetErrorTabHelper implementation:
44 void StartDnsProbe() override
{
45 EXPECT_FALSE(mock_probe_running_
);
46 mock_probe_running_
= true;
49 void SendInfo() override
{
50 last_status_sent_
= dns_probe_status();
54 void RunNetworkDiagnosticsHelper(const GURL
& sanitized_url
) override
{
55 network_diagnostics_url_
= sanitized_url
;
58 bool mock_probe_running_
;
59 DnsProbeStatus last_status_sent_
;
61 GURL network_diagnostics_url_
;
64 class NetErrorTabHelperTest
: public ChromeRenderViewHostTestHarness
{
66 enum MainFrame
{ SUB_FRAME
, MAIN_FRAME
};
67 enum ErrorPage
{ NORMAL_PAGE
, ERROR_PAGE
};
68 enum ErrorType
{ DNS_ERROR
, OTHER_ERROR
};
70 void SetUp() override
{
71 ChromeRenderViewHostTestHarness::SetUp();
73 // This will simulate the initialization of the RenderFrame in the renderer
74 // process. This is needed because WebContents does not initialize a
75 // RenderFrame on construction, and the tests expect one to exist.
76 content::RenderFrameHostTester::For(main_rfh())
77 ->InitializeRenderFrameIfNeeded();
79 subframe_
= content::RenderFrameHostTester::For(main_rfh())
80 ->AppendChild("subframe");
82 tab_helper_
.reset(new TestNetErrorTabHelper(web_contents()));
83 NetErrorTabHelper::set_state_for_testing(
84 NetErrorTabHelper::TESTING_FORCE_ENABLED
);
87 void TearDown() override
{
88 // Have to shut down the helper before the profile.
90 ChromeRenderViewHostTestHarness::TearDown();
93 void StartProvisionalLoad(MainFrame main_frame
, ErrorPage error_page
) {
94 tab_helper_
->DidStartProvisionalLoadForFrame(
95 (main_frame
== MAIN_FRAME
) ? main_rfh() : subframe_
,
96 bogus_url_
, // validated_url
97 (error_page
== ERROR_PAGE
),
98 false); // is_iframe_srcdoc
101 void CommitProvisionalLoad(MainFrame main_frame
) {
102 tab_helper_
->DidCommitProvisionalLoadForFrame(
103 (main_frame
== MAIN_FRAME
) ? main_rfh() : subframe_
,
105 ui::PAGE_TRANSITION_TYPED
);
108 void FailProvisionalLoad(MainFrame main_frame
, ErrorType error_type
) {
111 if (error_type
== DNS_ERROR
)
112 net_error
= net::ERR_NAME_NOT_RESOLVED
;
114 net_error
= net::ERR_TIMED_OUT
;
116 tab_helper_
->DidFailProvisionalLoad(
117 (main_frame
== MAIN_FRAME
) ? main_rfh() : subframe_
,
118 bogus_url_
, // validated_url
124 void FinishProbe(DnsProbeStatus status
) { tab_helper_
->FinishProbe(status
); }
126 bool probe_running() { return tab_helper_
->mock_probe_running(); }
127 DnsProbeStatus
last_status_sent() { return tab_helper_
->last_status_sent(); }
128 int sent_count() { return tab_helper_
->mock_sent_count(); }
130 TestNetErrorTabHelper
* tab_helper() { return tab_helper_
.get(); }
133 content::RenderFrameHost
* subframe_
;
134 scoped_ptr
<TestNetErrorTabHelper
> tab_helper_
;
138 TEST_F(NetErrorTabHelperTest
, Null
) {
139 EXPECT_FALSE(probe_running());
142 TEST_F(NetErrorTabHelperTest
, MainFrameNonDnsError
) {
143 StartProvisionalLoad(MAIN_FRAME
, NORMAL_PAGE
);
144 FailProvisionalLoad(MAIN_FRAME
, OTHER_ERROR
);
145 EXPECT_FALSE(probe_running());
146 EXPECT_EQ(0, sent_count());
149 TEST_F(NetErrorTabHelperTest
, NonMainFrameDnsError
) {
150 StartProvisionalLoad(SUB_FRAME
, NORMAL_PAGE
);
151 FailProvisionalLoad(SUB_FRAME
, DNS_ERROR
);
152 EXPECT_FALSE(probe_running());
153 EXPECT_EQ(0, sent_count());
156 // Test complete DNS error page loads. Note that the helper can see two error
157 // page loads: Link Doctor loads an empty HTML page so the user knows something
158 // is going on, then fails over to the normal error page if and when Link
159 // Doctor fails to load or declines to provide a page.
161 TEST_F(NetErrorTabHelperTest
, ProbeResponseBeforeFirstCommit
) {
162 StartProvisionalLoad(MAIN_FRAME
, NORMAL_PAGE
);
163 FailProvisionalLoad(MAIN_FRAME
, DNS_ERROR
);
164 EXPECT_TRUE(probe_running());
165 EXPECT_EQ(0, sent_count());
167 StartProvisionalLoad(MAIN_FRAME
, ERROR_PAGE
);
168 EXPECT_TRUE(probe_running());
169 EXPECT_EQ(0, sent_count());
171 FinishProbe(chrome_common_net::DNS_PROBE_FINISHED_NXDOMAIN
);
172 EXPECT_FALSE(probe_running());
173 EXPECT_EQ(0, sent_count());
175 CommitProvisionalLoad(MAIN_FRAME
);
176 EXPECT_FALSE(probe_running());
177 EXPECT_EQ(1, sent_count());
178 EXPECT_EQ(chrome_common_net::DNS_PROBE_FINISHED_NXDOMAIN
, last_status_sent());
180 StartProvisionalLoad(MAIN_FRAME
, ERROR_PAGE
);
181 EXPECT_FALSE(probe_running());
182 EXPECT_EQ(1, sent_count());
184 CommitProvisionalLoad(MAIN_FRAME
);
185 EXPECT_FALSE(probe_running());
186 EXPECT_EQ(2, sent_count());
187 EXPECT_EQ(chrome_common_net::DNS_PROBE_FINISHED_NXDOMAIN
, last_status_sent());
190 TEST_F(NetErrorTabHelperTest
, ProbeResponseBetweenFirstAndSecondCommit
) {
191 StartProvisionalLoad(MAIN_FRAME
, NORMAL_PAGE
);
192 FailProvisionalLoad(MAIN_FRAME
, DNS_ERROR
);
193 EXPECT_TRUE(probe_running());
194 EXPECT_EQ(0, sent_count());
196 StartProvisionalLoad(MAIN_FRAME
, ERROR_PAGE
);
197 EXPECT_TRUE(probe_running());
198 EXPECT_EQ(0, sent_count());
200 CommitProvisionalLoad(MAIN_FRAME
);
201 EXPECT_TRUE(probe_running());
202 EXPECT_EQ(1, sent_count());
203 EXPECT_EQ(chrome_common_net::DNS_PROBE_STARTED
, last_status_sent());
205 FinishProbe(chrome_common_net::DNS_PROBE_FINISHED_NXDOMAIN
);
206 EXPECT_FALSE(probe_running());
207 EXPECT_EQ(2, sent_count());
208 EXPECT_EQ(chrome_common_net::DNS_PROBE_FINISHED_NXDOMAIN
, last_status_sent());
210 StartProvisionalLoad(MAIN_FRAME
, ERROR_PAGE
);
211 EXPECT_FALSE(probe_running());
212 EXPECT_EQ(2, sent_count());
214 CommitProvisionalLoad(MAIN_FRAME
);
215 EXPECT_FALSE(probe_running());
216 EXPECT_EQ(3, sent_count());
217 EXPECT_EQ(chrome_common_net::DNS_PROBE_FINISHED_NXDOMAIN
, last_status_sent());
220 TEST_F(NetErrorTabHelperTest
, ProbeResponseAfterSecondCommit
) {
221 StartProvisionalLoad(MAIN_FRAME
, NORMAL_PAGE
);
222 FailProvisionalLoad(MAIN_FRAME
, DNS_ERROR
);
223 EXPECT_TRUE(probe_running());
224 EXPECT_EQ(0, sent_count());
226 StartProvisionalLoad(MAIN_FRAME
, ERROR_PAGE
);
227 EXPECT_TRUE(probe_running());
228 EXPECT_EQ(0, sent_count());
230 CommitProvisionalLoad(MAIN_FRAME
);
231 EXPECT_TRUE(probe_running());
232 EXPECT_EQ(1, sent_count());
233 EXPECT_EQ(chrome_common_net::DNS_PROBE_STARTED
, last_status_sent());
235 StartProvisionalLoad(MAIN_FRAME
, ERROR_PAGE
);
236 EXPECT_TRUE(probe_running());
237 EXPECT_EQ(1, sent_count());
239 CommitProvisionalLoad(MAIN_FRAME
);
240 EXPECT_TRUE(probe_running());
241 EXPECT_EQ(2, sent_count());
242 EXPECT_EQ(chrome_common_net::DNS_PROBE_STARTED
, last_status_sent());
244 FinishProbe(chrome_common_net::DNS_PROBE_FINISHED_NXDOMAIN
);
245 EXPECT_FALSE(probe_running());
246 EXPECT_EQ(3, sent_count());
247 EXPECT_EQ(chrome_common_net::DNS_PROBE_FINISHED_NXDOMAIN
, last_status_sent());
250 // Send result even if a new page load has started; the error page is still
251 // visible, and the user might cancel the load.
252 TEST_F(NetErrorTabHelperTest
, ProbeResponseAfterNewStart
) {
253 StartProvisionalLoad(MAIN_FRAME
, NORMAL_PAGE
);
254 FailProvisionalLoad(MAIN_FRAME
, DNS_ERROR
);
255 EXPECT_TRUE(probe_running());
256 EXPECT_EQ(0, sent_count());
258 StartProvisionalLoad(MAIN_FRAME
, ERROR_PAGE
);
259 EXPECT_TRUE(probe_running());
260 EXPECT_EQ(0, sent_count());
262 CommitProvisionalLoad(MAIN_FRAME
);
263 EXPECT_TRUE(probe_running());
264 EXPECT_EQ(1, sent_count());
265 EXPECT_EQ(chrome_common_net::DNS_PROBE_STARTED
, last_status_sent());
267 StartProvisionalLoad(MAIN_FRAME
, ERROR_PAGE
);
268 EXPECT_TRUE(probe_running());
269 EXPECT_EQ(1, sent_count());
271 CommitProvisionalLoad(MAIN_FRAME
);
272 EXPECT_TRUE(probe_running());
273 EXPECT_EQ(2, sent_count());
274 EXPECT_EQ(chrome_common_net::DNS_PROBE_STARTED
, last_status_sent());
276 StartProvisionalLoad(MAIN_FRAME
, NORMAL_PAGE
);
277 EXPECT_TRUE(probe_running());
278 EXPECT_EQ(2, sent_count());
280 FinishProbe(chrome_common_net::DNS_PROBE_FINISHED_NXDOMAIN
);
281 EXPECT_FALSE(probe_running());
282 EXPECT_EQ(3, sent_count());
283 EXPECT_EQ(chrome_common_net::DNS_PROBE_FINISHED_NXDOMAIN
, last_status_sent());
286 // Don't send result if a new page has committed; the result would go to the
287 // wrong page, and the error page is gone anyway.
288 TEST_F(NetErrorTabHelperTest
, ProbeResponseAfterNewCommit
) {
289 StartProvisionalLoad(MAIN_FRAME
, NORMAL_PAGE
);
290 FailProvisionalLoad(MAIN_FRAME
, DNS_ERROR
);
291 EXPECT_TRUE(probe_running());
292 EXPECT_EQ(0, sent_count());
294 StartProvisionalLoad(MAIN_FRAME
, ERROR_PAGE
);
295 EXPECT_TRUE(probe_running());
296 EXPECT_EQ(0, sent_count());
298 CommitProvisionalLoad(MAIN_FRAME
);
299 EXPECT_TRUE(probe_running());
300 EXPECT_EQ(1, sent_count());
301 EXPECT_EQ(chrome_common_net::DNS_PROBE_STARTED
, last_status_sent());
303 StartProvisionalLoad(MAIN_FRAME
, ERROR_PAGE
);
304 EXPECT_TRUE(probe_running());
305 EXPECT_EQ(1, sent_count());
307 CommitProvisionalLoad(MAIN_FRAME
);
308 EXPECT_TRUE(probe_running());
309 EXPECT_EQ(2, sent_count());
310 EXPECT_EQ(chrome_common_net::DNS_PROBE_STARTED
, last_status_sent());
312 StartProvisionalLoad(MAIN_FRAME
, NORMAL_PAGE
);
313 EXPECT_TRUE(probe_running());
314 EXPECT_EQ(2, sent_count());
316 CommitProvisionalLoad(MAIN_FRAME
);
317 EXPECT_TRUE(probe_running());
318 EXPECT_EQ(2, sent_count());
320 FinishProbe(chrome_common_net::DNS_PROBE_FINISHED_NXDOMAIN
);
321 EXPECT_FALSE(probe_running());
322 EXPECT_EQ(2, sent_count());
325 TEST_F(NetErrorTabHelperTest
, MultipleDnsErrorsWithProbesWithoutErrorPages
) {
326 StartProvisionalLoad(MAIN_FRAME
, NORMAL_PAGE
);
327 FailProvisionalLoad(MAIN_FRAME
, DNS_ERROR
);
328 EXPECT_TRUE(probe_running());
329 EXPECT_EQ(0, sent_count());
331 FinishProbe(chrome_common_net::DNS_PROBE_FINISHED_NXDOMAIN
);
332 EXPECT_FALSE(probe_running());
333 EXPECT_EQ(0, sent_count());
335 StartProvisionalLoad(MAIN_FRAME
, NORMAL_PAGE
);
336 FailProvisionalLoad(MAIN_FRAME
, DNS_ERROR
);
337 EXPECT_TRUE(probe_running());
338 EXPECT_EQ(0, sent_count());
340 FinishProbe(chrome_common_net::DNS_PROBE_FINISHED_NO_INTERNET
);
341 EXPECT_FALSE(probe_running());
342 EXPECT_EQ(0, sent_count());
345 TEST_F(NetErrorTabHelperTest
, MultipleDnsErrorsWithProbesAndErrorPages
) {
346 StartProvisionalLoad(MAIN_FRAME
, NORMAL_PAGE
);
347 FailProvisionalLoad(MAIN_FRAME
, DNS_ERROR
);
348 EXPECT_TRUE(probe_running());
349 EXPECT_EQ(0, sent_count());
351 StartProvisionalLoad(MAIN_FRAME
, ERROR_PAGE
);
352 CommitProvisionalLoad(MAIN_FRAME
);
353 EXPECT_TRUE(probe_running());
354 EXPECT_EQ(1, sent_count());
355 EXPECT_EQ(chrome_common_net::DNS_PROBE_STARTED
, last_status_sent());
357 FinishProbe(chrome_common_net::DNS_PROBE_FINISHED_NXDOMAIN
);
358 EXPECT_FALSE(probe_running());
359 EXPECT_EQ(2, sent_count());
360 EXPECT_EQ(chrome_common_net::DNS_PROBE_FINISHED_NXDOMAIN
, last_status_sent());
362 StartProvisionalLoad(MAIN_FRAME
, NORMAL_PAGE
);
363 FailProvisionalLoad(MAIN_FRAME
, DNS_ERROR
);
364 EXPECT_TRUE(probe_running());
365 EXPECT_EQ(2, sent_count());
367 StartProvisionalLoad(MAIN_FRAME
, ERROR_PAGE
);
368 CommitProvisionalLoad(MAIN_FRAME
);
369 EXPECT_TRUE(probe_running());
370 EXPECT_EQ(3, sent_count());
371 EXPECT_EQ(chrome_common_net::DNS_PROBE_STARTED
, last_status_sent());
373 FinishProbe(chrome_common_net::DNS_PROBE_FINISHED_NO_INTERNET
);
374 EXPECT_FALSE(probe_running());
375 EXPECT_EQ(4, sent_count());
376 EXPECT_EQ(chrome_common_net::DNS_PROBE_FINISHED_NO_INTERNET
,
380 // If multiple DNS errors occur in a row before a probe result, don't start
382 TEST_F(NetErrorTabHelperTest
, CoalesceFailures
) {
383 StartProvisionalLoad(MAIN_FRAME
, NORMAL_PAGE
);
384 FailProvisionalLoad(MAIN_FRAME
, DNS_ERROR
);
385 StartProvisionalLoad(MAIN_FRAME
, ERROR_PAGE
);
386 CommitProvisionalLoad(MAIN_FRAME
);
387 EXPECT_TRUE(probe_running());
388 EXPECT_EQ(1, sent_count());
389 EXPECT_EQ(chrome_common_net::DNS_PROBE_STARTED
, last_status_sent());
391 StartProvisionalLoad(MAIN_FRAME
, NORMAL_PAGE
);
392 FailProvisionalLoad(MAIN_FRAME
, DNS_ERROR
);
393 StartProvisionalLoad(MAIN_FRAME
, ERROR_PAGE
);
394 CommitProvisionalLoad(MAIN_FRAME
);
395 EXPECT_TRUE(probe_running());
396 EXPECT_EQ(2, sent_count());
397 EXPECT_EQ(chrome_common_net::DNS_PROBE_STARTED
, last_status_sent());
399 StartProvisionalLoad(MAIN_FRAME
, NORMAL_PAGE
);
400 FailProvisionalLoad(MAIN_FRAME
, DNS_ERROR
);
401 StartProvisionalLoad(MAIN_FRAME
, ERROR_PAGE
);
402 CommitProvisionalLoad(MAIN_FRAME
);
403 EXPECT_TRUE(probe_running());
404 EXPECT_EQ(3, sent_count());
405 EXPECT_EQ(chrome_common_net::DNS_PROBE_STARTED
, last_status_sent());
407 FinishProbe(chrome_common_net::DNS_PROBE_FINISHED_NXDOMAIN
);
408 EXPECT_FALSE(probe_running());
409 EXPECT_EQ(4, sent_count());
410 EXPECT_EQ(chrome_common_net::DNS_PROBE_FINISHED_NXDOMAIN
, last_status_sent());
413 // Makes sure that URLs are sanitized before running the platform network
415 TEST_F(NetErrorTabHelperTest
, SanitizeDiagnosticsUrl
) {
416 content::RenderFrameHost
* rfh
= web_contents()->GetMainFrame();
417 rfh
->OnMessageReceived(ChromeViewHostMsg_RunNetworkDiagnostics(
419 GURL("http://foo:bar@somewhere:123/hats?for#goats")));
420 EXPECT_EQ(GURL("http://somewhere:123/"),
421 tab_helper()->network_diagnostics_url());
424 // Makes sure that diagnostics aren't run on URLS with non-HTTP/HTTPS schemes.
425 TEST_F(NetErrorTabHelperTest
, NoDiagnosticsForNonHttpSchemes
) {
426 const char* kUrls
[] = {
433 for (const char* url
: kUrls
) {
434 content::RenderFrameHost
* rfh
= web_contents()->GetMainFrame();
435 rfh
->OnMessageReceived(ChromeViewHostMsg_RunNetworkDiagnostics(
436 rfh
->GetRoutingID(), GURL(url
)));
437 EXPECT_EQ(GURL(""), tab_helper()->network_diagnostics_url());