blob: 8686f20beef8854a9cdee1e62a630f92e3cf7166 [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"
Jorge Lucangeli Obesad43cc62012-04-11 16:25:43 -070028#include "shill/mock_dhcp_config.h"
29#include "shill/mock_dhcp_provider.h"
Chris Masone3bd3c8c2011-06-13 08:20:26 -070030#include "shill/mock_glib.h"
Chris Masone34af2182011-08-22 11:59:36 -070031#include "shill/mock_ipconfig.h"
Paul Stewart036dba02012-08-07 12:34:41 -070032#include "shill/mock_link_monitor.h"
Paul Stewart20088d82012-02-16 06:58:55 -080033#include "shill/mock_manager.h"
Thieu Le85e050b2012-03-13 15:04:38 -070034#include "shill/mock_metrics.h"
Paul Stewartc681fa02012-03-02 19:40:04 -080035#include "shill/mock_portal_detector.h"
mukesh agrawal5c4dd0b2011-09-14 13:53:14 -070036#include "shill/mock_rtnl_handler.h"
Paul Stewart03dba0b2011-08-22 16:32:45 -070037#include "shill/mock_service.h"
Chris Masone5dec5f42011-07-22 14:07:55 -070038#include "shill/mock_store.h"
Paul Stewart20088d82012-02-16 06:58:55 -080039#include "shill/portal_detector.h"
Chris Masone3bd3c8c2011-06-13 08:20:26 -070040#include "shill/property_store_unittest.h"
mukesh agrawalcc0fded2012-05-09 13:40:58 -070041#include "shill/static_ip_parameters.h"
Gaurav Shah435de2c2011-11-17 19:01:07 -080042#include "shill/technology.h"
Chris Masone3bd3c8c2011-06-13 08:20:26 -070043
44using std::map;
45using std::string;
46using std::vector;
47using ::testing::_;
mukesh agrawalcc0fded2012-05-09 13:40:58 -070048using ::testing::AnyNumber;
Chris Masone5dec5f42011-07-22 14:07:55 -070049using ::testing::AtLeast;
Paul Stewart6ff27f52012-07-11 06:51:41 -070050using ::testing::Invoke;
Thieu Le85e050b2012-03-13 15:04:38 -070051using ::testing::Mock;
Chris Masone3bd3c8c2011-06-13 08:20:26 -070052using ::testing::NiceMock;
53using ::testing::Return;
Paul Stewart20088d82012-02-16 06:58:55 -080054using ::testing::ReturnRef;
Paul Stewart03dba0b2011-08-22 16:32:45 -070055using ::testing::StrictMock;
Chris Masone3bd3c8c2011-06-13 08:20:26 -070056using ::testing::Test;
Chris Masone34af2182011-08-22 11:59:36 -070057using ::testing::Values;
Darin Petkovafa6fc42011-06-21 16:21:08 -070058
59namespace shill {
60
Eric Shienbrood9a245532012-03-07 14:20:39 -050061class TestDevice : public Device {
62 public:
63 TestDevice(ControlInterface *control_interface,
64 EventDispatcher *dispatcher,
65 Metrics *metrics,
66 Manager *manager,
67 const std::string &link_name,
68 const std::string &address,
69 int interface_index,
70 Technology::Identifier technology)
71 : Device(control_interface, dispatcher, metrics, manager, link_name,
72 address, interface_index, technology) {}
73 ~TestDevice() {}
74 virtual void Start(Error *error,
Jason Glasgow4a490792012-04-10 15:02:05 -040075 const EnabledStateChangedCallback &callback) {
76 DCHECK(error);
77 }
Eric Shienbrood9a245532012-03-07 14:20:39 -050078 virtual void Stop(Error *error,
Jason Glasgow4a490792012-04-10 15:02:05 -040079 const EnabledStateChangedCallback &callback) {
80 DCHECK(error);
81 }
Eric Shienbrood9a245532012-03-07 14:20:39 -050082};
83
Chris Masone3bd3c8c2011-06-13 08:20:26 -070084class DeviceTest : public PropertyStoreTest {
Darin Petkovafa6fc42011-06-21 16:21:08 -070085 public:
86 DeviceTest()
Eric Shienbrood9a245532012-03-07 14:20:39 -050087 : device_(new TestDevice(control_interface(),
88 dispatcher(),
89 NULL,
90 manager(),
91 kDeviceName,
92 kDeviceAddress,
93 kDeviceInterfaceIndex,
94 Technology::kUnknown)),
Paul Stewartc681fa02012-03-02 19:40:04 -080095 device_info_(control_interface(), NULL, NULL, NULL) {
Chris Masone2176a882011-09-14 22:29:15 -070096 DHCPProvider::GetInstance()->glib_ = glib();
97 DHCPProvider::GetInstance()->control_interface_ = control_interface();
mukesh agrawalcc0fded2012-05-09 13:40:58 -070098 DHCPProvider::GetInstance()->dispatcher_ = dispatcher();
Darin Petkovafa6fc42011-06-21 16:21:08 -070099 }
Chris Masone3bd3c8c2011-06-13 08:20:26 -0700100 virtual ~DeviceTest() {}
Darin Petkovafa6fc42011-06-21 16:21:08 -0700101
mukesh agrawal5c4dd0b2011-09-14 13:53:14 -0700102 virtual void SetUp() {
Thieu Le85e050b2012-03-13 15:04:38 -0700103 device_->metrics_ = &metrics_;
mukesh agrawal5c4dd0b2011-09-14 13:53:14 -0700104 device_->rtnl_handler_ = &rtnl_handler_;
105 }
106
Darin Petkovafa6fc42011-06-21 16:21:08 -0700107 protected:
Chris Masone626719f2011-08-18 16:58:48 -0700108 static const char kDeviceName[];
109 static const char kDeviceAddress[];
Thieu Lefb46caf2012-03-08 11:57:15 -0800110 static const int kDeviceInterfaceIndex;
Chris Masone626719f2011-08-18 16:58:48 -0700111
Darin Petkov79d74c92012-03-07 17:20:32 +0100112 void OnIPConfigUpdated(const IPConfigRefPtr &ipconfig, bool success) {
113 device_->OnIPConfigUpdated(ipconfig, success);
Paul Stewart20088d82012-02-16 06:58:55 -0800114 }
115
116 void SelectService(const ServiceRefPtr service) {
117 device_->SelectService(service);
118 }
119
Paul Stewart20088d82012-02-16 06:58:55 -0800120 void SetConnection(ConnectionRefPtr connection) {
121 device_->connection_ = connection;
122 }
123
Paul Stewart036dba02012-08-07 12:34:41 -0700124 void SetLinkMonitor(LinkMonitor *link_monitor) {
125 device_->set_link_monitor(link_monitor); // Passes ownership.
126 }
127
Paul Stewartc8860612012-09-28 07:36:21 -0700128 bool HasLinkMonitor() {
129 return device_->link_monitor();
130 }
131
Paul Stewart036dba02012-08-07 12:34:41 -0700132 bool StartLinkMonitor() {
133 return device_->StartLinkMonitor();
134 }
135
136 void StopLinkMonitor() {
137 device_->StopLinkMonitor();
138 }
139
140 uint64 GetLinkMonitorResponseTime(Error *error) {
141 return device_->GetLinkMonitorResponseTime(error);
142 }
143
144 void SetManager(Manager *manager) {
145 device_->manager_ = manager;
146 }
147
Darin Petkovafa6fc42011-06-21 16:21:08 -0700148 MockControl control_interface_;
149 DeviceRefPtr device_;
Paul Stewartc681fa02012-03-02 19:40:04 -0800150 MockDeviceInfo device_info_;
Thieu Le85e050b2012-03-13 15:04:38 -0700151 MockMetrics metrics_;
mukesh agrawal5c4dd0b2011-09-14 13:53:14 -0700152 StrictMock<MockRTNLHandler> rtnl_handler_;
Darin Petkovafa6fc42011-06-21 16:21:08 -0700153};
154
Chris Masone626719f2011-08-18 16:58:48 -0700155const char DeviceTest::kDeviceName[] = "testdevice";
156const char DeviceTest::kDeviceAddress[] = "address";
Thieu Lefb46caf2012-03-08 11:57:15 -0800157const int DeviceTest::kDeviceInterfaceIndex = 0;
Chris Masone626719f2011-08-18 16:58:48 -0700158
Chris Masone3bd3c8c2011-06-13 08:20:26 -0700159TEST_F(DeviceTest, Contains) {
mukesh agrawalde29fa82011-09-16 16:16:36 -0700160 EXPECT_TRUE(device_->store().Contains(flimflam::kNameProperty));
161 EXPECT_FALSE(device_->store().Contains(""));
Chris Masone3bd3c8c2011-06-13 08:20:26 -0700162}
163
Chris Masonea8a2c252011-06-27 22:16:30 -0700164TEST_F(DeviceTest, GetProperties) {
165 map<string, ::DBus::Variant> props;
166 Error error(Error::kInvalidProperty, "");
Eric Shienbrood9a245532012-03-07 14:20:39 -0500167 ::DBus::Error dbus_error;
168 DBusAdaptor::GetProperties(device_->store(), &props, &dbus_error);
169 ASSERT_FALSE(props.find(flimflam::kNameProperty) == props.end());
170 EXPECT_EQ(props[flimflam::kNameProperty].reader().get_string(),
171 string(kDeviceName));
Chris Masonea8a2c252011-06-27 22:16:30 -0700172}
173
Eric Shienbrood9a245532012-03-07 14:20:39 -0500174// Note: there are currently no writeable Device properties that
175// aren't registered in a subclass.
176TEST_F(DeviceTest, SetReadOnlyProperty) {
Chris Masone3bd3c8c2011-06-13 08:20:26 -0700177 ::DBus::Error error;
Chris Masoneb925cc82011-06-22 15:39:57 -0700178 // Ensure that an attempt to write a R/O property returns InvalidArgs error.
mukesh agrawal6bb9e7c2012-01-30 14:57:54 -0800179 EXPECT_FALSE(DBusAdaptor::SetProperty(device_->mutable_store(),
180 flimflam::kAddressProperty,
181 PropertyStoreTest::kStringV,
182 &error));
Chris Masone9d779932011-08-25 16:33:41 -0700183 EXPECT_EQ(invalid_args(), error.name());
Chris Masone3bd3c8c2011-06-13 08:20:26 -0700184}
185
mukesh agrawal8abd2f62012-01-30 14:56:14 -0800186TEST_F(DeviceTest, ClearReadOnlyProperty) {
187 ::DBus::Error error;
mukesh agrawal6bb9e7c2012-01-30 14:57:54 -0800188 EXPECT_FALSE(DBusAdaptor::SetProperty(device_->mutable_store(),
189 flimflam::kAddressProperty,
190 PropertyStoreTest::kStringV,
191 &error));
mukesh agrawal8abd2f62012-01-30 14:56:14 -0800192}
193
194TEST_F(DeviceTest, ClearReadOnlyDerivedProperty) {
195 ::DBus::Error error;
mukesh agrawal6bb9e7c2012-01-30 14:57:54 -0800196 EXPECT_FALSE(DBusAdaptor::SetProperty(device_->mutable_store(),
197 flimflam::kIPConfigsProperty,
198 PropertyStoreTest::kStringsV,
199 &error));
mukesh agrawal8abd2f62012-01-30 14:56:14 -0800200}
201
Darin Petkovafa6fc42011-06-21 16:21:08 -0700202TEST_F(DeviceTest, DestroyIPConfig) {
203 ASSERT_FALSE(device_->ipconfig_.get());
Chris Masone2176a882011-09-14 22:29:15 -0700204 device_->ipconfig_ = new IPConfig(control_interface(), kDeviceName);
Darin Petkovafa6fc42011-06-21 16:21:08 -0700205 device_->DestroyIPConfig();
206 ASSERT_FALSE(device_->ipconfig_.get());
207}
208
209TEST_F(DeviceTest, DestroyIPConfigNULL) {
210 ASSERT_FALSE(device_->ipconfig_.get());
211 device_->DestroyIPConfig();
212 ASSERT_FALSE(device_->ipconfig_.get());
213}
214
Paul Stewart2bf1d352011-12-06 15:02:55 -0800215TEST_F(DeviceTest, AcquireIPConfig) {
Chris Masone2176a882011-09-14 22:29:15 -0700216 device_->ipconfig_ = new IPConfig(control_interface(), "randomname");
Jorge Lucangeli Obesad43cc62012-04-11 16:25:43 -0700217 scoped_ptr<MockDHCPProvider> dhcp_provider(new MockDHCPProvider());
218 device_->dhcp_provider_ = dhcp_provider.get();
219 scoped_refptr<MockDHCPConfig> dhcp_config(new MockDHCPConfig(
220 control_interface(),
221 kDeviceName));
222 EXPECT_CALL(*dhcp_provider, CreateConfig(_, _, _, _))
223 .WillOnce(Return(dhcp_config));
224 EXPECT_CALL(*dhcp_config, RequestIP())
Darin Petkovafa6fc42011-06-21 16:21:08 -0700225 .WillOnce(Return(false));
Paul Stewart2bf1d352011-12-06 15:02:55 -0800226 EXPECT_FALSE(device_->AcquireIPConfig());
Darin Petkovafa6fc42011-06-21 16:21:08 -0700227 ASSERT_TRUE(device_->ipconfig_.get());
228 EXPECT_EQ(kDeviceName, device_->ipconfig_->device_name());
Eric Shienbrood3e20a232012-02-16 11:35:56 -0500229 EXPECT_FALSE(device_->ipconfig_->update_callback_.is_null());
Jorge Lucangeli Obesad43cc62012-04-11 16:25:43 -0700230 device_->dhcp_provider_ = NULL;
Darin Petkovafa6fc42011-06-21 16:21:08 -0700231}
232
Chris Masone5dec5f42011-07-22 14:07:55 -0700233TEST_F(DeviceTest, Load) {
234 NiceMock<MockStore> storage;
235 const string id = device_->GetStorageIdentifier();
236 EXPECT_CALL(storage, ContainsGroup(id)).WillOnce(Return(true));
Paul Stewart6ff27f52012-07-11 06:51:41 -0700237 EXPECT_CALL(storage, GetBool(id, Device::kStoragePowered, _))
238 .WillOnce(Return(true));
239 EXPECT_CALL(storage, GetUint64(id, Device::kStorageReceiveByteCount, _))
240 .WillOnce(Return(true));
241 EXPECT_CALL(storage, GetUint64(id, Device::kStorageTransmitByteCount, _))
242 .WillOnce(Return(true));
Chris Masone5dec5f42011-07-22 14:07:55 -0700243 EXPECT_TRUE(device_->Load(&storage));
244}
245
246TEST_F(DeviceTest, Save) {
247 NiceMock<MockStore> storage;
248 const string id = device_->GetStorageIdentifier();
Paul Stewart6ff27f52012-07-11 06:51:41 -0700249 EXPECT_CALL(storage, SetString(id, Device::kStorageIPConfigs, _))
250 .WillOnce(Return(true));
251 EXPECT_CALL(storage, SetBool(id, Device::kStoragePowered, _))
252 .WillOnce(Return(true));
Chris Masone2176a882011-09-14 22:29:15 -0700253 scoped_refptr<MockIPConfig> ipconfig = new MockIPConfig(control_interface(),
Chris Masone34af2182011-08-22 11:59:36 -0700254 kDeviceName);
255 EXPECT_CALL(*ipconfig.get(), Save(_, _))
256 .WillOnce(Return(true));
257 device_->ipconfig_ = ipconfig;
Paul Stewart6ff27f52012-07-11 06:51:41 -0700258 EXPECT_CALL(storage, SetUint64(id, Device::kStorageReceiveByteCount, _))
259 .WillOnce(Return(true));
260 EXPECT_CALL(storage, SetUint64(id, Device::kStorageTransmitByteCount, _))
261 .Times(AtLeast(true));
Chris Masone5dec5f42011-07-22 14:07:55 -0700262 EXPECT_TRUE(device_->Save(&storage));
263}
264
Chris Masone34af2182011-08-22 11:59:36 -0700265TEST_F(DeviceTest, StorageIdGeneration) {
266 string to_process("/device/stuff/0");
267 ControlInterface::RpcIdToStorageId(&to_process);
268 EXPECT_TRUE(isalpha(to_process[0]));
269 EXPECT_EQ(string::npos, to_process.find('/'));
270}
271
Paul Stewartc1dec4d2011-12-08 15:25:28 -0800272MATCHER(IsNullRefPtr, "") {
273 return !arg;
274}
275
276MATCHER(NotNullRefPtr, "") {
277 return arg;
278}
279
Paul Stewart03dba0b2011-08-22 16:32:45 -0700280TEST_F(DeviceTest, SelectedService) {
281 EXPECT_FALSE(device_->selected_service_.get());
282 device_->SetServiceState(Service::kStateAssociating);
283 scoped_refptr<MockService> service(
Chris Masone2176a882011-09-14 22:29:15 -0700284 new StrictMock<MockService>(control_interface(),
285 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800286 metrics(),
Chris Masone9d779932011-08-25 16:33:41 -0700287 manager()));
Paul Stewart20088d82012-02-16 06:58:55 -0800288 SelectService(service);
Paul Stewart03dba0b2011-08-22 16:32:45 -0700289 EXPECT_TRUE(device_->selected_service_.get() == service.get());
290
291 EXPECT_CALL(*service.get(), SetState(Service::kStateConfiguring));
292 device_->SetServiceState(Service::kStateConfiguring);
293 EXPECT_CALL(*service.get(), SetFailure(Service::kFailureOutOfRange));
294 device_->SetServiceFailure(Service::kFailureOutOfRange);
295
296 // Service should be returned to "Idle" state
297 EXPECT_CALL(*service.get(), state())
298 .WillOnce(Return(Service::kStateUnknown));
299 EXPECT_CALL(*service.get(), SetState(Service::kStateIdle));
Paul Stewartc1dec4d2011-12-08 15:25:28 -0800300 EXPECT_CALL(*service.get(), SetConnection(IsNullRefPtr()));
Paul Stewart20088d82012-02-16 06:58:55 -0800301 SelectService(NULL);
Paul Stewart03dba0b2011-08-22 16:32:45 -0700302
303 // A service in the "Failure" state should not be reset to "Idle"
Paul Stewart20088d82012-02-16 06:58:55 -0800304 SelectService(service);
Paul Stewart03dba0b2011-08-22 16:32:45 -0700305 EXPECT_CALL(*service.get(), state())
306 .WillOnce(Return(Service::kStateFailure));
Paul Stewartc1dec4d2011-12-08 15:25:28 -0800307 EXPECT_CALL(*service.get(), SetConnection(IsNullRefPtr()));
Paul Stewart20088d82012-02-16 06:58:55 -0800308 SelectService(NULL);
Paul Stewart03dba0b2011-08-22 16:32:45 -0700309}
310
Paul Stewartbe5f5b32011-12-07 17:11:11 -0800311TEST_F(DeviceTest, IPConfigUpdatedFailure) {
312 scoped_refptr<MockService> service(
313 new StrictMock<MockService>(control_interface(),
314 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800315 metrics(),
Paul Stewartbe5f5b32011-12-07 17:11:11 -0800316 manager()));
Paul Stewart20088d82012-02-16 06:58:55 -0800317 SelectService(service);
Christopher Wileyabd3b502012-09-26 13:08:52 -0700318 EXPECT_CALL(*service.get(), DisconnectWithFailure(Service::kFailureDHCP, _));
Paul Stewartc1dec4d2011-12-08 15:25:28 -0800319 EXPECT_CALL(*service.get(), SetConnection(IsNullRefPtr()));
Darin Petkov79d74c92012-03-07 17:20:32 +0100320 OnIPConfigUpdated(NULL, false);
Paul Stewartbe5f5b32011-12-07 17:11:11 -0800321}
322
mukesh agrawalcc0fded2012-05-09 13:40:58 -0700323TEST_F(DeviceTest, IPConfigUpdatedFailureWithStatic) {
324 scoped_refptr<MockService> service(
325 new StrictMock<MockService>(control_interface(),
326 dispatcher(),
327 metrics(),
328 manager()));
329 SelectService(service);
330 service->static_ip_parameters_.args_.SetString(
331 flimflam::kAddressProperty, "1.1.1.1");
332 service->static_ip_parameters_.args_.SetInt(flimflam::kPrefixlenProperty, 16);
333 EXPECT_CALL(*service.get(), SetState(_)).Times(0);
334 EXPECT_CALL(*service.get(), SetConnection(_)).Times(0);
335 OnIPConfigUpdated(NULL, false);
336}
337
Paul Stewartbe5f5b32011-12-07 17:11:11 -0800338TEST_F(DeviceTest, IPConfigUpdatedSuccess) {
339 scoped_refptr<MockService> service(
340 new StrictMock<MockService>(control_interface(),
341 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800342 metrics(),
Paul Stewartbe5f5b32011-12-07 17:11:11 -0800343 manager()));
Paul Stewart20088d82012-02-16 06:58:55 -0800344 SelectService(service);
Paul Stewartbe5f5b32011-12-07 17:11:11 -0800345 scoped_refptr<MockIPConfig> ipconfig = new MockIPConfig(control_interface(),
346 kDeviceName);
347 EXPECT_CALL(*service.get(), SetState(Service::kStateConnected));
Paul Stewart20088d82012-02-16 06:58:55 -0800348 EXPECT_CALL(*service.get(), IsConnected())
349 .WillRepeatedly(Return(true));
Paul Stewartd215af62012-04-24 23:25:50 -0700350 EXPECT_CALL(*service.get(), IsPortalDetectionDisabled())
351 .WillRepeatedly(Return(true));
Paul Stewart20088d82012-02-16 06:58:55 -0800352 EXPECT_CALL(*service.get(), SetState(Service::kStateOnline));
Paul Stewartc1dec4d2011-12-08 15:25:28 -0800353 EXPECT_CALL(*service.get(), SetConnection(NotNullRefPtr()));
Darin Petkov79d74c92012-03-07 17:20:32 +0100354 OnIPConfigUpdated(ipconfig.get(), true);
Paul Stewartbe5f5b32011-12-07 17:11:11 -0800355}
356
Thieu Led1760922012-09-11 14:15:35 -0700357TEST_F(DeviceTest, IPConfigUpdatedSuccessNoSelectedService) {
358 // Make sure shill doesn't crash if a service is disabled immediately
359 // after receiving its IP config (selected_service_ is NULL in this case).
360 scoped_refptr<MockIPConfig> ipconfig = new MockIPConfig(control_interface(),
361 kDeviceName);
362 SelectService(NULL);
363 OnIPConfigUpdated(ipconfig.get(), true);
364}
365
Darin Petkove7c6ad32012-06-29 10:22:09 +0200366TEST_F(DeviceTest, SetEnabledPersistent) {
367 EXPECT_FALSE(device_->enabled_);
368 EXPECT_FALSE(device_->enabled_pending_);
369 device_->enabled_persistent_ = false;
370 StrictMock<MockManager> manager(control_interface(),
371 dispatcher(),
372 metrics(),
373 glib());
374 EXPECT_CALL(manager, UpdateDevice(_));
Paul Stewart036dba02012-08-07 12:34:41 -0700375 SetManager(&manager);
Darin Petkove7c6ad32012-06-29 10:22:09 +0200376 Error error;
377 device_->SetEnabledPersistent(true, &error, ResultCallback());
378 EXPECT_TRUE(device_->enabled_persistent_);
379 EXPECT_TRUE(device_->enabled_pending_);
380}
381
Thieu Lefb46caf2012-03-08 11:57:15 -0800382TEST_F(DeviceTest, Start) {
Paul Stewart8c116a92012-05-02 18:30:03 -0700383 EXPECT_FALSE(device_->running_);
384 EXPECT_FALSE(device_->enabled_);
385 EXPECT_FALSE(device_->enabled_pending_);
Eric Shienbrood9a245532012-03-07 14:20:39 -0500386 device_->SetEnabled(true);
Paul Stewart8c116a92012-05-02 18:30:03 -0700387 EXPECT_TRUE(device_->running_);
388 EXPECT_TRUE(device_->enabled_pending_);
Gary Morainbaeefdf2012-04-30 14:53:35 -0700389 device_->OnEnabledStateChanged(ResultCallback(),
390 Error(Error::kOperationFailed));
391 EXPECT_FALSE(device_->enabled_pending_);
Thieu Lefb46caf2012-03-08 11:57:15 -0800392}
393
mukesh agrawal5c4dd0b2011-09-14 13:53:14 -0700394TEST_F(DeviceTest, Stop) {
Eric Shienbrood9a245532012-03-07 14:20:39 -0500395 device_->enabled_ = true;
396 device_->enabled_pending_ = true;
mukesh agrawal5c4dd0b2011-09-14 13:53:14 -0700397 device_->ipconfig_ = new IPConfig(&control_interface_, kDeviceName);
398 scoped_refptr<MockService> service(
399 new NiceMock<MockService>(&control_interface_,
400 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800401 metrics(),
mukesh agrawal5c4dd0b2011-09-14 13:53:14 -0700402 manager()));
Paul Stewart20088d82012-02-16 06:58:55 -0800403 SelectService(service);
mukesh agrawal5c4dd0b2011-09-14 13:53:14 -0700404
405 EXPECT_CALL(*service.get(), state()).
406 WillRepeatedly(Return(Service::kStateConnected));
407 EXPECT_CALL(*dynamic_cast<DeviceMockAdaptor *>(device_->adaptor_.get()),
408 UpdateEnabled());
Eric Shienbrood9a245532012-03-07 14:20:39 -0500409 EXPECT_CALL(*dynamic_cast<DeviceMockAdaptor *>(device_->adaptor_.get()),
410 EmitBoolChanged(flimflam::kPoweredProperty, false));
mukesh agrawal5c4dd0b2011-09-14 13:53:14 -0700411 EXPECT_CALL(rtnl_handler_, SetInterfaceFlags(_, 0, IFF_UP));
Eric Shienbrood9a245532012-03-07 14:20:39 -0500412 device_->SetEnabled(false);
413 device_->OnEnabledStateChanged(ResultCallback(), Error());
mukesh agrawal5c4dd0b2011-09-14 13:53:14 -0700414
415 EXPECT_FALSE(device_->ipconfig_.get());
416 EXPECT_FALSE(device_->selected_service_.get());
417}
418
mukesh agrawal784566d2012-08-08 18:32:58 -0700419TEST_F(DeviceTest, ResumeWithIPConfig) {
420 scoped_refptr<MockIPConfig> ipconfig =
421 new MockIPConfig(control_interface(), kDeviceName);
422 device_->set_ipconfig(ipconfig);
423 EXPECT_CALL(*ipconfig, RenewIP());
424 device_->OnAfterResume();
425}
426
427TEST_F(DeviceTest, ResumeWithoutIPConfig) {
428 // Just test that we don't crash in this case.
429 ASSERT_EQ(NULL, device_->ipconfig().get());
430 device_->OnAfterResume();
431}
432
Paul Stewart036dba02012-08-07 12:34:41 -0700433TEST_F(DeviceTest, LinkMonitor) {
434 scoped_refptr<MockConnection> connection(
435 new StrictMock<MockConnection>(&device_info_));
436 MockManager manager(control_interface(),
437 dispatcher(),
438 metrics(),
439 glib());
440 scoped_refptr<MockService> service(
441 new StrictMock<MockService>(control_interface(),
442 dispatcher(),
443 metrics(),
444 &manager));
445 SelectService(service);
446 SetConnection(connection.get());
447 MockLinkMonitor *link_monitor = new StrictMock<MockLinkMonitor>();
448 SetLinkMonitor(link_monitor); // Passes ownership.
449 SetManager(&manager);
450 EXPECT_CALL(*link_monitor, Start()).Times(0);
451 EXPECT_CALL(manager, IsTechnologyLinkMonitorEnabled(Technology::kUnknown))
452 .WillOnce(Return(false))
453 .WillRepeatedly(Return(true));
454 EXPECT_FALSE(StartLinkMonitor());
455
456 EXPECT_CALL(*link_monitor, Start())
457 .WillOnce(Return(false))
458 .WillOnce(Return(true));
459 EXPECT_FALSE(StartLinkMonitor());
460 EXPECT_TRUE(StartLinkMonitor());
461
462 unsigned int kResponseTime = 123;
463 EXPECT_CALL(*link_monitor, GetResponseTimeMilliseconds())
464 .WillOnce(Return(kResponseTime));
465 {
466 Error error;
467 EXPECT_EQ(kResponseTime, GetLinkMonitorResponseTime(&error));
468 EXPECT_TRUE(error.IsSuccess());
469 }
470 StopLinkMonitor();
471 {
472 Error error;
473 EXPECT_EQ(0, GetLinkMonitorResponseTime(&error));
474 EXPECT_FALSE(error.IsSuccess());
475 }
476}
477
Paul Stewartc8860612012-09-28 07:36:21 -0700478TEST_F(DeviceTest, LinkMonitorCancelledOnSelectService) {
479 scoped_refptr<MockConnection> connection(
480 new StrictMock<MockConnection>(&device_info_));
481 MockManager manager(control_interface(),
482 dispatcher(),
483 metrics(),
484 glib());
485 scoped_refptr<MockService> service(
486 new StrictMock<MockService>(control_interface(),
487 dispatcher(),
488 metrics(),
489 &manager));
490 SelectService(service);
491 SetConnection(connection.get());
492 MockLinkMonitor *link_monitor = new StrictMock<MockLinkMonitor>();
493 SetLinkMonitor(link_monitor); // Passes ownership.
494 SetManager(&manager);
495 EXPECT_CALL(*service.get(), state())
496 .WillOnce(Return(Service::kStateIdle));
497 EXPECT_CALL(*service.get(), SetState(_));
498 EXPECT_CALL(*service.get(), SetConnection(_));
499 EXPECT_TRUE(HasLinkMonitor());
500 SelectService(NULL);
501 EXPECT_FALSE(HasLinkMonitor());
502}
503
Paul Stewartc681fa02012-03-02 19:40:04 -0800504class DevicePortalDetectionTest : public DeviceTest {
505 public:
506 DevicePortalDetectionTest()
507 : connection_(new StrictMock<MockConnection>(&device_info_)),
508 manager_(control_interface(),
509 dispatcher(),
510 metrics(),
511 glib()),
512 service_(new StrictMock<MockService>(control_interface(),
513 dispatcher(),
514 metrics(),
515 &manager_)),
516 portal_detector_(new StrictMock<MockPortalDetector>(connection_)) {}
517 virtual ~DevicePortalDetectionTest() {}
518 virtual void SetUp() {
519 DeviceTest::SetUp();
520 SelectService(service_);
521 SetConnection(connection_.get());
522 device_->portal_detector_.reset(portal_detector_); // Passes ownership.
Paul Stewart036dba02012-08-07 12:34:41 -0700523 SetManager(&manager_);
Paul Stewartc681fa02012-03-02 19:40:04 -0800524 }
525
526 protected:
Thieu Le85e050b2012-03-13 15:04:38 -0700527 static const int kPortalAttempts;
528
Paul Stewartc681fa02012-03-02 19:40:04 -0800529 bool StartPortalDetection() { return device_->StartPortalDetection(); }
530 void StopPortalDetection() { device_->StopPortalDetection(); }
531
532 void PortalDetectorCallback(const PortalDetector::Result &result) {
533 device_->PortalDetectorCallback(result);
534 }
535 bool RequestPortalDetection() {
536 return device_->RequestPortalDetection();
537 }
538 void SetServiceConnectedState(Service::ConnectState state) {
539 device_->SetServiceConnectedState(state);
540 }
541 void ExpectPortalDetectorReset() {
542 EXPECT_FALSE(device_->portal_detector_.get());
543 }
544 void ExpectPortalDetectorSet() {
545 EXPECT_TRUE(device_->portal_detector_.get());
546 }
547 void ExpectPortalDetectorIsMock() {
548 EXPECT_EQ(portal_detector_, device_->portal_detector_.get());
549 }
550 scoped_refptr<MockConnection> connection_;
551 StrictMock<MockManager> manager_;
552 scoped_refptr<MockService> service_;
553
554 // Used only for EXPECT_CALL(). Object is owned by device.
555 MockPortalDetector *portal_detector_;
556};
557
Thieu Le85e050b2012-03-13 15:04:38 -0700558const int DevicePortalDetectionTest::kPortalAttempts = 2;
559
Paul Stewartd215af62012-04-24 23:25:50 -0700560TEST_F(DevicePortalDetectionTest, ServicePortalDetectionDisabled) {
561 EXPECT_CALL(*service_.get(), IsPortalDetectionDisabled())
562 .WillOnce(Return(true));
Paul Stewartc681fa02012-03-02 19:40:04 -0800563 EXPECT_CALL(*service_.get(), IsConnected())
Paul Stewart20088d82012-02-16 06:58:55 -0800564 .WillRepeatedly(Return(true));
Paul Stewartd215af62012-04-24 23:25:50 -0700565 EXPECT_CALL(*service_.get(), SetState(Service::kStateOnline));
566 EXPECT_FALSE(StartPortalDetection());
567}
568
569TEST_F(DevicePortalDetectionTest, TechnologyPortalDetectionDisabled) {
570 EXPECT_CALL(*service_.get(), IsPortalDetectionDisabled())
571 .WillOnce(Return(false));
572 EXPECT_CALL(*service_.get(), IsConnected())
573 .WillRepeatedly(Return(true));
574 EXPECT_CALL(*service_.get(), IsPortalDetectionAuto())
575 .WillOnce(Return(true));
Paul Stewartc681fa02012-03-02 19:40:04 -0800576 EXPECT_CALL(manager_, IsPortalDetectionEnabled(device_->technology()))
Paul Stewart20088d82012-02-16 06:58:55 -0800577 .WillOnce(Return(false));
Paul Stewartc681fa02012-03-02 19:40:04 -0800578 EXPECT_CALL(*service_.get(), SetState(Service::kStateOnline));
Paul Stewart20088d82012-02-16 06:58:55 -0800579 EXPECT_FALSE(StartPortalDetection());
580}
581
Paul Stewartc681fa02012-03-02 19:40:04 -0800582TEST_F(DevicePortalDetectionTest, PortalDetectionProxyConfig) {
Paul Stewartd215af62012-04-24 23:25:50 -0700583 EXPECT_CALL(*service_.get(), IsPortalDetectionDisabled())
584 .WillOnce(Return(false));
Paul Stewartc681fa02012-03-02 19:40:04 -0800585 EXPECT_CALL(*service_.get(), IsConnected())
Paul Stewart20088d82012-02-16 06:58:55 -0800586 .WillRepeatedly(Return(true));
Paul Stewartc681fa02012-03-02 19:40:04 -0800587 EXPECT_CALL(*service_.get(), HasProxyConfig())
Paul Stewart20088d82012-02-16 06:58:55 -0800588 .WillOnce(Return(true));
Paul Stewartd215af62012-04-24 23:25:50 -0700589 EXPECT_CALL(*service_.get(), IsPortalDetectionAuto())
590 .WillOnce(Return(true));
Paul Stewartc681fa02012-03-02 19:40:04 -0800591 EXPECT_CALL(manager_, IsPortalDetectionEnabled(device_->technology()))
Paul Stewart20088d82012-02-16 06:58:55 -0800592 .WillOnce(Return(true));
Paul Stewartc681fa02012-03-02 19:40:04 -0800593 EXPECT_CALL(*service_.get(), SetState(Service::kStateOnline));
Paul Stewart20088d82012-02-16 06:58:55 -0800594 EXPECT_FALSE(StartPortalDetection());
595}
596
Paul Stewartc681fa02012-03-02 19:40:04 -0800597TEST_F(DevicePortalDetectionTest, PortalDetectionBadUrl) {
Paul Stewartd215af62012-04-24 23:25:50 -0700598 EXPECT_CALL(*service_.get(), IsPortalDetectionDisabled())
599 .WillOnce(Return(false));
Paul Stewartc681fa02012-03-02 19:40:04 -0800600 EXPECT_CALL(*service_.get(), IsConnected())
Paul Stewart20088d82012-02-16 06:58:55 -0800601 .WillRepeatedly(Return(true));
Paul Stewartc681fa02012-03-02 19:40:04 -0800602 EXPECT_CALL(*service_.get(), HasProxyConfig())
Paul Stewart20088d82012-02-16 06:58:55 -0800603 .WillOnce(Return(false));
Paul Stewartd215af62012-04-24 23:25:50 -0700604 EXPECT_CALL(*service_.get(), IsPortalDetectionAuto())
605 .WillOnce(Return(true));
Paul Stewartc681fa02012-03-02 19:40:04 -0800606 EXPECT_CALL(manager_, IsPortalDetectionEnabled(device_->technology()))
Paul Stewart20088d82012-02-16 06:58:55 -0800607 .WillOnce(Return(true));
608 const string portal_url;
Paul Stewartc681fa02012-03-02 19:40:04 -0800609 EXPECT_CALL(manager_, GetPortalCheckURL())
Paul Stewart20088d82012-02-16 06:58:55 -0800610 .WillRepeatedly(ReturnRef(portal_url));
Paul Stewartc681fa02012-03-02 19:40:04 -0800611 EXPECT_CALL(*service_.get(), SetState(Service::kStateOnline));
Paul Stewart20088d82012-02-16 06:58:55 -0800612 EXPECT_FALSE(StartPortalDetection());
613}
614
Paul Stewartc681fa02012-03-02 19:40:04 -0800615TEST_F(DevicePortalDetectionTest, PortalDetectionStart) {
Paul Stewartd215af62012-04-24 23:25:50 -0700616 EXPECT_CALL(*service_.get(), IsPortalDetectionDisabled())
617 .WillOnce(Return(false));
Paul Stewartc681fa02012-03-02 19:40:04 -0800618 EXPECT_CALL(*service_.get(), IsConnected())
Paul Stewart20088d82012-02-16 06:58:55 -0800619 .WillRepeatedly(Return(true));
Paul Stewartc681fa02012-03-02 19:40:04 -0800620 EXPECT_CALL(*service_.get(), HasProxyConfig())
Paul Stewart20088d82012-02-16 06:58:55 -0800621 .WillOnce(Return(false));
Paul Stewartd215af62012-04-24 23:25:50 -0700622 EXPECT_CALL(*service_.get(), IsPortalDetectionAuto())
623 .WillOnce(Return(true));
Paul Stewartc681fa02012-03-02 19:40:04 -0800624 EXPECT_CALL(manager_, IsPortalDetectionEnabled(device_->technology()))
Paul Stewart20088d82012-02-16 06:58:55 -0800625 .WillOnce(Return(true));
626 const string portal_url(PortalDetector::kDefaultURL);
Paul Stewartc681fa02012-03-02 19:40:04 -0800627 EXPECT_CALL(manager_, GetPortalCheckURL())
Paul Stewart20088d82012-02-16 06:58:55 -0800628 .WillRepeatedly(ReturnRef(portal_url));
Paul Stewartc681fa02012-03-02 19:40:04 -0800629 EXPECT_CALL(*service_.get(), SetState(Service::kStateOnline))
Paul Stewart20088d82012-02-16 06:58:55 -0800630 .Times(0);
Paul Stewart20088d82012-02-16 06:58:55 -0800631 const string kInterfaceName("int0");
Paul Stewartc681fa02012-03-02 19:40:04 -0800632 EXPECT_CALL(*connection_.get(), interface_name())
633 .WillRepeatedly(ReturnRef(kInterfaceName));
Paul Stewart20088d82012-02-16 06:58:55 -0800634 const vector<string> kDNSServers;
Paul Stewartc681fa02012-03-02 19:40:04 -0800635 EXPECT_CALL(*connection_.get(), dns_servers())
636 .WillRepeatedly(ReturnRef(kDNSServers));
Paul Stewart20088d82012-02-16 06:58:55 -0800637 EXPECT_TRUE(StartPortalDetection());
638
639 // Drop all references to device_info before it falls out of scope.
640 SetConnection(NULL);
641 StopPortalDetection();
642}
643
Paul Stewartc681fa02012-03-02 19:40:04 -0800644TEST_F(DevicePortalDetectionTest, PortalDetectionNonFinal) {
645 EXPECT_CALL(*service_.get(), IsConnected())
Paul Stewart20088d82012-02-16 06:58:55 -0800646 .Times(0);
Paul Stewartc681fa02012-03-02 19:40:04 -0800647 EXPECT_CALL(*service_.get(), SetState(_))
Paul Stewart20088d82012-02-16 06:58:55 -0800648 .Times(0);
Paul Stewart20088d82012-02-16 06:58:55 -0800649 PortalDetectorCallback(PortalDetector::Result(
650 PortalDetector::kPhaseUnknown,
651 PortalDetector::kStatusFailure,
Thieu Le85e050b2012-03-13 15:04:38 -0700652 kPortalAttempts,
Paul Stewart20088d82012-02-16 06:58:55 -0800653 false));
654}
655
Paul Stewartc681fa02012-03-02 19:40:04 -0800656TEST_F(DevicePortalDetectionTest, PortalDetectionFailure) {
657 EXPECT_CALL(*service_.get(), IsConnected())
Paul Stewart20088d82012-02-16 06:58:55 -0800658 .WillOnce(Return(true));
Paul Stewartc681fa02012-03-02 19:40:04 -0800659 EXPECT_CALL(*service_.get(), SetState(Service::kStatePortal));
Thieu Le85e050b2012-03-13 15:04:38 -0700660 EXPECT_CALL(metrics_,
661 SendEnumToUMA("Network.Shill.Unknown.PortalResult",
662 Metrics::kPortalResultConnectionFailure,
663 Metrics::kPortalResultMax));
664 EXPECT_CALL(metrics_,
665 SendToUMA("Network.Shill.Unknown.PortalAttemptsToOnline",
666 _, _, _, _)).Times(0);
667 EXPECT_CALL(metrics_,
668 SendToUMA("Network.Shill.Unknown.PortalAttempts",
669 kPortalAttempts,
670 Metrics::kMetricPortalAttemptsMin,
671 Metrics::kMetricPortalAttemptsMax,
672 Metrics::kMetricPortalAttemptsNumBuckets));
Paul Stewartc681fa02012-03-02 19:40:04 -0800673 EXPECT_CALL(*connection_.get(), is_default())
674 .WillOnce(Return(false));
Paul Stewart20088d82012-02-16 06:58:55 -0800675 PortalDetectorCallback(PortalDetector::Result(
Thieu Le85e050b2012-03-13 15:04:38 -0700676 PortalDetector::kPhaseConnection,
Paul Stewart20088d82012-02-16 06:58:55 -0800677 PortalDetector::kStatusFailure,
Thieu Le85e050b2012-03-13 15:04:38 -0700678 kPortalAttempts,
Paul Stewart20088d82012-02-16 06:58:55 -0800679 true));
680}
681
Paul Stewartc681fa02012-03-02 19:40:04 -0800682TEST_F(DevicePortalDetectionTest, PortalDetectionSuccess) {
683 EXPECT_CALL(*service_.get(), IsConnected())
Paul Stewart20088d82012-02-16 06:58:55 -0800684 .WillOnce(Return(true));
Paul Stewartc681fa02012-03-02 19:40:04 -0800685 EXPECT_CALL(*service_.get(), SetState(Service::kStateOnline));
Thieu Le85e050b2012-03-13 15:04:38 -0700686 EXPECT_CALL(metrics_,
687 SendEnumToUMA("Network.Shill.Unknown.PortalResult",
688 Metrics::kPortalResultSuccess,
689 Metrics::kPortalResultMax));
690 EXPECT_CALL(metrics_,
691 SendToUMA("Network.Shill.Unknown.PortalAttemptsToOnline",
692 kPortalAttempts,
693 Metrics::kMetricPortalAttemptsToOnlineMin,
694 Metrics::kMetricPortalAttemptsToOnlineMax,
695 Metrics::kMetricPortalAttemptsToOnlineNumBuckets));
696 EXPECT_CALL(metrics_,
697 SendToUMA("Network.Shill.Unknown.PortalAttempts",
698 _, _, _, _)).Times(0);
Paul Stewart20088d82012-02-16 06:58:55 -0800699 PortalDetectorCallback(PortalDetector::Result(
Thieu Le85e050b2012-03-13 15:04:38 -0700700 PortalDetector::kPhaseContent,
Paul Stewart20088d82012-02-16 06:58:55 -0800701 PortalDetector::kStatusSuccess,
Thieu Le85e050b2012-03-13 15:04:38 -0700702 kPortalAttempts,
703 true));
704}
705
706TEST_F(DevicePortalDetectionTest, PortalDetectionSuccessAfterFailure) {
707 EXPECT_CALL(*service_.get(), IsConnected())
708 .WillRepeatedly(Return(true));
709 EXPECT_CALL(*service_.get(), SetState(Service::kStatePortal));
710 EXPECT_CALL(metrics_,
711 SendEnumToUMA("Network.Shill.Unknown.PortalResult",
712 Metrics::kPortalResultConnectionFailure,
713 Metrics::kPortalResultMax));
714 EXPECT_CALL(metrics_,
715 SendToUMA("Network.Shill.Unknown.PortalAttemptsToOnline",
716 _, _, _, _)).Times(0);
717 EXPECT_CALL(metrics_,
718 SendToUMA("Network.Shill.Unknown.PortalAttempts",
719 kPortalAttempts,
720 Metrics::kMetricPortalAttemptsMin,
721 Metrics::kMetricPortalAttemptsMax,
722 Metrics::kMetricPortalAttemptsNumBuckets));
723 EXPECT_CALL(*connection_.get(), is_default())
724 .WillOnce(Return(false));
725 PortalDetectorCallback(PortalDetector::Result(
726 PortalDetector::kPhaseConnection,
727 PortalDetector::kStatusFailure,
728 kPortalAttempts,
729 true));
730 Mock::VerifyAndClearExpectations(&metrics_);
731
732 EXPECT_CALL(*service_.get(), SetState(Service::kStateOnline));
733 EXPECT_CALL(metrics_,
734 SendEnumToUMA("Network.Shill.Unknown.PortalResult",
735 Metrics::kPortalResultSuccess,
736 Metrics::kPortalResultMax));
737 EXPECT_CALL(metrics_,
738 SendToUMA("Network.Shill.Unknown.PortalAttemptsToOnline",
739 kPortalAttempts * 2,
740 Metrics::kMetricPortalAttemptsToOnlineMin,
741 Metrics::kMetricPortalAttemptsToOnlineMax,
742 Metrics::kMetricPortalAttemptsToOnlineNumBuckets));
743 EXPECT_CALL(metrics_,
744 SendToUMA("Network.Shill.Unknown.PortalAttempts",
745 _, _, _, _)).Times(0);
746 PortalDetectorCallback(PortalDetector::Result(
747 PortalDetector::kPhaseContent,
748 PortalDetector::kStatusSuccess,
749 kPortalAttempts,
Paul Stewart20088d82012-02-16 06:58:55 -0800750 true));
751}
752
Paul Stewartc681fa02012-03-02 19:40:04 -0800753TEST_F(DevicePortalDetectionTest, RequestPortalDetection) {
754 EXPECT_CALL(*service_.get(), state())
755 .WillOnce(Return(Service::kStateOnline))
756 .WillRepeatedly(Return(Service::kStatePortal));
757 EXPECT_FALSE(RequestPortalDetection());
758
759 EXPECT_CALL(*connection_.get(), is_default())
760 .WillOnce(Return(false))
761 .WillRepeatedly(Return(true));
762 EXPECT_FALSE(RequestPortalDetection());
763
764 EXPECT_CALL(*portal_detector_, IsInProgress())
765 .WillOnce(Return(true));
766 // Portal detection already running.
767 EXPECT_TRUE(RequestPortalDetection());
768
769 // Make sure our running mock portal detector was not replaced.
770 ExpectPortalDetectorIsMock();
771
772 // Throw away our pre-fabricated portal detector, and have the device create
773 // a new one.
774 StopPortalDetection();
Paul Stewartd215af62012-04-24 23:25:50 -0700775 EXPECT_CALL(*service_.get(), IsPortalDetectionDisabled())
776 .WillRepeatedly(Return(false));
777 EXPECT_CALL(*service_.get(), IsPortalDetectionAuto())
778 .WillRepeatedly(Return(true));
Paul Stewartc681fa02012-03-02 19:40:04 -0800779 EXPECT_CALL(manager_, IsPortalDetectionEnabled(device_->technology()))
780 .WillRepeatedly(Return(true));
781 EXPECT_CALL(*service_.get(), HasProxyConfig())
782 .WillRepeatedly(Return(false));
783 const string kPortalCheckURL("http://portal");
784 EXPECT_CALL(manager_, GetPortalCheckURL())
785 .WillOnce(ReturnRef(kPortalCheckURL));
786 const string kInterfaceName("int0");
787 EXPECT_CALL(*connection_.get(), interface_name())
788 .WillRepeatedly(ReturnRef(kInterfaceName));
789 const vector<string> kDNSServers;
790 EXPECT_CALL(*connection_.get(), dns_servers())
791 .WillRepeatedly(ReturnRef(kDNSServers));
792 EXPECT_TRUE(RequestPortalDetection());
793}
794
795TEST_F(DevicePortalDetectionTest, NotConnected) {
796 EXPECT_CALL(*service_.get(), IsConnected())
797 .WillOnce(Return(false));
798 SetServiceConnectedState(Service::kStatePortal);
799 // We don't check for the portal detector to be reset here, because
800 // it would have been reset as a part of disconnection.
801}
802
803TEST_F(DevicePortalDetectionTest, NotPortal) {
804 EXPECT_CALL(*service_.get(), IsConnected())
805 .WillOnce(Return(true));
806 EXPECT_CALL(*service_.get(), SetState(Service::kStateOnline));
807 SetServiceConnectedState(Service::kStateOnline);
808 ExpectPortalDetectorReset();
809}
810
811TEST_F(DevicePortalDetectionTest, NotDefault) {
812 EXPECT_CALL(*service_.get(), IsConnected())
813 .WillOnce(Return(true));
814 EXPECT_CALL(*connection_.get(), is_default())
815 .WillOnce(Return(false));
816 EXPECT_CALL(*service_.get(), SetState(Service::kStatePortal));
817 SetServiceConnectedState(Service::kStatePortal);
818 ExpectPortalDetectorReset();
819}
820
821TEST_F(DevicePortalDetectionTest, PortalIntervalIsZero) {
822 EXPECT_CALL(*service_.get(), IsConnected())
823 .WillOnce(Return(true));
824 EXPECT_CALL(*connection_.get(), is_default())
825 .WillOnce(Return(true));
826 EXPECT_CALL(manager_, GetPortalCheckInterval())
827 .WillOnce(Return(0));
828 EXPECT_CALL(*service_.get(), SetState(Service::kStatePortal));
829 SetServiceConnectedState(Service::kStatePortal);
830 ExpectPortalDetectorReset();
831}
832
833TEST_F(DevicePortalDetectionTest, RestartPortalDetection) {
834 EXPECT_CALL(*service_.get(), IsConnected())
835 .WillOnce(Return(true));
836 EXPECT_CALL(*connection_.get(), is_default())
837 .WillOnce(Return(true));
838 const int kPortalDetectionInterval = 10;
839 EXPECT_CALL(manager_, GetPortalCheckInterval())
840 .Times(AtLeast(1))
841 .WillRepeatedly(Return(kPortalDetectionInterval));
842 const string kPortalCheckURL("http://portal");
843 EXPECT_CALL(manager_, GetPortalCheckURL())
844 .WillOnce(ReturnRef(kPortalCheckURL));
845 EXPECT_CALL(*portal_detector_, StartAfterDelay(kPortalCheckURL,
846 kPortalDetectionInterval))
847 .WillOnce(Return(true));
848 EXPECT_CALL(*service_.get(), SetState(Service::kStatePortal));
849 SetServiceConnectedState(Service::kStatePortal);
850 ExpectPortalDetectorSet();
851}
852
Paul Stewartc8860612012-09-28 07:36:21 -0700853TEST_F(DevicePortalDetectionTest, CancelledOnSelectService) {
854 ExpectPortalDetectorSet();
855 EXPECT_CALL(*service_.get(), state())
856 .WillOnce(Return(Service::kStateIdle));
857 EXPECT_CALL(*service_.get(), SetState(_));
858 EXPECT_CALL(*service_.get(), SetConnection(_));
859 SelectService(NULL);
860 ExpectPortalDetectorReset();
861}
862
Paul Stewart6ff27f52012-07-11 06:51:41 -0700863class DeviceByteCountTest : public DeviceTest {
864 public:
865 DeviceByteCountTest()
866 : manager_(control_interface(),
867 dispatcher(),
868 metrics(),
869 glib()),
870 rx_byte_count_(0),
871 tx_byte_count_(0),
872 rx_stored_byte_count_(0),
873 tx_stored_byte_count_(0) {}
874 virtual ~DeviceByteCountTest() {}
875
876 virtual void SetUp() {
877 DeviceTest::SetUp();
878 EXPECT_CALL(manager_, device_info()).WillRepeatedly(Return(&device_info_));
879 EXPECT_CALL(device_info_, GetByteCounts(kDeviceInterfaceIndex, _, _))
880 .WillRepeatedly(Invoke(this, &DeviceByteCountTest::ReturnByteCounts));
881 const string id = device_->GetStorageIdentifier();
882 EXPECT_CALL(storage_, ContainsGroup(id)).WillRepeatedly(Return(true));
883 EXPECT_CALL(storage_, GetUint64(id, Device::kStorageReceiveByteCount, _))
884 .WillRepeatedly(
885 Invoke(this, &DeviceByteCountTest::GetStoredReceiveCount));
886 EXPECT_CALL(storage_, GetUint64(id, Device::kStorageTransmitByteCount, _))
887 .WillRepeatedly(
888 Invoke(this, &DeviceByteCountTest::GetStoredTransmitCount));
889 }
890
891 bool ReturnByteCounts(int interface_index, uint64 *rx, uint64 *tx) {
892 *rx = rx_byte_count_;
893 *tx = tx_byte_count_;
894 return true;
895 }
896
897 bool ExpectByteCounts(DeviceRefPtr device,
898 int64 expected_rx, int64 expected_tx) {
899 int64 actual_rx = device->GetReceiveByteCount(NULL);
900 int64 actual_tx = device->GetTransmitByteCount(NULL);
901 EXPECT_EQ(expected_rx, actual_rx);
902 EXPECT_EQ(expected_tx, actual_tx);
903 return expected_rx == actual_rx && expected_tx == actual_tx;
904 }
905
906 void ExpectSavedCounts(DeviceRefPtr device,
907 int64 expected_rx, int64 expected_tx) {
908 EXPECT_CALL(storage_,
909 SetUint64(_, Device::kStorageReceiveByteCount, expected_rx))
910 .WillOnce(Return(true));
911 EXPECT_CALL(storage_,
912 SetUint64(_, Device::kStorageTransmitByteCount, expected_tx))
913 .WillOnce(Return(true));
914 EXPECT_TRUE(device->Save(&storage_));
915 }
916
917
918 bool GetStoredReceiveCount(const string &group, const string &key,
919 uint64 *value) {
920 if (!rx_stored_byte_count_) {
921 return false;
922 }
923 *value = rx_stored_byte_count_;
924 return true;
925 }
926
927 bool GetStoredTransmitCount(const string &group, const string &key,
928 uint64 *value) {
929 if (!tx_stored_byte_count_) {
930 return false;
931 }
932 *value = tx_stored_byte_count_;
933 return true;
934 }
935
936 protected:
937 NiceMock<MockManager> manager_;
938 NiceMock<MockStore> storage_;
939 uint64 rx_byte_count_;
940 uint64 tx_byte_count_;
941 uint64 rx_stored_byte_count_;
942 uint64 tx_stored_byte_count_;
943};
944
945
946TEST_F(DeviceByteCountTest, GetByteCounts) {
947 // On Device initialization, byte counts should be zero, independent of
948 // the byte counts reported by the interface.
949 rx_byte_count_ = 123;
950 tx_byte_count_ = 456;
951 DeviceRefPtr device(new TestDevice(control_interface(),
952 dispatcher(),
953 NULL,
954 &manager_,
955 kDeviceName,
956 kDeviceAddress,
957 kDeviceInterfaceIndex,
958 Technology::kUnknown));
959 EXPECT_TRUE(ExpectByteCounts(device, 0, 0));
960
961 // Device should report any increase in the byte counts reported in the
962 // interface.
963 const int64 delta_rx_count = 789;
964 const int64 delta_tx_count = 12;
965 rx_byte_count_ += delta_rx_count;
966 tx_byte_count_ += delta_tx_count;
967 EXPECT_TRUE(ExpectByteCounts(device, delta_rx_count, delta_tx_count));
968
969 // Expect the correct values to be saved to the profile.
970 ExpectSavedCounts(device, delta_rx_count, delta_tx_count);
971
972 // If Device is loaded from a profile that does not contain stored byte
973 // counts, the byte counts reported should remain unchanged.
974 EXPECT_TRUE(device->Load(&storage_));
975 EXPECT_TRUE(ExpectByteCounts(device, delta_rx_count, delta_tx_count));
976
977 // If Device is loaded from a profile that contains stored byte
978 // counts, the byte counts reported should now reflect the stored values.
979 rx_stored_byte_count_ = 345;
980 tx_stored_byte_count_ = 678;
981 EXPECT_TRUE(device->Load(&storage_));
982 EXPECT_TRUE(ExpectByteCounts(
983 device, rx_stored_byte_count_, tx_stored_byte_count_));
984
985 // Increases to the interface receive count should be reflected as offsets
986 // to the stored byte counts.
987 rx_byte_count_ += delta_rx_count;
988 tx_byte_count_ += delta_tx_count;
989 EXPECT_TRUE(ExpectByteCounts(device,
990 rx_stored_byte_count_ + delta_rx_count,
991 tx_stored_byte_count_ + delta_tx_count));
992
993 // Expect the correct values to be saved to the profile.
994 ExpectSavedCounts(device,
995 rx_stored_byte_count_ + delta_rx_count,
996 tx_stored_byte_count_ + delta_tx_count);
997
998 // Expect that after resetting byte counts, read-back values return to zero,
999 // and that the device requests this information to be persisted.
1000 EXPECT_CALL(manager_, UpdateDevice(device));
1001 device->ResetByteCounters();
1002 EXPECT_TRUE(ExpectByteCounts(device, 0, 0));
1003}
1004
Darin Petkovafa6fc42011-06-21 16:21:08 -07001005} // namespace shill