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 (main_frame == MAIN_FRAME), 82 bogus_url_, // url 83 content::PAGE_TRANSITION_TYPED, 84 NULL); // render_view_host 85 } 86 87 void FailProvisionalLoad(MainFrame main_frame, ErrorType error_type) { 88 int net_error; 89 90 if (error_type == DNS_ERROR) 91 net_error = net::ERR_NAME_NOT_RESOLVED; 92 else 93 net_error = net::ERR_TIMED_OUT; 94 95 tab_helper_.DidFailProvisionalLoad( 96 1, // frame id 97 (main_frame == MAIN_FRAME), 98 bogus_url_, // validated_url 99 net_error, 100 string16(), 101 NULL); // render_view_host 102 } 103 104 void FinishProbe(DnsProbeStatus status) { 105 tab_helper_.FinishProbe(status); 106 } 107 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(); } 111 112 private: 113 MessageLoop message_loop_; 114 TestBrowserThread fake_ui_thread_; 115 TestNetErrorTabHelper tab_helper_; 116 GURL bogus_url_; 117 }; 118 119 TEST_F(NetErrorTabHelperTest, Null) { 120 EXPECT_FALSE(probe_running()); 121 } 122 123 TEST_F(NetErrorTabHelperTest, MainFrameNonDnsError) { 124 StartProvisionalLoad(MAIN_FRAME, NORMAL_PAGE); 125 FailProvisionalLoad(MAIN_FRAME, OTHER_ERROR); 126 EXPECT_FALSE(probe_running()); 127 EXPECT_EQ(0, sent_count()); 128 } 129 130 TEST_F(NetErrorTabHelperTest, NonMainFrameDnsError) { 131 StartProvisionalLoad(SUB_FRAME, NORMAL_PAGE); 132 FailProvisionalLoad(SUB_FRAME, DNS_ERROR); 133 EXPECT_FALSE(probe_running()); 134 EXPECT_EQ(0, sent_count()); 135 } 136 137 // Test complete DNS error page loads. Note that the helper can see two error 138 // page loads: Link Doctor loads an empty HTML page so the user knows something 139 // is going on, then fails over to the normal error page if and when Link 140 // Doctor fails to load or declines to provide a page. 141 142 TEST_F(NetErrorTabHelperTest, ProbeResponseBeforeFirstCommit) { 143 StartProvisionalLoad(MAIN_FRAME, NORMAL_PAGE); 144 FailProvisionalLoad(MAIN_FRAME, DNS_ERROR); 145 EXPECT_TRUE(probe_running()); 146 EXPECT_EQ(0, sent_count()); 147 148 StartProvisionalLoad(MAIN_FRAME, ERROR_PAGE); 149 EXPECT_TRUE(probe_running()); 150 EXPECT_EQ(0, sent_count()); 151 152 FinishProbe(chrome_common_net::DNS_PROBE_FINISHED_NXDOMAIN); 153 EXPECT_FALSE(probe_running()); 154 EXPECT_EQ(0, sent_count()); 155 156 CommitProvisionalLoad(MAIN_FRAME); 157 EXPECT_FALSE(probe_running()); 158 EXPECT_EQ(1, sent_count()); 159 EXPECT_EQ(chrome_common_net::DNS_PROBE_FINISHED_NXDOMAIN, last_status_sent()); 160 161 StartProvisionalLoad(MAIN_FRAME, ERROR_PAGE); 162 EXPECT_FALSE(probe_running()); 163 EXPECT_EQ(1, sent_count()); 164 165 CommitProvisionalLoad(MAIN_FRAME); 166 EXPECT_FALSE(probe_running()); 167 EXPECT_EQ(2, sent_count()); 168 EXPECT_EQ(chrome_common_net::DNS_PROBE_FINISHED_NXDOMAIN, last_status_sent()); 169 } 170 171 TEST_F(NetErrorTabHelperTest, ProbeResponseBetweenFirstAndSecondCommit) { 172 StartProvisionalLoad(MAIN_FRAME, NORMAL_PAGE); 173 FailProvisionalLoad(MAIN_FRAME, DNS_ERROR); 174 EXPECT_TRUE(probe_running()); 175 EXPECT_EQ(0, sent_count()); 176 177 StartProvisionalLoad(MAIN_FRAME, ERROR_PAGE); 178 EXPECT_TRUE(probe_running()); 179 EXPECT_EQ(0, sent_count()); 180 181 CommitProvisionalLoad(MAIN_FRAME); 182 EXPECT_TRUE(probe_running()); 183 EXPECT_EQ(1, sent_count()); 184 EXPECT_EQ(chrome_common_net::DNS_PROBE_STARTED, last_status_sent()); 185 186 FinishProbe(chrome_common_net::DNS_PROBE_FINISHED_NXDOMAIN); 187 EXPECT_FALSE(probe_running()); 188 EXPECT_EQ(2, sent_count()); 189 EXPECT_EQ(chrome_common_net::DNS_PROBE_FINISHED_NXDOMAIN, last_status_sent()); 190 191 StartProvisionalLoad(MAIN_FRAME, ERROR_PAGE); 192 EXPECT_FALSE(probe_running()); 193 EXPECT_EQ(2, sent_count()); 194 195 CommitProvisionalLoad(MAIN_FRAME); 196 EXPECT_FALSE(probe_running()); 197 EXPECT_EQ(3, sent_count()); 198 EXPECT_EQ(chrome_common_net::DNS_PROBE_FINISHED_NXDOMAIN, last_status_sent()); 199 } 200 201 TEST_F(NetErrorTabHelperTest, ProbeResponseAfterSecondCommit) { 202 StartProvisionalLoad(MAIN_FRAME, NORMAL_PAGE); 203 FailProvisionalLoad(MAIN_FRAME, DNS_ERROR); 204 EXPECT_TRUE(probe_running()); 205 EXPECT_EQ(0, sent_count()); 206 207 StartProvisionalLoad(MAIN_FRAME, ERROR_PAGE); 208 EXPECT_TRUE(probe_running()); 209 EXPECT_EQ(0, sent_count()); 210 211 CommitProvisionalLoad(MAIN_FRAME); 212 EXPECT_TRUE(probe_running()); 213 EXPECT_EQ(1, sent_count()); 214 EXPECT_EQ(chrome_common_net::DNS_PROBE_STARTED, last_status_sent()); 215 216 StartProvisionalLoad(MAIN_FRAME, ERROR_PAGE); 217 EXPECT_TRUE(probe_running()); 218 EXPECT_EQ(1, sent_count()); 219 220 CommitProvisionalLoad(MAIN_FRAME); 221 EXPECT_TRUE(probe_running()); 222 EXPECT_EQ(2, sent_count()); 223 EXPECT_EQ(chrome_common_net::DNS_PROBE_STARTED, last_status_sent()); 224 225 FinishProbe(chrome_common_net::DNS_PROBE_FINISHED_NXDOMAIN); 226 EXPECT_FALSE(probe_running()); 227 EXPECT_EQ(3, sent_count()); 228 EXPECT_EQ(chrome_common_net::DNS_PROBE_FINISHED_NXDOMAIN, last_status_sent()); 229 } 230 231 // Send result even if a new page load has started; the error page is still 232 // visible, and the user might cancel the load. 233 TEST_F(NetErrorTabHelperTest, ProbeResponseAfterNewStart) { 234 StartProvisionalLoad(MAIN_FRAME, NORMAL_PAGE); 235 FailProvisionalLoad(MAIN_FRAME, DNS_ERROR); 236 EXPECT_TRUE(probe_running()); 237 EXPECT_EQ(0, sent_count()); 238 239 StartProvisionalLoad(MAIN_FRAME, ERROR_PAGE); 240 EXPECT_TRUE(probe_running()); 241 EXPECT_EQ(0, sent_count()); 242 243 CommitProvisionalLoad(MAIN_FRAME); 244 EXPECT_TRUE(probe_running()); 245 EXPECT_EQ(1, sent_count()); 246 EXPECT_EQ(chrome_common_net::DNS_PROBE_STARTED, last_status_sent()); 247 248 StartProvisionalLoad(MAIN_FRAME, ERROR_PAGE); 249 EXPECT_TRUE(probe_running()); 250 EXPECT_EQ(1, sent_count()); 251 252 CommitProvisionalLoad(MAIN_FRAME); 253 EXPECT_TRUE(probe_running()); 254 EXPECT_EQ(2, sent_count()); 255 EXPECT_EQ(chrome_common_net::DNS_PROBE_STARTED, last_status_sent()); 256 257 StartProvisionalLoad(MAIN_FRAME, NORMAL_PAGE); 258 EXPECT_TRUE(probe_running()); 259 EXPECT_EQ(2, sent_count()); 260 261 FinishProbe(chrome_common_net::DNS_PROBE_FINISHED_NXDOMAIN); 262 EXPECT_FALSE(probe_running()); 263 EXPECT_EQ(3, sent_count()); 264 EXPECT_EQ(chrome_common_net::DNS_PROBE_FINISHED_NXDOMAIN, last_status_sent()); 265 } 266 267 // Don't send result if a new page has committed; the result would go to the 268 // wrong page, and the error page is gone anyway. 269 TEST_F(NetErrorTabHelperTest, ProbeResponseAfterNewCommit) { 270 StartProvisionalLoad(MAIN_FRAME, NORMAL_PAGE); 271 FailProvisionalLoad(MAIN_FRAME, DNS_ERROR); 272 EXPECT_TRUE(probe_running()); 273 EXPECT_EQ(0, sent_count()); 274 275 StartProvisionalLoad(MAIN_FRAME, ERROR_PAGE); 276 EXPECT_TRUE(probe_running()); 277 EXPECT_EQ(0, sent_count()); 278 279 CommitProvisionalLoad(MAIN_FRAME); 280 EXPECT_TRUE(probe_running()); 281 EXPECT_EQ(1, sent_count()); 282 EXPECT_EQ(chrome_common_net::DNS_PROBE_STARTED, last_status_sent()); 283 284 StartProvisionalLoad(MAIN_FRAME, ERROR_PAGE); 285 EXPECT_TRUE(probe_running()); 286 EXPECT_EQ(1, sent_count()); 287 288 CommitProvisionalLoad(MAIN_FRAME); 289 EXPECT_TRUE(probe_running()); 290 EXPECT_EQ(2, sent_count()); 291 EXPECT_EQ(chrome_common_net::DNS_PROBE_STARTED, last_status_sent()); 292 293 StartProvisionalLoad(MAIN_FRAME, NORMAL_PAGE); 294 EXPECT_TRUE(probe_running()); 295 EXPECT_EQ(2, sent_count()); 296 297 CommitProvisionalLoad(MAIN_FRAME); 298 EXPECT_TRUE(probe_running()); 299 EXPECT_EQ(2, sent_count()); 300 301 FinishProbe(chrome_common_net::DNS_PROBE_FINISHED_NXDOMAIN); 302 EXPECT_FALSE(probe_running()); 303 EXPECT_EQ(2, sent_count()); 304 } 305 306 TEST_F(NetErrorTabHelperTest, MultipleDnsErrorsWithProbesWithoutErrorPages) { 307 StartProvisionalLoad(MAIN_FRAME, NORMAL_PAGE); 308 FailProvisionalLoad(MAIN_FRAME, DNS_ERROR); 309 EXPECT_TRUE(probe_running()); 310 EXPECT_EQ(0, sent_count()); 311 312 FinishProbe(chrome_common_net::DNS_PROBE_FINISHED_NXDOMAIN); 313 EXPECT_FALSE(probe_running()); 314 EXPECT_EQ(0, sent_count()); 315 316 StartProvisionalLoad(MAIN_FRAME, NORMAL_PAGE); 317 FailProvisionalLoad(MAIN_FRAME, DNS_ERROR); 318 EXPECT_TRUE(probe_running()); 319 EXPECT_EQ(0, sent_count()); 320 321 FinishProbe(chrome_common_net::DNS_PROBE_FINISHED_NO_INTERNET); 322 EXPECT_FALSE(probe_running()); 323 EXPECT_EQ(0, sent_count()); 324 } 325 326 TEST_F(NetErrorTabHelperTest, MultipleDnsErrorsWithProbesAndErrorPages) { 327 StartProvisionalLoad(MAIN_FRAME, NORMAL_PAGE); 328 FailProvisionalLoad(MAIN_FRAME, DNS_ERROR); 329 EXPECT_TRUE(probe_running()); 330 EXPECT_EQ(0, sent_count()); 331 332 StartProvisionalLoad(MAIN_FRAME, ERROR_PAGE); 333 CommitProvisionalLoad(MAIN_FRAME); 334 EXPECT_TRUE(probe_running()); 335 EXPECT_EQ(1, sent_count()); 336 EXPECT_EQ(chrome_common_net::DNS_PROBE_STARTED, last_status_sent()); 337 338 FinishProbe(chrome_common_net::DNS_PROBE_FINISHED_NXDOMAIN); 339 EXPECT_FALSE(probe_running()); 340 EXPECT_EQ(2, sent_count()); 341 EXPECT_EQ(chrome_common_net::DNS_PROBE_FINISHED_NXDOMAIN, last_status_sent()); 342 343 StartProvisionalLoad(MAIN_FRAME, NORMAL_PAGE); 344 FailProvisionalLoad(MAIN_FRAME, DNS_ERROR); 345 EXPECT_TRUE(probe_running()); 346 EXPECT_EQ(2, sent_count()); 347 348 StartProvisionalLoad(MAIN_FRAME, ERROR_PAGE); 349 CommitProvisionalLoad(MAIN_FRAME); 350 EXPECT_TRUE(probe_running()); 351 EXPECT_EQ(3, sent_count()); 352 EXPECT_EQ(chrome_common_net::DNS_PROBE_STARTED, last_status_sent()); 353 354 FinishProbe(chrome_common_net::DNS_PROBE_FINISHED_NO_INTERNET); 355 EXPECT_FALSE(probe_running()); 356 EXPECT_EQ(4, sent_count()); 357 EXPECT_EQ(chrome_common_net::DNS_PROBE_FINISHED_NO_INTERNET, 358 last_status_sent()); 359 } 360 361 // If multiple DNS errors occur in a row before a probe result, don't start 362 // multiple probes. 363 TEST_F(NetErrorTabHelperTest, CoalesceFailures) { 364 StartProvisionalLoad(MAIN_FRAME, NORMAL_PAGE); 365 FailProvisionalLoad(MAIN_FRAME, DNS_ERROR); 366 StartProvisionalLoad(MAIN_FRAME, ERROR_PAGE); 367 CommitProvisionalLoad(MAIN_FRAME); 368 EXPECT_TRUE(probe_running()); 369 EXPECT_EQ(1, sent_count()); 370 EXPECT_EQ(chrome_common_net::DNS_PROBE_STARTED, last_status_sent()); 371 372 StartProvisionalLoad(MAIN_FRAME, NORMAL_PAGE); 373 FailProvisionalLoad(MAIN_FRAME, DNS_ERROR); 374 StartProvisionalLoad(MAIN_FRAME, ERROR_PAGE); 375 CommitProvisionalLoad(MAIN_FRAME); 376 EXPECT_TRUE(probe_running()); 377 EXPECT_EQ(2, sent_count()); 378 EXPECT_EQ(chrome_common_net::DNS_PROBE_STARTED, last_status_sent()); 379 380 StartProvisionalLoad(MAIN_FRAME, NORMAL_PAGE); 381 FailProvisionalLoad(MAIN_FRAME, DNS_ERROR); 382 StartProvisionalLoad(MAIN_FRAME, ERROR_PAGE); 383 CommitProvisionalLoad(MAIN_FRAME); 384 EXPECT_TRUE(probe_running()); 385 EXPECT_EQ(3, sent_count()); 386 EXPECT_EQ(chrome_common_net::DNS_PROBE_STARTED, last_status_sent()); 387 388 FinishProbe(chrome_common_net::DNS_PROBE_FINISHED_NXDOMAIN); 389 EXPECT_FALSE(probe_running()); 390 EXPECT_EQ(4, sent_count()); 391 EXPECT_EQ(chrome_common_net::DNS_PROBE_FINISHED_NXDOMAIN, last_status_sent()); 392 } 393