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