blob: 180c12acec3c40f584f601f663437168b033faac [file] [log] [blame]
Thieu Le3426c8f2012-01-11 17:35:11 -08001// Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
Darin Petkovafa6fc42011-06-21 16:21:08 -07002// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
Darin Petkovafa6fc42011-06-21 16:21:08 -07005#include "shill/device.h"
Darin Petkovafa6fc42011-06-21 16:21:08 -07006
Chris Masone34af2182011-08-22 11:59:36 -07007#include <ctype.h>
mukesh agrawal5c4dd0b2011-09-14 13:53:14 -07008#include <sys/socket.h>
9#include <linux/if.h> // Needs typedefs from sys/socket.h.
Chris Masone34af2182011-08-22 11:59:36 -070010
Chris Masone3bd3c8c2011-06-13 08:20:26 -070011#include <map>
12#include <string>
13#include <vector>
14
Chris Masone3bd3c8c2011-06-13 08:20:26 -070015#include <chromeos/dbus/service_constants.h>
Chris Masone34af2182011-08-22 11:59:36 -070016#include <dbus-c++/dbus.h>
Chris Masone3bd3c8c2011-06-13 08:20:26 -070017#include <gmock/gmock.h>
Chris Masone34af2182011-08-22 11:59:36 -070018#include <gtest/gtest.h>
Chris Masone3bd3c8c2011-06-13 08:20:26 -070019
20#include "shill/dbus_adaptor.h"
21#include "shill/dhcp_provider.h"
Paul Stewart26b327e2011-10-19 11:38:09 -070022#include "shill/event_dispatcher.h"
Chris Masone95207da2011-06-29 16:50:49 -070023#include "shill/mock_adaptors.h"
Chris Masone3bd3c8c2011-06-13 08:20:26 -070024#include "shill/mock_control.h"
Paul Stewart20088d82012-02-16 06:58:55 -080025#include "shill/mock_connection.h"
Chris Masone3bd3c8c2011-06-13 08:20:26 -070026#include "shill/mock_device.h"
Paul Stewart20088d82012-02-16 06:58:55 -080027#include "shill/mock_device_info.h"
Chris Masone3bd3c8c2011-06-13 08:20:26 -070028#include "shill/mock_glib.h"
Chris Masone34af2182011-08-22 11:59:36 -070029#include "shill/mock_ipconfig.h"
Paul Stewart20088d82012-02-16 06:58:55 -080030#include "shill/mock_manager.h"
Paul Stewartc681fa02012-03-02 19:40:04 -080031#include "shill/mock_portal_detector.h"
mukesh agrawal5c4dd0b2011-09-14 13:53:14 -070032#include "shill/mock_rtnl_handler.h"
Paul Stewart03dba0b2011-08-22 16:32:45 -070033#include "shill/mock_service.h"
Chris Masone5dec5f42011-07-22 14:07:55 -070034#include "shill/mock_store.h"
Paul Stewart20088d82012-02-16 06:58:55 -080035#include "shill/portal_detector.h"
Chris Masone3bd3c8c2011-06-13 08:20:26 -070036#include "shill/property_store_unittest.h"
Gaurav Shah435de2c2011-11-17 19:01:07 -080037#include "shill/technology.h"
Chris Masone3bd3c8c2011-06-13 08:20:26 -070038
39using std::map;
40using std::string;
41using std::vector;
42using ::testing::_;
Chris Masone5dec5f42011-07-22 14:07:55 -070043using ::testing::AtLeast;
Chris Masone3bd3c8c2011-06-13 08:20:26 -070044using ::testing::NiceMock;
45using ::testing::Return;
Paul Stewart20088d82012-02-16 06:58:55 -080046using ::testing::ReturnRef;
Paul Stewart03dba0b2011-08-22 16:32:45 -070047using ::testing::StrictMock;
Chris Masone3bd3c8c2011-06-13 08:20:26 -070048using ::testing::Test;
Chris Masone34af2182011-08-22 11:59:36 -070049using ::testing::Values;
Darin Petkovafa6fc42011-06-21 16:21:08 -070050
51namespace shill {
52
Chris Masone3bd3c8c2011-06-13 08:20:26 -070053class DeviceTest : public PropertyStoreTest {
Darin Petkovafa6fc42011-06-21 16:21:08 -070054 public:
55 DeviceTest()
Chris Masone2176a882011-09-14 22:29:15 -070056 : device_(new Device(control_interface(),
Paul Stewart20088d82012-02-16 06:58:55 -080057 dispatcher(),
Chris Masone626719f2011-08-18 16:58:48 -070058 NULL,
Paul Stewart20088d82012-02-16 06:58:55 -080059 manager(),
Chris Masone626719f2011-08-18 16:58:48 -070060 kDeviceName,
61 kDeviceAddress,
Gaurav Shah435de2c2011-11-17 19:01:07 -080062 0,
Paul Stewartc681fa02012-03-02 19:40:04 -080063 Technology::kUnknown)),
64 device_info_(control_interface(), NULL, NULL, NULL) {
Chris Masone2176a882011-09-14 22:29:15 -070065 DHCPProvider::GetInstance()->glib_ = glib();
66 DHCPProvider::GetInstance()->control_interface_ = control_interface();
Darin Petkovafa6fc42011-06-21 16:21:08 -070067 }
Chris Masone3bd3c8c2011-06-13 08:20:26 -070068 virtual ~DeviceTest() {}
Darin Petkovafa6fc42011-06-21 16:21:08 -070069
mukesh agrawal5c4dd0b2011-09-14 13:53:14 -070070 virtual void SetUp() {
71 device_->rtnl_handler_ = &rtnl_handler_;
72 }
73
Darin Petkovafa6fc42011-06-21 16:21:08 -070074 protected:
Chris Masone626719f2011-08-18 16:58:48 -070075 static const char kDeviceName[];
76 static const char kDeviceAddress[];
77
Darin Petkov79d74c92012-03-07 17:20:32 +010078 void OnIPConfigUpdated(const IPConfigRefPtr &ipconfig, bool success) {
79 device_->OnIPConfigUpdated(ipconfig, success);
Paul Stewart20088d82012-02-16 06:58:55 -080080 }
81
82 void SelectService(const ServiceRefPtr service) {
83 device_->SelectService(service);
84 }
85
Paul Stewart20088d82012-02-16 06:58:55 -080086 void SetConnection(ConnectionRefPtr connection) {
87 device_->connection_ = connection;
88 }
89
Darin Petkovafa6fc42011-06-21 16:21:08 -070090 MockControl control_interface_;
91 DeviceRefPtr device_;
Paul Stewartc681fa02012-03-02 19:40:04 -080092 MockDeviceInfo device_info_;
mukesh agrawal5c4dd0b2011-09-14 13:53:14 -070093 StrictMock<MockRTNLHandler> rtnl_handler_;
Darin Petkovafa6fc42011-06-21 16:21:08 -070094};
95
Chris Masone626719f2011-08-18 16:58:48 -070096const char DeviceTest::kDeviceName[] = "testdevice";
97const char DeviceTest::kDeviceAddress[] = "address";
98
Chris Masone3bd3c8c2011-06-13 08:20:26 -070099TEST_F(DeviceTest, Contains) {
mukesh agrawalde29fa82011-09-16 16:16:36 -0700100 EXPECT_TRUE(device_->store().Contains(flimflam::kNameProperty));
101 EXPECT_FALSE(device_->store().Contains(""));
Chris Masone3bd3c8c2011-06-13 08:20:26 -0700102}
103
Chris Masonea8a2c252011-06-27 22:16:30 -0700104TEST_F(DeviceTest, GetProperties) {
105 map<string, ::DBus::Variant> props;
106 Error error(Error::kInvalidProperty, "");
107 {
108 ::DBus::Error dbus_error;
109 bool expected = true;
mukesh agrawalde29fa82011-09-16 16:16:36 -0700110 device_->mutable_store()->SetBoolProperty(flimflam::kPoweredProperty,
111 expected,
112 &error);
Chris Masone27c4aa52011-07-02 13:10:14 -0700113 DBusAdaptor::GetProperties(device_->store(), &props, &dbus_error);
Chris Masonea8a2c252011-06-27 22:16:30 -0700114 ASSERT_FALSE(props.find(flimflam::kPoweredProperty) == props.end());
115 EXPECT_EQ(props[flimflam::kPoweredProperty].reader().get_bool(),
116 expected);
117 }
118 {
119 ::DBus::Error dbus_error;
Chris Masone27c4aa52011-07-02 13:10:14 -0700120 DBusAdaptor::GetProperties(device_->store(), &props, &dbus_error);
Chris Masonea8a2c252011-06-27 22:16:30 -0700121 ASSERT_FALSE(props.find(flimflam::kNameProperty) == props.end());
122 EXPECT_EQ(props[flimflam::kNameProperty].reader().get_string(),
123 string(kDeviceName));
124 }
125}
126
mukesh agrawal6bb9e7c2012-01-30 14:57:54 -0800127TEST_F(DeviceTest, SetProperty) {
Chris Masone3bd3c8c2011-06-13 08:20:26 -0700128 ::DBus::Error error;
mukesh agrawal6bb9e7c2012-01-30 14:57:54 -0800129 EXPECT_TRUE(DBusAdaptor::SetProperty(device_->mutable_store(),
130 flimflam::kPoweredProperty,
131 PropertyStoreTest::kBoolV,
132 &error));
Chris Masone3bd3c8c2011-06-13 08:20:26 -0700133
Chris Masoneb925cc82011-06-22 15:39:57 -0700134 // Ensure that an attempt to write a R/O property returns InvalidArgs error.
mukesh agrawal6bb9e7c2012-01-30 14:57:54 -0800135 EXPECT_FALSE(DBusAdaptor::SetProperty(device_->mutable_store(),
136 flimflam::kAddressProperty,
137 PropertyStoreTest::kStringV,
138 &error));
Chris Masone9d779932011-08-25 16:33:41 -0700139 EXPECT_EQ(invalid_args(), error.name());
Chris Masone3bd3c8c2011-06-13 08:20:26 -0700140}
141
mukesh agrawal8abd2f62012-01-30 14:56:14 -0800142TEST_F(DeviceTest, ClearProperty) {
143 ::DBus::Error error;
144 EXPECT_TRUE(device_->powered());
145
mukesh agrawal6bb9e7c2012-01-30 14:57:54 -0800146 EXPECT_TRUE(DBusAdaptor::SetProperty(device_->mutable_store(),
147 flimflam::kPoweredProperty,
148 PropertyStoreTest::kBoolV,
149 &error));
mukesh agrawal8abd2f62012-01-30 14:56:14 -0800150 EXPECT_FALSE(device_->powered());
151
152 EXPECT_TRUE(DBusAdaptor::ClearProperty(device_->mutable_store(),
153 flimflam::kPoweredProperty,
154 &error));
155 EXPECT_TRUE(device_->powered());
156}
157
158TEST_F(DeviceTest, ClearReadOnlyProperty) {
159 ::DBus::Error error;
mukesh agrawal6bb9e7c2012-01-30 14:57:54 -0800160 EXPECT_FALSE(DBusAdaptor::SetProperty(device_->mutable_store(),
161 flimflam::kAddressProperty,
162 PropertyStoreTest::kStringV,
163 &error));
mukesh agrawal8abd2f62012-01-30 14:56:14 -0800164}
165
166TEST_F(DeviceTest, ClearReadOnlyDerivedProperty) {
167 ::DBus::Error error;
mukesh agrawal6bb9e7c2012-01-30 14:57:54 -0800168 EXPECT_FALSE(DBusAdaptor::SetProperty(device_->mutable_store(),
169 flimflam::kIPConfigsProperty,
170 PropertyStoreTest::kStringsV,
171 &error));
mukesh agrawal8abd2f62012-01-30 14:56:14 -0800172}
173
Darin Petkovafa6fc42011-06-21 16:21:08 -0700174TEST_F(DeviceTest, TechnologyIs) {
Paul Stewartfdd16072011-09-16 12:41:35 -0700175 EXPECT_FALSE(device_->TechnologyIs(Technology::kEthernet));
Darin Petkovafa6fc42011-06-21 16:21:08 -0700176}
177
178TEST_F(DeviceTest, DestroyIPConfig) {
179 ASSERT_FALSE(device_->ipconfig_.get());
Chris Masone2176a882011-09-14 22:29:15 -0700180 device_->ipconfig_ = new IPConfig(control_interface(), kDeviceName);
Darin Petkovafa6fc42011-06-21 16:21:08 -0700181 device_->DestroyIPConfig();
182 ASSERT_FALSE(device_->ipconfig_.get());
183}
184
185TEST_F(DeviceTest, DestroyIPConfigNULL) {
186 ASSERT_FALSE(device_->ipconfig_.get());
187 device_->DestroyIPConfig();
188 ASSERT_FALSE(device_->ipconfig_.get());
189}
190
Paul Stewart2bf1d352011-12-06 15:02:55 -0800191TEST_F(DeviceTest, AcquireIPConfig) {
Chris Masone2176a882011-09-14 22:29:15 -0700192 device_->ipconfig_ = new IPConfig(control_interface(), "randomname");
193 EXPECT_CALL(*glib(), SpawnAsync(_, _, _, _, _, _, _, _))
Darin Petkovafa6fc42011-06-21 16:21:08 -0700194 .WillOnce(Return(false));
Paul Stewart2bf1d352011-12-06 15:02:55 -0800195 EXPECT_FALSE(device_->AcquireIPConfig());
Darin Petkovafa6fc42011-06-21 16:21:08 -0700196 ASSERT_TRUE(device_->ipconfig_.get());
197 EXPECT_EQ(kDeviceName, device_->ipconfig_->device_name());
198 EXPECT_TRUE(device_->ipconfig_->update_callback_.get());
199}
200
Chris Masone5dec5f42011-07-22 14:07:55 -0700201TEST_F(DeviceTest, Load) {
202 NiceMock<MockStore> storage;
203 const string id = device_->GetStorageIdentifier();
204 EXPECT_CALL(storage, ContainsGroup(id)).WillOnce(Return(true));
205 EXPECT_CALL(storage, GetBool(id, _, _))
206 .Times(AtLeast(1))
207 .WillRepeatedly(Return(true));
208 EXPECT_TRUE(device_->Load(&storage));
209}
210
211TEST_F(DeviceTest, Save) {
212 NiceMock<MockStore> storage;
213 const string id = device_->GetStorageIdentifier();
Chris Masone5dec5f42011-07-22 14:07:55 -0700214 EXPECT_CALL(storage, SetString(id, _, _))
215 .Times(AtLeast(1))
216 .WillRepeatedly(Return(true));
217 EXPECT_CALL(storage, SetBool(id, _, _))
218 .Times(AtLeast(1))
219 .WillRepeatedly(Return(true));
Chris Masone2176a882011-09-14 22:29:15 -0700220 scoped_refptr<MockIPConfig> ipconfig = new MockIPConfig(control_interface(),
Chris Masone34af2182011-08-22 11:59:36 -0700221 kDeviceName);
222 EXPECT_CALL(*ipconfig.get(), Save(_, _))
223 .WillOnce(Return(true));
224 device_->ipconfig_ = ipconfig;
Chris Masone5dec5f42011-07-22 14:07:55 -0700225 EXPECT_TRUE(device_->Save(&storage));
226}
227
Chris Masone34af2182011-08-22 11:59:36 -0700228TEST_F(DeviceTest, StorageIdGeneration) {
229 string to_process("/device/stuff/0");
230 ControlInterface::RpcIdToStorageId(&to_process);
231 EXPECT_TRUE(isalpha(to_process[0]));
232 EXPECT_EQ(string::npos, to_process.find('/'));
233}
234
Paul Stewartc1dec4d2011-12-08 15:25:28 -0800235MATCHER(IsNullRefPtr, "") {
236 return !arg;
237}
238
239MATCHER(NotNullRefPtr, "") {
240 return arg;
241}
242
Paul Stewart03dba0b2011-08-22 16:32:45 -0700243TEST_F(DeviceTest, SelectedService) {
244 EXPECT_FALSE(device_->selected_service_.get());
245 device_->SetServiceState(Service::kStateAssociating);
246 scoped_refptr<MockService> service(
Chris Masone2176a882011-09-14 22:29:15 -0700247 new StrictMock<MockService>(control_interface(),
248 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800249 metrics(),
Chris Masone9d779932011-08-25 16:33:41 -0700250 manager()));
Paul Stewart20088d82012-02-16 06:58:55 -0800251 SelectService(service);
Paul Stewart03dba0b2011-08-22 16:32:45 -0700252 EXPECT_TRUE(device_->selected_service_.get() == service.get());
253
254 EXPECT_CALL(*service.get(), SetState(Service::kStateConfiguring));
255 device_->SetServiceState(Service::kStateConfiguring);
256 EXPECT_CALL(*service.get(), SetFailure(Service::kFailureOutOfRange));
257 device_->SetServiceFailure(Service::kFailureOutOfRange);
258
259 // Service should be returned to "Idle" state
260 EXPECT_CALL(*service.get(), state())
261 .WillOnce(Return(Service::kStateUnknown));
262 EXPECT_CALL(*service.get(), SetState(Service::kStateIdle));
Paul Stewartc1dec4d2011-12-08 15:25:28 -0800263 EXPECT_CALL(*service.get(), SetConnection(IsNullRefPtr()));
Paul Stewart20088d82012-02-16 06:58:55 -0800264 SelectService(NULL);
Paul Stewart03dba0b2011-08-22 16:32:45 -0700265
266 // A service in the "Failure" state should not be reset to "Idle"
Paul Stewart20088d82012-02-16 06:58:55 -0800267 SelectService(service);
Paul Stewart03dba0b2011-08-22 16:32:45 -0700268 EXPECT_CALL(*service.get(), state())
269 .WillOnce(Return(Service::kStateFailure));
Paul Stewartc1dec4d2011-12-08 15:25:28 -0800270 EXPECT_CALL(*service.get(), SetConnection(IsNullRefPtr()));
Paul Stewart20088d82012-02-16 06:58:55 -0800271 SelectService(NULL);
Paul Stewart03dba0b2011-08-22 16:32:45 -0700272}
273
Paul Stewartbe5f5b32011-12-07 17:11:11 -0800274TEST_F(DeviceTest, IPConfigUpdatedFailure) {
275 scoped_refptr<MockService> service(
276 new StrictMock<MockService>(control_interface(),
277 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800278 metrics(),
Paul Stewartbe5f5b32011-12-07 17:11:11 -0800279 manager()));
Paul Stewart20088d82012-02-16 06:58:55 -0800280 SelectService(service);
Paul Stewartbe5f5b32011-12-07 17:11:11 -0800281 EXPECT_CALL(*service.get(), SetState(Service::kStateDisconnected));
Paul Stewartc1dec4d2011-12-08 15:25:28 -0800282 EXPECT_CALL(*service.get(), SetConnection(IsNullRefPtr()));
Darin Petkov79d74c92012-03-07 17:20:32 +0100283 OnIPConfigUpdated(NULL, false);
Paul Stewartbe5f5b32011-12-07 17:11:11 -0800284}
285
286TEST_F(DeviceTest, IPConfigUpdatedSuccess) {
287 scoped_refptr<MockService> service(
288 new StrictMock<MockService>(control_interface(),
289 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800290 metrics(),
Paul Stewartbe5f5b32011-12-07 17:11:11 -0800291 manager()));
Paul Stewart20088d82012-02-16 06:58:55 -0800292 SelectService(service);
Paul Stewartbe5f5b32011-12-07 17:11:11 -0800293 scoped_refptr<MockIPConfig> ipconfig = new MockIPConfig(control_interface(),
294 kDeviceName);
295 EXPECT_CALL(*service.get(), SetState(Service::kStateConnected));
Paul Stewart20088d82012-02-16 06:58:55 -0800296 EXPECT_CALL(*service.get(), IsConnected())
297 .WillRepeatedly(Return(true));
298 EXPECT_CALL(*service.get(), SetState(Service::kStateOnline));
Paul Stewartc1dec4d2011-12-08 15:25:28 -0800299 EXPECT_CALL(*service.get(), SetConnection(NotNullRefPtr()));
Darin Petkov79d74c92012-03-07 17:20:32 +0100300 OnIPConfigUpdated(ipconfig.get(), true);
Paul Stewartbe5f5b32011-12-07 17:11:11 -0800301}
302
mukesh agrawal5c4dd0b2011-09-14 13:53:14 -0700303TEST_F(DeviceTest, Stop) {
304 device_->ipconfig_ = new IPConfig(&control_interface_, kDeviceName);
305 scoped_refptr<MockService> service(
306 new NiceMock<MockService>(&control_interface_,
307 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800308 metrics(),
mukesh agrawal5c4dd0b2011-09-14 13:53:14 -0700309 manager()));
Paul Stewart20088d82012-02-16 06:58:55 -0800310 SelectService(service);
mukesh agrawal5c4dd0b2011-09-14 13:53:14 -0700311
312 EXPECT_CALL(*service.get(), state()).
313 WillRepeatedly(Return(Service::kStateConnected));
314 EXPECT_CALL(*dynamic_cast<DeviceMockAdaptor *>(device_->adaptor_.get()),
315 UpdateEnabled());
316 EXPECT_CALL(rtnl_handler_, SetInterfaceFlags(_, 0, IFF_UP));
317 device_->Stop();
318
319 EXPECT_FALSE(device_->ipconfig_.get());
320 EXPECT_FALSE(device_->selected_service_.get());
321}
322
Paul Stewartc681fa02012-03-02 19:40:04 -0800323
324class DevicePortalDetectionTest : public DeviceTest {
325 public:
326 DevicePortalDetectionTest()
327 : connection_(new StrictMock<MockConnection>(&device_info_)),
328 manager_(control_interface(),
329 dispatcher(),
330 metrics(),
331 glib()),
332 service_(new StrictMock<MockService>(control_interface(),
333 dispatcher(),
334 metrics(),
335 &manager_)),
336 portal_detector_(new StrictMock<MockPortalDetector>(connection_)) {}
337 virtual ~DevicePortalDetectionTest() {}
338 virtual void SetUp() {
339 DeviceTest::SetUp();
340 SelectService(service_);
341 SetConnection(connection_.get());
342 device_->portal_detector_.reset(portal_detector_); // Passes ownership.
343 device_->manager_ = &manager_;
344 }
345
346 protected:
347 bool StartPortalDetection() { return device_->StartPortalDetection(); }
348 void StopPortalDetection() { device_->StopPortalDetection(); }
349
350 void PortalDetectorCallback(const PortalDetector::Result &result) {
351 device_->PortalDetectorCallback(result);
352 }
353 bool RequestPortalDetection() {
354 return device_->RequestPortalDetection();
355 }
356 void SetServiceConnectedState(Service::ConnectState state) {
357 device_->SetServiceConnectedState(state);
358 }
359 void ExpectPortalDetectorReset() {
360 EXPECT_FALSE(device_->portal_detector_.get());
361 }
362 void ExpectPortalDetectorSet() {
363 EXPECT_TRUE(device_->portal_detector_.get());
364 }
365 void ExpectPortalDetectorIsMock() {
366 EXPECT_EQ(portal_detector_, device_->portal_detector_.get());
367 }
368 scoped_refptr<MockConnection> connection_;
369 StrictMock<MockManager> manager_;
370 scoped_refptr<MockService> service_;
371
372 // Used only for EXPECT_CALL(). Object is owned by device.
373 MockPortalDetector *portal_detector_;
374};
375
376TEST_F(DevicePortalDetectionTest, PortalDetectionDisabled) {
377 EXPECT_CALL(*service_.get(), IsConnected())
Paul Stewart20088d82012-02-16 06:58:55 -0800378 .WillRepeatedly(Return(true));
Paul Stewartc681fa02012-03-02 19:40:04 -0800379 EXPECT_CALL(manager_, IsPortalDetectionEnabled(device_->technology()))
Paul Stewart20088d82012-02-16 06:58:55 -0800380 .WillOnce(Return(false));
Paul Stewartc681fa02012-03-02 19:40:04 -0800381 EXPECT_CALL(*service_.get(), SetState(Service::kStateOnline));
Paul Stewart20088d82012-02-16 06:58:55 -0800382 EXPECT_FALSE(StartPortalDetection());
383}
384
Paul Stewartc681fa02012-03-02 19:40:04 -0800385TEST_F(DevicePortalDetectionTest, PortalDetectionProxyConfig) {
386 EXPECT_CALL(*service_.get(), IsConnected())
Paul Stewart20088d82012-02-16 06:58:55 -0800387 .WillRepeatedly(Return(true));
Paul Stewartc681fa02012-03-02 19:40:04 -0800388 EXPECT_CALL(*service_.get(), HasProxyConfig())
Paul Stewart20088d82012-02-16 06:58:55 -0800389 .WillOnce(Return(true));
Paul Stewartc681fa02012-03-02 19:40:04 -0800390 EXPECT_CALL(manager_, IsPortalDetectionEnabled(device_->technology()))
Paul Stewart20088d82012-02-16 06:58:55 -0800391 .WillOnce(Return(true));
Paul Stewartc681fa02012-03-02 19:40:04 -0800392 EXPECT_CALL(*service_.get(), SetState(Service::kStateOnline));
Paul Stewart20088d82012-02-16 06:58:55 -0800393 EXPECT_FALSE(StartPortalDetection());
394}
395
Paul Stewartc681fa02012-03-02 19:40:04 -0800396TEST_F(DevicePortalDetectionTest, PortalDetectionBadUrl) {
397 EXPECT_CALL(*service_.get(), IsConnected())
Paul Stewart20088d82012-02-16 06:58:55 -0800398 .WillRepeatedly(Return(true));
Paul Stewartc681fa02012-03-02 19:40:04 -0800399 EXPECT_CALL(*service_.get(), HasProxyConfig())
Paul Stewart20088d82012-02-16 06:58:55 -0800400 .WillOnce(Return(false));
Paul Stewartc681fa02012-03-02 19:40:04 -0800401 EXPECT_CALL(manager_, IsPortalDetectionEnabled(device_->technology()))
Paul Stewart20088d82012-02-16 06:58:55 -0800402 .WillOnce(Return(true));
403 const string portal_url;
Paul Stewartc681fa02012-03-02 19:40:04 -0800404 EXPECT_CALL(manager_, GetPortalCheckURL())
Paul Stewart20088d82012-02-16 06:58:55 -0800405 .WillRepeatedly(ReturnRef(portal_url));
Paul Stewartc681fa02012-03-02 19:40:04 -0800406 EXPECT_CALL(*service_.get(), SetState(Service::kStateOnline));
Paul Stewart20088d82012-02-16 06:58:55 -0800407 EXPECT_FALSE(StartPortalDetection());
408}
409
Paul Stewartc681fa02012-03-02 19:40:04 -0800410TEST_F(DevicePortalDetectionTest, PortalDetectionStart) {
411 EXPECT_CALL(*service_.get(), IsConnected())
Paul Stewart20088d82012-02-16 06:58:55 -0800412 .WillRepeatedly(Return(true));
Paul Stewartc681fa02012-03-02 19:40:04 -0800413 EXPECT_CALL(*service_.get(), HasProxyConfig())
Paul Stewart20088d82012-02-16 06:58:55 -0800414 .WillOnce(Return(false));
Paul Stewartc681fa02012-03-02 19:40:04 -0800415 EXPECT_CALL(manager_, IsPortalDetectionEnabled(device_->technology()))
Paul Stewart20088d82012-02-16 06:58:55 -0800416 .WillOnce(Return(true));
417 const string portal_url(PortalDetector::kDefaultURL);
Paul Stewartc681fa02012-03-02 19:40:04 -0800418 EXPECT_CALL(manager_, GetPortalCheckURL())
Paul Stewart20088d82012-02-16 06:58:55 -0800419 .WillRepeatedly(ReturnRef(portal_url));
Paul Stewartc681fa02012-03-02 19:40:04 -0800420 EXPECT_CALL(*service_.get(), SetState(Service::kStateOnline))
Paul Stewart20088d82012-02-16 06:58:55 -0800421 .Times(0);
Paul Stewart20088d82012-02-16 06:58:55 -0800422 const string kInterfaceName("int0");
Paul Stewartc681fa02012-03-02 19:40:04 -0800423 EXPECT_CALL(*connection_.get(), interface_name())
424 .WillRepeatedly(ReturnRef(kInterfaceName));
Paul Stewart20088d82012-02-16 06:58:55 -0800425 const vector<string> kDNSServers;
Paul Stewartc681fa02012-03-02 19:40:04 -0800426 EXPECT_CALL(*connection_.get(), dns_servers())
427 .WillRepeatedly(ReturnRef(kDNSServers));
Paul Stewart20088d82012-02-16 06:58:55 -0800428 EXPECT_TRUE(StartPortalDetection());
429
430 // Drop all references to device_info before it falls out of scope.
431 SetConnection(NULL);
432 StopPortalDetection();
433}
434
Paul Stewartc681fa02012-03-02 19:40:04 -0800435TEST_F(DevicePortalDetectionTest, PortalDetectionNonFinal) {
436 EXPECT_CALL(*service_.get(), IsConnected())
Paul Stewart20088d82012-02-16 06:58:55 -0800437 .Times(0);
Paul Stewartc681fa02012-03-02 19:40:04 -0800438 EXPECT_CALL(*service_.get(), SetState(_))
Paul Stewart20088d82012-02-16 06:58:55 -0800439 .Times(0);
Paul Stewart20088d82012-02-16 06:58:55 -0800440 PortalDetectorCallback(PortalDetector::Result(
441 PortalDetector::kPhaseUnknown,
442 PortalDetector::kStatusFailure,
443 false));
444}
445
Paul Stewartc681fa02012-03-02 19:40:04 -0800446TEST_F(DevicePortalDetectionTest, PortalDetectionFailure) {
447 EXPECT_CALL(*service_.get(), IsConnected())
Paul Stewart20088d82012-02-16 06:58:55 -0800448 .WillOnce(Return(true));
Paul Stewartc681fa02012-03-02 19:40:04 -0800449 EXPECT_CALL(*service_.get(), SetState(Service::kStatePortal));
450 EXPECT_CALL(*connection_.get(), is_default())
451 .WillOnce(Return(false));
Paul Stewart20088d82012-02-16 06:58:55 -0800452 PortalDetectorCallback(PortalDetector::Result(
453 PortalDetector::kPhaseUnknown,
454 PortalDetector::kStatusFailure,
455 true));
456}
457
Paul Stewartc681fa02012-03-02 19:40:04 -0800458TEST_F(DevicePortalDetectionTest, PortalDetectionSuccess) {
459 EXPECT_CALL(*service_.get(), IsConnected())
Paul Stewart20088d82012-02-16 06:58:55 -0800460 .WillOnce(Return(true));
Paul Stewartc681fa02012-03-02 19:40:04 -0800461 EXPECT_CALL(*service_.get(), SetState(Service::kStateOnline));
Paul Stewart20088d82012-02-16 06:58:55 -0800462 PortalDetectorCallback(PortalDetector::Result(
463 PortalDetector::kPhaseUnknown,
464 PortalDetector::kStatusSuccess,
465 true));
466}
467
Paul Stewartc681fa02012-03-02 19:40:04 -0800468TEST_F(DevicePortalDetectionTest, RequestPortalDetection) {
469 EXPECT_CALL(*service_.get(), state())
470 .WillOnce(Return(Service::kStateOnline))
471 .WillRepeatedly(Return(Service::kStatePortal));
472 EXPECT_FALSE(RequestPortalDetection());
473
474 EXPECT_CALL(*connection_.get(), is_default())
475 .WillOnce(Return(false))
476 .WillRepeatedly(Return(true));
477 EXPECT_FALSE(RequestPortalDetection());
478
479 EXPECT_CALL(*portal_detector_, IsInProgress())
480 .WillOnce(Return(true));
481 // Portal detection already running.
482 EXPECT_TRUE(RequestPortalDetection());
483
484 // Make sure our running mock portal detector was not replaced.
485 ExpectPortalDetectorIsMock();
486
487 // Throw away our pre-fabricated portal detector, and have the device create
488 // a new one.
489 StopPortalDetection();
490 EXPECT_CALL(manager_, IsPortalDetectionEnabled(device_->technology()))
491 .WillRepeatedly(Return(true));
492 EXPECT_CALL(*service_.get(), HasProxyConfig())
493 .WillRepeatedly(Return(false));
494 const string kPortalCheckURL("http://portal");
495 EXPECT_CALL(manager_, GetPortalCheckURL())
496 .WillOnce(ReturnRef(kPortalCheckURL));
497 const string kInterfaceName("int0");
498 EXPECT_CALL(*connection_.get(), interface_name())
499 .WillRepeatedly(ReturnRef(kInterfaceName));
500 const vector<string> kDNSServers;
501 EXPECT_CALL(*connection_.get(), dns_servers())
502 .WillRepeatedly(ReturnRef(kDNSServers));
503 EXPECT_TRUE(RequestPortalDetection());
504}
505
506TEST_F(DevicePortalDetectionTest, NotConnected) {
507 EXPECT_CALL(*service_.get(), IsConnected())
508 .WillOnce(Return(false));
509 SetServiceConnectedState(Service::kStatePortal);
510 // We don't check for the portal detector to be reset here, because
511 // it would have been reset as a part of disconnection.
512}
513
514TEST_F(DevicePortalDetectionTest, NotPortal) {
515 EXPECT_CALL(*service_.get(), IsConnected())
516 .WillOnce(Return(true));
517 EXPECT_CALL(*service_.get(), SetState(Service::kStateOnline));
518 SetServiceConnectedState(Service::kStateOnline);
519 ExpectPortalDetectorReset();
520}
521
522TEST_F(DevicePortalDetectionTest, NotDefault) {
523 EXPECT_CALL(*service_.get(), IsConnected())
524 .WillOnce(Return(true));
525 EXPECT_CALL(*connection_.get(), is_default())
526 .WillOnce(Return(false));
527 EXPECT_CALL(*service_.get(), SetState(Service::kStatePortal));
528 SetServiceConnectedState(Service::kStatePortal);
529 ExpectPortalDetectorReset();
530}
531
532TEST_F(DevicePortalDetectionTest, PortalIntervalIsZero) {
533 EXPECT_CALL(*service_.get(), IsConnected())
534 .WillOnce(Return(true));
535 EXPECT_CALL(*connection_.get(), is_default())
536 .WillOnce(Return(true));
537 EXPECT_CALL(manager_, GetPortalCheckInterval())
538 .WillOnce(Return(0));
539 EXPECT_CALL(*service_.get(), SetState(Service::kStatePortal));
540 SetServiceConnectedState(Service::kStatePortal);
541 ExpectPortalDetectorReset();
542}
543
544TEST_F(DevicePortalDetectionTest, RestartPortalDetection) {
545 EXPECT_CALL(*service_.get(), IsConnected())
546 .WillOnce(Return(true));
547 EXPECT_CALL(*connection_.get(), is_default())
548 .WillOnce(Return(true));
549 const int kPortalDetectionInterval = 10;
550 EXPECT_CALL(manager_, GetPortalCheckInterval())
551 .Times(AtLeast(1))
552 .WillRepeatedly(Return(kPortalDetectionInterval));
553 const string kPortalCheckURL("http://portal");
554 EXPECT_CALL(manager_, GetPortalCheckURL())
555 .WillOnce(ReturnRef(kPortalCheckURL));
556 EXPECT_CALL(*portal_detector_, StartAfterDelay(kPortalCheckURL,
557 kPortalDetectionInterval))
558 .WillOnce(Return(true));
559 EXPECT_CALL(*service_.get(), SetState(Service::kStatePortal));
560 SetServiceConnectedState(Service::kStatePortal);
561 ExpectPortalDetectorSet();
562}
563
Darin Petkovafa6fc42011-06-21 16:21:08 -0700564} // namespace shill