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