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