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. 4 5 #include "chrome/browser/net/net_error_tab_helper.h" 6 7 #include "chrome/common/net/net_error_info.h" 8 #include "chrome/test/base/chrome_render_view_host_test_harness.h" 9 #include "content/public/browser/browser_thread.h" 10 #include "net/base/net_errors.h" 11 #include "testing/gtest/include/gtest/gtest.h" 12 #include "ui/base/page_transition_types.h" 13 14 using chrome_browser_net::NetErrorTabHelper; 15 using chrome_common_net::DnsProbeStatus; 16 17 class TestNetErrorTabHelper : public NetErrorTabHelper { 18 public: 19 TestNetErrorTabHelper() 20 : NetErrorTabHelper(NULL), 21 mock_probe_running_(false), 22 last_status_sent_(chrome_common_net::DNS_PROBE_MAX), 23 mock_sent_count_(0) {} 24 25 void FinishProbe(DnsProbeStatus status) { 26 EXPECT_TRUE(mock_probe_running_); 27 OnDnsProbeFinished(status); 28 mock_probe_running_ = false; 29 } 30 31 bool mock_probe_running() const { return mock_probe_running_; } 32 DnsProbeStatus last_status_sent() const { return last_status_sent_; } 33 int mock_sent_count() const { return mock_sent_count_; } 34 35 private: 36 virtual void StartDnsProbe() OVERRIDE { 37 EXPECT_FALSE(mock_probe_running_); 38 mock_probe_running_ = true; 39 } 40 41 virtual void SendInfo() OVERRIDE { 42 last_status_sent_ = dns_probe_status(); 43 mock_sent_count_++; 44 } 45 46 bool mock_probe_running_; 47 DnsProbeStatus last_status_sent_; 48 int mock_sent_count_; 49 }; 50 51 class NetErrorTabHelperTest : public ChromeRenderViewHostTestHarness { 52 protected: 53 enum MainFrame { SUB_FRAME, MAIN_FRAME }; 54 enum ErrorPage { NORMAL_PAGE, ERROR_PAGE }; 55 enum ErrorType { DNS_ERROR, OTHER_ERROR }; 56 57 virtual void SetUp() OVERRIDE { 58 ChromeRenderViewHostTestHarness::SetUp(); 59 subframe_ = content::RenderFrameHostTester::For(main_rfh()) 60 ->AppendChild("subframe"); 61 62 tab_helper_.reset(new TestNetErrorTabHelper); 63 NetErrorTabHelper::set_state_for_testing( 64 NetErrorTabHelper::TESTING_FORCE_ENABLED); 65 } 66 67 void StartProvisionalLoad(MainFrame main_frame, ErrorPage error_page) { 68 tab_helper_->DidStartProvisionalLoadForFrame( 69 (main_frame == MAIN_FRAME) ? main_rfh() : subframe_, 70 bogus_url_, // validated_url 71 (error_page == ERROR_PAGE), 72 false); // is_iframe_srcdoc 73 } 74 75 void CommitProvisionalLoad(MainFrame main_frame) { 76 tab_helper_->DidCommitProvisionalLoadForFrame( 77 (main_frame == MAIN_FRAME) ? main_rfh() : subframe_, 78 bogus_url_, // url 79 ui::PAGE_TRANSITION_TYPED); 80 } 81 82 void FailProvisionalLoad(MainFrame main_frame, ErrorType error_type) { 83 int net_error; 84 85 if (error_type == DNS_ERROR) 86 net_error = net::ERR_NAME_NOT_RESOLVED; 87 else 88 net_error = net::ERR_TIMED_OUT; 89 90 tab_helper_->DidFailProvisionalLoad( 91 (main_frame == MAIN_FRAME) ? main_rfh() : subframe_, 92 bogus_url_, // validated_url 93 net_error, 94 base::string16()); 95 } 96 97 void FinishProbe(DnsProbeStatus status) { tab_helper_->FinishProbe(status); } 98 99 bool probe_running() { return tab_helper_->mock_probe_running(); } 100 DnsProbeStatus last_status_sent() { return tab_helper_->last_status_sent(); } 101 int sent_count() { return tab_helper_->mock_sent_count(); } 102 103 private: 104 content::RenderFrameHost* subframe_; 105 scoped_ptr<TestNetErrorTabHelper> tab_helper_; 106 GURL bogus_url_; 107 }; 108 109 TEST_F(NetErrorTabHelperTest, Null) { 110 EXPECT_FALSE(probe_running()); 111 } 112 113 TEST_F(NetErrorTabHelperTest, MainFrameNonDnsError) { 114 StartProvisionalLoad(MAIN_FRAME, NORMAL_PAGE); 115 FailProvisionalLoad(MAIN_FRAME, OTHER_ERROR); 116 EXPECT_FALSE(probe_running()); 117 EXPECT_EQ(0, sent_count()); 118 } 119 120 TEST_F(NetErrorTabHelperTest, NonMainFrameDnsError) { 121 StartProvisionalLoad(SUB_FRAME, NORMAL_PAGE); 122 FailProvisionalLoad(SUB_FRAME, DNS_ERROR); 123 EXPECT_FALSE(probe_running()); 124 EXPECT_EQ(0, sent_count()); 125 } 126 127 // Test complete DNS error page loads. Note that the helper can see two error 128 // page loads: Link Doctor loads an empty HTML page so the user knows something 129 // is going on, then fails over to the normal error page if and when Link 130 // Doctor fails to load or declines to provide a page. 131 132 TEST_F(NetErrorTabHelperTest, ProbeResponseBeforeFirstCommit) { 133 StartProvisionalLoad(MAIN_FRAME, NORMAL_PAGE); 134 FailProvisionalLoad(MAIN_FRAME, DNS_ERROR); 135 EXPECT_TRUE(probe_running()); 136 EXPECT_EQ(0, sent_count()); 137 138 StartProvisionalLoad(MAIN_FRAME, ERROR_PAGE); 139 EXPECT_TRUE(probe_running()); 140 EXPECT_EQ(0, sent_count()); 141 142 FinishProbe(chrome_common_net::DNS_PROBE_FINISHED_NXDOMAIN); 143 EXPECT_FALSE(probe_running()); 144 EXPECT_EQ(0, sent_count()); 145 146 CommitProvisionalLoad(MAIN_FRAME); 147 EXPECT_FALSE(probe_running()); 148 EXPECT_EQ(1, sent_count()); 149 EXPECT_EQ(chrome_common_net::DNS_PROBE_FINISHED_NXDOMAIN, last_status_sent()); 150 151 StartProvisionalLoad(MAIN_FRAME, ERROR_PAGE); 152 EXPECT_FALSE(probe_running()); 153 EXPECT_EQ(1, sent_count()); 154 155 CommitProvisionalLoad(MAIN_FRAME); 156 EXPECT_FALSE(probe_running()); 157 EXPECT_EQ(2, sent_count()); 158 EXPECT_EQ(chrome_common_net::DNS_PROBE_FINISHED_NXDOMAIN, last_status_sent()); 159 } 160 161 TEST_F(NetErrorTabHelperTest, ProbeResponseBetweenFirstAndSecondCommit) { 162 StartProvisionalLoad(MAIN_FRAME, NORMAL_PAGE); 163 FailProvisionalLoad(MAIN_FRAME, DNS_ERROR); 164 EXPECT_TRUE(probe_running()); 165 EXPECT_EQ(0, sent_count()); 166 167 StartProvisionalLoad(MAIN_FRAME, ERROR_PAGE); 168 EXPECT_TRUE(probe_running()); 169 EXPECT_EQ(0, sent_count()); 170 171 CommitProvisionalLoad(MAIN_FRAME); 172 EXPECT_TRUE(probe_running()); 173 EXPECT_EQ(1, sent_count()); 174 EXPECT_EQ(chrome_common_net::DNS_PROBE_STARTED, last_status_sent()); 175 176 FinishProbe(chrome_common_net::DNS_PROBE_FINISHED_NXDOMAIN); 177 EXPECT_FALSE(probe_running()); 178 EXPECT_EQ(2, sent_count()); 179 EXPECT_EQ(chrome_common_net::DNS_PROBE_FINISHED_NXDOMAIN, last_status_sent()); 180 181 StartProvisionalLoad(MAIN_FRAME, ERROR_PAGE); 182 EXPECT_FALSE(probe_running()); 183 EXPECT_EQ(2, sent_count()); 184 185 CommitProvisionalLoad(MAIN_FRAME); 186 EXPECT_FALSE(probe_running()); 187 EXPECT_EQ(3, sent_count()); 188 EXPECT_EQ(chrome_common_net::DNS_PROBE_FINISHED_NXDOMAIN, last_status_sent()); 189 } 190 191 TEST_F(NetErrorTabHelperTest, ProbeResponseAfterSecondCommit) { 192 StartProvisionalLoad(MAIN_FRAME, NORMAL_PAGE); 193 FailProvisionalLoad(MAIN_FRAME, DNS_ERROR); 194 EXPECT_TRUE(probe_running()); 195 EXPECT_EQ(0, sent_count()); 196 197 StartProvisionalLoad(MAIN_FRAME, ERROR_PAGE); 198 EXPECT_TRUE(probe_running()); 199 EXPECT_EQ(0, sent_count()); 200 201 CommitProvisionalLoad(MAIN_FRAME); 202 EXPECT_TRUE(probe_running()); 203 EXPECT_EQ(1, sent_count()); 204 EXPECT_EQ(chrome_common_net::DNS_PROBE_STARTED, last_status_sent()); 205 206 StartProvisionalLoad(MAIN_FRAME, ERROR_PAGE); 207 EXPECT_TRUE(probe_running()); 208 EXPECT_EQ(1, sent_count()); 209 210 CommitProvisionalLoad(MAIN_FRAME); 211 EXPECT_TRUE(probe_running()); 212 EXPECT_EQ(2, sent_count()); 213 EXPECT_EQ(chrome_common_net::DNS_PROBE_STARTED, last_status_sent()); 214 215 FinishProbe(chrome_common_net::DNS_PROBE_FINISHED_NXDOMAIN); 216 EXPECT_FALSE(probe_running()); 217 EXPECT_EQ(3, sent_count()); 218 EXPECT_EQ(chrome_common_net::DNS_PROBE_FINISHED_NXDOMAIN, last_status_sent()); 219 } 220 221 // Send result even if a new page load has started; the error page is still 222 // visible, and the user might cancel the load. 223 TEST_F(NetErrorTabHelperTest, ProbeResponseAfterNewStart) { 224 StartProvisionalLoad(MAIN_FRAME, NORMAL_PAGE); 225 FailProvisionalLoad(MAIN_FRAME, DNS_ERROR); 226 EXPECT_TRUE(probe_running()); 227 EXPECT_EQ(0, sent_count()); 228 229 StartProvisionalLoad(MAIN_FRAME, ERROR_PAGE); 230 EXPECT_TRUE(probe_running()); 231 EXPECT_EQ(0, sent_count()); 232 233 CommitProvisionalLoad(MAIN_FRAME); 234 EXPECT_TRUE(probe_running()); 235 EXPECT_EQ(1, sent_count()); 236 EXPECT_EQ(chrome_common_net::DNS_PROBE_STARTED, last_status_sent()); 237 238 StartProvisionalLoad(MAIN_FRAME, ERROR_PAGE); 239 EXPECT_TRUE(probe_running()); 240 EXPECT_EQ(1, sent_count()); 241 242 CommitProvisionalLoad(MAIN_FRAME); 243 EXPECT_TRUE(probe_running()); 244 EXPECT_EQ(2, sent_count()); 245 EXPECT_EQ(chrome_common_net::DNS_PROBE_STARTED, last_status_sent()); 246 247 StartProvisionalLoad(MAIN_FRAME, NORMAL_PAGE); 248 EXPECT_TRUE(probe_running()); 249 EXPECT_EQ(2, sent_count()); 250 251 FinishProbe(chrome_common_net::DNS_PROBE_FINISHED_NXDOMAIN); 252 EXPECT_FALSE(probe_running()); 253 EXPECT_EQ(3, sent_count()); 254 EXPECT_EQ(chrome_common_net::DNS_PROBE_FINISHED_NXDOMAIN, last_status_sent()); 255 } 256 257 // Don't send result if a new page has committed; the result would go to the 258 // wrong page, and the error page is gone anyway. 259 TEST_F(NetErrorTabHelperTest, ProbeResponseAfterNewCommit) { 260 StartProvisionalLoad(MAIN_FRAME, NORMAL_PAGE); 261 FailProvisionalLoad(MAIN_FRAME, DNS_ERROR); 262 EXPECT_TRUE(probe_running()); 263 EXPECT_EQ(0, sent_count()); 264 265 StartProvisionalLoad(MAIN_FRAME, ERROR_PAGE); 266 EXPECT_TRUE(probe_running()); 267 EXPECT_EQ(0, sent_count()); 268 269 CommitProvisionalLoad(MAIN_FRAME); 270 EXPECT_TRUE(probe_running()); 271 EXPECT_EQ(1, sent_count()); 272 EXPECT_EQ(chrome_common_net::DNS_PROBE_STARTED, last_status_sent()); 273 274 StartProvisionalLoad(MAIN_FRAME, ERROR_PAGE); 275 EXPECT_TRUE(probe_running()); 276 EXPECT_EQ(1, sent_count()); 277 278 CommitProvisionalLoad(MAIN_FRAME); 279 EXPECT_TRUE(probe_running()); 280 EXPECT_EQ(2, sent_count()); 281 EXPECT_EQ(chrome_common_net::DNS_PROBE_STARTED, last_status_sent()); 282 283 StartProvisionalLoad(MAIN_FRAME, NORMAL_PAGE); 284 EXPECT_TRUE(probe_running()); 285 EXPECT_EQ(2, sent_count()); 286 287 CommitProvisionalLoad(MAIN_FRAME); 288 EXPECT_TRUE(probe_running()); 289 EXPECT_EQ(2, sent_count()); 290 291 FinishProbe(chrome_common_net::DNS_PROBE_FINISHED_NXDOMAIN); 292 EXPECT_FALSE(probe_running()); 293 EXPECT_EQ(2, sent_count()); 294 } 295 296 TEST_F(NetErrorTabHelperTest, MultipleDnsErrorsWithProbesWithoutErrorPages) { 297 StartProvisionalLoad(MAIN_FRAME, NORMAL_PAGE); 298 FailProvisionalLoad(MAIN_FRAME, DNS_ERROR); 299 EXPECT_TRUE(probe_running()); 300 EXPECT_EQ(0, sent_count()); 301 302 FinishProbe(chrome_common_net::DNS_PROBE_FINISHED_NXDOMAIN); 303 EXPECT_FALSE(probe_running()); 304 EXPECT_EQ(0, sent_count()); 305 306 StartProvisionalLoad(MAIN_FRAME, NORMAL_PAGE); 307 FailProvisionalLoad(MAIN_FRAME, DNS_ERROR); 308 EXPECT_TRUE(probe_running()); 309 EXPECT_EQ(0, sent_count()); 310 311 FinishProbe(chrome_common_net::DNS_PROBE_FINISHED_NO_INTERNET); 312 EXPECT_FALSE(probe_running()); 313 EXPECT_EQ(0, sent_count()); 314 } 315 316 TEST_F(NetErrorTabHelperTest, MultipleDnsErrorsWithProbesAndErrorPages) { 317 StartProvisionalLoad(MAIN_FRAME, NORMAL_PAGE); 318 FailProvisionalLoad(MAIN_FRAME, DNS_ERROR); 319 EXPECT_TRUE(probe_running()); 320 EXPECT_EQ(0, sent_count()); 321 322 StartProvisionalLoad(MAIN_FRAME, ERROR_PAGE); 323 CommitProvisionalLoad(MAIN_FRAME); 324 EXPECT_TRUE(probe_running()); 325 EXPECT_EQ(1, sent_count()); 326 EXPECT_EQ(chrome_common_net::DNS_PROBE_STARTED, last_status_sent()); 327 328 FinishProbe(chrome_common_net::DNS_PROBE_FINISHED_NXDOMAIN); 329 EXPECT_FALSE(probe_running()); 330 EXPECT_EQ(2, sent_count()); 331 EXPECT_EQ(chrome_common_net::DNS_PROBE_FINISHED_NXDOMAIN, last_status_sent()); 332 333 StartProvisionalLoad(MAIN_FRAME, NORMAL_PAGE); 334 FailProvisionalLoad(MAIN_FRAME, DNS_ERROR); 335 EXPECT_TRUE(probe_running()); 336 EXPECT_EQ(2, sent_count()); 337 338 StartProvisionalLoad(MAIN_FRAME, ERROR_PAGE); 339 CommitProvisionalLoad(MAIN_FRAME); 340 EXPECT_TRUE(probe_running()); 341 EXPECT_EQ(3, sent_count()); 342 EXPECT_EQ(chrome_common_net::DNS_PROBE_STARTED, last_status_sent()); 343 344 FinishProbe(chrome_common_net::DNS_PROBE_FINISHED_NO_INTERNET); 345 EXPECT_FALSE(probe_running()); 346 EXPECT_EQ(4, sent_count()); 347 EXPECT_EQ(chrome_common_net::DNS_PROBE_FINISHED_NO_INTERNET, 348 last_status_sent()); 349 } 350 351 // If multiple DNS errors occur in a row before a probe result, don't start 352 // multiple probes. 353 TEST_F(NetErrorTabHelperTest, CoalesceFailures) { 354 StartProvisionalLoad(MAIN_FRAME, NORMAL_PAGE); 355 FailProvisionalLoad(MAIN_FRAME, DNS_ERROR); 356 StartProvisionalLoad(MAIN_FRAME, ERROR_PAGE); 357 CommitProvisionalLoad(MAIN_FRAME); 358 EXPECT_TRUE(probe_running()); 359 EXPECT_EQ(1, sent_count()); 360 EXPECT_EQ(chrome_common_net::DNS_PROBE_STARTED, last_status_sent()); 361 362 StartProvisionalLoad(MAIN_FRAME, NORMAL_PAGE); 363 FailProvisionalLoad(MAIN_FRAME, DNS_ERROR); 364 StartProvisionalLoad(MAIN_FRAME, ERROR_PAGE); 365 CommitProvisionalLoad(MAIN_FRAME); 366 EXPECT_TRUE(probe_running()); 367 EXPECT_EQ(2, sent_count()); 368 EXPECT_EQ(chrome_common_net::DNS_PROBE_STARTED, last_status_sent()); 369 370 StartProvisionalLoad(MAIN_FRAME, NORMAL_PAGE); 371 FailProvisionalLoad(MAIN_FRAME, DNS_ERROR); 372 StartProvisionalLoad(MAIN_FRAME, ERROR_PAGE); 373 CommitProvisionalLoad(MAIN_FRAME); 374 EXPECT_TRUE(probe_running()); 375 EXPECT_EQ(3, sent_count()); 376 EXPECT_EQ(chrome_common_net::DNS_PROBE_STARTED, last_status_sent()); 377 378 FinishProbe(chrome_common_net::DNS_PROBE_FINISHED_NXDOMAIN); 379 EXPECT_FALSE(probe_running()); 380 EXPECT_EQ(4, sent_count()); 381 EXPECT_EQ(chrome_common_net::DNS_PROBE_FINISHED_NXDOMAIN, last_status_sent()); 382 } 383