blob: 0ce805944010dfa7b85c75b5c51eaa5d23c86eb0 [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
mukesh agrawalbb2231c2013-07-17 16:32:24 -0700464TEST_F(DeviceTest, ResumeWithLinkMonitor) {
465 MockLinkMonitor *link_monitor = new StrictMock<MockLinkMonitor>();
466 SetLinkMonitor(link_monitor); // Passes ownership.
467 EXPECT_CALL(*link_monitor, OnAfterResume());
468 device_->OnAfterResume();
469}
470
471TEST_F(DeviceTest, ResumeWithoutLinkMonitor) {
472 // Just test that we don't crash in this case.
473 EXPECT_FALSE(HasLinkMonitor());
474 device_->OnAfterResume();
475}
476
Paul Stewart036dba02012-08-07 12:34:41 -0700477TEST_F(DeviceTest, LinkMonitor) {
478 scoped_refptr<MockConnection> connection(
479 new StrictMock<MockConnection>(&device_info_));
480 MockManager manager(control_interface(),
481 dispatcher(),
482 metrics(),
483 glib());
484 scoped_refptr<MockService> service(
485 new StrictMock<MockService>(control_interface(),
486 dispatcher(),
487 metrics(),
488 &manager));
489 SelectService(service);
490 SetConnection(connection.get());
491 MockLinkMonitor *link_monitor = new StrictMock<MockLinkMonitor>();
492 SetLinkMonitor(link_monitor); // Passes ownership.
493 SetManager(&manager);
494 EXPECT_CALL(*link_monitor, Start()).Times(0);
495 EXPECT_CALL(manager, IsTechnologyLinkMonitorEnabled(Technology::kUnknown))
496 .WillOnce(Return(false))
497 .WillRepeatedly(Return(true));
498 EXPECT_FALSE(StartLinkMonitor());
499
500 EXPECT_CALL(*link_monitor, Start())
501 .WillOnce(Return(false))
502 .WillOnce(Return(true));
503 EXPECT_FALSE(StartLinkMonitor());
504 EXPECT_TRUE(StartLinkMonitor());
505
506 unsigned int kResponseTime = 123;
507 EXPECT_CALL(*link_monitor, GetResponseTimeMilliseconds())
508 .WillOnce(Return(kResponseTime));
509 {
510 Error error;
511 EXPECT_EQ(kResponseTime, GetLinkMonitorResponseTime(&error));
512 EXPECT_TRUE(error.IsSuccess());
513 }
514 StopLinkMonitor();
515 {
516 Error error;
517 EXPECT_EQ(0, GetLinkMonitorResponseTime(&error));
518 EXPECT_FALSE(error.IsSuccess());
519 }
520}
521
Paul Stewartc8860612012-09-28 07:36:21 -0700522TEST_F(DeviceTest, LinkMonitorCancelledOnSelectService) {
523 scoped_refptr<MockConnection> connection(
524 new StrictMock<MockConnection>(&device_info_));
525 MockManager manager(control_interface(),
526 dispatcher(),
527 metrics(),
528 glib());
529 scoped_refptr<MockService> service(
530 new StrictMock<MockService>(control_interface(),
531 dispatcher(),
532 metrics(),
533 &manager));
534 SelectService(service);
535 SetConnection(connection.get());
536 MockLinkMonitor *link_monitor = new StrictMock<MockLinkMonitor>();
537 SetLinkMonitor(link_monitor); // Passes ownership.
538 SetManager(&manager);
539 EXPECT_CALL(*service.get(), state())
540 .WillOnce(Return(Service::kStateIdle));
541 EXPECT_CALL(*service.get(), SetState(_));
542 EXPECT_CALL(*service.get(), SetConnection(_));
543 EXPECT_TRUE(HasLinkMonitor());
544 SelectService(NULL);
545 EXPECT_FALSE(HasLinkMonitor());
546}
547
Ben Chanb061f892013-02-27 17:46:55 -0800548TEST_F(DeviceTest, StartTrafficMonitor) {
549 MockTrafficMonitor *traffic_monitor = new StrictMock<MockTrafficMonitor>();
550 SetTrafficMonitor(traffic_monitor); // Passes ownership.
551
552 EXPECT_CALL(*traffic_monitor, Start()).Times(0);
553 EXPECT_FALSE(device_->traffic_monitor_enabled());
554 EXPECT_FALSE(StartTrafficMonitor());
555
556 device_->set_traffic_monitor_enabled(true);
557 EXPECT_CALL(*traffic_monitor, Start()).Times(1);
558 EXPECT_TRUE(device_->traffic_monitor_enabled());
559 EXPECT_TRUE(StartTrafficMonitor());
560}
561
562TEST_F(DeviceTest, StopTrafficMonitor) {
563 // Invoke Stop() without a traffic monitor set.
564 EXPECT_FALSE(device_->traffic_monitor_.get());
565 StopTrafficMonitor();
566 EXPECT_FALSE(device_->traffic_monitor_.get());
567
568 // Invoke Stop() with a traffic monitor set but without invoking Start().
569 TrafficMonitor *traffic_monitor = new TrafficMonitor(device_, dispatcher());
570 SetTrafficMonitor(traffic_monitor); // Passes ownership.
571 EXPECT_TRUE(device_->traffic_monitor_.get());
572 StopTrafficMonitor();
573 EXPECT_FALSE(device_->traffic_monitor_.get());
574
575 // Invoke Stop() with a traffic monitor set but not enabled.
576 traffic_monitor = new TrafficMonitor(device_, dispatcher());
577 SetTrafficMonitor(traffic_monitor); // Passes ownership.
578 EXPECT_FALSE(device_->traffic_monitor_enabled());
579 EXPECT_FALSE(StartTrafficMonitor());
580 EXPECT_TRUE(device_->traffic_monitor_.get());
581 StopTrafficMonitor();
582 EXPECT_FALSE(device_->traffic_monitor_.get());
583
584 // Invoke Stop() with a traffic monitor set and started.
585 device_->set_traffic_monitor_enabled(true);
586 EXPECT_TRUE(device_->traffic_monitor_enabled());
587 EXPECT_TRUE(StartTrafficMonitor());
588 EXPECT_TRUE(device_->traffic_monitor_.get());
589 StopTrafficMonitor();
590 EXPECT_FALSE(device_->traffic_monitor_.get());
591
592 // Invoke Stop() again after the traffic monitor is stopped.
593 StopTrafficMonitor();
594 EXPECT_FALSE(device_->traffic_monitor_.get());
595}
596
Paul Stewartc681fa02012-03-02 19:40:04 -0800597class DevicePortalDetectionTest : public DeviceTest {
598 public:
599 DevicePortalDetectionTest()
600 : connection_(new StrictMock<MockConnection>(&device_info_)),
601 manager_(control_interface(),
602 dispatcher(),
603 metrics(),
604 glib()),
605 service_(new StrictMock<MockService>(control_interface(),
606 dispatcher(),
607 metrics(),
608 &manager_)),
609 portal_detector_(new StrictMock<MockPortalDetector>(connection_)) {}
610 virtual ~DevicePortalDetectionTest() {}
611 virtual void SetUp() {
612 DeviceTest::SetUp();
613 SelectService(service_);
614 SetConnection(connection_.get());
615 device_->portal_detector_.reset(portal_detector_); // Passes ownership.
Paul Stewart036dba02012-08-07 12:34:41 -0700616 SetManager(&manager_);
Paul Stewartc681fa02012-03-02 19:40:04 -0800617 }
618
619 protected:
Thieu Le85e050b2012-03-13 15:04:38 -0700620 static const int kPortalAttempts;
621
Paul Stewartc681fa02012-03-02 19:40:04 -0800622 bool StartPortalDetection() { return device_->StartPortalDetection(); }
623 void StopPortalDetection() { device_->StopPortalDetection(); }
624
625 void PortalDetectorCallback(const PortalDetector::Result &result) {
626 device_->PortalDetectorCallback(result);
627 }
628 bool RequestPortalDetection() {
629 return device_->RequestPortalDetection();
630 }
631 void SetServiceConnectedState(Service::ConnectState state) {
632 device_->SetServiceConnectedState(state);
633 }
634 void ExpectPortalDetectorReset() {
635 EXPECT_FALSE(device_->portal_detector_.get());
636 }
637 void ExpectPortalDetectorSet() {
638 EXPECT_TRUE(device_->portal_detector_.get());
639 }
640 void ExpectPortalDetectorIsMock() {
641 EXPECT_EQ(portal_detector_, device_->portal_detector_.get());
642 }
643 scoped_refptr<MockConnection> connection_;
644 StrictMock<MockManager> manager_;
645 scoped_refptr<MockService> service_;
646
647 // Used only for EXPECT_CALL(). Object is owned by device.
648 MockPortalDetector *portal_detector_;
649};
650
Thieu Le85e050b2012-03-13 15:04:38 -0700651const int DevicePortalDetectionTest::kPortalAttempts = 2;
652
Paul Stewartd215af62012-04-24 23:25:50 -0700653TEST_F(DevicePortalDetectionTest, ServicePortalDetectionDisabled) {
654 EXPECT_CALL(*service_.get(), IsPortalDetectionDisabled())
655 .WillOnce(Return(true));
Paul Stewartc681fa02012-03-02 19:40:04 -0800656 EXPECT_CALL(*service_.get(), IsConnected())
Paul Stewart20088d82012-02-16 06:58:55 -0800657 .WillRepeatedly(Return(true));
Paul Stewartd215af62012-04-24 23:25:50 -0700658 EXPECT_CALL(*service_.get(), SetState(Service::kStateOnline));
659 EXPECT_FALSE(StartPortalDetection());
660}
661
662TEST_F(DevicePortalDetectionTest, TechnologyPortalDetectionDisabled) {
663 EXPECT_CALL(*service_.get(), IsPortalDetectionDisabled())
664 .WillOnce(Return(false));
665 EXPECT_CALL(*service_.get(), IsConnected())
666 .WillRepeatedly(Return(true));
667 EXPECT_CALL(*service_.get(), IsPortalDetectionAuto())
668 .WillOnce(Return(true));
Paul Stewartc681fa02012-03-02 19:40:04 -0800669 EXPECT_CALL(manager_, IsPortalDetectionEnabled(device_->technology()))
Paul Stewart20088d82012-02-16 06:58:55 -0800670 .WillOnce(Return(false));
Paul Stewartc681fa02012-03-02 19:40:04 -0800671 EXPECT_CALL(*service_.get(), SetState(Service::kStateOnline));
Paul Stewart20088d82012-02-16 06:58:55 -0800672 EXPECT_FALSE(StartPortalDetection());
673}
674
Paul Stewartc681fa02012-03-02 19:40:04 -0800675TEST_F(DevicePortalDetectionTest, PortalDetectionProxyConfig) {
Paul Stewartd215af62012-04-24 23:25:50 -0700676 EXPECT_CALL(*service_.get(), IsPortalDetectionDisabled())
677 .WillOnce(Return(false));
Paul Stewartc681fa02012-03-02 19:40:04 -0800678 EXPECT_CALL(*service_.get(), IsConnected())
Paul Stewart20088d82012-02-16 06:58:55 -0800679 .WillRepeatedly(Return(true));
Paul Stewartc681fa02012-03-02 19:40:04 -0800680 EXPECT_CALL(*service_.get(), HasProxyConfig())
Paul Stewart20088d82012-02-16 06:58:55 -0800681 .WillOnce(Return(true));
Paul Stewartd215af62012-04-24 23:25:50 -0700682 EXPECT_CALL(*service_.get(), IsPortalDetectionAuto())
683 .WillOnce(Return(true));
Paul Stewartc681fa02012-03-02 19:40:04 -0800684 EXPECT_CALL(manager_, IsPortalDetectionEnabled(device_->technology()))
Paul Stewart20088d82012-02-16 06:58:55 -0800685 .WillOnce(Return(true));
Paul Stewartc681fa02012-03-02 19:40:04 -0800686 EXPECT_CALL(*service_.get(), SetState(Service::kStateOnline));
Paul Stewart20088d82012-02-16 06:58:55 -0800687 EXPECT_FALSE(StartPortalDetection());
688}
689
Paul Stewartc681fa02012-03-02 19:40:04 -0800690TEST_F(DevicePortalDetectionTest, PortalDetectionBadUrl) {
Paul Stewartd215af62012-04-24 23:25:50 -0700691 EXPECT_CALL(*service_.get(), IsPortalDetectionDisabled())
692 .WillOnce(Return(false));
Paul Stewartc681fa02012-03-02 19:40:04 -0800693 EXPECT_CALL(*service_.get(), IsConnected())
Paul Stewart20088d82012-02-16 06:58:55 -0800694 .WillRepeatedly(Return(true));
Paul Stewartc681fa02012-03-02 19:40:04 -0800695 EXPECT_CALL(*service_.get(), HasProxyConfig())
Paul Stewart20088d82012-02-16 06:58:55 -0800696 .WillOnce(Return(false));
Paul Stewartd215af62012-04-24 23:25:50 -0700697 EXPECT_CALL(*service_.get(), IsPortalDetectionAuto())
698 .WillOnce(Return(true));
Paul Stewartc681fa02012-03-02 19:40:04 -0800699 EXPECT_CALL(manager_, IsPortalDetectionEnabled(device_->technology()))
Paul Stewart20088d82012-02-16 06:58:55 -0800700 .WillOnce(Return(true));
701 const string portal_url;
Paul Stewartc681fa02012-03-02 19:40:04 -0800702 EXPECT_CALL(manager_, GetPortalCheckURL())
Paul Stewart20088d82012-02-16 06:58:55 -0800703 .WillRepeatedly(ReturnRef(portal_url));
Paul Stewartc681fa02012-03-02 19:40:04 -0800704 EXPECT_CALL(*service_.get(), SetState(Service::kStateOnline));
Paul Stewart20088d82012-02-16 06:58:55 -0800705 EXPECT_FALSE(StartPortalDetection());
706}
707
Paul Stewartc681fa02012-03-02 19:40:04 -0800708TEST_F(DevicePortalDetectionTest, PortalDetectionStart) {
Paul Stewartd215af62012-04-24 23:25:50 -0700709 EXPECT_CALL(*service_.get(), IsPortalDetectionDisabled())
710 .WillOnce(Return(false));
Paul Stewartc681fa02012-03-02 19:40:04 -0800711 EXPECT_CALL(*service_.get(), IsConnected())
Paul Stewart20088d82012-02-16 06:58:55 -0800712 .WillRepeatedly(Return(true));
Paul Stewartc681fa02012-03-02 19:40:04 -0800713 EXPECT_CALL(*service_.get(), HasProxyConfig())
Paul Stewart20088d82012-02-16 06:58:55 -0800714 .WillOnce(Return(false));
Paul Stewartd215af62012-04-24 23:25:50 -0700715 EXPECT_CALL(*service_.get(), IsPortalDetectionAuto())
716 .WillOnce(Return(true));
Paul Stewartc681fa02012-03-02 19:40:04 -0800717 EXPECT_CALL(manager_, IsPortalDetectionEnabled(device_->technology()))
Paul Stewart20088d82012-02-16 06:58:55 -0800718 .WillOnce(Return(true));
719 const string portal_url(PortalDetector::kDefaultURL);
Paul Stewartc681fa02012-03-02 19:40:04 -0800720 EXPECT_CALL(manager_, GetPortalCheckURL())
Paul Stewart20088d82012-02-16 06:58:55 -0800721 .WillRepeatedly(ReturnRef(portal_url));
Paul Stewartc681fa02012-03-02 19:40:04 -0800722 EXPECT_CALL(*service_.get(), SetState(Service::kStateOnline))
Paul Stewart20088d82012-02-16 06:58:55 -0800723 .Times(0);
Paul Stewart20088d82012-02-16 06:58:55 -0800724 const string kInterfaceName("int0");
Paul Stewartc681fa02012-03-02 19:40:04 -0800725 EXPECT_CALL(*connection_.get(), interface_name())
726 .WillRepeatedly(ReturnRef(kInterfaceName));
Paul Stewart20088d82012-02-16 06:58:55 -0800727 const vector<string> kDNSServers;
Paul Stewartc681fa02012-03-02 19:40:04 -0800728 EXPECT_CALL(*connection_.get(), dns_servers())
729 .WillRepeatedly(ReturnRef(kDNSServers));
Paul Stewart20088d82012-02-16 06:58:55 -0800730 EXPECT_TRUE(StartPortalDetection());
731
732 // Drop all references to device_info before it falls out of scope.
733 SetConnection(NULL);
734 StopPortalDetection();
735}
736
Paul Stewartc681fa02012-03-02 19:40:04 -0800737TEST_F(DevicePortalDetectionTest, PortalDetectionNonFinal) {
738 EXPECT_CALL(*service_.get(), IsConnected())
Paul Stewart20088d82012-02-16 06:58:55 -0800739 .Times(0);
Paul Stewartc681fa02012-03-02 19:40:04 -0800740 EXPECT_CALL(*service_.get(), SetState(_))
Paul Stewart20088d82012-02-16 06:58:55 -0800741 .Times(0);
Paul Stewart20088d82012-02-16 06:58:55 -0800742 PortalDetectorCallback(PortalDetector::Result(
743 PortalDetector::kPhaseUnknown,
744 PortalDetector::kStatusFailure,
Thieu Le85e050b2012-03-13 15:04:38 -0700745 kPortalAttempts,
Paul Stewart20088d82012-02-16 06:58:55 -0800746 false));
747}
748
Paul Stewartc681fa02012-03-02 19:40:04 -0800749TEST_F(DevicePortalDetectionTest, PortalDetectionFailure) {
750 EXPECT_CALL(*service_.get(), IsConnected())
Paul Stewart20088d82012-02-16 06:58:55 -0800751 .WillOnce(Return(true));
Paul Stewartc681fa02012-03-02 19:40:04 -0800752 EXPECT_CALL(*service_.get(), SetState(Service::kStatePortal));
Thieu Le85e050b2012-03-13 15:04:38 -0700753 EXPECT_CALL(metrics_,
754 SendEnumToUMA("Network.Shill.Unknown.PortalResult",
755 Metrics::kPortalResultConnectionFailure,
756 Metrics::kPortalResultMax));
757 EXPECT_CALL(metrics_,
758 SendToUMA("Network.Shill.Unknown.PortalAttemptsToOnline",
759 _, _, _, _)).Times(0);
760 EXPECT_CALL(metrics_,
761 SendToUMA("Network.Shill.Unknown.PortalAttempts",
762 kPortalAttempts,
763 Metrics::kMetricPortalAttemptsMin,
764 Metrics::kMetricPortalAttemptsMax,
765 Metrics::kMetricPortalAttemptsNumBuckets));
Paul Stewartc681fa02012-03-02 19:40:04 -0800766 EXPECT_CALL(*connection_.get(), is_default())
767 .WillOnce(Return(false));
Paul Stewart20088d82012-02-16 06:58:55 -0800768 PortalDetectorCallback(PortalDetector::Result(
Thieu Le85e050b2012-03-13 15:04:38 -0700769 PortalDetector::kPhaseConnection,
Paul Stewart20088d82012-02-16 06:58:55 -0800770 PortalDetector::kStatusFailure,
Thieu Le85e050b2012-03-13 15:04:38 -0700771 kPortalAttempts,
Paul Stewart20088d82012-02-16 06:58:55 -0800772 true));
773}
774
Paul Stewartc681fa02012-03-02 19:40:04 -0800775TEST_F(DevicePortalDetectionTest, PortalDetectionSuccess) {
776 EXPECT_CALL(*service_.get(), IsConnected())
Paul Stewart20088d82012-02-16 06:58:55 -0800777 .WillOnce(Return(true));
Paul Stewartc681fa02012-03-02 19:40:04 -0800778 EXPECT_CALL(*service_.get(), SetState(Service::kStateOnline));
Thieu Le85e050b2012-03-13 15:04:38 -0700779 EXPECT_CALL(metrics_,
780 SendEnumToUMA("Network.Shill.Unknown.PortalResult",
781 Metrics::kPortalResultSuccess,
782 Metrics::kPortalResultMax));
783 EXPECT_CALL(metrics_,
784 SendToUMA("Network.Shill.Unknown.PortalAttemptsToOnline",
785 kPortalAttempts,
786 Metrics::kMetricPortalAttemptsToOnlineMin,
787 Metrics::kMetricPortalAttemptsToOnlineMax,
788 Metrics::kMetricPortalAttemptsToOnlineNumBuckets));
789 EXPECT_CALL(metrics_,
790 SendToUMA("Network.Shill.Unknown.PortalAttempts",
791 _, _, _, _)).Times(0);
Paul Stewart20088d82012-02-16 06:58:55 -0800792 PortalDetectorCallback(PortalDetector::Result(
Thieu Le85e050b2012-03-13 15:04:38 -0700793 PortalDetector::kPhaseContent,
Paul Stewart20088d82012-02-16 06:58:55 -0800794 PortalDetector::kStatusSuccess,
Thieu Le85e050b2012-03-13 15:04:38 -0700795 kPortalAttempts,
796 true));
797}
798
799TEST_F(DevicePortalDetectionTest, PortalDetectionSuccessAfterFailure) {
800 EXPECT_CALL(*service_.get(), IsConnected())
801 .WillRepeatedly(Return(true));
802 EXPECT_CALL(*service_.get(), SetState(Service::kStatePortal));
803 EXPECT_CALL(metrics_,
804 SendEnumToUMA("Network.Shill.Unknown.PortalResult",
805 Metrics::kPortalResultConnectionFailure,
806 Metrics::kPortalResultMax));
807 EXPECT_CALL(metrics_,
808 SendToUMA("Network.Shill.Unknown.PortalAttemptsToOnline",
809 _, _, _, _)).Times(0);
810 EXPECT_CALL(metrics_,
811 SendToUMA("Network.Shill.Unknown.PortalAttempts",
812 kPortalAttempts,
813 Metrics::kMetricPortalAttemptsMin,
814 Metrics::kMetricPortalAttemptsMax,
815 Metrics::kMetricPortalAttemptsNumBuckets));
816 EXPECT_CALL(*connection_.get(), is_default())
817 .WillOnce(Return(false));
818 PortalDetectorCallback(PortalDetector::Result(
819 PortalDetector::kPhaseConnection,
820 PortalDetector::kStatusFailure,
821 kPortalAttempts,
822 true));
823 Mock::VerifyAndClearExpectations(&metrics_);
824
825 EXPECT_CALL(*service_.get(), SetState(Service::kStateOnline));
826 EXPECT_CALL(metrics_,
827 SendEnumToUMA("Network.Shill.Unknown.PortalResult",
828 Metrics::kPortalResultSuccess,
829 Metrics::kPortalResultMax));
830 EXPECT_CALL(metrics_,
831 SendToUMA("Network.Shill.Unknown.PortalAttemptsToOnline",
832 kPortalAttempts * 2,
833 Metrics::kMetricPortalAttemptsToOnlineMin,
834 Metrics::kMetricPortalAttemptsToOnlineMax,
835 Metrics::kMetricPortalAttemptsToOnlineNumBuckets));
836 EXPECT_CALL(metrics_,
837 SendToUMA("Network.Shill.Unknown.PortalAttempts",
838 _, _, _, _)).Times(0);
839 PortalDetectorCallback(PortalDetector::Result(
840 PortalDetector::kPhaseContent,
841 PortalDetector::kStatusSuccess,
842 kPortalAttempts,
Paul Stewart20088d82012-02-16 06:58:55 -0800843 true));
844}
845
Paul Stewartc681fa02012-03-02 19:40:04 -0800846TEST_F(DevicePortalDetectionTest, RequestPortalDetection) {
847 EXPECT_CALL(*service_.get(), state())
848 .WillOnce(Return(Service::kStateOnline))
849 .WillRepeatedly(Return(Service::kStatePortal));
850 EXPECT_FALSE(RequestPortalDetection());
851
852 EXPECT_CALL(*connection_.get(), is_default())
853 .WillOnce(Return(false))
854 .WillRepeatedly(Return(true));
855 EXPECT_FALSE(RequestPortalDetection());
856
857 EXPECT_CALL(*portal_detector_, IsInProgress())
858 .WillOnce(Return(true));
859 // Portal detection already running.
860 EXPECT_TRUE(RequestPortalDetection());
861
862 // Make sure our running mock portal detector was not replaced.
863 ExpectPortalDetectorIsMock();
864
865 // Throw away our pre-fabricated portal detector, and have the device create
866 // a new one.
867 StopPortalDetection();
Paul Stewartd215af62012-04-24 23:25:50 -0700868 EXPECT_CALL(*service_.get(), IsPortalDetectionDisabled())
869 .WillRepeatedly(Return(false));
870 EXPECT_CALL(*service_.get(), IsPortalDetectionAuto())
871 .WillRepeatedly(Return(true));
Paul Stewartc681fa02012-03-02 19:40:04 -0800872 EXPECT_CALL(manager_, IsPortalDetectionEnabled(device_->technology()))
873 .WillRepeatedly(Return(true));
874 EXPECT_CALL(*service_.get(), HasProxyConfig())
875 .WillRepeatedly(Return(false));
876 const string kPortalCheckURL("http://portal");
877 EXPECT_CALL(manager_, GetPortalCheckURL())
878 .WillOnce(ReturnRef(kPortalCheckURL));
879 const string kInterfaceName("int0");
880 EXPECT_CALL(*connection_.get(), interface_name())
881 .WillRepeatedly(ReturnRef(kInterfaceName));
882 const vector<string> kDNSServers;
883 EXPECT_CALL(*connection_.get(), dns_servers())
884 .WillRepeatedly(ReturnRef(kDNSServers));
885 EXPECT_TRUE(RequestPortalDetection());
886}
887
888TEST_F(DevicePortalDetectionTest, NotConnected) {
889 EXPECT_CALL(*service_.get(), IsConnected())
890 .WillOnce(Return(false));
891 SetServiceConnectedState(Service::kStatePortal);
892 // We don't check for the portal detector to be reset here, because
893 // it would have been reset as a part of disconnection.
894}
895
896TEST_F(DevicePortalDetectionTest, NotPortal) {
897 EXPECT_CALL(*service_.get(), IsConnected())
898 .WillOnce(Return(true));
899 EXPECT_CALL(*service_.get(), SetState(Service::kStateOnline));
900 SetServiceConnectedState(Service::kStateOnline);
901 ExpectPortalDetectorReset();
902}
903
904TEST_F(DevicePortalDetectionTest, NotDefault) {
905 EXPECT_CALL(*service_.get(), IsConnected())
906 .WillOnce(Return(true));
907 EXPECT_CALL(*connection_.get(), is_default())
908 .WillOnce(Return(false));
909 EXPECT_CALL(*service_.get(), SetState(Service::kStatePortal));
910 SetServiceConnectedState(Service::kStatePortal);
911 ExpectPortalDetectorReset();
912}
913
914TEST_F(DevicePortalDetectionTest, PortalIntervalIsZero) {
915 EXPECT_CALL(*service_.get(), IsConnected())
916 .WillOnce(Return(true));
917 EXPECT_CALL(*connection_.get(), is_default())
918 .WillOnce(Return(true));
919 EXPECT_CALL(manager_, GetPortalCheckInterval())
920 .WillOnce(Return(0));
921 EXPECT_CALL(*service_.get(), SetState(Service::kStatePortal));
922 SetServiceConnectedState(Service::kStatePortal);
923 ExpectPortalDetectorReset();
924}
925
926TEST_F(DevicePortalDetectionTest, RestartPortalDetection) {
927 EXPECT_CALL(*service_.get(), IsConnected())
928 .WillOnce(Return(true));
929 EXPECT_CALL(*connection_.get(), is_default())
930 .WillOnce(Return(true));
931 const int kPortalDetectionInterval = 10;
932 EXPECT_CALL(manager_, GetPortalCheckInterval())
933 .Times(AtLeast(1))
934 .WillRepeatedly(Return(kPortalDetectionInterval));
935 const string kPortalCheckURL("http://portal");
936 EXPECT_CALL(manager_, GetPortalCheckURL())
937 .WillOnce(ReturnRef(kPortalCheckURL));
938 EXPECT_CALL(*portal_detector_, StartAfterDelay(kPortalCheckURL,
939 kPortalDetectionInterval))
940 .WillOnce(Return(true));
941 EXPECT_CALL(*service_.get(), SetState(Service::kStatePortal));
942 SetServiceConnectedState(Service::kStatePortal);
943 ExpectPortalDetectorSet();
944}
945
Paul Stewartc8860612012-09-28 07:36:21 -0700946TEST_F(DevicePortalDetectionTest, CancelledOnSelectService) {
947 ExpectPortalDetectorSet();
948 EXPECT_CALL(*service_.get(), state())
949 .WillOnce(Return(Service::kStateIdle));
950 EXPECT_CALL(*service_.get(), SetState(_));
951 EXPECT_CALL(*service_.get(), SetConnection(_));
952 SelectService(NULL);
953 ExpectPortalDetectorReset();
954}
955
Paul Stewart6ff27f52012-07-11 06:51:41 -0700956class DeviceByteCountTest : public DeviceTest {
957 public:
958 DeviceByteCountTest()
959 : manager_(control_interface(),
960 dispatcher(),
961 metrics(),
962 glib()),
963 rx_byte_count_(0),
964 tx_byte_count_(0),
965 rx_stored_byte_count_(0),
966 tx_stored_byte_count_(0) {}
967 virtual ~DeviceByteCountTest() {}
968
969 virtual void SetUp() {
970 DeviceTest::SetUp();
971 EXPECT_CALL(manager_, device_info()).WillRepeatedly(Return(&device_info_));
972 EXPECT_CALL(device_info_, GetByteCounts(kDeviceInterfaceIndex, _, _))
973 .WillRepeatedly(Invoke(this, &DeviceByteCountTest::ReturnByteCounts));
974 const string id = device_->GetStorageIdentifier();
975 EXPECT_CALL(storage_, ContainsGroup(id)).WillRepeatedly(Return(true));
976 EXPECT_CALL(storage_, GetUint64(id, Device::kStorageReceiveByteCount, _))
977 .WillRepeatedly(
978 Invoke(this, &DeviceByteCountTest::GetStoredReceiveCount));
979 EXPECT_CALL(storage_, GetUint64(id, Device::kStorageTransmitByteCount, _))
980 .WillRepeatedly(
981 Invoke(this, &DeviceByteCountTest::GetStoredTransmitCount));
982 }
983
984 bool ReturnByteCounts(int interface_index, uint64 *rx, uint64 *tx) {
985 *rx = rx_byte_count_;
986 *tx = tx_byte_count_;
987 return true;
988 }
989
990 bool ExpectByteCounts(DeviceRefPtr device,
991 int64 expected_rx, int64 expected_tx) {
Ben Chanb061f892013-02-27 17:46:55 -0800992 int64 actual_rx = device->GetReceiveByteCount();
993 int64 actual_tx = device->GetTransmitByteCount();
Paul Stewart6ff27f52012-07-11 06:51:41 -0700994 EXPECT_EQ(expected_rx, actual_rx);
995 EXPECT_EQ(expected_tx, actual_tx);
996 return expected_rx == actual_rx && expected_tx == actual_tx;
997 }
998
999 void ExpectSavedCounts(DeviceRefPtr device,
1000 int64 expected_rx, int64 expected_tx) {
1001 EXPECT_CALL(storage_,
1002 SetUint64(_, Device::kStorageReceiveByteCount, expected_rx))
1003 .WillOnce(Return(true));
1004 EXPECT_CALL(storage_,
1005 SetUint64(_, Device::kStorageTransmitByteCount, expected_tx))
1006 .WillOnce(Return(true));
1007 EXPECT_TRUE(device->Save(&storage_));
1008 }
1009
1010
1011 bool GetStoredReceiveCount(const string &group, const string &key,
1012 uint64 *value) {
1013 if (!rx_stored_byte_count_) {
1014 return false;
1015 }
1016 *value = rx_stored_byte_count_;
1017 return true;
1018 }
1019
1020 bool GetStoredTransmitCount(const string &group, const string &key,
1021 uint64 *value) {
1022 if (!tx_stored_byte_count_) {
1023 return false;
1024 }
1025 *value = tx_stored_byte_count_;
1026 return true;
1027 }
1028
1029 protected:
1030 NiceMock<MockManager> manager_;
1031 NiceMock<MockStore> storage_;
1032 uint64 rx_byte_count_;
1033 uint64 tx_byte_count_;
1034 uint64 rx_stored_byte_count_;
1035 uint64 tx_stored_byte_count_;
1036};
1037
1038
1039TEST_F(DeviceByteCountTest, GetByteCounts) {
1040 // On Device initialization, byte counts should be zero, independent of
1041 // the byte counts reported by the interface.
1042 rx_byte_count_ = 123;
1043 tx_byte_count_ = 456;
1044 DeviceRefPtr device(new TestDevice(control_interface(),
1045 dispatcher(),
1046 NULL,
1047 &manager_,
1048 kDeviceName,
1049 kDeviceAddress,
1050 kDeviceInterfaceIndex,
1051 Technology::kUnknown));
1052 EXPECT_TRUE(ExpectByteCounts(device, 0, 0));
1053
1054 // Device should report any increase in the byte counts reported in the
1055 // interface.
1056 const int64 delta_rx_count = 789;
1057 const int64 delta_tx_count = 12;
1058 rx_byte_count_ += delta_rx_count;
1059 tx_byte_count_ += delta_tx_count;
1060 EXPECT_TRUE(ExpectByteCounts(device, delta_rx_count, delta_tx_count));
1061
1062 // Expect the correct values to be saved to the profile.
1063 ExpectSavedCounts(device, delta_rx_count, delta_tx_count);
1064
1065 // If Device is loaded from a profile that does not contain stored byte
1066 // counts, the byte counts reported should remain unchanged.
1067 EXPECT_TRUE(device->Load(&storage_));
1068 EXPECT_TRUE(ExpectByteCounts(device, delta_rx_count, delta_tx_count));
1069
1070 // If Device is loaded from a profile that contains stored byte
1071 // counts, the byte counts reported should now reflect the stored values.
1072 rx_stored_byte_count_ = 345;
1073 tx_stored_byte_count_ = 678;
1074 EXPECT_TRUE(device->Load(&storage_));
1075 EXPECT_TRUE(ExpectByteCounts(
1076 device, rx_stored_byte_count_, tx_stored_byte_count_));
1077
1078 // Increases to the interface receive count should be reflected as offsets
1079 // to the stored byte counts.
1080 rx_byte_count_ += delta_rx_count;
1081 tx_byte_count_ += delta_tx_count;
1082 EXPECT_TRUE(ExpectByteCounts(device,
1083 rx_stored_byte_count_ + delta_rx_count,
1084 tx_stored_byte_count_ + delta_tx_count));
1085
1086 // Expect the correct values to be saved to the profile.
1087 ExpectSavedCounts(device,
1088 rx_stored_byte_count_ + delta_rx_count,
1089 tx_stored_byte_count_ + delta_tx_count);
1090
1091 // Expect that after resetting byte counts, read-back values return to zero,
1092 // and that the device requests this information to be persisted.
1093 EXPECT_CALL(manager_, UpdateDevice(device));
1094 device->ResetByteCounters();
1095 EXPECT_TRUE(ExpectByteCounts(device, 0, 0));
1096}
1097
Arman Ugurayf84a4242013-04-09 20:01:07 -07001098class DeviceHealthCheckerTest : public DeviceTest {
1099 public:
1100 DeviceHealthCheckerTest()
1101 : connection_(new StrictMock<MockConnection>(&device_info_)),
Prathmesh Prabhuba99b592013-04-17 15:13:14 -07001102 ip_address_store_(new MockIPAddressStore()),
Arman Ugurayf84a4242013-04-09 20:01:07 -07001103 weak_ptr_factory_(this) {}
1104
1105 protected:
1106 void SetUp() {
1107 DeviceTest::SetUp();
1108
1109 string default_str;
1110 vector<string> default_vector;
1111
1112 ON_CALL(*connection_.get(), interface_name())
1113 .WillByDefault(ReturnRef(default_str));
1114 ON_CALL(*connection_.get(), dns_servers())
1115 .WillByDefault(ReturnRef(default_vector));
1116 EXPECT_CALL(*connection_.get(), interface_name())
1117 .Times(AnyNumber());
1118 EXPECT_CALL(*connection_.get(), dns_servers())
1119 .Times(AnyNumber());
Prathmesh Prabhuba99b592013-04-17 15:13:14 -07001120 EXPECT_CALL(*ip_address_store_.get(), AddUnique(_)).Times(AnyNumber());
Arman Ugurayf84a4242013-04-09 20:01:07 -07001121
1122 mock_health_checker_.reset(
1123 new MockConnectionHealthChecker(
1124 connection_,
1125 NULL,
Prathmesh Prabhuba99b592013-04-17 15:13:14 -07001126 ip_address_store_.get(),
Arman Ugurayf84a4242013-04-09 20:01:07 -07001127 Bind(&DeviceHealthCheckerTest::OnConnectionHealthCheckerResult,
1128 weak_ptr_factory_.GetWeakPtr())));
1129 }
1130
1131 void SetMockHealthChecker() {
1132 device_->set_health_checker(mock_health_checker_.release());
1133 EXPECT_TRUE(device_->health_checker_.get());
1134 }
1135
Prathmesh Prabhuba99b592013-04-17 15:13:14 -07001136 void SetMockConnection() {
1137 device_->connection_ = connection_;
1138 }
1139
Arman Ugurayf84a4242013-04-09 20:01:07 -07001140 void OnConnectionHealthCheckerResult(
1141 ConnectionHealthChecker::Result result) {
1142 }
1143
1144 scoped_refptr<MockConnection> connection_;
1145 scoped_ptr<MockConnectionHealthChecker> mock_health_checker_;
Prathmesh Prabhuba99b592013-04-17 15:13:14 -07001146 scoped_ptr<MockIPAddressStore> ip_address_store_;
Arman Ugurayf84a4242013-04-09 20:01:07 -07001147 base::WeakPtrFactory<DeviceHealthCheckerTest> weak_ptr_factory_;
1148};
1149
Arman Ugurayf84a4242013-04-09 20:01:07 -07001150TEST_F(DeviceHealthCheckerTest, RequestConnectionHealthCheck) {
1151 EXPECT_FALSE(device_->health_checker_.get());
1152 MockConnectionHealthChecker *health_checker = mock_health_checker_.get();
1153 SetMockHealthChecker();
Arman Ugurayf84a4242013-04-09 20:01:07 -07001154 EXPECT_CALL(*health_checker, health_check_in_progress())
Arman Ugurayf84a4242013-04-09 20:01:07 -07001155 .WillOnce(Return(true));
Prathmesh Prabhuade9b9a2013-04-22 18:01:19 -07001156 EXPECT_CALL(*health_checker, Start()).Times(0);
Arman Ugurayf84a4242013-04-09 20:01:07 -07001157 device_->RequestConnectionHealthCheck();
1158 Mock::VerifyAndClearExpectations(health_checker);
1159
Arman Ugurayf84a4242013-04-09 20:01:07 -07001160 EXPECT_CALL(*health_checker, health_check_in_progress())
Arman Ugurayf84a4242013-04-09 20:01:07 -07001161 .WillOnce(Return(false));
Prathmesh Prabhuade9b9a2013-04-22 18:01:19 -07001162 EXPECT_CALL(*health_checker, Start()).Times(1);
Arman Ugurayf84a4242013-04-09 20:01:07 -07001163 device_->RequestConnectionHealthCheck();
1164 Mock::VerifyAndClearExpectations(health_checker);
1165}
1166
Darin Petkovafa6fc42011-06-21 16:21:08 -07001167} // namespace shill