blob: f127bd5000827310edb68dfcca695389dd86c259 [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()),
Eric Shienbrood9a245532012-03-07 14:20:39 -0500432 EmitBoolChanged(flimflam::kPoweredProperty, false));
mukesh agrawal5c4dd0b2011-09-14 13:53:14 -0700433 EXPECT_CALL(rtnl_handler_, SetInterfaceFlags(_, 0, IFF_UP));
Eric Shienbrood9a245532012-03-07 14:20:39 -0500434 device_->SetEnabled(false);
435 device_->OnEnabledStateChanged(ResultCallback(), Error());
mukesh agrawal5c4dd0b2011-09-14 13:53:14 -0700436
437 EXPECT_FALSE(device_->ipconfig_.get());
438 EXPECT_FALSE(device_->selected_service_.get());
439}
440
Ben Chanad663e12013-01-08 01:58:47 -0800441TEST_F(DeviceTest, Reset) {
442 Error e;
443 device_->Reset(&e, ResultCallback());
444 EXPECT_EQ(Error::kNotSupported, e.type());
445 EXPECT_EQ("Device doesn't support Reset.", e.message());
446}
447
mukesh agrawal784566d2012-08-08 18:32:58 -0700448TEST_F(DeviceTest, ResumeWithIPConfig) {
449 scoped_refptr<MockIPConfig> ipconfig =
450 new MockIPConfig(control_interface(), kDeviceName);
451 device_->set_ipconfig(ipconfig);
452 EXPECT_CALL(*ipconfig, RenewIP());
453 device_->OnAfterResume();
454}
455
456TEST_F(DeviceTest, ResumeWithoutIPConfig) {
457 // Just test that we don't crash in this case.
458 ASSERT_EQ(NULL, device_->ipconfig().get());
459 device_->OnAfterResume();
460}
461
mukesh agrawalbb2231c2013-07-17 16:32:24 -0700462TEST_F(DeviceTest, ResumeWithLinkMonitor) {
463 MockLinkMonitor *link_monitor = new StrictMock<MockLinkMonitor>();
464 SetLinkMonitor(link_monitor); // Passes ownership.
465 EXPECT_CALL(*link_monitor, OnAfterResume());
466 device_->OnAfterResume();
467}
468
469TEST_F(DeviceTest, ResumeWithoutLinkMonitor) {
470 // Just test that we don't crash in this case.
471 EXPECT_FALSE(HasLinkMonitor());
472 device_->OnAfterResume();
473}
474
Paul Stewart036dba02012-08-07 12:34:41 -0700475TEST_F(DeviceTest, LinkMonitor) {
476 scoped_refptr<MockConnection> connection(
477 new StrictMock<MockConnection>(&device_info_));
478 MockManager manager(control_interface(),
479 dispatcher(),
480 metrics(),
481 glib());
482 scoped_refptr<MockService> service(
483 new StrictMock<MockService>(control_interface(),
484 dispatcher(),
485 metrics(),
486 &manager));
487 SelectService(service);
488 SetConnection(connection.get());
489 MockLinkMonitor *link_monitor = new StrictMock<MockLinkMonitor>();
490 SetLinkMonitor(link_monitor); // Passes ownership.
491 SetManager(&manager);
492 EXPECT_CALL(*link_monitor, Start()).Times(0);
493 EXPECT_CALL(manager, IsTechnologyLinkMonitorEnabled(Technology::kUnknown))
494 .WillOnce(Return(false))
495 .WillRepeatedly(Return(true));
496 EXPECT_FALSE(StartLinkMonitor());
497
498 EXPECT_CALL(*link_monitor, Start())
499 .WillOnce(Return(false))
500 .WillOnce(Return(true));
501 EXPECT_FALSE(StartLinkMonitor());
502 EXPECT_TRUE(StartLinkMonitor());
503
504 unsigned int kResponseTime = 123;
505 EXPECT_CALL(*link_monitor, GetResponseTimeMilliseconds())
506 .WillOnce(Return(kResponseTime));
507 {
508 Error error;
509 EXPECT_EQ(kResponseTime, GetLinkMonitorResponseTime(&error));
510 EXPECT_TRUE(error.IsSuccess());
511 }
512 StopLinkMonitor();
513 {
514 Error error;
515 EXPECT_EQ(0, GetLinkMonitorResponseTime(&error));
516 EXPECT_FALSE(error.IsSuccess());
517 }
518}
519
Paul Stewartc8860612012-09-28 07:36:21 -0700520TEST_F(DeviceTest, LinkMonitorCancelledOnSelectService) {
521 scoped_refptr<MockConnection> connection(
522 new StrictMock<MockConnection>(&device_info_));
523 MockManager manager(control_interface(),
524 dispatcher(),
525 metrics(),
526 glib());
527 scoped_refptr<MockService> service(
528 new StrictMock<MockService>(control_interface(),
529 dispatcher(),
530 metrics(),
531 &manager));
532 SelectService(service);
533 SetConnection(connection.get());
534 MockLinkMonitor *link_monitor = new StrictMock<MockLinkMonitor>();
535 SetLinkMonitor(link_monitor); // Passes ownership.
536 SetManager(&manager);
537 EXPECT_CALL(*service.get(), state())
538 .WillOnce(Return(Service::kStateIdle));
539 EXPECT_CALL(*service.get(), SetState(_));
540 EXPECT_CALL(*service.get(), SetConnection(_));
541 EXPECT_TRUE(HasLinkMonitor());
542 SelectService(NULL);
543 EXPECT_FALSE(HasLinkMonitor());
544}
545
Ben Chanb061f892013-02-27 17:46:55 -0800546TEST_F(DeviceTest, StartTrafficMonitor) {
547 MockTrafficMonitor *traffic_monitor = new StrictMock<MockTrafficMonitor>();
548 SetTrafficMonitor(traffic_monitor); // Passes ownership.
549
550 EXPECT_CALL(*traffic_monitor, Start()).Times(0);
551 EXPECT_FALSE(device_->traffic_monitor_enabled());
552 EXPECT_FALSE(StartTrafficMonitor());
553
554 device_->set_traffic_monitor_enabled(true);
555 EXPECT_CALL(*traffic_monitor, Start()).Times(1);
556 EXPECT_TRUE(device_->traffic_monitor_enabled());
557 EXPECT_TRUE(StartTrafficMonitor());
558}
559
560TEST_F(DeviceTest, StopTrafficMonitor) {
561 // Invoke Stop() without a traffic monitor set.
562 EXPECT_FALSE(device_->traffic_monitor_.get());
563 StopTrafficMonitor();
564 EXPECT_FALSE(device_->traffic_monitor_.get());
565
566 // Invoke Stop() with a traffic monitor set but without invoking Start().
567 TrafficMonitor *traffic_monitor = new TrafficMonitor(device_, dispatcher());
568 SetTrafficMonitor(traffic_monitor); // Passes ownership.
569 EXPECT_TRUE(device_->traffic_monitor_.get());
570 StopTrafficMonitor();
571 EXPECT_FALSE(device_->traffic_monitor_.get());
572
573 // Invoke Stop() with a traffic monitor set but not enabled.
574 traffic_monitor = new TrafficMonitor(device_, dispatcher());
575 SetTrafficMonitor(traffic_monitor); // Passes ownership.
576 EXPECT_FALSE(device_->traffic_monitor_enabled());
577 EXPECT_FALSE(StartTrafficMonitor());
578 EXPECT_TRUE(device_->traffic_monitor_.get());
579 StopTrafficMonitor();
580 EXPECT_FALSE(device_->traffic_monitor_.get());
581
582 // Invoke Stop() with a traffic monitor set and started.
583 device_->set_traffic_monitor_enabled(true);
584 EXPECT_TRUE(device_->traffic_monitor_enabled());
585 EXPECT_TRUE(StartTrafficMonitor());
586 EXPECT_TRUE(device_->traffic_monitor_.get());
587 StopTrafficMonitor();
588 EXPECT_FALSE(device_->traffic_monitor_.get());
589
590 // Invoke Stop() again after the traffic monitor is stopped.
591 StopTrafficMonitor();
592 EXPECT_FALSE(device_->traffic_monitor_.get());
593}
594
Paul Stewartc681fa02012-03-02 19:40:04 -0800595class DevicePortalDetectionTest : public DeviceTest {
596 public:
597 DevicePortalDetectionTest()
598 : connection_(new StrictMock<MockConnection>(&device_info_)),
599 manager_(control_interface(),
600 dispatcher(),
601 metrics(),
602 glib()),
603 service_(new StrictMock<MockService>(control_interface(),
604 dispatcher(),
605 metrics(),
606 &manager_)),
607 portal_detector_(new StrictMock<MockPortalDetector>(connection_)) {}
608 virtual ~DevicePortalDetectionTest() {}
609 virtual void SetUp() {
610 DeviceTest::SetUp();
611 SelectService(service_);
612 SetConnection(connection_.get());
613 device_->portal_detector_.reset(portal_detector_); // Passes ownership.
Paul Stewart036dba02012-08-07 12:34:41 -0700614 SetManager(&manager_);
Paul Stewartc681fa02012-03-02 19:40:04 -0800615 }
616
617 protected:
Thieu Le85e050b2012-03-13 15:04:38 -0700618 static const int kPortalAttempts;
619
Paul Stewartc681fa02012-03-02 19:40:04 -0800620 bool StartPortalDetection() { return device_->StartPortalDetection(); }
621 void StopPortalDetection() { device_->StopPortalDetection(); }
622
623 void PortalDetectorCallback(const PortalDetector::Result &result) {
624 device_->PortalDetectorCallback(result);
625 }
626 bool RequestPortalDetection() {
627 return device_->RequestPortalDetection();
628 }
629 void SetServiceConnectedState(Service::ConnectState state) {
630 device_->SetServiceConnectedState(state);
631 }
632 void ExpectPortalDetectorReset() {
633 EXPECT_FALSE(device_->portal_detector_.get());
634 }
635 void ExpectPortalDetectorSet() {
636 EXPECT_TRUE(device_->portal_detector_.get());
637 }
638 void ExpectPortalDetectorIsMock() {
639 EXPECT_EQ(portal_detector_, device_->portal_detector_.get());
640 }
641 scoped_refptr<MockConnection> connection_;
642 StrictMock<MockManager> manager_;
643 scoped_refptr<MockService> service_;
644
645 // Used only for EXPECT_CALL(). Object is owned by device.
646 MockPortalDetector *portal_detector_;
647};
648
Thieu Le85e050b2012-03-13 15:04:38 -0700649const int DevicePortalDetectionTest::kPortalAttempts = 2;
650
Paul Stewartd215af62012-04-24 23:25:50 -0700651TEST_F(DevicePortalDetectionTest, ServicePortalDetectionDisabled) {
652 EXPECT_CALL(*service_.get(), IsPortalDetectionDisabled())
653 .WillOnce(Return(true));
Paul Stewartc681fa02012-03-02 19:40:04 -0800654 EXPECT_CALL(*service_.get(), IsConnected())
Paul Stewart20088d82012-02-16 06:58:55 -0800655 .WillRepeatedly(Return(true));
Paul Stewartd215af62012-04-24 23:25:50 -0700656 EXPECT_CALL(*service_.get(), SetState(Service::kStateOnline));
657 EXPECT_FALSE(StartPortalDetection());
658}
659
660TEST_F(DevicePortalDetectionTest, TechnologyPortalDetectionDisabled) {
661 EXPECT_CALL(*service_.get(), IsPortalDetectionDisabled())
662 .WillOnce(Return(false));
663 EXPECT_CALL(*service_.get(), IsConnected())
664 .WillRepeatedly(Return(true));
665 EXPECT_CALL(*service_.get(), IsPortalDetectionAuto())
666 .WillOnce(Return(true));
Paul Stewartc681fa02012-03-02 19:40:04 -0800667 EXPECT_CALL(manager_, IsPortalDetectionEnabled(device_->technology()))
Paul Stewart20088d82012-02-16 06:58:55 -0800668 .WillOnce(Return(false));
Paul Stewartc681fa02012-03-02 19:40:04 -0800669 EXPECT_CALL(*service_.get(), SetState(Service::kStateOnline));
Paul Stewart20088d82012-02-16 06:58:55 -0800670 EXPECT_FALSE(StartPortalDetection());
671}
672
Paul Stewartc681fa02012-03-02 19:40:04 -0800673TEST_F(DevicePortalDetectionTest, PortalDetectionProxyConfig) {
Paul Stewartd215af62012-04-24 23:25:50 -0700674 EXPECT_CALL(*service_.get(), IsPortalDetectionDisabled())
675 .WillOnce(Return(false));
Paul Stewartc681fa02012-03-02 19:40:04 -0800676 EXPECT_CALL(*service_.get(), IsConnected())
Paul Stewart20088d82012-02-16 06:58:55 -0800677 .WillRepeatedly(Return(true));
Paul Stewartc681fa02012-03-02 19:40:04 -0800678 EXPECT_CALL(*service_.get(), HasProxyConfig())
Paul Stewart20088d82012-02-16 06:58:55 -0800679 .WillOnce(Return(true));
Paul Stewartd215af62012-04-24 23:25:50 -0700680 EXPECT_CALL(*service_.get(), IsPortalDetectionAuto())
681 .WillOnce(Return(true));
Paul Stewartc681fa02012-03-02 19:40:04 -0800682 EXPECT_CALL(manager_, IsPortalDetectionEnabled(device_->technology()))
Paul Stewart20088d82012-02-16 06:58:55 -0800683 .WillOnce(Return(true));
Paul Stewartc681fa02012-03-02 19:40:04 -0800684 EXPECT_CALL(*service_.get(), SetState(Service::kStateOnline));
Paul Stewart20088d82012-02-16 06:58:55 -0800685 EXPECT_FALSE(StartPortalDetection());
686}
687
Paul Stewartc681fa02012-03-02 19:40:04 -0800688TEST_F(DevicePortalDetectionTest, PortalDetectionBadUrl) {
Paul Stewartd215af62012-04-24 23:25:50 -0700689 EXPECT_CALL(*service_.get(), IsPortalDetectionDisabled())
690 .WillOnce(Return(false));
Paul Stewartc681fa02012-03-02 19:40:04 -0800691 EXPECT_CALL(*service_.get(), IsConnected())
Paul Stewart20088d82012-02-16 06:58:55 -0800692 .WillRepeatedly(Return(true));
Paul Stewartc681fa02012-03-02 19:40:04 -0800693 EXPECT_CALL(*service_.get(), HasProxyConfig())
Paul Stewart20088d82012-02-16 06:58:55 -0800694 .WillOnce(Return(false));
Paul Stewartd215af62012-04-24 23:25:50 -0700695 EXPECT_CALL(*service_.get(), IsPortalDetectionAuto())
696 .WillOnce(Return(true));
Paul Stewartc681fa02012-03-02 19:40:04 -0800697 EXPECT_CALL(manager_, IsPortalDetectionEnabled(device_->technology()))
Paul Stewart20088d82012-02-16 06:58:55 -0800698 .WillOnce(Return(true));
699 const string portal_url;
Paul Stewartc681fa02012-03-02 19:40:04 -0800700 EXPECT_CALL(manager_, GetPortalCheckURL())
Paul Stewart20088d82012-02-16 06:58:55 -0800701 .WillRepeatedly(ReturnRef(portal_url));
Paul Stewartc681fa02012-03-02 19:40:04 -0800702 EXPECT_CALL(*service_.get(), SetState(Service::kStateOnline));
Paul Stewart20088d82012-02-16 06:58:55 -0800703 EXPECT_FALSE(StartPortalDetection());
704}
705
Paul Stewartc681fa02012-03-02 19:40:04 -0800706TEST_F(DevicePortalDetectionTest, PortalDetectionStart) {
Paul Stewartd215af62012-04-24 23:25:50 -0700707 EXPECT_CALL(*service_.get(), IsPortalDetectionDisabled())
708 .WillOnce(Return(false));
Paul Stewartc681fa02012-03-02 19:40:04 -0800709 EXPECT_CALL(*service_.get(), IsConnected())
Paul Stewart20088d82012-02-16 06:58:55 -0800710 .WillRepeatedly(Return(true));
Paul Stewartc681fa02012-03-02 19:40:04 -0800711 EXPECT_CALL(*service_.get(), HasProxyConfig())
Paul Stewart20088d82012-02-16 06:58:55 -0800712 .WillOnce(Return(false));
Paul Stewartd215af62012-04-24 23:25:50 -0700713 EXPECT_CALL(*service_.get(), IsPortalDetectionAuto())
714 .WillOnce(Return(true));
Paul Stewartc681fa02012-03-02 19:40:04 -0800715 EXPECT_CALL(manager_, IsPortalDetectionEnabled(device_->technology()))
Paul Stewart20088d82012-02-16 06:58:55 -0800716 .WillOnce(Return(true));
717 const string portal_url(PortalDetector::kDefaultURL);
Paul Stewartc681fa02012-03-02 19:40:04 -0800718 EXPECT_CALL(manager_, GetPortalCheckURL())
Paul Stewart20088d82012-02-16 06:58:55 -0800719 .WillRepeatedly(ReturnRef(portal_url));
Paul Stewartc681fa02012-03-02 19:40:04 -0800720 EXPECT_CALL(*service_.get(), SetState(Service::kStateOnline))
Paul Stewart20088d82012-02-16 06:58:55 -0800721 .Times(0);
Paul Stewart20088d82012-02-16 06:58:55 -0800722 const string kInterfaceName("int0");
Paul Stewartc681fa02012-03-02 19:40:04 -0800723 EXPECT_CALL(*connection_.get(), interface_name())
724 .WillRepeatedly(ReturnRef(kInterfaceName));
Paul Stewart20088d82012-02-16 06:58:55 -0800725 const vector<string> kDNSServers;
Paul Stewartc681fa02012-03-02 19:40:04 -0800726 EXPECT_CALL(*connection_.get(), dns_servers())
727 .WillRepeatedly(ReturnRef(kDNSServers));
Paul Stewart20088d82012-02-16 06:58:55 -0800728 EXPECT_TRUE(StartPortalDetection());
729
730 // Drop all references to device_info before it falls out of scope.
731 SetConnection(NULL);
732 StopPortalDetection();
733}
734
Paul Stewartc681fa02012-03-02 19:40:04 -0800735TEST_F(DevicePortalDetectionTest, PortalDetectionNonFinal) {
736 EXPECT_CALL(*service_.get(), IsConnected())
Paul Stewart20088d82012-02-16 06:58:55 -0800737 .Times(0);
Paul Stewartc681fa02012-03-02 19:40:04 -0800738 EXPECT_CALL(*service_.get(), SetState(_))
Paul Stewart20088d82012-02-16 06:58:55 -0800739 .Times(0);
Paul Stewart20088d82012-02-16 06:58:55 -0800740 PortalDetectorCallback(PortalDetector::Result(
741 PortalDetector::kPhaseUnknown,
742 PortalDetector::kStatusFailure,
Thieu Le85e050b2012-03-13 15:04:38 -0700743 kPortalAttempts,
Paul Stewart20088d82012-02-16 06:58:55 -0800744 false));
745}
746
Paul Stewartc681fa02012-03-02 19:40:04 -0800747TEST_F(DevicePortalDetectionTest, PortalDetectionFailure) {
748 EXPECT_CALL(*service_.get(), IsConnected())
Paul Stewart20088d82012-02-16 06:58:55 -0800749 .WillOnce(Return(true));
Paul Stewartc681fa02012-03-02 19:40:04 -0800750 EXPECT_CALL(*service_.get(), SetState(Service::kStatePortal));
Thieu Le85e050b2012-03-13 15:04:38 -0700751 EXPECT_CALL(metrics_,
752 SendEnumToUMA("Network.Shill.Unknown.PortalResult",
753 Metrics::kPortalResultConnectionFailure,
754 Metrics::kPortalResultMax));
755 EXPECT_CALL(metrics_,
756 SendToUMA("Network.Shill.Unknown.PortalAttemptsToOnline",
757 _, _, _, _)).Times(0);
758 EXPECT_CALL(metrics_,
759 SendToUMA("Network.Shill.Unknown.PortalAttempts",
760 kPortalAttempts,
761 Metrics::kMetricPortalAttemptsMin,
762 Metrics::kMetricPortalAttemptsMax,
763 Metrics::kMetricPortalAttemptsNumBuckets));
Paul Stewartc681fa02012-03-02 19:40:04 -0800764 EXPECT_CALL(*connection_.get(), is_default())
765 .WillOnce(Return(false));
Paul Stewart20088d82012-02-16 06:58:55 -0800766 PortalDetectorCallback(PortalDetector::Result(
Thieu Le85e050b2012-03-13 15:04:38 -0700767 PortalDetector::kPhaseConnection,
Paul Stewart20088d82012-02-16 06:58:55 -0800768 PortalDetector::kStatusFailure,
Thieu Le85e050b2012-03-13 15:04:38 -0700769 kPortalAttempts,
Paul Stewart20088d82012-02-16 06:58:55 -0800770 true));
771}
772
Paul Stewartc681fa02012-03-02 19:40:04 -0800773TEST_F(DevicePortalDetectionTest, PortalDetectionSuccess) {
774 EXPECT_CALL(*service_.get(), IsConnected())
Paul Stewart20088d82012-02-16 06:58:55 -0800775 .WillOnce(Return(true));
Paul Stewartc681fa02012-03-02 19:40:04 -0800776 EXPECT_CALL(*service_.get(), SetState(Service::kStateOnline));
Thieu Le85e050b2012-03-13 15:04:38 -0700777 EXPECT_CALL(metrics_,
778 SendEnumToUMA("Network.Shill.Unknown.PortalResult",
779 Metrics::kPortalResultSuccess,
780 Metrics::kPortalResultMax));
781 EXPECT_CALL(metrics_,
782 SendToUMA("Network.Shill.Unknown.PortalAttemptsToOnline",
783 kPortalAttempts,
784 Metrics::kMetricPortalAttemptsToOnlineMin,
785 Metrics::kMetricPortalAttemptsToOnlineMax,
786 Metrics::kMetricPortalAttemptsToOnlineNumBuckets));
787 EXPECT_CALL(metrics_,
788 SendToUMA("Network.Shill.Unknown.PortalAttempts",
789 _, _, _, _)).Times(0);
Paul Stewart20088d82012-02-16 06:58:55 -0800790 PortalDetectorCallback(PortalDetector::Result(
Thieu Le85e050b2012-03-13 15:04:38 -0700791 PortalDetector::kPhaseContent,
Paul Stewart20088d82012-02-16 06:58:55 -0800792 PortalDetector::kStatusSuccess,
Thieu Le85e050b2012-03-13 15:04:38 -0700793 kPortalAttempts,
794 true));
795}
796
797TEST_F(DevicePortalDetectionTest, PortalDetectionSuccessAfterFailure) {
798 EXPECT_CALL(*service_.get(), IsConnected())
799 .WillRepeatedly(Return(true));
800 EXPECT_CALL(*service_.get(), SetState(Service::kStatePortal));
801 EXPECT_CALL(metrics_,
802 SendEnumToUMA("Network.Shill.Unknown.PortalResult",
803 Metrics::kPortalResultConnectionFailure,
804 Metrics::kPortalResultMax));
805 EXPECT_CALL(metrics_,
806 SendToUMA("Network.Shill.Unknown.PortalAttemptsToOnline",
807 _, _, _, _)).Times(0);
808 EXPECT_CALL(metrics_,
809 SendToUMA("Network.Shill.Unknown.PortalAttempts",
810 kPortalAttempts,
811 Metrics::kMetricPortalAttemptsMin,
812 Metrics::kMetricPortalAttemptsMax,
813 Metrics::kMetricPortalAttemptsNumBuckets));
814 EXPECT_CALL(*connection_.get(), is_default())
815 .WillOnce(Return(false));
816 PortalDetectorCallback(PortalDetector::Result(
817 PortalDetector::kPhaseConnection,
818 PortalDetector::kStatusFailure,
819 kPortalAttempts,
820 true));
821 Mock::VerifyAndClearExpectations(&metrics_);
822
823 EXPECT_CALL(*service_.get(), SetState(Service::kStateOnline));
824 EXPECT_CALL(metrics_,
825 SendEnumToUMA("Network.Shill.Unknown.PortalResult",
826 Metrics::kPortalResultSuccess,
827 Metrics::kPortalResultMax));
828 EXPECT_CALL(metrics_,
829 SendToUMA("Network.Shill.Unknown.PortalAttemptsToOnline",
830 kPortalAttempts * 2,
831 Metrics::kMetricPortalAttemptsToOnlineMin,
832 Metrics::kMetricPortalAttemptsToOnlineMax,
833 Metrics::kMetricPortalAttemptsToOnlineNumBuckets));
834 EXPECT_CALL(metrics_,
835 SendToUMA("Network.Shill.Unknown.PortalAttempts",
836 _, _, _, _)).Times(0);
837 PortalDetectorCallback(PortalDetector::Result(
838 PortalDetector::kPhaseContent,
839 PortalDetector::kStatusSuccess,
840 kPortalAttempts,
Paul Stewart20088d82012-02-16 06:58:55 -0800841 true));
842}
843
Paul Stewartc681fa02012-03-02 19:40:04 -0800844TEST_F(DevicePortalDetectionTest, RequestPortalDetection) {
845 EXPECT_CALL(*service_.get(), state())
846 .WillOnce(Return(Service::kStateOnline))
847 .WillRepeatedly(Return(Service::kStatePortal));
848 EXPECT_FALSE(RequestPortalDetection());
849
850 EXPECT_CALL(*connection_.get(), is_default())
851 .WillOnce(Return(false))
852 .WillRepeatedly(Return(true));
853 EXPECT_FALSE(RequestPortalDetection());
854
855 EXPECT_CALL(*portal_detector_, IsInProgress())
856 .WillOnce(Return(true));
857 // Portal detection already running.
858 EXPECT_TRUE(RequestPortalDetection());
859
860 // Make sure our running mock portal detector was not replaced.
861 ExpectPortalDetectorIsMock();
862
863 // Throw away our pre-fabricated portal detector, and have the device create
864 // a new one.
865 StopPortalDetection();
Paul Stewartd215af62012-04-24 23:25:50 -0700866 EXPECT_CALL(*service_.get(), IsPortalDetectionDisabled())
867 .WillRepeatedly(Return(false));
868 EXPECT_CALL(*service_.get(), IsPortalDetectionAuto())
869 .WillRepeatedly(Return(true));
Paul Stewartc681fa02012-03-02 19:40:04 -0800870 EXPECT_CALL(manager_, IsPortalDetectionEnabled(device_->technology()))
871 .WillRepeatedly(Return(true));
872 EXPECT_CALL(*service_.get(), HasProxyConfig())
873 .WillRepeatedly(Return(false));
874 const string kPortalCheckURL("http://portal");
875 EXPECT_CALL(manager_, GetPortalCheckURL())
876 .WillOnce(ReturnRef(kPortalCheckURL));
877 const string kInterfaceName("int0");
878 EXPECT_CALL(*connection_.get(), interface_name())
879 .WillRepeatedly(ReturnRef(kInterfaceName));
880 const vector<string> kDNSServers;
881 EXPECT_CALL(*connection_.get(), dns_servers())
882 .WillRepeatedly(ReturnRef(kDNSServers));
883 EXPECT_TRUE(RequestPortalDetection());
884}
885
886TEST_F(DevicePortalDetectionTest, NotConnected) {
887 EXPECT_CALL(*service_.get(), IsConnected())
888 .WillOnce(Return(false));
889 SetServiceConnectedState(Service::kStatePortal);
890 // We don't check for the portal detector to be reset here, because
891 // it would have been reset as a part of disconnection.
892}
893
894TEST_F(DevicePortalDetectionTest, NotPortal) {
895 EXPECT_CALL(*service_.get(), IsConnected())
896 .WillOnce(Return(true));
897 EXPECT_CALL(*service_.get(), SetState(Service::kStateOnline));
898 SetServiceConnectedState(Service::kStateOnline);
899 ExpectPortalDetectorReset();
900}
901
902TEST_F(DevicePortalDetectionTest, NotDefault) {
903 EXPECT_CALL(*service_.get(), IsConnected())
904 .WillOnce(Return(true));
905 EXPECT_CALL(*connection_.get(), is_default())
906 .WillOnce(Return(false));
907 EXPECT_CALL(*service_.get(), SetState(Service::kStatePortal));
908 SetServiceConnectedState(Service::kStatePortal);
909 ExpectPortalDetectorReset();
910}
911
912TEST_F(DevicePortalDetectionTest, PortalIntervalIsZero) {
913 EXPECT_CALL(*service_.get(), IsConnected())
914 .WillOnce(Return(true));
915 EXPECT_CALL(*connection_.get(), is_default())
916 .WillOnce(Return(true));
917 EXPECT_CALL(manager_, GetPortalCheckInterval())
918 .WillOnce(Return(0));
919 EXPECT_CALL(*service_.get(), SetState(Service::kStatePortal));
920 SetServiceConnectedState(Service::kStatePortal);
921 ExpectPortalDetectorReset();
922}
923
924TEST_F(DevicePortalDetectionTest, RestartPortalDetection) {
925 EXPECT_CALL(*service_.get(), IsConnected())
926 .WillOnce(Return(true));
927 EXPECT_CALL(*connection_.get(), is_default())
928 .WillOnce(Return(true));
929 const int kPortalDetectionInterval = 10;
930 EXPECT_CALL(manager_, GetPortalCheckInterval())
931 .Times(AtLeast(1))
932 .WillRepeatedly(Return(kPortalDetectionInterval));
933 const string kPortalCheckURL("http://portal");
934 EXPECT_CALL(manager_, GetPortalCheckURL())
935 .WillOnce(ReturnRef(kPortalCheckURL));
936 EXPECT_CALL(*portal_detector_, StartAfterDelay(kPortalCheckURL,
937 kPortalDetectionInterval))
938 .WillOnce(Return(true));
939 EXPECT_CALL(*service_.get(), SetState(Service::kStatePortal));
940 SetServiceConnectedState(Service::kStatePortal);
941 ExpectPortalDetectorSet();
942}
943
Paul Stewartc8860612012-09-28 07:36:21 -0700944TEST_F(DevicePortalDetectionTest, CancelledOnSelectService) {
945 ExpectPortalDetectorSet();
946 EXPECT_CALL(*service_.get(), state())
947 .WillOnce(Return(Service::kStateIdle));
948 EXPECT_CALL(*service_.get(), SetState(_));
949 EXPECT_CALL(*service_.get(), SetConnection(_));
950 SelectService(NULL);
951 ExpectPortalDetectorReset();
952}
953
Paul Stewart6ff27f52012-07-11 06:51:41 -0700954class DeviceByteCountTest : public DeviceTest {
955 public:
956 DeviceByteCountTest()
957 : manager_(control_interface(),
958 dispatcher(),
959 metrics(),
960 glib()),
961 rx_byte_count_(0),
962 tx_byte_count_(0),
963 rx_stored_byte_count_(0),
964 tx_stored_byte_count_(0) {}
965 virtual ~DeviceByteCountTest() {}
966
967 virtual void SetUp() {
968 DeviceTest::SetUp();
969 EXPECT_CALL(manager_, device_info()).WillRepeatedly(Return(&device_info_));
970 EXPECT_CALL(device_info_, GetByteCounts(kDeviceInterfaceIndex, _, _))
971 .WillRepeatedly(Invoke(this, &DeviceByteCountTest::ReturnByteCounts));
972 const string id = device_->GetStorageIdentifier();
973 EXPECT_CALL(storage_, ContainsGroup(id)).WillRepeatedly(Return(true));
974 EXPECT_CALL(storage_, GetUint64(id, Device::kStorageReceiveByteCount, _))
975 .WillRepeatedly(
976 Invoke(this, &DeviceByteCountTest::GetStoredReceiveCount));
977 EXPECT_CALL(storage_, GetUint64(id, Device::kStorageTransmitByteCount, _))
978 .WillRepeatedly(
979 Invoke(this, &DeviceByteCountTest::GetStoredTransmitCount));
980 }
981
982 bool ReturnByteCounts(int interface_index, uint64 *rx, uint64 *tx) {
983 *rx = rx_byte_count_;
984 *tx = tx_byte_count_;
985 return true;
986 }
987
988 bool ExpectByteCounts(DeviceRefPtr device,
989 int64 expected_rx, int64 expected_tx) {
Ben Chanb061f892013-02-27 17:46:55 -0800990 int64 actual_rx = device->GetReceiveByteCount();
991 int64 actual_tx = device->GetTransmitByteCount();
Paul Stewart6ff27f52012-07-11 06:51:41 -0700992 EXPECT_EQ(expected_rx, actual_rx);
993 EXPECT_EQ(expected_tx, actual_tx);
994 return expected_rx == actual_rx && expected_tx == actual_tx;
995 }
996
997 void ExpectSavedCounts(DeviceRefPtr device,
998 int64 expected_rx, int64 expected_tx) {
999 EXPECT_CALL(storage_,
1000 SetUint64(_, Device::kStorageReceiveByteCount, expected_rx))
1001 .WillOnce(Return(true));
1002 EXPECT_CALL(storage_,
1003 SetUint64(_, Device::kStorageTransmitByteCount, expected_tx))
1004 .WillOnce(Return(true));
1005 EXPECT_TRUE(device->Save(&storage_));
1006 }
1007
1008
1009 bool GetStoredReceiveCount(const string &group, const string &key,
1010 uint64 *value) {
1011 if (!rx_stored_byte_count_) {
1012 return false;
1013 }
1014 *value = rx_stored_byte_count_;
1015 return true;
1016 }
1017
1018 bool GetStoredTransmitCount(const string &group, const string &key,
1019 uint64 *value) {
1020 if (!tx_stored_byte_count_) {
1021 return false;
1022 }
1023 *value = tx_stored_byte_count_;
1024 return true;
1025 }
1026
1027 protected:
1028 NiceMock<MockManager> manager_;
1029 NiceMock<MockStore> storage_;
1030 uint64 rx_byte_count_;
1031 uint64 tx_byte_count_;
1032 uint64 rx_stored_byte_count_;
1033 uint64 tx_stored_byte_count_;
1034};
1035
1036
1037TEST_F(DeviceByteCountTest, GetByteCounts) {
1038 // On Device initialization, byte counts should be zero, independent of
1039 // the byte counts reported by the interface.
1040 rx_byte_count_ = 123;
1041 tx_byte_count_ = 456;
1042 DeviceRefPtr device(new TestDevice(control_interface(),
1043 dispatcher(),
1044 NULL,
1045 &manager_,
1046 kDeviceName,
1047 kDeviceAddress,
1048 kDeviceInterfaceIndex,
1049 Technology::kUnknown));
1050 EXPECT_TRUE(ExpectByteCounts(device, 0, 0));
1051
1052 // Device should report any increase in the byte counts reported in the
1053 // interface.
1054 const int64 delta_rx_count = 789;
1055 const int64 delta_tx_count = 12;
1056 rx_byte_count_ += delta_rx_count;
1057 tx_byte_count_ += delta_tx_count;
1058 EXPECT_TRUE(ExpectByteCounts(device, delta_rx_count, delta_tx_count));
1059
1060 // Expect the correct values to be saved to the profile.
1061 ExpectSavedCounts(device, delta_rx_count, delta_tx_count);
1062
1063 // If Device is loaded from a profile that does not contain stored byte
1064 // counts, the byte counts reported should remain unchanged.
1065 EXPECT_TRUE(device->Load(&storage_));
1066 EXPECT_TRUE(ExpectByteCounts(device, delta_rx_count, delta_tx_count));
1067
1068 // If Device is loaded from a profile that contains stored byte
1069 // counts, the byte counts reported should now reflect the stored values.
1070 rx_stored_byte_count_ = 345;
1071 tx_stored_byte_count_ = 678;
1072 EXPECT_TRUE(device->Load(&storage_));
1073 EXPECT_TRUE(ExpectByteCounts(
1074 device, rx_stored_byte_count_, tx_stored_byte_count_));
1075
1076 // Increases to the interface receive count should be reflected as offsets
1077 // to the stored byte counts.
1078 rx_byte_count_ += delta_rx_count;
1079 tx_byte_count_ += delta_tx_count;
1080 EXPECT_TRUE(ExpectByteCounts(device,
1081 rx_stored_byte_count_ + delta_rx_count,
1082 tx_stored_byte_count_ + delta_tx_count));
1083
1084 // Expect the correct values to be saved to the profile.
1085 ExpectSavedCounts(device,
1086 rx_stored_byte_count_ + delta_rx_count,
1087 tx_stored_byte_count_ + delta_tx_count);
1088
1089 // Expect that after resetting byte counts, read-back values return to zero,
1090 // and that the device requests this information to be persisted.
1091 EXPECT_CALL(manager_, UpdateDevice(device));
1092 device->ResetByteCounters();
1093 EXPECT_TRUE(ExpectByteCounts(device, 0, 0));
1094}
1095
Arman Ugurayf84a4242013-04-09 20:01:07 -07001096class DeviceHealthCheckerTest : public DeviceTest {
1097 public:
1098 DeviceHealthCheckerTest()
1099 : connection_(new StrictMock<MockConnection>(&device_info_)),
Prathmesh Prabhuba99b592013-04-17 15:13:14 -07001100 ip_address_store_(new MockIPAddressStore()),
Arman Ugurayf84a4242013-04-09 20:01:07 -07001101 weak_ptr_factory_(this) {}
1102
1103 protected:
1104 void SetUp() {
1105 DeviceTest::SetUp();
1106
1107 string default_str;
1108 vector<string> default_vector;
1109
1110 ON_CALL(*connection_.get(), interface_name())
1111 .WillByDefault(ReturnRef(default_str));
1112 ON_CALL(*connection_.get(), dns_servers())
1113 .WillByDefault(ReturnRef(default_vector));
1114 EXPECT_CALL(*connection_.get(), interface_name())
1115 .Times(AnyNumber());
1116 EXPECT_CALL(*connection_.get(), dns_servers())
1117 .Times(AnyNumber());
Prathmesh Prabhuba99b592013-04-17 15:13:14 -07001118 EXPECT_CALL(*ip_address_store_.get(), AddUnique(_)).Times(AnyNumber());
Arman Ugurayf84a4242013-04-09 20:01:07 -07001119
1120 mock_health_checker_.reset(
1121 new MockConnectionHealthChecker(
1122 connection_,
1123 NULL,
Prathmesh Prabhuba99b592013-04-17 15:13:14 -07001124 ip_address_store_.get(),
Arman Ugurayf84a4242013-04-09 20:01:07 -07001125 Bind(&DeviceHealthCheckerTest::OnConnectionHealthCheckerResult,
1126 weak_ptr_factory_.GetWeakPtr())));
1127 }
1128
1129 void SetMockHealthChecker() {
1130 device_->set_health_checker(mock_health_checker_.release());
1131 EXPECT_TRUE(device_->health_checker_.get());
1132 }
1133
Prathmesh Prabhuba99b592013-04-17 15:13:14 -07001134 void SetMockConnection() {
1135 device_->connection_ = connection_;
1136 }
1137
Arman Ugurayf84a4242013-04-09 20:01:07 -07001138 void OnConnectionHealthCheckerResult(
1139 ConnectionHealthChecker::Result result) {
1140 }
1141
1142 scoped_refptr<MockConnection> connection_;
1143 scoped_ptr<MockConnectionHealthChecker> mock_health_checker_;
Prathmesh Prabhuba99b592013-04-17 15:13:14 -07001144 scoped_ptr<MockIPAddressStore> ip_address_store_;
Arman Ugurayf84a4242013-04-09 20:01:07 -07001145 base::WeakPtrFactory<DeviceHealthCheckerTest> weak_ptr_factory_;
1146};
1147
Arman Ugurayf84a4242013-04-09 20:01:07 -07001148TEST_F(DeviceHealthCheckerTest, RequestConnectionHealthCheck) {
1149 EXPECT_FALSE(device_->health_checker_.get());
1150 MockConnectionHealthChecker *health_checker = mock_health_checker_.get();
1151 SetMockHealthChecker();
Arman Ugurayf84a4242013-04-09 20:01:07 -07001152 EXPECT_CALL(*health_checker, health_check_in_progress())
Arman Ugurayf84a4242013-04-09 20:01:07 -07001153 .WillOnce(Return(true));
Prathmesh Prabhuade9b9a2013-04-22 18:01:19 -07001154 EXPECT_CALL(*health_checker, Start()).Times(0);
Arman Ugurayf84a4242013-04-09 20:01:07 -07001155 device_->RequestConnectionHealthCheck();
1156 Mock::VerifyAndClearExpectations(health_checker);
1157
Arman Ugurayf84a4242013-04-09 20:01:07 -07001158 EXPECT_CALL(*health_checker, health_check_in_progress())
Arman Ugurayf84a4242013-04-09 20:01:07 -07001159 .WillOnce(Return(false));
Prathmesh Prabhuade9b9a2013-04-22 18:01:19 -07001160 EXPECT_CALL(*health_checker, Start()).Times(1);
Arman Ugurayf84a4242013-04-09 20:01:07 -07001161 device_->RequestConnectionHealthCheck();
1162 Mock::VerifyAndClearExpectations(health_checker);
1163}
1164
Darin Petkovafa6fc42011-06-21 16:21:08 -07001165} // namespace shill