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