Home | History | Annotate | Download | only in net
      1 // Copyright (c) 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 "base/compiler_specific.h"
      6 #include "base/logging.h"
      7 #include "base/memory/scoped_ptr.h"
      8 #include "base/run_loop.h"
      9 #include "chrome/browser/captive_portal/captive_portal_detector.h"
     10 #include "chrome/browser/captive_portal/testing_utils.h"
     11 #include "chrome/browser/chromeos/net/network_portal_detector_impl.h"
     12 #include "chrome/test/base/testing_profile.h"
     13 #include "chromeos/dbus/dbus_thread_manager.h"
     14 #include "chromeos/dbus/shill_device_client.h"
     15 #include "chromeos/dbus/shill_service_client.h"
     16 #include "chromeos/network/network_state.h"
     17 #include "chromeos/network/network_state_handler.h"
     18 #include "chromeos/network/shill_property_util.h"
     19 #include "content/public/test/test_browser_thread_bundle.h"
     20 #include "dbus/object_path.h"
     21 #include "net/base/net_errors.h"
     22 #include "testing/gmock/include/gmock/gmock.h"
     23 #include "testing/gtest/include/gtest/gtest.h"
     24 #include "third_party/cros_system_api/dbus/service_constants.h"
     25 
     26 using testing::Mock;
     27 using testing::_;
     28 
     29 namespace chromeos {
     30 
     31 namespace {
     32 
     33 void ErrorCallbackFunction(const std::string& error_name,
     34                            const std::string& error_message) {
     35   LOG(ERROR) << "Shill Error: " << error_name << " : " << error_message;
     36 }
     37 
     38 class MockObserver : public NetworkPortalDetector::Observer {
     39  public:
     40   virtual ~MockObserver() {}
     41 
     42   MOCK_METHOD2(OnPortalDetectionCompleted,
     43                void(const NetworkState* network,
     44                     const NetworkPortalDetector::CaptivePortalState& state));
     45 };
     46 
     47 }  // namespace
     48 
     49 // Service paths for stub network devices.
     50 const char* kStubEthernet = "stub_ethernet";
     51 const char* kStubWireless1 = "stub_wifi1";
     52 const char* kStubWireless2 = "stub_wifi2";
     53 const char* kStubCellular = "stub_cellular";
     54 
     55 class NetworkPortalDetectorImplTest
     56     : public testing::Test,
     57       public captive_portal::CaptivePortalDetectorTestBase {
     58  protected:
     59   virtual void SetUp() {
     60     DBusThreadManager::InitializeWithStub();
     61     SetupNetworkHandler();
     62 
     63     profile_.reset(new TestingProfile());
     64     network_portal_detector_.reset(
     65         new NetworkPortalDetectorImpl(profile_->GetRequestContext()));
     66     network_portal_detector_->Enable(false);
     67 
     68     set_detector(network_portal_detector_->captive_portal_detector_.get());
     69 
     70     // Prevents flakiness due to message loop delays.
     71     set_time_ticks(base::TimeTicks::Now());
     72   }
     73 
     74   virtual void TearDown() {
     75     network_portal_detector_.reset();
     76     profile_.reset();
     77     NetworkHandler::Shutdown();
     78     DBusThreadManager::Shutdown();
     79   }
     80 
     81   void CheckPortalState(NetworkPortalDetector::CaptivePortalStatus status,
     82                         int response_code,
     83                         const std::string& network_service_path) {
     84     const NetworkState* network =
     85         NetworkHandler::Get()->network_state_handler()->GetNetworkState(
     86             network_service_path);
     87     NetworkPortalDetector::CaptivePortalState state =
     88         network_portal_detector()->GetCaptivePortalState(network);
     89     ASSERT_EQ(status, state.status);
     90     ASSERT_EQ(response_code, state.response_code);
     91   }
     92 
     93   void CheckRequestTimeoutAndCompleteAttempt(
     94       int expected_attempt_count,
     95       int expected_request_timeout_sec,
     96       int net_error,
     97       int status_code) {
     98     ASSERT_TRUE(is_state_checking_for_portal());
     99     ASSERT_EQ(expected_attempt_count, attempt_count());
    100     ASSERT_EQ(expected_request_timeout_sec, get_request_timeout_sec());
    101     CompleteURLFetch(net_error, status_code, NULL);
    102   }
    103 
    104   Profile* profile() { return profile_.get(); }
    105 
    106   NetworkPortalDetectorImpl* network_portal_detector() {
    107     return network_portal_detector_.get();
    108   }
    109 
    110   NetworkPortalDetectorImpl::State state() {
    111     return network_portal_detector()->state();
    112   }
    113 
    114   bool start_detection_if_idle() {
    115     return network_portal_detector()->StartDetectionIfIdle();
    116   }
    117 
    118   void enable_lazy_detection() {
    119     network_portal_detector()->EnableLazyDetection();
    120   }
    121 
    122   void disable_lazy_detection() {
    123     network_portal_detector()->DisableLazyDetection();
    124   }
    125 
    126   void cancel_portal_detection() {
    127     network_portal_detector()->CancelPortalDetection();
    128   }
    129 
    130   bool detection_timeout_is_cancelled() {
    131     return
    132         network_portal_detector()->DetectionTimeoutIsCancelledForTesting();
    133   }
    134 
    135   int get_request_timeout_sec() {
    136     return network_portal_detector()->GetRequestTimeoutSec();
    137   }
    138 
    139   bool is_state_idle() {
    140     return (NetworkPortalDetectorImpl::STATE_IDLE == state());
    141   }
    142 
    143   bool is_state_portal_detection_pending() {
    144     return (NetworkPortalDetectorImpl::STATE_PORTAL_CHECK_PENDING == state());
    145   }
    146 
    147   bool is_state_checking_for_portal() {
    148     return (NetworkPortalDetectorImpl::STATE_CHECKING_FOR_PORTAL == state());
    149   }
    150 
    151   void set_request_timeout(const base::TimeDelta& timeout) {
    152     network_portal_detector()->set_request_timeout_for_testing(timeout);
    153   }
    154 
    155   const base::TimeDelta& next_attempt_delay() {
    156     return network_portal_detector()->next_attempt_delay_for_testing();
    157   }
    158 
    159   int attempt_count() {
    160     return network_portal_detector()->attempt_count_for_testing();
    161   }
    162 
    163   void set_attempt_count(int ac) {
    164     return network_portal_detector()->set_attempt_count_for_testing(ac);
    165   }
    166 
    167   void set_min_time_between_attempts(const base::TimeDelta& delta) {
    168     network_portal_detector()->set_min_time_between_attempts_for_testing(delta);
    169   }
    170 
    171   void set_lazy_check_interval(const base::TimeDelta& delta) {
    172     network_portal_detector()->set_lazy_check_interval_for_testing(delta);
    173   }
    174 
    175   void set_time_ticks(const base::TimeTicks& time_ticks) {
    176     network_portal_detector()->set_time_ticks_for_testing(time_ticks);
    177   }
    178 
    179   void SetBehindPortal(const std::string& service_path) {
    180     DBusThreadManager::Get()->GetShillServiceClient()->SetProperty(
    181         dbus::ObjectPath(service_path),
    182         shill::kStateProperty, base::StringValue(shill::kStatePortal),
    183         base::Bind(&base::DoNothing), base::Bind(&ErrorCallbackFunction));
    184     base::RunLoop().RunUntilIdle();
    185   }
    186 
    187   void SetNetworkDeviceEnabled(const std::string& type, bool enabled) {
    188     NetworkHandler::Get()->network_state_handler()->SetTechnologyEnabled(
    189         NetworkTypePattern::Primitive(type),
    190         enabled,
    191         network_handler::ErrorCallback());
    192     base::RunLoop().RunUntilIdle();
    193   }
    194 
    195   void SetConnected(const std::string& service_path) {
    196     DBusThreadManager::Get()->GetShillServiceClient()->Connect(
    197         dbus::ObjectPath(service_path),
    198         base::Bind(&base::DoNothing), base::Bind(&ErrorCallbackFunction));
    199     base::RunLoop().RunUntilIdle();
    200   }
    201 
    202   void SetDisconnected(const std::string& service_path) {
    203     DBusThreadManager::Get()->GetShillServiceClient()->Disconnect(
    204         dbus::ObjectPath(service_path),
    205         base::Bind(&*base::DoNothing), base::Bind(&ErrorCallbackFunction));
    206     base::RunLoop().RunUntilIdle();
    207   }
    208 
    209  private:
    210   void SetupDefaultShillState() {
    211     base::RunLoop().RunUntilIdle();
    212     ShillServiceClient::TestInterface* service_test =
    213         DBusThreadManager::Get()->GetShillServiceClient()->GetTestInterface();
    214     service_test->ClearServices();
    215     const bool add_to_visible = true;
    216     const bool add_to_watchlist = true;
    217     service_test->AddService(kStubEthernet,
    218                              kStubEthernet,
    219                              shill::kTypeEthernet, shill::kStateIdle,
    220                              add_to_visible, add_to_watchlist);
    221     service_test->AddService(kStubWireless1,
    222                              kStubWireless1,
    223                              shill::kTypeWifi, shill::kStateIdle,
    224                              add_to_visible, add_to_watchlist);
    225     service_test->AddService(kStubWireless2,
    226                              kStubWireless2,
    227                              shill::kTypeWifi, shill::kStateIdle,
    228                              add_to_visible, add_to_watchlist);
    229     service_test->AddService(kStubCellular,
    230                              kStubCellular,
    231                              shill::kTypeCellular, shill::kStateIdle,
    232                              add_to_visible, add_to_watchlist);
    233   }
    234 
    235   void SetupNetworkHandler() {
    236     SetupDefaultShillState();
    237     NetworkHandler::Initialize();
    238   }
    239 
    240   content::TestBrowserThreadBundle thread_bundle_;
    241   scoped_ptr<TestingProfile> profile_;
    242   scoped_ptr<NetworkPortalDetectorImpl> network_portal_detector_;
    243 };
    244 
    245 TEST_F(NetworkPortalDetectorImplTest, NoPortal) {
    246   ASSERT_TRUE(is_state_idle());
    247 
    248   SetConnected(kStubWireless1);
    249 
    250   ASSERT_TRUE(is_state_checking_for_portal());
    251   CheckPortalState(NetworkPortalDetector::CAPTIVE_PORTAL_STATUS_UNKNOWN, -1,
    252                    kStubWireless1);
    253 
    254   CompleteURLFetch(net::OK, 204, NULL);
    255 
    256   ASSERT_TRUE(is_state_idle());
    257   CheckPortalState(NetworkPortalDetector::CAPTIVE_PORTAL_STATUS_ONLINE, 204,
    258                    kStubWireless1);
    259 }
    260 
    261 TEST_F(NetworkPortalDetectorImplTest, Portal) {
    262   ASSERT_TRUE(is_state_idle());
    263 
    264   // Check HTTP 200 response code.
    265   SetConnected(kStubWireless1);
    266   ASSERT_TRUE(is_state_checking_for_portal());
    267 
    268   CompleteURLFetch(net::OK, 200, NULL);
    269 
    270   ASSERT_TRUE(is_state_idle());
    271   CheckPortalState(NetworkPortalDetector::CAPTIVE_PORTAL_STATUS_PORTAL, 200,
    272                    kStubWireless1);
    273 
    274   // Check HTTP 301 response code.
    275   SetConnected(kStubWireless2);
    276   ASSERT_TRUE(is_state_checking_for_portal());
    277 
    278   CompleteURLFetch(net::OK, 301, NULL);
    279 
    280   ASSERT_TRUE(is_state_idle());
    281   CheckPortalState(NetworkPortalDetector::CAPTIVE_PORTAL_STATUS_PORTAL, 301,
    282                    kStubWireless2);
    283 
    284   // Check HTTP 302 response code.
    285   SetConnected(kStubEthernet);
    286   ASSERT_TRUE(is_state_checking_for_portal());
    287 
    288   CompleteURLFetch(net::OK, 302, NULL);
    289 
    290   ASSERT_TRUE(is_state_idle());
    291   CheckPortalState(NetworkPortalDetector::CAPTIVE_PORTAL_STATUS_PORTAL, 302,
    292                    kStubEthernet);
    293 }
    294 
    295 TEST_F(NetworkPortalDetectorImplTest, Online2Offline) {
    296   ASSERT_TRUE(is_state_idle());
    297 
    298   MockObserver observer;
    299   network_portal_detector()->AddObserver(&observer);
    300 
    301   // WiFi is in online state.
    302   {
    303     NetworkPortalDetector::CaptivePortalState state;
    304     state.status = NetworkPortalDetector::CAPTIVE_PORTAL_STATUS_ONLINE;
    305     state.response_code = 204;
    306     EXPECT_CALL(observer, OnPortalDetectionCompleted(_, state)).Times(1);
    307 
    308     SetConnected(kStubWireless1);
    309     ASSERT_TRUE(is_state_checking_for_portal());
    310 
    311     CompleteURLFetch(net::OK, 204, NULL);
    312     ASSERT_TRUE(is_state_idle());
    313 
    314     // Check that observer was notified about online state.
    315     Mock::VerifyAndClearExpectations(&observer);
    316   }
    317 
    318   // WiFi is turned off.
    319   {
    320     NetworkPortalDetector::CaptivePortalState state;
    321     state.status = NetworkPortalDetector::CAPTIVE_PORTAL_STATUS_OFFLINE;
    322     EXPECT_CALL(observer, OnPortalDetectionCompleted(NULL, state)).Times(1);
    323 
    324     SetDisconnected(kStubWireless1);
    325     ASSERT_TRUE(is_state_idle());
    326 
    327     // Check that observer was notified about offline state.
    328     Mock::VerifyAndClearExpectations(&observer);
    329   }
    330 
    331   network_portal_detector()->RemoveObserver(&observer);
    332 }
    333 
    334 TEST_F(NetworkPortalDetectorImplTest, TwoNetworks) {
    335   ASSERT_TRUE(is_state_idle());
    336 
    337   SetConnected(kStubWireless1);
    338   ASSERT_TRUE(is_state_checking_for_portal());
    339 
    340   // WiFi is in portal state.
    341   CompleteURLFetch(net::OK, 200, NULL);
    342   ASSERT_TRUE(is_state_idle());
    343 
    344   SetConnected(kStubEthernet);
    345   ASSERT_TRUE(is_state_checking_for_portal());
    346 
    347   // ethernet is in online state.
    348   CompleteURLFetch(net::OK, 204, NULL);
    349   ASSERT_TRUE(is_state_idle());
    350   CheckPortalState(NetworkPortalDetector::CAPTIVE_PORTAL_STATUS_ONLINE, 204,
    351                    kStubEthernet);
    352   CheckPortalState(NetworkPortalDetector::CAPTIVE_PORTAL_STATUS_PORTAL, 200,
    353                    kStubWireless1);
    354 }
    355 
    356 TEST_F(NetworkPortalDetectorImplTest, NetworkChanged) {
    357   ASSERT_TRUE(is_state_idle());
    358 
    359   SetConnected(kStubWireless1);
    360 
    361   // WiFi is in portal state.
    362   fetcher()->set_response_code(200);
    363   ASSERT_TRUE(is_state_checking_for_portal());
    364 
    365   // Active network is changed during portal detection for WiFi.
    366   SetConnected(kStubEthernet);
    367 
    368   // Portal detection for WiFi is cancelled, portal detection for
    369   // ethernet is initiated.
    370   ASSERT_TRUE(is_state_checking_for_portal());
    371 
    372   // ethernet is in online state.
    373   CompleteURLFetch(net::OK, 204, NULL);
    374   ASSERT_TRUE(is_state_idle());
    375   CheckPortalState(NetworkPortalDetector::CAPTIVE_PORTAL_STATUS_ONLINE, 204,
    376                    kStubEthernet);
    377 
    378   // As active network was changed during portal detection for wifi
    379   // network, it's state must be unknown.
    380   CheckPortalState(NetworkPortalDetector::CAPTIVE_PORTAL_STATUS_UNKNOWN, -1,
    381                    kStubWireless1);
    382 }
    383 
    384 TEST_F(NetworkPortalDetectorImplTest, NetworkStateNotChanged) {
    385   ASSERT_TRUE(is_state_idle());
    386 
    387   SetConnected(kStubWireless1);
    388   ASSERT_TRUE(is_state_checking_for_portal());
    389 
    390   CompleteURLFetch(net::OK, 204, NULL);
    391 
    392   ASSERT_TRUE(is_state_idle());
    393   CheckPortalState(NetworkPortalDetector::CAPTIVE_PORTAL_STATUS_ONLINE, 204,
    394                    kStubWireless1);
    395 
    396   SetConnected(kStubWireless1);
    397   ASSERT_TRUE(is_state_idle());
    398 }
    399 
    400 TEST_F(NetworkPortalDetectorImplTest, NetworkStateChanged) {
    401   // Test for Portal -> Online -> Portal network state transitions.
    402   ASSERT_TRUE(is_state_idle());
    403 
    404   SetBehindPortal(kStubWireless1);
    405   ASSERT_TRUE(is_state_checking_for_portal());
    406 
    407   CompleteURLFetch(net::OK, 200, NULL);
    408 
    409   ASSERT_TRUE(is_state_idle());
    410   CheckPortalState(NetworkPortalDetector::CAPTIVE_PORTAL_STATUS_PORTAL, 200,
    411                    kStubWireless1);
    412 
    413   SetConnected(kStubWireless1);
    414   ASSERT_TRUE(is_state_checking_for_portal());
    415 
    416   CompleteURLFetch(net::OK, 204, NULL);
    417 
    418   ASSERT_TRUE(is_state_idle());
    419   CheckPortalState(NetworkPortalDetector::CAPTIVE_PORTAL_STATUS_ONLINE, 204,
    420                    kStubWireless1);
    421 
    422   SetBehindPortal(kStubWireless1);
    423   ASSERT_TRUE(is_state_checking_for_portal());
    424 
    425   CompleteURLFetch(net::OK, 200, NULL);
    426 
    427   ASSERT_TRUE(is_state_idle());
    428   CheckPortalState(NetworkPortalDetector::CAPTIVE_PORTAL_STATUS_PORTAL, 200,
    429                    kStubWireless1);
    430 }
    431 
    432 TEST_F(NetworkPortalDetectorImplTest, PortalDetectionTimeout) {
    433   ASSERT_TRUE(is_state_idle());
    434 
    435   // For instantaneous timeout.
    436   set_request_timeout(base::TimeDelta::FromSeconds(0));
    437 
    438   ASSERT_TRUE(is_state_idle());
    439   ASSERT_EQ(0, attempt_count());
    440 
    441   SetConnected(kStubWireless1);
    442   base::RunLoop().RunUntilIdle();
    443 
    444   // First portal detection timeouts, next portal detection is
    445   // scheduled.
    446   ASSERT_TRUE(is_state_portal_detection_pending());
    447   ASSERT_EQ(1, attempt_count());
    448   ASSERT_EQ(base::TimeDelta::FromSeconds(3), next_attempt_delay());
    449 }
    450 
    451 TEST_F(NetworkPortalDetectorImplTest, PortalDetectionRetryAfter) {
    452   ASSERT_TRUE(is_state_idle());
    453 
    454   const char* retry_after = "HTTP/1.1 503 OK\nRetry-After: 101\n\n";
    455 
    456   ASSERT_TRUE(is_state_idle());
    457   ASSERT_EQ(0, attempt_count());
    458 
    459   SetConnected(kStubWireless1);
    460   CompleteURLFetch(net::OK, 503, retry_after);
    461 
    462   // First portal detection completed, next portal detection is
    463   // scheduled after 101 seconds.
    464   ASSERT_TRUE(is_state_portal_detection_pending());
    465   ASSERT_EQ(1, attempt_count());
    466   ASSERT_EQ(base::TimeDelta::FromSeconds(101), next_attempt_delay());
    467 }
    468 
    469 TEST_F(NetworkPortalDetectorImplTest, PortalDetectorRetryAfterIsSmall) {
    470   ASSERT_TRUE(is_state_idle());
    471 
    472   const char* retry_after = "HTTP/1.1 503 OK\nRetry-After: 1\n\n";
    473 
    474   ASSERT_TRUE(is_state_idle());
    475   ASSERT_EQ(0, attempt_count());
    476 
    477   SetConnected(kStubWireless1);
    478   CompleteURLFetch(net::OK, 503, retry_after);
    479 
    480   // First portal detection completed, next portal detection is
    481   // scheduled after 3 seconds (due to minimum time between detection
    482   // attemps).
    483   ASSERT_TRUE(is_state_portal_detection_pending());
    484   ASSERT_EQ(1, attempt_count());
    485   ASSERT_EQ(base::TimeDelta::FromSeconds(3), next_attempt_delay());
    486 }
    487 
    488 TEST_F(NetworkPortalDetectorImplTest, FirstAttemptFailed) {
    489   ASSERT_TRUE(is_state_idle());
    490 
    491   set_min_time_between_attempts(base::TimeDelta());
    492   const char* retry_after = "HTTP/1.1 503 OK\nRetry-After: 0\n\n";
    493 
    494   ASSERT_TRUE(is_state_idle());
    495   ASSERT_EQ(0, attempt_count());
    496 
    497   SetConnected(kStubWireless1);
    498 
    499   CompleteURLFetch(net::OK, 503, retry_after);
    500   ASSERT_TRUE(is_state_portal_detection_pending());
    501   ASSERT_EQ(1, attempt_count());
    502   ASSERT_EQ(base::TimeDelta::FromSeconds(0), next_attempt_delay());
    503 
    504   // To run CaptivePortalDetector::DetectCaptivePortal().
    505   base::RunLoop().RunUntilIdle();
    506 
    507   CompleteURLFetch(net::OK, 204, NULL);
    508   ASSERT_TRUE(is_state_idle());
    509   ASSERT_EQ(2, attempt_count());
    510   CheckPortalState(NetworkPortalDetector::CAPTIVE_PORTAL_STATUS_ONLINE, 204,
    511                    kStubWireless1);
    512 }
    513 
    514 TEST_F(NetworkPortalDetectorImplTest, AllAttemptsFailed) {
    515   ASSERT_TRUE(is_state_idle());
    516 
    517   set_min_time_between_attempts(base::TimeDelta());
    518   const char* retry_after = "HTTP/1.1 503 OK\nRetry-After: 0\n\n";
    519 
    520   ASSERT_TRUE(is_state_idle());
    521   ASSERT_EQ(0, attempt_count());
    522 
    523   SetConnected(kStubWireless1);
    524 
    525   CompleteURLFetch(net::OK, 503, retry_after);
    526   ASSERT_TRUE(is_state_portal_detection_pending());
    527   ASSERT_EQ(1, attempt_count());
    528   ASSERT_EQ(base::TimeDelta::FromSeconds(0), next_attempt_delay());
    529 
    530   // To run CaptivePortalDetector::DetectCaptivePortal().
    531   base::RunLoop().RunUntilIdle();
    532 
    533   CompleteURLFetch(net::OK, 503, retry_after);
    534   ASSERT_TRUE(is_state_portal_detection_pending());
    535   ASSERT_EQ(2, attempt_count());
    536   ASSERT_EQ(base::TimeDelta::FromSeconds(0), next_attempt_delay());
    537 
    538   // To run CaptivePortalDetector::DetectCaptivePortal().
    539   base::RunLoop().RunUntilIdle();
    540 
    541   CompleteURLFetch(net::OK, 503, retry_after);
    542   ASSERT_TRUE(is_state_idle());
    543   ASSERT_EQ(3, attempt_count());
    544   CheckPortalState(NetworkPortalDetector::CAPTIVE_PORTAL_STATUS_OFFLINE, 503,
    545                    kStubWireless1);
    546 }
    547 
    548 TEST_F(NetworkPortalDetectorImplTest, ProxyAuthRequired) {
    549   ASSERT_TRUE(is_state_idle());
    550   set_min_time_between_attempts(base::TimeDelta());
    551 
    552   SetConnected(kStubWireless1);
    553   CompleteURLFetch(net::OK, 407, NULL);
    554   ASSERT_EQ(1, attempt_count());
    555   ASSERT_TRUE(is_state_idle());
    556   CheckPortalState(
    557       NetworkPortalDetector::CAPTIVE_PORTAL_STATUS_PROXY_AUTH_REQUIRED, 407,
    558       kStubWireless1);
    559 }
    560 
    561 TEST_F(NetworkPortalDetectorImplTest, NoResponseButBehindPortal) {
    562   ASSERT_TRUE(is_state_idle());
    563   set_min_time_between_attempts(base::TimeDelta());
    564 
    565   SetBehindPortal(kStubWireless1);
    566   ASSERT_TRUE(is_state_checking_for_portal());
    567 
    568   CompleteURLFetch(net::ERR_CONNECTION_CLOSED,
    569                    net::URLFetcher::RESPONSE_CODE_INVALID,
    570                    NULL);
    571   ASSERT_EQ(1, attempt_count());
    572   ASSERT_TRUE(is_state_portal_detection_pending());
    573 
    574   // To run CaptivePortalDetector::DetectCaptivePortal().
    575   base::RunLoop().RunUntilIdle();
    576 
    577   CompleteURLFetch(net::ERR_CONNECTION_CLOSED,
    578                    net::URLFetcher::RESPONSE_CODE_INVALID,
    579                    NULL);
    580   ASSERT_EQ(2, attempt_count());
    581   ASSERT_TRUE(is_state_portal_detection_pending());
    582 
    583   // To run CaptivePortalDetector::DetectCaptivePortal().
    584   base::RunLoop().RunUntilIdle();
    585 
    586   CompleteURLFetch(net::ERR_CONNECTION_CLOSED,
    587                    net::URLFetcher::RESPONSE_CODE_INVALID,
    588                    NULL);
    589   ASSERT_EQ(3, attempt_count());
    590   ASSERT_TRUE(is_state_idle());
    591 
    592   CheckPortalState(NetworkPortalDetector::CAPTIVE_PORTAL_STATUS_PORTAL,
    593                    net::URLFetcher::RESPONSE_CODE_INVALID,
    594                    kStubWireless1);
    595 }
    596 
    597 TEST_F(NetworkPortalDetectorImplTest, DisableLazyDetectionWhilePendingRequest) {
    598   ASSERT_TRUE(is_state_idle());
    599   set_attempt_count(3);
    600   enable_lazy_detection();
    601   ASSERT_TRUE(is_state_portal_detection_pending());
    602   disable_lazy_detection();
    603 
    604   // To run CaptivePortalDetector::DetectCaptivePortal().
    605   base::MessageLoop::current()->RunUntilIdle();
    606 }
    607 
    608 TEST_F(NetworkPortalDetectorImplTest, LazyDetectionForOnlineNetwork) {
    609   ASSERT_TRUE(is_state_idle());
    610   set_min_time_between_attempts(base::TimeDelta());
    611   set_lazy_check_interval(base::TimeDelta());
    612 
    613   SetConnected(kStubWireless1);
    614   enable_lazy_detection();
    615   CompleteURLFetch(net::OK, 204, NULL);
    616 
    617   ASSERT_EQ(1, attempt_count());
    618   ASSERT_TRUE(is_state_portal_detection_pending());
    619   CheckPortalState(
    620       NetworkPortalDetector::CAPTIVE_PORTAL_STATUS_ONLINE, 204,
    621       kStubWireless1);
    622 
    623   // To run CaptivePortalDetector::DetectCaptivePortal().
    624   base::RunLoop().RunUntilIdle();
    625 
    626   CompleteURLFetch(net::OK, 204, NULL);
    627 
    628   ASSERT_EQ(2, attempt_count());
    629   ASSERT_TRUE(is_state_portal_detection_pending());
    630   CheckPortalState(
    631       NetworkPortalDetector::CAPTIVE_PORTAL_STATUS_ONLINE, 204,
    632       kStubWireless1);
    633 
    634   // To run CaptivePortalDetector::DetectCaptivePortal().
    635   base::RunLoop().RunUntilIdle();
    636 
    637   disable_lazy_detection();
    638 
    639   // One more detection result, because DizableLazyDetection() doesn't
    640   // cancel last detection request.
    641   CompleteURLFetch(net::OK, 204, NULL);
    642   ASSERT_EQ(3, attempt_count());
    643   ASSERT_TRUE(is_state_idle());
    644   CheckPortalState(
    645       NetworkPortalDetector::CAPTIVE_PORTAL_STATUS_ONLINE, 204,
    646       kStubWireless1);
    647 }
    648 
    649 TEST_F(NetworkPortalDetectorImplTest, LazyDetectionForPortalNetwork) {
    650   ASSERT_TRUE(is_state_idle());
    651   set_min_time_between_attempts(base::TimeDelta());
    652   set_lazy_check_interval(base::TimeDelta());
    653 
    654   SetConnected(kStubWireless1);
    655   enable_lazy_detection();
    656 
    657   CompleteURLFetch(net::ERR_CONNECTION_CLOSED,
    658                    net::URLFetcher::RESPONSE_CODE_INVALID,
    659                    NULL);
    660   ASSERT_EQ(1, attempt_count());
    661   ASSERT_TRUE(is_state_portal_detection_pending());
    662   CheckPortalState(NetworkPortalDetector::CAPTIVE_PORTAL_STATUS_UNKNOWN, -1,
    663                    kStubWireless1);
    664 
    665   // To run CaptivePortalDetector::DetectCaptivePortal().
    666   base::RunLoop().RunUntilIdle();
    667 
    668   CompleteURLFetch(net::ERR_CONNECTION_CLOSED,
    669                    net::URLFetcher::RESPONSE_CODE_INVALID,
    670                    NULL);
    671   ASSERT_EQ(2, attempt_count());
    672   ASSERT_TRUE(is_state_portal_detection_pending());
    673   CheckPortalState(NetworkPortalDetector::CAPTIVE_PORTAL_STATUS_UNKNOWN, -1,
    674                    kStubWireless1);
    675 
    676   // To run CaptivePortalDetector::DetectCaptivePortal().
    677   base::RunLoop().RunUntilIdle();
    678 
    679   CompleteURLFetch(net::OK, 200, NULL);
    680   ASSERT_EQ(3, attempt_count());
    681   ASSERT_TRUE(is_state_portal_detection_pending());
    682   CheckPortalState(NetworkPortalDetector::CAPTIVE_PORTAL_STATUS_PORTAL, 200,
    683                    kStubWireless1);
    684 
    685   // To run CaptivePortalDetector::DetectCaptivePortal().
    686   base::RunLoop().RunUntilIdle();
    687 
    688   disable_lazy_detection();
    689 
    690   // One more detection result, because DizableLazyDetection() doesn't
    691   // cancel last detection request.
    692   CompleteURLFetch(net::OK, 200, NULL);
    693   ASSERT_EQ(3, attempt_count());
    694   ASSERT_TRUE(is_state_idle());
    695   CheckPortalState(NetworkPortalDetector::CAPTIVE_PORTAL_STATUS_PORTAL, 200,
    696                    kStubWireless1);
    697 }
    698 
    699 TEST_F(NetworkPortalDetectorImplTest, DetectionTimeoutIsCancelled) {
    700   ASSERT_TRUE(is_state_idle());
    701   set_min_time_between_attempts(base::TimeDelta());
    702 
    703   SetConnected(kStubWireless1);
    704   ASSERT_TRUE(is_state_checking_for_portal());
    705   CheckPortalState(NetworkPortalDetector::CAPTIVE_PORTAL_STATUS_UNKNOWN, -1,
    706                    kStubWireless1);
    707 
    708   cancel_portal_detection();
    709 
    710   ASSERT_TRUE(is_state_idle());
    711   ASSERT_TRUE(detection_timeout_is_cancelled());
    712   CheckPortalState(NetworkPortalDetector::CAPTIVE_PORTAL_STATUS_UNKNOWN, -1,
    713                    kStubWireless1);
    714 }
    715 
    716 TEST_F(NetworkPortalDetectorImplTest, TestDetectionRestart) {
    717   ASSERT_TRUE(is_state_idle());
    718   set_min_time_between_attempts(base::TimeDelta());
    719 
    720   // First portal detection attempts determines ONLINE state.
    721   SetConnected(kStubWireless1);
    722   ASSERT_TRUE(is_state_checking_for_portal());
    723   ASSERT_FALSE(start_detection_if_idle());
    724 
    725   CompleteURLFetch(net::OK, 204, NULL);
    726 
    727   CheckPortalState(NetworkPortalDetector::CAPTIVE_PORTAL_STATUS_ONLINE, 204,
    728                    kStubWireless1);
    729   ASSERT_TRUE(is_state_idle());
    730 
    731   // First portal detection attempts determines PORTAL state.
    732   ASSERT_TRUE(start_detection_if_idle());
    733   ASSERT_TRUE(is_state_portal_detection_pending());
    734   ASSERT_FALSE(start_detection_if_idle());
    735 
    736   base::RunLoop().RunUntilIdle();
    737   ASSERT_TRUE(is_state_checking_for_portal());
    738   CompleteURLFetch(net::OK, 200, NULL);
    739 
    740   CheckPortalState(NetworkPortalDetector::CAPTIVE_PORTAL_STATUS_PORTAL, 200,
    741                    kStubWireless1);
    742   ASSERT_TRUE(is_state_idle());
    743 }
    744 
    745 TEST_F(NetworkPortalDetectorImplTest, RequestTimeouts) {
    746   ASSERT_TRUE(is_state_idle());
    747   set_min_time_between_attempts(base::TimeDelta());
    748   set_lazy_check_interval(base::TimeDelta());
    749 
    750   SetNetworkDeviceEnabled(shill::kTypeWifi, false);
    751   SetConnected(kStubCellular);
    752 
    753   // First portal detection attempt for cellular1 uses 5sec timeout.
    754   CheckRequestTimeoutAndCompleteAttempt(1, 5, net::ERR_CONNECTION_CLOSED,
    755                                         net::URLFetcher::RESPONSE_CODE_INVALID);
    756 
    757   // Second portal detection attempt for cellular1 uses 10sec timeout.
    758   ASSERT_TRUE(is_state_portal_detection_pending());
    759   base::RunLoop().RunUntilIdle();
    760   CheckRequestTimeoutAndCompleteAttempt(2, 10, net::ERR_CONNECTION_CLOSED,
    761                                         net::URLFetcher::RESPONSE_CODE_INVALID);
    762 
    763   // Third portal detection attempt for cellular1 uses 15sec timeout.
    764   ASSERT_TRUE(is_state_portal_detection_pending());
    765   base::RunLoop().RunUntilIdle();
    766   CheckRequestTimeoutAndCompleteAttempt(3, 15, net::ERR_CONNECTION_CLOSED,
    767                                         net::URLFetcher::RESPONSE_CODE_INVALID);
    768 
    769   ASSERT_TRUE(is_state_idle());
    770 
    771   // Check that in lazy detection for cellular1 15sec timeout is used.
    772   enable_lazy_detection();
    773   ASSERT_TRUE(is_state_portal_detection_pending());
    774   base::RunLoop().RunUntilIdle();
    775   disable_lazy_detection();
    776   CheckRequestTimeoutAndCompleteAttempt(3, 15, net::ERR_CONNECTION_CLOSED,
    777                                         net::URLFetcher::RESPONSE_CODE_INVALID);
    778   ASSERT_TRUE(is_state_idle());
    779 
    780   SetNetworkDeviceEnabled(shill::kTypeWifi, true);
    781   SetConnected(kStubWireless1);
    782 
    783   // First portal detection attempt for wifi1 uses 5sec timeout.
    784   CheckRequestTimeoutAndCompleteAttempt(1, 5, net::ERR_CONNECTION_CLOSED,
    785                                         net::URLFetcher::RESPONSE_CODE_INVALID);
    786 
    787   // Second portal detection attempt for wifi1 also uses 5sec timeout.
    788   ASSERT_TRUE(is_state_portal_detection_pending());
    789   base::RunLoop().RunUntilIdle();
    790   CheckRequestTimeoutAndCompleteAttempt(2, 10, net::OK, 204);
    791   ASSERT_TRUE(is_state_idle());
    792 
    793   // Check that in lazy detection for wifi1 5sec timeout is used.
    794   enable_lazy_detection();
    795   ASSERT_TRUE(is_state_portal_detection_pending());
    796   base::RunLoop().RunUntilIdle();
    797   disable_lazy_detection();
    798   CheckRequestTimeoutAndCompleteAttempt(3, 15, net::OK, 204);
    799   ASSERT_TRUE(is_state_idle());
    800 }
    801 
    802 TEST_F(NetworkPortalDetectorImplTest, StartDetectionIfIdle) {
    803   ASSERT_TRUE(is_state_idle());
    804   set_min_time_between_attempts(base::TimeDelta());
    805   SetConnected(kStubWireless1);
    806 
    807   // First portal detection attempt for wifi1 uses 5sec timeout.
    808   CheckRequestTimeoutAndCompleteAttempt(1, 5, net::ERR_CONNECTION_CLOSED,
    809                                         net::URLFetcher::RESPONSE_CODE_INVALID);
    810   ASSERT_TRUE(is_state_portal_detection_pending());
    811   base::RunLoop().RunUntilIdle();
    812 
    813   // Second portal detection attempt for wifi1 uses 10sec timeout.
    814   CheckRequestTimeoutAndCompleteAttempt(2, 10, net::ERR_CONNECTION_CLOSED,
    815                                         net::URLFetcher::RESPONSE_CODE_INVALID);
    816   ASSERT_TRUE(is_state_portal_detection_pending());
    817   base::RunLoop().RunUntilIdle();
    818 
    819   // Second portal detection attempt for wifi1 uses 15sec timeout.
    820   CheckRequestTimeoutAndCompleteAttempt(3, 15, net::ERR_CONNECTION_CLOSED,
    821                                         net::URLFetcher::RESPONSE_CODE_INVALID);
    822   ASSERT_TRUE(is_state_idle());
    823   start_detection_if_idle();
    824 
    825   ASSERT_TRUE(is_state_portal_detection_pending());
    826 
    827   // First portal detection attempt for wifi1 uses 5sec timeout.
    828   base::RunLoop().RunUntilIdle();
    829   CheckRequestTimeoutAndCompleteAttempt(1, 5, net::OK, 204);
    830   ASSERT_TRUE(is_state_idle());
    831 }
    832 
    833 }  // namespace chromeos
    834