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