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/test/base/chrome_render_view_host_test_harness.h"
8 #include "components/error_page/common/net_error_info.h"
9 #include "content/public/browser/browser_thread.h"
10 #include "content/public/test/test_renderer_host.h"
11 #include "net/base/net_errors.h"
12 #include "testing/gtest/include/gtest/gtest.h"
13 #include "ui/base/page_transition_types.h"
15 using chrome_browser_net::NetErrorTabHelper
;
16 using chrome_common_net::DnsProbeStatus
;
18 class TestNetErrorTabHelper
: public NetErrorTabHelper
{
20 TestNetErrorTabHelper()
21 : NetErrorTabHelper(NULL
),
22 mock_probe_running_(false),
23 last_status_sent_(chrome_common_net::DNS_PROBE_MAX
),
24 mock_sent_count_(0) {}
26 void FinishProbe(DnsProbeStatus status
) {
27 EXPECT_TRUE(mock_probe_running_
);
28 OnDnsProbeFinished(status
);
29 mock_probe_running_
= false;
32 bool mock_probe_running() const { return mock_probe_running_
; }
33 DnsProbeStatus
last_status_sent() const { return last_status_sent_
; }
34 int mock_sent_count() const { return mock_sent_count_
; }
37 void StartDnsProbe() override
{
38 EXPECT_FALSE(mock_probe_running_
);
39 mock_probe_running_
= true;
42 void SendInfo() override
{
43 last_status_sent_
= dns_probe_status();
47 bool mock_probe_running_
;
48 DnsProbeStatus last_status_sent_
;
52 class NetErrorTabHelperTest
: public ChromeRenderViewHostTestHarness
{
54 enum MainFrame
{ SUB_FRAME
, MAIN_FRAME
};
55 enum ErrorPage
{ NORMAL_PAGE
, ERROR_PAGE
};
56 enum ErrorType
{ DNS_ERROR
, OTHER_ERROR
};
58 void SetUp() override
{
59 ChromeRenderViewHostTestHarness::SetUp();
61 // This will simulate the initialization of the RenderFrame in the renderer
62 // process. This is needed because WebContents does not initialize a
63 // RenderFrame on construction, and the tests expect one to exist.
64 content::RenderFrameHostTester::For(main_rfh())
65 ->InitializeRenderFrameIfNeeded();
67 subframe_
= content::RenderFrameHostTester::For(main_rfh())
68 ->AppendChild("subframe");
70 tab_helper_
.reset(new TestNetErrorTabHelper
);
71 NetErrorTabHelper::set_state_for_testing(
72 NetErrorTabHelper::TESTING_FORCE_ENABLED
);
75 void StartProvisionalLoad(MainFrame main_frame
, ErrorPage error_page
) {
76 tab_helper_
->DidStartProvisionalLoadForFrame(
77 (main_frame
== MAIN_FRAME
) ? main_rfh() : subframe_
,
78 bogus_url_
, // validated_url
79 (error_page
== ERROR_PAGE
),
80 false); // is_iframe_srcdoc
83 void CommitProvisionalLoad(MainFrame main_frame
) {
84 tab_helper_
->DidCommitProvisionalLoadForFrame(
85 (main_frame
== MAIN_FRAME
) ? main_rfh() : subframe_
,
87 ui::PAGE_TRANSITION_TYPED
);
90 void FailProvisionalLoad(MainFrame main_frame
, ErrorType error_type
) {
93 if (error_type
== DNS_ERROR
)
94 net_error
= net::ERR_NAME_NOT_RESOLVED
;
96 net_error
= net::ERR_TIMED_OUT
;
98 tab_helper_
->DidFailProvisionalLoad(
99 (main_frame
== MAIN_FRAME
) ? main_rfh() : subframe_
,
100 bogus_url_
, // validated_url
106 void FinishProbe(DnsProbeStatus status
) { tab_helper_
->FinishProbe(status
); }
108 bool probe_running() { return tab_helper_
->mock_probe_running(); }
109 DnsProbeStatus
last_status_sent() { return tab_helper_
->last_status_sent(); }
110 int sent_count() { return tab_helper_
->mock_sent_count(); }
113 content::RenderFrameHost
* subframe_
;
114 scoped_ptr
<TestNetErrorTabHelper
> tab_helper_
;
118 TEST_F(NetErrorTabHelperTest
, Null
) {
119 EXPECT_FALSE(probe_running());
122 TEST_F(NetErrorTabHelperTest
, MainFrameNonDnsError
) {
123 StartProvisionalLoad(MAIN_FRAME
, NORMAL_PAGE
);
124 FailProvisionalLoad(MAIN_FRAME
, OTHER_ERROR
);
125 EXPECT_FALSE(probe_running());
126 EXPECT_EQ(0, sent_count());
129 TEST_F(NetErrorTabHelperTest
, NonMainFrameDnsError
) {
130 StartProvisionalLoad(SUB_FRAME
, NORMAL_PAGE
);
131 FailProvisionalLoad(SUB_FRAME
, DNS_ERROR
);
132 EXPECT_FALSE(probe_running());
133 EXPECT_EQ(0, sent_count());
136 // Test complete DNS error page loads. Note that the helper can see two error
137 // page loads: Link Doctor loads an empty HTML page so the user knows something
138 // is going on, then fails over to the normal error page if and when Link
139 // Doctor fails to load or declines to provide a page.
141 TEST_F(NetErrorTabHelperTest
, ProbeResponseBeforeFirstCommit
) {
142 StartProvisionalLoad(MAIN_FRAME
, NORMAL_PAGE
);
143 FailProvisionalLoad(MAIN_FRAME
, DNS_ERROR
);
144 EXPECT_TRUE(probe_running());
145 EXPECT_EQ(0, sent_count());
147 StartProvisionalLoad(MAIN_FRAME
, ERROR_PAGE
);
148 EXPECT_TRUE(probe_running());
149 EXPECT_EQ(0, sent_count());
151 FinishProbe(chrome_common_net::DNS_PROBE_FINISHED_NXDOMAIN
);
152 EXPECT_FALSE(probe_running());
153 EXPECT_EQ(0, sent_count());
155 CommitProvisionalLoad(MAIN_FRAME
);
156 EXPECT_FALSE(probe_running());
157 EXPECT_EQ(1, sent_count());
158 EXPECT_EQ(chrome_common_net::DNS_PROBE_FINISHED_NXDOMAIN
, last_status_sent());
160 StartProvisionalLoad(MAIN_FRAME
, ERROR_PAGE
);
161 EXPECT_FALSE(probe_running());
162 EXPECT_EQ(1, sent_count());
164 CommitProvisionalLoad(MAIN_FRAME
);
165 EXPECT_FALSE(probe_running());
166 EXPECT_EQ(2, sent_count());
167 EXPECT_EQ(chrome_common_net::DNS_PROBE_FINISHED_NXDOMAIN
, last_status_sent());
170 TEST_F(NetErrorTabHelperTest
, ProbeResponseBetweenFirstAndSecondCommit
) {
171 StartProvisionalLoad(MAIN_FRAME
, NORMAL_PAGE
);
172 FailProvisionalLoad(MAIN_FRAME
, DNS_ERROR
);
173 EXPECT_TRUE(probe_running());
174 EXPECT_EQ(0, sent_count());
176 StartProvisionalLoad(MAIN_FRAME
, ERROR_PAGE
);
177 EXPECT_TRUE(probe_running());
178 EXPECT_EQ(0, sent_count());
180 CommitProvisionalLoad(MAIN_FRAME
);
181 EXPECT_TRUE(probe_running());
182 EXPECT_EQ(1, sent_count());
183 EXPECT_EQ(chrome_common_net::DNS_PROBE_STARTED
, last_status_sent());
185 FinishProbe(chrome_common_net::DNS_PROBE_FINISHED_NXDOMAIN
);
186 EXPECT_FALSE(probe_running());
187 EXPECT_EQ(2, sent_count());
188 EXPECT_EQ(chrome_common_net::DNS_PROBE_FINISHED_NXDOMAIN
, last_status_sent());
190 StartProvisionalLoad(MAIN_FRAME
, ERROR_PAGE
);
191 EXPECT_FALSE(probe_running());
192 EXPECT_EQ(2, sent_count());
194 CommitProvisionalLoad(MAIN_FRAME
);
195 EXPECT_FALSE(probe_running());
196 EXPECT_EQ(3, sent_count());
197 EXPECT_EQ(chrome_common_net::DNS_PROBE_FINISHED_NXDOMAIN
, last_status_sent());
200 TEST_F(NetErrorTabHelperTest
, ProbeResponseAfterSecondCommit
) {
201 StartProvisionalLoad(MAIN_FRAME
, NORMAL_PAGE
);
202 FailProvisionalLoad(MAIN_FRAME
, DNS_ERROR
);
203 EXPECT_TRUE(probe_running());
204 EXPECT_EQ(0, sent_count());
206 StartProvisionalLoad(MAIN_FRAME
, ERROR_PAGE
);
207 EXPECT_TRUE(probe_running());
208 EXPECT_EQ(0, sent_count());
210 CommitProvisionalLoad(MAIN_FRAME
);
211 EXPECT_TRUE(probe_running());
212 EXPECT_EQ(1, sent_count());
213 EXPECT_EQ(chrome_common_net::DNS_PROBE_STARTED
, last_status_sent());
215 StartProvisionalLoad(MAIN_FRAME
, ERROR_PAGE
);
216 EXPECT_TRUE(probe_running());
217 EXPECT_EQ(1, sent_count());
219 CommitProvisionalLoad(MAIN_FRAME
);
220 EXPECT_TRUE(probe_running());
221 EXPECT_EQ(2, sent_count());
222 EXPECT_EQ(chrome_common_net::DNS_PROBE_STARTED
, last_status_sent());
224 FinishProbe(chrome_common_net::DNS_PROBE_FINISHED_NXDOMAIN
);
225 EXPECT_FALSE(probe_running());
226 EXPECT_EQ(3, sent_count());
227 EXPECT_EQ(chrome_common_net::DNS_PROBE_FINISHED_NXDOMAIN
, last_status_sent());
230 // Send result even if a new page load has started; the error page is still
231 // visible, and the user might cancel the load.
232 TEST_F(NetErrorTabHelperTest
, ProbeResponseAfterNewStart
) {
233 StartProvisionalLoad(MAIN_FRAME
, NORMAL_PAGE
);
234 FailProvisionalLoad(MAIN_FRAME
, DNS_ERROR
);
235 EXPECT_TRUE(probe_running());
236 EXPECT_EQ(0, sent_count());
238 StartProvisionalLoad(MAIN_FRAME
, ERROR_PAGE
);
239 EXPECT_TRUE(probe_running());
240 EXPECT_EQ(0, sent_count());
242 CommitProvisionalLoad(MAIN_FRAME
);
243 EXPECT_TRUE(probe_running());
244 EXPECT_EQ(1, sent_count());
245 EXPECT_EQ(chrome_common_net::DNS_PROBE_STARTED
, last_status_sent());
247 StartProvisionalLoad(MAIN_FRAME
, ERROR_PAGE
);
248 EXPECT_TRUE(probe_running());
249 EXPECT_EQ(1, sent_count());
251 CommitProvisionalLoad(MAIN_FRAME
);
252 EXPECT_TRUE(probe_running());
253 EXPECT_EQ(2, sent_count());
254 EXPECT_EQ(chrome_common_net::DNS_PROBE_STARTED
, last_status_sent());
256 StartProvisionalLoad(MAIN_FRAME
, NORMAL_PAGE
);
257 EXPECT_TRUE(probe_running());
258 EXPECT_EQ(2, sent_count());
260 FinishProbe(chrome_common_net::DNS_PROBE_FINISHED_NXDOMAIN
);
261 EXPECT_FALSE(probe_running());
262 EXPECT_EQ(3, sent_count());
263 EXPECT_EQ(chrome_common_net::DNS_PROBE_FINISHED_NXDOMAIN
, last_status_sent());
266 // Don't send result if a new page has committed; the result would go to the
267 // wrong page, and the error page is gone anyway.
268 TEST_F(NetErrorTabHelperTest
, ProbeResponseAfterNewCommit
) {
269 StartProvisionalLoad(MAIN_FRAME
, NORMAL_PAGE
);
270 FailProvisionalLoad(MAIN_FRAME
, DNS_ERROR
);
271 EXPECT_TRUE(probe_running());
272 EXPECT_EQ(0, sent_count());
274 StartProvisionalLoad(MAIN_FRAME
, ERROR_PAGE
);
275 EXPECT_TRUE(probe_running());
276 EXPECT_EQ(0, sent_count());
278 CommitProvisionalLoad(MAIN_FRAME
);
279 EXPECT_TRUE(probe_running());
280 EXPECT_EQ(1, sent_count());
281 EXPECT_EQ(chrome_common_net::DNS_PROBE_STARTED
, last_status_sent());
283 StartProvisionalLoad(MAIN_FRAME
, ERROR_PAGE
);
284 EXPECT_TRUE(probe_running());
285 EXPECT_EQ(1, sent_count());
287 CommitProvisionalLoad(MAIN_FRAME
);
288 EXPECT_TRUE(probe_running());
289 EXPECT_EQ(2, sent_count());
290 EXPECT_EQ(chrome_common_net::DNS_PROBE_STARTED
, last_status_sent());
292 StartProvisionalLoad(MAIN_FRAME
, NORMAL_PAGE
);
293 EXPECT_TRUE(probe_running());
294 EXPECT_EQ(2, sent_count());
296 CommitProvisionalLoad(MAIN_FRAME
);
297 EXPECT_TRUE(probe_running());
298 EXPECT_EQ(2, sent_count());
300 FinishProbe(chrome_common_net::DNS_PROBE_FINISHED_NXDOMAIN
);
301 EXPECT_FALSE(probe_running());
302 EXPECT_EQ(2, sent_count());
305 TEST_F(NetErrorTabHelperTest
, MultipleDnsErrorsWithProbesWithoutErrorPages
) {
306 StartProvisionalLoad(MAIN_FRAME
, NORMAL_PAGE
);
307 FailProvisionalLoad(MAIN_FRAME
, DNS_ERROR
);
308 EXPECT_TRUE(probe_running());
309 EXPECT_EQ(0, sent_count());
311 FinishProbe(chrome_common_net::DNS_PROBE_FINISHED_NXDOMAIN
);
312 EXPECT_FALSE(probe_running());
313 EXPECT_EQ(0, sent_count());
315 StartProvisionalLoad(MAIN_FRAME
, NORMAL_PAGE
);
316 FailProvisionalLoad(MAIN_FRAME
, DNS_ERROR
);
317 EXPECT_TRUE(probe_running());
318 EXPECT_EQ(0, sent_count());
320 FinishProbe(chrome_common_net::DNS_PROBE_FINISHED_NO_INTERNET
);
321 EXPECT_FALSE(probe_running());
322 EXPECT_EQ(0, sent_count());
325 TEST_F(NetErrorTabHelperTest
, MultipleDnsErrorsWithProbesAndErrorPages
) {
326 StartProvisionalLoad(MAIN_FRAME
, NORMAL_PAGE
);
327 FailProvisionalLoad(MAIN_FRAME
, DNS_ERROR
);
328 EXPECT_TRUE(probe_running());
329 EXPECT_EQ(0, sent_count());
331 StartProvisionalLoad(MAIN_FRAME
, ERROR_PAGE
);
332 CommitProvisionalLoad(MAIN_FRAME
);
333 EXPECT_TRUE(probe_running());
334 EXPECT_EQ(1, sent_count());
335 EXPECT_EQ(chrome_common_net::DNS_PROBE_STARTED
, last_status_sent());
337 FinishProbe(chrome_common_net::DNS_PROBE_FINISHED_NXDOMAIN
);
338 EXPECT_FALSE(probe_running());
339 EXPECT_EQ(2, sent_count());
340 EXPECT_EQ(chrome_common_net::DNS_PROBE_FINISHED_NXDOMAIN
, last_status_sent());
342 StartProvisionalLoad(MAIN_FRAME
, NORMAL_PAGE
);
343 FailProvisionalLoad(MAIN_FRAME
, DNS_ERROR
);
344 EXPECT_TRUE(probe_running());
345 EXPECT_EQ(2, sent_count());
347 StartProvisionalLoad(MAIN_FRAME
, ERROR_PAGE
);
348 CommitProvisionalLoad(MAIN_FRAME
);
349 EXPECT_TRUE(probe_running());
350 EXPECT_EQ(3, sent_count());
351 EXPECT_EQ(chrome_common_net::DNS_PROBE_STARTED
, last_status_sent());
353 FinishProbe(chrome_common_net::DNS_PROBE_FINISHED_NO_INTERNET
);
354 EXPECT_FALSE(probe_running());
355 EXPECT_EQ(4, sent_count());
356 EXPECT_EQ(chrome_common_net::DNS_PROBE_FINISHED_NO_INTERNET
,
360 // If multiple DNS errors occur in a row before a probe result, don't start
362 TEST_F(NetErrorTabHelperTest
, CoalesceFailures
) {
363 StartProvisionalLoad(MAIN_FRAME
, NORMAL_PAGE
);
364 FailProvisionalLoad(MAIN_FRAME
, DNS_ERROR
);
365 StartProvisionalLoad(MAIN_FRAME
, ERROR_PAGE
);
366 CommitProvisionalLoad(MAIN_FRAME
);
367 EXPECT_TRUE(probe_running());
368 EXPECT_EQ(1, sent_count());
369 EXPECT_EQ(chrome_common_net::DNS_PROBE_STARTED
, last_status_sent());
371 StartProvisionalLoad(MAIN_FRAME
, NORMAL_PAGE
);
372 FailProvisionalLoad(MAIN_FRAME
, DNS_ERROR
);
373 StartProvisionalLoad(MAIN_FRAME
, ERROR_PAGE
);
374 CommitProvisionalLoad(MAIN_FRAME
);
375 EXPECT_TRUE(probe_running());
376 EXPECT_EQ(2, sent_count());
377 EXPECT_EQ(chrome_common_net::DNS_PROBE_STARTED
, last_status_sent());
379 StartProvisionalLoad(MAIN_FRAME
, NORMAL_PAGE
);
380 FailProvisionalLoad(MAIN_FRAME
, DNS_ERROR
);
381 StartProvisionalLoad(MAIN_FRAME
, ERROR_PAGE
);
382 CommitProvisionalLoad(MAIN_FRAME
);
383 EXPECT_TRUE(probe_running());
384 EXPECT_EQ(3, sent_count());
385 EXPECT_EQ(chrome_common_net::DNS_PROBE_STARTED
, last_status_sent());
387 FinishProbe(chrome_common_net::DNS_PROBE_FINISHED_NXDOMAIN
);
388 EXPECT_FALSE(probe_running());
389 EXPECT_EQ(4, sent_count());
390 EXPECT_EQ(chrome_common_net::DNS_PROBE_FINISHED_NXDOMAIN
, last_status_sent());