blob: c053f4e1b7bc9dde02d7b55f8acdcf6bc4feaa46 [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
Arman Ugurayf84a4242013-04-09 20:01:07 -070015#include <base/basictypes.h>
16#include <base/bind.h>
17#include <base/callback.h>
18#include <base/memory/weak_ptr.h>
Chris Masone3bd3c8c2011-06-13 08:20:26 -070019#include <chromeos/dbus/service_constants.h>
Chris Masone34af2182011-08-22 11:59:36 -070020#include <dbus-c++/dbus.h>
Chris Masone3bd3c8c2011-06-13 08:20:26 -070021#include <gmock/gmock.h>
Chris Masone34af2182011-08-22 11:59:36 -070022#include <gtest/gtest.h>
Chris Masone3bd3c8c2011-06-13 08:20:26 -070023
24#include "shill/dbus_adaptor.h"
25#include "shill/dhcp_provider.h"
Paul Stewart26b327e2011-10-19 11:38:09 -070026#include "shill/event_dispatcher.h"
Chris Masone95207da2011-06-29 16:50:49 -070027#include "shill/mock_adaptors.h"
Paul Stewart20088d82012-02-16 06:58:55 -080028#include "shill/mock_connection.h"
Arman Ugurayf84a4242013-04-09 20:01:07 -070029#include "shill/mock_connection_health_checker.h"
Ben Chanb061f892013-02-27 17:46:55 -080030#include "shill/mock_control.h"
Chris Masone3bd3c8c2011-06-13 08:20:26 -070031#include "shill/mock_device.h"
Paul Stewart20088d82012-02-16 06:58:55 -080032#include "shill/mock_device_info.h"
Jorge Lucangeli Obesad43cc62012-04-11 16:25:43 -070033#include "shill/mock_dhcp_config.h"
34#include "shill/mock_dhcp_provider.h"
Chris Masone3bd3c8c2011-06-13 08:20:26 -070035#include "shill/mock_glib.h"
Prathmesh Prabhuba99b592013-04-17 15:13:14 -070036#include "shill/mock_ip_address_store.h"
Chris Masone34af2182011-08-22 11:59:36 -070037#include "shill/mock_ipconfig.h"
Paul Stewart036dba02012-08-07 12:34:41 -070038#include "shill/mock_link_monitor.h"
Paul Stewart20088d82012-02-16 06:58:55 -080039#include "shill/mock_manager.h"
Thieu Le85e050b2012-03-13 15:04:38 -070040#include "shill/mock_metrics.h"
Paul Stewartc681fa02012-03-02 19:40:04 -080041#include "shill/mock_portal_detector.h"
mukesh agrawal5c4dd0b2011-09-14 13:53:14 -070042#include "shill/mock_rtnl_handler.h"
Paul Stewart03dba0b2011-08-22 16:32:45 -070043#include "shill/mock_service.h"
Chris Masone5dec5f42011-07-22 14:07:55 -070044#include "shill/mock_store.h"
Ben Chanb061f892013-02-27 17:46:55 -080045#include "shill/mock_traffic_monitor.h"
Paul Stewart20088d82012-02-16 06:58:55 -080046#include "shill/portal_detector.h"
Chris Masone3bd3c8c2011-06-13 08:20:26 -070047#include "shill/property_store_unittest.h"
mukesh agrawalcc0fded2012-05-09 13:40:58 -070048#include "shill/static_ip_parameters.h"
Gaurav Shah435de2c2011-11-17 19:01:07 -080049#include "shill/technology.h"
Ben Chanb061f892013-02-27 17:46:55 -080050#include "shill/traffic_monitor.h"
Chris Masone3bd3c8c2011-06-13 08:20:26 -070051
Arman Ugurayf84a4242013-04-09 20:01:07 -070052using base::Bind;
53using base::Callback;
Chris Masone3bd3c8c2011-06-13 08:20:26 -070054using std::map;
55using std::string;
56using std::vector;
57using ::testing::_;
mukesh agrawalcc0fded2012-05-09 13:40:58 -070058using ::testing::AnyNumber;
Chris Masone5dec5f42011-07-22 14:07:55 -070059using ::testing::AtLeast;
Arman Ugurayf84a4242013-04-09 20:01:07 -070060using ::testing::DefaultValue;
Paul Stewart6ff27f52012-07-11 06:51:41 -070061using ::testing::Invoke;
Thieu Le85e050b2012-03-13 15:04:38 -070062using ::testing::Mock;
Chris Masone3bd3c8c2011-06-13 08:20:26 -070063using ::testing::NiceMock;
64using ::testing::Return;
Paul Stewart20088d82012-02-16 06:58:55 -080065using ::testing::ReturnRef;
Paul Stewart03dba0b2011-08-22 16:32:45 -070066using ::testing::StrictMock;
Chris Masone3bd3c8c2011-06-13 08:20:26 -070067using ::testing::Test;
Chris Masone34af2182011-08-22 11:59:36 -070068using ::testing::Values;
Darin Petkovafa6fc42011-06-21 16:21:08 -070069
70namespace shill {
71
Eric Shienbrood9a245532012-03-07 14:20:39 -050072class TestDevice : public Device {
73 public:
74 TestDevice(ControlInterface *control_interface,
75 EventDispatcher *dispatcher,
76 Metrics *metrics,
77 Manager *manager,
78 const std::string &link_name,
79 const std::string &address,
80 int interface_index,
81 Technology::Identifier technology)
82 : Device(control_interface, dispatcher, metrics, manager, link_name,
83 address, interface_index, technology) {}
84 ~TestDevice() {}
85 virtual void Start(Error *error,
Jason Glasgow4a490792012-04-10 15:02:05 -040086 const EnabledStateChangedCallback &callback) {
87 DCHECK(error);
88 }
Eric Shienbrood9a245532012-03-07 14:20:39 -050089 virtual void Stop(Error *error,
Jason Glasgow4a490792012-04-10 15:02:05 -040090 const EnabledStateChangedCallback &callback) {
91 DCHECK(error);
92 }
Eric Shienbrood9a245532012-03-07 14:20:39 -050093};
94
Chris Masone3bd3c8c2011-06-13 08:20:26 -070095class DeviceTest : public PropertyStoreTest {
Darin Petkovafa6fc42011-06-21 16:21:08 -070096 public:
97 DeviceTest()
Eric Shienbrood9a245532012-03-07 14:20:39 -050098 : device_(new TestDevice(control_interface(),
99 dispatcher(),
100 NULL,
101 manager(),
102 kDeviceName,
103 kDeviceAddress,
104 kDeviceInterfaceIndex,
105 Technology::kUnknown)),
Thieu Le6c1e3bb2013-02-06 15:20:35 -0800106 device_info_(control_interface(), NULL, NULL, NULL),
107 metrics_(dispatcher()) {
Chris Masone2176a882011-09-14 22:29:15 -0700108 DHCPProvider::GetInstance()->glib_ = glib();
109 DHCPProvider::GetInstance()->control_interface_ = control_interface();
mukesh agrawalcc0fded2012-05-09 13:40:58 -0700110 DHCPProvider::GetInstance()->dispatcher_ = dispatcher();
Darin Petkovafa6fc42011-06-21 16:21:08 -0700111 }
Chris Masone3bd3c8c2011-06-13 08:20:26 -0700112 virtual ~DeviceTest() {}
Darin Petkovafa6fc42011-06-21 16:21:08 -0700113
mukesh agrawal5c4dd0b2011-09-14 13:53:14 -0700114 virtual void SetUp() {
Thieu Le85e050b2012-03-13 15:04:38 -0700115 device_->metrics_ = &metrics_;
mukesh agrawal5c4dd0b2011-09-14 13:53:14 -0700116 device_->rtnl_handler_ = &rtnl_handler_;
117 }
118
Darin Petkovafa6fc42011-06-21 16:21:08 -0700119 protected:
Chris Masone626719f2011-08-18 16:58:48 -0700120 static const char kDeviceName[];
121 static const char kDeviceAddress[];
Thieu Lefb46caf2012-03-08 11:57:15 -0800122 static const int kDeviceInterfaceIndex;
Chris Masone626719f2011-08-18 16:58:48 -0700123
Darin Petkov79d74c92012-03-07 17:20:32 +0100124 void OnIPConfigUpdated(const IPConfigRefPtr &ipconfig, bool success) {
125 device_->OnIPConfigUpdated(ipconfig, success);
Paul Stewart20088d82012-02-16 06:58:55 -0800126 }
127
128 void SelectService(const ServiceRefPtr service) {
129 device_->SelectService(service);
130 }
131
Paul Stewart20088d82012-02-16 06:58:55 -0800132 void SetConnection(ConnectionRefPtr connection) {
133 device_->connection_ = connection;
134 }
135
Paul Stewart036dba02012-08-07 12:34:41 -0700136 void SetLinkMonitor(LinkMonitor *link_monitor) {
137 device_->set_link_monitor(link_monitor); // Passes ownership.
138 }
139
Paul Stewartc8860612012-09-28 07:36:21 -0700140 bool HasLinkMonitor() {
141 return device_->link_monitor();
142 }
143
Paul Stewart036dba02012-08-07 12:34:41 -0700144 bool StartLinkMonitor() {
145 return device_->StartLinkMonitor();
146 }
147
148 void StopLinkMonitor() {
149 device_->StopLinkMonitor();
150 }
151
152 uint64 GetLinkMonitorResponseTime(Error *error) {
153 return device_->GetLinkMonitorResponseTime(error);
154 }
155
Ben Chanb061f892013-02-27 17:46:55 -0800156 void SetTrafficMonitor(TrafficMonitor *traffic_monitor) {
157 device_->set_traffic_monitor(traffic_monitor); // Passes ownership.
158 }
159
160 bool StartTrafficMonitor() {
161 return device_->StartTrafficMonitor();
162 }
163
164 void StopTrafficMonitor() {
165 device_->StopTrafficMonitor();
166 }
167
Paul Stewart036dba02012-08-07 12:34:41 -0700168 void SetManager(Manager *manager) {
169 device_->manager_ = manager;
170 }
171
Darin Petkovafa6fc42011-06-21 16:21:08 -0700172 MockControl control_interface_;
173 DeviceRefPtr device_;
Paul Stewartc681fa02012-03-02 19:40:04 -0800174 MockDeviceInfo device_info_;
Thieu Le85e050b2012-03-13 15:04:38 -0700175 MockMetrics metrics_;
mukesh agrawal5c4dd0b2011-09-14 13:53:14 -0700176 StrictMock<MockRTNLHandler> rtnl_handler_;
Darin Petkovafa6fc42011-06-21 16:21:08 -0700177};
178
Chris Masone626719f2011-08-18 16:58:48 -0700179const char DeviceTest::kDeviceName[] = "testdevice";
180const char DeviceTest::kDeviceAddress[] = "address";
Thieu Lefb46caf2012-03-08 11:57:15 -0800181const int DeviceTest::kDeviceInterfaceIndex = 0;
Chris Masone626719f2011-08-18 16:58:48 -0700182
Chris Masone3bd3c8c2011-06-13 08:20:26 -0700183TEST_F(DeviceTest, Contains) {
mukesh agrawalde29fa82011-09-16 16:16:36 -0700184 EXPECT_TRUE(device_->store().Contains(flimflam::kNameProperty));
185 EXPECT_FALSE(device_->store().Contains(""));
Chris Masone3bd3c8c2011-06-13 08:20:26 -0700186}
187
Chris Masonea8a2c252011-06-27 22:16:30 -0700188TEST_F(DeviceTest, GetProperties) {
189 map<string, ::DBus::Variant> props;
190 Error error(Error::kInvalidProperty, "");
Eric Shienbrood9a245532012-03-07 14:20:39 -0500191 ::DBus::Error dbus_error;
192 DBusAdaptor::GetProperties(device_->store(), &props, &dbus_error);
193 ASSERT_FALSE(props.find(flimflam::kNameProperty) == props.end());
194 EXPECT_EQ(props[flimflam::kNameProperty].reader().get_string(),
195 string(kDeviceName));
Chris Masonea8a2c252011-06-27 22:16:30 -0700196}
197
Eric Shienbrood9a245532012-03-07 14:20:39 -0500198// Note: there are currently no writeable Device properties that
199// aren't registered in a subclass.
200TEST_F(DeviceTest, SetReadOnlyProperty) {
Chris Masone3bd3c8c2011-06-13 08:20:26 -0700201 ::DBus::Error error;
Chris Masoneb925cc82011-06-22 15:39:57 -0700202 // Ensure that an attempt to write a R/O property returns InvalidArgs error.
mukesh agrawal6bb9e7c2012-01-30 14:57:54 -0800203 EXPECT_FALSE(DBusAdaptor::SetProperty(device_->mutable_store(),
204 flimflam::kAddressProperty,
205 PropertyStoreTest::kStringV,
206 &error));
Chris Masone9d779932011-08-25 16:33:41 -0700207 EXPECT_EQ(invalid_args(), error.name());
Chris Masone3bd3c8c2011-06-13 08:20:26 -0700208}
209
mukesh agrawal8abd2f62012-01-30 14:56:14 -0800210TEST_F(DeviceTest, ClearReadOnlyProperty) {
211 ::DBus::Error error;
mukesh agrawal6bb9e7c2012-01-30 14:57:54 -0800212 EXPECT_FALSE(DBusAdaptor::SetProperty(device_->mutable_store(),
213 flimflam::kAddressProperty,
214 PropertyStoreTest::kStringV,
215 &error));
mukesh agrawal8abd2f62012-01-30 14:56:14 -0800216}
217
218TEST_F(DeviceTest, ClearReadOnlyDerivedProperty) {
219 ::DBus::Error error;
mukesh agrawal6bb9e7c2012-01-30 14:57:54 -0800220 EXPECT_FALSE(DBusAdaptor::SetProperty(device_->mutable_store(),
221 flimflam::kIPConfigsProperty,
222 PropertyStoreTest::kStringsV,
223 &error));
mukesh agrawal8abd2f62012-01-30 14:56:14 -0800224}
225
Darin Petkovafa6fc42011-06-21 16:21:08 -0700226TEST_F(DeviceTest, DestroyIPConfig) {
227 ASSERT_FALSE(device_->ipconfig_.get());
Chris Masone2176a882011-09-14 22:29:15 -0700228 device_->ipconfig_ = new IPConfig(control_interface(), kDeviceName);
Darin Petkovafa6fc42011-06-21 16:21:08 -0700229 device_->DestroyIPConfig();
230 ASSERT_FALSE(device_->ipconfig_.get());
231}
232
233TEST_F(DeviceTest, DestroyIPConfigNULL) {
234 ASSERT_FALSE(device_->ipconfig_.get());
235 device_->DestroyIPConfig();
236 ASSERT_FALSE(device_->ipconfig_.get());
237}
238
Paul Stewart2bf1d352011-12-06 15:02:55 -0800239TEST_F(DeviceTest, AcquireIPConfig) {
Chris Masone2176a882011-09-14 22:29:15 -0700240 device_->ipconfig_ = new IPConfig(control_interface(), "randomname");
Jorge Lucangeli Obesad43cc62012-04-11 16:25:43 -0700241 scoped_ptr<MockDHCPProvider> dhcp_provider(new MockDHCPProvider());
242 device_->dhcp_provider_ = dhcp_provider.get();
243 scoped_refptr<MockDHCPConfig> dhcp_config(new MockDHCPConfig(
244 control_interface(),
245 kDeviceName));
246 EXPECT_CALL(*dhcp_provider, CreateConfig(_, _, _, _))
247 .WillOnce(Return(dhcp_config));
248 EXPECT_CALL(*dhcp_config, RequestIP())
Darin Petkovafa6fc42011-06-21 16:21:08 -0700249 .WillOnce(Return(false));
Paul Stewart2bf1d352011-12-06 15:02:55 -0800250 EXPECT_FALSE(device_->AcquireIPConfig());
Darin Petkovafa6fc42011-06-21 16:21:08 -0700251 ASSERT_TRUE(device_->ipconfig_.get());
252 EXPECT_EQ(kDeviceName, device_->ipconfig_->device_name());
Eric Shienbrood3e20a232012-02-16 11:35:56 -0500253 EXPECT_FALSE(device_->ipconfig_->update_callback_.is_null());
Jorge Lucangeli Obesad43cc62012-04-11 16:25:43 -0700254 device_->dhcp_provider_ = NULL;
Darin Petkovafa6fc42011-06-21 16:21:08 -0700255}
256
Chris Masone5dec5f42011-07-22 14:07:55 -0700257TEST_F(DeviceTest, Load) {
258 NiceMock<MockStore> storage;
259 const string id = device_->GetStorageIdentifier();
260 EXPECT_CALL(storage, ContainsGroup(id)).WillOnce(Return(true));
Paul Stewart6ff27f52012-07-11 06:51:41 -0700261 EXPECT_CALL(storage, GetBool(id, Device::kStoragePowered, _))
262 .WillOnce(Return(true));
263 EXPECT_CALL(storage, GetUint64(id, Device::kStorageReceiveByteCount, _))
264 .WillOnce(Return(true));
265 EXPECT_CALL(storage, GetUint64(id, Device::kStorageTransmitByteCount, _))
266 .WillOnce(Return(true));
Chris Masone5dec5f42011-07-22 14:07:55 -0700267 EXPECT_TRUE(device_->Load(&storage));
268}
269
270TEST_F(DeviceTest, Save) {
271 NiceMock<MockStore> storage;
272 const string id = device_->GetStorageIdentifier();
Paul Stewart6ff27f52012-07-11 06:51:41 -0700273 EXPECT_CALL(storage, SetString(id, Device::kStorageIPConfigs, _))
274 .WillOnce(Return(true));
275 EXPECT_CALL(storage, SetBool(id, Device::kStoragePowered, _))
276 .WillOnce(Return(true));
Chris Masone2176a882011-09-14 22:29:15 -0700277 scoped_refptr<MockIPConfig> ipconfig = new MockIPConfig(control_interface(),
Chris Masone34af2182011-08-22 11:59:36 -0700278 kDeviceName);
279 EXPECT_CALL(*ipconfig.get(), Save(_, _))
280 .WillOnce(Return(true));
281 device_->ipconfig_ = ipconfig;
Paul Stewart6ff27f52012-07-11 06:51:41 -0700282 EXPECT_CALL(storage, SetUint64(id, Device::kStorageReceiveByteCount, _))
283 .WillOnce(Return(true));
284 EXPECT_CALL(storage, SetUint64(id, Device::kStorageTransmitByteCount, _))
285 .Times(AtLeast(true));
Chris Masone5dec5f42011-07-22 14:07:55 -0700286 EXPECT_TRUE(device_->Save(&storage));
287}
288
Chris Masone34af2182011-08-22 11:59:36 -0700289TEST_F(DeviceTest, StorageIdGeneration) {
290 string to_process("/device/stuff/0");
291 ControlInterface::RpcIdToStorageId(&to_process);
292 EXPECT_TRUE(isalpha(to_process[0]));
293 EXPECT_EQ(string::npos, to_process.find('/'));
294}
295
Paul Stewartc1dec4d2011-12-08 15:25:28 -0800296MATCHER(IsNullRefPtr, "") {
297 return !arg;
298}
299
300MATCHER(NotNullRefPtr, "") {
301 return arg;
302}
303
Paul Stewart03dba0b2011-08-22 16:32:45 -0700304TEST_F(DeviceTest, SelectedService) {
305 EXPECT_FALSE(device_->selected_service_.get());
306 device_->SetServiceState(Service::kStateAssociating);
307 scoped_refptr<MockService> service(
Chris Masone2176a882011-09-14 22:29:15 -0700308 new StrictMock<MockService>(control_interface(),
309 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800310 metrics(),
Chris Masone9d779932011-08-25 16:33:41 -0700311 manager()));
Paul Stewart20088d82012-02-16 06:58:55 -0800312 SelectService(service);
Paul Stewart03dba0b2011-08-22 16:32:45 -0700313 EXPECT_TRUE(device_->selected_service_.get() == service.get());
314
315 EXPECT_CALL(*service.get(), SetState(Service::kStateConfiguring));
316 device_->SetServiceState(Service::kStateConfiguring);
317 EXPECT_CALL(*service.get(), SetFailure(Service::kFailureOutOfRange));
318 device_->SetServiceFailure(Service::kFailureOutOfRange);
319
320 // Service should be returned to "Idle" state
321 EXPECT_CALL(*service.get(), state())
322 .WillOnce(Return(Service::kStateUnknown));
323 EXPECT_CALL(*service.get(), SetState(Service::kStateIdle));
Paul Stewartc1dec4d2011-12-08 15:25:28 -0800324 EXPECT_CALL(*service.get(), SetConnection(IsNullRefPtr()));
Paul Stewart20088d82012-02-16 06:58:55 -0800325 SelectService(NULL);
Paul Stewart03dba0b2011-08-22 16:32:45 -0700326
327 // A service in the "Failure" state should not be reset to "Idle"
Paul Stewart20088d82012-02-16 06:58:55 -0800328 SelectService(service);
Paul Stewart03dba0b2011-08-22 16:32:45 -0700329 EXPECT_CALL(*service.get(), state())
330 .WillOnce(Return(Service::kStateFailure));
Paul Stewartc1dec4d2011-12-08 15:25:28 -0800331 EXPECT_CALL(*service.get(), SetConnection(IsNullRefPtr()));
Paul Stewart20088d82012-02-16 06:58:55 -0800332 SelectService(NULL);
Paul Stewart03dba0b2011-08-22 16:32:45 -0700333}
334
Paul Stewartbe5f5b32011-12-07 17:11:11 -0800335TEST_F(DeviceTest, IPConfigUpdatedFailure) {
336 scoped_refptr<MockService> service(
337 new StrictMock<MockService>(control_interface(),
338 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800339 metrics(),
Paul Stewartbe5f5b32011-12-07 17:11:11 -0800340 manager()));
Paul Stewart20088d82012-02-16 06:58:55 -0800341 SelectService(service);
Christopher Wileyabd3b502012-09-26 13:08:52 -0700342 EXPECT_CALL(*service.get(), DisconnectWithFailure(Service::kFailureDHCP, _));
Paul Stewartc1dec4d2011-12-08 15:25:28 -0800343 EXPECT_CALL(*service.get(), SetConnection(IsNullRefPtr()));
Darin Petkov79d74c92012-03-07 17:20:32 +0100344 OnIPConfigUpdated(NULL, false);
Paul Stewartbe5f5b32011-12-07 17:11:11 -0800345}
346
mukesh agrawalcc0fded2012-05-09 13:40:58 -0700347TEST_F(DeviceTest, IPConfigUpdatedFailureWithStatic) {
348 scoped_refptr<MockService> service(
349 new StrictMock<MockService>(control_interface(),
350 dispatcher(),
351 metrics(),
352 manager()));
353 SelectService(service);
354 service->static_ip_parameters_.args_.SetString(
355 flimflam::kAddressProperty, "1.1.1.1");
356 service->static_ip_parameters_.args_.SetInt(flimflam::kPrefixlenProperty, 16);
357 EXPECT_CALL(*service.get(), SetState(_)).Times(0);
358 EXPECT_CALL(*service.get(), SetConnection(_)).Times(0);
359 OnIPConfigUpdated(NULL, false);
360}
361
Paul Stewartbe5f5b32011-12-07 17:11:11 -0800362TEST_F(DeviceTest, IPConfigUpdatedSuccess) {
363 scoped_refptr<MockService> service(
364 new StrictMock<MockService>(control_interface(),
365 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800366 metrics(),
Paul Stewartbe5f5b32011-12-07 17:11:11 -0800367 manager()));
Paul Stewart20088d82012-02-16 06:58:55 -0800368 SelectService(service);
Paul Stewartbe5f5b32011-12-07 17:11:11 -0800369 scoped_refptr<MockIPConfig> ipconfig = new MockIPConfig(control_interface(),
370 kDeviceName);
371 EXPECT_CALL(*service.get(), SetState(Service::kStateConnected));
Paul Stewart20088d82012-02-16 06:58:55 -0800372 EXPECT_CALL(*service.get(), IsConnected())
373 .WillRepeatedly(Return(true));
Paul Stewartd215af62012-04-24 23:25:50 -0700374 EXPECT_CALL(*service.get(), IsPortalDetectionDisabled())
375 .WillRepeatedly(Return(true));
Paul Stewart20088d82012-02-16 06:58:55 -0800376 EXPECT_CALL(*service.get(), SetState(Service::kStateOnline));
Paul Stewartc1dec4d2011-12-08 15:25:28 -0800377 EXPECT_CALL(*service.get(), SetConnection(NotNullRefPtr()));
Darin Petkov79d74c92012-03-07 17:20:32 +0100378 OnIPConfigUpdated(ipconfig.get(), true);
Paul Stewartbe5f5b32011-12-07 17:11:11 -0800379}
380
Thieu Led1760922012-09-11 14:15:35 -0700381TEST_F(DeviceTest, IPConfigUpdatedSuccessNoSelectedService) {
382 // Make sure shill doesn't crash if a service is disabled immediately
383 // after receiving its IP config (selected_service_ is NULL in this case).
384 scoped_refptr<MockIPConfig> ipconfig = new MockIPConfig(control_interface(),
385 kDeviceName);
386 SelectService(NULL);
387 OnIPConfigUpdated(ipconfig.get(), true);
388}
389
Darin Petkove7c6ad32012-06-29 10:22:09 +0200390TEST_F(DeviceTest, SetEnabledPersistent) {
391 EXPECT_FALSE(device_->enabled_);
392 EXPECT_FALSE(device_->enabled_pending_);
393 device_->enabled_persistent_ = false;
394 StrictMock<MockManager> manager(control_interface(),
395 dispatcher(),
396 metrics(),
397 glib());
398 EXPECT_CALL(manager, UpdateDevice(_));
Paul Stewart036dba02012-08-07 12:34:41 -0700399 SetManager(&manager);
Darin Petkove7c6ad32012-06-29 10:22:09 +0200400 Error error;
401 device_->SetEnabledPersistent(true, &error, ResultCallback());
402 EXPECT_TRUE(device_->enabled_persistent_);
403 EXPECT_TRUE(device_->enabled_pending_);
404}
405
Thieu Lefb46caf2012-03-08 11:57:15 -0800406TEST_F(DeviceTest, Start) {
Paul Stewart8c116a92012-05-02 18:30:03 -0700407 EXPECT_FALSE(device_->running_);
408 EXPECT_FALSE(device_->enabled_);
409 EXPECT_FALSE(device_->enabled_pending_);
Eric Shienbrood9a245532012-03-07 14:20:39 -0500410 device_->SetEnabled(true);
Paul Stewart8c116a92012-05-02 18:30:03 -0700411 EXPECT_TRUE(device_->running_);
412 EXPECT_TRUE(device_->enabled_pending_);
Gary Morainbaeefdf2012-04-30 14:53:35 -0700413 device_->OnEnabledStateChanged(ResultCallback(),
414 Error(Error::kOperationFailed));
415 EXPECT_FALSE(device_->enabled_pending_);
Thieu Lefb46caf2012-03-08 11:57:15 -0800416}
417
mukesh agrawal5c4dd0b2011-09-14 13:53:14 -0700418TEST_F(DeviceTest, Stop) {
Eric Shienbrood9a245532012-03-07 14:20:39 -0500419 device_->enabled_ = true;
420 device_->enabled_pending_ = true;
mukesh agrawal5c4dd0b2011-09-14 13:53:14 -0700421 device_->ipconfig_ = new IPConfig(&control_interface_, kDeviceName);
422 scoped_refptr<MockService> service(
423 new NiceMock<MockService>(&control_interface_,
424 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800425 metrics(),
mukesh agrawal5c4dd0b2011-09-14 13:53:14 -0700426 manager()));
Paul Stewart20088d82012-02-16 06:58:55 -0800427 SelectService(service);
mukesh agrawal5c4dd0b2011-09-14 13:53:14 -0700428
429 EXPECT_CALL(*service.get(), state()).
430 WillRepeatedly(Return(Service::kStateConnected));
431 EXPECT_CALL(*dynamic_cast<DeviceMockAdaptor *>(device_->adaptor_.get()),
432 UpdateEnabled());
Eric Shienbrood9a245532012-03-07 14:20:39 -0500433 EXPECT_CALL(*dynamic_cast<DeviceMockAdaptor *>(device_->adaptor_.get()),
434 EmitBoolChanged(flimflam::kPoweredProperty, false));
mukesh agrawal5c4dd0b2011-09-14 13:53:14 -0700435 EXPECT_CALL(rtnl_handler_, SetInterfaceFlags(_, 0, IFF_UP));
Eric Shienbrood9a245532012-03-07 14:20:39 -0500436 device_->SetEnabled(false);
437 device_->OnEnabledStateChanged(ResultCallback(), Error());
mukesh agrawal5c4dd0b2011-09-14 13:53:14 -0700438
439 EXPECT_FALSE(device_->ipconfig_.get());
440 EXPECT_FALSE(device_->selected_service_.get());
441}
442
Ben Chanad663e12013-01-08 01:58:47 -0800443TEST_F(DeviceTest, Reset) {
444 Error e;
445 device_->Reset(&e, ResultCallback());
446 EXPECT_EQ(Error::kNotSupported, e.type());
447 EXPECT_EQ("Device doesn't support Reset.", e.message());
448}
449
mukesh agrawal784566d2012-08-08 18:32:58 -0700450TEST_F(DeviceTest, ResumeWithIPConfig) {
451 scoped_refptr<MockIPConfig> ipconfig =
452 new MockIPConfig(control_interface(), kDeviceName);
453 device_->set_ipconfig(ipconfig);
454 EXPECT_CALL(*ipconfig, RenewIP());
455 device_->OnAfterResume();
456}
457
458TEST_F(DeviceTest, ResumeWithoutIPConfig) {
459 // Just test that we don't crash in this case.
460 ASSERT_EQ(NULL, device_->ipconfig().get());
461 device_->OnAfterResume();
462}
463
Paul Stewart036dba02012-08-07 12:34:41 -0700464TEST_F(DeviceTest, LinkMonitor) {
465 scoped_refptr<MockConnection> connection(
466 new StrictMock<MockConnection>(&device_info_));
467 MockManager manager(control_interface(),
468 dispatcher(),
469 metrics(),
470 glib());
471 scoped_refptr<MockService> service(
472 new StrictMock<MockService>(control_interface(),
473 dispatcher(),
474 metrics(),
475 &manager));
476 SelectService(service);
477 SetConnection(connection.get());
478 MockLinkMonitor *link_monitor = new StrictMock<MockLinkMonitor>();
479 SetLinkMonitor(link_monitor); // Passes ownership.
480 SetManager(&manager);
481 EXPECT_CALL(*link_monitor, Start()).Times(0);
482 EXPECT_CALL(manager, IsTechnologyLinkMonitorEnabled(Technology::kUnknown))
483 .WillOnce(Return(false))
484 .WillRepeatedly(Return(true));
485 EXPECT_FALSE(StartLinkMonitor());
486
487 EXPECT_CALL(*link_monitor, Start())
488 .WillOnce(Return(false))
489 .WillOnce(Return(true));
490 EXPECT_FALSE(StartLinkMonitor());
491 EXPECT_TRUE(StartLinkMonitor());
492
493 unsigned int kResponseTime = 123;
494 EXPECT_CALL(*link_monitor, GetResponseTimeMilliseconds())
495 .WillOnce(Return(kResponseTime));
496 {
497 Error error;
498 EXPECT_EQ(kResponseTime, GetLinkMonitorResponseTime(&error));
499 EXPECT_TRUE(error.IsSuccess());
500 }
501 StopLinkMonitor();
502 {
503 Error error;
504 EXPECT_EQ(0, GetLinkMonitorResponseTime(&error));
505 EXPECT_FALSE(error.IsSuccess());
506 }
507}
508
Paul Stewartc8860612012-09-28 07:36:21 -0700509TEST_F(DeviceTest, LinkMonitorCancelledOnSelectService) {
510 scoped_refptr<MockConnection> connection(
511 new StrictMock<MockConnection>(&device_info_));
512 MockManager manager(control_interface(),
513 dispatcher(),
514 metrics(),
515 glib());
516 scoped_refptr<MockService> service(
517 new StrictMock<MockService>(control_interface(),
518 dispatcher(),
519 metrics(),
520 &manager));
521 SelectService(service);
522 SetConnection(connection.get());
523 MockLinkMonitor *link_monitor = new StrictMock<MockLinkMonitor>();
524 SetLinkMonitor(link_monitor); // Passes ownership.
525 SetManager(&manager);
526 EXPECT_CALL(*service.get(), state())
527 .WillOnce(Return(Service::kStateIdle));
528 EXPECT_CALL(*service.get(), SetState(_));
529 EXPECT_CALL(*service.get(), SetConnection(_));
530 EXPECT_TRUE(HasLinkMonitor());
531 SelectService(NULL);
532 EXPECT_FALSE(HasLinkMonitor());
533}
534
Ben Chanb061f892013-02-27 17:46:55 -0800535TEST_F(DeviceTest, StartTrafficMonitor) {
536 MockTrafficMonitor *traffic_monitor = new StrictMock<MockTrafficMonitor>();
537 SetTrafficMonitor(traffic_monitor); // Passes ownership.
538
539 EXPECT_CALL(*traffic_monitor, Start()).Times(0);
540 EXPECT_FALSE(device_->traffic_monitor_enabled());
541 EXPECT_FALSE(StartTrafficMonitor());
542
543 device_->set_traffic_monitor_enabled(true);
544 EXPECT_CALL(*traffic_monitor, Start()).Times(1);
545 EXPECT_TRUE(device_->traffic_monitor_enabled());
546 EXPECT_TRUE(StartTrafficMonitor());
547}
548
549TEST_F(DeviceTest, StopTrafficMonitor) {
550 // Invoke Stop() without a traffic monitor set.
551 EXPECT_FALSE(device_->traffic_monitor_.get());
552 StopTrafficMonitor();
553 EXPECT_FALSE(device_->traffic_monitor_.get());
554
555 // Invoke Stop() with a traffic monitor set but without invoking Start().
556 TrafficMonitor *traffic_monitor = new TrafficMonitor(device_, dispatcher());
557 SetTrafficMonitor(traffic_monitor); // Passes ownership.
558 EXPECT_TRUE(device_->traffic_monitor_.get());
559 StopTrafficMonitor();
560 EXPECT_FALSE(device_->traffic_monitor_.get());
561
562 // Invoke Stop() with a traffic monitor set but not enabled.
563 traffic_monitor = new TrafficMonitor(device_, dispatcher());
564 SetTrafficMonitor(traffic_monitor); // Passes ownership.
565 EXPECT_FALSE(device_->traffic_monitor_enabled());
566 EXPECT_FALSE(StartTrafficMonitor());
567 EXPECT_TRUE(device_->traffic_monitor_.get());
568 StopTrafficMonitor();
569 EXPECT_FALSE(device_->traffic_monitor_.get());
570
571 // Invoke Stop() with a traffic monitor set and started.
572 device_->set_traffic_monitor_enabled(true);
573 EXPECT_TRUE(device_->traffic_monitor_enabled());
574 EXPECT_TRUE(StartTrafficMonitor());
575 EXPECT_TRUE(device_->traffic_monitor_.get());
576 StopTrafficMonitor();
577 EXPECT_FALSE(device_->traffic_monitor_.get());
578
579 // Invoke Stop() again after the traffic monitor is stopped.
580 StopTrafficMonitor();
581 EXPECT_FALSE(device_->traffic_monitor_.get());
582}
583
Paul Stewartc681fa02012-03-02 19:40:04 -0800584class DevicePortalDetectionTest : public DeviceTest {
585 public:
586 DevicePortalDetectionTest()
587 : connection_(new StrictMock<MockConnection>(&device_info_)),
588 manager_(control_interface(),
589 dispatcher(),
590 metrics(),
591 glib()),
592 service_(new StrictMock<MockService>(control_interface(),
593 dispatcher(),
594 metrics(),
595 &manager_)),
596 portal_detector_(new StrictMock<MockPortalDetector>(connection_)) {}
597 virtual ~DevicePortalDetectionTest() {}
598 virtual void SetUp() {
599 DeviceTest::SetUp();
600 SelectService(service_);
601 SetConnection(connection_.get());
602 device_->portal_detector_.reset(portal_detector_); // Passes ownership.
Paul Stewart036dba02012-08-07 12:34:41 -0700603 SetManager(&manager_);
Paul Stewartc681fa02012-03-02 19:40:04 -0800604 }
605
606 protected:
Thieu Le85e050b2012-03-13 15:04:38 -0700607 static const int kPortalAttempts;
608
Paul Stewartc681fa02012-03-02 19:40:04 -0800609 bool StartPortalDetection() { return device_->StartPortalDetection(); }
610 void StopPortalDetection() { device_->StopPortalDetection(); }
611
612 void PortalDetectorCallback(const PortalDetector::Result &result) {
613 device_->PortalDetectorCallback(result);
614 }
615 bool RequestPortalDetection() {
616 return device_->RequestPortalDetection();
617 }
618 void SetServiceConnectedState(Service::ConnectState state) {
619 device_->SetServiceConnectedState(state);
620 }
621 void ExpectPortalDetectorReset() {
622 EXPECT_FALSE(device_->portal_detector_.get());
623 }
624 void ExpectPortalDetectorSet() {
625 EXPECT_TRUE(device_->portal_detector_.get());
626 }
627 void ExpectPortalDetectorIsMock() {
628 EXPECT_EQ(portal_detector_, device_->portal_detector_.get());
629 }
630 scoped_refptr<MockConnection> connection_;
631 StrictMock<MockManager> manager_;
632 scoped_refptr<MockService> service_;
633
634 // Used only for EXPECT_CALL(). Object is owned by device.
635 MockPortalDetector *portal_detector_;
636};
637
Thieu Le85e050b2012-03-13 15:04:38 -0700638const int DevicePortalDetectionTest::kPortalAttempts = 2;
639
Paul Stewartd215af62012-04-24 23:25:50 -0700640TEST_F(DevicePortalDetectionTest, ServicePortalDetectionDisabled) {
641 EXPECT_CALL(*service_.get(), IsPortalDetectionDisabled())
642 .WillOnce(Return(true));
Paul Stewartc681fa02012-03-02 19:40:04 -0800643 EXPECT_CALL(*service_.get(), IsConnected())
Paul Stewart20088d82012-02-16 06:58:55 -0800644 .WillRepeatedly(Return(true));
Paul Stewartd215af62012-04-24 23:25:50 -0700645 EXPECT_CALL(*service_.get(), SetState(Service::kStateOnline));
646 EXPECT_FALSE(StartPortalDetection());
647}
648
649TEST_F(DevicePortalDetectionTest, TechnologyPortalDetectionDisabled) {
650 EXPECT_CALL(*service_.get(), IsPortalDetectionDisabled())
651 .WillOnce(Return(false));
652 EXPECT_CALL(*service_.get(), IsConnected())
653 .WillRepeatedly(Return(true));
654 EXPECT_CALL(*service_.get(), IsPortalDetectionAuto())
655 .WillOnce(Return(true));
Paul Stewartc681fa02012-03-02 19:40:04 -0800656 EXPECT_CALL(manager_, IsPortalDetectionEnabled(device_->technology()))
Paul Stewart20088d82012-02-16 06:58:55 -0800657 .WillOnce(Return(false));
Paul Stewartc681fa02012-03-02 19:40:04 -0800658 EXPECT_CALL(*service_.get(), SetState(Service::kStateOnline));
Paul Stewart20088d82012-02-16 06:58:55 -0800659 EXPECT_FALSE(StartPortalDetection());
660}
661
Paul Stewartc681fa02012-03-02 19:40:04 -0800662TEST_F(DevicePortalDetectionTest, PortalDetectionProxyConfig) {
Paul Stewartd215af62012-04-24 23:25:50 -0700663 EXPECT_CALL(*service_.get(), IsPortalDetectionDisabled())
664 .WillOnce(Return(false));
Paul Stewartc681fa02012-03-02 19:40:04 -0800665 EXPECT_CALL(*service_.get(), IsConnected())
Paul Stewart20088d82012-02-16 06:58:55 -0800666 .WillRepeatedly(Return(true));
Paul Stewartc681fa02012-03-02 19:40:04 -0800667 EXPECT_CALL(*service_.get(), HasProxyConfig())
Paul Stewart20088d82012-02-16 06:58:55 -0800668 .WillOnce(Return(true));
Paul Stewartd215af62012-04-24 23:25:50 -0700669 EXPECT_CALL(*service_.get(), IsPortalDetectionAuto())
670 .WillOnce(Return(true));
Paul Stewartc681fa02012-03-02 19:40:04 -0800671 EXPECT_CALL(manager_, IsPortalDetectionEnabled(device_->technology()))
Paul Stewart20088d82012-02-16 06:58:55 -0800672 .WillOnce(Return(true));
Paul Stewartc681fa02012-03-02 19:40:04 -0800673 EXPECT_CALL(*service_.get(), SetState(Service::kStateOnline));
Paul Stewart20088d82012-02-16 06:58:55 -0800674 EXPECT_FALSE(StartPortalDetection());
675}
676
Paul Stewartc681fa02012-03-02 19:40:04 -0800677TEST_F(DevicePortalDetectionTest, PortalDetectionBadUrl) {
Paul Stewartd215af62012-04-24 23:25:50 -0700678 EXPECT_CALL(*service_.get(), IsPortalDetectionDisabled())
679 .WillOnce(Return(false));
Paul Stewartc681fa02012-03-02 19:40:04 -0800680 EXPECT_CALL(*service_.get(), IsConnected())
Paul Stewart20088d82012-02-16 06:58:55 -0800681 .WillRepeatedly(Return(true));
Paul Stewartc681fa02012-03-02 19:40:04 -0800682 EXPECT_CALL(*service_.get(), HasProxyConfig())
Paul Stewart20088d82012-02-16 06:58:55 -0800683 .WillOnce(Return(false));
Paul Stewartd215af62012-04-24 23:25:50 -0700684 EXPECT_CALL(*service_.get(), IsPortalDetectionAuto())
685 .WillOnce(Return(true));
Paul Stewartc681fa02012-03-02 19:40:04 -0800686 EXPECT_CALL(manager_, IsPortalDetectionEnabled(device_->technology()))
Paul Stewart20088d82012-02-16 06:58:55 -0800687 .WillOnce(Return(true));
688 const string portal_url;
Paul Stewartc681fa02012-03-02 19:40:04 -0800689 EXPECT_CALL(manager_, GetPortalCheckURL())
Paul Stewart20088d82012-02-16 06:58:55 -0800690 .WillRepeatedly(ReturnRef(portal_url));
Paul Stewartc681fa02012-03-02 19:40:04 -0800691 EXPECT_CALL(*service_.get(), SetState(Service::kStateOnline));
Paul Stewart20088d82012-02-16 06:58:55 -0800692 EXPECT_FALSE(StartPortalDetection());
693}
694
Paul Stewartc681fa02012-03-02 19:40:04 -0800695TEST_F(DevicePortalDetectionTest, PortalDetectionStart) {
Paul Stewartd215af62012-04-24 23:25:50 -0700696 EXPECT_CALL(*service_.get(), IsPortalDetectionDisabled())
697 .WillOnce(Return(false));
Paul Stewartc681fa02012-03-02 19:40:04 -0800698 EXPECT_CALL(*service_.get(), IsConnected())
Paul Stewart20088d82012-02-16 06:58:55 -0800699 .WillRepeatedly(Return(true));
Paul Stewartc681fa02012-03-02 19:40:04 -0800700 EXPECT_CALL(*service_.get(), HasProxyConfig())
Paul Stewart20088d82012-02-16 06:58:55 -0800701 .WillOnce(Return(false));
Paul Stewartd215af62012-04-24 23:25:50 -0700702 EXPECT_CALL(*service_.get(), IsPortalDetectionAuto())
703 .WillOnce(Return(true));
Paul Stewartc681fa02012-03-02 19:40:04 -0800704 EXPECT_CALL(manager_, IsPortalDetectionEnabled(device_->technology()))
Paul Stewart20088d82012-02-16 06:58:55 -0800705 .WillOnce(Return(true));
706 const string portal_url(PortalDetector::kDefaultURL);
Paul Stewartc681fa02012-03-02 19:40:04 -0800707 EXPECT_CALL(manager_, GetPortalCheckURL())
Paul Stewart20088d82012-02-16 06:58:55 -0800708 .WillRepeatedly(ReturnRef(portal_url));
Paul Stewartc681fa02012-03-02 19:40:04 -0800709 EXPECT_CALL(*service_.get(), SetState(Service::kStateOnline))
Paul Stewart20088d82012-02-16 06:58:55 -0800710 .Times(0);
Paul Stewart20088d82012-02-16 06:58:55 -0800711 const string kInterfaceName("int0");
Paul Stewartc681fa02012-03-02 19:40:04 -0800712 EXPECT_CALL(*connection_.get(), interface_name())
713 .WillRepeatedly(ReturnRef(kInterfaceName));
Paul Stewart20088d82012-02-16 06:58:55 -0800714 const vector<string> kDNSServers;
Paul Stewartc681fa02012-03-02 19:40:04 -0800715 EXPECT_CALL(*connection_.get(), dns_servers())
716 .WillRepeatedly(ReturnRef(kDNSServers));
Paul Stewart20088d82012-02-16 06:58:55 -0800717 EXPECT_TRUE(StartPortalDetection());
718
719 // Drop all references to device_info before it falls out of scope.
720 SetConnection(NULL);
721 StopPortalDetection();
722}
723
Paul Stewartc681fa02012-03-02 19:40:04 -0800724TEST_F(DevicePortalDetectionTest, PortalDetectionNonFinal) {
725 EXPECT_CALL(*service_.get(), IsConnected())
Paul Stewart20088d82012-02-16 06:58:55 -0800726 .Times(0);
Paul Stewartc681fa02012-03-02 19:40:04 -0800727 EXPECT_CALL(*service_.get(), SetState(_))
Paul Stewart20088d82012-02-16 06:58:55 -0800728 .Times(0);
Paul Stewart20088d82012-02-16 06:58:55 -0800729 PortalDetectorCallback(PortalDetector::Result(
730 PortalDetector::kPhaseUnknown,
731 PortalDetector::kStatusFailure,
Thieu Le85e050b2012-03-13 15:04:38 -0700732 kPortalAttempts,
Paul Stewart20088d82012-02-16 06:58:55 -0800733 false));
734}
735
Paul Stewartc681fa02012-03-02 19:40:04 -0800736TEST_F(DevicePortalDetectionTest, PortalDetectionFailure) {
737 EXPECT_CALL(*service_.get(), IsConnected())
Paul Stewart20088d82012-02-16 06:58:55 -0800738 .WillOnce(Return(true));
Paul Stewartc681fa02012-03-02 19:40:04 -0800739 EXPECT_CALL(*service_.get(), SetState(Service::kStatePortal));
Thieu Le85e050b2012-03-13 15:04:38 -0700740 EXPECT_CALL(metrics_,
741 SendEnumToUMA("Network.Shill.Unknown.PortalResult",
742 Metrics::kPortalResultConnectionFailure,
743 Metrics::kPortalResultMax));
744 EXPECT_CALL(metrics_,
745 SendToUMA("Network.Shill.Unknown.PortalAttemptsToOnline",
746 _, _, _, _)).Times(0);
747 EXPECT_CALL(metrics_,
748 SendToUMA("Network.Shill.Unknown.PortalAttempts",
749 kPortalAttempts,
750 Metrics::kMetricPortalAttemptsMin,
751 Metrics::kMetricPortalAttemptsMax,
752 Metrics::kMetricPortalAttemptsNumBuckets));
Paul Stewartc681fa02012-03-02 19:40:04 -0800753 EXPECT_CALL(*connection_.get(), is_default())
754 .WillOnce(Return(false));
Paul Stewart20088d82012-02-16 06:58:55 -0800755 PortalDetectorCallback(PortalDetector::Result(
Thieu Le85e050b2012-03-13 15:04:38 -0700756 PortalDetector::kPhaseConnection,
Paul Stewart20088d82012-02-16 06:58:55 -0800757 PortalDetector::kStatusFailure,
Thieu Le85e050b2012-03-13 15:04:38 -0700758 kPortalAttempts,
Paul Stewart20088d82012-02-16 06:58:55 -0800759 true));
760}
761
Paul Stewartc681fa02012-03-02 19:40:04 -0800762TEST_F(DevicePortalDetectionTest, PortalDetectionSuccess) {
763 EXPECT_CALL(*service_.get(), IsConnected())
Paul Stewart20088d82012-02-16 06:58:55 -0800764 .WillOnce(Return(true));
Paul Stewartc681fa02012-03-02 19:40:04 -0800765 EXPECT_CALL(*service_.get(), SetState(Service::kStateOnline));
Thieu Le85e050b2012-03-13 15:04:38 -0700766 EXPECT_CALL(metrics_,
767 SendEnumToUMA("Network.Shill.Unknown.PortalResult",
768 Metrics::kPortalResultSuccess,
769 Metrics::kPortalResultMax));
770 EXPECT_CALL(metrics_,
771 SendToUMA("Network.Shill.Unknown.PortalAttemptsToOnline",
772 kPortalAttempts,
773 Metrics::kMetricPortalAttemptsToOnlineMin,
774 Metrics::kMetricPortalAttemptsToOnlineMax,
775 Metrics::kMetricPortalAttemptsToOnlineNumBuckets));
776 EXPECT_CALL(metrics_,
777 SendToUMA("Network.Shill.Unknown.PortalAttempts",
778 _, _, _, _)).Times(0);
Paul Stewart20088d82012-02-16 06:58:55 -0800779 PortalDetectorCallback(PortalDetector::Result(
Thieu Le85e050b2012-03-13 15:04:38 -0700780 PortalDetector::kPhaseContent,
Paul Stewart20088d82012-02-16 06:58:55 -0800781 PortalDetector::kStatusSuccess,
Thieu Le85e050b2012-03-13 15:04:38 -0700782 kPortalAttempts,
783 true));
784}
785
786TEST_F(DevicePortalDetectionTest, PortalDetectionSuccessAfterFailure) {
787 EXPECT_CALL(*service_.get(), IsConnected())
788 .WillRepeatedly(Return(true));
789 EXPECT_CALL(*service_.get(), SetState(Service::kStatePortal));
790 EXPECT_CALL(metrics_,
791 SendEnumToUMA("Network.Shill.Unknown.PortalResult",
792 Metrics::kPortalResultConnectionFailure,
793 Metrics::kPortalResultMax));
794 EXPECT_CALL(metrics_,
795 SendToUMA("Network.Shill.Unknown.PortalAttemptsToOnline",
796 _, _, _, _)).Times(0);
797 EXPECT_CALL(metrics_,
798 SendToUMA("Network.Shill.Unknown.PortalAttempts",
799 kPortalAttempts,
800 Metrics::kMetricPortalAttemptsMin,
801 Metrics::kMetricPortalAttemptsMax,
802 Metrics::kMetricPortalAttemptsNumBuckets));
803 EXPECT_CALL(*connection_.get(), is_default())
804 .WillOnce(Return(false));
805 PortalDetectorCallback(PortalDetector::Result(
806 PortalDetector::kPhaseConnection,
807 PortalDetector::kStatusFailure,
808 kPortalAttempts,
809 true));
810 Mock::VerifyAndClearExpectations(&metrics_);
811
812 EXPECT_CALL(*service_.get(), SetState(Service::kStateOnline));
813 EXPECT_CALL(metrics_,
814 SendEnumToUMA("Network.Shill.Unknown.PortalResult",
815 Metrics::kPortalResultSuccess,
816 Metrics::kPortalResultMax));
817 EXPECT_CALL(metrics_,
818 SendToUMA("Network.Shill.Unknown.PortalAttemptsToOnline",
819 kPortalAttempts * 2,
820 Metrics::kMetricPortalAttemptsToOnlineMin,
821 Metrics::kMetricPortalAttemptsToOnlineMax,
822 Metrics::kMetricPortalAttemptsToOnlineNumBuckets));
823 EXPECT_CALL(metrics_,
824 SendToUMA("Network.Shill.Unknown.PortalAttempts",
825 _, _, _, _)).Times(0);
826 PortalDetectorCallback(PortalDetector::Result(
827 PortalDetector::kPhaseContent,
828 PortalDetector::kStatusSuccess,
829 kPortalAttempts,
Paul Stewart20088d82012-02-16 06:58:55 -0800830 true));
831}
832
Paul Stewartc681fa02012-03-02 19:40:04 -0800833TEST_F(DevicePortalDetectionTest, RequestPortalDetection) {
834 EXPECT_CALL(*service_.get(), state())
835 .WillOnce(Return(Service::kStateOnline))
836 .WillRepeatedly(Return(Service::kStatePortal));
837 EXPECT_FALSE(RequestPortalDetection());
838
839 EXPECT_CALL(*connection_.get(), is_default())
840 .WillOnce(Return(false))
841 .WillRepeatedly(Return(true));
842 EXPECT_FALSE(RequestPortalDetection());
843
844 EXPECT_CALL(*portal_detector_, IsInProgress())
845 .WillOnce(Return(true));
846 // Portal detection already running.
847 EXPECT_TRUE(RequestPortalDetection());
848
849 // Make sure our running mock portal detector was not replaced.
850 ExpectPortalDetectorIsMock();
851
852 // Throw away our pre-fabricated portal detector, and have the device create
853 // a new one.
854 StopPortalDetection();
Paul Stewartd215af62012-04-24 23:25:50 -0700855 EXPECT_CALL(*service_.get(), IsPortalDetectionDisabled())
856 .WillRepeatedly(Return(false));
857 EXPECT_CALL(*service_.get(), IsPortalDetectionAuto())
858 .WillRepeatedly(Return(true));
Paul Stewartc681fa02012-03-02 19:40:04 -0800859 EXPECT_CALL(manager_, IsPortalDetectionEnabled(device_->technology()))
860 .WillRepeatedly(Return(true));
861 EXPECT_CALL(*service_.get(), HasProxyConfig())
862 .WillRepeatedly(Return(false));
863 const string kPortalCheckURL("http://portal");
864 EXPECT_CALL(manager_, GetPortalCheckURL())
865 .WillOnce(ReturnRef(kPortalCheckURL));
866 const string kInterfaceName("int0");
867 EXPECT_CALL(*connection_.get(), interface_name())
868 .WillRepeatedly(ReturnRef(kInterfaceName));
869 const vector<string> kDNSServers;
870 EXPECT_CALL(*connection_.get(), dns_servers())
871 .WillRepeatedly(ReturnRef(kDNSServers));
872 EXPECT_TRUE(RequestPortalDetection());
873}
874
875TEST_F(DevicePortalDetectionTest, NotConnected) {
876 EXPECT_CALL(*service_.get(), IsConnected())
877 .WillOnce(Return(false));
878 SetServiceConnectedState(Service::kStatePortal);
879 // We don't check for the portal detector to be reset here, because
880 // it would have been reset as a part of disconnection.
881}
882
883TEST_F(DevicePortalDetectionTest, NotPortal) {
884 EXPECT_CALL(*service_.get(), IsConnected())
885 .WillOnce(Return(true));
886 EXPECT_CALL(*service_.get(), SetState(Service::kStateOnline));
887 SetServiceConnectedState(Service::kStateOnline);
888 ExpectPortalDetectorReset();
889}
890
891TEST_F(DevicePortalDetectionTest, NotDefault) {
892 EXPECT_CALL(*service_.get(), IsConnected())
893 .WillOnce(Return(true));
894 EXPECT_CALL(*connection_.get(), is_default())
895 .WillOnce(Return(false));
896 EXPECT_CALL(*service_.get(), SetState(Service::kStatePortal));
897 SetServiceConnectedState(Service::kStatePortal);
898 ExpectPortalDetectorReset();
899}
900
901TEST_F(DevicePortalDetectionTest, PortalIntervalIsZero) {
902 EXPECT_CALL(*service_.get(), IsConnected())
903 .WillOnce(Return(true));
904 EXPECT_CALL(*connection_.get(), is_default())
905 .WillOnce(Return(true));
906 EXPECT_CALL(manager_, GetPortalCheckInterval())
907 .WillOnce(Return(0));
908 EXPECT_CALL(*service_.get(), SetState(Service::kStatePortal));
909 SetServiceConnectedState(Service::kStatePortal);
910 ExpectPortalDetectorReset();
911}
912
913TEST_F(DevicePortalDetectionTest, RestartPortalDetection) {
914 EXPECT_CALL(*service_.get(), IsConnected())
915 .WillOnce(Return(true));
916 EXPECT_CALL(*connection_.get(), is_default())
917 .WillOnce(Return(true));
918 const int kPortalDetectionInterval = 10;
919 EXPECT_CALL(manager_, GetPortalCheckInterval())
920 .Times(AtLeast(1))
921 .WillRepeatedly(Return(kPortalDetectionInterval));
922 const string kPortalCheckURL("http://portal");
923 EXPECT_CALL(manager_, GetPortalCheckURL())
924 .WillOnce(ReturnRef(kPortalCheckURL));
925 EXPECT_CALL(*portal_detector_, StartAfterDelay(kPortalCheckURL,
926 kPortalDetectionInterval))
927 .WillOnce(Return(true));
928 EXPECT_CALL(*service_.get(), SetState(Service::kStatePortal));
929 SetServiceConnectedState(Service::kStatePortal);
930 ExpectPortalDetectorSet();
931}
932
Paul Stewartc8860612012-09-28 07:36:21 -0700933TEST_F(DevicePortalDetectionTest, CancelledOnSelectService) {
934 ExpectPortalDetectorSet();
935 EXPECT_CALL(*service_.get(), state())
936 .WillOnce(Return(Service::kStateIdle));
937 EXPECT_CALL(*service_.get(), SetState(_));
938 EXPECT_CALL(*service_.get(), SetConnection(_));
939 SelectService(NULL);
940 ExpectPortalDetectorReset();
941}
942
Paul Stewart6ff27f52012-07-11 06:51:41 -0700943class DeviceByteCountTest : public DeviceTest {
944 public:
945 DeviceByteCountTest()
946 : manager_(control_interface(),
947 dispatcher(),
948 metrics(),
949 glib()),
950 rx_byte_count_(0),
951 tx_byte_count_(0),
952 rx_stored_byte_count_(0),
953 tx_stored_byte_count_(0) {}
954 virtual ~DeviceByteCountTest() {}
955
956 virtual void SetUp() {
957 DeviceTest::SetUp();
958 EXPECT_CALL(manager_, device_info()).WillRepeatedly(Return(&device_info_));
959 EXPECT_CALL(device_info_, GetByteCounts(kDeviceInterfaceIndex, _, _))
960 .WillRepeatedly(Invoke(this, &DeviceByteCountTest::ReturnByteCounts));
961 const string id = device_->GetStorageIdentifier();
962 EXPECT_CALL(storage_, ContainsGroup(id)).WillRepeatedly(Return(true));
963 EXPECT_CALL(storage_, GetUint64(id, Device::kStorageReceiveByteCount, _))
964 .WillRepeatedly(
965 Invoke(this, &DeviceByteCountTest::GetStoredReceiveCount));
966 EXPECT_CALL(storage_, GetUint64(id, Device::kStorageTransmitByteCount, _))
967 .WillRepeatedly(
968 Invoke(this, &DeviceByteCountTest::GetStoredTransmitCount));
969 }
970
971 bool ReturnByteCounts(int interface_index, uint64 *rx, uint64 *tx) {
972 *rx = rx_byte_count_;
973 *tx = tx_byte_count_;
974 return true;
975 }
976
977 bool ExpectByteCounts(DeviceRefPtr device,
978 int64 expected_rx, int64 expected_tx) {
Ben Chanb061f892013-02-27 17:46:55 -0800979 int64 actual_rx = device->GetReceiveByteCount();
980 int64 actual_tx = device->GetTransmitByteCount();
Paul Stewart6ff27f52012-07-11 06:51:41 -0700981 EXPECT_EQ(expected_rx, actual_rx);
982 EXPECT_EQ(expected_tx, actual_tx);
983 return expected_rx == actual_rx && expected_tx == actual_tx;
984 }
985
986 void ExpectSavedCounts(DeviceRefPtr device,
987 int64 expected_rx, int64 expected_tx) {
988 EXPECT_CALL(storage_,
989 SetUint64(_, Device::kStorageReceiveByteCount, expected_rx))
990 .WillOnce(Return(true));
991 EXPECT_CALL(storage_,
992 SetUint64(_, Device::kStorageTransmitByteCount, expected_tx))
993 .WillOnce(Return(true));
994 EXPECT_TRUE(device->Save(&storage_));
995 }
996
997
998 bool GetStoredReceiveCount(const string &group, const string &key,
999 uint64 *value) {
1000 if (!rx_stored_byte_count_) {
1001 return false;
1002 }
1003 *value = rx_stored_byte_count_;
1004 return true;
1005 }
1006
1007 bool GetStoredTransmitCount(const string &group, const string &key,
1008 uint64 *value) {
1009 if (!tx_stored_byte_count_) {
1010 return false;
1011 }
1012 *value = tx_stored_byte_count_;
1013 return true;
1014 }
1015
1016 protected:
1017 NiceMock<MockManager> manager_;
1018 NiceMock<MockStore> storage_;
1019 uint64 rx_byte_count_;
1020 uint64 tx_byte_count_;
1021 uint64 rx_stored_byte_count_;
1022 uint64 tx_stored_byte_count_;
1023};
1024
1025
1026TEST_F(DeviceByteCountTest, GetByteCounts) {
1027 // On Device initialization, byte counts should be zero, independent of
1028 // the byte counts reported by the interface.
1029 rx_byte_count_ = 123;
1030 tx_byte_count_ = 456;
1031 DeviceRefPtr device(new TestDevice(control_interface(),
1032 dispatcher(),
1033 NULL,
1034 &manager_,
1035 kDeviceName,
1036 kDeviceAddress,
1037 kDeviceInterfaceIndex,
1038 Technology::kUnknown));
1039 EXPECT_TRUE(ExpectByteCounts(device, 0, 0));
1040
1041 // Device should report any increase in the byte counts reported in the
1042 // interface.
1043 const int64 delta_rx_count = 789;
1044 const int64 delta_tx_count = 12;
1045 rx_byte_count_ += delta_rx_count;
1046 tx_byte_count_ += delta_tx_count;
1047 EXPECT_TRUE(ExpectByteCounts(device, delta_rx_count, delta_tx_count));
1048
1049 // Expect the correct values to be saved to the profile.
1050 ExpectSavedCounts(device, delta_rx_count, delta_tx_count);
1051
1052 // If Device is loaded from a profile that does not contain stored byte
1053 // counts, the byte counts reported should remain unchanged.
1054 EXPECT_TRUE(device->Load(&storage_));
1055 EXPECT_TRUE(ExpectByteCounts(device, delta_rx_count, delta_tx_count));
1056
1057 // If Device is loaded from a profile that contains stored byte
1058 // counts, the byte counts reported should now reflect the stored values.
1059 rx_stored_byte_count_ = 345;
1060 tx_stored_byte_count_ = 678;
1061 EXPECT_TRUE(device->Load(&storage_));
1062 EXPECT_TRUE(ExpectByteCounts(
1063 device, rx_stored_byte_count_, tx_stored_byte_count_));
1064
1065 // Increases to the interface receive count should be reflected as offsets
1066 // to the stored byte counts.
1067 rx_byte_count_ += delta_rx_count;
1068 tx_byte_count_ += delta_tx_count;
1069 EXPECT_TRUE(ExpectByteCounts(device,
1070 rx_stored_byte_count_ + delta_rx_count,
1071 tx_stored_byte_count_ + delta_tx_count));
1072
1073 // Expect the correct values to be saved to the profile.
1074 ExpectSavedCounts(device,
1075 rx_stored_byte_count_ + delta_rx_count,
1076 tx_stored_byte_count_ + delta_tx_count);
1077
1078 // Expect that after resetting byte counts, read-back values return to zero,
1079 // and that the device requests this information to be persisted.
1080 EXPECT_CALL(manager_, UpdateDevice(device));
1081 device->ResetByteCounters();
1082 EXPECT_TRUE(ExpectByteCounts(device, 0, 0));
1083}
1084
Arman Ugurayf84a4242013-04-09 20:01:07 -07001085class DeviceHealthCheckerTest : public DeviceTest {
1086 public:
1087 DeviceHealthCheckerTest()
1088 : connection_(new StrictMock<MockConnection>(&device_info_)),
Prathmesh Prabhuba99b592013-04-17 15:13:14 -07001089 ip_address_store_(new MockIPAddressStore()),
Arman Ugurayf84a4242013-04-09 20:01:07 -07001090 weak_ptr_factory_(this) {}
1091
1092 protected:
1093 void SetUp() {
1094 DeviceTest::SetUp();
1095
1096 string default_str;
1097 vector<string> default_vector;
1098
1099 ON_CALL(*connection_.get(), interface_name())
1100 .WillByDefault(ReturnRef(default_str));
1101 ON_CALL(*connection_.get(), dns_servers())
1102 .WillByDefault(ReturnRef(default_vector));
1103 EXPECT_CALL(*connection_.get(), interface_name())
1104 .Times(AnyNumber());
1105 EXPECT_CALL(*connection_.get(), dns_servers())
1106 .Times(AnyNumber());
Prathmesh Prabhuba99b592013-04-17 15:13:14 -07001107 EXPECT_CALL(*ip_address_store_.get(), AddUnique(_)).Times(AnyNumber());
Arman Ugurayf84a4242013-04-09 20:01:07 -07001108
1109 mock_health_checker_.reset(
1110 new MockConnectionHealthChecker(
1111 connection_,
1112 NULL,
Prathmesh Prabhuba99b592013-04-17 15:13:14 -07001113 ip_address_store_.get(),
Arman Ugurayf84a4242013-04-09 20:01:07 -07001114 Bind(&DeviceHealthCheckerTest::OnConnectionHealthCheckerResult,
1115 weak_ptr_factory_.GetWeakPtr())));
1116 }
1117
1118 void SetMockHealthChecker() {
1119 device_->set_health_checker(mock_health_checker_.release());
1120 EXPECT_TRUE(device_->health_checker_.get());
1121 }
1122
Prathmesh Prabhuba99b592013-04-17 15:13:14 -07001123 void SetMockConnection() {
1124 device_->connection_ = connection_;
1125 }
1126
Arman Ugurayf84a4242013-04-09 20:01:07 -07001127 void OnConnectionHealthCheckerResult(
1128 ConnectionHealthChecker::Result result) {
1129 }
1130
1131 scoped_refptr<MockConnection> connection_;
1132 scoped_ptr<MockConnectionHealthChecker> mock_health_checker_;
Prathmesh Prabhuba99b592013-04-17 15:13:14 -07001133 scoped_ptr<MockIPAddressStore> ip_address_store_;
Arman Ugurayf84a4242013-04-09 20:01:07 -07001134 base::WeakPtrFactory<DeviceHealthCheckerTest> weak_ptr_factory_;
1135};
1136
Arman Ugurayf84a4242013-04-09 20:01:07 -07001137TEST_F(DeviceHealthCheckerTest, RequestConnectionHealthCheck) {
1138 EXPECT_FALSE(device_->health_checker_.get());
1139 MockConnectionHealthChecker *health_checker = mock_health_checker_.get();
1140 SetMockHealthChecker();
Arman Ugurayf84a4242013-04-09 20:01:07 -07001141 EXPECT_CALL(*health_checker, health_check_in_progress())
Arman Ugurayf84a4242013-04-09 20:01:07 -07001142 .WillOnce(Return(true));
Prathmesh Prabhuade9b9a2013-04-22 18:01:19 -07001143 EXPECT_CALL(*health_checker, Start()).Times(0);
Arman Ugurayf84a4242013-04-09 20:01:07 -07001144 device_->RequestConnectionHealthCheck();
1145 Mock::VerifyAndClearExpectations(health_checker);
1146
Arman Ugurayf84a4242013-04-09 20:01:07 -07001147 EXPECT_CALL(*health_checker, health_check_in_progress())
Arman Ugurayf84a4242013-04-09 20:01:07 -07001148 .WillOnce(Return(false));
Prathmesh Prabhuade9b9a2013-04-22 18:01:19 -07001149 EXPECT_CALL(*health_checker, Start()).Times(1);
Arman Ugurayf84a4242013-04-09 20:01:07 -07001150 device_->RequestConnectionHealthCheck();
1151 Mock::VerifyAndClearExpectations(health_checker);
1152}
1153
Darin Petkovafa6fc42011-06-21 16:21:08 -07001154} // namespace shill