blob: 42ee525562befc67fcab793110b2e916816a983c [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
128 bool StartLinkMonitor() {
129 return device_->StartLinkMonitor();
130 }
131
132 void StopLinkMonitor() {
133 device_->StopLinkMonitor();
134 }
135
136 uint64 GetLinkMonitorResponseTime(Error *error) {
137 return device_->GetLinkMonitorResponseTime(error);
138 }
139
140 void SetManager(Manager *manager) {
141 device_->manager_ = manager;
142 }
143
Darin Petkovafa6fc42011-06-21 16:21:08 -0700144 MockControl control_interface_;
145 DeviceRefPtr device_;
Paul Stewartc681fa02012-03-02 19:40:04 -0800146 MockDeviceInfo device_info_;
Thieu Le85e050b2012-03-13 15:04:38 -0700147 MockMetrics metrics_;
mukesh agrawal5c4dd0b2011-09-14 13:53:14 -0700148 StrictMock<MockRTNLHandler> rtnl_handler_;
Darin Petkovafa6fc42011-06-21 16:21:08 -0700149};
150
Chris Masone626719f2011-08-18 16:58:48 -0700151const char DeviceTest::kDeviceName[] = "testdevice";
152const char DeviceTest::kDeviceAddress[] = "address";
Thieu Lefb46caf2012-03-08 11:57:15 -0800153const int DeviceTest::kDeviceInterfaceIndex = 0;
Chris Masone626719f2011-08-18 16:58:48 -0700154
Chris Masone3bd3c8c2011-06-13 08:20:26 -0700155TEST_F(DeviceTest, Contains) {
mukesh agrawalde29fa82011-09-16 16:16:36 -0700156 EXPECT_TRUE(device_->store().Contains(flimflam::kNameProperty));
157 EXPECT_FALSE(device_->store().Contains(""));
Chris Masone3bd3c8c2011-06-13 08:20:26 -0700158}
159
Chris Masonea8a2c252011-06-27 22:16:30 -0700160TEST_F(DeviceTest, GetProperties) {
161 map<string, ::DBus::Variant> props;
162 Error error(Error::kInvalidProperty, "");
Eric Shienbrood9a245532012-03-07 14:20:39 -0500163 ::DBus::Error dbus_error;
164 DBusAdaptor::GetProperties(device_->store(), &props, &dbus_error);
165 ASSERT_FALSE(props.find(flimflam::kNameProperty) == props.end());
166 EXPECT_EQ(props[flimflam::kNameProperty].reader().get_string(),
167 string(kDeviceName));
Chris Masonea8a2c252011-06-27 22:16:30 -0700168}
169
Eric Shienbrood9a245532012-03-07 14:20:39 -0500170// Note: there are currently no writeable Device properties that
171// aren't registered in a subclass.
172TEST_F(DeviceTest, SetReadOnlyProperty) {
Chris Masone3bd3c8c2011-06-13 08:20:26 -0700173 ::DBus::Error error;
Chris Masoneb925cc82011-06-22 15:39:57 -0700174 // Ensure that an attempt to write a R/O property returns InvalidArgs error.
mukesh agrawal6bb9e7c2012-01-30 14:57:54 -0800175 EXPECT_FALSE(DBusAdaptor::SetProperty(device_->mutable_store(),
176 flimflam::kAddressProperty,
177 PropertyStoreTest::kStringV,
178 &error));
Chris Masone9d779932011-08-25 16:33:41 -0700179 EXPECT_EQ(invalid_args(), error.name());
Chris Masone3bd3c8c2011-06-13 08:20:26 -0700180}
181
mukesh agrawal8abd2f62012-01-30 14:56:14 -0800182TEST_F(DeviceTest, ClearReadOnlyProperty) {
183 ::DBus::Error error;
mukesh agrawal6bb9e7c2012-01-30 14:57:54 -0800184 EXPECT_FALSE(DBusAdaptor::SetProperty(device_->mutable_store(),
185 flimflam::kAddressProperty,
186 PropertyStoreTest::kStringV,
187 &error));
mukesh agrawal8abd2f62012-01-30 14:56:14 -0800188}
189
190TEST_F(DeviceTest, ClearReadOnlyDerivedProperty) {
191 ::DBus::Error error;
mukesh agrawal6bb9e7c2012-01-30 14:57:54 -0800192 EXPECT_FALSE(DBusAdaptor::SetProperty(device_->mutable_store(),
193 flimflam::kIPConfigsProperty,
194 PropertyStoreTest::kStringsV,
195 &error));
mukesh agrawal8abd2f62012-01-30 14:56:14 -0800196}
197
Darin Petkovafa6fc42011-06-21 16:21:08 -0700198TEST_F(DeviceTest, DestroyIPConfig) {
199 ASSERT_FALSE(device_->ipconfig_.get());
Chris Masone2176a882011-09-14 22:29:15 -0700200 device_->ipconfig_ = new IPConfig(control_interface(), kDeviceName);
Darin Petkovafa6fc42011-06-21 16:21:08 -0700201 device_->DestroyIPConfig();
202 ASSERT_FALSE(device_->ipconfig_.get());
203}
204
205TEST_F(DeviceTest, DestroyIPConfigNULL) {
206 ASSERT_FALSE(device_->ipconfig_.get());
207 device_->DestroyIPConfig();
208 ASSERT_FALSE(device_->ipconfig_.get());
209}
210
Paul Stewart2bf1d352011-12-06 15:02:55 -0800211TEST_F(DeviceTest, AcquireIPConfig) {
Chris Masone2176a882011-09-14 22:29:15 -0700212 device_->ipconfig_ = new IPConfig(control_interface(), "randomname");
Jorge Lucangeli Obesad43cc62012-04-11 16:25:43 -0700213 scoped_ptr<MockDHCPProvider> dhcp_provider(new MockDHCPProvider());
214 device_->dhcp_provider_ = dhcp_provider.get();
215 scoped_refptr<MockDHCPConfig> dhcp_config(new MockDHCPConfig(
216 control_interface(),
217 kDeviceName));
218 EXPECT_CALL(*dhcp_provider, CreateConfig(_, _, _, _))
219 .WillOnce(Return(dhcp_config));
220 EXPECT_CALL(*dhcp_config, RequestIP())
Darin Petkovafa6fc42011-06-21 16:21:08 -0700221 .WillOnce(Return(false));
Paul Stewart2bf1d352011-12-06 15:02:55 -0800222 EXPECT_FALSE(device_->AcquireIPConfig());
Darin Petkovafa6fc42011-06-21 16:21:08 -0700223 ASSERT_TRUE(device_->ipconfig_.get());
224 EXPECT_EQ(kDeviceName, device_->ipconfig_->device_name());
Eric Shienbrood3e20a232012-02-16 11:35:56 -0500225 EXPECT_FALSE(device_->ipconfig_->update_callback_.is_null());
Jorge Lucangeli Obesad43cc62012-04-11 16:25:43 -0700226 device_->dhcp_provider_ = NULL;
Darin Petkovafa6fc42011-06-21 16:21:08 -0700227}
228
Chris Masone5dec5f42011-07-22 14:07:55 -0700229TEST_F(DeviceTest, Load) {
230 NiceMock<MockStore> storage;
231 const string id = device_->GetStorageIdentifier();
232 EXPECT_CALL(storage, ContainsGroup(id)).WillOnce(Return(true));
Paul Stewart6ff27f52012-07-11 06:51:41 -0700233 EXPECT_CALL(storage, GetBool(id, Device::kStoragePowered, _))
234 .WillOnce(Return(true));
235 EXPECT_CALL(storage, GetUint64(id, Device::kStorageReceiveByteCount, _))
236 .WillOnce(Return(true));
237 EXPECT_CALL(storage, GetUint64(id, Device::kStorageTransmitByteCount, _))
238 .WillOnce(Return(true));
Chris Masone5dec5f42011-07-22 14:07:55 -0700239 EXPECT_TRUE(device_->Load(&storage));
240}
241
242TEST_F(DeviceTest, Save) {
243 NiceMock<MockStore> storage;
244 const string id = device_->GetStorageIdentifier();
Paul Stewart6ff27f52012-07-11 06:51:41 -0700245 EXPECT_CALL(storage, SetString(id, Device::kStorageIPConfigs, _))
246 .WillOnce(Return(true));
247 EXPECT_CALL(storage, SetBool(id, Device::kStoragePowered, _))
248 .WillOnce(Return(true));
Chris Masone2176a882011-09-14 22:29:15 -0700249 scoped_refptr<MockIPConfig> ipconfig = new MockIPConfig(control_interface(),
Chris Masone34af2182011-08-22 11:59:36 -0700250 kDeviceName);
251 EXPECT_CALL(*ipconfig.get(), Save(_, _))
252 .WillOnce(Return(true));
253 device_->ipconfig_ = ipconfig;
Paul Stewart6ff27f52012-07-11 06:51:41 -0700254 EXPECT_CALL(storage, SetUint64(id, Device::kStorageReceiveByteCount, _))
255 .WillOnce(Return(true));
256 EXPECT_CALL(storage, SetUint64(id, Device::kStorageTransmitByteCount, _))
257 .Times(AtLeast(true));
Chris Masone5dec5f42011-07-22 14:07:55 -0700258 EXPECT_TRUE(device_->Save(&storage));
259}
260
Chris Masone34af2182011-08-22 11:59:36 -0700261TEST_F(DeviceTest, StorageIdGeneration) {
262 string to_process("/device/stuff/0");
263 ControlInterface::RpcIdToStorageId(&to_process);
264 EXPECT_TRUE(isalpha(to_process[0]));
265 EXPECT_EQ(string::npos, to_process.find('/'));
266}
267
Paul Stewartc1dec4d2011-12-08 15:25:28 -0800268MATCHER(IsNullRefPtr, "") {
269 return !arg;
270}
271
272MATCHER(NotNullRefPtr, "") {
273 return arg;
274}
275
Paul Stewart03dba0b2011-08-22 16:32:45 -0700276TEST_F(DeviceTest, SelectedService) {
277 EXPECT_FALSE(device_->selected_service_.get());
278 device_->SetServiceState(Service::kStateAssociating);
279 scoped_refptr<MockService> service(
Chris Masone2176a882011-09-14 22:29:15 -0700280 new StrictMock<MockService>(control_interface(),
281 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800282 metrics(),
Chris Masone9d779932011-08-25 16:33:41 -0700283 manager()));
Paul Stewart20088d82012-02-16 06:58:55 -0800284 SelectService(service);
Paul Stewart03dba0b2011-08-22 16:32:45 -0700285 EXPECT_TRUE(device_->selected_service_.get() == service.get());
286
287 EXPECT_CALL(*service.get(), SetState(Service::kStateConfiguring));
288 device_->SetServiceState(Service::kStateConfiguring);
289 EXPECT_CALL(*service.get(), SetFailure(Service::kFailureOutOfRange));
290 device_->SetServiceFailure(Service::kFailureOutOfRange);
291
292 // Service should be returned to "Idle" state
293 EXPECT_CALL(*service.get(), state())
294 .WillOnce(Return(Service::kStateUnknown));
295 EXPECT_CALL(*service.get(), SetState(Service::kStateIdle));
Paul Stewartc1dec4d2011-12-08 15:25:28 -0800296 EXPECT_CALL(*service.get(), SetConnection(IsNullRefPtr()));
Paul Stewart20088d82012-02-16 06:58:55 -0800297 SelectService(NULL);
Paul Stewart03dba0b2011-08-22 16:32:45 -0700298
299 // A service in the "Failure" state should not be reset to "Idle"
Paul Stewart20088d82012-02-16 06:58:55 -0800300 SelectService(service);
Paul Stewart03dba0b2011-08-22 16:32:45 -0700301 EXPECT_CALL(*service.get(), state())
302 .WillOnce(Return(Service::kStateFailure));
Paul Stewartc1dec4d2011-12-08 15:25:28 -0800303 EXPECT_CALL(*service.get(), SetConnection(IsNullRefPtr()));
Paul Stewart20088d82012-02-16 06:58:55 -0800304 SelectService(NULL);
Paul Stewart03dba0b2011-08-22 16:32:45 -0700305}
306
Paul Stewartbe5f5b32011-12-07 17:11:11 -0800307TEST_F(DeviceTest, IPConfigUpdatedFailure) {
308 scoped_refptr<MockService> service(
309 new StrictMock<MockService>(control_interface(),
310 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800311 metrics(),
Paul Stewartbe5f5b32011-12-07 17:11:11 -0800312 manager()));
Paul Stewart20088d82012-02-16 06:58:55 -0800313 SelectService(service);
Paul Stewartbe5f5b32011-12-07 17:11:11 -0800314 EXPECT_CALL(*service.get(), SetState(Service::kStateDisconnected));
Paul Stewartc1dec4d2011-12-08 15:25:28 -0800315 EXPECT_CALL(*service.get(), SetConnection(IsNullRefPtr()));
Darin Petkov79d74c92012-03-07 17:20:32 +0100316 OnIPConfigUpdated(NULL, false);
Paul Stewartbe5f5b32011-12-07 17:11:11 -0800317}
318
mukesh agrawalcc0fded2012-05-09 13:40:58 -0700319TEST_F(DeviceTest, IPConfigUpdatedFailureWithStatic) {
320 scoped_refptr<MockService> service(
321 new StrictMock<MockService>(control_interface(),
322 dispatcher(),
323 metrics(),
324 manager()));
325 SelectService(service);
326 service->static_ip_parameters_.args_.SetString(
327 flimflam::kAddressProperty, "1.1.1.1");
328 service->static_ip_parameters_.args_.SetInt(flimflam::kPrefixlenProperty, 16);
329 EXPECT_CALL(*service.get(), SetState(_)).Times(0);
330 EXPECT_CALL(*service.get(), SetConnection(_)).Times(0);
331 OnIPConfigUpdated(NULL, false);
332}
333
Paul Stewartbe5f5b32011-12-07 17:11:11 -0800334TEST_F(DeviceTest, IPConfigUpdatedSuccess) {
335 scoped_refptr<MockService> service(
336 new StrictMock<MockService>(control_interface(),
337 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800338 metrics(),
Paul Stewartbe5f5b32011-12-07 17:11:11 -0800339 manager()));
Paul Stewart20088d82012-02-16 06:58:55 -0800340 SelectService(service);
Paul Stewartbe5f5b32011-12-07 17:11:11 -0800341 scoped_refptr<MockIPConfig> ipconfig = new MockIPConfig(control_interface(),
342 kDeviceName);
343 EXPECT_CALL(*service.get(), SetState(Service::kStateConnected));
Paul Stewart20088d82012-02-16 06:58:55 -0800344 EXPECT_CALL(*service.get(), IsConnected())
345 .WillRepeatedly(Return(true));
Paul Stewartd215af62012-04-24 23:25:50 -0700346 EXPECT_CALL(*service.get(), IsPortalDetectionDisabled())
347 .WillRepeatedly(Return(true));
Paul Stewart20088d82012-02-16 06:58:55 -0800348 EXPECT_CALL(*service.get(), SetState(Service::kStateOnline));
Paul Stewartc1dec4d2011-12-08 15:25:28 -0800349 EXPECT_CALL(*service.get(), SetConnection(NotNullRefPtr()));
Darin Petkov79d74c92012-03-07 17:20:32 +0100350 OnIPConfigUpdated(ipconfig.get(), true);
Paul Stewartbe5f5b32011-12-07 17:11:11 -0800351}
352
Darin Petkove7c6ad32012-06-29 10:22:09 +0200353TEST_F(DeviceTest, SetEnabledPersistent) {
354 EXPECT_FALSE(device_->enabled_);
355 EXPECT_FALSE(device_->enabled_pending_);
356 device_->enabled_persistent_ = false;
357 StrictMock<MockManager> manager(control_interface(),
358 dispatcher(),
359 metrics(),
360 glib());
361 EXPECT_CALL(manager, UpdateDevice(_));
Paul Stewart036dba02012-08-07 12:34:41 -0700362 SetManager(&manager);
Darin Petkove7c6ad32012-06-29 10:22:09 +0200363 Error error;
364 device_->SetEnabledPersistent(true, &error, ResultCallback());
365 EXPECT_TRUE(device_->enabled_persistent_);
366 EXPECT_TRUE(device_->enabled_pending_);
367}
368
Thieu Lefb46caf2012-03-08 11:57:15 -0800369TEST_F(DeviceTest, Start) {
Paul Stewart8c116a92012-05-02 18:30:03 -0700370 EXPECT_FALSE(device_->running_);
371 EXPECT_FALSE(device_->enabled_);
372 EXPECT_FALSE(device_->enabled_pending_);
Eric Shienbrood9a245532012-03-07 14:20:39 -0500373 device_->SetEnabled(true);
Paul Stewart8c116a92012-05-02 18:30:03 -0700374 EXPECT_TRUE(device_->running_);
375 EXPECT_TRUE(device_->enabled_pending_);
Gary Morainbaeefdf2012-04-30 14:53:35 -0700376 device_->OnEnabledStateChanged(ResultCallback(),
377 Error(Error::kOperationFailed));
378 EXPECT_FALSE(device_->enabled_pending_);
Thieu Lefb46caf2012-03-08 11:57:15 -0800379}
380
mukesh agrawal5c4dd0b2011-09-14 13:53:14 -0700381TEST_F(DeviceTest, Stop) {
Eric Shienbrood9a245532012-03-07 14:20:39 -0500382 device_->enabled_ = true;
383 device_->enabled_pending_ = true;
mukesh agrawal5c4dd0b2011-09-14 13:53:14 -0700384 device_->ipconfig_ = new IPConfig(&control_interface_, kDeviceName);
385 scoped_refptr<MockService> service(
386 new NiceMock<MockService>(&control_interface_,
387 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800388 metrics(),
mukesh agrawal5c4dd0b2011-09-14 13:53:14 -0700389 manager()));
Paul Stewart20088d82012-02-16 06:58:55 -0800390 SelectService(service);
mukesh agrawal5c4dd0b2011-09-14 13:53:14 -0700391
392 EXPECT_CALL(*service.get(), state()).
393 WillRepeatedly(Return(Service::kStateConnected));
394 EXPECT_CALL(*dynamic_cast<DeviceMockAdaptor *>(device_->adaptor_.get()),
395 UpdateEnabled());
Eric Shienbrood9a245532012-03-07 14:20:39 -0500396 EXPECT_CALL(*dynamic_cast<DeviceMockAdaptor *>(device_->adaptor_.get()),
397 EmitBoolChanged(flimflam::kPoweredProperty, false));
mukesh agrawal5c4dd0b2011-09-14 13:53:14 -0700398 EXPECT_CALL(rtnl_handler_, SetInterfaceFlags(_, 0, IFF_UP));
Eric Shienbrood9a245532012-03-07 14:20:39 -0500399 device_->SetEnabled(false);
400 device_->OnEnabledStateChanged(ResultCallback(), Error());
mukesh agrawal5c4dd0b2011-09-14 13:53:14 -0700401
402 EXPECT_FALSE(device_->ipconfig_.get());
403 EXPECT_FALSE(device_->selected_service_.get());
404}
405
mukesh agrawal784566d2012-08-08 18:32:58 -0700406TEST_F(DeviceTest, ResumeWithIPConfig) {
407 scoped_refptr<MockIPConfig> ipconfig =
408 new MockIPConfig(control_interface(), kDeviceName);
409 device_->set_ipconfig(ipconfig);
410 EXPECT_CALL(*ipconfig, RenewIP());
411 device_->OnAfterResume();
412}
413
414TEST_F(DeviceTest, ResumeWithoutIPConfig) {
415 // Just test that we don't crash in this case.
416 ASSERT_EQ(NULL, device_->ipconfig().get());
417 device_->OnAfterResume();
418}
419
Paul Stewart036dba02012-08-07 12:34:41 -0700420TEST_F(DeviceTest, LinkMonitor) {
421 scoped_refptr<MockConnection> connection(
422 new StrictMock<MockConnection>(&device_info_));
423 MockManager manager(control_interface(),
424 dispatcher(),
425 metrics(),
426 glib());
427 scoped_refptr<MockService> service(
428 new StrictMock<MockService>(control_interface(),
429 dispatcher(),
430 metrics(),
431 &manager));
432 SelectService(service);
433 SetConnection(connection.get());
434 MockLinkMonitor *link_monitor = new StrictMock<MockLinkMonitor>();
435 SetLinkMonitor(link_monitor); // Passes ownership.
436 SetManager(&manager);
437 EXPECT_CALL(*link_monitor, Start()).Times(0);
438 EXPECT_CALL(manager, IsTechnologyLinkMonitorEnabled(Technology::kUnknown))
439 .WillOnce(Return(false))
440 .WillRepeatedly(Return(true));
441 EXPECT_FALSE(StartLinkMonitor());
442
443 EXPECT_CALL(*link_monitor, Start())
444 .WillOnce(Return(false))
445 .WillOnce(Return(true));
446 EXPECT_FALSE(StartLinkMonitor());
447 EXPECT_TRUE(StartLinkMonitor());
448
449 unsigned int kResponseTime = 123;
450 EXPECT_CALL(*link_monitor, GetResponseTimeMilliseconds())
451 .WillOnce(Return(kResponseTime));
452 {
453 Error error;
454 EXPECT_EQ(kResponseTime, GetLinkMonitorResponseTime(&error));
455 EXPECT_TRUE(error.IsSuccess());
456 }
457 StopLinkMonitor();
458 {
459 Error error;
460 EXPECT_EQ(0, GetLinkMonitorResponseTime(&error));
461 EXPECT_FALSE(error.IsSuccess());
462 }
463}
464
Paul Stewartc681fa02012-03-02 19:40:04 -0800465class DevicePortalDetectionTest : public DeviceTest {
466 public:
467 DevicePortalDetectionTest()
468 : connection_(new StrictMock<MockConnection>(&device_info_)),
469 manager_(control_interface(),
470 dispatcher(),
471 metrics(),
472 glib()),
473 service_(new StrictMock<MockService>(control_interface(),
474 dispatcher(),
475 metrics(),
476 &manager_)),
477 portal_detector_(new StrictMock<MockPortalDetector>(connection_)) {}
478 virtual ~DevicePortalDetectionTest() {}
479 virtual void SetUp() {
480 DeviceTest::SetUp();
481 SelectService(service_);
482 SetConnection(connection_.get());
483 device_->portal_detector_.reset(portal_detector_); // Passes ownership.
Paul Stewart036dba02012-08-07 12:34:41 -0700484 SetManager(&manager_);
Paul Stewartc681fa02012-03-02 19:40:04 -0800485 }
486
487 protected:
Thieu Le85e050b2012-03-13 15:04:38 -0700488 static const int kPortalAttempts;
489
Paul Stewartc681fa02012-03-02 19:40:04 -0800490 bool StartPortalDetection() { return device_->StartPortalDetection(); }
491 void StopPortalDetection() { device_->StopPortalDetection(); }
492
493 void PortalDetectorCallback(const PortalDetector::Result &result) {
494 device_->PortalDetectorCallback(result);
495 }
496 bool RequestPortalDetection() {
497 return device_->RequestPortalDetection();
498 }
499 void SetServiceConnectedState(Service::ConnectState state) {
500 device_->SetServiceConnectedState(state);
501 }
502 void ExpectPortalDetectorReset() {
503 EXPECT_FALSE(device_->portal_detector_.get());
504 }
505 void ExpectPortalDetectorSet() {
506 EXPECT_TRUE(device_->portal_detector_.get());
507 }
508 void ExpectPortalDetectorIsMock() {
509 EXPECT_EQ(portal_detector_, device_->portal_detector_.get());
510 }
511 scoped_refptr<MockConnection> connection_;
512 StrictMock<MockManager> manager_;
513 scoped_refptr<MockService> service_;
514
515 // Used only for EXPECT_CALL(). Object is owned by device.
516 MockPortalDetector *portal_detector_;
517};
518
Thieu Le85e050b2012-03-13 15:04:38 -0700519const int DevicePortalDetectionTest::kPortalAttempts = 2;
520
Paul Stewartd215af62012-04-24 23:25:50 -0700521TEST_F(DevicePortalDetectionTest, ServicePortalDetectionDisabled) {
522 EXPECT_CALL(*service_.get(), IsPortalDetectionDisabled())
523 .WillOnce(Return(true));
Paul Stewartc681fa02012-03-02 19:40:04 -0800524 EXPECT_CALL(*service_.get(), IsConnected())
Paul Stewart20088d82012-02-16 06:58:55 -0800525 .WillRepeatedly(Return(true));
Paul Stewartd215af62012-04-24 23:25:50 -0700526 EXPECT_CALL(*service_.get(), SetState(Service::kStateOnline));
527 EXPECT_FALSE(StartPortalDetection());
528}
529
530TEST_F(DevicePortalDetectionTest, TechnologyPortalDetectionDisabled) {
531 EXPECT_CALL(*service_.get(), IsPortalDetectionDisabled())
532 .WillOnce(Return(false));
533 EXPECT_CALL(*service_.get(), IsConnected())
534 .WillRepeatedly(Return(true));
535 EXPECT_CALL(*service_.get(), IsPortalDetectionAuto())
536 .WillOnce(Return(true));
Paul Stewartc681fa02012-03-02 19:40:04 -0800537 EXPECT_CALL(manager_, IsPortalDetectionEnabled(device_->technology()))
Paul Stewart20088d82012-02-16 06:58:55 -0800538 .WillOnce(Return(false));
Paul Stewartc681fa02012-03-02 19:40:04 -0800539 EXPECT_CALL(*service_.get(), SetState(Service::kStateOnline));
Paul Stewart20088d82012-02-16 06:58:55 -0800540 EXPECT_FALSE(StartPortalDetection());
541}
542
Paul Stewartc681fa02012-03-02 19:40:04 -0800543TEST_F(DevicePortalDetectionTest, PortalDetectionProxyConfig) {
Paul Stewartd215af62012-04-24 23:25:50 -0700544 EXPECT_CALL(*service_.get(), IsPortalDetectionDisabled())
545 .WillOnce(Return(false));
Paul Stewartc681fa02012-03-02 19:40:04 -0800546 EXPECT_CALL(*service_.get(), IsConnected())
Paul Stewart20088d82012-02-16 06:58:55 -0800547 .WillRepeatedly(Return(true));
Paul Stewartc681fa02012-03-02 19:40:04 -0800548 EXPECT_CALL(*service_.get(), HasProxyConfig())
Paul Stewart20088d82012-02-16 06:58:55 -0800549 .WillOnce(Return(true));
Paul Stewartd215af62012-04-24 23:25:50 -0700550 EXPECT_CALL(*service_.get(), IsPortalDetectionAuto())
551 .WillOnce(Return(true));
Paul Stewartc681fa02012-03-02 19:40:04 -0800552 EXPECT_CALL(manager_, IsPortalDetectionEnabled(device_->technology()))
Paul Stewart20088d82012-02-16 06:58:55 -0800553 .WillOnce(Return(true));
Paul Stewartc681fa02012-03-02 19:40:04 -0800554 EXPECT_CALL(*service_.get(), SetState(Service::kStateOnline));
Paul Stewart20088d82012-02-16 06:58:55 -0800555 EXPECT_FALSE(StartPortalDetection());
556}
557
Paul Stewartc681fa02012-03-02 19:40:04 -0800558TEST_F(DevicePortalDetectionTest, PortalDetectionBadUrl) {
Paul Stewartd215af62012-04-24 23:25:50 -0700559 EXPECT_CALL(*service_.get(), IsPortalDetectionDisabled())
560 .WillOnce(Return(false));
Paul Stewartc681fa02012-03-02 19:40:04 -0800561 EXPECT_CALL(*service_.get(), IsConnected())
Paul Stewart20088d82012-02-16 06:58:55 -0800562 .WillRepeatedly(Return(true));
Paul Stewartc681fa02012-03-02 19:40:04 -0800563 EXPECT_CALL(*service_.get(), HasProxyConfig())
Paul Stewart20088d82012-02-16 06:58:55 -0800564 .WillOnce(Return(false));
Paul Stewartd215af62012-04-24 23:25:50 -0700565 EXPECT_CALL(*service_.get(), IsPortalDetectionAuto())
566 .WillOnce(Return(true));
Paul Stewartc681fa02012-03-02 19:40:04 -0800567 EXPECT_CALL(manager_, IsPortalDetectionEnabled(device_->technology()))
Paul Stewart20088d82012-02-16 06:58:55 -0800568 .WillOnce(Return(true));
569 const string portal_url;
Paul Stewartc681fa02012-03-02 19:40:04 -0800570 EXPECT_CALL(manager_, GetPortalCheckURL())
Paul Stewart20088d82012-02-16 06:58:55 -0800571 .WillRepeatedly(ReturnRef(portal_url));
Paul Stewartc681fa02012-03-02 19:40:04 -0800572 EXPECT_CALL(*service_.get(), SetState(Service::kStateOnline));
Paul Stewart20088d82012-02-16 06:58:55 -0800573 EXPECT_FALSE(StartPortalDetection());
574}
575
Paul Stewartc681fa02012-03-02 19:40:04 -0800576TEST_F(DevicePortalDetectionTest, PortalDetectionStart) {
Paul Stewartd215af62012-04-24 23:25:50 -0700577 EXPECT_CALL(*service_.get(), IsPortalDetectionDisabled())
578 .WillOnce(Return(false));
Paul Stewartc681fa02012-03-02 19:40:04 -0800579 EXPECT_CALL(*service_.get(), IsConnected())
Paul Stewart20088d82012-02-16 06:58:55 -0800580 .WillRepeatedly(Return(true));
Paul Stewartc681fa02012-03-02 19:40:04 -0800581 EXPECT_CALL(*service_.get(), HasProxyConfig())
Paul Stewart20088d82012-02-16 06:58:55 -0800582 .WillOnce(Return(false));
Paul Stewartd215af62012-04-24 23:25:50 -0700583 EXPECT_CALL(*service_.get(), IsPortalDetectionAuto())
584 .WillOnce(Return(true));
Paul Stewartc681fa02012-03-02 19:40:04 -0800585 EXPECT_CALL(manager_, IsPortalDetectionEnabled(device_->technology()))
Paul Stewart20088d82012-02-16 06:58:55 -0800586 .WillOnce(Return(true));
587 const string portal_url(PortalDetector::kDefaultURL);
Paul Stewartc681fa02012-03-02 19:40:04 -0800588 EXPECT_CALL(manager_, GetPortalCheckURL())
Paul Stewart20088d82012-02-16 06:58:55 -0800589 .WillRepeatedly(ReturnRef(portal_url));
Paul Stewartc681fa02012-03-02 19:40:04 -0800590 EXPECT_CALL(*service_.get(), SetState(Service::kStateOnline))
Paul Stewart20088d82012-02-16 06:58:55 -0800591 .Times(0);
Paul Stewart20088d82012-02-16 06:58:55 -0800592 const string kInterfaceName("int0");
Paul Stewartc681fa02012-03-02 19:40:04 -0800593 EXPECT_CALL(*connection_.get(), interface_name())
594 .WillRepeatedly(ReturnRef(kInterfaceName));
Paul Stewart20088d82012-02-16 06:58:55 -0800595 const vector<string> kDNSServers;
Paul Stewartc681fa02012-03-02 19:40:04 -0800596 EXPECT_CALL(*connection_.get(), dns_servers())
597 .WillRepeatedly(ReturnRef(kDNSServers));
Paul Stewart20088d82012-02-16 06:58:55 -0800598 EXPECT_TRUE(StartPortalDetection());
599
600 // Drop all references to device_info before it falls out of scope.
601 SetConnection(NULL);
602 StopPortalDetection();
603}
604
Paul Stewartc681fa02012-03-02 19:40:04 -0800605TEST_F(DevicePortalDetectionTest, PortalDetectionNonFinal) {
606 EXPECT_CALL(*service_.get(), IsConnected())
Paul Stewart20088d82012-02-16 06:58:55 -0800607 .Times(0);
Paul Stewartc681fa02012-03-02 19:40:04 -0800608 EXPECT_CALL(*service_.get(), SetState(_))
Paul Stewart20088d82012-02-16 06:58:55 -0800609 .Times(0);
Paul Stewart20088d82012-02-16 06:58:55 -0800610 PortalDetectorCallback(PortalDetector::Result(
611 PortalDetector::kPhaseUnknown,
612 PortalDetector::kStatusFailure,
Thieu Le85e050b2012-03-13 15:04:38 -0700613 kPortalAttempts,
Paul Stewart20088d82012-02-16 06:58:55 -0800614 false));
615}
616
Paul Stewartc681fa02012-03-02 19:40:04 -0800617TEST_F(DevicePortalDetectionTest, PortalDetectionFailure) {
618 EXPECT_CALL(*service_.get(), IsConnected())
Paul Stewart20088d82012-02-16 06:58:55 -0800619 .WillOnce(Return(true));
Paul Stewartc681fa02012-03-02 19:40:04 -0800620 EXPECT_CALL(*service_.get(), SetState(Service::kStatePortal));
Thieu Le85e050b2012-03-13 15:04:38 -0700621 EXPECT_CALL(metrics_,
622 SendEnumToUMA("Network.Shill.Unknown.PortalResult",
623 Metrics::kPortalResultConnectionFailure,
624 Metrics::kPortalResultMax));
625 EXPECT_CALL(metrics_,
626 SendToUMA("Network.Shill.Unknown.PortalAttemptsToOnline",
627 _, _, _, _)).Times(0);
628 EXPECT_CALL(metrics_,
629 SendToUMA("Network.Shill.Unknown.PortalAttempts",
630 kPortalAttempts,
631 Metrics::kMetricPortalAttemptsMin,
632 Metrics::kMetricPortalAttemptsMax,
633 Metrics::kMetricPortalAttemptsNumBuckets));
Paul Stewartc681fa02012-03-02 19:40:04 -0800634 EXPECT_CALL(*connection_.get(), is_default())
635 .WillOnce(Return(false));
Paul Stewart20088d82012-02-16 06:58:55 -0800636 PortalDetectorCallback(PortalDetector::Result(
Thieu Le85e050b2012-03-13 15:04:38 -0700637 PortalDetector::kPhaseConnection,
Paul Stewart20088d82012-02-16 06:58:55 -0800638 PortalDetector::kStatusFailure,
Thieu Le85e050b2012-03-13 15:04:38 -0700639 kPortalAttempts,
Paul Stewart20088d82012-02-16 06:58:55 -0800640 true));
641}
642
Paul Stewartc681fa02012-03-02 19:40:04 -0800643TEST_F(DevicePortalDetectionTest, PortalDetectionSuccess) {
644 EXPECT_CALL(*service_.get(), IsConnected())
Paul Stewart20088d82012-02-16 06:58:55 -0800645 .WillOnce(Return(true));
Paul Stewartc681fa02012-03-02 19:40:04 -0800646 EXPECT_CALL(*service_.get(), SetState(Service::kStateOnline));
Thieu Le85e050b2012-03-13 15:04:38 -0700647 EXPECT_CALL(metrics_,
648 SendEnumToUMA("Network.Shill.Unknown.PortalResult",
649 Metrics::kPortalResultSuccess,
650 Metrics::kPortalResultMax));
651 EXPECT_CALL(metrics_,
652 SendToUMA("Network.Shill.Unknown.PortalAttemptsToOnline",
653 kPortalAttempts,
654 Metrics::kMetricPortalAttemptsToOnlineMin,
655 Metrics::kMetricPortalAttemptsToOnlineMax,
656 Metrics::kMetricPortalAttemptsToOnlineNumBuckets));
657 EXPECT_CALL(metrics_,
658 SendToUMA("Network.Shill.Unknown.PortalAttempts",
659 _, _, _, _)).Times(0);
Paul Stewart20088d82012-02-16 06:58:55 -0800660 PortalDetectorCallback(PortalDetector::Result(
Thieu Le85e050b2012-03-13 15:04:38 -0700661 PortalDetector::kPhaseContent,
Paul Stewart20088d82012-02-16 06:58:55 -0800662 PortalDetector::kStatusSuccess,
Thieu Le85e050b2012-03-13 15:04:38 -0700663 kPortalAttempts,
664 true));
665}
666
667TEST_F(DevicePortalDetectionTest, PortalDetectionSuccessAfterFailure) {
668 EXPECT_CALL(*service_.get(), IsConnected())
669 .WillRepeatedly(Return(true));
670 EXPECT_CALL(*service_.get(), SetState(Service::kStatePortal));
671 EXPECT_CALL(metrics_,
672 SendEnumToUMA("Network.Shill.Unknown.PortalResult",
673 Metrics::kPortalResultConnectionFailure,
674 Metrics::kPortalResultMax));
675 EXPECT_CALL(metrics_,
676 SendToUMA("Network.Shill.Unknown.PortalAttemptsToOnline",
677 _, _, _, _)).Times(0);
678 EXPECT_CALL(metrics_,
679 SendToUMA("Network.Shill.Unknown.PortalAttempts",
680 kPortalAttempts,
681 Metrics::kMetricPortalAttemptsMin,
682 Metrics::kMetricPortalAttemptsMax,
683 Metrics::kMetricPortalAttemptsNumBuckets));
684 EXPECT_CALL(*connection_.get(), is_default())
685 .WillOnce(Return(false));
686 PortalDetectorCallback(PortalDetector::Result(
687 PortalDetector::kPhaseConnection,
688 PortalDetector::kStatusFailure,
689 kPortalAttempts,
690 true));
691 Mock::VerifyAndClearExpectations(&metrics_);
692
693 EXPECT_CALL(*service_.get(), SetState(Service::kStateOnline));
694 EXPECT_CALL(metrics_,
695 SendEnumToUMA("Network.Shill.Unknown.PortalResult",
696 Metrics::kPortalResultSuccess,
697 Metrics::kPortalResultMax));
698 EXPECT_CALL(metrics_,
699 SendToUMA("Network.Shill.Unknown.PortalAttemptsToOnline",
700 kPortalAttempts * 2,
701 Metrics::kMetricPortalAttemptsToOnlineMin,
702 Metrics::kMetricPortalAttemptsToOnlineMax,
703 Metrics::kMetricPortalAttemptsToOnlineNumBuckets));
704 EXPECT_CALL(metrics_,
705 SendToUMA("Network.Shill.Unknown.PortalAttempts",
706 _, _, _, _)).Times(0);
707 PortalDetectorCallback(PortalDetector::Result(
708 PortalDetector::kPhaseContent,
709 PortalDetector::kStatusSuccess,
710 kPortalAttempts,
Paul Stewart20088d82012-02-16 06:58:55 -0800711 true));
712}
713
Paul Stewartc681fa02012-03-02 19:40:04 -0800714TEST_F(DevicePortalDetectionTest, RequestPortalDetection) {
715 EXPECT_CALL(*service_.get(), state())
716 .WillOnce(Return(Service::kStateOnline))
717 .WillRepeatedly(Return(Service::kStatePortal));
718 EXPECT_FALSE(RequestPortalDetection());
719
720 EXPECT_CALL(*connection_.get(), is_default())
721 .WillOnce(Return(false))
722 .WillRepeatedly(Return(true));
723 EXPECT_FALSE(RequestPortalDetection());
724
725 EXPECT_CALL(*portal_detector_, IsInProgress())
726 .WillOnce(Return(true));
727 // Portal detection already running.
728 EXPECT_TRUE(RequestPortalDetection());
729
730 // Make sure our running mock portal detector was not replaced.
731 ExpectPortalDetectorIsMock();
732
733 // Throw away our pre-fabricated portal detector, and have the device create
734 // a new one.
735 StopPortalDetection();
Paul Stewartd215af62012-04-24 23:25:50 -0700736 EXPECT_CALL(*service_.get(), IsPortalDetectionDisabled())
737 .WillRepeatedly(Return(false));
738 EXPECT_CALL(*service_.get(), IsPortalDetectionAuto())
739 .WillRepeatedly(Return(true));
Paul Stewartc681fa02012-03-02 19:40:04 -0800740 EXPECT_CALL(manager_, IsPortalDetectionEnabled(device_->technology()))
741 .WillRepeatedly(Return(true));
742 EXPECT_CALL(*service_.get(), HasProxyConfig())
743 .WillRepeatedly(Return(false));
744 const string kPortalCheckURL("http://portal");
745 EXPECT_CALL(manager_, GetPortalCheckURL())
746 .WillOnce(ReturnRef(kPortalCheckURL));
747 const string kInterfaceName("int0");
748 EXPECT_CALL(*connection_.get(), interface_name())
749 .WillRepeatedly(ReturnRef(kInterfaceName));
750 const vector<string> kDNSServers;
751 EXPECT_CALL(*connection_.get(), dns_servers())
752 .WillRepeatedly(ReturnRef(kDNSServers));
753 EXPECT_TRUE(RequestPortalDetection());
754}
755
756TEST_F(DevicePortalDetectionTest, NotConnected) {
757 EXPECT_CALL(*service_.get(), IsConnected())
758 .WillOnce(Return(false));
759 SetServiceConnectedState(Service::kStatePortal);
760 // We don't check for the portal detector to be reset here, because
761 // it would have been reset as a part of disconnection.
762}
763
764TEST_F(DevicePortalDetectionTest, NotPortal) {
765 EXPECT_CALL(*service_.get(), IsConnected())
766 .WillOnce(Return(true));
767 EXPECT_CALL(*service_.get(), SetState(Service::kStateOnline));
768 SetServiceConnectedState(Service::kStateOnline);
769 ExpectPortalDetectorReset();
770}
771
772TEST_F(DevicePortalDetectionTest, NotDefault) {
773 EXPECT_CALL(*service_.get(), IsConnected())
774 .WillOnce(Return(true));
775 EXPECT_CALL(*connection_.get(), is_default())
776 .WillOnce(Return(false));
777 EXPECT_CALL(*service_.get(), SetState(Service::kStatePortal));
778 SetServiceConnectedState(Service::kStatePortal);
779 ExpectPortalDetectorReset();
780}
781
782TEST_F(DevicePortalDetectionTest, PortalIntervalIsZero) {
783 EXPECT_CALL(*service_.get(), IsConnected())
784 .WillOnce(Return(true));
785 EXPECT_CALL(*connection_.get(), is_default())
786 .WillOnce(Return(true));
787 EXPECT_CALL(manager_, GetPortalCheckInterval())
788 .WillOnce(Return(0));
789 EXPECT_CALL(*service_.get(), SetState(Service::kStatePortal));
790 SetServiceConnectedState(Service::kStatePortal);
791 ExpectPortalDetectorReset();
792}
793
794TEST_F(DevicePortalDetectionTest, RestartPortalDetection) {
795 EXPECT_CALL(*service_.get(), IsConnected())
796 .WillOnce(Return(true));
797 EXPECT_CALL(*connection_.get(), is_default())
798 .WillOnce(Return(true));
799 const int kPortalDetectionInterval = 10;
800 EXPECT_CALL(manager_, GetPortalCheckInterval())
801 .Times(AtLeast(1))
802 .WillRepeatedly(Return(kPortalDetectionInterval));
803 const string kPortalCheckURL("http://portal");
804 EXPECT_CALL(manager_, GetPortalCheckURL())
805 .WillOnce(ReturnRef(kPortalCheckURL));
806 EXPECT_CALL(*portal_detector_, StartAfterDelay(kPortalCheckURL,
807 kPortalDetectionInterval))
808 .WillOnce(Return(true));
809 EXPECT_CALL(*service_.get(), SetState(Service::kStatePortal));
810 SetServiceConnectedState(Service::kStatePortal);
811 ExpectPortalDetectorSet();
812}
813
Paul Stewart6ff27f52012-07-11 06:51:41 -0700814class DeviceByteCountTest : public DeviceTest {
815 public:
816 DeviceByteCountTest()
817 : manager_(control_interface(),
818 dispatcher(),
819 metrics(),
820 glib()),
821 rx_byte_count_(0),
822 tx_byte_count_(0),
823 rx_stored_byte_count_(0),
824 tx_stored_byte_count_(0) {}
825 virtual ~DeviceByteCountTest() {}
826
827 virtual void SetUp() {
828 DeviceTest::SetUp();
829 EXPECT_CALL(manager_, device_info()).WillRepeatedly(Return(&device_info_));
830 EXPECT_CALL(device_info_, GetByteCounts(kDeviceInterfaceIndex, _, _))
831 .WillRepeatedly(Invoke(this, &DeviceByteCountTest::ReturnByteCounts));
832 const string id = device_->GetStorageIdentifier();
833 EXPECT_CALL(storage_, ContainsGroup(id)).WillRepeatedly(Return(true));
834 EXPECT_CALL(storage_, GetUint64(id, Device::kStorageReceiveByteCount, _))
835 .WillRepeatedly(
836 Invoke(this, &DeviceByteCountTest::GetStoredReceiveCount));
837 EXPECT_CALL(storage_, GetUint64(id, Device::kStorageTransmitByteCount, _))
838 .WillRepeatedly(
839 Invoke(this, &DeviceByteCountTest::GetStoredTransmitCount));
840 }
841
842 bool ReturnByteCounts(int interface_index, uint64 *rx, uint64 *tx) {
843 *rx = rx_byte_count_;
844 *tx = tx_byte_count_;
845 return true;
846 }
847
848 bool ExpectByteCounts(DeviceRefPtr device,
849 int64 expected_rx, int64 expected_tx) {
850 int64 actual_rx = device->GetReceiveByteCount(NULL);
851 int64 actual_tx = device->GetTransmitByteCount(NULL);
852 EXPECT_EQ(expected_rx, actual_rx);
853 EXPECT_EQ(expected_tx, actual_tx);
854 return expected_rx == actual_rx && expected_tx == actual_tx;
855 }
856
857 void ExpectSavedCounts(DeviceRefPtr device,
858 int64 expected_rx, int64 expected_tx) {
859 EXPECT_CALL(storage_,
860 SetUint64(_, Device::kStorageReceiveByteCount, expected_rx))
861 .WillOnce(Return(true));
862 EXPECT_CALL(storage_,
863 SetUint64(_, Device::kStorageTransmitByteCount, expected_tx))
864 .WillOnce(Return(true));
865 EXPECT_TRUE(device->Save(&storage_));
866 }
867
868
869 bool GetStoredReceiveCount(const string &group, const string &key,
870 uint64 *value) {
871 if (!rx_stored_byte_count_) {
872 return false;
873 }
874 *value = rx_stored_byte_count_;
875 return true;
876 }
877
878 bool GetStoredTransmitCount(const string &group, const string &key,
879 uint64 *value) {
880 if (!tx_stored_byte_count_) {
881 return false;
882 }
883 *value = tx_stored_byte_count_;
884 return true;
885 }
886
887 protected:
888 NiceMock<MockManager> manager_;
889 NiceMock<MockStore> storage_;
890 uint64 rx_byte_count_;
891 uint64 tx_byte_count_;
892 uint64 rx_stored_byte_count_;
893 uint64 tx_stored_byte_count_;
894};
895
896
897TEST_F(DeviceByteCountTest, GetByteCounts) {
898 // On Device initialization, byte counts should be zero, independent of
899 // the byte counts reported by the interface.
900 rx_byte_count_ = 123;
901 tx_byte_count_ = 456;
902 DeviceRefPtr device(new TestDevice(control_interface(),
903 dispatcher(),
904 NULL,
905 &manager_,
906 kDeviceName,
907 kDeviceAddress,
908 kDeviceInterfaceIndex,
909 Technology::kUnknown));
910 EXPECT_TRUE(ExpectByteCounts(device, 0, 0));
911
912 // Device should report any increase in the byte counts reported in the
913 // interface.
914 const int64 delta_rx_count = 789;
915 const int64 delta_tx_count = 12;
916 rx_byte_count_ += delta_rx_count;
917 tx_byte_count_ += delta_tx_count;
918 EXPECT_TRUE(ExpectByteCounts(device, delta_rx_count, delta_tx_count));
919
920 // Expect the correct values to be saved to the profile.
921 ExpectSavedCounts(device, delta_rx_count, delta_tx_count);
922
923 // If Device is loaded from a profile that does not contain stored byte
924 // counts, the byte counts reported should remain unchanged.
925 EXPECT_TRUE(device->Load(&storage_));
926 EXPECT_TRUE(ExpectByteCounts(device, delta_rx_count, delta_tx_count));
927
928 // If Device is loaded from a profile that contains stored byte
929 // counts, the byte counts reported should now reflect the stored values.
930 rx_stored_byte_count_ = 345;
931 tx_stored_byte_count_ = 678;
932 EXPECT_TRUE(device->Load(&storage_));
933 EXPECT_TRUE(ExpectByteCounts(
934 device, rx_stored_byte_count_, tx_stored_byte_count_));
935
936 // Increases to the interface receive count should be reflected as offsets
937 // to the stored byte counts.
938 rx_byte_count_ += delta_rx_count;
939 tx_byte_count_ += delta_tx_count;
940 EXPECT_TRUE(ExpectByteCounts(device,
941 rx_stored_byte_count_ + delta_rx_count,
942 tx_stored_byte_count_ + delta_tx_count));
943
944 // Expect the correct values to be saved to the profile.
945 ExpectSavedCounts(device,
946 rx_stored_byte_count_ + delta_rx_count,
947 tx_stored_byte_count_ + delta_tx_count);
948
949 // Expect that after resetting byte counts, read-back values return to zero,
950 // and that the device requests this information to be persisted.
951 EXPECT_CALL(manager_, UpdateDevice(device));
952 device->ResetByteCounters();
953 EXPECT_TRUE(ExpectByteCounts(device, 0, 0));
954}
955
Darin Petkovafa6fc42011-06-21 16:21:08 -0700956} // namespace shill