network_portal_detector_impl_unittest.cc revision a1401311d1ab56c4ed0a474bd38c108f75cb0cd9
195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley// Copyright (c) 2013 The Chromium Authors. All rights reserved. 295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley// Use of this source code is governed by a BSD-style license that can be 395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley// found in the LICENSE file. 495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley#include <algorithm> 695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley#include <vector> 795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley#include "base/command_line.h" 995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley#include "base/compiler_specific.h" 1095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley#include "base/logging.h" 1195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley#include "base/memory/scoped_ptr.h" 1295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley#include "base/metrics/histogram_base.h" 1395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley#include "base/metrics/histogram_samples.h" 1495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley#include "base/metrics/statistics_recorder.h" 1595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley#include "base/run_loop.h" 1695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley#include "chrome/browser/captive_portal/captive_portal_detector.h" 1795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley#include "chrome/browser/captive_portal/testing_utils.h" 1895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley#include "chrome/browser/chromeos/net/network_portal_detector_impl.h" 1995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley#include "chrome/test/base/testing_profile.h" 2095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley#include "chromeos/chromeos_switches.h" 2195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley#include "chromeos/dbus/dbus_thread_manager.h" 2295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley#include "chromeos/dbus/shill_device_client.h" 2395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley#include "chromeos/dbus/shill_service_client.h" 2495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley#include "chromeos/network/network_state.h" 2595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley#include "chromeos/network/network_state_handler.h" 2695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley#include "chromeos/network/shill_property_util.h" 2795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley#include "content/public/test/test_browser_thread_bundle.h" 2895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley#include "dbus/object_path.h" 2995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley#include "net/base/net_errors.h" 3095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley#include "testing/gmock/include/gmock/gmock.h" 3195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley#include "testing/gtest/include/gtest/gtest.h" 3295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley#include "third_party/cros_system_api/dbus/service_constants.h" 3395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 3495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langleyusing testing::AnyNumber; 3595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langleyusing testing::Mock; 3695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langleyusing testing::_; 3795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 3895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langleynamespace chromeos { 3995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 4095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langleynamespace { 4195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 4295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley// Service paths for stub network devices. 4395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langleyconst char kStubEthernet[] = "stub_ethernet"; 4495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langleyconst char kStubWireless1[] = "stub_wifi1"; 4595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langleyconst char kStubWireless2[] = "stub_wifi2"; 4695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langleyconst char kStubCellular[] = "stub_cellular"; 4795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 4895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langleyvoid ErrorCallbackFunction(const std::string& error_name, 4995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley const std::string& error_message) { 5095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley LOG(ERROR) << "Shill Error: " << error_name << " : " << error_message; 5195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley} 5295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 5395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langleyclass MockObserver : public NetworkPortalDetector::Observer { 5495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley public: 5595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley virtual ~MockObserver() {} 5695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 5795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley MOCK_METHOD2(OnPortalDetectionCompleted, 5895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley void(const NetworkState* network, 5995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley const NetworkPortalDetector::CaptivePortalState& state)); 6095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley}; 6195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 6295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langleyclass ResultHistogramChecker { 6395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley public: 6495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley explicit ResultHistogramChecker(base::HistogramSamples* base) 6595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley : base_(base), 6695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley count_(NetworkPortalDetector::CAPTIVE_PORTAL_STATUS_COUNT) {} 6795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley virtual ~ResultHistogramChecker() {} 6895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 6995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley ResultHistogramChecker* Expect( 7095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley NetworkPortalDetector::CaptivePortalStatus status, 7195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley int count) { 7295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley count_[status] = count; 7395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return this; 7495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 7595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 7695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley bool Check() const { 7795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley base::HistogramBase* histogram = base::StatisticsRecorder::FindHistogram( 7895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley NetworkPortalDetectorImpl::kDetectionResultHistogram); 7995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley bool empty = false; 8095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (static_cast<size_t>(std::count(count_.begin(), count_.end(), 0)) == 8195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley count_.size()) { 8295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley empty = true; 8395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 8495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 8595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (!histogram) { 8695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (empty) 8795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return true; 8895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley LOG(ERROR) << "Can't get histogram for " 8995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley << NetworkPortalDetectorImpl::kDetectionResultHistogram; 9095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return false; 9195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 9295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley scoped_ptr<base::HistogramSamples> samples = histogram->SnapshotSamples(); 9395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (!samples.get()) { 9495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (empty) 9595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return true; 9695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley LOG(ERROR) << "Can't get samples for " 9795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley << NetworkPortalDetectorImpl::kDetectionResultHistogram; 9895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return false; 9995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 10095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley bool ok = true; 10195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley for (size_t i = 0; i < count_.size(); ++i) { 10295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley const int base = base_ ? base_->GetCount(i) : 0; 10395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley const int actual = samples->GetCount(i) - base; 10495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley const NetworkPortalDetector::CaptivePortalStatus status = 10595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley static_cast<NetworkPortalDetector::CaptivePortalStatus>(i); 10695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (actual != count_[i]) { 10795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley LOG(ERROR) << "Expected: " << count_[i] << ", " 10895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley << "actual: " << actual << " for " 10995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley << NetworkPortalDetector::CaptivePortalStatusString(status); 11095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley ok = false; 11195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 11295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 11395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return ok; 11495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 11595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 11695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley private: 11795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley base::HistogramSamples* base_; 11895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley std::vector<int> count_; 11995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 12095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley DISALLOW_COPY_AND_ASSIGN(ResultHistogramChecker); 12195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley}; 12295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 12395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley} // namespace 12495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 12595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langleyclass NetworkPortalDetectorImplTest 12695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley : public testing::Test, 12795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley public captive_portal::CaptivePortalDetectorTestBase { 12895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley protected: 12995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley virtual void SetUp() { 13095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley CommandLine* cl = CommandLine::ForCurrentProcess(); 13195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley cl->AppendSwitch(switches::kDisableNetworkPortalNotification); 13295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 13395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley DBusThreadManager::InitializeWithStub(); 13495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley base::StatisticsRecorder::Initialize(); 13595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley SetupNetworkHandler(); 13695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 13795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley profile_.reset(new TestingProfile()); 13895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley network_portal_detector_.reset( 13995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley new NetworkPortalDetectorImpl(profile_->GetRequestContext())); 14095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley network_portal_detector_->Enable(false); 14195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 14295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley set_detector(network_portal_detector_->captive_portal_detector_.get()); 14395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 14495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley // Prevents flakiness due to message loop delays. 14595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley set_time_ticks(base::TimeTicks::Now()); 14695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 14795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (base::HistogramBase* histogram = 14895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley base::StatisticsRecorder::FindHistogram( 14995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley NetworkPortalDetectorImpl::kDetectionResultHistogram)) { 15095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley original_samples_.reset(histogram->SnapshotSamples().release()); 15195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 15295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 15395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 15495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley virtual void TearDown() { 15595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley network_portal_detector_.reset(); 15695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley profile_.reset(); 15795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley NetworkHandler::Shutdown(); 15895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley DBusThreadManager::Shutdown(); 15995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley PortalDetectorStrategy::reset_fields_for_testing(); 16095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 16195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 16295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley void CheckPortalState(NetworkPortalDetector::CaptivePortalStatus status, 16395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley int response_code, 16495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley const std::string& service_path) { 16595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley NetworkPortalDetector::CaptivePortalState state = 16695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley network_portal_detector()->GetCaptivePortalState(service_path); 16795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley ASSERT_EQ(status, state.status); 16895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley ASSERT_EQ(response_code, state.response_code); 16995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 17095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 17195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley void CheckRequestTimeoutAndCompleteAttempt(int expected_attempt_count, 17295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley int expected_request_timeout_sec, 17395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley int net_error, 17495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley int status_code) { 17595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley ASSERT_TRUE(is_state_checking_for_portal()); 17695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley ASSERT_EQ(expected_attempt_count, attempt_count()); 17795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley ASSERT_EQ(base::TimeDelta::FromSeconds(expected_request_timeout_sec), 17895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley get_next_attempt_timeout()); 17995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley CompleteURLFetch(net_error, status_code, NULL); 18095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 18195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 18295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley Profile* profile() { return profile_.get(); } 18395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 18495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley NetworkPortalDetectorImpl* network_portal_detector() { 18595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return network_portal_detector_.get(); 18695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 18795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 18895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley NetworkPortalDetectorImpl::State state() { 18995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return network_portal_detector()->state(); 19095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 19195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 19295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley bool start_detection_if_idle() { 19395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return network_portal_detector()->StartDetectionIfIdle(); 19495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 19595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 19695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley void enable_error_screen_strategy() { 19795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley network_portal_detector()->OnErrorScreenShow(); 19895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 19995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 20095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley void disable_error_screen_strategy() { 20195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley network_portal_detector()->OnErrorScreenHide(); 20295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 20395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 20495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley void stop_detection() { 20595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley network_portal_detector()->StopDetection(); 20695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 20795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 20895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley bool attempt_timeout_is_cancelled() { 20995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return network_portal_detector()->AttemptTimeoutIsCancelledForTesting(); 21095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 21195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 21295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley base::TimeDelta get_next_attempt_timeout() { 21395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return network_portal_detector()->strategy_->GetNextAttemptTimeout(); 21495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 21595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 21695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley void set_next_attempt_timeout(const base::TimeDelta& timeout) { 21795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley PortalDetectorStrategy::set_next_attempt_timeout_for_testing(timeout); 21895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 21995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 22095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley bool is_state_idle() { 22195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return (NetworkPortalDetectorImpl::STATE_IDLE == state()); 22295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 22395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 22495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley bool is_state_portal_detection_pending() { 22595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return (NetworkPortalDetectorImpl::STATE_PORTAL_CHECK_PENDING == state()); 22695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 22795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 22895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley bool is_state_checking_for_portal() { 22995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return (NetworkPortalDetectorImpl::STATE_CHECKING_FOR_PORTAL == state()); 23095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 23195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 23295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 23395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 23495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley const base::TimeDelta& next_attempt_delay() { 23595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return network_portal_detector()->next_attempt_delay_for_testing(); 23695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 23795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 23895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley int attempt_count() { 23995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return network_portal_detector()->attempt_count_for_testing(); 24095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 24195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 24295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley void set_attempt_count(int ac) { 24395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley network_portal_detector()->set_attempt_count_for_testing(ac); 24495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 24595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 24695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley void set_delay_till_next_attempt(const base::TimeDelta& delta) { 24795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley PortalDetectorStrategy::set_delay_till_next_attempt_for_testing(delta); 24895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 24995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 25095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley void set_time_ticks(const base::TimeTicks& time_ticks) { 25195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley network_portal_detector()->set_time_ticks_for_testing(time_ticks); 25295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 25395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 25495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley void SetBehindPortal(const std::string& service_path) { 25595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley DBusThreadManager::Get()->GetShillServiceClient()->SetProperty( 25695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley dbus::ObjectPath(service_path), 25795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley shill::kStateProperty, 25895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley base::StringValue(shill::kStatePortal), 25995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley base::Bind(&base::DoNothing), 26095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley base::Bind(&ErrorCallbackFunction)); 26195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley base::RunLoop().RunUntilIdle(); 26295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 26395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 26495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley void SetNetworkDeviceEnabled(const std::string& type, bool enabled) { 26595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley NetworkHandler::Get()->network_state_handler()->SetTechnologyEnabled( 26695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley NetworkTypePattern::Primitive(type), 26795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley enabled, 26895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley network_handler::ErrorCallback()); 26995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley base::RunLoop().RunUntilIdle(); 27095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 27195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 27295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley void SetConnected(const std::string& service_path) { 27395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley DBusThreadManager::Get()->GetShillServiceClient()->Connect( 27495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley dbus::ObjectPath(service_path), 27595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley base::Bind(&base::DoNothing), 27695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley base::Bind(&ErrorCallbackFunction)); 27795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley base::RunLoop().RunUntilIdle(); 27895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 27995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 28095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley void SetDisconnected(const std::string& service_path) { 28195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley DBusThreadManager::Get()->GetShillServiceClient()->Disconnect( 28295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley dbus::ObjectPath(service_path), 28395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley base::Bind(&*base::DoNothing), 28495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley base::Bind(&ErrorCallbackFunction)); 28595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley base::RunLoop().RunUntilIdle(); 28695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 28795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 28895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley scoped_ptr<ResultHistogramChecker> MakeResultHistogramChecker() { 28995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return scoped_ptr<ResultHistogramChecker>( 29095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley new ResultHistogramChecker(original_samples_.get())).Pass(); 29195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 29295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 29395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley private: 29495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley void SetupDefaultShillState() { 29595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley base::RunLoop().RunUntilIdle(); 29695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley ShillServiceClient::TestInterface* service_test = 29795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley DBusThreadManager::Get()->GetShillServiceClient()->GetTestInterface(); 29895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley service_test->ClearServices(); 29995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley const bool add_to_visible = true; 30095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley const bool add_to_watchlist = true; 30195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley service_test->AddService(kStubEthernet, 30295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley kStubEthernet, 30395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley shill::kTypeEthernet, 30495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley shill::kStateIdle, 30595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley add_to_visible, 30695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley add_to_watchlist); 30795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley service_test->AddService(kStubWireless1, 30895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley kStubWireless1, 30995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley shill::kTypeWifi, 31095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley shill::kStateIdle, 31195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley add_to_visible, 31295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley add_to_watchlist); 31395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley service_test->AddService(kStubWireless2, 31495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley kStubWireless2, 31595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley shill::kTypeWifi, 31695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley shill::kStateIdle, 31795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley add_to_visible, 31895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley add_to_watchlist); 31995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley service_test->AddService(kStubCellular, 32095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley kStubCellular, 32195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley shill::kTypeCellular, 32295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley shill::kStateIdle, 32395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley add_to_visible, 32495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley add_to_watchlist); 32595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 32695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 32795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley void SetupNetworkHandler() { 32895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley SetupDefaultShillState(); 32995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley NetworkHandler::Initialize(); 33095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 33195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 33295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley content::TestBrowserThreadBundle thread_bundle_; 33395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley scoped_ptr<TestingProfile> profile_; 33495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley scoped_ptr<NetworkPortalDetectorImpl> network_portal_detector_; 33595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley scoped_ptr<base::HistogramSamples> original_samples_; 33695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley}; 33795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 33895c29f3cd1f6c08c6c0927868683392eea727ccAdam LangleyTEST_F(NetworkPortalDetectorImplTest, NoPortal) { 33995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley ASSERT_TRUE(is_state_idle()); 34095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 34195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley SetConnected(kStubWireless1); 34295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 34395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley ASSERT_TRUE(is_state_checking_for_portal()); 34495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley CheckPortalState( 34595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley NetworkPortalDetector::CAPTIVE_PORTAL_STATUS_UNKNOWN, -1, kStubWireless1); 34695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 34795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley CompleteURLFetch(net::OK, 204, NULL); 34895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 34995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley ASSERT_TRUE(is_state_idle()); 35095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley CheckPortalState( 35195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley NetworkPortalDetector::CAPTIVE_PORTAL_STATUS_ONLINE, 204, kStubWireless1); 35295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley ASSERT_TRUE( 35395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley MakeResultHistogramChecker() 35495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley ->Expect(NetworkPortalDetector::CAPTIVE_PORTAL_STATUS_ONLINE, 1) 35595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley ->Check()); 35695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley} 35795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 35895c29f3cd1f6c08c6c0927868683392eea727ccAdam LangleyTEST_F(NetworkPortalDetectorImplTest, Portal) { 35995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley ASSERT_TRUE(is_state_idle()); 36095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 36195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley // Check HTTP 200 response code. 36295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley SetConnected(kStubWireless1); 36395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley ASSERT_TRUE(is_state_checking_for_portal()); 36495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 36595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley CompleteURLFetch(net::OK, 200, NULL); 36695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 36795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley ASSERT_TRUE(is_state_idle()); 36895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley CheckPortalState( 36995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley NetworkPortalDetector::CAPTIVE_PORTAL_STATUS_PORTAL, 200, kStubWireless1); 37095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 37195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley // Check HTTP 301 response code. 37295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley SetConnected(kStubWireless2); 37395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley ASSERT_TRUE(is_state_checking_for_portal()); 37495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 37595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley CompleteURLFetch(net::OK, 301, NULL); 37695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 37795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley ASSERT_TRUE(is_state_idle()); 37895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley CheckPortalState( 37995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley NetworkPortalDetector::CAPTIVE_PORTAL_STATUS_PORTAL, 301, kStubWireless2); 38095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 38195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley // Check HTTP 302 response code. 38295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley SetConnected(kStubEthernet); 38395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley ASSERT_TRUE(is_state_checking_for_portal()); 38495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 38595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley CompleteURLFetch(net::OK, 302, NULL); 38695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 38795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley ASSERT_TRUE(is_state_idle()); 38895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley CheckPortalState( 38995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley NetworkPortalDetector::CAPTIVE_PORTAL_STATUS_PORTAL, 302, kStubEthernet); 39095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 39195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley ASSERT_TRUE( 39295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley MakeResultHistogramChecker() 39395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley ->Expect(NetworkPortalDetector::CAPTIVE_PORTAL_STATUS_PORTAL, 3) 39495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley ->Check()); 395} 396 397TEST_F(NetworkPortalDetectorImplTest, Online2Offline) { 398 ASSERT_TRUE(is_state_idle()); 399 400 MockObserver observer; 401 network_portal_detector()->AddObserver(&observer); 402 403 NetworkPortalDetector::CaptivePortalState offline_state; 404 offline_state.status = NetworkPortalDetector::CAPTIVE_PORTAL_STATUS_OFFLINE; 405 406 // WiFi is in online state. 407 { 408 // When transitioning to a connected state, the network will transition to 409 // connecting states which will set the default network to NULL. This may 410 // get triggered multiple times. 411 EXPECT_CALL(observer, OnPortalDetectionCompleted(_, offline_state)) 412 .Times(AnyNumber()); 413 414 // Expect a single transition to an online state. 415 NetworkPortalDetector::CaptivePortalState online_state; 416 online_state.status = NetworkPortalDetector::CAPTIVE_PORTAL_STATUS_ONLINE; 417 online_state.response_code = 204; 418 EXPECT_CALL(observer, OnPortalDetectionCompleted(_, online_state)).Times(1); 419 420 SetConnected(kStubWireless1); 421 ASSERT_TRUE(is_state_checking_for_portal()); 422 423 CompleteURLFetch(net::OK, 204, NULL); 424 ASSERT_TRUE(is_state_idle()); 425 426 // Check that observer was notified about online state. 427 Mock::VerifyAndClearExpectations(&observer); 428 } 429 430 // WiFi is turned off. 431 { 432 EXPECT_CALL(observer, OnPortalDetectionCompleted(NULL, offline_state)) 433 .Times(1); 434 435 SetDisconnected(kStubWireless1); 436 ASSERT_TRUE(is_state_idle()); 437 438 // Check that observer was notified about offline state. 439 Mock::VerifyAndClearExpectations(&observer); 440 } 441 442 network_portal_detector()->RemoveObserver(&observer); 443 444 ASSERT_TRUE( 445 MakeResultHistogramChecker() 446 ->Expect(NetworkPortalDetector::CAPTIVE_PORTAL_STATUS_ONLINE, 1) 447 ->Check()); 448} 449 450TEST_F(NetworkPortalDetectorImplTest, TwoNetworks) { 451 ASSERT_TRUE(is_state_idle()); 452 453 SetConnected(kStubWireless1); 454 ASSERT_TRUE(is_state_checking_for_portal()); 455 456 // WiFi is in portal state. 457 CompleteURLFetch(net::OK, 200, NULL); 458 ASSERT_TRUE(is_state_idle()); 459 460 SetConnected(kStubEthernet); 461 ASSERT_TRUE(is_state_checking_for_portal()); 462 463 // ethernet is in online state. 464 CompleteURLFetch(net::OK, 204, NULL); 465 ASSERT_TRUE(is_state_idle()); 466 CheckPortalState( 467 NetworkPortalDetector::CAPTIVE_PORTAL_STATUS_ONLINE, 204, kStubEthernet); 468 CheckPortalState( 469 NetworkPortalDetector::CAPTIVE_PORTAL_STATUS_PORTAL, 200, kStubWireless1); 470 471 ASSERT_TRUE( 472 MakeResultHistogramChecker() 473 ->Expect(NetworkPortalDetector::CAPTIVE_PORTAL_STATUS_ONLINE, 1) 474 ->Expect(NetworkPortalDetector::CAPTIVE_PORTAL_STATUS_PORTAL, 1) 475 ->Check()); 476} 477 478TEST_F(NetworkPortalDetectorImplTest, NetworkChanged) { 479 ASSERT_TRUE(is_state_idle()); 480 481 SetConnected(kStubWireless1); 482 483 // WiFi is in portal state. 484 fetcher()->set_response_code(200); 485 ASSERT_TRUE(is_state_checking_for_portal()); 486 487 // Active network is changed during portal detection for WiFi. 488 SetConnected(kStubEthernet); 489 490 // Portal detection for WiFi is cancelled, portal detection for 491 // ethernet is initiated. 492 ASSERT_TRUE(is_state_checking_for_portal()); 493 494 // ethernet is in online state. 495 CompleteURLFetch(net::OK, 204, NULL); 496 ASSERT_TRUE(is_state_idle()); 497 CheckPortalState( 498 NetworkPortalDetector::CAPTIVE_PORTAL_STATUS_ONLINE, 204, kStubEthernet); 499 500 // As active network was changed during portal detection for wifi 501 // network, it's state must be unknown. 502 CheckPortalState( 503 NetworkPortalDetector::CAPTIVE_PORTAL_STATUS_UNKNOWN, -1, kStubWireless1); 504 505 ASSERT_TRUE( 506 MakeResultHistogramChecker() 507 ->Expect(NetworkPortalDetector::CAPTIVE_PORTAL_STATUS_ONLINE, 1) 508 ->Check()); 509} 510 511TEST_F(NetworkPortalDetectorImplTest, NetworkStateNotChanged) { 512 ASSERT_TRUE(is_state_idle()); 513 514 SetConnected(kStubWireless1); 515 ASSERT_TRUE(is_state_checking_for_portal()); 516 517 CompleteURLFetch(net::OK, 204, NULL); 518 519 ASSERT_TRUE(is_state_idle()); 520 CheckPortalState( 521 NetworkPortalDetector::CAPTIVE_PORTAL_STATUS_ONLINE, 204, kStubWireless1); 522 523 SetConnected(kStubWireless1); 524 ASSERT_TRUE(is_state_idle()); 525 526 ASSERT_TRUE( 527 MakeResultHistogramChecker() 528 ->Expect(NetworkPortalDetector::CAPTIVE_PORTAL_STATUS_ONLINE, 1) 529 ->Check()); 530} 531 532TEST_F(NetworkPortalDetectorImplTest, NetworkStateChanged) { 533 // Test for Portal -> Online -> Portal network state transitions. 534 ASSERT_TRUE(is_state_idle()); 535 536 SetBehindPortal(kStubWireless1); 537 ASSERT_TRUE(is_state_checking_for_portal()); 538 539 CompleteURLFetch(net::OK, 200, NULL); 540 541 ASSERT_TRUE(is_state_idle()); 542 CheckPortalState( 543 NetworkPortalDetector::CAPTIVE_PORTAL_STATUS_PORTAL, 200, kStubWireless1); 544 545 SetConnected(kStubWireless1); 546 ASSERT_TRUE(is_state_checking_for_portal()); 547 548 CompleteURLFetch(net::OK, 204, NULL); 549 550 ASSERT_TRUE(is_state_idle()); 551 CheckPortalState( 552 NetworkPortalDetector::CAPTIVE_PORTAL_STATUS_ONLINE, 204, kStubWireless1); 553 554 SetBehindPortal(kStubWireless1); 555 ASSERT_TRUE(is_state_checking_for_portal()); 556 557 CompleteURLFetch(net::OK, 200, NULL); 558 559 ASSERT_TRUE(is_state_idle()); 560 CheckPortalState( 561 NetworkPortalDetector::CAPTIVE_PORTAL_STATUS_PORTAL, 200, kStubWireless1); 562 563 ASSERT_TRUE( 564 MakeResultHistogramChecker() 565 ->Expect(NetworkPortalDetector::CAPTIVE_PORTAL_STATUS_ONLINE, 1) 566 ->Expect(NetworkPortalDetector::CAPTIVE_PORTAL_STATUS_PORTAL, 2) 567 ->Check()); 568} 569 570TEST_F(NetworkPortalDetectorImplTest, PortalDetectionTimeout) { 571 ASSERT_TRUE(is_state_idle()); 572 573 // For instantaneous timeout. 574 set_next_attempt_timeout(base::TimeDelta::FromSeconds(0)); 575 576 ASSERT_TRUE(is_state_idle()); 577 ASSERT_EQ(0, attempt_count()); 578 579 SetConnected(kStubWireless1); 580 base::RunLoop().RunUntilIdle(); 581 582 // First portal detection timeouts, next portal detection is 583 // scheduled. 584 ASSERT_TRUE(is_state_portal_detection_pending()); 585 ASSERT_EQ(1, attempt_count()); 586 ASSERT_EQ(base::TimeDelta::FromSeconds(3), next_attempt_delay()); 587 588 ASSERT_TRUE(MakeResultHistogramChecker()->Check()); 589} 590 591TEST_F(NetworkPortalDetectorImplTest, PortalDetectionRetryAfter) { 592 ASSERT_TRUE(is_state_idle()); 593 594 const char* retry_after = "HTTP/1.1 503 OK\nRetry-After: 101\n\n"; 595 596 ASSERT_TRUE(is_state_idle()); 597 ASSERT_EQ(0, attempt_count()); 598 599 SetConnected(kStubWireless1); 600 ASSERT_TRUE(is_state_checking_for_portal()); 601 CompleteURLFetch(net::OK, 503, retry_after); 602 603 // First portal detection completed, next portal detection is 604 // scheduled after 101 seconds. 605 ASSERT_TRUE(is_state_portal_detection_pending()); 606 ASSERT_EQ(1, attempt_count()); 607 ASSERT_EQ(base::TimeDelta::FromSeconds(101), next_attempt_delay()); 608 609 ASSERT_TRUE(MakeResultHistogramChecker()->Check()); 610} 611 612TEST_F(NetworkPortalDetectorImplTest, PortalDetectorRetryAfterIsSmall) { 613 ASSERT_TRUE(is_state_idle()); 614 615 const char* retry_after = "HTTP/1.1 503 OK\nRetry-After: 1\n\n"; 616 617 ASSERT_TRUE(is_state_idle()); 618 ASSERT_EQ(0, attempt_count()); 619 620 SetConnected(kStubWireless1); 621 CompleteURLFetch(net::OK, 503, retry_after); 622 623 // First portal detection completed, next portal detection is 624 // scheduled after 3 seconds (due to minimum time between detection 625 // attemps). 626 ASSERT_TRUE(is_state_portal_detection_pending()); 627 ASSERT_EQ(1, attempt_count()); 628 ASSERT_EQ(base::TimeDelta::FromSeconds(3), next_attempt_delay()); 629 630 ASSERT_TRUE(MakeResultHistogramChecker()->Check()); 631} 632 633TEST_F(NetworkPortalDetectorImplTest, FirstAttemptFailed) { 634 ASSERT_TRUE(is_state_idle()); 635 636 set_delay_till_next_attempt(base::TimeDelta()); 637 const char* retry_after = "HTTP/1.1 503 OK\nRetry-After: 0\n\n"; 638 639 ASSERT_TRUE(is_state_idle()); 640 ASSERT_EQ(0, attempt_count()); 641 642 SetConnected(kStubWireless1); 643 644 CompleteURLFetch(net::OK, 503, retry_after); 645 ASSERT_TRUE(is_state_portal_detection_pending()); 646 ASSERT_EQ(1, attempt_count()); 647 ASSERT_EQ(base::TimeDelta::FromSeconds(0), next_attempt_delay()); 648 649 // To run CaptivePortalDetector::DetectCaptivePortal(). 650 base::RunLoop().RunUntilIdle(); 651 652 CompleteURLFetch(net::OK, 204, NULL); 653 ASSERT_TRUE(is_state_idle()); 654 ASSERT_EQ(2, attempt_count()); 655 CheckPortalState( 656 NetworkPortalDetector::CAPTIVE_PORTAL_STATUS_ONLINE, 204, kStubWireless1); 657 658 ASSERT_TRUE( 659 MakeResultHistogramChecker() 660 ->Expect(NetworkPortalDetector::CAPTIVE_PORTAL_STATUS_ONLINE, 1) 661 ->Check()); 662} 663 664TEST_F(NetworkPortalDetectorImplTest, AllAttemptsFailed) { 665 ASSERT_TRUE(is_state_idle()); 666 667 set_delay_till_next_attempt(base::TimeDelta()); 668 const char* retry_after = "HTTP/1.1 503 OK\nRetry-After: 0\n\n"; 669 670 ASSERT_TRUE(is_state_idle()); 671 ASSERT_EQ(0, attempt_count()); 672 673 SetConnected(kStubWireless1); 674 675 CompleteURLFetch(net::OK, 503, retry_after); 676 ASSERT_TRUE(is_state_portal_detection_pending()); 677 ASSERT_EQ(1, attempt_count()); 678 ASSERT_EQ(base::TimeDelta::FromSeconds(0), next_attempt_delay()); 679 680 // To run CaptivePortalDetector::DetectCaptivePortal(). 681 base::RunLoop().RunUntilIdle(); 682 683 CompleteURLFetch(net::OK, 503, retry_after); 684 ASSERT_TRUE(is_state_portal_detection_pending()); 685 ASSERT_EQ(2, attempt_count()); 686 ASSERT_EQ(base::TimeDelta::FromSeconds(0), next_attempt_delay()); 687 688 // To run CaptivePortalDetector::DetectCaptivePortal(). 689 base::RunLoop().RunUntilIdle(); 690 691 CompleteURLFetch(net::OK, 503, retry_after); 692 ASSERT_TRUE(is_state_idle()); 693 ASSERT_EQ(3, attempt_count()); 694 CheckPortalState(NetworkPortalDetector::CAPTIVE_PORTAL_STATUS_OFFLINE, 695 503, 696 kStubWireless1); 697 698 ASSERT_TRUE( 699 MakeResultHistogramChecker() 700 ->Expect(NetworkPortalDetector::CAPTIVE_PORTAL_STATUS_OFFLINE, 1) 701 ->Check()); 702} 703 704TEST_F(NetworkPortalDetectorImplTest, ProxyAuthRequired) { 705 ASSERT_TRUE(is_state_idle()); 706 set_delay_till_next_attempt(base::TimeDelta()); 707 708 SetConnected(kStubWireless1); 709 CompleteURLFetch(net::OK, 407, NULL); 710 ASSERT_EQ(1, attempt_count()); 711 ASSERT_TRUE(is_state_idle()); 712 CheckPortalState( 713 NetworkPortalDetector::CAPTIVE_PORTAL_STATUS_PROXY_AUTH_REQUIRED, 714 407, 715 kStubWireless1); 716 717 ASSERT_TRUE(MakeResultHistogramChecker() 718 ->Expect(NetworkPortalDetector:: 719 CAPTIVE_PORTAL_STATUS_PROXY_AUTH_REQUIRED, 720 1) 721 ->Check()); 722} 723 724TEST_F(NetworkPortalDetectorImplTest, NoResponseButBehindPortal) { 725 ASSERT_TRUE(is_state_idle()); 726 set_delay_till_next_attempt(base::TimeDelta()); 727 728 SetBehindPortal(kStubWireless1); 729 ASSERT_TRUE(is_state_checking_for_portal()); 730 731 CompleteURLFetch( 732 net::ERR_CONNECTION_CLOSED, net::URLFetcher::RESPONSE_CODE_INVALID, NULL); 733 ASSERT_EQ(1, attempt_count()); 734 ASSERT_TRUE(is_state_portal_detection_pending()); 735 736 // To run CaptivePortalDetector::DetectCaptivePortal(). 737 base::RunLoop().RunUntilIdle(); 738 739 CompleteURLFetch( 740 net::ERR_CONNECTION_CLOSED, net::URLFetcher::RESPONSE_CODE_INVALID, NULL); 741 ASSERT_EQ(2, attempt_count()); 742 ASSERT_TRUE(is_state_portal_detection_pending()); 743 744 // To run CaptivePortalDetector::DetectCaptivePortal(). 745 base::RunLoop().RunUntilIdle(); 746 747 CompleteURLFetch( 748 net::ERR_CONNECTION_CLOSED, net::URLFetcher::RESPONSE_CODE_INVALID, NULL); 749 ASSERT_EQ(3, attempt_count()); 750 ASSERT_TRUE(is_state_idle()); 751 752 CheckPortalState(NetworkPortalDetector::CAPTIVE_PORTAL_STATUS_PORTAL, 753 net::URLFetcher::RESPONSE_CODE_INVALID, 754 kStubWireless1); 755 756 ASSERT_TRUE( 757 MakeResultHistogramChecker() 758 ->Expect(NetworkPortalDetector::CAPTIVE_PORTAL_STATUS_PORTAL, 1) 759 ->Check()); 760} 761 762TEST_F(NetworkPortalDetectorImplTest, 763 DisableErrorScreenStrategyWhilePendingRequest) { 764 ASSERT_TRUE(is_state_idle()); 765 set_attempt_count(3); 766 enable_error_screen_strategy(); 767 ASSERT_TRUE(is_state_portal_detection_pending()); 768 disable_error_screen_strategy(); 769 770 // To run CaptivePortalDetector::DetectCaptivePortal(). 771 base::MessageLoop::current()->RunUntilIdle(); 772 773 ASSERT_TRUE(MakeResultHistogramChecker()->Check()); 774} 775 776TEST_F(NetworkPortalDetectorImplTest, ErrorScreenStrategyForOnlineNetwork) { 777 ASSERT_TRUE(is_state_idle()); 778 set_delay_till_next_attempt(base::TimeDelta()); 779 780 SetConnected(kStubWireless1); 781 enable_error_screen_strategy(); 782 // To run CaptivePortalDetector::DetectCaptivePortal(). 783 base::RunLoop().RunUntilIdle(); 784 CompleteURLFetch(net::OK, 204, NULL); 785 786 ASSERT_TRUE(is_state_portal_detection_pending()); 787 CheckPortalState( 788 NetworkPortalDetector::CAPTIVE_PORTAL_STATUS_ONLINE, 204, kStubWireless1); 789 790 // To run CaptivePortalDetector::DetectCaptivePortal(). 791 base::RunLoop().RunUntilIdle(); 792 793 CompleteURLFetch(net::OK, 204, NULL); 794 795 ASSERT_TRUE(is_state_portal_detection_pending()); 796 CheckPortalState( 797 NetworkPortalDetector::CAPTIVE_PORTAL_STATUS_ONLINE, 204, kStubWireless1); 798 799 // To run CaptivePortalDetector::DetectCaptivePortal(). 800 base::RunLoop().RunUntilIdle(); 801 802 disable_error_screen_strategy(); 803 804 ASSERT_TRUE(is_state_portal_detection_pending()); 805 // To run CaptivePortalDetector::DetectCaptivePortal(). 806 base::RunLoop().RunUntilIdle(); 807 ASSERT_TRUE(is_state_checking_for_portal()); 808 CompleteURLFetch(net::OK, 204, NULL); 809 810 CheckPortalState( 811 NetworkPortalDetector::CAPTIVE_PORTAL_STATUS_ONLINE, 204, kStubWireless1); 812 813 ASSERT_TRUE( 814 MakeResultHistogramChecker() 815 ->Expect(NetworkPortalDetector::CAPTIVE_PORTAL_STATUS_ONLINE, 1) 816 ->Check()); 817} 818 819TEST_F(NetworkPortalDetectorImplTest, ErrorScreenStrategyForPortalNetwork) { 820 ASSERT_TRUE(is_state_idle()); 821 set_delay_till_next_attempt(base::TimeDelta()); 822 823 enable_error_screen_strategy(); 824 SetConnected(kStubWireless1); 825 826 CompleteURLFetch( 827 net::ERR_CONNECTION_CLOSED, net::URLFetcher::RESPONSE_CODE_INVALID, NULL); 828 ASSERT_EQ(1, attempt_count()); 829 ASSERT_TRUE(is_state_portal_detection_pending()); 830 CheckPortalState( 831 NetworkPortalDetector::CAPTIVE_PORTAL_STATUS_UNKNOWN, -1, kStubWireless1); 832 833 // To run CaptivePortalDetector::DetectCaptivePortal(). 834 base::RunLoop().RunUntilIdle(); 835 836 CompleteURLFetch( 837 net::ERR_CONNECTION_CLOSED, net::URLFetcher::RESPONSE_CODE_INVALID, NULL); 838 ASSERT_EQ(2, attempt_count()); 839 ASSERT_TRUE(is_state_portal_detection_pending()); 840 CheckPortalState( 841 NetworkPortalDetector::CAPTIVE_PORTAL_STATUS_UNKNOWN, -1, kStubWireless1); 842 843 // To run CaptivePortalDetector::DetectCaptivePortal(). 844 base::RunLoop().RunUntilIdle(); 845 846 CompleteURLFetch(net::OK, 200, NULL); 847 ASSERT_EQ(3, attempt_count()); 848 ASSERT_TRUE(is_state_portal_detection_pending()); 849 CheckPortalState( 850 NetworkPortalDetector::CAPTIVE_PORTAL_STATUS_PORTAL, 200, kStubWireless1); 851 852 // To run CaptivePortalDetector::DetectCaptivePortal(). 853 base::RunLoop().RunUntilIdle(); 854 855 disable_error_screen_strategy(); 856 857 ASSERT_TRUE(is_state_portal_detection_pending()); 858 CheckPortalState( 859 NetworkPortalDetector::CAPTIVE_PORTAL_STATUS_PORTAL, 200, kStubWireless1); 860 861 ASSERT_TRUE( 862 MakeResultHistogramChecker() 863 ->Expect(NetworkPortalDetector::CAPTIVE_PORTAL_STATUS_PORTAL, 1) 864 ->Check()); 865} 866 867TEST_F(NetworkPortalDetectorImplTest, DetectionTimeoutIsCancelled) { 868 ASSERT_TRUE(is_state_idle()); 869 set_delay_till_next_attempt(base::TimeDelta()); 870 871 SetConnected(kStubWireless1); 872 ASSERT_TRUE(is_state_checking_for_portal()); 873 CheckPortalState( 874 NetworkPortalDetector::CAPTIVE_PORTAL_STATUS_UNKNOWN, -1, kStubWireless1); 875 876 stop_detection(); 877 878 ASSERT_TRUE(is_state_idle()); 879 ASSERT_TRUE(attempt_timeout_is_cancelled()); 880 CheckPortalState( 881 NetworkPortalDetector::CAPTIVE_PORTAL_STATUS_UNKNOWN, -1, kStubWireless1); 882 883 ASSERT_TRUE(MakeResultHistogramChecker()->Check()); 884} 885 886TEST_F(NetworkPortalDetectorImplTest, TestDetectionRestart) { 887 ASSERT_TRUE(is_state_idle()); 888 set_delay_till_next_attempt(base::TimeDelta()); 889 890 // First portal detection attempts determines ONLINE state. 891 SetConnected(kStubWireless1); 892 ASSERT_TRUE(is_state_checking_for_portal()); 893 ASSERT_FALSE(start_detection_if_idle()); 894 895 CompleteURLFetch(net::OK, 204, NULL); 896 897 CheckPortalState( 898 NetworkPortalDetector::CAPTIVE_PORTAL_STATUS_ONLINE, 204, kStubWireless1); 899 ASSERT_TRUE(is_state_idle()); 900 901 // First portal detection attempts determines PORTAL state. 902 ASSERT_TRUE(start_detection_if_idle()); 903 ASSERT_TRUE(is_state_portal_detection_pending()); 904 ASSERT_FALSE(start_detection_if_idle()); 905 906 base::RunLoop().RunUntilIdle(); 907 ASSERT_TRUE(is_state_checking_for_portal()); 908 CompleteURLFetch(net::OK, 200, NULL); 909 910 CheckPortalState( 911 NetworkPortalDetector::CAPTIVE_PORTAL_STATUS_PORTAL, 200, kStubWireless1); 912 ASSERT_TRUE(is_state_idle()); 913 914 ASSERT_TRUE( 915 MakeResultHistogramChecker() 916 ->Expect(NetworkPortalDetector::CAPTIVE_PORTAL_STATUS_ONLINE, 1) 917 ->Expect(NetworkPortalDetector::CAPTIVE_PORTAL_STATUS_PORTAL, 1) 918 ->Check()); 919} 920 921TEST_F(NetworkPortalDetectorImplTest, RequestTimeouts) { 922 ASSERT_TRUE(is_state_idle()); 923 set_delay_till_next_attempt(base::TimeDelta()); 924 925 SetNetworkDeviceEnabled(shill::kTypeWifi, false); 926 SetConnected(kStubCellular); 927 928 // First portal detection attempt for cellular1 uses 5sec timeout. 929 CheckRequestTimeoutAndCompleteAttempt( 930 0, 5, net::ERR_CONNECTION_CLOSED, net::URLFetcher::RESPONSE_CODE_INVALID); 931 932 // Second portal detection attempt for cellular1 uses 10sec timeout. 933 ASSERT_TRUE(is_state_portal_detection_pending()); 934 base::RunLoop().RunUntilIdle(); 935 CheckRequestTimeoutAndCompleteAttempt(1, 936 10, 937 net::ERR_CONNECTION_CLOSED, 938 net::URLFetcher::RESPONSE_CODE_INVALID); 939 940 // Third portal detection attempt for cellular1 uses 15sec timeout. 941 ASSERT_TRUE(is_state_portal_detection_pending()); 942 base::RunLoop().RunUntilIdle(); 943 CheckRequestTimeoutAndCompleteAttempt(2, 944 15, 945 net::ERR_CONNECTION_CLOSED, 946 net::URLFetcher::RESPONSE_CODE_INVALID); 947 948 ASSERT_TRUE(is_state_idle()); 949 950 // Check that in lazy detection for cellular1 15sec timeout is used. 951 enable_error_screen_strategy(); 952 ASSERT_TRUE(is_state_portal_detection_pending()); 953 base::RunLoop().RunUntilIdle(); 954 CheckRequestTimeoutAndCompleteAttempt(0, 955 15, 956 net::ERR_CONNECTION_CLOSED, 957 net::URLFetcher::RESPONSE_CODE_INVALID); 958 disable_error_screen_strategy(); 959 ASSERT_TRUE(is_state_portal_detection_pending()); 960 961 SetNetworkDeviceEnabled(shill::kTypeWifi, true); 962 SetConnected(kStubWireless1); 963 964 // First portal detection attempt for wifi1 uses 5sec timeout. 965 CheckRequestTimeoutAndCompleteAttempt( 966 0, 5, net::ERR_CONNECTION_CLOSED, net::URLFetcher::RESPONSE_CODE_INVALID); 967 968 // Second portal detection attempt for wifi1 also uses 5sec timeout. 969 ASSERT_TRUE(is_state_portal_detection_pending()); 970 base::RunLoop().RunUntilIdle(); 971 CheckRequestTimeoutAndCompleteAttempt(1, 10, net::OK, 204); 972 ASSERT_TRUE(is_state_idle()); 973 974 // Check that in error screen strategy detection for wifi1 15sec 975 // timeout is used. 976 enable_error_screen_strategy(); 977 ASSERT_TRUE(is_state_portal_detection_pending()); 978 base::RunLoop().RunUntilIdle(); 979 CheckRequestTimeoutAndCompleteAttempt(0, 15, net::OK, 204); 980 disable_error_screen_strategy(); 981 ASSERT_TRUE(is_state_portal_detection_pending()); 982 983 ASSERT_TRUE( 984 MakeResultHistogramChecker() 985 ->Expect(NetworkPortalDetector::CAPTIVE_PORTAL_STATUS_OFFLINE, 1) 986 ->Expect(NetworkPortalDetector::CAPTIVE_PORTAL_STATUS_ONLINE, 1) 987 ->Check()); 988} 989 990TEST_F(NetworkPortalDetectorImplTest, StartDetectionIfIdle) { 991 ASSERT_TRUE(is_state_idle()); 992 set_delay_till_next_attempt(base::TimeDelta()); 993 SetConnected(kStubWireless1); 994 995 // First portal detection attempt for wifi1 uses 5sec timeout. 996 CheckRequestTimeoutAndCompleteAttempt( 997 0, 5, net::ERR_CONNECTION_CLOSED, net::URLFetcher::RESPONSE_CODE_INVALID); 998 ASSERT_TRUE(is_state_portal_detection_pending()); 999 base::RunLoop().RunUntilIdle(); 1000 1001 // Second portal detection attempt for wifi1 uses 10sec timeout. 1002 CheckRequestTimeoutAndCompleteAttempt(1, 1003 10, 1004 net::ERR_CONNECTION_CLOSED, 1005 net::URLFetcher::RESPONSE_CODE_INVALID); 1006 ASSERT_TRUE(is_state_portal_detection_pending()); 1007 base::RunLoop().RunUntilIdle(); 1008 1009 // Second portal detection attempt for wifi1 uses 15sec timeout. 1010 CheckRequestTimeoutAndCompleteAttempt(2, 1011 15, 1012 net::ERR_CONNECTION_CLOSED, 1013 net::URLFetcher::RESPONSE_CODE_INVALID); 1014 ASSERT_TRUE(is_state_idle()); 1015 start_detection_if_idle(); 1016 1017 ASSERT_TRUE(is_state_portal_detection_pending()); 1018 1019 // First portal detection attempt for wifi1 uses 5sec timeout. 1020 base::RunLoop().RunUntilIdle(); 1021 CheckRequestTimeoutAndCompleteAttempt(0, 5, net::OK, 204); 1022 ASSERT_TRUE(is_state_idle()); 1023 1024 ASSERT_TRUE( 1025 MakeResultHistogramChecker() 1026 ->Expect(NetworkPortalDetector::CAPTIVE_PORTAL_STATUS_OFFLINE, 1) 1027 ->Expect(NetworkPortalDetector::CAPTIVE_PORTAL_STATUS_ONLINE, 1) 1028 ->Check()); 1029} 1030 1031} // namespace chromeos 1032