blob: bc1fdc9c0e01b0ff8e858a5a24fb09db7d542c71 [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
Thieu Led1760922012-09-11 14:15:35 -0700353TEST_F(DeviceTest, IPConfigUpdatedSuccessNoSelectedService) {
354 // Make sure shill doesn't crash if a service is disabled immediately
355 // after receiving its IP config (selected_service_ is NULL in this case).
356 scoped_refptr<MockIPConfig> ipconfig = new MockIPConfig(control_interface(),
357 kDeviceName);
358 SelectService(NULL);
359 OnIPConfigUpdated(ipconfig.get(), true);
360}
361
Darin Petkove7c6ad32012-06-29 10:22:09 +0200362TEST_F(DeviceTest, SetEnabledPersistent) {
363 EXPECT_FALSE(device_->enabled_);
364 EXPECT_FALSE(device_->enabled_pending_);
365 device_->enabled_persistent_ = false;
366 StrictMock<MockManager> manager(control_interface(),
367 dispatcher(),
368 metrics(),
369 glib());
370 EXPECT_CALL(manager, UpdateDevice(_));
Paul Stewart036dba02012-08-07 12:34:41 -0700371 SetManager(&manager);
Darin Petkove7c6ad32012-06-29 10:22:09 +0200372 Error error;
373 device_->SetEnabledPersistent(true, &error, ResultCallback());
374 EXPECT_TRUE(device_->enabled_persistent_);
375 EXPECT_TRUE(device_->enabled_pending_);
376}
377
Thieu Lefb46caf2012-03-08 11:57:15 -0800378TEST_F(DeviceTest, Start) {
Paul Stewart8c116a92012-05-02 18:30:03 -0700379 EXPECT_FALSE(device_->running_);
380 EXPECT_FALSE(device_->enabled_);
381 EXPECT_FALSE(device_->enabled_pending_);
Eric Shienbrood9a245532012-03-07 14:20:39 -0500382 device_->SetEnabled(true);
Paul Stewart8c116a92012-05-02 18:30:03 -0700383 EXPECT_TRUE(device_->running_);
384 EXPECT_TRUE(device_->enabled_pending_);
Gary Morainbaeefdf2012-04-30 14:53:35 -0700385 device_->OnEnabledStateChanged(ResultCallback(),
386 Error(Error::kOperationFailed));
387 EXPECT_FALSE(device_->enabled_pending_);
Thieu Lefb46caf2012-03-08 11:57:15 -0800388}
389
mukesh agrawal5c4dd0b2011-09-14 13:53:14 -0700390TEST_F(DeviceTest, Stop) {
Eric Shienbrood9a245532012-03-07 14:20:39 -0500391 device_->enabled_ = true;
392 device_->enabled_pending_ = true;
mukesh agrawal5c4dd0b2011-09-14 13:53:14 -0700393 device_->ipconfig_ = new IPConfig(&control_interface_, kDeviceName);
394 scoped_refptr<MockService> service(
395 new NiceMock<MockService>(&control_interface_,
396 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800397 metrics(),
mukesh agrawal5c4dd0b2011-09-14 13:53:14 -0700398 manager()));
Paul Stewart20088d82012-02-16 06:58:55 -0800399 SelectService(service);
mukesh agrawal5c4dd0b2011-09-14 13:53:14 -0700400
401 EXPECT_CALL(*service.get(), state()).
402 WillRepeatedly(Return(Service::kStateConnected));
403 EXPECT_CALL(*dynamic_cast<DeviceMockAdaptor *>(device_->adaptor_.get()),
404 UpdateEnabled());
Eric Shienbrood9a245532012-03-07 14:20:39 -0500405 EXPECT_CALL(*dynamic_cast<DeviceMockAdaptor *>(device_->adaptor_.get()),
406 EmitBoolChanged(flimflam::kPoweredProperty, false));
mukesh agrawal5c4dd0b2011-09-14 13:53:14 -0700407 EXPECT_CALL(rtnl_handler_, SetInterfaceFlags(_, 0, IFF_UP));
Eric Shienbrood9a245532012-03-07 14:20:39 -0500408 device_->SetEnabled(false);
409 device_->OnEnabledStateChanged(ResultCallback(), Error());
mukesh agrawal5c4dd0b2011-09-14 13:53:14 -0700410
411 EXPECT_FALSE(device_->ipconfig_.get());
412 EXPECT_FALSE(device_->selected_service_.get());
413}
414
mukesh agrawal784566d2012-08-08 18:32:58 -0700415TEST_F(DeviceTest, ResumeWithIPConfig) {
416 scoped_refptr<MockIPConfig> ipconfig =
417 new MockIPConfig(control_interface(), kDeviceName);
418 device_->set_ipconfig(ipconfig);
419 EXPECT_CALL(*ipconfig, RenewIP());
420 device_->OnAfterResume();
421}
422
423TEST_F(DeviceTest, ResumeWithoutIPConfig) {
424 // Just test that we don't crash in this case.
425 ASSERT_EQ(NULL, device_->ipconfig().get());
426 device_->OnAfterResume();
427}
428
Paul Stewart036dba02012-08-07 12:34:41 -0700429TEST_F(DeviceTest, LinkMonitor) {
430 scoped_refptr<MockConnection> connection(
431 new StrictMock<MockConnection>(&device_info_));
432 MockManager manager(control_interface(),
433 dispatcher(),
434 metrics(),
435 glib());
436 scoped_refptr<MockService> service(
437 new StrictMock<MockService>(control_interface(),
438 dispatcher(),
439 metrics(),
440 &manager));
441 SelectService(service);
442 SetConnection(connection.get());
443 MockLinkMonitor *link_monitor = new StrictMock<MockLinkMonitor>();
444 SetLinkMonitor(link_monitor); // Passes ownership.
445 SetManager(&manager);
446 EXPECT_CALL(*link_monitor, Start()).Times(0);
447 EXPECT_CALL(manager, IsTechnologyLinkMonitorEnabled(Technology::kUnknown))
448 .WillOnce(Return(false))
449 .WillRepeatedly(Return(true));
450 EXPECT_FALSE(StartLinkMonitor());
451
452 EXPECT_CALL(*link_monitor, Start())
453 .WillOnce(Return(false))
454 .WillOnce(Return(true));
455 EXPECT_FALSE(StartLinkMonitor());
456 EXPECT_TRUE(StartLinkMonitor());
457
458 unsigned int kResponseTime = 123;
459 EXPECT_CALL(*link_monitor, GetResponseTimeMilliseconds())
460 .WillOnce(Return(kResponseTime));
461 {
462 Error error;
463 EXPECT_EQ(kResponseTime, GetLinkMonitorResponseTime(&error));
464 EXPECT_TRUE(error.IsSuccess());
465 }
466 StopLinkMonitor();
467 {
468 Error error;
469 EXPECT_EQ(0, GetLinkMonitorResponseTime(&error));
470 EXPECT_FALSE(error.IsSuccess());
471 }
472}
473
Paul Stewartc681fa02012-03-02 19:40:04 -0800474class DevicePortalDetectionTest : public DeviceTest {
475 public:
476 DevicePortalDetectionTest()
477 : connection_(new StrictMock<MockConnection>(&device_info_)),
478 manager_(control_interface(),
479 dispatcher(),
480 metrics(),
481 glib()),
482 service_(new StrictMock<MockService>(control_interface(),
483 dispatcher(),
484 metrics(),
485 &manager_)),
486 portal_detector_(new StrictMock<MockPortalDetector>(connection_)) {}
487 virtual ~DevicePortalDetectionTest() {}
488 virtual void SetUp() {
489 DeviceTest::SetUp();
490 SelectService(service_);
491 SetConnection(connection_.get());
492 device_->portal_detector_.reset(portal_detector_); // Passes ownership.
Paul Stewart036dba02012-08-07 12:34:41 -0700493 SetManager(&manager_);
Paul Stewartc681fa02012-03-02 19:40:04 -0800494 }
495
496 protected:
Thieu Le85e050b2012-03-13 15:04:38 -0700497 static const int kPortalAttempts;
498
Paul Stewartc681fa02012-03-02 19:40:04 -0800499 bool StartPortalDetection() { return device_->StartPortalDetection(); }
500 void StopPortalDetection() { device_->StopPortalDetection(); }
501
502 void PortalDetectorCallback(const PortalDetector::Result &result) {
503 device_->PortalDetectorCallback(result);
504 }
505 bool RequestPortalDetection() {
506 return device_->RequestPortalDetection();
507 }
508 void SetServiceConnectedState(Service::ConnectState state) {
509 device_->SetServiceConnectedState(state);
510 }
511 void ExpectPortalDetectorReset() {
512 EXPECT_FALSE(device_->portal_detector_.get());
513 }
514 void ExpectPortalDetectorSet() {
515 EXPECT_TRUE(device_->portal_detector_.get());
516 }
517 void ExpectPortalDetectorIsMock() {
518 EXPECT_EQ(portal_detector_, device_->portal_detector_.get());
519 }
520 scoped_refptr<MockConnection> connection_;
521 StrictMock<MockManager> manager_;
522 scoped_refptr<MockService> service_;
523
524 // Used only for EXPECT_CALL(). Object is owned by device.
525 MockPortalDetector *portal_detector_;
526};
527
Thieu Le85e050b2012-03-13 15:04:38 -0700528const int DevicePortalDetectionTest::kPortalAttempts = 2;
529
Paul Stewartd215af62012-04-24 23:25:50 -0700530TEST_F(DevicePortalDetectionTest, ServicePortalDetectionDisabled) {
531 EXPECT_CALL(*service_.get(), IsPortalDetectionDisabled())
532 .WillOnce(Return(true));
Paul Stewartc681fa02012-03-02 19:40:04 -0800533 EXPECT_CALL(*service_.get(), IsConnected())
Paul Stewart20088d82012-02-16 06:58:55 -0800534 .WillRepeatedly(Return(true));
Paul Stewartd215af62012-04-24 23:25:50 -0700535 EXPECT_CALL(*service_.get(), SetState(Service::kStateOnline));
536 EXPECT_FALSE(StartPortalDetection());
537}
538
539TEST_F(DevicePortalDetectionTest, TechnologyPortalDetectionDisabled) {
540 EXPECT_CALL(*service_.get(), IsPortalDetectionDisabled())
541 .WillOnce(Return(false));
542 EXPECT_CALL(*service_.get(), IsConnected())
543 .WillRepeatedly(Return(true));
544 EXPECT_CALL(*service_.get(), IsPortalDetectionAuto())
545 .WillOnce(Return(true));
Paul Stewartc681fa02012-03-02 19:40:04 -0800546 EXPECT_CALL(manager_, IsPortalDetectionEnabled(device_->technology()))
Paul Stewart20088d82012-02-16 06:58:55 -0800547 .WillOnce(Return(false));
Paul Stewartc681fa02012-03-02 19:40:04 -0800548 EXPECT_CALL(*service_.get(), SetState(Service::kStateOnline));
Paul Stewart20088d82012-02-16 06:58:55 -0800549 EXPECT_FALSE(StartPortalDetection());
550}
551
Paul Stewartc681fa02012-03-02 19:40:04 -0800552TEST_F(DevicePortalDetectionTest, PortalDetectionProxyConfig) {
Paul Stewartd215af62012-04-24 23:25:50 -0700553 EXPECT_CALL(*service_.get(), IsPortalDetectionDisabled())
554 .WillOnce(Return(false));
Paul Stewartc681fa02012-03-02 19:40:04 -0800555 EXPECT_CALL(*service_.get(), IsConnected())
Paul Stewart20088d82012-02-16 06:58:55 -0800556 .WillRepeatedly(Return(true));
Paul Stewartc681fa02012-03-02 19:40:04 -0800557 EXPECT_CALL(*service_.get(), HasProxyConfig())
Paul Stewart20088d82012-02-16 06:58:55 -0800558 .WillOnce(Return(true));
Paul Stewartd215af62012-04-24 23:25:50 -0700559 EXPECT_CALL(*service_.get(), IsPortalDetectionAuto())
560 .WillOnce(Return(true));
Paul Stewartc681fa02012-03-02 19:40:04 -0800561 EXPECT_CALL(manager_, IsPortalDetectionEnabled(device_->technology()))
Paul Stewart20088d82012-02-16 06:58:55 -0800562 .WillOnce(Return(true));
Paul Stewartc681fa02012-03-02 19:40:04 -0800563 EXPECT_CALL(*service_.get(), SetState(Service::kStateOnline));
Paul Stewart20088d82012-02-16 06:58:55 -0800564 EXPECT_FALSE(StartPortalDetection());
565}
566
Paul Stewartc681fa02012-03-02 19:40:04 -0800567TEST_F(DevicePortalDetectionTest, PortalDetectionBadUrl) {
Paul Stewartd215af62012-04-24 23:25:50 -0700568 EXPECT_CALL(*service_.get(), IsPortalDetectionDisabled())
569 .WillOnce(Return(false));
Paul Stewartc681fa02012-03-02 19:40:04 -0800570 EXPECT_CALL(*service_.get(), IsConnected())
Paul Stewart20088d82012-02-16 06:58:55 -0800571 .WillRepeatedly(Return(true));
Paul Stewartc681fa02012-03-02 19:40:04 -0800572 EXPECT_CALL(*service_.get(), HasProxyConfig())
Paul Stewart20088d82012-02-16 06:58:55 -0800573 .WillOnce(Return(false));
Paul Stewartd215af62012-04-24 23:25:50 -0700574 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(true));
578 const string portal_url;
Paul Stewartc681fa02012-03-02 19:40:04 -0800579 EXPECT_CALL(manager_, GetPortalCheckURL())
Paul Stewart20088d82012-02-16 06:58:55 -0800580 .WillRepeatedly(ReturnRef(portal_url));
Paul Stewartc681fa02012-03-02 19:40:04 -0800581 EXPECT_CALL(*service_.get(), SetState(Service::kStateOnline));
Paul Stewart20088d82012-02-16 06:58:55 -0800582 EXPECT_FALSE(StartPortalDetection());
583}
584
Paul Stewartc681fa02012-03-02 19:40:04 -0800585TEST_F(DevicePortalDetectionTest, PortalDetectionStart) {
Paul Stewartd215af62012-04-24 23:25:50 -0700586 EXPECT_CALL(*service_.get(), IsPortalDetectionDisabled())
587 .WillOnce(Return(false));
Paul Stewartc681fa02012-03-02 19:40:04 -0800588 EXPECT_CALL(*service_.get(), IsConnected())
Paul Stewart20088d82012-02-16 06:58:55 -0800589 .WillRepeatedly(Return(true));
Paul Stewartc681fa02012-03-02 19:40:04 -0800590 EXPECT_CALL(*service_.get(), HasProxyConfig())
Paul Stewart20088d82012-02-16 06:58:55 -0800591 .WillOnce(Return(false));
Paul Stewartd215af62012-04-24 23:25:50 -0700592 EXPECT_CALL(*service_.get(), IsPortalDetectionAuto())
593 .WillOnce(Return(true));
Paul Stewartc681fa02012-03-02 19:40:04 -0800594 EXPECT_CALL(manager_, IsPortalDetectionEnabled(device_->technology()))
Paul Stewart20088d82012-02-16 06:58:55 -0800595 .WillOnce(Return(true));
596 const string portal_url(PortalDetector::kDefaultURL);
Paul Stewartc681fa02012-03-02 19:40:04 -0800597 EXPECT_CALL(manager_, GetPortalCheckURL())
Paul Stewart20088d82012-02-16 06:58:55 -0800598 .WillRepeatedly(ReturnRef(portal_url));
Paul Stewartc681fa02012-03-02 19:40:04 -0800599 EXPECT_CALL(*service_.get(), SetState(Service::kStateOnline))
Paul Stewart20088d82012-02-16 06:58:55 -0800600 .Times(0);
Paul Stewart20088d82012-02-16 06:58:55 -0800601 const string kInterfaceName("int0");
Paul Stewartc681fa02012-03-02 19:40:04 -0800602 EXPECT_CALL(*connection_.get(), interface_name())
603 .WillRepeatedly(ReturnRef(kInterfaceName));
Paul Stewart20088d82012-02-16 06:58:55 -0800604 const vector<string> kDNSServers;
Paul Stewartc681fa02012-03-02 19:40:04 -0800605 EXPECT_CALL(*connection_.get(), dns_servers())
606 .WillRepeatedly(ReturnRef(kDNSServers));
Paul Stewart20088d82012-02-16 06:58:55 -0800607 EXPECT_TRUE(StartPortalDetection());
608
609 // Drop all references to device_info before it falls out of scope.
610 SetConnection(NULL);
611 StopPortalDetection();
612}
613
Paul Stewartc681fa02012-03-02 19:40:04 -0800614TEST_F(DevicePortalDetectionTest, PortalDetectionNonFinal) {
615 EXPECT_CALL(*service_.get(), IsConnected())
Paul Stewart20088d82012-02-16 06:58:55 -0800616 .Times(0);
Paul Stewartc681fa02012-03-02 19:40:04 -0800617 EXPECT_CALL(*service_.get(), SetState(_))
Paul Stewart20088d82012-02-16 06:58:55 -0800618 .Times(0);
Paul Stewart20088d82012-02-16 06:58:55 -0800619 PortalDetectorCallback(PortalDetector::Result(
620 PortalDetector::kPhaseUnknown,
621 PortalDetector::kStatusFailure,
Thieu Le85e050b2012-03-13 15:04:38 -0700622 kPortalAttempts,
Paul Stewart20088d82012-02-16 06:58:55 -0800623 false));
624}
625
Paul Stewartc681fa02012-03-02 19:40:04 -0800626TEST_F(DevicePortalDetectionTest, PortalDetectionFailure) {
627 EXPECT_CALL(*service_.get(), IsConnected())
Paul Stewart20088d82012-02-16 06:58:55 -0800628 .WillOnce(Return(true));
Paul Stewartc681fa02012-03-02 19:40:04 -0800629 EXPECT_CALL(*service_.get(), SetState(Service::kStatePortal));
Thieu Le85e050b2012-03-13 15:04:38 -0700630 EXPECT_CALL(metrics_,
631 SendEnumToUMA("Network.Shill.Unknown.PortalResult",
632 Metrics::kPortalResultConnectionFailure,
633 Metrics::kPortalResultMax));
634 EXPECT_CALL(metrics_,
635 SendToUMA("Network.Shill.Unknown.PortalAttemptsToOnline",
636 _, _, _, _)).Times(0);
637 EXPECT_CALL(metrics_,
638 SendToUMA("Network.Shill.Unknown.PortalAttempts",
639 kPortalAttempts,
640 Metrics::kMetricPortalAttemptsMin,
641 Metrics::kMetricPortalAttemptsMax,
642 Metrics::kMetricPortalAttemptsNumBuckets));
Paul Stewartc681fa02012-03-02 19:40:04 -0800643 EXPECT_CALL(*connection_.get(), is_default())
644 .WillOnce(Return(false));
Paul Stewart20088d82012-02-16 06:58:55 -0800645 PortalDetectorCallback(PortalDetector::Result(
Thieu Le85e050b2012-03-13 15:04:38 -0700646 PortalDetector::kPhaseConnection,
Paul Stewart20088d82012-02-16 06:58:55 -0800647 PortalDetector::kStatusFailure,
Thieu Le85e050b2012-03-13 15:04:38 -0700648 kPortalAttempts,
Paul Stewart20088d82012-02-16 06:58:55 -0800649 true));
650}
651
Paul Stewartc681fa02012-03-02 19:40:04 -0800652TEST_F(DevicePortalDetectionTest, PortalDetectionSuccess) {
653 EXPECT_CALL(*service_.get(), IsConnected())
Paul Stewart20088d82012-02-16 06:58:55 -0800654 .WillOnce(Return(true));
Paul Stewartc681fa02012-03-02 19:40:04 -0800655 EXPECT_CALL(*service_.get(), SetState(Service::kStateOnline));
Thieu Le85e050b2012-03-13 15:04:38 -0700656 EXPECT_CALL(metrics_,
657 SendEnumToUMA("Network.Shill.Unknown.PortalResult",
658 Metrics::kPortalResultSuccess,
659 Metrics::kPortalResultMax));
660 EXPECT_CALL(metrics_,
661 SendToUMA("Network.Shill.Unknown.PortalAttemptsToOnline",
662 kPortalAttempts,
663 Metrics::kMetricPortalAttemptsToOnlineMin,
664 Metrics::kMetricPortalAttemptsToOnlineMax,
665 Metrics::kMetricPortalAttemptsToOnlineNumBuckets));
666 EXPECT_CALL(metrics_,
667 SendToUMA("Network.Shill.Unknown.PortalAttempts",
668 _, _, _, _)).Times(0);
Paul Stewart20088d82012-02-16 06:58:55 -0800669 PortalDetectorCallback(PortalDetector::Result(
Thieu Le85e050b2012-03-13 15:04:38 -0700670 PortalDetector::kPhaseContent,
Paul Stewart20088d82012-02-16 06:58:55 -0800671 PortalDetector::kStatusSuccess,
Thieu Le85e050b2012-03-13 15:04:38 -0700672 kPortalAttempts,
673 true));
674}
675
676TEST_F(DevicePortalDetectionTest, PortalDetectionSuccessAfterFailure) {
677 EXPECT_CALL(*service_.get(), IsConnected())
678 .WillRepeatedly(Return(true));
679 EXPECT_CALL(*service_.get(), SetState(Service::kStatePortal));
680 EXPECT_CALL(metrics_,
681 SendEnumToUMA("Network.Shill.Unknown.PortalResult",
682 Metrics::kPortalResultConnectionFailure,
683 Metrics::kPortalResultMax));
684 EXPECT_CALL(metrics_,
685 SendToUMA("Network.Shill.Unknown.PortalAttemptsToOnline",
686 _, _, _, _)).Times(0);
687 EXPECT_CALL(metrics_,
688 SendToUMA("Network.Shill.Unknown.PortalAttempts",
689 kPortalAttempts,
690 Metrics::kMetricPortalAttemptsMin,
691 Metrics::kMetricPortalAttemptsMax,
692 Metrics::kMetricPortalAttemptsNumBuckets));
693 EXPECT_CALL(*connection_.get(), is_default())
694 .WillOnce(Return(false));
695 PortalDetectorCallback(PortalDetector::Result(
696 PortalDetector::kPhaseConnection,
697 PortalDetector::kStatusFailure,
698 kPortalAttempts,
699 true));
700 Mock::VerifyAndClearExpectations(&metrics_);
701
702 EXPECT_CALL(*service_.get(), SetState(Service::kStateOnline));
703 EXPECT_CALL(metrics_,
704 SendEnumToUMA("Network.Shill.Unknown.PortalResult",
705 Metrics::kPortalResultSuccess,
706 Metrics::kPortalResultMax));
707 EXPECT_CALL(metrics_,
708 SendToUMA("Network.Shill.Unknown.PortalAttemptsToOnline",
709 kPortalAttempts * 2,
710 Metrics::kMetricPortalAttemptsToOnlineMin,
711 Metrics::kMetricPortalAttemptsToOnlineMax,
712 Metrics::kMetricPortalAttemptsToOnlineNumBuckets));
713 EXPECT_CALL(metrics_,
714 SendToUMA("Network.Shill.Unknown.PortalAttempts",
715 _, _, _, _)).Times(0);
716 PortalDetectorCallback(PortalDetector::Result(
717 PortalDetector::kPhaseContent,
718 PortalDetector::kStatusSuccess,
719 kPortalAttempts,
Paul Stewart20088d82012-02-16 06:58:55 -0800720 true));
721}
722
Paul Stewartc681fa02012-03-02 19:40:04 -0800723TEST_F(DevicePortalDetectionTest, RequestPortalDetection) {
724 EXPECT_CALL(*service_.get(), state())
725 .WillOnce(Return(Service::kStateOnline))
726 .WillRepeatedly(Return(Service::kStatePortal));
727 EXPECT_FALSE(RequestPortalDetection());
728
729 EXPECT_CALL(*connection_.get(), is_default())
730 .WillOnce(Return(false))
731 .WillRepeatedly(Return(true));
732 EXPECT_FALSE(RequestPortalDetection());
733
734 EXPECT_CALL(*portal_detector_, IsInProgress())
735 .WillOnce(Return(true));
736 // Portal detection already running.
737 EXPECT_TRUE(RequestPortalDetection());
738
739 // Make sure our running mock portal detector was not replaced.
740 ExpectPortalDetectorIsMock();
741
742 // Throw away our pre-fabricated portal detector, and have the device create
743 // a new one.
744 StopPortalDetection();
Paul Stewartd215af62012-04-24 23:25:50 -0700745 EXPECT_CALL(*service_.get(), IsPortalDetectionDisabled())
746 .WillRepeatedly(Return(false));
747 EXPECT_CALL(*service_.get(), IsPortalDetectionAuto())
748 .WillRepeatedly(Return(true));
Paul Stewartc681fa02012-03-02 19:40:04 -0800749 EXPECT_CALL(manager_, IsPortalDetectionEnabled(device_->technology()))
750 .WillRepeatedly(Return(true));
751 EXPECT_CALL(*service_.get(), HasProxyConfig())
752 .WillRepeatedly(Return(false));
753 const string kPortalCheckURL("http://portal");
754 EXPECT_CALL(manager_, GetPortalCheckURL())
755 .WillOnce(ReturnRef(kPortalCheckURL));
756 const string kInterfaceName("int0");
757 EXPECT_CALL(*connection_.get(), interface_name())
758 .WillRepeatedly(ReturnRef(kInterfaceName));
759 const vector<string> kDNSServers;
760 EXPECT_CALL(*connection_.get(), dns_servers())
761 .WillRepeatedly(ReturnRef(kDNSServers));
762 EXPECT_TRUE(RequestPortalDetection());
763}
764
765TEST_F(DevicePortalDetectionTest, NotConnected) {
766 EXPECT_CALL(*service_.get(), IsConnected())
767 .WillOnce(Return(false));
768 SetServiceConnectedState(Service::kStatePortal);
769 // We don't check for the portal detector to be reset here, because
770 // it would have been reset as a part of disconnection.
771}
772
773TEST_F(DevicePortalDetectionTest, NotPortal) {
774 EXPECT_CALL(*service_.get(), IsConnected())
775 .WillOnce(Return(true));
776 EXPECT_CALL(*service_.get(), SetState(Service::kStateOnline));
777 SetServiceConnectedState(Service::kStateOnline);
778 ExpectPortalDetectorReset();
779}
780
781TEST_F(DevicePortalDetectionTest, NotDefault) {
782 EXPECT_CALL(*service_.get(), IsConnected())
783 .WillOnce(Return(true));
784 EXPECT_CALL(*connection_.get(), is_default())
785 .WillOnce(Return(false));
786 EXPECT_CALL(*service_.get(), SetState(Service::kStatePortal));
787 SetServiceConnectedState(Service::kStatePortal);
788 ExpectPortalDetectorReset();
789}
790
791TEST_F(DevicePortalDetectionTest, PortalIntervalIsZero) {
792 EXPECT_CALL(*service_.get(), IsConnected())
793 .WillOnce(Return(true));
794 EXPECT_CALL(*connection_.get(), is_default())
795 .WillOnce(Return(true));
796 EXPECT_CALL(manager_, GetPortalCheckInterval())
797 .WillOnce(Return(0));
798 EXPECT_CALL(*service_.get(), SetState(Service::kStatePortal));
799 SetServiceConnectedState(Service::kStatePortal);
800 ExpectPortalDetectorReset();
801}
802
803TEST_F(DevicePortalDetectionTest, RestartPortalDetection) {
804 EXPECT_CALL(*service_.get(), IsConnected())
805 .WillOnce(Return(true));
806 EXPECT_CALL(*connection_.get(), is_default())
807 .WillOnce(Return(true));
808 const int kPortalDetectionInterval = 10;
809 EXPECT_CALL(manager_, GetPortalCheckInterval())
810 .Times(AtLeast(1))
811 .WillRepeatedly(Return(kPortalDetectionInterval));
812 const string kPortalCheckURL("http://portal");
813 EXPECT_CALL(manager_, GetPortalCheckURL())
814 .WillOnce(ReturnRef(kPortalCheckURL));
815 EXPECT_CALL(*portal_detector_, StartAfterDelay(kPortalCheckURL,
816 kPortalDetectionInterval))
817 .WillOnce(Return(true));
818 EXPECT_CALL(*service_.get(), SetState(Service::kStatePortal));
819 SetServiceConnectedState(Service::kStatePortal);
820 ExpectPortalDetectorSet();
821}
822
Paul Stewart6ff27f52012-07-11 06:51:41 -0700823class DeviceByteCountTest : public DeviceTest {
824 public:
825 DeviceByteCountTest()
826 : manager_(control_interface(),
827 dispatcher(),
828 metrics(),
829 glib()),
830 rx_byte_count_(0),
831 tx_byte_count_(0),
832 rx_stored_byte_count_(0),
833 tx_stored_byte_count_(0) {}
834 virtual ~DeviceByteCountTest() {}
835
836 virtual void SetUp() {
837 DeviceTest::SetUp();
838 EXPECT_CALL(manager_, device_info()).WillRepeatedly(Return(&device_info_));
839 EXPECT_CALL(device_info_, GetByteCounts(kDeviceInterfaceIndex, _, _))
840 .WillRepeatedly(Invoke(this, &DeviceByteCountTest::ReturnByteCounts));
841 const string id = device_->GetStorageIdentifier();
842 EXPECT_CALL(storage_, ContainsGroup(id)).WillRepeatedly(Return(true));
843 EXPECT_CALL(storage_, GetUint64(id, Device::kStorageReceiveByteCount, _))
844 .WillRepeatedly(
845 Invoke(this, &DeviceByteCountTest::GetStoredReceiveCount));
846 EXPECT_CALL(storage_, GetUint64(id, Device::kStorageTransmitByteCount, _))
847 .WillRepeatedly(
848 Invoke(this, &DeviceByteCountTest::GetStoredTransmitCount));
849 }
850
851 bool ReturnByteCounts(int interface_index, uint64 *rx, uint64 *tx) {
852 *rx = rx_byte_count_;
853 *tx = tx_byte_count_;
854 return true;
855 }
856
857 bool ExpectByteCounts(DeviceRefPtr device,
858 int64 expected_rx, int64 expected_tx) {
859 int64 actual_rx = device->GetReceiveByteCount(NULL);
860 int64 actual_tx = device->GetTransmitByteCount(NULL);
861 EXPECT_EQ(expected_rx, actual_rx);
862 EXPECT_EQ(expected_tx, actual_tx);
863 return expected_rx == actual_rx && expected_tx == actual_tx;
864 }
865
866 void ExpectSavedCounts(DeviceRefPtr device,
867 int64 expected_rx, int64 expected_tx) {
868 EXPECT_CALL(storage_,
869 SetUint64(_, Device::kStorageReceiveByteCount, expected_rx))
870 .WillOnce(Return(true));
871 EXPECT_CALL(storage_,
872 SetUint64(_, Device::kStorageTransmitByteCount, expected_tx))
873 .WillOnce(Return(true));
874 EXPECT_TRUE(device->Save(&storage_));
875 }
876
877
878 bool GetStoredReceiveCount(const string &group, const string &key,
879 uint64 *value) {
880 if (!rx_stored_byte_count_) {
881 return false;
882 }
883 *value = rx_stored_byte_count_;
884 return true;
885 }
886
887 bool GetStoredTransmitCount(const string &group, const string &key,
888 uint64 *value) {
889 if (!tx_stored_byte_count_) {
890 return false;
891 }
892 *value = tx_stored_byte_count_;
893 return true;
894 }
895
896 protected:
897 NiceMock<MockManager> manager_;
898 NiceMock<MockStore> storage_;
899 uint64 rx_byte_count_;
900 uint64 tx_byte_count_;
901 uint64 rx_stored_byte_count_;
902 uint64 tx_stored_byte_count_;
903};
904
905
906TEST_F(DeviceByteCountTest, GetByteCounts) {
907 // On Device initialization, byte counts should be zero, independent of
908 // the byte counts reported by the interface.
909 rx_byte_count_ = 123;
910 tx_byte_count_ = 456;
911 DeviceRefPtr device(new TestDevice(control_interface(),
912 dispatcher(),
913 NULL,
914 &manager_,
915 kDeviceName,
916 kDeviceAddress,
917 kDeviceInterfaceIndex,
918 Technology::kUnknown));
919 EXPECT_TRUE(ExpectByteCounts(device, 0, 0));
920
921 // Device should report any increase in the byte counts reported in the
922 // interface.
923 const int64 delta_rx_count = 789;
924 const int64 delta_tx_count = 12;
925 rx_byte_count_ += delta_rx_count;
926 tx_byte_count_ += delta_tx_count;
927 EXPECT_TRUE(ExpectByteCounts(device, delta_rx_count, delta_tx_count));
928
929 // Expect the correct values to be saved to the profile.
930 ExpectSavedCounts(device, delta_rx_count, delta_tx_count);
931
932 // If Device is loaded from a profile that does not contain stored byte
933 // counts, the byte counts reported should remain unchanged.
934 EXPECT_TRUE(device->Load(&storage_));
935 EXPECT_TRUE(ExpectByteCounts(device, delta_rx_count, delta_tx_count));
936
937 // If Device is loaded from a profile that contains stored byte
938 // counts, the byte counts reported should now reflect the stored values.
939 rx_stored_byte_count_ = 345;
940 tx_stored_byte_count_ = 678;
941 EXPECT_TRUE(device->Load(&storage_));
942 EXPECT_TRUE(ExpectByteCounts(
943 device, rx_stored_byte_count_, tx_stored_byte_count_));
944
945 // Increases to the interface receive count should be reflected as offsets
946 // to the stored byte counts.
947 rx_byte_count_ += delta_rx_count;
948 tx_byte_count_ += delta_tx_count;
949 EXPECT_TRUE(ExpectByteCounts(device,
950 rx_stored_byte_count_ + delta_rx_count,
951 tx_stored_byte_count_ + delta_tx_count));
952
953 // Expect the correct values to be saved to the profile.
954 ExpectSavedCounts(device,
955 rx_stored_byte_count_ + delta_rx_count,
956 tx_stored_byte_count_ + delta_tx_count);
957
958 // Expect that after resetting byte counts, read-back values return to zero,
959 // and that the device requests this information to be persisted.
960 EXPECT_CALL(manager_, UpdateDevice(device));
961 device->ResetByteCounters();
962 EXPECT_TRUE(ExpectByteCounts(device, 0, 0));
963}
964
Darin Petkovafa6fc42011-06-21 16:21:08 -0700965} // namespace shill