network_portal_detector_impl_unittest.cc revision effb81e5f8246d0db0270817048dc992db66e9fb
15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2013 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <algorithm> 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <vector> 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/command_line.h" 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/compiler_specific.h" 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/logging.h" 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/scoped_ptr.h" 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/metrics/histogram_base.h" 13868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/metrics/histogram_samples.h" 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/metrics/statistics_recorder.h" 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/run_loop.h" 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/captive_portal/captive_portal_detector.h" 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/captive_portal/testing_utils.h" 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/chromeos/net/network_portal_detector_impl.h" 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/chromeos/net/network_portal_detector_test_utils.h" 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/test/base/testing_profile.h" 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chromeos/chromeos_switches.h" 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chromeos/dbus/dbus_thread_manager.h" 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chromeos/dbus/shill_device_client.h" 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chromeos/dbus/shill_service_client.h" 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chromeos/network/network_state.h" 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chromeos/network/network_state_handler.h" 275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "chromeos/network/shill_property_util.h" 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/test/test_browser_thread_bundle.h" 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "dbus/object_path.h" 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/base/net_errors.h" 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "testing/gmock/include/gmock/gmock.h" 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "testing/gtest/include/gtest/gtest.h" 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "third_party/cros_system_api/dbus/service_constants.h" 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using testing::AnyNumber; 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using testing::Mock; 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using testing::_; 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 39namespace chromeos { 40 41namespace { 42 43// Service paths for stub network devices. 44const char kStubEthernet[] = "stub_ethernet"; 45const char kStubWireless1[] = "stub_wifi1"; 46const char kStubWireless2[] = "stub_wifi2"; 47const char kStubCellular[] = "stub_cellular"; 48 49void ErrorCallbackFunction(const std::string& error_name, 50 const std::string& error_message) { 51 LOG(ERROR) << "Shill Error: " << error_name << " : " << error_message; 52} 53 54class MockObserver : public NetworkPortalDetector::Observer { 55 public: 56 virtual ~MockObserver() {} 57 58 MOCK_METHOD2(OnPortalDetectionCompleted, 59 void(const NetworkState* network, 60 const NetworkPortalDetector::CaptivePortalState& state)); 61}; 62 63} // namespace 64 65class NetworkPortalDetectorImplTest 66 : public testing::Test, 67 public captive_portal::CaptivePortalDetectorTestBase { 68 protected: 69 virtual void SetUp() { 70 CommandLine* cl = CommandLine::ForCurrentProcess(); 71 cl->AppendSwitch(switches::kDisableNetworkPortalNotification); 72 73 DBusThreadManager::InitializeWithStub(); 74 base::StatisticsRecorder::Initialize(); 75 SetupNetworkHandler(); 76 77 profile_.reset(new TestingProfile()); 78 network_portal_detector_.reset( 79 new NetworkPortalDetectorImpl(profile_->GetRequestContext())); 80 network_portal_detector_->Enable(false); 81 82 set_detector(network_portal_detector_->captive_portal_detector_.get()); 83 84 // Prevents flakiness due to message loop delays. 85 set_time_ticks(base::TimeTicks::Now()); 86 87 if (base::HistogramBase* histogram = 88 base::StatisticsRecorder::FindHistogram( 89 "CaptivePortal.OOBE.DetectionResult")) { 90 original_samples_.reset(histogram->SnapshotSamples().release()); 91 } 92 } 93 94 virtual void TearDown() { 95 network_portal_detector_.reset(); 96 profile_.reset(); 97 NetworkHandler::Shutdown(); 98 DBusThreadManager::Shutdown(); 99 PortalDetectorStrategy::reset_fields_for_testing(); 100 } 101 102 void CheckPortalState(NetworkPortalDetector::CaptivePortalStatus status, 103 int response_code, 104 const std::string& service_path) { 105 NetworkPortalDetector::CaptivePortalState state = 106 network_portal_detector()->GetCaptivePortalState(service_path); 107 ASSERT_EQ(status, state.status); 108 ASSERT_EQ(response_code, state.response_code); 109 } 110 111 void CheckRequestTimeoutAndCompleteAttempt(int expected_attempt_count, 112 int expected_request_timeout_sec, 113 int net_error, 114 int status_code) { 115 ASSERT_TRUE(is_state_checking_for_portal()); 116 ASSERT_EQ(expected_attempt_count, attempt_count()); 117 ASSERT_EQ(base::TimeDelta::FromSeconds(expected_request_timeout_sec), 118 get_next_attempt_timeout()); 119 CompleteURLFetch(net_error, status_code, NULL); 120 } 121 122 Profile* profile() { return profile_.get(); } 123 124 NetworkPortalDetectorImpl* network_portal_detector() { 125 return network_portal_detector_.get(); 126 } 127 128 NetworkPortalDetectorImpl::State state() { 129 return network_portal_detector()->state(); 130 } 131 132 bool start_detection_if_idle() { 133 return network_portal_detector()->StartDetectionIfIdle(); 134 } 135 136 void enable_error_screen_strategy() { 137 network_portal_detector()->OnErrorScreenShow(); 138 } 139 140 void disable_error_screen_strategy() { 141 network_portal_detector()->OnErrorScreenHide(); 142 } 143 144 void stop_detection() { network_portal_detector()->StopDetection(); } 145 146 bool attempt_timeout_is_cancelled() { 147 return network_portal_detector()->AttemptTimeoutIsCancelledForTesting(); 148 } 149 150 base::TimeDelta get_next_attempt_timeout() { 151 return network_portal_detector()->strategy_->GetNextAttemptTimeout(); 152 } 153 154 void set_next_attempt_timeout(const base::TimeDelta& timeout) { 155 PortalDetectorStrategy::set_next_attempt_timeout_for_testing(timeout); 156 } 157 158 bool is_state_idle() { 159 return (NetworkPortalDetectorImpl::STATE_IDLE == state()); 160 } 161 162 bool is_state_portal_detection_pending() { 163 return (NetworkPortalDetectorImpl::STATE_PORTAL_CHECK_PENDING == state()); 164 } 165 166 bool is_state_checking_for_portal() { 167 return (NetworkPortalDetectorImpl::STATE_CHECKING_FOR_PORTAL == state()); 168 } 169 170 const base::TimeDelta& next_attempt_delay() { 171 return network_portal_detector()->next_attempt_delay_for_testing(); 172 } 173 174 int attempt_count() { 175 return network_portal_detector()->attempt_count_for_testing(); 176 } 177 178 void set_attempt_count(int ac) { 179 network_portal_detector()->set_attempt_count_for_testing(ac); 180 } 181 182 void set_delay_till_next_attempt(const base::TimeDelta& delta) { 183 PortalDetectorStrategy::set_delay_till_next_attempt_for_testing(delta); 184 } 185 186 void set_time_ticks(const base::TimeTicks& time_ticks) { 187 network_portal_detector()->set_time_ticks_for_testing(time_ticks); 188 } 189 190 void SetBehindPortal(const std::string& service_path) { 191 DBusThreadManager::Get()->GetShillServiceClient()->SetProperty( 192 dbus::ObjectPath(service_path), 193 shill::kStateProperty, 194 base::StringValue(shill::kStatePortal), 195 base::Bind(&base::DoNothing), 196 base::Bind(&ErrorCallbackFunction)); 197 base::RunLoop().RunUntilIdle(); 198 } 199 200 void SetNetworkDeviceEnabled(const std::string& type, bool enabled) { 201 NetworkHandler::Get()->network_state_handler()->SetTechnologyEnabled( 202 NetworkTypePattern::Primitive(type), 203 enabled, 204 network_handler::ErrorCallback()); 205 base::RunLoop().RunUntilIdle(); 206 } 207 208 void SetConnected(const std::string& service_path) { 209 DBusThreadManager::Get()->GetShillServiceClient()->Connect( 210 dbus::ObjectPath(service_path), 211 base::Bind(&base::DoNothing), 212 base::Bind(&ErrorCallbackFunction)); 213 base::RunLoop().RunUntilIdle(); 214 } 215 216 void SetDisconnected(const std::string& service_path) { 217 DBusThreadManager::Get()->GetShillServiceClient()->Disconnect( 218 dbus::ObjectPath(service_path), 219 base::Bind(&*base::DoNothing), 220 base::Bind(&ErrorCallbackFunction)); 221 base::RunLoop().RunUntilIdle(); 222 } 223 224 scoped_ptr<EnumHistogramChecker> MakeResultHistogramChecker() { 225 return scoped_ptr<EnumHistogramChecker>( 226 new EnumHistogramChecker( 227 "CaptivePortal.OOBE.DetectionResult", 228 NetworkPortalDetector::CAPTIVE_PORTAL_STATUS_COUNT, 229 original_samples_.get())); 230 } 231 232 private: 233 void SetupDefaultShillState() { 234 base::RunLoop().RunUntilIdle(); 235 ShillServiceClient::TestInterface* service_test = 236 DBusThreadManager::Get()->GetShillServiceClient()->GetTestInterface(); 237 service_test->ClearServices(); 238 const bool add_to_visible = true; 239 const bool add_to_watchlist = true; 240 service_test->AddService(kStubEthernet, 241 kStubEthernet, 242 shill::kTypeEthernet, 243 shill::kStateIdle, 244 add_to_visible, 245 add_to_watchlist); 246 service_test->AddService(kStubWireless1, 247 kStubWireless1, 248 shill::kTypeWifi, 249 shill::kStateIdle, 250 add_to_visible, 251 add_to_watchlist); 252 service_test->AddService(kStubWireless2, 253 kStubWireless2, 254 shill::kTypeWifi, 255 shill::kStateIdle, 256 add_to_visible, 257 add_to_watchlist); 258 service_test->AddService(kStubCellular, 259 kStubCellular, 260 shill::kTypeCellular, 261 shill::kStateIdle, 262 add_to_visible, 263 add_to_watchlist); 264 } 265 266 void SetupNetworkHandler() { 267 SetupDefaultShillState(); 268 NetworkHandler::Initialize(); 269 } 270 271 content::TestBrowserThreadBundle thread_bundle_; 272 scoped_ptr<TestingProfile> profile_; 273 scoped_ptr<NetworkPortalDetectorImpl> network_portal_detector_; 274 scoped_ptr<base::HistogramSamples> original_samples_; 275}; 276 277TEST_F(NetworkPortalDetectorImplTest, NoPortal) { 278 ASSERT_TRUE(is_state_idle()); 279 280 SetConnected(kStubWireless1); 281 282 ASSERT_TRUE(is_state_checking_for_portal()); 283 CheckPortalState( 284 NetworkPortalDetector::CAPTIVE_PORTAL_STATUS_UNKNOWN, -1, kStubWireless1); 285 286 CompleteURLFetch(net::OK, 204, NULL); 287 288 ASSERT_TRUE(is_state_idle()); 289 CheckPortalState( 290 NetworkPortalDetector::CAPTIVE_PORTAL_STATUS_ONLINE, 204, kStubWireless1); 291 ASSERT_TRUE( 292 MakeResultHistogramChecker() 293 ->Expect(NetworkPortalDetector::CAPTIVE_PORTAL_STATUS_ONLINE, 1) 294 ->Check()); 295} 296 297TEST_F(NetworkPortalDetectorImplTest, Portal) { 298 ASSERT_TRUE(is_state_idle()); 299 300 // Check HTTP 200 response code. 301 SetConnected(kStubWireless1); 302 ASSERT_TRUE(is_state_checking_for_portal()); 303 304 CompleteURLFetch(net::OK, 200, NULL); 305 306 ASSERT_TRUE(is_state_idle()); 307 CheckPortalState( 308 NetworkPortalDetector::CAPTIVE_PORTAL_STATUS_PORTAL, 200, kStubWireless1); 309 310 // Check HTTP 301 response code. 311 SetConnected(kStubWireless2); 312 ASSERT_TRUE(is_state_checking_for_portal()); 313 314 CompleteURLFetch(net::OK, 301, NULL); 315 316 ASSERT_TRUE(is_state_idle()); 317 CheckPortalState( 318 NetworkPortalDetector::CAPTIVE_PORTAL_STATUS_PORTAL, 301, kStubWireless2); 319 320 // Check HTTP 302 response code. 321 SetConnected(kStubEthernet); 322 ASSERT_TRUE(is_state_checking_for_portal()); 323 324 CompleteURLFetch(net::OK, 302, NULL); 325 326 ASSERT_TRUE(is_state_idle()); 327 CheckPortalState( 328 NetworkPortalDetector::CAPTIVE_PORTAL_STATUS_PORTAL, 302, kStubEthernet); 329 330 ASSERT_TRUE( 331 MakeResultHistogramChecker() 332 ->Expect(NetworkPortalDetector::CAPTIVE_PORTAL_STATUS_PORTAL, 3) 333 ->Check()); 334} 335 336TEST_F(NetworkPortalDetectorImplTest, Online2Offline) { 337 ASSERT_TRUE(is_state_idle()); 338 339 MockObserver observer; 340 network_portal_detector()->AddObserver(&observer); 341 342 NetworkPortalDetector::CaptivePortalState offline_state; 343 offline_state.status = NetworkPortalDetector::CAPTIVE_PORTAL_STATUS_OFFLINE; 344 345 // WiFi is in online state. 346 { 347 // When transitioning to a connected state, the network will transition to 348 // connecting states which will set the default network to NULL. This may 349 // get triggered multiple times. 350 EXPECT_CALL(observer, OnPortalDetectionCompleted(_, offline_state)) 351 .Times(AnyNumber()); 352 353 // Expect a single transition to an online state. 354 NetworkPortalDetector::CaptivePortalState online_state; 355 online_state.status = NetworkPortalDetector::CAPTIVE_PORTAL_STATUS_ONLINE; 356 online_state.response_code = 204; 357 EXPECT_CALL(observer, OnPortalDetectionCompleted(_, online_state)).Times(1); 358 359 SetConnected(kStubWireless1); 360 ASSERT_TRUE(is_state_checking_for_portal()); 361 362 CompleteURLFetch(net::OK, 204, NULL); 363 ASSERT_TRUE(is_state_idle()); 364 365 // Check that observer was notified about online state. 366 Mock::VerifyAndClearExpectations(&observer); 367 } 368 369 // WiFi is turned off. 370 { 371 EXPECT_CALL(observer, OnPortalDetectionCompleted(NULL, offline_state)) 372 .Times(1); 373 374 SetDisconnected(kStubWireless1); 375 ASSERT_TRUE(is_state_idle()); 376 377 // Check that observer was notified about offline state. 378 Mock::VerifyAndClearExpectations(&observer); 379 } 380 381 network_portal_detector()->RemoveObserver(&observer); 382 383 ASSERT_TRUE( 384 MakeResultHistogramChecker() 385 ->Expect(NetworkPortalDetector::CAPTIVE_PORTAL_STATUS_ONLINE, 1) 386 ->Check()); 387} 388 389TEST_F(NetworkPortalDetectorImplTest, TwoNetworks) { 390 ASSERT_TRUE(is_state_idle()); 391 392 SetConnected(kStubWireless1); 393 ASSERT_TRUE(is_state_checking_for_portal()); 394 395 // WiFi is in portal state. 396 CompleteURLFetch(net::OK, 200, NULL); 397 ASSERT_TRUE(is_state_idle()); 398 399 SetConnected(kStubEthernet); 400 ASSERT_TRUE(is_state_checking_for_portal()); 401 402 // ethernet is in online state. 403 CompleteURLFetch(net::OK, 204, NULL); 404 ASSERT_TRUE(is_state_idle()); 405 CheckPortalState( 406 NetworkPortalDetector::CAPTIVE_PORTAL_STATUS_ONLINE, 204, kStubEthernet); 407 CheckPortalState( 408 NetworkPortalDetector::CAPTIVE_PORTAL_STATUS_PORTAL, 200, kStubWireless1); 409 410 ASSERT_TRUE( 411 MakeResultHistogramChecker() 412 ->Expect(NetworkPortalDetector::CAPTIVE_PORTAL_STATUS_ONLINE, 1) 413 ->Expect(NetworkPortalDetector::CAPTIVE_PORTAL_STATUS_PORTAL, 1) 414 ->Check()); 415} 416 417TEST_F(NetworkPortalDetectorImplTest, NetworkChanged) { 418 ASSERT_TRUE(is_state_idle()); 419 420 SetConnected(kStubWireless1); 421 422 // WiFi is in portal state. 423 fetcher()->set_response_code(200); 424 ASSERT_TRUE(is_state_checking_for_portal()); 425 426 // Active network is changed during portal detection for WiFi. 427 SetConnected(kStubEthernet); 428 429 // Portal detection for WiFi is cancelled, portal detection for 430 // ethernet is initiated. 431 ASSERT_TRUE(is_state_checking_for_portal()); 432 433 // ethernet is in online state. 434 CompleteURLFetch(net::OK, 204, NULL); 435 ASSERT_TRUE(is_state_idle()); 436 CheckPortalState( 437 NetworkPortalDetector::CAPTIVE_PORTAL_STATUS_ONLINE, 204, kStubEthernet); 438 439 // As active network was changed during portal detection for wifi 440 // network, it's state must be unknown. 441 CheckPortalState( 442 NetworkPortalDetector::CAPTIVE_PORTAL_STATUS_UNKNOWN, -1, kStubWireless1); 443 444 ASSERT_TRUE( 445 MakeResultHistogramChecker() 446 ->Expect(NetworkPortalDetector::CAPTIVE_PORTAL_STATUS_ONLINE, 1) 447 ->Check()); 448} 449 450TEST_F(NetworkPortalDetectorImplTest, NetworkStateNotChanged) { 451 ASSERT_TRUE(is_state_idle()); 452 453 SetConnected(kStubWireless1); 454 ASSERT_TRUE(is_state_checking_for_portal()); 455 456 CompleteURLFetch(net::OK, 204, NULL); 457 458 ASSERT_TRUE(is_state_idle()); 459 CheckPortalState( 460 NetworkPortalDetector::CAPTIVE_PORTAL_STATUS_ONLINE, 204, kStubWireless1); 461 462 SetConnected(kStubWireless1); 463 ASSERT_TRUE(is_state_idle()); 464 465 ASSERT_TRUE( 466 MakeResultHistogramChecker() 467 ->Expect(NetworkPortalDetector::CAPTIVE_PORTAL_STATUS_ONLINE, 1) 468 ->Check()); 469} 470 471TEST_F(NetworkPortalDetectorImplTest, NetworkStateChanged) { 472 // Test for Portal -> Online -> Portal network state transitions. 473 ASSERT_TRUE(is_state_idle()); 474 475 SetBehindPortal(kStubWireless1); 476 ASSERT_TRUE(is_state_checking_for_portal()); 477 478 CompleteURLFetch(net::OK, 200, NULL); 479 480 ASSERT_TRUE(is_state_idle()); 481 CheckPortalState( 482 NetworkPortalDetector::CAPTIVE_PORTAL_STATUS_PORTAL, 200, kStubWireless1); 483 484 SetConnected(kStubWireless1); 485 ASSERT_TRUE(is_state_checking_for_portal()); 486 487 CompleteURLFetch(net::OK, 204, NULL); 488 489 ASSERT_TRUE(is_state_idle()); 490 CheckPortalState( 491 NetworkPortalDetector::CAPTIVE_PORTAL_STATUS_ONLINE, 204, kStubWireless1); 492 493 SetBehindPortal(kStubWireless1); 494 ASSERT_TRUE(is_state_checking_for_portal()); 495 496 CompleteURLFetch(net::OK, 200, NULL); 497 498 ASSERT_TRUE(is_state_idle()); 499 CheckPortalState( 500 NetworkPortalDetector::CAPTIVE_PORTAL_STATUS_PORTAL, 200, kStubWireless1); 501 502 ASSERT_TRUE( 503 MakeResultHistogramChecker() 504 ->Expect(NetworkPortalDetector::CAPTIVE_PORTAL_STATUS_ONLINE, 1) 505 ->Expect(NetworkPortalDetector::CAPTIVE_PORTAL_STATUS_PORTAL, 2) 506 ->Check()); 507} 508 509TEST_F(NetworkPortalDetectorImplTest, PortalDetectionTimeout) { 510 ASSERT_TRUE(is_state_idle()); 511 512 // For instantaneous timeout. 513 set_next_attempt_timeout(base::TimeDelta::FromSeconds(0)); 514 515 ASSERT_TRUE(is_state_idle()); 516 ASSERT_EQ(0, attempt_count()); 517 518 SetConnected(kStubWireless1); 519 base::RunLoop().RunUntilIdle(); 520 521 // First portal detection timeouts, next portal detection is 522 // scheduled. 523 ASSERT_TRUE(is_state_portal_detection_pending()); 524 ASSERT_EQ(1, attempt_count()); 525 ASSERT_EQ(base::TimeDelta::FromSeconds(3), next_attempt_delay()); 526 527 ASSERT_TRUE(MakeResultHistogramChecker()->Check()); 528} 529 530TEST_F(NetworkPortalDetectorImplTest, PortalDetectionRetryAfter) { 531 ASSERT_TRUE(is_state_idle()); 532 533 const char* retry_after = "HTTP/1.1 503 OK\nRetry-After: 101\n\n"; 534 535 ASSERT_TRUE(is_state_idle()); 536 ASSERT_EQ(0, attempt_count()); 537 538 SetConnected(kStubWireless1); 539 ASSERT_TRUE(is_state_checking_for_portal()); 540 CompleteURLFetch(net::OK, 503, retry_after); 541 542 // First portal detection completed, next portal detection is 543 // scheduled after 101 seconds. 544 ASSERT_TRUE(is_state_portal_detection_pending()); 545 ASSERT_EQ(1, attempt_count()); 546 ASSERT_EQ(base::TimeDelta::FromSeconds(101), next_attempt_delay()); 547 548 ASSERT_TRUE(MakeResultHistogramChecker()->Check()); 549} 550 551TEST_F(NetworkPortalDetectorImplTest, PortalDetectorRetryAfterIsSmall) { 552 ASSERT_TRUE(is_state_idle()); 553 554 const char* retry_after = "HTTP/1.1 503 OK\nRetry-After: 1\n\n"; 555 556 ASSERT_TRUE(is_state_idle()); 557 ASSERT_EQ(0, attempt_count()); 558 559 SetConnected(kStubWireless1); 560 CompleteURLFetch(net::OK, 503, retry_after); 561 562 // First portal detection completed, next portal detection is 563 // scheduled after 3 seconds (due to minimum time between detection 564 // attemps). 565 ASSERT_TRUE(is_state_portal_detection_pending()); 566 ASSERT_EQ(1, attempt_count()); 567 ASSERT_EQ(base::TimeDelta::FromSeconds(3), next_attempt_delay()); 568 569 ASSERT_TRUE(MakeResultHistogramChecker()->Check()); 570} 571 572TEST_F(NetworkPortalDetectorImplTest, FirstAttemptFailed) { 573 ASSERT_TRUE(is_state_idle()); 574 575 set_delay_till_next_attempt(base::TimeDelta()); 576 const char* retry_after = "HTTP/1.1 503 OK\nRetry-After: 0\n\n"; 577 578 ASSERT_TRUE(is_state_idle()); 579 ASSERT_EQ(0, attempt_count()); 580 581 SetConnected(kStubWireless1); 582 583 CompleteURLFetch(net::OK, 503, retry_after); 584 ASSERT_TRUE(is_state_portal_detection_pending()); 585 ASSERT_EQ(1, attempt_count()); 586 ASSERT_EQ(base::TimeDelta::FromSeconds(0), next_attempt_delay()); 587 588 // To run CaptivePortalDetector::DetectCaptivePortal(). 589 base::RunLoop().RunUntilIdle(); 590 591 CompleteURLFetch(net::OK, 204, NULL); 592 ASSERT_TRUE(is_state_idle()); 593 ASSERT_EQ(2, attempt_count()); 594 CheckPortalState( 595 NetworkPortalDetector::CAPTIVE_PORTAL_STATUS_ONLINE, 204, kStubWireless1); 596 597 ASSERT_TRUE( 598 MakeResultHistogramChecker() 599 ->Expect(NetworkPortalDetector::CAPTIVE_PORTAL_STATUS_ONLINE, 1) 600 ->Check()); 601} 602 603TEST_F(NetworkPortalDetectorImplTest, AllAttemptsFailed) { 604 ASSERT_TRUE(is_state_idle()); 605 606 set_delay_till_next_attempt(base::TimeDelta()); 607 const char* retry_after = "HTTP/1.1 503 OK\nRetry-After: 0\n\n"; 608 609 ASSERT_TRUE(is_state_idle()); 610 ASSERT_EQ(0, attempt_count()); 611 612 SetConnected(kStubWireless1); 613 614 CompleteURLFetch(net::OK, 503, retry_after); 615 ASSERT_TRUE(is_state_portal_detection_pending()); 616 ASSERT_EQ(1, attempt_count()); 617 ASSERT_EQ(base::TimeDelta::FromSeconds(0), next_attempt_delay()); 618 619 // To run CaptivePortalDetector::DetectCaptivePortal(). 620 base::RunLoop().RunUntilIdle(); 621 622 CompleteURLFetch(net::OK, 503, retry_after); 623 ASSERT_TRUE(is_state_portal_detection_pending()); 624 ASSERT_EQ(2, attempt_count()); 625 ASSERT_EQ(base::TimeDelta::FromSeconds(0), next_attempt_delay()); 626 627 // To run CaptivePortalDetector::DetectCaptivePortal(). 628 base::RunLoop().RunUntilIdle(); 629 630 CompleteURLFetch(net::OK, 503, retry_after); 631 ASSERT_TRUE(is_state_idle()); 632 ASSERT_EQ(3, attempt_count()); 633 CheckPortalState(NetworkPortalDetector::CAPTIVE_PORTAL_STATUS_OFFLINE, 634 503, 635 kStubWireless1); 636 637 ASSERT_TRUE( 638 MakeResultHistogramChecker() 639 ->Expect(NetworkPortalDetector::CAPTIVE_PORTAL_STATUS_OFFLINE, 1) 640 ->Check()); 641} 642 643TEST_F(NetworkPortalDetectorImplTest, ProxyAuthRequired) { 644 ASSERT_TRUE(is_state_idle()); 645 set_delay_till_next_attempt(base::TimeDelta()); 646 647 SetConnected(kStubWireless1); 648 CompleteURLFetch(net::OK, 407, NULL); 649 ASSERT_EQ(1, attempt_count()); 650 ASSERT_TRUE(is_state_idle()); 651 CheckPortalState( 652 NetworkPortalDetector::CAPTIVE_PORTAL_STATUS_PROXY_AUTH_REQUIRED, 653 407, 654 kStubWireless1); 655 656 ASSERT_TRUE(MakeResultHistogramChecker() 657 ->Expect(NetworkPortalDetector:: 658 CAPTIVE_PORTAL_STATUS_PROXY_AUTH_REQUIRED, 659 1) 660 ->Check()); 661} 662 663TEST_F(NetworkPortalDetectorImplTest, NoResponseButBehindPortal) { 664 ASSERT_TRUE(is_state_idle()); 665 set_delay_till_next_attempt(base::TimeDelta()); 666 667 SetBehindPortal(kStubWireless1); 668 ASSERT_TRUE(is_state_checking_for_portal()); 669 670 CompleteURLFetch( 671 net::ERR_CONNECTION_CLOSED, net::URLFetcher::RESPONSE_CODE_INVALID, NULL); 672 ASSERT_EQ(1, attempt_count()); 673 ASSERT_TRUE(is_state_portal_detection_pending()); 674 675 // To run CaptivePortalDetector::DetectCaptivePortal(). 676 base::RunLoop().RunUntilIdle(); 677 678 CompleteURLFetch( 679 net::ERR_CONNECTION_CLOSED, net::URLFetcher::RESPONSE_CODE_INVALID, NULL); 680 ASSERT_EQ(2, attempt_count()); 681 ASSERT_TRUE(is_state_portal_detection_pending()); 682 683 // To run CaptivePortalDetector::DetectCaptivePortal(). 684 base::RunLoop().RunUntilIdle(); 685 686 CompleteURLFetch( 687 net::ERR_CONNECTION_CLOSED, net::URLFetcher::RESPONSE_CODE_INVALID, NULL); 688 ASSERT_EQ(3, attempt_count()); 689 ASSERT_TRUE(is_state_idle()); 690 691 CheckPortalState(NetworkPortalDetector::CAPTIVE_PORTAL_STATUS_PORTAL, 692 net::URLFetcher::RESPONSE_CODE_INVALID, 693 kStubWireless1); 694 695 ASSERT_TRUE( 696 MakeResultHistogramChecker() 697 ->Expect(NetworkPortalDetector::CAPTIVE_PORTAL_STATUS_PORTAL, 1) 698 ->Check()); 699} 700 701TEST_F(NetworkPortalDetectorImplTest, 702 DisableErrorScreenStrategyWhilePendingRequest) { 703 ASSERT_TRUE(is_state_idle()); 704 set_attempt_count(3); 705 enable_error_screen_strategy(); 706 ASSERT_TRUE(is_state_portal_detection_pending()); 707 disable_error_screen_strategy(); 708 709 // To run CaptivePortalDetector::DetectCaptivePortal(). 710 base::MessageLoop::current()->RunUntilIdle(); 711 712 ASSERT_TRUE(MakeResultHistogramChecker()->Check()); 713} 714 715TEST_F(NetworkPortalDetectorImplTest, ErrorScreenStrategyForOnlineNetwork) { 716 ASSERT_TRUE(is_state_idle()); 717 set_delay_till_next_attempt(base::TimeDelta()); 718 719 SetConnected(kStubWireless1); 720 enable_error_screen_strategy(); 721 // To run CaptivePortalDetector::DetectCaptivePortal(). 722 base::RunLoop().RunUntilIdle(); 723 CompleteURLFetch(net::OK, 204, NULL); 724 725 ASSERT_TRUE(is_state_portal_detection_pending()); 726 CheckPortalState( 727 NetworkPortalDetector::CAPTIVE_PORTAL_STATUS_ONLINE, 204, kStubWireless1); 728 729 // To run CaptivePortalDetector::DetectCaptivePortal(). 730 base::RunLoop().RunUntilIdle(); 731 732 CompleteURLFetch(net::OK, 204, NULL); 733 734 ASSERT_TRUE(is_state_portal_detection_pending()); 735 CheckPortalState( 736 NetworkPortalDetector::CAPTIVE_PORTAL_STATUS_ONLINE, 204, kStubWireless1); 737 738 // To run CaptivePortalDetector::DetectCaptivePortal(). 739 base::RunLoop().RunUntilIdle(); 740 741 disable_error_screen_strategy(); 742 743 ASSERT_TRUE(is_state_portal_detection_pending()); 744 // To run CaptivePortalDetector::DetectCaptivePortal(). 745 base::RunLoop().RunUntilIdle(); 746 ASSERT_TRUE(is_state_checking_for_portal()); 747 CompleteURLFetch(net::OK, 204, NULL); 748 749 CheckPortalState( 750 NetworkPortalDetector::CAPTIVE_PORTAL_STATUS_ONLINE, 204, kStubWireless1); 751 752 ASSERT_TRUE( 753 MakeResultHistogramChecker() 754 ->Expect(NetworkPortalDetector::CAPTIVE_PORTAL_STATUS_ONLINE, 1) 755 ->Check()); 756} 757 758TEST_F(NetworkPortalDetectorImplTest, ErrorScreenStrategyForPortalNetwork) { 759 ASSERT_TRUE(is_state_idle()); 760 set_delay_till_next_attempt(base::TimeDelta()); 761 762 enable_error_screen_strategy(); 763 SetConnected(kStubWireless1); 764 765 CompleteURLFetch( 766 net::ERR_CONNECTION_CLOSED, net::URLFetcher::RESPONSE_CODE_INVALID, NULL); 767 ASSERT_EQ(1, attempt_count()); 768 ASSERT_TRUE(is_state_portal_detection_pending()); 769 CheckPortalState( 770 NetworkPortalDetector::CAPTIVE_PORTAL_STATUS_UNKNOWN, -1, kStubWireless1); 771 772 // To run CaptivePortalDetector::DetectCaptivePortal(). 773 base::RunLoop().RunUntilIdle(); 774 775 CompleteURLFetch( 776 net::ERR_CONNECTION_CLOSED, net::URLFetcher::RESPONSE_CODE_INVALID, NULL); 777 ASSERT_EQ(2, attempt_count()); 778 ASSERT_TRUE(is_state_portal_detection_pending()); 779 CheckPortalState( 780 NetworkPortalDetector::CAPTIVE_PORTAL_STATUS_UNKNOWN, -1, kStubWireless1); 781 782 // To run CaptivePortalDetector::DetectCaptivePortal(). 783 base::RunLoop().RunUntilIdle(); 784 785 CompleteURLFetch(net::OK, 200, NULL); 786 ASSERT_EQ(3, attempt_count()); 787 ASSERT_TRUE(is_state_portal_detection_pending()); 788 CheckPortalState( 789 NetworkPortalDetector::CAPTIVE_PORTAL_STATUS_PORTAL, 200, kStubWireless1); 790 791 // To run CaptivePortalDetector::DetectCaptivePortal(). 792 base::RunLoop().RunUntilIdle(); 793 794 disable_error_screen_strategy(); 795 796 ASSERT_TRUE(is_state_portal_detection_pending()); 797 CheckPortalState( 798 NetworkPortalDetector::CAPTIVE_PORTAL_STATUS_PORTAL, 200, kStubWireless1); 799 800 ASSERT_TRUE( 801 MakeResultHistogramChecker() 802 ->Expect(NetworkPortalDetector::CAPTIVE_PORTAL_STATUS_PORTAL, 1) 803 ->Check()); 804} 805 806TEST_F(NetworkPortalDetectorImplTest, DetectionTimeoutIsCancelled) { 807 ASSERT_TRUE(is_state_idle()); 808 set_delay_till_next_attempt(base::TimeDelta()); 809 810 SetConnected(kStubWireless1); 811 ASSERT_TRUE(is_state_checking_for_portal()); 812 CheckPortalState( 813 NetworkPortalDetector::CAPTIVE_PORTAL_STATUS_UNKNOWN, -1, kStubWireless1); 814 815 stop_detection(); 816 817 ASSERT_TRUE(is_state_idle()); 818 ASSERT_TRUE(attempt_timeout_is_cancelled()); 819 CheckPortalState( 820 NetworkPortalDetector::CAPTIVE_PORTAL_STATUS_UNKNOWN, -1, kStubWireless1); 821 822 ASSERT_TRUE(MakeResultHistogramChecker()->Check()); 823} 824 825TEST_F(NetworkPortalDetectorImplTest, TestDetectionRestart) { 826 ASSERT_TRUE(is_state_idle()); 827 set_delay_till_next_attempt(base::TimeDelta()); 828 829 // First portal detection attempts determines ONLINE state. 830 SetConnected(kStubWireless1); 831 ASSERT_TRUE(is_state_checking_for_portal()); 832 ASSERT_FALSE(start_detection_if_idle()); 833 834 CompleteURLFetch(net::OK, 204, NULL); 835 836 CheckPortalState( 837 NetworkPortalDetector::CAPTIVE_PORTAL_STATUS_ONLINE, 204, kStubWireless1); 838 ASSERT_TRUE(is_state_idle()); 839 840 // First portal detection attempts determines PORTAL state. 841 ASSERT_TRUE(start_detection_if_idle()); 842 ASSERT_TRUE(is_state_portal_detection_pending()); 843 ASSERT_FALSE(start_detection_if_idle()); 844 845 base::RunLoop().RunUntilIdle(); 846 ASSERT_TRUE(is_state_checking_for_portal()); 847 CompleteURLFetch(net::OK, 200, NULL); 848 849 CheckPortalState( 850 NetworkPortalDetector::CAPTIVE_PORTAL_STATUS_PORTAL, 200, kStubWireless1); 851 ASSERT_TRUE(is_state_idle()); 852 853 ASSERT_TRUE( 854 MakeResultHistogramChecker() 855 ->Expect(NetworkPortalDetector::CAPTIVE_PORTAL_STATUS_ONLINE, 1) 856 ->Expect(NetworkPortalDetector::CAPTIVE_PORTAL_STATUS_PORTAL, 1) 857 ->Check()); 858} 859 860TEST_F(NetworkPortalDetectorImplTest, RequestTimeouts) { 861 ASSERT_TRUE(is_state_idle()); 862 set_delay_till_next_attempt(base::TimeDelta()); 863 864 SetNetworkDeviceEnabled(shill::kTypeWifi, false); 865 SetConnected(kStubCellular); 866 867 // First portal detection attempt for cellular1 uses 5sec timeout. 868 CheckRequestTimeoutAndCompleteAttempt( 869 0, 5, net::ERR_CONNECTION_CLOSED, net::URLFetcher::RESPONSE_CODE_INVALID); 870 871 // Second portal detection attempt for cellular1 uses 10sec timeout. 872 ASSERT_TRUE(is_state_portal_detection_pending()); 873 base::RunLoop().RunUntilIdle(); 874 CheckRequestTimeoutAndCompleteAttempt(1, 875 10, 876 net::ERR_CONNECTION_CLOSED, 877 net::URLFetcher::RESPONSE_CODE_INVALID); 878 879 // Third portal detection attempt for cellular1 uses 15sec timeout. 880 ASSERT_TRUE(is_state_portal_detection_pending()); 881 base::RunLoop().RunUntilIdle(); 882 CheckRequestTimeoutAndCompleteAttempt(2, 883 15, 884 net::ERR_CONNECTION_CLOSED, 885 net::URLFetcher::RESPONSE_CODE_INVALID); 886 887 ASSERT_TRUE(is_state_idle()); 888 889 // Check that in lazy detection for cellular1 15sec timeout is used. 890 enable_error_screen_strategy(); 891 ASSERT_TRUE(is_state_portal_detection_pending()); 892 base::RunLoop().RunUntilIdle(); 893 CheckRequestTimeoutAndCompleteAttempt(0, 894 15, 895 net::ERR_CONNECTION_CLOSED, 896 net::URLFetcher::RESPONSE_CODE_INVALID); 897 disable_error_screen_strategy(); 898 ASSERT_TRUE(is_state_portal_detection_pending()); 899 900 SetNetworkDeviceEnabled(shill::kTypeWifi, true); 901 SetConnected(kStubWireless1); 902 903 // First portal detection attempt for wifi1 uses 5sec timeout. 904 CheckRequestTimeoutAndCompleteAttempt( 905 0, 5, net::ERR_CONNECTION_CLOSED, net::URLFetcher::RESPONSE_CODE_INVALID); 906 907 // Second portal detection attempt for wifi1 also uses 5sec timeout. 908 ASSERT_TRUE(is_state_portal_detection_pending()); 909 base::RunLoop().RunUntilIdle(); 910 CheckRequestTimeoutAndCompleteAttempt(1, 10, net::OK, 204); 911 ASSERT_TRUE(is_state_idle()); 912 913 // Check that in error screen strategy detection for wifi1 15sec 914 // timeout is used. 915 enable_error_screen_strategy(); 916 ASSERT_TRUE(is_state_portal_detection_pending()); 917 base::RunLoop().RunUntilIdle(); 918 CheckRequestTimeoutAndCompleteAttempt(0, 15, net::OK, 204); 919 disable_error_screen_strategy(); 920 ASSERT_TRUE(is_state_portal_detection_pending()); 921 922 ASSERT_TRUE( 923 MakeResultHistogramChecker() 924 ->Expect(NetworkPortalDetector::CAPTIVE_PORTAL_STATUS_OFFLINE, 1) 925 ->Expect(NetworkPortalDetector::CAPTIVE_PORTAL_STATUS_ONLINE, 1) 926 ->Check()); 927} 928 929TEST_F(NetworkPortalDetectorImplTest, StartDetectionIfIdle) { 930 ASSERT_TRUE(is_state_idle()); 931 set_delay_till_next_attempt(base::TimeDelta()); 932 SetConnected(kStubWireless1); 933 934 // First portal detection attempt for wifi1 uses 5sec timeout. 935 CheckRequestTimeoutAndCompleteAttempt( 936 0, 5, net::ERR_CONNECTION_CLOSED, net::URLFetcher::RESPONSE_CODE_INVALID); 937 ASSERT_TRUE(is_state_portal_detection_pending()); 938 base::RunLoop().RunUntilIdle(); 939 940 // Second portal detection attempt for wifi1 uses 10sec timeout. 941 CheckRequestTimeoutAndCompleteAttempt(1, 942 10, 943 net::ERR_CONNECTION_CLOSED, 944 net::URLFetcher::RESPONSE_CODE_INVALID); 945 ASSERT_TRUE(is_state_portal_detection_pending()); 946 base::RunLoop().RunUntilIdle(); 947 948 // Second portal detection attempt for wifi1 uses 15sec timeout. 949 CheckRequestTimeoutAndCompleteAttempt(2, 950 15, 951 net::ERR_CONNECTION_CLOSED, 952 net::URLFetcher::RESPONSE_CODE_INVALID); 953 ASSERT_TRUE(is_state_idle()); 954 start_detection_if_idle(); 955 956 ASSERT_TRUE(is_state_portal_detection_pending()); 957 958 // First portal detection attempt for wifi1 uses 5sec timeout. 959 base::RunLoop().RunUntilIdle(); 960 CheckRequestTimeoutAndCompleteAttempt(0, 5, net::OK, 204); 961 ASSERT_TRUE(is_state_idle()); 962 963 ASSERT_TRUE( 964 MakeResultHistogramChecker() 965 ->Expect(NetworkPortalDetector::CAPTIVE_PORTAL_STATUS_OFFLINE, 1) 966 ->Expect(NetworkPortalDetector::CAPTIVE_PORTAL_STATUS_ONLINE, 1) 967 ->Check()); 968} 969 970} // namespace chromeos 971