blob: 1c3f5d4a41f82726a538ae84eadc92b3963b712b [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"
Thieu Lefb46caf2012-03-08 11:57:15 -080032#include "shill/mock_routing_table.h"
mukesh agrawal5c4dd0b2011-09-14 13:53:14 -070033#include "shill/mock_rtnl_handler.h"
Paul Stewart03dba0b2011-08-22 16:32:45 -070034#include "shill/mock_service.h"
Chris Masone5dec5f42011-07-22 14:07:55 -070035#include "shill/mock_store.h"
Paul Stewart20088d82012-02-16 06:58:55 -080036#include "shill/portal_detector.h"
Chris Masone3bd3c8c2011-06-13 08:20:26 -070037#include "shill/property_store_unittest.h"
Gaurav Shah435de2c2011-11-17 19:01:07 -080038#include "shill/technology.h"
Chris Masone3bd3c8c2011-06-13 08:20:26 -070039
40using std::map;
41using std::string;
42using std::vector;
43using ::testing::_;
Chris Masone5dec5f42011-07-22 14:07:55 -070044using ::testing::AtLeast;
Chris Masone3bd3c8c2011-06-13 08:20:26 -070045using ::testing::NiceMock;
46using ::testing::Return;
Paul Stewart20088d82012-02-16 06:58:55 -080047using ::testing::ReturnRef;
Paul Stewart03dba0b2011-08-22 16:32:45 -070048using ::testing::StrictMock;
Chris Masone3bd3c8c2011-06-13 08:20:26 -070049using ::testing::Test;
Chris Masone34af2182011-08-22 11:59:36 -070050using ::testing::Values;
Darin Petkovafa6fc42011-06-21 16:21:08 -070051
52namespace shill {
53
Chris Masone3bd3c8c2011-06-13 08:20:26 -070054class DeviceTest : public PropertyStoreTest {
Darin Petkovafa6fc42011-06-21 16:21:08 -070055 public:
56 DeviceTest()
Chris Masone2176a882011-09-14 22:29:15 -070057 : device_(new Device(control_interface(),
Paul Stewart20088d82012-02-16 06:58:55 -080058 dispatcher(),
Chris Masone626719f2011-08-18 16:58:48 -070059 NULL,
Paul Stewart20088d82012-02-16 06:58:55 -080060 manager(),
Chris Masone626719f2011-08-18 16:58:48 -070061 kDeviceName,
62 kDeviceAddress,
Thieu Lefb46caf2012-03-08 11:57:15 -080063 kDeviceInterfaceIndex,
Paul Stewartc681fa02012-03-02 19:40:04 -080064 Technology::kUnknown)),
65 device_info_(control_interface(), NULL, NULL, NULL) {
Chris Masone2176a882011-09-14 22:29:15 -070066 DHCPProvider::GetInstance()->glib_ = glib();
67 DHCPProvider::GetInstance()->control_interface_ = control_interface();
Darin Petkovafa6fc42011-06-21 16:21:08 -070068 }
Chris Masone3bd3c8c2011-06-13 08:20:26 -070069 virtual ~DeviceTest() {}
Darin Petkovafa6fc42011-06-21 16:21:08 -070070
mukesh agrawal5c4dd0b2011-09-14 13:53:14 -070071 virtual void SetUp() {
Thieu Lefb46caf2012-03-08 11:57:15 -080072 device_->routing_table_ = &routing_table_;
mukesh agrawal5c4dd0b2011-09-14 13:53:14 -070073 device_->rtnl_handler_ = &rtnl_handler_;
74 }
75
Darin Petkovafa6fc42011-06-21 16:21:08 -070076 protected:
Chris Masone626719f2011-08-18 16:58:48 -070077 static const char kDeviceName[];
78 static const char kDeviceAddress[];
Thieu Lefb46caf2012-03-08 11:57:15 -080079 static const int kDeviceInterfaceIndex;
Chris Masone626719f2011-08-18 16:58:48 -070080
Darin Petkov79d74c92012-03-07 17:20:32 +010081 void OnIPConfigUpdated(const IPConfigRefPtr &ipconfig, bool success) {
82 device_->OnIPConfigUpdated(ipconfig, success);
Paul Stewart20088d82012-02-16 06:58:55 -080083 }
84
85 void SelectService(const ServiceRefPtr service) {
86 device_->SelectService(service);
87 }
88
Paul Stewart20088d82012-02-16 06:58:55 -080089 void SetConnection(ConnectionRefPtr connection) {
90 device_->connection_ = connection;
91 }
92
Darin Petkovafa6fc42011-06-21 16:21:08 -070093 MockControl control_interface_;
94 DeviceRefPtr device_;
Paul Stewartc681fa02012-03-02 19:40:04 -080095 MockDeviceInfo device_info_;
Thieu Lefb46caf2012-03-08 11:57:15 -080096 MockRoutingTable routing_table_;
mukesh agrawal5c4dd0b2011-09-14 13:53:14 -070097 StrictMock<MockRTNLHandler> rtnl_handler_;
Darin Petkovafa6fc42011-06-21 16:21:08 -070098};
99
Chris Masone626719f2011-08-18 16:58:48 -0700100const char DeviceTest::kDeviceName[] = "testdevice";
101const char DeviceTest::kDeviceAddress[] = "address";
Thieu Lefb46caf2012-03-08 11:57:15 -0800102const int DeviceTest::kDeviceInterfaceIndex = 0;
Chris Masone626719f2011-08-18 16:58:48 -0700103
Chris Masone3bd3c8c2011-06-13 08:20:26 -0700104TEST_F(DeviceTest, Contains) {
mukesh agrawalde29fa82011-09-16 16:16:36 -0700105 EXPECT_TRUE(device_->store().Contains(flimflam::kNameProperty));
106 EXPECT_FALSE(device_->store().Contains(""));
Chris Masone3bd3c8c2011-06-13 08:20:26 -0700107}
108
Chris Masonea8a2c252011-06-27 22:16:30 -0700109TEST_F(DeviceTest, GetProperties) {
110 map<string, ::DBus::Variant> props;
111 Error error(Error::kInvalidProperty, "");
112 {
113 ::DBus::Error dbus_error;
114 bool expected = true;
mukesh agrawalde29fa82011-09-16 16:16:36 -0700115 device_->mutable_store()->SetBoolProperty(flimflam::kPoweredProperty,
116 expected,
117 &error);
Chris Masone27c4aa52011-07-02 13:10:14 -0700118 DBusAdaptor::GetProperties(device_->store(), &props, &dbus_error);
Chris Masonea8a2c252011-06-27 22:16:30 -0700119 ASSERT_FALSE(props.find(flimflam::kPoweredProperty) == props.end());
120 EXPECT_EQ(props[flimflam::kPoweredProperty].reader().get_bool(),
121 expected);
122 }
123 {
124 ::DBus::Error dbus_error;
Chris Masone27c4aa52011-07-02 13:10:14 -0700125 DBusAdaptor::GetProperties(device_->store(), &props, &dbus_error);
Chris Masonea8a2c252011-06-27 22:16:30 -0700126 ASSERT_FALSE(props.find(flimflam::kNameProperty) == props.end());
127 EXPECT_EQ(props[flimflam::kNameProperty].reader().get_string(),
128 string(kDeviceName));
129 }
130}
131
mukesh agrawal6bb9e7c2012-01-30 14:57:54 -0800132TEST_F(DeviceTest, SetProperty) {
Chris Masone3bd3c8c2011-06-13 08:20:26 -0700133 ::DBus::Error error;
mukesh agrawal6bb9e7c2012-01-30 14:57:54 -0800134 EXPECT_TRUE(DBusAdaptor::SetProperty(device_->mutable_store(),
135 flimflam::kPoweredProperty,
136 PropertyStoreTest::kBoolV,
137 &error));
Chris Masone3bd3c8c2011-06-13 08:20:26 -0700138
Chris Masoneb925cc82011-06-22 15:39:57 -0700139 // Ensure that an attempt to write a R/O property returns InvalidArgs error.
mukesh agrawal6bb9e7c2012-01-30 14:57:54 -0800140 EXPECT_FALSE(DBusAdaptor::SetProperty(device_->mutable_store(),
141 flimflam::kAddressProperty,
142 PropertyStoreTest::kStringV,
143 &error));
Chris Masone9d779932011-08-25 16:33:41 -0700144 EXPECT_EQ(invalid_args(), error.name());
Chris Masone3bd3c8c2011-06-13 08:20:26 -0700145}
146
mukesh agrawal8abd2f62012-01-30 14:56:14 -0800147TEST_F(DeviceTest, ClearProperty) {
148 ::DBus::Error error;
149 EXPECT_TRUE(device_->powered());
150
mukesh agrawal6bb9e7c2012-01-30 14:57:54 -0800151 EXPECT_TRUE(DBusAdaptor::SetProperty(device_->mutable_store(),
152 flimflam::kPoweredProperty,
153 PropertyStoreTest::kBoolV,
154 &error));
mukesh agrawal8abd2f62012-01-30 14:56:14 -0800155 EXPECT_FALSE(device_->powered());
156
157 EXPECT_TRUE(DBusAdaptor::ClearProperty(device_->mutable_store(),
158 flimflam::kPoweredProperty,
159 &error));
160 EXPECT_TRUE(device_->powered());
161}
162
163TEST_F(DeviceTest, ClearReadOnlyProperty) {
164 ::DBus::Error error;
mukesh agrawal6bb9e7c2012-01-30 14:57:54 -0800165 EXPECT_FALSE(DBusAdaptor::SetProperty(device_->mutable_store(),
166 flimflam::kAddressProperty,
167 PropertyStoreTest::kStringV,
168 &error));
mukesh agrawal8abd2f62012-01-30 14:56:14 -0800169}
170
171TEST_F(DeviceTest, ClearReadOnlyDerivedProperty) {
172 ::DBus::Error error;
mukesh agrawal6bb9e7c2012-01-30 14:57:54 -0800173 EXPECT_FALSE(DBusAdaptor::SetProperty(device_->mutable_store(),
174 flimflam::kIPConfigsProperty,
175 PropertyStoreTest::kStringsV,
176 &error));
mukesh agrawal8abd2f62012-01-30 14:56:14 -0800177}
178
Darin Petkovafa6fc42011-06-21 16:21:08 -0700179TEST_F(DeviceTest, TechnologyIs) {
Paul Stewartfdd16072011-09-16 12:41:35 -0700180 EXPECT_FALSE(device_->TechnologyIs(Technology::kEthernet));
Darin Petkovafa6fc42011-06-21 16:21:08 -0700181}
182
183TEST_F(DeviceTest, DestroyIPConfig) {
184 ASSERT_FALSE(device_->ipconfig_.get());
Chris Masone2176a882011-09-14 22:29:15 -0700185 device_->ipconfig_ = new IPConfig(control_interface(), kDeviceName);
Darin Petkovafa6fc42011-06-21 16:21:08 -0700186 device_->DestroyIPConfig();
187 ASSERT_FALSE(device_->ipconfig_.get());
188}
189
190TEST_F(DeviceTest, DestroyIPConfigNULL) {
191 ASSERT_FALSE(device_->ipconfig_.get());
192 device_->DestroyIPConfig();
193 ASSERT_FALSE(device_->ipconfig_.get());
194}
195
Paul Stewart2bf1d352011-12-06 15:02:55 -0800196TEST_F(DeviceTest, AcquireIPConfig) {
Chris Masone2176a882011-09-14 22:29:15 -0700197 device_->ipconfig_ = new IPConfig(control_interface(), "randomname");
198 EXPECT_CALL(*glib(), SpawnAsync(_, _, _, _, _, _, _, _))
Darin Petkovafa6fc42011-06-21 16:21:08 -0700199 .WillOnce(Return(false));
Paul Stewart2bf1d352011-12-06 15:02:55 -0800200 EXPECT_FALSE(device_->AcquireIPConfig());
Darin Petkovafa6fc42011-06-21 16:21:08 -0700201 ASSERT_TRUE(device_->ipconfig_.get());
202 EXPECT_EQ(kDeviceName, device_->ipconfig_->device_name());
203 EXPECT_TRUE(device_->ipconfig_->update_callback_.get());
204}
205
Chris Masone5dec5f42011-07-22 14:07:55 -0700206TEST_F(DeviceTest, Load) {
207 NiceMock<MockStore> storage;
208 const string id = device_->GetStorageIdentifier();
209 EXPECT_CALL(storage, ContainsGroup(id)).WillOnce(Return(true));
210 EXPECT_CALL(storage, GetBool(id, _, _))
211 .Times(AtLeast(1))
212 .WillRepeatedly(Return(true));
213 EXPECT_TRUE(device_->Load(&storage));
214}
215
216TEST_F(DeviceTest, Save) {
217 NiceMock<MockStore> storage;
218 const string id = device_->GetStorageIdentifier();
Chris Masone5dec5f42011-07-22 14:07:55 -0700219 EXPECT_CALL(storage, SetString(id, _, _))
220 .Times(AtLeast(1))
221 .WillRepeatedly(Return(true));
222 EXPECT_CALL(storage, SetBool(id, _, _))
223 .Times(AtLeast(1))
224 .WillRepeatedly(Return(true));
Chris Masone2176a882011-09-14 22:29:15 -0700225 scoped_refptr<MockIPConfig> ipconfig = new MockIPConfig(control_interface(),
Chris Masone34af2182011-08-22 11:59:36 -0700226 kDeviceName);
227 EXPECT_CALL(*ipconfig.get(), Save(_, _))
228 .WillOnce(Return(true));
229 device_->ipconfig_ = ipconfig;
Chris Masone5dec5f42011-07-22 14:07:55 -0700230 EXPECT_TRUE(device_->Save(&storage));
231}
232
Chris Masone34af2182011-08-22 11:59:36 -0700233TEST_F(DeviceTest, StorageIdGeneration) {
234 string to_process("/device/stuff/0");
235 ControlInterface::RpcIdToStorageId(&to_process);
236 EXPECT_TRUE(isalpha(to_process[0]));
237 EXPECT_EQ(string::npos, to_process.find('/'));
238}
239
Paul Stewartc1dec4d2011-12-08 15:25:28 -0800240MATCHER(IsNullRefPtr, "") {
241 return !arg;
242}
243
244MATCHER(NotNullRefPtr, "") {
245 return arg;
246}
247
Paul Stewart03dba0b2011-08-22 16:32:45 -0700248TEST_F(DeviceTest, SelectedService) {
249 EXPECT_FALSE(device_->selected_service_.get());
250 device_->SetServiceState(Service::kStateAssociating);
251 scoped_refptr<MockService> service(
Chris Masone2176a882011-09-14 22:29:15 -0700252 new StrictMock<MockService>(control_interface(),
253 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800254 metrics(),
Chris Masone9d779932011-08-25 16:33:41 -0700255 manager()));
Paul Stewart20088d82012-02-16 06:58:55 -0800256 SelectService(service);
Paul Stewart03dba0b2011-08-22 16:32:45 -0700257 EXPECT_TRUE(device_->selected_service_.get() == service.get());
258
259 EXPECT_CALL(*service.get(), SetState(Service::kStateConfiguring));
260 device_->SetServiceState(Service::kStateConfiguring);
261 EXPECT_CALL(*service.get(), SetFailure(Service::kFailureOutOfRange));
262 device_->SetServiceFailure(Service::kFailureOutOfRange);
263
264 // Service should be returned to "Idle" state
265 EXPECT_CALL(*service.get(), state())
266 .WillOnce(Return(Service::kStateUnknown));
267 EXPECT_CALL(*service.get(), SetState(Service::kStateIdle));
Paul Stewartc1dec4d2011-12-08 15:25:28 -0800268 EXPECT_CALL(*service.get(), SetConnection(IsNullRefPtr()));
Paul Stewart20088d82012-02-16 06:58:55 -0800269 SelectService(NULL);
Paul Stewart03dba0b2011-08-22 16:32:45 -0700270
271 // A service in the "Failure" state should not be reset to "Idle"
Paul Stewart20088d82012-02-16 06:58:55 -0800272 SelectService(service);
Paul Stewart03dba0b2011-08-22 16:32:45 -0700273 EXPECT_CALL(*service.get(), state())
274 .WillOnce(Return(Service::kStateFailure));
Paul Stewartc1dec4d2011-12-08 15:25:28 -0800275 EXPECT_CALL(*service.get(), SetConnection(IsNullRefPtr()));
Paul Stewart20088d82012-02-16 06:58:55 -0800276 SelectService(NULL);
Paul Stewart03dba0b2011-08-22 16:32:45 -0700277}
278
Paul Stewartbe5f5b32011-12-07 17:11:11 -0800279TEST_F(DeviceTest, IPConfigUpdatedFailure) {
280 scoped_refptr<MockService> service(
281 new StrictMock<MockService>(control_interface(),
282 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800283 metrics(),
Paul Stewartbe5f5b32011-12-07 17:11:11 -0800284 manager()));
Paul Stewart20088d82012-02-16 06:58:55 -0800285 SelectService(service);
Paul Stewartbe5f5b32011-12-07 17:11:11 -0800286 EXPECT_CALL(*service.get(), SetState(Service::kStateDisconnected));
Paul Stewartc1dec4d2011-12-08 15:25:28 -0800287 EXPECT_CALL(*service.get(), SetConnection(IsNullRefPtr()));
Darin Petkov79d74c92012-03-07 17:20:32 +0100288 OnIPConfigUpdated(NULL, false);
Paul Stewartbe5f5b32011-12-07 17:11:11 -0800289}
290
291TEST_F(DeviceTest, IPConfigUpdatedSuccess) {
292 scoped_refptr<MockService> service(
293 new StrictMock<MockService>(control_interface(),
294 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800295 metrics(),
Paul Stewartbe5f5b32011-12-07 17:11:11 -0800296 manager()));
Paul Stewart20088d82012-02-16 06:58:55 -0800297 SelectService(service);
Paul Stewartbe5f5b32011-12-07 17:11:11 -0800298 scoped_refptr<MockIPConfig> ipconfig = new MockIPConfig(control_interface(),
299 kDeviceName);
300 EXPECT_CALL(*service.get(), SetState(Service::kStateConnected));
Paul Stewart20088d82012-02-16 06:58:55 -0800301 EXPECT_CALL(*service.get(), IsConnected())
302 .WillRepeatedly(Return(true));
303 EXPECT_CALL(*service.get(), SetState(Service::kStateOnline));
Paul Stewartc1dec4d2011-12-08 15:25:28 -0800304 EXPECT_CALL(*service.get(), SetConnection(NotNullRefPtr()));
Darin Petkov79d74c92012-03-07 17:20:32 +0100305 OnIPConfigUpdated(ipconfig.get(), true);
Paul Stewartbe5f5b32011-12-07 17:11:11 -0800306}
307
Thieu Lefb46caf2012-03-08 11:57:15 -0800308TEST_F(DeviceTest, Start) {
309 EXPECT_CALL(routing_table_, FlushRoutes(kDeviceInterfaceIndex));
310 device_->Start();
311}
312
mukesh agrawal5c4dd0b2011-09-14 13:53:14 -0700313TEST_F(DeviceTest, Stop) {
314 device_->ipconfig_ = new IPConfig(&control_interface_, kDeviceName);
315 scoped_refptr<MockService> service(
316 new NiceMock<MockService>(&control_interface_,
317 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800318 metrics(),
mukesh agrawal5c4dd0b2011-09-14 13:53:14 -0700319 manager()));
Paul Stewart20088d82012-02-16 06:58:55 -0800320 SelectService(service);
mukesh agrawal5c4dd0b2011-09-14 13:53:14 -0700321
322 EXPECT_CALL(*service.get(), state()).
323 WillRepeatedly(Return(Service::kStateConnected));
324 EXPECT_CALL(*dynamic_cast<DeviceMockAdaptor *>(device_->adaptor_.get()),
325 UpdateEnabled());
326 EXPECT_CALL(rtnl_handler_, SetInterfaceFlags(_, 0, IFF_UP));
327 device_->Stop();
328
329 EXPECT_FALSE(device_->ipconfig_.get());
330 EXPECT_FALSE(device_->selected_service_.get());
331}
332
Paul Stewartc681fa02012-03-02 19:40:04 -0800333
334class DevicePortalDetectionTest : public DeviceTest {
335 public:
336 DevicePortalDetectionTest()
337 : connection_(new StrictMock<MockConnection>(&device_info_)),
338 manager_(control_interface(),
339 dispatcher(),
340 metrics(),
341 glib()),
342 service_(new StrictMock<MockService>(control_interface(),
343 dispatcher(),
344 metrics(),
345 &manager_)),
346 portal_detector_(new StrictMock<MockPortalDetector>(connection_)) {}
347 virtual ~DevicePortalDetectionTest() {}
348 virtual void SetUp() {
349 DeviceTest::SetUp();
350 SelectService(service_);
351 SetConnection(connection_.get());
352 device_->portal_detector_.reset(portal_detector_); // Passes ownership.
353 device_->manager_ = &manager_;
354 }
355
356 protected:
357 bool StartPortalDetection() { return device_->StartPortalDetection(); }
358 void StopPortalDetection() { device_->StopPortalDetection(); }
359
360 void PortalDetectorCallback(const PortalDetector::Result &result) {
361 device_->PortalDetectorCallback(result);
362 }
363 bool RequestPortalDetection() {
364 return device_->RequestPortalDetection();
365 }
366 void SetServiceConnectedState(Service::ConnectState state) {
367 device_->SetServiceConnectedState(state);
368 }
369 void ExpectPortalDetectorReset() {
370 EXPECT_FALSE(device_->portal_detector_.get());
371 }
372 void ExpectPortalDetectorSet() {
373 EXPECT_TRUE(device_->portal_detector_.get());
374 }
375 void ExpectPortalDetectorIsMock() {
376 EXPECT_EQ(portal_detector_, device_->portal_detector_.get());
377 }
378 scoped_refptr<MockConnection> connection_;
379 StrictMock<MockManager> manager_;
380 scoped_refptr<MockService> service_;
381
382 // Used only for EXPECT_CALL(). Object is owned by device.
383 MockPortalDetector *portal_detector_;
384};
385
386TEST_F(DevicePortalDetectionTest, PortalDetectionDisabled) {
387 EXPECT_CALL(*service_.get(), IsConnected())
Paul Stewart20088d82012-02-16 06:58:55 -0800388 .WillRepeatedly(Return(true));
Paul Stewartc681fa02012-03-02 19:40:04 -0800389 EXPECT_CALL(manager_, IsPortalDetectionEnabled(device_->technology()))
Paul Stewart20088d82012-02-16 06:58:55 -0800390 .WillOnce(Return(false));
Paul Stewartc681fa02012-03-02 19:40:04 -0800391 EXPECT_CALL(*service_.get(), SetState(Service::kStateOnline));
Paul Stewart20088d82012-02-16 06:58:55 -0800392 EXPECT_FALSE(StartPortalDetection());
393}
394
Paul Stewartc681fa02012-03-02 19:40:04 -0800395TEST_F(DevicePortalDetectionTest, PortalDetectionProxyConfig) {
396 EXPECT_CALL(*service_.get(), IsConnected())
Paul Stewart20088d82012-02-16 06:58:55 -0800397 .WillRepeatedly(Return(true));
Paul Stewartc681fa02012-03-02 19:40:04 -0800398 EXPECT_CALL(*service_.get(), HasProxyConfig())
Paul Stewart20088d82012-02-16 06:58:55 -0800399 .WillOnce(Return(true));
Paul Stewartc681fa02012-03-02 19:40:04 -0800400 EXPECT_CALL(manager_, IsPortalDetectionEnabled(device_->technology()))
Paul Stewart20088d82012-02-16 06:58:55 -0800401 .WillOnce(Return(true));
Paul Stewartc681fa02012-03-02 19:40:04 -0800402 EXPECT_CALL(*service_.get(), SetState(Service::kStateOnline));
Paul Stewart20088d82012-02-16 06:58:55 -0800403 EXPECT_FALSE(StartPortalDetection());
404}
405
Paul Stewartc681fa02012-03-02 19:40:04 -0800406TEST_F(DevicePortalDetectionTest, PortalDetectionBadUrl) {
407 EXPECT_CALL(*service_.get(), IsConnected())
Paul Stewart20088d82012-02-16 06:58:55 -0800408 .WillRepeatedly(Return(true));
Paul Stewartc681fa02012-03-02 19:40:04 -0800409 EXPECT_CALL(*service_.get(), HasProxyConfig())
Paul Stewart20088d82012-02-16 06:58:55 -0800410 .WillOnce(Return(false));
Paul Stewartc681fa02012-03-02 19:40:04 -0800411 EXPECT_CALL(manager_, IsPortalDetectionEnabled(device_->technology()))
Paul Stewart20088d82012-02-16 06:58:55 -0800412 .WillOnce(Return(true));
413 const string portal_url;
Paul Stewartc681fa02012-03-02 19:40:04 -0800414 EXPECT_CALL(manager_, GetPortalCheckURL())
Paul Stewart20088d82012-02-16 06:58:55 -0800415 .WillRepeatedly(ReturnRef(portal_url));
Paul Stewartc681fa02012-03-02 19:40:04 -0800416 EXPECT_CALL(*service_.get(), SetState(Service::kStateOnline));
Paul Stewart20088d82012-02-16 06:58:55 -0800417 EXPECT_FALSE(StartPortalDetection());
418}
419
Paul Stewartc681fa02012-03-02 19:40:04 -0800420TEST_F(DevicePortalDetectionTest, PortalDetectionStart) {
421 EXPECT_CALL(*service_.get(), IsConnected())
Paul Stewart20088d82012-02-16 06:58:55 -0800422 .WillRepeatedly(Return(true));
Paul Stewartc681fa02012-03-02 19:40:04 -0800423 EXPECT_CALL(*service_.get(), HasProxyConfig())
Paul Stewart20088d82012-02-16 06:58:55 -0800424 .WillOnce(Return(false));
Paul Stewartc681fa02012-03-02 19:40:04 -0800425 EXPECT_CALL(manager_, IsPortalDetectionEnabled(device_->technology()))
Paul Stewart20088d82012-02-16 06:58:55 -0800426 .WillOnce(Return(true));
427 const string portal_url(PortalDetector::kDefaultURL);
Paul Stewartc681fa02012-03-02 19:40:04 -0800428 EXPECT_CALL(manager_, GetPortalCheckURL())
Paul Stewart20088d82012-02-16 06:58:55 -0800429 .WillRepeatedly(ReturnRef(portal_url));
Paul Stewartc681fa02012-03-02 19:40:04 -0800430 EXPECT_CALL(*service_.get(), SetState(Service::kStateOnline))
Paul Stewart20088d82012-02-16 06:58:55 -0800431 .Times(0);
Paul Stewart20088d82012-02-16 06:58:55 -0800432 const string kInterfaceName("int0");
Paul Stewartc681fa02012-03-02 19:40:04 -0800433 EXPECT_CALL(*connection_.get(), interface_name())
434 .WillRepeatedly(ReturnRef(kInterfaceName));
Paul Stewart20088d82012-02-16 06:58:55 -0800435 const vector<string> kDNSServers;
Paul Stewartc681fa02012-03-02 19:40:04 -0800436 EXPECT_CALL(*connection_.get(), dns_servers())
437 .WillRepeatedly(ReturnRef(kDNSServers));
Paul Stewart20088d82012-02-16 06:58:55 -0800438 EXPECT_TRUE(StartPortalDetection());
439
440 // Drop all references to device_info before it falls out of scope.
441 SetConnection(NULL);
442 StopPortalDetection();
443}
444
Paul Stewartc681fa02012-03-02 19:40:04 -0800445TEST_F(DevicePortalDetectionTest, PortalDetectionNonFinal) {
446 EXPECT_CALL(*service_.get(), IsConnected())
Paul Stewart20088d82012-02-16 06:58:55 -0800447 .Times(0);
Paul Stewartc681fa02012-03-02 19:40:04 -0800448 EXPECT_CALL(*service_.get(), SetState(_))
Paul Stewart20088d82012-02-16 06:58:55 -0800449 .Times(0);
Paul Stewart20088d82012-02-16 06:58:55 -0800450 PortalDetectorCallback(PortalDetector::Result(
451 PortalDetector::kPhaseUnknown,
452 PortalDetector::kStatusFailure,
453 false));
454}
455
Paul Stewartc681fa02012-03-02 19:40:04 -0800456TEST_F(DevicePortalDetectionTest, PortalDetectionFailure) {
457 EXPECT_CALL(*service_.get(), IsConnected())
Paul Stewart20088d82012-02-16 06:58:55 -0800458 .WillOnce(Return(true));
Paul Stewartc681fa02012-03-02 19:40:04 -0800459 EXPECT_CALL(*service_.get(), SetState(Service::kStatePortal));
460 EXPECT_CALL(*connection_.get(), is_default())
461 .WillOnce(Return(false));
Paul Stewart20088d82012-02-16 06:58:55 -0800462 PortalDetectorCallback(PortalDetector::Result(
463 PortalDetector::kPhaseUnknown,
464 PortalDetector::kStatusFailure,
465 true));
466}
467
Paul Stewartc681fa02012-03-02 19:40:04 -0800468TEST_F(DevicePortalDetectionTest, PortalDetectionSuccess) {
469 EXPECT_CALL(*service_.get(), IsConnected())
Paul Stewart20088d82012-02-16 06:58:55 -0800470 .WillOnce(Return(true));
Paul Stewartc681fa02012-03-02 19:40:04 -0800471 EXPECT_CALL(*service_.get(), SetState(Service::kStateOnline));
Paul Stewart20088d82012-02-16 06:58:55 -0800472 PortalDetectorCallback(PortalDetector::Result(
473 PortalDetector::kPhaseUnknown,
474 PortalDetector::kStatusSuccess,
475 true));
476}
477
Paul Stewartc681fa02012-03-02 19:40:04 -0800478TEST_F(DevicePortalDetectionTest, RequestPortalDetection) {
479 EXPECT_CALL(*service_.get(), state())
480 .WillOnce(Return(Service::kStateOnline))
481 .WillRepeatedly(Return(Service::kStatePortal));
482 EXPECT_FALSE(RequestPortalDetection());
483
484 EXPECT_CALL(*connection_.get(), is_default())
485 .WillOnce(Return(false))
486 .WillRepeatedly(Return(true));
487 EXPECT_FALSE(RequestPortalDetection());
488
489 EXPECT_CALL(*portal_detector_, IsInProgress())
490 .WillOnce(Return(true));
491 // Portal detection already running.
492 EXPECT_TRUE(RequestPortalDetection());
493
494 // Make sure our running mock portal detector was not replaced.
495 ExpectPortalDetectorIsMock();
496
497 // Throw away our pre-fabricated portal detector, and have the device create
498 // a new one.
499 StopPortalDetection();
500 EXPECT_CALL(manager_, IsPortalDetectionEnabled(device_->technology()))
501 .WillRepeatedly(Return(true));
502 EXPECT_CALL(*service_.get(), HasProxyConfig())
503 .WillRepeatedly(Return(false));
504 const string kPortalCheckURL("http://portal");
505 EXPECT_CALL(manager_, GetPortalCheckURL())
506 .WillOnce(ReturnRef(kPortalCheckURL));
507 const string kInterfaceName("int0");
508 EXPECT_CALL(*connection_.get(), interface_name())
509 .WillRepeatedly(ReturnRef(kInterfaceName));
510 const vector<string> kDNSServers;
511 EXPECT_CALL(*connection_.get(), dns_servers())
512 .WillRepeatedly(ReturnRef(kDNSServers));
513 EXPECT_TRUE(RequestPortalDetection());
514}
515
516TEST_F(DevicePortalDetectionTest, NotConnected) {
517 EXPECT_CALL(*service_.get(), IsConnected())
518 .WillOnce(Return(false));
519 SetServiceConnectedState(Service::kStatePortal);
520 // We don't check for the portal detector to be reset here, because
521 // it would have been reset as a part of disconnection.
522}
523
524TEST_F(DevicePortalDetectionTest, NotPortal) {
525 EXPECT_CALL(*service_.get(), IsConnected())
526 .WillOnce(Return(true));
527 EXPECT_CALL(*service_.get(), SetState(Service::kStateOnline));
528 SetServiceConnectedState(Service::kStateOnline);
529 ExpectPortalDetectorReset();
530}
531
532TEST_F(DevicePortalDetectionTest, NotDefault) {
533 EXPECT_CALL(*service_.get(), IsConnected())
534 .WillOnce(Return(true));
535 EXPECT_CALL(*connection_.get(), is_default())
536 .WillOnce(Return(false));
537 EXPECT_CALL(*service_.get(), SetState(Service::kStatePortal));
538 SetServiceConnectedState(Service::kStatePortal);
539 ExpectPortalDetectorReset();
540}
541
542TEST_F(DevicePortalDetectionTest, PortalIntervalIsZero) {
543 EXPECT_CALL(*service_.get(), IsConnected())
544 .WillOnce(Return(true));
545 EXPECT_CALL(*connection_.get(), is_default())
546 .WillOnce(Return(true));
547 EXPECT_CALL(manager_, GetPortalCheckInterval())
548 .WillOnce(Return(0));
549 EXPECT_CALL(*service_.get(), SetState(Service::kStatePortal));
550 SetServiceConnectedState(Service::kStatePortal);
551 ExpectPortalDetectorReset();
552}
553
554TEST_F(DevicePortalDetectionTest, RestartPortalDetection) {
555 EXPECT_CALL(*service_.get(), IsConnected())
556 .WillOnce(Return(true));
557 EXPECT_CALL(*connection_.get(), is_default())
558 .WillOnce(Return(true));
559 const int kPortalDetectionInterval = 10;
560 EXPECT_CALL(manager_, GetPortalCheckInterval())
561 .Times(AtLeast(1))
562 .WillRepeatedly(Return(kPortalDetectionInterval));
563 const string kPortalCheckURL("http://portal");
564 EXPECT_CALL(manager_, GetPortalCheckURL())
565 .WillOnce(ReturnRef(kPortalCheckURL));
566 EXPECT_CALL(*portal_detector_, StartAfterDelay(kPortalCheckURL,
567 kPortalDetectionInterval))
568 .WillOnce(Return(true));
569 EXPECT_CALL(*service_.get(), SetState(Service::kStatePortal));
570 SetServiceConnectedState(Service::kStatePortal);
571 ExpectPortalDetectorSet();
572}
573
Darin Petkovafa6fc42011-06-21 16:21:08 -0700574} // namespace shill