blob: 33a00f5965cab04b10452c709d75f1ccd158a0f4 [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>
Alex Vakulenkoa41ab512014-07-23 14:24:23 -07009#include <linux/if.h> // NOLINT - Needs typedefs from sys/socket.h.
Chris Masone34af2182011-08-22 11:59:36 -070010
Chris Masone3bd3c8c2011-06-13 08:20:26 -070011#include <map>
Ben Chancd477322014-10-17 14:19:30 -070012#include <memory>
Chris Masone3bd3c8c2011-06-13 08:20:26 -070013#include <string>
14#include <vector>
15
Arman Ugurayf84a4242013-04-09 20:01:07 -070016#include <base/bind.h>
17#include <base/callback.h>
Ben Chancc67c522014-09-03 07:19:18 -070018#include <base/macros.h>
Arman Ugurayf84a4242013-04-09 20:01:07 -070019#include <base/memory/weak_ptr.h>
Chris Masone3bd3c8c2011-06-13 08:20:26 -070020#include <chromeos/dbus/service_constants.h>
Chris Masone34af2182011-08-22 11:59:36 -070021#include <dbus-c++/dbus.h>
Chris Masone3bd3c8c2011-06-13 08:20:26 -070022#include <gmock/gmock.h>
Chris Masone34af2182011-08-22 11:59:36 -070023#include <gtest/gtest.h>
Chris Masone3bd3c8c2011-06-13 08:20:26 -070024
Rebecca Silberstein3d49ea42014-08-21 11:20:50 -070025#include "shill/connectivity_trial.h"
Chris Masone3bd3c8c2011-06-13 08:20:26 -070026#include "shill/dbus_adaptor.h"
Peter Qiu675d0b02015-06-03 13:08:09 -070027#include "shill/dhcp/dhcp_provider.h"
28#include "shill/dhcp/mock_dhcp_config.h"
29#include "shill/dhcp/mock_dhcp_provider.h"
Paul Stewart26b327e2011-10-19 11:38:09 -070030#include "shill/event_dispatcher.h"
Chris Masone95207da2011-06-29 16:50:49 -070031#include "shill/mock_adaptors.h"
Paul Stewart20088d82012-02-16 06:58:55 -080032#include "shill/mock_connection.h"
Arman Ugurayf84a4242013-04-09 20:01:07 -070033#include "shill/mock_connection_health_checker.h"
Ben Chanb061f892013-02-27 17:46:55 -080034#include "shill/mock_control.h"
Chris Masone3bd3c8c2011-06-13 08:20:26 -070035#include "shill/mock_device.h"
Paul Stewart20088d82012-02-16 06:58:55 -080036#include "shill/mock_device_info.h"
Peter Qiud670d032014-06-03 15:04:43 -070037#include "shill/mock_dns_server_tester.h"
Peter Qiu25f1be62014-08-12 10:42:27 -070038#include "shill/mock_event_dispatcher.h"
Chris Masone3bd3c8c2011-06-13 08:20:26 -070039#include "shill/mock_glib.h"
Prathmesh Prabhuba99b592013-04-17 15:13:14 -070040#include "shill/mock_ip_address_store.h"
Chris Masone34af2182011-08-22 11:59:36 -070041#include "shill/mock_ipconfig.h"
Paul Stewart036dba02012-08-07 12:34:41 -070042#include "shill/mock_link_monitor.h"
Paul Stewart20088d82012-02-16 06:58:55 -080043#include "shill/mock_manager.h"
Thieu Le85e050b2012-03-13 15:04:38 -070044#include "shill/mock_metrics.h"
Paul Stewartc681fa02012-03-02 19:40:04 -080045#include "shill/mock_portal_detector.h"
Paul Stewart03dba0b2011-08-22 16:32:45 -070046#include "shill/mock_service.h"
Chris Masone5dec5f42011-07-22 14:07:55 -070047#include "shill/mock_store.h"
Ben Chanb061f892013-02-27 17:46:55 -080048#include "shill/mock_traffic_monitor.h"
Peter Qiu8d6b5972014-10-28 15:33:34 -070049#include "shill/net/mock_rtnl_handler.h"
50#include "shill/net/mock_time.h"
51#include "shill/net/ndisc.h"
Paul Stewart20088d82012-02-16 06:58:55 -080052#include "shill/portal_detector.h"
Chris Masone3bd3c8c2011-06-13 08:20:26 -070053#include "shill/property_store_unittest.h"
mukesh agrawalcc0fded2012-05-09 13:40:58 -070054#include "shill/static_ip_parameters.h"
Gaurav Shah435de2c2011-11-17 19:01:07 -080055#include "shill/technology.h"
Paul Stewartd4f26482014-04-25 19:12:03 -070056#include "shill/testing.h"
Paul Stewartfa11e282013-12-02 22:04:25 -080057#include "shill/tethering.h"
Ben Chanb061f892013-02-27 17:46:55 -080058#include "shill/traffic_monitor.h"
Chris Masone3bd3c8c2011-06-13 08:20:26 -070059
Arman Ugurayf84a4242013-04-09 20:01:07 -070060using base::Bind;
61using base::Callback;
Chris Masone3bd3c8c2011-06-13 08:20:26 -070062using std::map;
63using std::string;
64using std::vector;
65using ::testing::_;
mukesh agrawalcc0fded2012-05-09 13:40:58 -070066using ::testing::AnyNumber;
Chris Masone5dec5f42011-07-22 14:07:55 -070067using ::testing::AtLeast;
Arman Ugurayf84a4242013-04-09 20:01:07 -070068using ::testing::DefaultValue;
Paul Stewartd4f26482014-04-25 19:12:03 -070069using ::testing::DoAll;
Paul Stewart6ff27f52012-07-11 06:51:41 -070070using ::testing::Invoke;
Thieu Le85e050b2012-03-13 15:04:38 -070071using ::testing::Mock;
Chris Masone3bd3c8c2011-06-13 08:20:26 -070072using ::testing::NiceMock;
73using ::testing::Return;
Paul Stewart20088d82012-02-16 06:58:55 -080074using ::testing::ReturnRef;
Paul Stewartd4f26482014-04-25 19:12:03 -070075using ::testing::SetArgPointee;
Ben Chanbcc6e012013-11-04 14:28:37 -080076using ::testing::StrEq;
Paul Stewart03dba0b2011-08-22 16:32:45 -070077using ::testing::StrictMock;
Chris Masone3bd3c8c2011-06-13 08:20:26 -070078using ::testing::Test;
Chris Masone34af2182011-08-22 11:59:36 -070079using ::testing::Values;
Darin Petkovafa6fc42011-06-21 16:21:08 -070080
81namespace shill {
82
Eric Shienbrood9a245532012-03-07 14:20:39 -050083class TestDevice : public Device {
84 public:
Paul Stewart3b30ca52015-06-16 13:13:10 -070085 TestDevice(ControlInterface* control_interface,
86 EventDispatcher* dispatcher,
87 Metrics* metrics,
88 Manager* manager,
89 const std::string& link_name,
90 const std::string& address,
Eric Shienbrood9a245532012-03-07 14:20:39 -050091 int interface_index,
92 Technology::Identifier technology)
93 : Device(control_interface, dispatcher, metrics, manager, link_name,
Ben Chanbcc6e012013-11-04 14:28:37 -080094 address, interface_index, technology) {
95 ON_CALL(*this, IsIPv6Allowed())
96 .WillByDefault(Invoke(this, &TestDevice::DeviceIsIPv6Allowed));
97 ON_CALL(*this, SetIPFlag(_, _, _))
98 .WillByDefault(Invoke(this, &TestDevice::DeviceSetIPFlag));
Peter Qiudc335f82014-05-15 10:33:17 -070099 ON_CALL(*this, IsTrafficMonitorEnabled())
100 .WillByDefault(Invoke(this,
101 &TestDevice::DeviceIsTrafficMonitorEnabled));
Peter Qiu6f5618b2014-06-05 15:19:01 -0700102 ON_CALL(*this, StartDNSTest(_, _, _))
103 .WillByDefault(Invoke(
104 this,
105 &TestDevice::DeviceStartDNSTest));
Ben Chanbcc6e012013-11-04 14:28:37 -0800106 }
107
Eric Shienbrood9a245532012-03-07 14:20:39 -0500108 ~TestDevice() {}
Ben Chanbcc6e012013-11-04 14:28:37 -0800109
Paul Stewart3b30ca52015-06-16 13:13:10 -0700110 virtual void Start(Error* error,
111 const EnabledStateChangedCallback& callback) {
Jason Glasgow4a490792012-04-10 15:02:05 -0400112 DCHECK(error);
113 }
Ben Chanbcc6e012013-11-04 14:28:37 -0800114
Paul Stewart3b30ca52015-06-16 13:13:10 -0700115 virtual void Stop(Error* error,
116 const EnabledStateChangedCallback& callback) {
Jason Glasgow4a490792012-04-10 15:02:05 -0400117 DCHECK(error);
118 }
Ben Chanbcc6e012013-11-04 14:28:37 -0800119
120 MOCK_CONST_METHOD0(IsIPv6Allowed, bool());
Peter Qiudc335f82014-05-15 10:33:17 -0700121 MOCK_CONST_METHOD0(IsTrafficMonitorEnabled, bool());
Ben Chanbcc6e012013-11-04 14:28:37 -0800122
123 MOCK_METHOD3(SetIPFlag, bool(IPAddress::Family family,
Paul Stewart3b30ca52015-06-16 13:13:10 -0700124 const std::string& flag,
125 const std::string& value));
Ben Chanbcc6e012013-11-04 14:28:37 -0800126
Peter Qiu6f5618b2014-06-05 15:19:01 -0700127 MOCK_METHOD3(StartDNSTest, bool(
Paul Stewart3b30ca52015-06-16 13:13:10 -0700128 const std::vector<std::string>& dns_servers,
Peter Qiu6f5618b2014-06-05 15:19:01 -0700129 const bool retry_until_success,
Paul Stewart3b30ca52015-06-16 13:13:10 -0700130 const base::Callback<void(const DNSServerTester::Status)>& callback));
Peter Qiu6f5618b2014-06-05 15:19:01 -0700131
Ben Chanbcc6e012013-11-04 14:28:37 -0800132 virtual bool DeviceIsIPv6Allowed() const {
133 return Device::IsIPv6Allowed();
134 }
135
Peter Qiudc335f82014-05-15 10:33:17 -0700136 virtual bool DeviceIsTrafficMonitorEnabled() const {
137 return Device::IsTrafficMonitorEnabled();
138 }
139
Ben Chanbcc6e012013-11-04 14:28:37 -0800140 virtual bool DeviceSetIPFlag(IPAddress::Family family,
Paul Stewart3b30ca52015-06-16 13:13:10 -0700141 const std::string& flag,
142 const std::string& value) {
Ben Chanbcc6e012013-11-04 14:28:37 -0800143 return Device::SetIPFlag(family, flag, value);
144 }
Peter Qiu6f5618b2014-06-05 15:19:01 -0700145
146 virtual bool DeviceStartDNSTest(
Paul Stewart3b30ca52015-06-16 13:13:10 -0700147 const std::vector<std::string>& dns_servers,
Peter Qiu6f5618b2014-06-05 15:19:01 -0700148 const bool retry_until_success,
Paul Stewart3b30ca52015-06-16 13:13:10 -0700149 const base::Callback<void(const DNSServerTester::Status)>& callback) {
Peter Qiu6f5618b2014-06-05 15:19:01 -0700150 return Device::StartDNSTest(dns_servers, retry_until_success, callback);
151 }
Eric Shienbrood9a245532012-03-07 14:20:39 -0500152};
153
Chris Masone3bd3c8c2011-06-13 08:20:26 -0700154class DeviceTest : public PropertyStoreTest {
Darin Petkovafa6fc42011-06-21 16:21:08 -0700155 public:
156 DeviceTest()
Eric Shienbrood9a245532012-03-07 14:20:39 -0500157 : device_(new TestDevice(control_interface(),
158 dispatcher(),
Ben Chancc225ef2014-09-30 13:26:51 -0700159 nullptr,
Eric Shienbrood9a245532012-03-07 14:20:39 -0500160 manager(),
161 kDeviceName,
162 kDeviceAddress,
163 kDeviceInterfaceIndex,
164 Technology::kUnknown)),
Ben Chancc225ef2014-09-30 13:26:51 -0700165 device_info_(control_interface(), nullptr, nullptr, nullptr),
Thieu Le6c1e3bb2013-02-06 15:20:35 -0800166 metrics_(dispatcher()) {
Chris Masone2176a882011-09-14 22:29:15 -0700167 DHCPProvider::GetInstance()->glib_ = glib();
168 DHCPProvider::GetInstance()->control_interface_ = control_interface();
mukesh agrawalcc0fded2012-05-09 13:40:58 -0700169 DHCPProvider::GetInstance()->dispatcher_ = dispatcher();
Peter Qiua0572032014-09-26 10:07:37 -0700170 device_->time_ = &time_;
Darin Petkovafa6fc42011-06-21 16:21:08 -0700171 }
Chris Masone3bd3c8c2011-06-13 08:20:26 -0700172 virtual ~DeviceTest() {}
Darin Petkovafa6fc42011-06-21 16:21:08 -0700173
mukesh agrawal5c4dd0b2011-09-14 13:53:14 -0700174 virtual void SetUp() {
Thieu Le85e050b2012-03-13 15:04:38 -0700175 device_->metrics_ = &metrics_;
mukesh agrawal5c4dd0b2011-09-14 13:53:14 -0700176 device_->rtnl_handler_ = &rtnl_handler_;
177 }
178
Darin Petkovafa6fc42011-06-21 16:21:08 -0700179 protected:
Chris Masone626719f2011-08-18 16:58:48 -0700180 static const char kDeviceName[];
181 static const char kDeviceAddress[];
Thieu Lefb46caf2012-03-08 11:57:15 -0800182 static const int kDeviceInterfaceIndex;
Chris Masone626719f2011-08-18 16:58:48 -0700183
Paul Stewart3b30ca52015-06-16 13:13:10 -0700184 void OnIPConfigUpdated(const IPConfigRefPtr& ipconfig) {
Samuel Tan3c3c36a2014-12-16 16:53:19 -0800185 device_->OnIPConfigUpdated(ipconfig, true);
Paul Stewartc5099532013-12-12 07:53:15 -0800186 }
187
Paul Stewart3b30ca52015-06-16 13:13:10 -0700188 void OnIPConfigFailed(const IPConfigRefPtr& ipconfig) {
Paul Stewartc5099532013-12-12 07:53:15 -0800189 device_->OnIPConfigFailed(ipconfig);
Paul Stewart20088d82012-02-16 06:58:55 -0800190 }
191
Paul Stewart3b30ca52015-06-16 13:13:10 -0700192 void OnIPConfigExpired(const IPConfigRefPtr& ipconfig) {
Paul Stewart1f916e42013-12-23 09:52:54 -0800193 device_->OnIPConfigExpired(ipconfig);
194 }
195
Paul Stewart20088d82012-02-16 06:58:55 -0800196 void SelectService(const ServiceRefPtr service) {
197 device_->SelectService(service);
198 }
199
Paul Stewart20088d82012-02-16 06:58:55 -0800200 void SetConnection(ConnectionRefPtr connection) {
201 device_->connection_ = connection;
202 }
203
Paul Stewart3b30ca52015-06-16 13:13:10 -0700204 void SetLinkMonitor(LinkMonitor* link_monitor) {
Paul Stewart036dba02012-08-07 12:34:41 -0700205 device_->set_link_monitor(link_monitor); // Passes ownership.
206 }
207
Paul Stewartc8860612012-09-28 07:36:21 -0700208 bool HasLinkMonitor() {
209 return device_->link_monitor();
210 }
211
Paul Stewart036dba02012-08-07 12:34:41 -0700212 bool StartLinkMonitor() {
213 return device_->StartLinkMonitor();
214 }
215
216 void StopLinkMonitor() {
217 device_->StopLinkMonitor();
218 }
219
Paul Stewart3b30ca52015-06-16 13:13:10 -0700220 uint64_t GetLinkMonitorResponseTime(Error* error) {
Paul Stewart036dba02012-08-07 12:34:41 -0700221 return device_->GetLinkMonitorResponseTime(error);
222 }
223
Paul Stewart3b30ca52015-06-16 13:13:10 -0700224 void SetTrafficMonitor(TrafficMonitor* traffic_monitor) {
Peter Qiudc335f82014-05-15 10:33:17 -0700225 device_->set_traffic_monitor(traffic_monitor); // Passes ownership.
226 }
227
228 void StartTrafficMonitor() {
229 device_->StartTrafficMonitor();
230 }
231
232 void StopTrafficMonitor() {
233 device_->StopTrafficMonitor();
234 }
235
236 void NetworkProblemDetected(int reason) {
237 device_->OnEncounterNetworkProblem(reason);
238 }
239
Paul Stewart3b30ca52015-06-16 13:13:10 -0700240 DeviceMockAdaptor* GetDeviceMockAdaptor() {
241 return dynamic_cast<DeviceMockAdaptor*>(device_->adaptor_.get());
Paul Stewartd4f26482014-04-25 19:12:03 -0700242 }
243
Paul Stewart3b30ca52015-06-16 13:13:10 -0700244 void SetManager(Manager* manager) {
Paul Stewart036dba02012-08-07 12:34:41 -0700245 device_->manager_ = manager;
246 }
247
Peter Qiua388fdb2015-04-03 10:31:22 -0700248 MOCK_METHOD0(ReliableLinkCallback, void());
249 void SetReliableLinkCallback() {
250 device_->reliable_link_callback_.Reset(
251 base::Bind(&DeviceTest::ReliableLinkCallback, base::Unretained(this)));
252 }
253
254 bool ReliableLinkCallbackIsCancelled() {
255 return device_->reliable_link_callback_.IsCancelled();
256 }
257
Peter Qiub25083f2014-08-25 13:22:31 -0700258 void SetupIPv6Config() {
259 const char kAddress[] = "2001:db8::1";
260 const char kDnsServer1[] = "2001:db8::2";
261 const char kDnsServer2[] = "2001:db8::3";
262 IPConfig::Properties properties;
263 properties.address = kAddress;
264 properties.dns_servers.push_back(kDnsServer1);
265 properties.dns_servers.push_back(kDnsServer2);
266
267 device_->ip6config_ = new MockIPConfig(control_interface(), kDeviceName);
268 device_->ip6config_->set_properties(properties);
269 }
270
Paul Stewart3b30ca52015-06-16 13:13:10 -0700271 bool SetHostname(const string& hostname) {
Paul Stewart208a97e2015-05-13 09:11:12 -0700272 return device_->SetHostname(hostname);
273 }
274
Darin Petkovafa6fc42011-06-21 16:21:08 -0700275 MockControl control_interface_;
Ben Chanbcc6e012013-11-04 14:28:37 -0800276 scoped_refptr<TestDevice> device_;
Paul Stewartc681fa02012-03-02 19:40:04 -0800277 MockDeviceInfo device_info_;
Thieu Le85e050b2012-03-13 15:04:38 -0700278 MockMetrics metrics_;
Peter Qiua0572032014-09-26 10:07:37 -0700279 MockTime time_;
mukesh agrawal5c4dd0b2011-09-14 13:53:14 -0700280 StrictMock<MockRTNLHandler> rtnl_handler_;
Darin Petkovafa6fc42011-06-21 16:21:08 -0700281};
282
Chris Masone626719f2011-08-18 16:58:48 -0700283const char DeviceTest::kDeviceName[] = "testdevice";
284const char DeviceTest::kDeviceAddress[] = "address";
Thieu Lefb46caf2012-03-08 11:57:15 -0800285const int DeviceTest::kDeviceInterfaceIndex = 0;
Chris Masone626719f2011-08-18 16:58:48 -0700286
Chris Masone3bd3c8c2011-06-13 08:20:26 -0700287TEST_F(DeviceTest, Contains) {
Ben Chan923a5022013-09-20 11:23:23 -0700288 EXPECT_TRUE(device_->store().Contains(kNameProperty));
mukesh agrawalde29fa82011-09-16 16:16:36 -0700289 EXPECT_FALSE(device_->store().Contains(""));
Chris Masone3bd3c8c2011-06-13 08:20:26 -0700290}
291
Chris Masonea8a2c252011-06-27 22:16:30 -0700292TEST_F(DeviceTest, GetProperties) {
293 map<string, ::DBus::Variant> props;
294 Error error(Error::kInvalidProperty, "");
Eric Shienbrood9a245532012-03-07 14:20:39 -0500295 ::DBus::Error dbus_error;
296 DBusAdaptor::GetProperties(device_->store(), &props, &dbus_error);
Ben Chan923a5022013-09-20 11:23:23 -0700297 ASSERT_FALSE(props.find(kNameProperty) == props.end());
298 EXPECT_EQ(props[kNameProperty].reader().get_string(), string(kDeviceName));
Chris Masonea8a2c252011-06-27 22:16:30 -0700299}
300
Eric Shienbrood9a245532012-03-07 14:20:39 -0500301// Note: there are currently no writeable Device properties that
302// aren't registered in a subclass.
303TEST_F(DeviceTest, SetReadOnlyProperty) {
Chris Masone3bd3c8c2011-06-13 08:20:26 -0700304 ::DBus::Error error;
Chris Masoneb925cc82011-06-22 15:39:57 -0700305 // Ensure that an attempt to write a R/O property returns InvalidArgs error.
mukesh agrawal6bb9e7c2012-01-30 14:57:54 -0800306 EXPECT_FALSE(DBusAdaptor::SetProperty(device_->mutable_store(),
Ben Chan923a5022013-09-20 11:23:23 -0700307 kAddressProperty,
mukesh agrawal6bb9e7c2012-01-30 14:57:54 -0800308 PropertyStoreTest::kStringV,
309 &error));
Chris Masone9d779932011-08-25 16:33:41 -0700310 EXPECT_EQ(invalid_args(), error.name());
Chris Masone3bd3c8c2011-06-13 08:20:26 -0700311}
312
mukesh agrawal8abd2f62012-01-30 14:56:14 -0800313TEST_F(DeviceTest, ClearReadOnlyProperty) {
314 ::DBus::Error error;
mukesh agrawal6bb9e7c2012-01-30 14:57:54 -0800315 EXPECT_FALSE(DBusAdaptor::SetProperty(device_->mutable_store(),
Ben Chan923a5022013-09-20 11:23:23 -0700316 kAddressProperty,
mukesh agrawal6bb9e7c2012-01-30 14:57:54 -0800317 PropertyStoreTest::kStringV,
318 &error));
mukesh agrawal8abd2f62012-01-30 14:56:14 -0800319}
320
321TEST_F(DeviceTest, ClearReadOnlyDerivedProperty) {
322 ::DBus::Error error;
mukesh agrawal6bb9e7c2012-01-30 14:57:54 -0800323 EXPECT_FALSE(DBusAdaptor::SetProperty(device_->mutable_store(),
Ben Chan923a5022013-09-20 11:23:23 -0700324 kIPConfigsProperty,
mukesh agrawal6bb9e7c2012-01-30 14:57:54 -0800325 PropertyStoreTest::kStringsV,
326 &error));
mukesh agrawal8abd2f62012-01-30 14:56:14 -0800327}
328
Darin Petkovafa6fc42011-06-21 16:21:08 -0700329TEST_F(DeviceTest, DestroyIPConfig) {
330 ASSERT_FALSE(device_->ipconfig_.get());
Chris Masone2176a882011-09-14 22:29:15 -0700331 device_->ipconfig_ = new IPConfig(control_interface(), kDeviceName);
Peter Qiu25f1be62014-08-12 10:42:27 -0700332 device_->ip6config_ = new IPConfig(control_interface(), kDeviceName);
Peter Qiud48fa0c2015-06-10 12:20:48 -0700333 device_->dhcpv6_config_ = new IPConfig(control_interface(), kDeviceName);
Darin Petkovafa6fc42011-06-21 16:21:08 -0700334 device_->DestroyIPConfig();
335 ASSERT_FALSE(device_->ipconfig_.get());
Peter Qiu25f1be62014-08-12 10:42:27 -0700336 ASSERT_FALSE(device_->ip6config_.get());
Peter Qiud48fa0c2015-06-10 12:20:48 -0700337 ASSERT_FALSE(device_->dhcpv6_config_.get());
Darin Petkovafa6fc42011-06-21 16:21:08 -0700338}
339
340TEST_F(DeviceTest, DestroyIPConfigNULL) {
341 ASSERT_FALSE(device_->ipconfig_.get());
Peter Qiu25f1be62014-08-12 10:42:27 -0700342 ASSERT_FALSE(device_->ip6config_.get());
Peter Qiud48fa0c2015-06-10 12:20:48 -0700343 ASSERT_FALSE(device_->dhcpv6_config_.get());
Darin Petkovafa6fc42011-06-21 16:21:08 -0700344 device_->DestroyIPConfig();
345 ASSERT_FALSE(device_->ipconfig_.get());
Peter Qiu25f1be62014-08-12 10:42:27 -0700346 ASSERT_FALSE(device_->ip6config_.get());
Peter Qiud48fa0c2015-06-10 12:20:48 -0700347 ASSERT_FALSE(device_->dhcpv6_config_.get());
Darin Petkovafa6fc42011-06-21 16:21:08 -0700348}
349
Paul Stewart2bf1d352011-12-06 15:02:55 -0800350TEST_F(DeviceTest, AcquireIPConfig) {
Chris Masone2176a882011-09-14 22:29:15 -0700351 device_->ipconfig_ = new IPConfig(control_interface(), "randomname");
Ben Chancd477322014-10-17 14:19:30 -0700352 std::unique_ptr<MockDHCPProvider> dhcp_provider(new MockDHCPProvider());
Jorge Lucangeli Obesad43cc62012-04-11 16:25:43 -0700353 device_->dhcp_provider_ = dhcp_provider.get();
354 scoped_refptr<MockDHCPConfig> dhcp_config(new MockDHCPConfig(
355 control_interface(),
356 kDeviceName));
Peter Qiud48fa0c2015-06-10 12:20:48 -0700357#ifndef DISABLE_DHCPV6
358 MockManager manager(control_interface(),
359 dispatcher(),
360 metrics(),
361 glib());
362 manager.set_mock_device_info(&device_info_);
363 SetManager(&manager);
364
365 device_->dhcpv6_config_ = new IPConfig(control_interface(), "randomname");
366 scoped_refptr<MockDHCPConfig> dhcpv6_config(
367 new MockDHCPConfig(control_interface(), kDeviceName));
368
369 EXPECT_CALL(manager, IsDHCPv6EnabledForDevice(kDeviceName))
370 .WillOnce(Return(true));
371 EXPECT_CALL(*dhcp_provider, CreateIPv6Config(_, _))
372 .WillOnce(Return(dhcpv6_config));
373 EXPECT_CALL(*dhcpv6_config, RequestIP()).WillOnce(Return(true));
374#endif // DISABLE_DHCPV6
375
Peter Qiu8e0151e2015-06-04 09:41:47 -0700376 EXPECT_CALL(*dhcp_provider, CreateIPv4Config(_, _, _, _))
Jorge Lucangeli Obesad43cc62012-04-11 16:25:43 -0700377 .WillOnce(Return(dhcp_config));
378 EXPECT_CALL(*dhcp_config, RequestIP())
Peter Qiud48fa0c2015-06-10 12:20:48 -0700379 .WillOnce(Return(true));
380 EXPECT_TRUE(device_->AcquireIPConfig());
Darin Petkovafa6fc42011-06-21 16:21:08 -0700381 ASSERT_TRUE(device_->ipconfig_.get());
382 EXPECT_EQ(kDeviceName, device_->ipconfig_->device_name());
Eric Shienbrood3e20a232012-02-16 11:35:56 -0500383 EXPECT_FALSE(device_->ipconfig_->update_callback_.is_null());
Peter Qiud48fa0c2015-06-10 12:20:48 -0700384#ifndef DISABLE_DHCPV6
385 EXPECT_EQ(kDeviceName, device_->dhcpv6_config_->device_name());
386 EXPECT_FALSE(device_->dhcpv6_config_->update_callback_.is_null());
387#endif // DISABLE_DHCPV6
Ben Chancc225ef2014-09-30 13:26:51 -0700388 device_->dhcp_provider_ = nullptr;
Darin Petkovafa6fc42011-06-21 16:21:08 -0700389}
390
Garret Kelly782cdce2015-04-01 16:39:16 -0400391TEST_F(DeviceTest, ConfigWithMinimumMTU) {
392 const int minimum_mtu = 1500;
393
394 MockManager manager(control_interface(),
395 dispatcher(),
396 metrics(),
397 glib());
398 manager.set_mock_device_info(&device_info_);
399 SetManager(&manager);
400
401 EXPECT_CALL(manager, GetMinimumMTU()).WillOnce(Return(minimum_mtu));
402
403 device_->ipconfig_ = new IPConfig(control_interface(), "anothername");
404 std::unique_ptr<MockDHCPProvider> dhcp_provider(new MockDHCPProvider());
405 device_->dhcp_provider_ = dhcp_provider.get();
406
407 scoped_refptr<MockDHCPConfig> dhcp_config(
408 new MockDHCPConfig(control_interface(), kDeviceName));
Peter Qiu8e0151e2015-06-04 09:41:47 -0700409 EXPECT_CALL(*dhcp_provider, CreateIPv4Config(_, _, _, _))
Garret Kelly782cdce2015-04-01 16:39:16 -0400410 .WillOnce(Return(dhcp_config));
411 EXPECT_CALL(*dhcp_config, set_minimum_mtu(minimum_mtu));
412
413 device_->AcquireIPConfig();
414}
415
Ben Chanbcc6e012013-11-04 14:28:37 -0800416TEST_F(DeviceTest, EnableIPv6) {
417 EXPECT_CALL(*device_, SetIPFlag(IPAddress::kFamilyIPv6,
418 StrEq(Device::kIPFlagDisableIPv6),
419 StrEq("0")))
420 .WillOnce(Return(true));
421 device_->EnableIPv6();
422}
423
424TEST_F(DeviceTest, EnableIPv6NotAllowed) {
425 EXPECT_CALL(*device_, IsIPv6Allowed()).WillOnce(Return(false));
426 EXPECT_CALL(*device_, SetIPFlag(_, _, _)).Times(0);
427 device_->EnableIPv6();
428}
429
Paul Stewart2cb3fa72014-11-13 01:43:12 -0800430TEST_F(DeviceTest, MultiHomed) {
431 // Device should have multi-homing disabled by default.
432 EXPECT_CALL(*device_, SetIPFlag(_, _, _)).Times(0);
433 device_->SetIsMultiHomed(false);
Alex Vakulenko0951ccb2014-12-10 12:52:31 -0800434 Mock::VerifyAndClearExpectations(device_.get());
Paul Stewart2cb3fa72014-11-13 01:43:12 -0800435
436 // Disabled -> enabled should change flags on the device.
437 EXPECT_CALL(*device_, SetIPFlag(IPAddress::kFamilyIPv4, StrEq("arp_announce"),
438 StrEq("2"))).WillOnce(Return(true));
439 EXPECT_CALL(*device_, SetIPFlag(IPAddress::kFamilyIPv4, StrEq("arp_ignore"),
440 StrEq("1"))).WillOnce(Return(true));
441 EXPECT_CALL(*device_, SetIPFlag(IPAddress::kFamilyIPv4, StrEq("rp_filter"),
442 StrEq("2"))).WillOnce(Return(true));
443 device_->SetIsMultiHomed(true);
Alex Vakulenko0951ccb2014-12-10 12:52:31 -0800444 Mock::VerifyAndClearExpectations(device_.get());
Paul Stewart2cb3fa72014-11-13 01:43:12 -0800445
446 // Enabled -> enabled should be a no-op.
447 EXPECT_CALL(*device_, SetIPFlag(_, _, _)).Times(0);
448 device_->SetIsMultiHomed(true);
449
450 // Disabling or enabling reverse-path filtering should also be a no-op
451 // (since it is disabled due to multi-homing).
452 device_->SetLooseRouting(false);
453 device_->SetLooseRouting(true);
Alex Vakulenko0951ccb2014-12-10 12:52:31 -0800454 Mock::VerifyAndClearExpectations(device_.get());
Paul Stewart2cb3fa72014-11-13 01:43:12 -0800455
456 // Enabled -> disabled should reset the flags back to the default, but
457 // because non-default routing is enabled, rp_filter will be left
458 // in loose mode.
459 EXPECT_CALL(*device_, SetIPFlag(IPAddress::kFamilyIPv4, StrEq("arp_announce"),
460 StrEq("0"))).WillOnce(Return(true));
461 EXPECT_CALL(*device_, SetIPFlag(IPAddress::kFamilyIPv4, StrEq("arp_ignore"),
462 StrEq("0"))).WillOnce(Return(true));
463 device_->SetIsMultiHomed(false);
Alex Vakulenko0951ccb2014-12-10 12:52:31 -0800464 Mock::VerifyAndClearExpectations(device_.get());
Paul Stewart2cb3fa72014-11-13 01:43:12 -0800465
466 // Re-enable reverse-path filtering.
467 EXPECT_CALL(*device_, SetIPFlag(IPAddress::kFamilyIPv4, StrEq("rp_filter"),
468 StrEq("1"))).WillOnce(Return(true));
469 device_->SetLooseRouting(false);
Alex Vakulenko0951ccb2014-12-10 12:52:31 -0800470 Mock::VerifyAndClearExpectations(device_.get());
Paul Stewart2cb3fa72014-11-13 01:43:12 -0800471}
472
Chris Masone5dec5f42011-07-22 14:07:55 -0700473TEST_F(DeviceTest, Load) {
474 NiceMock<MockStore> storage;
475 const string id = device_->GetStorageIdentifier();
476 EXPECT_CALL(storage, ContainsGroup(id)).WillOnce(Return(true));
Paul Stewart6ff27f52012-07-11 06:51:41 -0700477 EXPECT_CALL(storage, GetBool(id, Device::kStoragePowered, _))
478 .WillOnce(Return(true));
479 EXPECT_CALL(storage, GetUint64(id, Device::kStorageReceiveByteCount, _))
480 .WillOnce(Return(true));
481 EXPECT_CALL(storage, GetUint64(id, Device::kStorageTransmitByteCount, _))
482 .WillOnce(Return(true));
Chris Masone5dec5f42011-07-22 14:07:55 -0700483 EXPECT_TRUE(device_->Load(&storage));
484}
485
486TEST_F(DeviceTest, Save) {
487 NiceMock<MockStore> storage;
488 const string id = device_->GetStorageIdentifier();
Paul Stewart6ff27f52012-07-11 06:51:41 -0700489 EXPECT_CALL(storage, SetBool(id, Device::kStoragePowered, _))
490 .WillOnce(Return(true));
Paul Stewart6ff27f52012-07-11 06:51:41 -0700491 EXPECT_CALL(storage, SetUint64(id, Device::kStorageReceiveByteCount, _))
492 .WillOnce(Return(true));
493 EXPECT_CALL(storage, SetUint64(id, Device::kStorageTransmitByteCount, _))
494 .Times(AtLeast(true));
Chris Masone5dec5f42011-07-22 14:07:55 -0700495 EXPECT_TRUE(device_->Save(&storage));
496}
497
Chris Masone34af2182011-08-22 11:59:36 -0700498TEST_F(DeviceTest, StorageIdGeneration) {
499 string to_process("/device/stuff/0");
500 ControlInterface::RpcIdToStorageId(&to_process);
501 EXPECT_TRUE(isalpha(to_process[0]));
502 EXPECT_EQ(string::npos, to_process.find('/'));
503}
504
Paul Stewart03dba0b2011-08-22 16:32:45 -0700505TEST_F(DeviceTest, SelectedService) {
506 EXPECT_FALSE(device_->selected_service_.get());
507 device_->SetServiceState(Service::kStateAssociating);
508 scoped_refptr<MockService> service(
Chris Masone2176a882011-09-14 22:29:15 -0700509 new StrictMock<MockService>(control_interface(),
510 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800511 metrics(),
Chris Masone9d779932011-08-25 16:33:41 -0700512 manager()));
Paul Stewart20088d82012-02-16 06:58:55 -0800513 SelectService(service);
Paul Stewart03dba0b2011-08-22 16:32:45 -0700514 EXPECT_TRUE(device_->selected_service_.get() == service.get());
515
Paul Stewartdded0072013-10-24 12:38:54 -0700516 EXPECT_CALL(*service, SetState(Service::kStateConfiguring));
Paul Stewart03dba0b2011-08-22 16:32:45 -0700517 device_->SetServiceState(Service::kStateConfiguring);
Paul Stewartdded0072013-10-24 12:38:54 -0700518 EXPECT_CALL(*service, SetFailure(Service::kFailureOutOfRange));
Paul Stewart03dba0b2011-08-22 16:32:45 -0700519 device_->SetServiceFailure(Service::kFailureOutOfRange);
520
521 // Service should be returned to "Idle" state
Paul Stewartdded0072013-10-24 12:38:54 -0700522 EXPECT_CALL(*service, state())
Paul Stewart03dba0b2011-08-22 16:32:45 -0700523 .WillOnce(Return(Service::kStateUnknown));
Paul Stewartdded0072013-10-24 12:38:54 -0700524 EXPECT_CALL(*service, SetState(Service::kStateIdle));
525 EXPECT_CALL(*service, SetConnection(IsNullRefPtr()));
Ben Chancc225ef2014-09-30 13:26:51 -0700526 SelectService(nullptr);
Paul Stewart03dba0b2011-08-22 16:32:45 -0700527
528 // A service in the "Failure" state should not be reset to "Idle"
Paul Stewart20088d82012-02-16 06:58:55 -0800529 SelectService(service);
Paul Stewartdded0072013-10-24 12:38:54 -0700530 EXPECT_CALL(*service, state())
Paul Stewart03dba0b2011-08-22 16:32:45 -0700531 .WillOnce(Return(Service::kStateFailure));
Paul Stewartdded0072013-10-24 12:38:54 -0700532 EXPECT_CALL(*service, SetConnection(IsNullRefPtr()));
Ben Chancc225ef2014-09-30 13:26:51 -0700533 SelectService(nullptr);
Paul Stewart03dba0b2011-08-22 16:32:45 -0700534}
535
Peter Qiua0572032014-09-26 10:07:37 -0700536TEST_F(DeviceTest, LinkMonitorFailure) {
537 scoped_refptr<MockService> service(
538 new StrictMock<MockService>(control_interface(),
539 dispatcher(),
540 metrics(),
541 manager()));
542 SelectService(service);
543 EXPECT_TRUE(device_->selected_service().get() == service.get());
544
Peter Qiua388fdb2015-04-03 10:31:22 -0700545 time_t current_time = 1000;
Peter Qiua0572032014-09-26 10:07:37 -0700546
547 // Initial link monitor failure.
548 EXPECT_CALL(time_, GetSecondsBoottime(_)).WillOnce(
Peter Qiua388fdb2015-04-03 10:31:22 -0700549 DoAll(SetArgPointee<0>(current_time), Return(true)));
Peter Qiua0572032014-09-26 10:07:37 -0700550 EXPECT_CALL(metrics_, NotifyUnreliableLinkSignalStrength(_, _)).Times(0);
551 device_->OnLinkMonitorFailure();
Peter Qiua388fdb2015-04-03 10:31:22 -0700552 EXPECT_FALSE(service->unreliable());
Peter Qiua0572032014-09-26 10:07:37 -0700553
554 // Another link monitor failure after 3 minutes, report signal strength.
Peter Qiua388fdb2015-04-03 10:31:22 -0700555 current_time += 180;
Peter Qiua0572032014-09-26 10:07:37 -0700556 EXPECT_CALL(time_, GetSecondsBoottime(_)).WillOnce(
Peter Qiua388fdb2015-04-03 10:31:22 -0700557 DoAll(SetArgPointee<0>(current_time), Return(true)));
Peter Qiua0572032014-09-26 10:07:37 -0700558 EXPECT_CALL(metrics_, NotifyUnreliableLinkSignalStrength(_, _)).Times(1);
559 device_->OnLinkMonitorFailure();
Peter Qiua388fdb2015-04-03 10:31:22 -0700560 EXPECT_TRUE(service->unreliable());
Peter Qiua0572032014-09-26 10:07:37 -0700561
Peter Qiua388fdb2015-04-03 10:31:22 -0700562 // Device is connected with the reliable link callback setup, then
563 // another link monitor failure after 3 minutes, which implies link is
564 // still unreliable, reliable link callback should be cancelled.
565 current_time += 180;
566 SetReliableLinkCallback();
Peter Qiua0572032014-09-26 10:07:37 -0700567 EXPECT_CALL(time_, GetSecondsBoottime(_)).WillOnce(
Peter Qiua388fdb2015-04-03 10:31:22 -0700568 DoAll(SetArgPointee<0>(current_time), Return(true)));
569 EXPECT_CALL(metrics_, NotifyUnreliableLinkSignalStrength(_, _)).Times(1);
570 device_->OnLinkMonitorFailure();
571 EXPECT_TRUE(service->unreliable());
572 EXPECT_TRUE(ReliableLinkCallbackIsCancelled());
573
574 // Another link monitor failure after an hour, link is still reliable, signal
575 // strength not reported.
576 current_time += 3600;
577 service->set_unreliable(false);
578 EXPECT_CALL(time_, GetSecondsBoottime(_)).WillOnce(
579 DoAll(SetArgPointee<0>(current_time), Return(true)));
Peter Qiua0572032014-09-26 10:07:37 -0700580 EXPECT_CALL(metrics_, NotifyUnreliableLinkSignalStrength(_, _)).Times(0);
581 device_->OnLinkMonitorFailure();
Peter Qiua388fdb2015-04-03 10:31:22 -0700582 EXPECT_FALSE(service->unreliable());
583}
584
585TEST_F(DeviceTest, LinkStatusResetOnSelectService) {
586 scoped_refptr<MockService> service(
587 new StrictMock<MockService>(control_interface(),
588 dispatcher(),
589 metrics(),
590 manager()));
591 SelectService(service);
592 service->set_unreliable(true);
593 SetReliableLinkCallback();
594 EXPECT_FALSE(ReliableLinkCallbackIsCancelled());
595
596 // Service is deselected, link status of the service should be resetted.
597 EXPECT_CALL(*service, state())
598 .WillOnce(Return(Service::kStateIdle));
599 EXPECT_CALL(*service, SetState(_));
600 EXPECT_CALL(*service, SetConnection(_));
601 SelectService(nullptr);
602 EXPECT_FALSE(service->unreliable());
603 EXPECT_TRUE(ReliableLinkCallbackIsCancelled());
Peter Qiua0572032014-09-26 10:07:37 -0700604}
605
Paul Stewartbe5f5b32011-12-07 17:11:11 -0800606TEST_F(DeviceTest, IPConfigUpdatedFailure) {
Paul Stewartc5099532013-12-12 07:53:15 -0800607 scoped_refptr<MockIPConfig> ipconfig = new MockIPConfig(control_interface(),
608 kDeviceName);
Paul Stewartbe5f5b32011-12-07 17:11:11 -0800609 scoped_refptr<MockService> service(
610 new StrictMock<MockService>(control_interface(),
611 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800612 metrics(),
Paul Stewartbe5f5b32011-12-07 17:11:11 -0800613 manager()));
Paul Stewart20088d82012-02-16 06:58:55 -0800614 SelectService(service);
Samuel Tan0d061192014-07-07 15:45:15 -0700615 EXPECT_CALL(*service, DisconnectWithFailure(Service::kFailureDHCP,
616 _,
617 StrEq("OnIPConfigFailure")));
Paul Stewartdded0072013-10-24 12:38:54 -0700618 EXPECT_CALL(*service, SetConnection(IsNullRefPtr()));
Paul Stewartc5099532013-12-12 07:53:15 -0800619 EXPECT_CALL(*ipconfig, ResetProperties());
620 OnIPConfigFailed(ipconfig.get());
Paul Stewartbe5f5b32011-12-07 17:11:11 -0800621}
622
Peter Qiub25083f2014-08-25 13:22:31 -0700623TEST_F(DeviceTest, IPConfigUpdatedFailureWithIPv6Config) {
624 // Setup IPv6 configuration.
625 SetupIPv6Config();
626 EXPECT_THAT(device_->ip6config_, NotNullRefPtr());
627
628 // IPv4 configuration failed, fallback to use IPv6 configuration.
629 scoped_refptr<MockIPConfig> ipconfig = new MockIPConfig(control_interface(),
630 kDeviceName);
631 scoped_refptr<MockService> service(
632 new StrictMock<MockService>(control_interface(),
633 dispatcher(),
634 metrics(),
635 manager()));
636 SelectService(service);
637 scoped_refptr<MockConnection> connection(
638 new StrictMock<MockConnection>(&device_info_));
639 SetConnection(connection.get());
640
641 EXPECT_CALL(*ipconfig, ResetProperties());
642 EXPECT_CALL(*connection, IsIPv6())
Peter Qiu300769e2014-08-27 11:48:45 -0700643 .WillRepeatedly(Return(false));
Peter Qiub25083f2014-08-25 13:22:31 -0700644 EXPECT_CALL(*connection, UpdateFromIPConfig(device_->ip6config_));
645 EXPECT_CALL(*service, SetState(Service::kStateConnected));
646 EXPECT_CALL(*service, IsConnected())
647 .WillRepeatedly(Return(true));
648 EXPECT_CALL(*service, IsPortalDetectionDisabled())
649 .WillRepeatedly(Return(true));
650 EXPECT_CALL(*service, SetState(Service::kStateOnline));
651 EXPECT_CALL(*service, SetConnection(NotNullRefPtr()));
652 OnIPConfigFailed(ipconfig.get());
653}
654
mukesh agrawalcc0fded2012-05-09 13:40:58 -0700655TEST_F(DeviceTest, IPConfigUpdatedFailureWithStatic) {
Paul Stewartc5099532013-12-12 07:53:15 -0800656 scoped_refptr<MockIPConfig> ipconfig = new MockIPConfig(control_interface(),
657 kDeviceName);
mukesh agrawalcc0fded2012-05-09 13:40:58 -0700658 scoped_refptr<MockService> service(
659 new StrictMock<MockService>(control_interface(),
660 dispatcher(),
661 metrics(),
662 manager()));
663 SelectService(service);
Ben Chan923a5022013-09-20 11:23:23 -0700664 service->static_ip_parameters_.args_.SetString(kAddressProperty, "1.1.1.1");
665 service->static_ip_parameters_.args_.SetInt(kPrefixlenProperty, 16);
Paul Stewartdded0072013-10-24 12:38:54 -0700666 // Even though we won't call DisconnectWithFailure, we should still have
667 // the service learn from the failed DHCP attempt.
Samuel Tan0d061192014-07-07 15:45:15 -0700668 EXPECT_CALL(*service, DisconnectWithFailure(_, _, _)).Times(0);
Paul Stewartdded0072013-10-24 12:38:54 -0700669 EXPECT_CALL(*service, SetConnection(_)).Times(0);
Paul Stewartc5099532013-12-12 07:53:15 -0800670 // The IPConfig should retain the previous values.
671 EXPECT_CALL(*ipconfig, ResetProperties()).Times(0);
672 OnIPConfigFailed(ipconfig.get());
mukesh agrawalcc0fded2012-05-09 13:40:58 -0700673}
674
Paul Stewartbe5f5b32011-12-07 17:11:11 -0800675TEST_F(DeviceTest, IPConfigUpdatedSuccess) {
676 scoped_refptr<MockService> service(
677 new StrictMock<MockService>(control_interface(),
678 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800679 metrics(),
Paul Stewartbe5f5b32011-12-07 17:11:11 -0800680 manager()));
Paul Stewart20088d82012-02-16 06:58:55 -0800681 SelectService(service);
Paul Stewartbe5f5b32011-12-07 17:11:11 -0800682 scoped_refptr<MockIPConfig> ipconfig = new MockIPConfig(control_interface(),
683 kDeviceName);
Paul Stewartd4f26482014-04-25 19:12:03 -0700684 device_->set_ipconfig(ipconfig);
Paul Stewartdded0072013-10-24 12:38:54 -0700685 EXPECT_CALL(*service, SetState(Service::kStateConnected));
Peter Qiu300769e2014-08-27 11:48:45 -0700686 EXPECT_CALL(metrics_,
687 NotifyNetworkConnectionIPType(
688 device_->technology(),
689 Metrics::kNetworkConnectionIPTypeIPv4));
690 EXPECT_CALL(metrics_,
691 NotifyIPv6ConnectivityStatus(device_->technology(), false));
Paul Stewartdded0072013-10-24 12:38:54 -0700692 EXPECT_CALL(*service, IsConnected())
Paul Stewart20088d82012-02-16 06:58:55 -0800693 .WillRepeatedly(Return(true));
Paul Stewartdded0072013-10-24 12:38:54 -0700694 EXPECT_CALL(*service, IsPortalDetectionDisabled())
Paul Stewartd215af62012-04-24 23:25:50 -0700695 .WillRepeatedly(Return(true));
Garret Kellyd01b5cc2015-03-12 16:20:55 -0400696 EXPECT_CALL(*service, HasStaticNameServers())
697 .WillRepeatedly(Return(false));
Paul Stewartdded0072013-10-24 12:38:54 -0700698 EXPECT_CALL(*service, SetState(Service::kStateOnline));
Paul Stewartdded0072013-10-24 12:38:54 -0700699 EXPECT_CALL(*service, SetConnection(NotNullRefPtr()));
Paul Stewartd4f26482014-04-25 19:12:03 -0700700 EXPECT_CALL(*GetDeviceMockAdaptor(),
701 EmitRpcIdentifierArrayChanged(
702 kIPConfigsProperty,
703 vector<string>{ IPConfigMockAdaptor::kRpcId }));
704
Paul Stewartc5099532013-12-12 07:53:15 -0800705 OnIPConfigUpdated(ipconfig.get());
Paul Stewartbe5f5b32011-12-07 17:11:11 -0800706}
707
Thieu Led1760922012-09-11 14:15:35 -0700708TEST_F(DeviceTest, IPConfigUpdatedSuccessNoSelectedService) {
709 // Make sure shill doesn't crash if a service is disabled immediately
Ben Chancc225ef2014-09-30 13:26:51 -0700710 // after receiving its IP config (selected_service_ is nullptr in this case).
Thieu Led1760922012-09-11 14:15:35 -0700711 scoped_refptr<MockIPConfig> ipconfig = new MockIPConfig(control_interface(),
712 kDeviceName);
Ben Chancc225ef2014-09-30 13:26:51 -0700713 SelectService(nullptr);
Paul Stewartc5099532013-12-12 07:53:15 -0800714 OnIPConfigUpdated(ipconfig.get());
Thieu Led1760922012-09-11 14:15:35 -0700715}
716
Paul Stewart1f916e42013-12-23 09:52:54 -0800717TEST_F(DeviceTest, OnIPConfigExpired) {
718 scoped_refptr<MockIPConfig> ipconfig =
719 new MockIPConfig(control_interface(), kDeviceName);
720 const int kLeaseLength = 1234;
721 ipconfig->properties_.lease_duration_seconds = kLeaseLength;
722
723 EXPECT_CALL(metrics_,
724 SendToUMA("Network.Shill.Unknown.ExpiredLeaseLengthSeconds",
725 kLeaseLength,
726 Metrics::kMetricExpiredLeaseLengthSecondsMin,
727 Metrics::kMetricExpiredLeaseLengthSecondsMax,
728 Metrics::kMetricExpiredLeaseLengthSecondsNumBuckets));
729
730 OnIPConfigExpired(ipconfig.get());
731}
732
Ben Chan9f3dcf82013-09-25 18:04:58 -0700733TEST_F(DeviceTest, SetEnabledNonPersistent) {
734 EXPECT_FALSE(device_->enabled_);
735 EXPECT_FALSE(device_->enabled_pending_);
736 device_->enabled_persistent_ = false;
737 StrictMock<MockManager> manager(control_interface(),
738 dispatcher(),
739 metrics(),
740 glib());
741 SetManager(&manager);
742 Error error;
743 device_->SetEnabledNonPersistent(true, &error, ResultCallback());
744 EXPECT_FALSE(device_->enabled_persistent_);
745 EXPECT_TRUE(device_->enabled_pending_);
746
747 // Enable while already enabled.
748 error.Populate(Error::kOperationInitiated);
749 device_->enabled_persistent_ = false;
750 device_->enabled_pending_ = true;
751 device_->enabled_ = true;
752 device_->SetEnabledNonPersistent(true, &error, ResultCallback());
753 EXPECT_FALSE(device_->enabled_persistent_);
754 EXPECT_TRUE(device_->enabled_pending_);
755 EXPECT_TRUE(device_->enabled_);
756 EXPECT_TRUE(error.IsSuccess());
757
758 // Enable while enabled but disabling.
759 error.Populate(Error::kOperationInitiated);
760 device_->enabled_pending_ = false;
761 device_->SetEnabledNonPersistent(true, &error, ResultCallback());
762 EXPECT_FALSE(device_->enabled_persistent_);
763 EXPECT_FALSE(device_->enabled_pending_);
764 EXPECT_TRUE(device_->enabled_);
765 EXPECT_TRUE(error.IsSuccess());
766
767 // Disable while already disabled.
768 error.Populate(Error::kOperationInitiated);
769 device_->enabled_ = false;
770 device_->SetEnabledNonPersistent(false, &error, ResultCallback());
771 EXPECT_FALSE(device_->enabled_persistent_);
772 EXPECT_FALSE(device_->enabled_pending_);
773 EXPECT_FALSE(device_->enabled_);
774 EXPECT_TRUE(error.IsSuccess());
775
776 // Disable while already enabling.
777 error.Populate(Error::kOperationInitiated);
778 device_->enabled_pending_ = true;
779 device_->SetEnabledNonPersistent(false, &error, ResultCallback());
780 EXPECT_FALSE(device_->enabled_persistent_);
781 EXPECT_TRUE(device_->enabled_pending_);
782 EXPECT_FALSE(device_->enabled_);
783 EXPECT_TRUE(error.IsSuccess());
784}
785
Darin Petkove7c6ad32012-06-29 10:22:09 +0200786TEST_F(DeviceTest, SetEnabledPersistent) {
787 EXPECT_FALSE(device_->enabled_);
788 EXPECT_FALSE(device_->enabled_pending_);
789 device_->enabled_persistent_ = false;
790 StrictMock<MockManager> manager(control_interface(),
791 dispatcher(),
792 metrics(),
793 glib());
794 EXPECT_CALL(manager, UpdateDevice(_));
Paul Stewart036dba02012-08-07 12:34:41 -0700795 SetManager(&manager);
Darin Petkove7c6ad32012-06-29 10:22:09 +0200796 Error error;
797 device_->SetEnabledPersistent(true, &error, ResultCallback());
798 EXPECT_TRUE(device_->enabled_persistent_);
799 EXPECT_TRUE(device_->enabled_pending_);
Arman Uguray2f352e62013-08-28 19:12:53 -0700800
801 // Enable while already enabled.
802 error.Populate(Error::kOperationInitiated);
803 device_->enabled_persistent_ = false;
804 device_->enabled_pending_ = true;
805 device_->enabled_ = true;
806 device_->SetEnabledPersistent(true, &error, ResultCallback());
807 EXPECT_FALSE(device_->enabled_persistent_);
808 EXPECT_TRUE(device_->enabled_pending_);
809 EXPECT_TRUE(device_->enabled_);
810 EXPECT_TRUE(error.IsSuccess());
811
812 // Enable while enabled but disabling.
813 error.Populate(Error::kOperationInitiated);
814 device_->enabled_pending_ = false;
815 device_->SetEnabledPersistent(true, &error, ResultCallback());
816 EXPECT_FALSE(device_->enabled_persistent_);
817 EXPECT_FALSE(device_->enabled_pending_);
818 EXPECT_TRUE(device_->enabled_);
819 EXPECT_EQ(Error::kOperationFailed, error.type());
820
821 // Disable while already disabled.
822 error.Populate(Error::kOperationInitiated);
823 device_->enabled_ = false;
824 device_->SetEnabledPersistent(false, &error, ResultCallback());
825 EXPECT_FALSE(device_->enabled_persistent_);
826 EXPECT_FALSE(device_->enabled_pending_);
827 EXPECT_FALSE(device_->enabled_);
828 EXPECT_TRUE(error.IsSuccess());
829
830 // Disable while already enabling.
831 error.Populate(Error::kOperationInitiated);
832 device_->enabled_pending_ = true;
833 device_->SetEnabledPersistent(false, &error, ResultCallback());
834 EXPECT_FALSE(device_->enabled_persistent_);
835 EXPECT_TRUE(device_->enabled_pending_);
836 EXPECT_FALSE(device_->enabled_);
837 EXPECT_EQ(Error::kOperationFailed, error.type());
Darin Petkove7c6ad32012-06-29 10:22:09 +0200838}
839
Thieu Lefb46caf2012-03-08 11:57:15 -0800840TEST_F(DeviceTest, Start) {
Paul Stewart8c116a92012-05-02 18:30:03 -0700841 EXPECT_FALSE(device_->running_);
842 EXPECT_FALSE(device_->enabled_);
843 EXPECT_FALSE(device_->enabled_pending_);
Eric Shienbrood9a245532012-03-07 14:20:39 -0500844 device_->SetEnabled(true);
Paul Stewart8c116a92012-05-02 18:30:03 -0700845 EXPECT_TRUE(device_->running_);
846 EXPECT_TRUE(device_->enabled_pending_);
Gary Morainbaeefdf2012-04-30 14:53:35 -0700847 device_->OnEnabledStateChanged(ResultCallback(),
848 Error(Error::kOperationFailed));
849 EXPECT_FALSE(device_->enabled_pending_);
Thieu Lefb46caf2012-03-08 11:57:15 -0800850}
851
mukesh agrawal5c4dd0b2011-09-14 13:53:14 -0700852TEST_F(DeviceTest, Stop) {
Eric Shienbrood9a245532012-03-07 14:20:39 -0500853 device_->enabled_ = true;
854 device_->enabled_pending_ = true;
mukesh agrawal5c4dd0b2011-09-14 13:53:14 -0700855 device_->ipconfig_ = new IPConfig(&control_interface_, kDeviceName);
856 scoped_refptr<MockService> service(
857 new NiceMock<MockService>(&control_interface_,
858 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800859 metrics(),
mukesh agrawal5c4dd0b2011-09-14 13:53:14 -0700860 manager()));
Paul Stewart20088d82012-02-16 06:58:55 -0800861 SelectService(service);
mukesh agrawal5c4dd0b2011-09-14 13:53:14 -0700862
Paul Stewartdded0072013-10-24 12:38:54 -0700863 EXPECT_CALL(*service, state()).
mukesh agrawal5c4dd0b2011-09-14 13:53:14 -0700864 WillRepeatedly(Return(Service::kStateConnected));
Paul Stewartd4f26482014-04-25 19:12:03 -0700865 EXPECT_CALL(*GetDeviceMockAdaptor(),
Ben Chan923a5022013-09-20 11:23:23 -0700866 EmitBoolChanged(kPoweredProperty, false));
mukesh agrawal5c4dd0b2011-09-14 13:53:14 -0700867 EXPECT_CALL(rtnl_handler_, SetInterfaceFlags(_, 0, IFF_UP));
Eric Shienbrood9a245532012-03-07 14:20:39 -0500868 device_->SetEnabled(false);
869 device_->OnEnabledStateChanged(ResultCallback(), Error());
mukesh agrawal5c4dd0b2011-09-14 13:53:14 -0700870
871 EXPECT_FALSE(device_->ipconfig_.get());
872 EXPECT_FALSE(device_->selected_service_.get());
873}
874
Paul Stewartff6be292014-11-24 17:05:03 -0800875TEST_F(DeviceTest, StartProhibited) {
876 DeviceRefPtr device(new TestDevice(control_interface(),
877 dispatcher(),
878 nullptr,
879 manager(),
880 kDeviceName,
881 kDeviceAddress,
882 kDeviceInterfaceIndex,
883 Technology::kWifi));
884 {
885 Error error;
886 manager()->SetProhibitedTechnologies("wifi", &error);
887 EXPECT_TRUE(error.IsSuccess());
888 }
889
890 device->SetEnabled(true);
891 EXPECT_FALSE(device->running());
892
893 {
894 Error error;
895 manager()->SetProhibitedTechnologies("", &error);
896 EXPECT_TRUE(error.IsSuccess());
897 }
898 device->SetEnabled(true);
899 EXPECT_TRUE(device->running());
900}
901
Ben Chanad663e12013-01-08 01:58:47 -0800902TEST_F(DeviceTest, Reset) {
903 Error e;
904 device_->Reset(&e, ResultCallback());
905 EXPECT_EQ(Error::kNotSupported, e.type());
906 EXPECT_EQ("Device doesn't support Reset.", e.message());
907}
908
mukesh agrawal784566d2012-08-08 18:32:58 -0700909TEST_F(DeviceTest, ResumeWithIPConfig) {
910 scoped_refptr<MockIPConfig> ipconfig =
911 new MockIPConfig(control_interface(), kDeviceName);
912 device_->set_ipconfig(ipconfig);
913 EXPECT_CALL(*ipconfig, RenewIP());
914 device_->OnAfterResume();
915}
916
917TEST_F(DeviceTest, ResumeWithoutIPConfig) {
918 // Just test that we don't crash in this case.
Ben Chancc225ef2014-09-30 13:26:51 -0700919 ASSERT_EQ(nullptr, device_->ipconfig().get());
mukesh agrawal784566d2012-08-08 18:32:58 -0700920 device_->OnAfterResume();
921}
922
mukesh agrawalbb2231c2013-07-17 16:32:24 -0700923TEST_F(DeviceTest, ResumeWithLinkMonitor) {
Paul Stewart3b30ca52015-06-16 13:13:10 -0700924 MockLinkMonitor* link_monitor = new StrictMock<MockLinkMonitor>();
mukesh agrawalbb2231c2013-07-17 16:32:24 -0700925 SetLinkMonitor(link_monitor); // Passes ownership.
926 EXPECT_CALL(*link_monitor, OnAfterResume());
927 device_->OnAfterResume();
928}
929
930TEST_F(DeviceTest, ResumeWithoutLinkMonitor) {
931 // Just test that we don't crash in this case.
932 EXPECT_FALSE(HasLinkMonitor());
933 device_->OnAfterResume();
934}
935
Peter Qiua388fdb2015-04-03 10:31:22 -0700936TEST_F(DeviceTest, ResumeWithUnreliableLink) {
937 scoped_refptr<MockService> service(
938 new StrictMock<MockService>(control_interface(),
939 dispatcher(),
940 metrics(),
941 manager()));
942 SelectService(service);
943 service->set_unreliable(true);
944 SetReliableLinkCallback();
945
946 // Link status should be resetted upon resume.
947 device_->OnAfterResume();
948 EXPECT_FALSE(service->unreliable());
949 EXPECT_TRUE(ReliableLinkCallbackIsCancelled());
950}
951
952TEST_F(DeviceTest, OnConnected) {
953 scoped_refptr<MockService> service(
954 new StrictMock<MockService>(control_interface(),
955 dispatcher(),
956 metrics(),
957 manager()));
958 SelectService(service);
959
960 // Link is reliable, no need to post delayed task to reset link status.
961 device_->OnConnected();
962 EXPECT_TRUE(ReliableLinkCallbackIsCancelled());
963
964 // Link is unreliable when connected, delayed task is posted to reset the
965 // link state.
966 service->set_unreliable(true);
967 device_->OnConnected();
968 EXPECT_FALSE(ReliableLinkCallbackIsCancelled());
969}
970
Paul Stewart036dba02012-08-07 12:34:41 -0700971TEST_F(DeviceTest, LinkMonitor) {
972 scoped_refptr<MockConnection> connection(
973 new StrictMock<MockConnection>(&device_info_));
974 MockManager manager(control_interface(),
975 dispatcher(),
976 metrics(),
977 glib());
978 scoped_refptr<MockService> service(
979 new StrictMock<MockService>(control_interface(),
980 dispatcher(),
981 metrics(),
982 &manager));
983 SelectService(service);
984 SetConnection(connection.get());
Paul Stewart3b30ca52015-06-16 13:13:10 -0700985 MockLinkMonitor* link_monitor = new StrictMock<MockLinkMonitor>();
Paul Stewart036dba02012-08-07 12:34:41 -0700986 SetLinkMonitor(link_monitor); // Passes ownership.
987 SetManager(&manager);
988 EXPECT_CALL(*link_monitor, Start()).Times(0);
989 EXPECT_CALL(manager, IsTechnologyLinkMonitorEnabled(Technology::kUnknown))
990 .WillOnce(Return(false))
991 .WillRepeatedly(Return(true));
992 EXPECT_FALSE(StartLinkMonitor());
993
Peter Qiud49760e2014-09-19 16:13:42 -0700994 EXPECT_CALL(*link_monitor, Start()).Times(0);
995 EXPECT_CALL(*service, link_monitor_disabled())
996 .WillOnce(Return(true))
997 .WillRepeatedly(Return(false));
998 EXPECT_FALSE(StartLinkMonitor());
999
Paul Stewart036dba02012-08-07 12:34:41 -07001000 EXPECT_CALL(*link_monitor, Start())
1001 .WillOnce(Return(false))
1002 .WillOnce(Return(true));
1003 EXPECT_FALSE(StartLinkMonitor());
1004 EXPECT_TRUE(StartLinkMonitor());
1005
1006 unsigned int kResponseTime = 123;
1007 EXPECT_CALL(*link_monitor, GetResponseTimeMilliseconds())
1008 .WillOnce(Return(kResponseTime));
1009 {
1010 Error error;
1011 EXPECT_EQ(kResponseTime, GetLinkMonitorResponseTime(&error));
1012 EXPECT_TRUE(error.IsSuccess());
1013 }
1014 StopLinkMonitor();
1015 {
1016 Error error;
1017 EXPECT_EQ(0, GetLinkMonitorResponseTime(&error));
1018 EXPECT_FALSE(error.IsSuccess());
1019 }
1020}
1021
Paul Stewartc8860612012-09-28 07:36:21 -07001022TEST_F(DeviceTest, LinkMonitorCancelledOnSelectService) {
1023 scoped_refptr<MockConnection> connection(
1024 new StrictMock<MockConnection>(&device_info_));
1025 MockManager manager(control_interface(),
1026 dispatcher(),
1027 metrics(),
1028 glib());
1029 scoped_refptr<MockService> service(
1030 new StrictMock<MockService>(control_interface(),
1031 dispatcher(),
1032 metrics(),
1033 &manager));
1034 SelectService(service);
1035 SetConnection(connection.get());
Paul Stewart3b30ca52015-06-16 13:13:10 -07001036 MockLinkMonitor* link_monitor = new StrictMock<MockLinkMonitor>();
Paul Stewartc8860612012-09-28 07:36:21 -07001037 SetLinkMonitor(link_monitor); // Passes ownership.
1038 SetManager(&manager);
Paul Stewartdded0072013-10-24 12:38:54 -07001039 EXPECT_CALL(*service, state())
Paul Stewartc8860612012-09-28 07:36:21 -07001040 .WillOnce(Return(Service::kStateIdle));
Paul Stewartdded0072013-10-24 12:38:54 -07001041 EXPECT_CALL(*service, SetState(_));
1042 EXPECT_CALL(*service, SetConnection(_));
Paul Stewartc8860612012-09-28 07:36:21 -07001043 EXPECT_TRUE(HasLinkMonitor());
Ben Chancc225ef2014-09-30 13:26:51 -07001044 SelectService(nullptr);
Paul Stewartc8860612012-09-28 07:36:21 -07001045 EXPECT_FALSE(HasLinkMonitor());
1046}
1047
Peter Qiudc335f82014-05-15 10:33:17 -07001048TEST_F(DeviceTest, TrafficMonitor) {
1049 scoped_refptr<MockConnection> connection(
1050 new StrictMock<MockConnection>(&device_info_));
1051 MockManager manager(control_interface(),
1052 dispatcher(),
1053 metrics(),
1054 glib());
1055 scoped_refptr<MockService> service(
1056 new StrictMock<MockService>(control_interface(),
1057 dispatcher(),
1058 metrics(),
1059 &manager));
1060 SelectService(service);
1061 SetConnection(connection.get());
Paul Stewart3b30ca52015-06-16 13:13:10 -07001062 MockTrafficMonitor* traffic_monitor = new StrictMock<MockTrafficMonitor>();
Peter Qiudc335f82014-05-15 10:33:17 -07001063 SetTrafficMonitor(traffic_monitor); // Passes ownership.
1064 SetManager(&manager);
1065
1066 EXPECT_CALL(*device_, IsTrafficMonitorEnabled()).WillRepeatedly(Return(true));
1067 EXPECT_CALL(*traffic_monitor, Start());
1068 StartTrafficMonitor();
1069 EXPECT_CALL(*traffic_monitor, Stop());
1070 StopTrafficMonitor();
1071 Mock::VerifyAndClearExpectations(traffic_monitor);
1072
1073 EXPECT_CALL(metrics_, NotifyNetworkProblemDetected(_,
1074 Metrics::kNetworkProblemDNSFailure)).Times(1);
1075 NetworkProblemDetected(TrafficMonitor::kNetworkProblemDNSFailure);
1076
1077 // Verify traffic monitor not running when it is disabled.
1078 traffic_monitor = new StrictMock<MockTrafficMonitor>();
1079 SetTrafficMonitor(traffic_monitor);
1080 EXPECT_CALL(*device_, IsTrafficMonitorEnabled())
1081 .WillRepeatedly(Return(false));
1082 EXPECT_CALL(*traffic_monitor, Start()).Times(0);
1083 StartTrafficMonitor();
1084 EXPECT_CALL(*traffic_monitor, Stop()).Times(0);
1085 StopTrafficMonitor();
Peter Qiudc335f82014-05-15 10:33:17 -07001086}
1087
1088TEST_F(DeviceTest, TrafficMonitorCancelledOnSelectService) {
1089 scoped_refptr<MockConnection> connection(
1090 new StrictMock<MockConnection>(&device_info_));
1091 MockManager manager(control_interface(),
1092 dispatcher(),
1093 metrics(),
1094 glib());
1095 scoped_refptr<MockService> service(
1096 new StrictMock<MockService>(control_interface(),
1097 dispatcher(),
1098 metrics(),
1099 &manager));
1100 SelectService(service);
1101 SetConnection(connection.get());
Paul Stewart3b30ca52015-06-16 13:13:10 -07001102 MockTrafficMonitor* traffic_monitor = new StrictMock<MockTrafficMonitor>();
Peter Qiudc335f82014-05-15 10:33:17 -07001103 SetTrafficMonitor(traffic_monitor); // Passes ownership.
1104 EXPECT_CALL(*device_, IsTrafficMonitorEnabled()).WillRepeatedly(Return(true));
1105 SetManager(&manager);
1106 EXPECT_CALL(*service, state())
1107 .WillOnce(Return(Service::kStateIdle));
1108 EXPECT_CALL(*service, SetState(_));
1109 EXPECT_CALL(*service, SetConnection(_));
1110 EXPECT_CALL(*traffic_monitor, Stop());
Ben Chancc225ef2014-09-30 13:26:51 -07001111 SelectService(nullptr);
Peter Qiudc335f82014-05-15 10:33:17 -07001112}
1113
Paul Stewart75a68b92013-10-24 10:50:27 -07001114TEST_F(DeviceTest, ShouldUseArpGateway) {
1115 EXPECT_FALSE(device_->ShouldUseArpGateway());
1116}
1117
Paul Stewartc6fbad92013-11-13 14:50:52 -08001118TEST_F(DeviceTest, PerformTDLSOperation) {
Ben Chancc225ef2014-09-30 13:26:51 -07001119 EXPECT_EQ(
1120 "", device_->PerformTDLSOperation("do something", "to someone", nullptr));
Paul Stewartc6fbad92013-11-13 14:50:52 -08001121}
1122
Paul Stewartfa11e282013-12-02 22:04:25 -08001123TEST_F(DeviceTest, IsConnectedViaTether) {
1124 EXPECT_FALSE(device_->IsConnectedViaTether());
1125
1126 // An empty ipconfig doesn't mean we're tethered.
1127 device_->ipconfig_ = new IPConfig(control_interface(), kDeviceName);
1128 EXPECT_FALSE(device_->IsConnectedViaTether());
1129
1130 // Add an ipconfig property that indicates this is an Android tether.
1131 IPConfig::Properties properties;
1132 properties.vendor_encapsulated_options =
1133 Tethering::kAndroidVendorEncapsulatedOptions;
Samuel Tan3c3c36a2014-12-16 16:53:19 -08001134 device_->ipconfig_->UpdateProperties(properties, true);
Paul Stewartfa11e282013-12-02 22:04:25 -08001135 EXPECT_TRUE(device_->IsConnectedViaTether());
1136
1137 properties.vendor_encapsulated_options = "Some other non-empty value";
Samuel Tan3c3c36a2014-12-16 16:53:19 -08001138 device_->ipconfig_->UpdateProperties(properties, true);
Paul Stewartfa11e282013-12-02 22:04:25 -08001139 EXPECT_FALSE(device_->IsConnectedViaTether());
1140}
1141
Paul Stewartd4f26482014-04-25 19:12:03 -07001142TEST_F(DeviceTest, AvailableIPConfigs) {
Ben Chancc225ef2014-09-30 13:26:51 -07001143 EXPECT_EQ(vector<string>(), device_->AvailableIPConfigs(nullptr));
Paul Stewartd4f26482014-04-25 19:12:03 -07001144 device_->ipconfig_ = new IPConfig(control_interface(), kDeviceName);
1145 EXPECT_EQ(vector<string> { IPConfigMockAdaptor::kRpcId },
Ben Chancc225ef2014-09-30 13:26:51 -07001146 device_->AvailableIPConfigs(nullptr));
Paul Stewartd4f26482014-04-25 19:12:03 -07001147 device_->ip6config_ = new IPConfig(control_interface(), kDeviceName);
1148
1149 // We don't really care that the RPC IDs for all IPConfig mock adaptors
1150 // are the same, or their ordering. We just need to see that there are two
1151 // of them when both IPv6 and IPv4 IPConfigs are available.
Ben Chancc225ef2014-09-30 13:26:51 -07001152 EXPECT_EQ(2, device_->AvailableIPConfigs(nullptr).size());
Paul Stewartd4f26482014-04-25 19:12:03 -07001153
Peter Qiud48fa0c2015-06-10 12:20:48 -07001154 device_->dhcpv6_config_ = new IPConfig(control_interface(), kDeviceName);
1155 EXPECT_EQ(3, device_->AvailableIPConfigs(nullptr).size());
1156
1157 device_->dhcpv6_config_ = nullptr;
1158 EXPECT_EQ(2, device_->AvailableIPConfigs(nullptr).size());
1159
Ben Chancc225ef2014-09-30 13:26:51 -07001160 device_->ipconfig_ = nullptr;
Paul Stewartd4f26482014-04-25 19:12:03 -07001161 EXPECT_EQ(vector<string> { IPConfigMockAdaptor::kRpcId },
Ben Chancc225ef2014-09-30 13:26:51 -07001162 device_->AvailableIPConfigs(nullptr));
Paul Stewartd4f26482014-04-25 19:12:03 -07001163
Ben Chancc225ef2014-09-30 13:26:51 -07001164 device_->ip6config_ = nullptr;
1165 EXPECT_EQ(vector<string>(), device_->AvailableIPConfigs(nullptr));
Paul Stewartd4f26482014-04-25 19:12:03 -07001166}
1167
1168TEST_F(DeviceTest, OnIPv6AddressChanged) {
1169 StrictMock<MockManager> manager(control_interface(),
1170 dispatcher(),
1171 metrics(),
1172 glib());
1173 manager.set_mock_device_info(&device_info_);
Paul Stewart1ce231c2015-06-12 19:44:22 -07001174 EXPECT_CALL(manager, FilterPrependDNSServersByFamily(_))
1175 .WillRepeatedly(Return(vector<string>()));
Paul Stewartd4f26482014-04-25 19:12:03 -07001176 SetManager(&manager);
1177
Ben Chancc225ef2014-09-30 13:26:51 -07001178 // An IPv6 clear while ip6config_ is nullptr will not emit a change.
Paul Stewartd4f26482014-04-25 19:12:03 -07001179 EXPECT_CALL(device_info_, GetPrimaryIPv6Address(kDeviceInterfaceIndex, _))
1180 .WillOnce(Return(false));
1181 EXPECT_CALL(*GetDeviceMockAdaptor(),
1182 EmitRpcIdentifierArrayChanged(kIPConfigsProperty, _)).Times(0);
1183 device_->OnIPv6AddressChanged();
1184 EXPECT_THAT(device_->ip6config_, IsNullRefPtr());
1185 Mock::VerifyAndClearExpectations(GetDeviceMockAdaptor());
1186 Mock::VerifyAndClearExpectations(&device_info_);
1187
1188 IPAddress address0(IPAddress::kFamilyIPv6);
1189 const char kAddress0[] = "fe80::1aa9:5ff:abcd:1234";
1190 ASSERT_TRUE(address0.SetAddressFromString(kAddress0));
1191
Ben Chancc225ef2014-09-30 13:26:51 -07001192 // Add an IPv6 address while ip6config_ is nullptr.
Paul Stewartd4f26482014-04-25 19:12:03 -07001193 EXPECT_CALL(device_info_, GetPrimaryIPv6Address(kDeviceInterfaceIndex, _))
1194 .WillOnce(DoAll(SetArgPointee<1>(address0), Return(true)));
1195 EXPECT_CALL(*GetDeviceMockAdaptor(),
1196 EmitRpcIdentifierArrayChanged(
1197 kIPConfigsProperty,
1198 vector<string> { IPConfigMockAdaptor::kRpcId }));
1199 device_->OnIPv6AddressChanged();
1200 EXPECT_THAT(device_->ip6config_, NotNullRefPtr());
1201 EXPECT_EQ(kAddress0, device_->ip6config_->properties().address);
1202 Mock::VerifyAndClearExpectations(GetDeviceMockAdaptor());
1203 Mock::VerifyAndClearExpectations(&device_info_);
1204
1205 // If the IPv6 address does not change, no signal is emitted.
1206 EXPECT_CALL(device_info_, GetPrimaryIPv6Address(kDeviceInterfaceIndex, _))
1207 .WillOnce(DoAll(SetArgPointee<1>(address0), Return(true)));
1208 EXPECT_CALL(*GetDeviceMockAdaptor(),
1209 EmitRpcIdentifierArrayChanged(kIPConfigsProperty, _)).Times(0);
1210 device_->OnIPv6AddressChanged();
1211 EXPECT_EQ(kAddress0, device_->ip6config_->properties().address);
1212 Mock::VerifyAndClearExpectations(GetDeviceMockAdaptor());
1213 Mock::VerifyAndClearExpectations(&device_info_);
1214
1215 IPAddress address1(IPAddress::kFamilyIPv6);
1216 const char kAddress1[] = "fe80::1aa9:5ff:abcd:5678";
1217 ASSERT_TRUE(address1.SetAddressFromString(kAddress1));
1218
1219 // If the IPv6 address changes, a signal is emitted.
1220 EXPECT_CALL(device_info_, GetPrimaryIPv6Address(kDeviceInterfaceIndex, _))
1221 .WillOnce(DoAll(SetArgPointee<1>(address1), Return(true)));
1222 EXPECT_CALL(*GetDeviceMockAdaptor(),
1223 EmitRpcIdentifierArrayChanged(
1224 kIPConfigsProperty,
1225 vector<string> { IPConfigMockAdaptor::kRpcId }));
1226 device_->OnIPv6AddressChanged();
1227 EXPECT_EQ(kAddress1, device_->ip6config_->properties().address);
1228 Mock::VerifyAndClearExpectations(GetDeviceMockAdaptor());
1229 Mock::VerifyAndClearExpectations(&device_info_);
1230
1231 // If the IPv6 prefix changes, a signal is emitted.
1232 address1.set_prefix(64);
1233 EXPECT_CALL(device_info_, GetPrimaryIPv6Address(kDeviceInterfaceIndex, _))
1234 .WillOnce(DoAll(SetArgPointee<1>(address1), Return(true)));
1235 EXPECT_CALL(*GetDeviceMockAdaptor(),
1236 EmitRpcIdentifierArrayChanged(
1237 kIPConfigsProperty,
1238 vector<string> { IPConfigMockAdaptor::kRpcId }));
1239 device_->OnIPv6AddressChanged();
1240 EXPECT_EQ(kAddress1, device_->ip6config_->properties().address);
1241
Ben Chancc225ef2014-09-30 13:26:51 -07001242 // Return the IPv6 address to nullptr.
Paul Stewartd4f26482014-04-25 19:12:03 -07001243 EXPECT_CALL(device_info_, GetPrimaryIPv6Address(kDeviceInterfaceIndex, _))
1244 .WillOnce(Return(false));
1245 EXPECT_CALL(*GetDeviceMockAdaptor(),
1246 EmitRpcIdentifierArrayChanged(kIPConfigsProperty,
1247 vector<string>()));
1248 device_->OnIPv6AddressChanged();
1249 EXPECT_THAT(device_->ip6config_, IsNullRefPtr());
1250 Mock::VerifyAndClearExpectations(GetDeviceMockAdaptor());
1251 Mock::VerifyAndClearExpectations(&device_info_);
1252}
1253
Samuel Tan815a6fb2014-10-23 16:53:59 -07001254TEST_F(DeviceTest, OnIPv6DnsServerAddressesChanged_LeaseExpirationUpdated) {
1255 MockManager manager(control_interface(),
1256 dispatcher(),
1257 metrics(),
1258 glib());
1259 manager.set_mock_device_info(&device_info_);
Paul Stewart1ce231c2015-06-12 19:44:22 -07001260 EXPECT_CALL(manager, FilterPrependDNSServersByFamily(_))
1261 .WillRepeatedly(Return(vector<string>()));
Samuel Tan815a6fb2014-10-23 16:53:59 -07001262 SetManager(&manager);
1263
1264 scoped_refptr<MockIPConfig> ip6config =
1265 new MockIPConfig(control_interface(), kDeviceName);
1266 device_->ip6config_ = ip6config;
1267
1268 // Non-infinite lifetime should trigger an update of the current lease
1269 // expiration time.
1270 const uint32 kExpiredLifetime = 1;
1271 EXPECT_CALL(device_info_,
1272 GetIPv6DnsServerAddresses(kDeviceInterfaceIndex, _, _))
1273 .WillOnce(DoAll(SetArgPointee<2>(kExpiredLifetime),
1274 Return(true)));
1275 EXPECT_CALL(*ip6config, UpdateLeaseExpirationTime(_)).Times(1);
1276 EXPECT_CALL(*ip6config, ResetLeaseExpirationTime()).Times(0);
1277 device_->OnIPv6DnsServerAddressesChanged();
1278
1279 // Infinite lifetime should cause a reset of the current lease expiration
1280 // time to its default value.
1281 const uint32 kExpiredLifetimeInfinity = ND_OPT_LIFETIME_INFINITY;
1282 EXPECT_CALL(device_info_,
1283 GetIPv6DnsServerAddresses(kDeviceInterfaceIndex, _, _))
1284 .WillOnce(DoAll(SetArgPointee<2>(kExpiredLifetimeInfinity),
1285 Return(true)));
1286 EXPECT_CALL(*ip6config, UpdateLeaseExpirationTime(_)).Times(0);
1287 EXPECT_CALL(*ip6config, ResetLeaseExpirationTime()).Times(1);
1288 device_->OnIPv6DnsServerAddressesChanged();
1289}
1290
Peter Qiu25f1be62014-08-12 10:42:27 -07001291TEST_F(DeviceTest, OnIPv6DnsServerAddressesChanged) {
1292 StrictMock<MockManager> manager(control_interface(),
1293 dispatcher(),
1294 metrics(),
1295 glib());
1296 manager.set_mock_device_info(&device_info_);
Paul Stewart1ce231c2015-06-12 19:44:22 -07001297 EXPECT_CALL(manager, FilterPrependDNSServersByFamily(_))
1298 .WillRepeatedly(Return(vector<string>()));
Peter Qiu25f1be62014-08-12 10:42:27 -07001299 SetManager(&manager);
1300
Peter Qiub25083f2014-08-25 13:22:31 -07001301 // With existing IPv4 connection, so no attempt to setup IPv6 connection.
1302 // IPv6 connection is being tested in OnIPv6ConfigurationCompleted test.
1303 scoped_refptr<MockConnection> connection(
1304 new StrictMock<MockConnection>(&device_info_));
1305 SetConnection(connection.get());
1306 EXPECT_CALL(*connection, IsIPv6())
1307 .WillRepeatedly(Return(false));
1308
Peter Qiu25f1be62014-08-12 10:42:27 -07001309 // IPv6 DNS server addresses are not provided will not emit a change.
1310 EXPECT_CALL(device_info_,
1311 GetIPv6DnsServerAddresses(kDeviceInterfaceIndex, _, _))
1312 .WillOnce(Return(false));
1313 EXPECT_CALL(*GetDeviceMockAdaptor(),
1314 EmitRpcIdentifierArrayChanged(kIPConfigsProperty, _)).Times(0);
1315 device_->OnIPv6DnsServerAddressesChanged();
1316 EXPECT_THAT(device_->ip6config_, IsNullRefPtr());
1317 Mock::VerifyAndClearExpectations(GetDeviceMockAdaptor());
1318 Mock::VerifyAndClearExpectations(&device_info_);
1319
1320 const char kAddress1[] = "fe80::1aa9:5ff:abcd:1234";
1321 const char kAddress2[] = "fe80::1aa9:5ff:abcd:1235";
1322 const uint32 kInfiniteLifetime = 0xffffffff;
1323 IPAddress ipv6_address1(IPAddress::kFamilyIPv6);
1324 IPAddress ipv6_address2(IPAddress::kFamilyIPv6);
1325 ASSERT_TRUE(ipv6_address1.SetAddressFromString(kAddress1));
1326 ASSERT_TRUE(ipv6_address2.SetAddressFromString(kAddress2));
1327 vector<IPAddress> dns_server_addresses;
1328 dns_server_addresses.push_back(ipv6_address1);
1329 dns_server_addresses.push_back(ipv6_address2);
1330 vector<string> dns_server_addresses_str;
1331 dns_server_addresses_str.push_back(kAddress1);
1332 dns_server_addresses_str.push_back(kAddress2);
1333
Ben Chancc225ef2014-09-30 13:26:51 -07001334 // Add IPv6 DNS server addresses while ip6config_ is nullptr.
Peter Qiu25f1be62014-08-12 10:42:27 -07001335 EXPECT_CALL(device_info_,
1336 GetIPv6DnsServerAddresses(kDeviceInterfaceIndex, _, _))
1337 .WillOnce(DoAll(SetArgPointee<1>(dns_server_addresses),
1338 SetArgPointee<2>(kInfiniteLifetime),
1339 Return(true)));
1340 EXPECT_CALL(*GetDeviceMockAdaptor(),
1341 EmitRpcIdentifierArrayChanged(
1342 kIPConfigsProperty,
1343 vector<string> { IPConfigMockAdaptor::kRpcId }));
1344 device_->OnIPv6DnsServerAddressesChanged();
1345 EXPECT_THAT(device_->ip6config_, NotNullRefPtr());
1346 EXPECT_EQ(dns_server_addresses_str,
1347 device_->ip6config_->properties().dns_servers);
1348 Mock::VerifyAndClearExpectations(GetDeviceMockAdaptor());
1349 Mock::VerifyAndClearExpectations(&device_info_);
1350
1351 // Add an IPv6 address while IPv6 DNS server addresses already existed.
1352 IPAddress address3(IPAddress::kFamilyIPv6);
1353 const char kAddress3[] = "fe80::1aa9:5ff:abcd:1236";
1354 ASSERT_TRUE(address3.SetAddressFromString(kAddress3));
1355 EXPECT_CALL(device_info_, GetPrimaryIPv6Address(kDeviceInterfaceIndex, _))
1356 .WillOnce(DoAll(SetArgPointee<1>(address3), Return(true)));
1357 EXPECT_CALL(*GetDeviceMockAdaptor(),
1358 EmitRpcIdentifierArrayChanged(
1359 kIPConfigsProperty,
1360 vector<string> { IPConfigMockAdaptor::kRpcId }));
1361 device_->OnIPv6AddressChanged();
1362 EXPECT_THAT(device_->ip6config_, NotNullRefPtr());
1363 EXPECT_EQ(kAddress3, device_->ip6config_->properties().address);
1364 EXPECT_EQ(dns_server_addresses_str,
1365 device_->ip6config_->properties().dns_servers);
1366 Mock::VerifyAndClearExpectations(GetDeviceMockAdaptor());
1367 Mock::VerifyAndClearExpectations(&device_info_);
1368
1369 // If the IPv6 DNS server addresses does not change, no signal is emitted.
1370 EXPECT_CALL(device_info_,
1371 GetIPv6DnsServerAddresses(kDeviceInterfaceIndex, _, _))
1372 .WillOnce(DoAll(SetArgPointee<1>(dns_server_addresses),
1373 SetArgPointee<2>(kInfiniteLifetime),
1374 Return(true)));
1375 EXPECT_CALL(*GetDeviceMockAdaptor(),
1376 EmitRpcIdentifierArrayChanged(kIPConfigsProperty, _)).Times(0);
1377 device_->OnIPv6DnsServerAddressesChanged();
1378 EXPECT_EQ(dns_server_addresses_str,
1379 device_->ip6config_->properties().dns_servers);
1380 Mock::VerifyAndClearExpectations(GetDeviceMockAdaptor());
1381 Mock::VerifyAndClearExpectations(&device_info_);
1382
1383 // Setting lifetime to 0 should expire and clear out the DNS server.
1384 const uint32 kExpiredLifetime = 0;
1385 vector<string> empty_dns_server;
1386 EXPECT_CALL(device_info_,
1387 GetIPv6DnsServerAddresses(kDeviceInterfaceIndex, _, _))
1388 .WillOnce(DoAll(SetArgPointee<1>(dns_server_addresses),
1389 SetArgPointee<2>(kExpiredLifetime),
1390 Return(true)));
1391 EXPECT_CALL(*GetDeviceMockAdaptor(),
1392 EmitRpcIdentifierArrayChanged(
1393 kIPConfigsProperty,
1394 vector<string> { IPConfigMockAdaptor::kRpcId }));
1395 device_->OnIPv6DnsServerAddressesChanged();
1396 EXPECT_EQ(empty_dns_server, device_->ip6config_->properties().dns_servers);
1397 Mock::VerifyAndClearExpectations(GetDeviceMockAdaptor());
1398 Mock::VerifyAndClearExpectations(&device_info_);
1399
1400 // Set DNS server with lifetime of 1 hour.
1401 const uint32 kLifetimeOneHr = 3600;
1402 EXPECT_CALL(device_info_,
1403 GetIPv6DnsServerAddresses(kDeviceInterfaceIndex, _, _))
1404 .WillOnce(DoAll(SetArgPointee<1>(dns_server_addresses),
1405 SetArgPointee<2>(kLifetimeOneHr),
1406 Return(true)));
1407 EXPECT_CALL(*GetDeviceMockAdaptor(),
1408 EmitRpcIdentifierArrayChanged(
1409 kIPConfigsProperty,
1410 vector<string> { IPConfigMockAdaptor::kRpcId }));
1411 device_->OnIPv6DnsServerAddressesChanged();
1412 EXPECT_EQ(dns_server_addresses_str,
1413 device_->ip6config_->properties().dns_servers);
1414 Mock::VerifyAndClearExpectations(GetDeviceMockAdaptor());
1415 Mock::VerifyAndClearExpectations(&device_info_);
1416
Ben Chancc225ef2014-09-30 13:26:51 -07001417 // Return the DNS server addresses to nullptr.
Peter Qiu25f1be62014-08-12 10:42:27 -07001418 EXPECT_CALL(device_info_,
1419 GetIPv6DnsServerAddresses(kDeviceInterfaceIndex, _, _))
1420 .WillOnce(Return(false));
1421 EXPECT_CALL(*GetDeviceMockAdaptor(),
1422 EmitRpcIdentifierArrayChanged(
1423 kIPConfigsProperty,
1424 vector<string> { IPConfigMockAdaptor::kRpcId }));
1425 device_->OnIPv6DnsServerAddressesChanged();
1426 EXPECT_EQ(empty_dns_server, device_->ip6config_->properties().dns_servers);
1427 Mock::VerifyAndClearExpectations(GetDeviceMockAdaptor());
1428 Mock::VerifyAndClearExpectations(&device_info_);
1429}
1430
Peter Qiub25083f2014-08-25 13:22:31 -07001431TEST_F(DeviceTest, OnIPv6ConfigurationCompleted) {
1432 StrictMock<MockManager> manager(control_interface(),
1433 dispatcher(),
1434 metrics(),
1435 glib());
1436 manager.set_mock_device_info(&device_info_);
Paul Stewart1ce231c2015-06-12 19:44:22 -07001437 EXPECT_CALL(manager, FilterPrependDNSServersByFamily(_))
1438 .WillRepeatedly(Return(vector<string>()));
Peter Qiub25083f2014-08-25 13:22:31 -07001439 SetManager(&manager);
1440 scoped_refptr<MockService> service(
1441 new StrictMock<MockService>(control_interface(),
1442 dispatcher(),
1443 metrics(),
1444 &manager));
1445 SelectService(service);
1446 scoped_refptr<MockConnection> connection(
1447 new StrictMock<MockConnection>(&device_info_));
1448 SetConnection(connection.get());
1449
1450 // Setup initial IPv6 configuration.
1451 SetupIPv6Config();
1452 EXPECT_THAT(device_->ip6config_, NotNullRefPtr());
1453
1454 // IPv6 configuration update with non-IPv6 connection, no connection update.
1455 EXPECT_THAT(device_->connection(), NotNullRefPtr());
1456 IPAddress address1(IPAddress::kFamilyIPv6);
1457 const char kAddress1[] = "fe80::1aa9:5ff:abcd:1231";
1458 ASSERT_TRUE(address1.SetAddressFromString(kAddress1));
1459 EXPECT_CALL(device_info_, GetPrimaryIPv6Address(kDeviceInterfaceIndex, _))
1460 .WillOnce(DoAll(SetArgPointee<1>(address1), Return(true)));
1461 EXPECT_CALL(*GetDeviceMockAdaptor(),
1462 EmitRpcIdentifierArrayChanged(
1463 kIPConfigsProperty,
1464 vector<string> { IPConfigMockAdaptor::kRpcId }));
1465 EXPECT_CALL(*connection, IsIPv6())
1466 .WillRepeatedly(Return(false));
1467 EXPECT_CALL(*service, SetConnection(_)).Times(0);
1468 device_->OnIPv6AddressChanged();
1469 Mock::VerifyAndClearExpectations(GetDeviceMockAdaptor());
1470 Mock::VerifyAndClearExpectations(&device_info_);
Alex Vakulenko0951ccb2014-12-10 12:52:31 -08001471 Mock::VerifyAndClearExpectations(service.get());
1472 Mock::VerifyAndClearExpectations(connection.get());
Peter Qiub25083f2014-08-25 13:22:31 -07001473
1474 // IPv6 configuration update with IPv6 connection, connection update.
1475 IPAddress address2(IPAddress::kFamilyIPv6);
1476 const char kAddress2[] = "fe80::1aa9:5ff:abcd:1232";
1477 ASSERT_TRUE(address2.SetAddressFromString(kAddress2));
1478 EXPECT_CALL(device_info_, GetPrimaryIPv6Address(kDeviceInterfaceIndex, _))
1479 .WillOnce(DoAll(SetArgPointee<1>(address2), Return(true)));
1480 EXPECT_CALL(*GetDeviceMockAdaptor(),
1481 EmitRpcIdentifierArrayChanged(
1482 kIPConfigsProperty,
1483 vector<string> { IPConfigMockAdaptor::kRpcId }));
1484 EXPECT_CALL(*connection, IsIPv6())
1485 .WillRepeatedly(Return(true));
1486 EXPECT_CALL(*connection, UpdateFromIPConfig(device_->ip6config_));
Peter Qiu300769e2014-08-27 11:48:45 -07001487 EXPECT_CALL(metrics_,
1488 NotifyNetworkConnectionIPType(
1489 device_->technology(),
1490 Metrics::kNetworkConnectionIPTypeIPv6));
1491 EXPECT_CALL(metrics_,
1492 NotifyIPv6ConnectivityStatus(device_->technology(), true));
Peter Qiub25083f2014-08-25 13:22:31 -07001493 EXPECT_CALL(*service, SetState(Service::kStateConnected));
1494 EXPECT_CALL(*service, IsConnected())
1495 .WillRepeatedly(Return(true));
1496 EXPECT_CALL(*service, IsPortalDetectionDisabled())
1497 .WillRepeatedly(Return(true));
1498 EXPECT_CALL(*service, SetState(Service::kStateOnline));
1499 EXPECT_CALL(*service, SetConnection(NotNullRefPtr()));
1500 EXPECT_CALL(manager, IsTechnologyLinkMonitorEnabled(_))
1501 .WillRepeatedly(Return(false));
1502 device_->OnIPv6AddressChanged();
1503 Mock::VerifyAndClearExpectations(GetDeviceMockAdaptor());
1504 Mock::VerifyAndClearExpectations(&device_info_);
Alex Vakulenko0951ccb2014-12-10 12:52:31 -08001505 Mock::VerifyAndClearExpectations(service.get());
1506 Mock::VerifyAndClearExpectations(connection.get());
Peter Qiub25083f2014-08-25 13:22:31 -07001507}
1508
Peter Qiud48fa0c2015-06-10 12:20:48 -07001509TEST_F(DeviceTest, OnDHCPv6ConfigUpdated) {
1510 device_->dhcpv6_config_ = new IPConfig(control_interface(), kDeviceName);
1511 EXPECT_CALL(*GetDeviceMockAdaptor(),
1512 EmitRpcIdentifierArrayChanged(
1513 kIPConfigsProperty,
1514 vector<string> { IPConfigMockAdaptor::kRpcId }));
1515 device_->OnDHCPv6ConfigUpdated(device_->dhcpv6_config_.get(), true);
1516}
1517
1518TEST_F(DeviceTest, OnDHCPv6ConfigFailed) {
1519 device_->dhcpv6_config_ = new IPConfig(control_interface(), kDeviceName);
1520 IPConfig::Properties properties;
1521 properties.address = "2001:db8:0:1::1";
1522 properties.delegated_prefix = "2001:db8:0:100::";
1523 properties.lease_duration_seconds = 1;
1524 device_->dhcpv6_config_->set_properties(properties);
1525 EXPECT_CALL(*GetDeviceMockAdaptor(),
1526 EmitRpcIdentifierArrayChanged(
1527 kIPConfigsProperty,
1528 vector<string> { IPConfigMockAdaptor::kRpcId }));
1529 device_->OnDHCPv6ConfigFailed(device_->dhcpv6_config_.get());
1530 EXPECT_TRUE(device_->dhcpv6_config_->properties().address.empty());
1531 EXPECT_TRUE(device_->dhcpv6_config_->properties().delegated_prefix.empty());
1532 EXPECT_EQ(0, device_->dhcpv6_config_->properties().lease_duration_seconds);
1533}
1534
1535TEST_F(DeviceTest, OnDHCPv6ConfigExpired) {
1536 device_->dhcpv6_config_ = new IPConfig(control_interface(), kDeviceName);
1537 IPConfig::Properties properties;
1538 properties.address = "2001:db8:0:1::1";
1539 properties.delegated_prefix = "2001:db8:0:100::";
1540 properties.lease_duration_seconds = 1;
1541 device_->dhcpv6_config_->set_properties(properties);
1542 EXPECT_CALL(*GetDeviceMockAdaptor(),
1543 EmitRpcIdentifierArrayChanged(
1544 kIPConfigsProperty,
1545 vector<string> { IPConfigMockAdaptor::kRpcId }));
1546 device_->OnDHCPv6ConfigExpired(device_->dhcpv6_config_.get());
1547 EXPECT_TRUE(device_->dhcpv6_config_->properties().address.empty());
1548 EXPECT_TRUE(device_->dhcpv6_config_->properties().delegated_prefix.empty());
1549 EXPECT_EQ(0, device_->dhcpv6_config_->properties().lease_duration_seconds);
1550}
1551
Garret Kellyc5f89d12015-02-18 14:39:36 -05001552TEST_F(DeviceTest, PrependIPv4DNSServers) {
1553 MockManager manager(control_interface(), dispatcher(), metrics(), glib());
1554 manager.set_mock_device_info(&device_info_);
1555 SetManager(&manager);
1556
Paul Stewart1ce231c2015-06-12 19:44:22 -07001557 const struct {
1558 vector<string> ipconfig_servers;
1559 vector<string> prepend_servers;
1560 vector<string> expected_servers;
1561 } expectations[] = {
1562 {{}, {"8.8.8.8"}, {"8.8.8.8"}},
1563 {{"8.8.8.8"}, {}, {"8.8.8.8"}},
1564 {{"8.8.8.8"}, {"10.10.10.10"}, {"10.10.10.10", "8.8.8.8"}},
1565 {{"8.8.8.8", "10.10.10.10"}, {"10.10.10.10"}, {"10.10.10.10", "8.8.8.8"}},
1566 {{"8.8.8.8", "10.10.10.10"}, {"8.8.8.8"}, {"8.8.8.8", "10.10.10.10"}},
1567 {{"8.8.8.8", "9.9.9.9", "10.10.10.10"}, {"9.9.9.9"},
1568 {"9.9.9.9", "8.8.8.8", "10.10.10.10"}},
1569 };
Garret Kellyc5f89d12015-02-18 14:39:36 -05001570
Paul Stewart3b30ca52015-06-16 13:13:10 -07001571 for (const auto& expectation : expectations) {
Paul Stewart1ce231c2015-06-12 19:44:22 -07001572 scoped_refptr<IPConfig> ipconfig =
1573 new IPConfig(control_interface(), kDeviceName);
1574
1575 EXPECT_CALL(manager, FilterPrependDNSServersByFamily(
1576 IPAddress::kFamilyIPv4)).WillOnce(Return(expectation.prepend_servers));
Garret Kellyc5f89d12015-02-18 14:39:36 -05001577 IPConfig::Properties properties;
Paul Stewart1ce231c2015-06-12 19:44:22 -07001578 properties.dns_servers = expectation.ipconfig_servers;
Garret Kellyc5f89d12015-02-18 14:39:36 -05001579 properties.address_family = IPAddress::kFamilyIPv4;
1580 ipconfig->set_properties(properties);
1581
1582 device_->set_ipconfig(ipconfig);
Garret Kellyc5f89d12015-02-18 14:39:36 -05001583 OnIPConfigUpdated(ipconfig.get());
Paul Stewart1ce231c2015-06-12 19:44:22 -07001584 EXPECT_EQ(expectation.expected_servers,
1585 device_->ipconfig()->properties().dns_servers);
Garret Kellyc5f89d12015-02-18 14:39:36 -05001586 }
1587}
1588
Paul Stewart60a922e2015-06-16 11:28:29 -07001589TEST_F(DeviceTest, PrependIPv6DNSServers) {
Garret Kellyc5f89d12015-02-18 14:39:36 -05001590 MockManager manager(control_interface(), dispatcher(), metrics(), glib());
1591 manager.set_mock_device_info(&device_info_);
1592 SetManager(&manager);
1593
1594 vector<IPAddress> dns_server_addresses = {
1595 IPAddress("2001:4860:4860::8888"),
Paul Stewart1ce231c2015-06-12 19:44:22 -07001596 IPAddress("2001:4860:4860::8844")
Garret Kellyc5f89d12015-02-18 14:39:36 -05001597 };
1598
Paul Stewart60a922e2015-06-16 11:28:29 -07001599 const uint32 kAddressLifetime = 1000;
Garret Kellyc5f89d12015-02-18 14:39:36 -05001600 EXPECT_CALL(device_info_, GetIPv6DnsServerAddresses(_, _, _))
1601 .WillRepeatedly(DoAll(SetArgPointee<1>(dns_server_addresses),
Paul Stewart60a922e2015-06-16 11:28:29 -07001602 SetArgPointee<2>(kAddressLifetime),
Garret Kellyc5f89d12015-02-18 14:39:36 -05001603 Return(true)));
Paul Stewart1ce231c2015-06-12 19:44:22 -07001604 const vector<string> kOutputServers {"2001:4860:4860::8899"};
1605 EXPECT_CALL(manager, FilterPrependDNSServersByFamily(
1606 IPAddress::kFamilyIPv6)).WillOnce(Return(kOutputServers));
Garret Kellyc5f89d12015-02-18 14:39:36 -05001607 device_->OnIPv6DnsServerAddressesChanged();
1608
Paul Stewart1ce231c2015-06-12 19:44:22 -07001609 const vector<string> kExpectedServers
1610 {"2001:4860:4860::8899", "2001:4860:4860::8888", "2001:4860:4860::8844"};
1611 EXPECT_EQ(kExpectedServers, device_->ip6config()->properties().dns_servers);
Garret Kellyc5f89d12015-02-18 14:39:36 -05001612}
1613
Garret Kelly84a90ce2015-03-25 14:54:19 -04001614TEST_F(DeviceTest, PrependWithStaticConfiguration) {
1615 MockManager manager(control_interface(), dispatcher(), metrics(), glib());
1616 manager.set_mock_device_info(&device_info_);
Garret Kelly84a90ce2015-03-25 14:54:19 -04001617 SetManager(&manager);
1618
Paul Stewart1ce231c2015-06-12 19:44:22 -07001619 scoped_refptr<IPConfig> ipconfig =
1620 new IPConfig(control_interface(), kDeviceName);
1621
Garret Kellyd01b5cc2015-03-12 16:20:55 -04001622 device_->set_ipconfig(ipconfig);
Garret Kelly84a90ce2015-03-25 14:54:19 -04001623
1624 scoped_refptr<MockService> service = new MockService(control_interface(),
1625 dispatcher(),
1626 metrics(),
1627 &manager);
Garret Kelly84a90ce2015-03-25 14:54:19 -04001628 EXPECT_CALL(*service, IsPortalDetectionDisabled())
1629 .WillRepeatedly(Return(true));
1630 SelectService(service);
1631
1632 auto parameters = service->mutable_static_ip_parameters();
1633 parameters->args_.SetString(kAddressProperty, "1.1.1.1");
Garret Kelly84a90ce2015-03-25 14:54:19 -04001634 parameters->args_.SetInt(kPrefixlenProperty, 16);
1635
1636 scoped_refptr<MockConnection> connection = new MockConnection(&device_info_);
1637 SetConnection(connection);
1638
Garret Kellyd01b5cc2015-03-12 16:20:55 -04001639 // Ensure that in the absence of statically configured nameservers that the
1640 // prepend DNS servers are still prepended.
Garret Kellyd01b5cc2015-03-12 16:20:55 -04001641 EXPECT_CALL(*service, HasStaticNameServers()).WillOnce(Return(false));
Paul Stewart1ce231c2015-06-12 19:44:22 -07001642 const vector<string> kOutputServers {"8.8.8.8"};
1643 EXPECT_CALL(manager, FilterPrependDNSServersByFamily(
1644 IPAddress::kFamilyIPv4)).WillRepeatedly(Return(kOutputServers));
Garret Kelly84a90ce2015-03-25 14:54:19 -04001645 OnIPConfigUpdated(ipconfig.get());
Paul Stewart1ce231c2015-06-12 19:44:22 -07001646 EXPECT_EQ(kOutputServers, device_->ipconfig()->properties().dns_servers);
Garret Kellyd01b5cc2015-03-12 16:20:55 -04001647
1648 // Ensure that when nameservers are statically configured that the prepend DNS
1649 // servers are not used.
1650 const vector<string> static_servers = {"4.4.4.4", "5.5.5.5"};
1651 parameters->args_.SetStrings(kNameServersProperty, static_servers);
1652 EXPECT_CALL(*service, HasStaticNameServers()).WillOnce(Return(true));
1653 OnIPConfigUpdated(ipconfig.get());
1654 EXPECT_EQ(static_servers, device_->ipconfig()->properties().dns_servers);
Garret Kelly84a90ce2015-03-25 14:54:19 -04001655}
1656
Peter Qiu62abf312015-05-05 12:58:05 -07001657TEST_F(DeviceTest, ResolvePeerMacAddress) {
1658 MockManager manager(control_interface(),
1659 dispatcher(),
1660 metrics(),
1661 glib());
1662 manager.set_mock_device_info(&device_info_);
1663 SetManager(&manager);
1664
1665 // Invalid peer address (not a valid IP address nor MAC address).
1666 Error error;
1667 string result;
1668 const char kInvalidPeer[] = "peer";
1669 EXPECT_FALSE(device_->ResolvePeerMacAddress(kInvalidPeer, &result, &error));
1670 EXPECT_EQ(Error::kInvalidArguments, error.type());
1671
1672 // No direct connectivity to the peer.
1673 const char kPeerIp[] = "192.168.1.1";
1674 error.Reset();
1675 EXPECT_CALL(device_info_,
1676 HasDirectConnectivityTo(device_->interface_index(), _))
1677 .WillOnce(Return(false));
1678 EXPECT_FALSE(device_->ResolvePeerMacAddress(kPeerIp, &result, &error));
1679 EXPECT_EQ(Error::kInvalidArguments, error.type());
1680 Mock::VerifyAndClearExpectations(&device_info_);
1681
1682 // Provided IP address is in the ARP cache, return the resolved MAC address.
1683 const char kResolvedMac[] = "00:11:22:33:44:55";
1684 const ByteString kMacBytes(
1685 Device::MakeHardwareAddressFromString(kResolvedMac));
1686 error.Reset();
1687 EXPECT_CALL(device_info_,
1688 HasDirectConnectivityTo(device_->interface_index(), _))
1689 .WillOnce(Return(true));
1690 EXPECT_CALL(device_info_,
1691 GetMACAddressOfPeer(device_->interface_index(), _, _))
1692 .WillOnce(DoAll(SetArgPointee<2>(kMacBytes), Return(true)));
1693 EXPECT_TRUE(device_->ResolvePeerMacAddress(kPeerIp, &result, &error));
1694 EXPECT_EQ(kResolvedMac, result);
1695}
1696
Paul Stewart208a97e2015-05-13 09:11:12 -07001697TEST_F(DeviceTest, SetHostnameWithEmptyHostname) {
1698 MockManager manager(control_interface(),
1699 dispatcher(),
1700 metrics(),
1701 glib());
1702 manager.set_mock_device_info(&device_info_);
1703 SetManager(&manager);
1704
1705 EXPECT_CALL(manager, ShouldAcceptHostnameFrom(_)).Times(0);
1706 EXPECT_CALL(device_info_, SetHostname(_)).Times(0);
1707 EXPECT_FALSE(SetHostname(""));
1708}
1709
1710TEST_F(DeviceTest, SetHostnameForDisallowedDevice) {
1711 MockManager manager(control_interface(),
1712 dispatcher(),
1713 metrics(),
1714 glib());
1715 manager.set_mock_device_info(&device_info_);
1716 SetManager(&manager);
1717
1718 EXPECT_CALL(manager, ShouldAcceptHostnameFrom(kDeviceName))
1719 .WillOnce(Return(false));
1720 EXPECT_CALL(device_info_, SetHostname(_)).Times(0);
1721 EXPECT_FALSE(SetHostname("wilson"));
1722}
1723
1724TEST_F(DeviceTest, SetHostnameWithFailingDeviceInfo) {
1725 MockManager manager(control_interface(),
1726 dispatcher(),
1727 metrics(),
1728 glib());
1729 manager.set_mock_device_info(&device_info_);
1730 SetManager(&manager);
1731
1732 EXPECT_CALL(manager, ShouldAcceptHostnameFrom(kDeviceName))
1733 .WillOnce(Return(true));
1734 EXPECT_CALL(device_info_, SetHostname("wilson"))
1735 .WillOnce(Return(false));
1736 EXPECT_FALSE(SetHostname("wilson"));
1737}
1738
1739TEST_F(DeviceTest, SetHostnameMaximumHostnameLength) {
1740 MockManager manager(control_interface(),
1741 dispatcher(),
1742 metrics(),
1743 glib());
1744 manager.set_mock_device_info(&device_info_);
1745 SetManager(&manager);
1746
1747 EXPECT_CALL(manager, ShouldAcceptHostnameFrom(kDeviceName))
1748 .WillOnce(Return(true));
1749 EXPECT_CALL(device_info_, SetHostname(
1750 "wilson.was-a-good-ball.and-was.an-excellent-swimmer.in-high-seas"))
1751 .WillOnce(Return(true));
1752 EXPECT_TRUE(SetHostname(
1753 "wilson.was-a-good-ball.and-was.an-excellent-swimmer.in-high-seas"));
1754}
1755
1756TEST_F(DeviceTest, SetHostnameTruncateDomainName) {
1757 MockManager manager(control_interface(),
1758 dispatcher(),
1759 metrics(),
1760 glib());
1761 manager.set_mock_device_info(&device_info_);
1762 SetManager(&manager);
1763
1764 EXPECT_CALL(manager, ShouldAcceptHostnameFrom(kDeviceName))
1765 .WillOnce(Return(true));
1766 EXPECT_CALL(device_info_, SetHostname("wilson"))
1767 .WillOnce(Return(false));
1768 EXPECT_FALSE(SetHostname(
1769 "wilson.was-a-great-ball.and-was.an-excellent-swimmer.in-high-seas"));
1770}
1771
1772TEST_F(DeviceTest, SetHostnameTruncateHostname) {
1773 MockManager manager(control_interface(),
1774 dispatcher(),
1775 metrics(),
1776 glib());
1777 manager.set_mock_device_info(&device_info_);
1778 SetManager(&manager);
1779
1780 EXPECT_CALL(manager, ShouldAcceptHostnameFrom(kDeviceName))
1781 .WillOnce(Return(true));
1782 EXPECT_CALL(device_info_, SetHostname(
1783 "wilson-was-a-great-ball-and-was-an-excellent-swimmer-in-high-sea"))
1784 .WillOnce(Return(true));
1785 EXPECT_TRUE(SetHostname(
1786 "wilson-was-a-great-ball-and-was-an-excellent-swimmer-in-high-sea-chop"));
1787}
1788
Paul Stewartc681fa02012-03-02 19:40:04 -08001789class DevicePortalDetectionTest : public DeviceTest {
1790 public:
1791 DevicePortalDetectionTest()
1792 : connection_(new StrictMock<MockConnection>(&device_info_)),
1793 manager_(control_interface(),
1794 dispatcher(),
1795 metrics(),
1796 glib()),
1797 service_(new StrictMock<MockService>(control_interface(),
1798 dispatcher(),
1799 metrics(),
1800 &manager_)),
1801 portal_detector_(new StrictMock<MockPortalDetector>(connection_)) {}
1802 virtual ~DevicePortalDetectionTest() {}
1803 virtual void SetUp() {
1804 DeviceTest::SetUp();
1805 SelectService(service_);
1806 SetConnection(connection_.get());
1807 device_->portal_detector_.reset(portal_detector_); // Passes ownership.
Paul Stewart036dba02012-08-07 12:34:41 -07001808 SetManager(&manager_);
Paul Stewartc681fa02012-03-02 19:40:04 -08001809 }
1810
1811 protected:
Thieu Le85e050b2012-03-13 15:04:38 -07001812 static const int kPortalAttempts;
1813
Paul Stewartc681fa02012-03-02 19:40:04 -08001814 bool StartPortalDetection() { return device_->StartPortalDetection(); }
1815 void StopPortalDetection() { device_->StopPortalDetection(); }
1816
Paul Stewart3b30ca52015-06-16 13:13:10 -07001817 void PortalDetectorCallback(const PortalDetector::Result& result) {
Paul Stewartc681fa02012-03-02 19:40:04 -08001818 device_->PortalDetectorCallback(result);
1819 }
1820 bool RequestPortalDetection() {
1821 return device_->RequestPortalDetection();
1822 }
1823 void SetServiceConnectedState(Service::ConnectState state) {
1824 device_->SetServiceConnectedState(state);
1825 }
1826 void ExpectPortalDetectorReset() {
1827 EXPECT_FALSE(device_->portal_detector_.get());
1828 }
1829 void ExpectPortalDetectorSet() {
1830 EXPECT_TRUE(device_->portal_detector_.get());
1831 }
1832 void ExpectPortalDetectorIsMock() {
1833 EXPECT_EQ(portal_detector_, device_->portal_detector_.get());
1834 }
Peter Qiud670d032014-06-03 15:04:43 -07001835 void InvokeFallbackDNSResultCallback(DNSServerTester::Status status) {
1836 device_->FallbackDNSResultCallback(status);
Peter Qiub9256f32014-05-09 15:27:29 -07001837 }
Peter Qiu6f5618b2014-06-05 15:19:01 -07001838 void InvokeConfigDNSResultCallback(DNSServerTester::Status status) {
1839 device_->ConfigDNSResultCallback(status);
1840 }
Paul Stewarte8303eb2014-10-08 22:51:14 -07001841 void DestroyConnection() { device_->DestroyConnection(); }
Paul Stewartc681fa02012-03-02 19:40:04 -08001842 scoped_refptr<MockConnection> connection_;
1843 StrictMock<MockManager> manager_;
1844 scoped_refptr<MockService> service_;
1845
1846 // Used only for EXPECT_CALL(). Object is owned by device.
Paul Stewart3b30ca52015-06-16 13:13:10 -07001847 MockPortalDetector* portal_detector_;
Paul Stewartc681fa02012-03-02 19:40:04 -08001848};
1849
Thieu Le85e050b2012-03-13 15:04:38 -07001850const int DevicePortalDetectionTest::kPortalAttempts = 2;
1851
Paul Stewartd215af62012-04-24 23:25:50 -07001852TEST_F(DevicePortalDetectionTest, ServicePortalDetectionDisabled) {
1853 EXPECT_CALL(*service_.get(), IsPortalDetectionDisabled())
1854 .WillOnce(Return(true));
Paul Stewartc681fa02012-03-02 19:40:04 -08001855 EXPECT_CALL(*service_.get(), IsConnected())
Paul Stewart20088d82012-02-16 06:58:55 -08001856 .WillRepeatedly(Return(true));
Paul Stewartd215af62012-04-24 23:25:50 -07001857 EXPECT_CALL(*service_.get(), SetState(Service::kStateOnline));
1858 EXPECT_FALSE(StartPortalDetection());
1859}
1860
1861TEST_F(DevicePortalDetectionTest, TechnologyPortalDetectionDisabled) {
1862 EXPECT_CALL(*service_.get(), IsPortalDetectionDisabled())
1863 .WillOnce(Return(false));
1864 EXPECT_CALL(*service_.get(), IsConnected())
1865 .WillRepeatedly(Return(true));
1866 EXPECT_CALL(*service_.get(), IsPortalDetectionAuto())
1867 .WillOnce(Return(true));
Paul Stewartc681fa02012-03-02 19:40:04 -08001868 EXPECT_CALL(manager_, IsPortalDetectionEnabled(device_->technology()))
Paul Stewart20088d82012-02-16 06:58:55 -08001869 .WillOnce(Return(false));
Paul Stewartc681fa02012-03-02 19:40:04 -08001870 EXPECT_CALL(*service_.get(), SetState(Service::kStateOnline));
Paul Stewart20088d82012-02-16 06:58:55 -08001871 EXPECT_FALSE(StartPortalDetection());
1872}
1873
Paul Stewartc681fa02012-03-02 19:40:04 -08001874TEST_F(DevicePortalDetectionTest, PortalDetectionProxyConfig) {
Paul Stewartd215af62012-04-24 23:25:50 -07001875 EXPECT_CALL(*service_.get(), IsPortalDetectionDisabled())
1876 .WillOnce(Return(false));
Paul Stewartc681fa02012-03-02 19:40:04 -08001877 EXPECT_CALL(*service_.get(), IsConnected())
Paul Stewart20088d82012-02-16 06:58:55 -08001878 .WillRepeatedly(Return(true));
Paul Stewartc681fa02012-03-02 19:40:04 -08001879 EXPECT_CALL(*service_.get(), HasProxyConfig())
Paul Stewart20088d82012-02-16 06:58:55 -08001880 .WillOnce(Return(true));
Paul Stewartd215af62012-04-24 23:25:50 -07001881 EXPECT_CALL(*service_.get(), IsPortalDetectionAuto())
1882 .WillOnce(Return(true));
Paul Stewartc681fa02012-03-02 19:40:04 -08001883 EXPECT_CALL(manager_, IsPortalDetectionEnabled(device_->technology()))
Paul Stewart20088d82012-02-16 06:58:55 -08001884 .WillOnce(Return(true));
Paul Stewartc681fa02012-03-02 19:40:04 -08001885 EXPECT_CALL(*service_.get(), SetState(Service::kStateOnline));
Paul Stewart20088d82012-02-16 06:58:55 -08001886 EXPECT_FALSE(StartPortalDetection());
1887}
1888
Paul Stewartc681fa02012-03-02 19:40:04 -08001889TEST_F(DevicePortalDetectionTest, PortalDetectionBadUrl) {
Paul Stewartd215af62012-04-24 23:25:50 -07001890 EXPECT_CALL(*service_.get(), IsPortalDetectionDisabled())
1891 .WillOnce(Return(false));
Paul Stewartc681fa02012-03-02 19:40:04 -08001892 EXPECT_CALL(*service_.get(), IsConnected())
Paul Stewart20088d82012-02-16 06:58:55 -08001893 .WillRepeatedly(Return(true));
Paul Stewartc681fa02012-03-02 19:40:04 -08001894 EXPECT_CALL(*service_.get(), HasProxyConfig())
Paul Stewart20088d82012-02-16 06:58:55 -08001895 .WillOnce(Return(false));
Paul Stewartd215af62012-04-24 23:25:50 -07001896 EXPECT_CALL(*service_.get(), IsPortalDetectionAuto())
1897 .WillOnce(Return(true));
Paul Stewartc681fa02012-03-02 19:40:04 -08001898 EXPECT_CALL(manager_, IsPortalDetectionEnabled(device_->technology()))
Paul Stewart20088d82012-02-16 06:58:55 -08001899 .WillOnce(Return(true));
1900 const string portal_url;
Paul Stewartc681fa02012-03-02 19:40:04 -08001901 EXPECT_CALL(manager_, GetPortalCheckURL())
Paul Stewart20088d82012-02-16 06:58:55 -08001902 .WillRepeatedly(ReturnRef(portal_url));
Paul Stewartc681fa02012-03-02 19:40:04 -08001903 EXPECT_CALL(*service_.get(), SetState(Service::kStateOnline));
Paul Stewart20088d82012-02-16 06:58:55 -08001904 EXPECT_FALSE(StartPortalDetection());
1905}
1906
Paul Stewartc681fa02012-03-02 19:40:04 -08001907TEST_F(DevicePortalDetectionTest, PortalDetectionStart) {
Paul Stewartd215af62012-04-24 23:25:50 -07001908 EXPECT_CALL(*service_.get(), IsPortalDetectionDisabled())
1909 .WillOnce(Return(false));
Paul Stewartc681fa02012-03-02 19:40:04 -08001910 EXPECT_CALL(*service_.get(), IsConnected())
Paul Stewart20088d82012-02-16 06:58:55 -08001911 .WillRepeatedly(Return(true));
Paul Stewartc681fa02012-03-02 19:40:04 -08001912 EXPECT_CALL(*service_.get(), HasProxyConfig())
Paul Stewart20088d82012-02-16 06:58:55 -08001913 .WillOnce(Return(false));
Paul Stewartd215af62012-04-24 23:25:50 -07001914 EXPECT_CALL(*service_.get(), IsPortalDetectionAuto())
1915 .WillOnce(Return(true));
Paul Stewartc681fa02012-03-02 19:40:04 -08001916 EXPECT_CALL(manager_, IsPortalDetectionEnabled(device_->technology()))
Paul Stewart20088d82012-02-16 06:58:55 -08001917 .WillOnce(Return(true));
Rebecca Silberstein3d49ea42014-08-21 11:20:50 -07001918 const string portal_url(ConnectivityTrial::kDefaultURL);
Paul Stewartc681fa02012-03-02 19:40:04 -08001919 EXPECT_CALL(manager_, GetPortalCheckURL())
Paul Stewart20088d82012-02-16 06:58:55 -08001920 .WillRepeatedly(ReturnRef(portal_url));
Paul Stewartc681fa02012-03-02 19:40:04 -08001921 EXPECT_CALL(*service_.get(), SetState(Service::kStateOnline))
Paul Stewart20088d82012-02-16 06:58:55 -08001922 .Times(0);
Paul Stewart20088d82012-02-16 06:58:55 -08001923 const string kInterfaceName("int0");
Paul Stewartc681fa02012-03-02 19:40:04 -08001924 EXPECT_CALL(*connection_.get(), interface_name())
1925 .WillRepeatedly(ReturnRef(kInterfaceName));
Peter Qiuf3a8f902014-08-20 10:05:42 -07001926 EXPECT_CALL(*connection_.get(), IsIPv6())
1927 .WillRepeatedly(Return(false));
1928 const vector<string> kDNSServers;
1929 EXPECT_CALL(*connection_.get(), dns_servers())
1930 .WillRepeatedly(ReturnRef(kDNSServers));
1931 EXPECT_TRUE(StartPortalDetection());
1932
1933 // Drop all references to device_info before it falls out of scope.
Ben Chancc225ef2014-09-30 13:26:51 -07001934 SetConnection(nullptr);
Peter Qiuf3a8f902014-08-20 10:05:42 -07001935 StopPortalDetection();
1936}
1937
1938TEST_F(DevicePortalDetectionTest, PortalDetectionStartIPv6) {
1939 EXPECT_CALL(*service_.get(), IsPortalDetectionDisabled())
1940 .WillOnce(Return(false));
1941 EXPECT_CALL(*service_.get(), IsConnected())
1942 .WillRepeatedly(Return(true));
1943 EXPECT_CALL(*service_.get(), HasProxyConfig())
1944 .WillOnce(Return(false));
1945 EXPECT_CALL(*service_.get(), IsPortalDetectionAuto())
1946 .WillOnce(Return(true));
1947 EXPECT_CALL(manager_, IsPortalDetectionEnabled(device_->technology()))
1948 .WillOnce(Return(true));
Rebecca Silberstein3d49ea42014-08-21 11:20:50 -07001949 const string portal_url(ConnectivityTrial::kDefaultURL);
Peter Qiuf3a8f902014-08-20 10:05:42 -07001950 EXPECT_CALL(manager_, GetPortalCheckURL())
1951 .WillRepeatedly(ReturnRef(portal_url));
1952 EXPECT_CALL(*service_.get(), SetState(Service::kStateOnline))
1953 .Times(0);
1954 const string kInterfaceName("int0");
1955 EXPECT_CALL(*connection_.get(), interface_name())
1956 .WillRepeatedly(ReturnRef(kInterfaceName));
1957 EXPECT_CALL(*connection_.get(), IsIPv6())
1958 .WillRepeatedly(Return(true));
Paul Stewart20088d82012-02-16 06:58:55 -08001959 const vector<string> kDNSServers;
Paul Stewartc681fa02012-03-02 19:40:04 -08001960 EXPECT_CALL(*connection_.get(), dns_servers())
1961 .WillRepeatedly(ReturnRef(kDNSServers));
Paul Stewart20088d82012-02-16 06:58:55 -08001962 EXPECT_TRUE(StartPortalDetection());
1963
1964 // Drop all references to device_info before it falls out of scope.
Ben Chancc225ef2014-09-30 13:26:51 -07001965 SetConnection(nullptr);
Paul Stewart20088d82012-02-16 06:58:55 -08001966 StopPortalDetection();
1967}
1968
Paul Stewartc681fa02012-03-02 19:40:04 -08001969TEST_F(DevicePortalDetectionTest, PortalDetectionNonFinal) {
1970 EXPECT_CALL(*service_.get(), IsConnected())
Paul Stewart20088d82012-02-16 06:58:55 -08001971 .Times(0);
Paul Stewartc681fa02012-03-02 19:40:04 -08001972 EXPECT_CALL(*service_.get(), SetState(_))
Paul Stewart20088d82012-02-16 06:58:55 -08001973 .Times(0);
Rebecca Silberstein3d49ea42014-08-21 11:20:50 -07001974 PortalDetectorCallback(
1975 PortalDetector::Result(
1976 ConnectivityTrial::Result(
1977 ConnectivityTrial::kPhaseUnknown,
1978 ConnectivityTrial::kStatusFailure),
1979 kPortalAttempts,
1980 false));
Paul Stewart20088d82012-02-16 06:58:55 -08001981}
1982
Paul Stewartc681fa02012-03-02 19:40:04 -08001983TEST_F(DevicePortalDetectionTest, PortalDetectionFailure) {
1984 EXPECT_CALL(*service_.get(), IsConnected())
Paul Stewart20088d82012-02-16 06:58:55 -08001985 .WillOnce(Return(true));
Peter Qiu9b83c892014-08-09 23:06:02 -07001986 EXPECT_CALL(*service_.get(),
1987 SetPortalDetectionFailure(kPortalDetectionPhaseConnection,
1988 kPortalDetectionStatusFailure));
Paul Stewartc681fa02012-03-02 19:40:04 -08001989 EXPECT_CALL(*service_.get(), SetState(Service::kStatePortal));
Thieu Le85e050b2012-03-13 15:04:38 -07001990 EXPECT_CALL(metrics_,
1991 SendEnumToUMA("Network.Shill.Unknown.PortalResult",
1992 Metrics::kPortalResultConnectionFailure,
1993 Metrics::kPortalResultMax));
1994 EXPECT_CALL(metrics_,
1995 SendToUMA("Network.Shill.Unknown.PortalAttemptsToOnline",
1996 _, _, _, _)).Times(0);
1997 EXPECT_CALL(metrics_,
1998 SendToUMA("Network.Shill.Unknown.PortalAttempts",
1999 kPortalAttempts,
2000 Metrics::kMetricPortalAttemptsMin,
2001 Metrics::kMetricPortalAttemptsMax,
2002 Metrics::kMetricPortalAttemptsNumBuckets));
Paul Stewartc681fa02012-03-02 19:40:04 -08002003 EXPECT_CALL(*connection_.get(), is_default())
2004 .WillOnce(Return(false));
Peter Qiub25083f2014-08-25 13:22:31 -07002005 EXPECT_CALL(*connection_.get(), IsIPv6())
2006 .WillOnce(Return(false));
Rebecca Silberstein3d49ea42014-08-21 11:20:50 -07002007 PortalDetectorCallback(
2008 PortalDetector::Result(
2009 ConnectivityTrial::Result(
2010 ConnectivityTrial::kPhaseConnection,
2011 ConnectivityTrial::kStatusFailure),
2012 kPortalAttempts,
2013 true));
Paul Stewart20088d82012-02-16 06:58:55 -08002014}
2015
Paul Stewartc681fa02012-03-02 19:40:04 -08002016TEST_F(DevicePortalDetectionTest, PortalDetectionSuccess) {
2017 EXPECT_CALL(*service_.get(), IsConnected())
Paul Stewart20088d82012-02-16 06:58:55 -08002018 .WillOnce(Return(true));
Peter Qiu9b83c892014-08-09 23:06:02 -07002019 EXPECT_CALL(*service_.get(), SetPortalDetectionFailure(_, _)).Times(0);
Paul Stewartc681fa02012-03-02 19:40:04 -08002020 EXPECT_CALL(*service_.get(), SetState(Service::kStateOnline));
Thieu Le85e050b2012-03-13 15:04:38 -07002021 EXPECT_CALL(metrics_,
2022 SendEnumToUMA("Network.Shill.Unknown.PortalResult",
2023 Metrics::kPortalResultSuccess,
2024 Metrics::kPortalResultMax));
2025 EXPECT_CALL(metrics_,
2026 SendToUMA("Network.Shill.Unknown.PortalAttemptsToOnline",
2027 kPortalAttempts,
2028 Metrics::kMetricPortalAttemptsToOnlineMin,
2029 Metrics::kMetricPortalAttemptsToOnlineMax,
2030 Metrics::kMetricPortalAttemptsToOnlineNumBuckets));
2031 EXPECT_CALL(metrics_,
2032 SendToUMA("Network.Shill.Unknown.PortalAttempts",
2033 _, _, _, _)).Times(0);
Rebecca Silberstein3d49ea42014-08-21 11:20:50 -07002034 PortalDetectorCallback(
2035 PortalDetector::Result(
2036 ConnectivityTrial::Result(
2037 ConnectivityTrial::kPhaseContent,
2038 ConnectivityTrial::kStatusSuccess),
2039 kPortalAttempts,
2040 true));
Thieu Le85e050b2012-03-13 15:04:38 -07002041}
2042
2043TEST_F(DevicePortalDetectionTest, PortalDetectionSuccessAfterFailure) {
2044 EXPECT_CALL(*service_.get(), IsConnected())
2045 .WillRepeatedly(Return(true));
Peter Qiu9b83c892014-08-09 23:06:02 -07002046 EXPECT_CALL(*service_.get(),
2047 SetPortalDetectionFailure(kPortalDetectionPhaseConnection,
2048 kPortalDetectionStatusFailure));
Thieu Le85e050b2012-03-13 15:04:38 -07002049 EXPECT_CALL(*service_.get(), SetState(Service::kStatePortal));
2050 EXPECT_CALL(metrics_,
2051 SendEnumToUMA("Network.Shill.Unknown.PortalResult",
2052 Metrics::kPortalResultConnectionFailure,
2053 Metrics::kPortalResultMax));
2054 EXPECT_CALL(metrics_,
2055 SendToUMA("Network.Shill.Unknown.PortalAttemptsToOnline",
2056 _, _, _, _)).Times(0);
2057 EXPECT_CALL(metrics_,
2058 SendToUMA("Network.Shill.Unknown.PortalAttempts",
2059 kPortalAttempts,
2060 Metrics::kMetricPortalAttemptsMin,
2061 Metrics::kMetricPortalAttemptsMax,
2062 Metrics::kMetricPortalAttemptsNumBuckets));
2063 EXPECT_CALL(*connection_.get(), is_default())
2064 .WillOnce(Return(false));
Peter Qiub25083f2014-08-25 13:22:31 -07002065 EXPECT_CALL(*connection_.get(), IsIPv6())
2066 .WillOnce(Return(false));
Rebecca Silberstein3d49ea42014-08-21 11:20:50 -07002067 PortalDetectorCallback(
2068 PortalDetector::Result(
2069 ConnectivityTrial::Result(
2070 ConnectivityTrial::kPhaseConnection,
2071 ConnectivityTrial::kStatusFailure),
2072 kPortalAttempts,
2073 true));
Thieu Le85e050b2012-03-13 15:04:38 -07002074 Mock::VerifyAndClearExpectations(&metrics_);
Peter Qiu9b83c892014-08-09 23:06:02 -07002075 EXPECT_CALL(*service_.get(), SetPortalDetectionFailure(_, _)).Times(0);
Thieu Le85e050b2012-03-13 15:04:38 -07002076 EXPECT_CALL(*service_.get(), SetState(Service::kStateOnline));
2077 EXPECT_CALL(metrics_,
2078 SendEnumToUMA("Network.Shill.Unknown.PortalResult",
2079 Metrics::kPortalResultSuccess,
2080 Metrics::kPortalResultMax));
2081 EXPECT_CALL(metrics_,
2082 SendToUMA("Network.Shill.Unknown.PortalAttemptsToOnline",
2083 kPortalAttempts * 2,
2084 Metrics::kMetricPortalAttemptsToOnlineMin,
2085 Metrics::kMetricPortalAttemptsToOnlineMax,
2086 Metrics::kMetricPortalAttemptsToOnlineNumBuckets));
2087 EXPECT_CALL(metrics_,
2088 SendToUMA("Network.Shill.Unknown.PortalAttempts",
2089 _, _, _, _)).Times(0);
Rebecca Silberstein3d49ea42014-08-21 11:20:50 -07002090 PortalDetectorCallback(
2091 PortalDetector::Result(
2092 ConnectivityTrial::Result(
2093 ConnectivityTrial::kPhaseContent,
2094 ConnectivityTrial::kStatusSuccess),
2095 kPortalAttempts,
2096 true));
Paul Stewart20088d82012-02-16 06:58:55 -08002097}
2098
Paul Stewartc681fa02012-03-02 19:40:04 -08002099TEST_F(DevicePortalDetectionTest, RequestPortalDetection) {
2100 EXPECT_CALL(*service_.get(), state())
2101 .WillOnce(Return(Service::kStateOnline))
2102 .WillRepeatedly(Return(Service::kStatePortal));
2103 EXPECT_FALSE(RequestPortalDetection());
2104
2105 EXPECT_CALL(*connection_.get(), is_default())
2106 .WillOnce(Return(false))
2107 .WillRepeatedly(Return(true));
2108 EXPECT_FALSE(RequestPortalDetection());
2109
2110 EXPECT_CALL(*portal_detector_, IsInProgress())
2111 .WillOnce(Return(true));
2112 // Portal detection already running.
2113 EXPECT_TRUE(RequestPortalDetection());
2114
2115 // Make sure our running mock portal detector was not replaced.
2116 ExpectPortalDetectorIsMock();
2117
2118 // Throw away our pre-fabricated portal detector, and have the device create
2119 // a new one.
2120 StopPortalDetection();
Paul Stewartd215af62012-04-24 23:25:50 -07002121 EXPECT_CALL(*service_.get(), IsPortalDetectionDisabled())
2122 .WillRepeatedly(Return(false));
2123 EXPECT_CALL(*service_.get(), IsPortalDetectionAuto())
2124 .WillRepeatedly(Return(true));
Paul Stewartc681fa02012-03-02 19:40:04 -08002125 EXPECT_CALL(manager_, IsPortalDetectionEnabled(device_->technology()))
2126 .WillRepeatedly(Return(true));
2127 EXPECT_CALL(*service_.get(), HasProxyConfig())
2128 .WillRepeatedly(Return(false));
2129 const string kPortalCheckURL("http://portal");
2130 EXPECT_CALL(manager_, GetPortalCheckURL())
2131 .WillOnce(ReturnRef(kPortalCheckURL));
2132 const string kInterfaceName("int0");
Peter Qiuf3a8f902014-08-20 10:05:42 -07002133 EXPECT_CALL(*connection_.get(), IsIPv6())
2134 .WillRepeatedly(Return(false));
Paul Stewartc681fa02012-03-02 19:40:04 -08002135 EXPECT_CALL(*connection_.get(), interface_name())
2136 .WillRepeatedly(ReturnRef(kInterfaceName));
2137 const vector<string> kDNSServers;
2138 EXPECT_CALL(*connection_.get(), dns_servers())
2139 .WillRepeatedly(ReturnRef(kDNSServers));
2140 EXPECT_TRUE(RequestPortalDetection());
2141}
2142
Rebecca Silberstein6862b382014-09-11 08:24:51 -07002143TEST_F(DevicePortalDetectionTest, RequestStartConnectivityTest) {
Rebecca Silbersteinf4365a62014-09-16 11:40:32 -07002144 const string kInterfaceName("int0");
2145 EXPECT_CALL(*connection_.get(), interface_name())
2146 .WillRepeatedly(ReturnRef(kInterfaceName));
2147 EXPECT_CALL(*connection_.get(), IsIPv6())
2148 .WillRepeatedly(Return(false));
2149 const vector<string> kDNSServers;
2150 EXPECT_CALL(*connection_.get(), dns_servers())
2151 .WillRepeatedly(ReturnRef(kDNSServers));
2152
2153 EXPECT_EQ(nullptr, device_->connection_tester_);
2154 EXPECT_TRUE(device_->StartConnectivityTest());
2155 EXPECT_NE(nullptr, device_->connection_tester_);
Rebecca Silberstein6862b382014-09-11 08:24:51 -07002156}
2157
Paul Stewartc681fa02012-03-02 19:40:04 -08002158TEST_F(DevicePortalDetectionTest, NotConnected) {
2159 EXPECT_CALL(*service_.get(), IsConnected())
2160 .WillOnce(Return(false));
2161 SetServiceConnectedState(Service::kStatePortal);
2162 // We don't check for the portal detector to be reset here, because
2163 // it would have been reset as a part of disconnection.
2164}
2165
2166TEST_F(DevicePortalDetectionTest, NotPortal) {
2167 EXPECT_CALL(*service_.get(), IsConnected())
2168 .WillOnce(Return(true));
2169 EXPECT_CALL(*service_.get(), SetState(Service::kStateOnline));
2170 SetServiceConnectedState(Service::kStateOnline);
2171 ExpectPortalDetectorReset();
2172}
2173
2174TEST_F(DevicePortalDetectionTest, NotDefault) {
2175 EXPECT_CALL(*service_.get(), IsConnected())
2176 .WillOnce(Return(true));
2177 EXPECT_CALL(*connection_.get(), is_default())
2178 .WillOnce(Return(false));
2179 EXPECT_CALL(*service_.get(), SetState(Service::kStatePortal));
2180 SetServiceConnectedState(Service::kStatePortal);
2181 ExpectPortalDetectorReset();
2182}
2183
2184TEST_F(DevicePortalDetectionTest, PortalIntervalIsZero) {
2185 EXPECT_CALL(*service_.get(), IsConnected())
2186 .WillOnce(Return(true));
2187 EXPECT_CALL(*connection_.get(), is_default())
2188 .WillOnce(Return(true));
2189 EXPECT_CALL(manager_, GetPortalCheckInterval())
2190 .WillOnce(Return(0));
2191 EXPECT_CALL(*service_.get(), SetState(Service::kStatePortal));
2192 SetServiceConnectedState(Service::kStatePortal);
2193 ExpectPortalDetectorReset();
2194}
2195
2196TEST_F(DevicePortalDetectionTest, RestartPortalDetection) {
2197 EXPECT_CALL(*service_.get(), IsConnected())
2198 .WillOnce(Return(true));
2199 EXPECT_CALL(*connection_.get(), is_default())
2200 .WillOnce(Return(true));
2201 const int kPortalDetectionInterval = 10;
2202 EXPECT_CALL(manager_, GetPortalCheckInterval())
2203 .Times(AtLeast(1))
2204 .WillRepeatedly(Return(kPortalDetectionInterval));
2205 const string kPortalCheckURL("http://portal");
2206 EXPECT_CALL(manager_, GetPortalCheckURL())
2207 .WillOnce(ReturnRef(kPortalCheckURL));
2208 EXPECT_CALL(*portal_detector_, StartAfterDelay(kPortalCheckURL,
2209 kPortalDetectionInterval))
2210 .WillOnce(Return(true));
2211 EXPECT_CALL(*service_.get(), SetState(Service::kStatePortal));
2212 SetServiceConnectedState(Service::kStatePortal);
2213 ExpectPortalDetectorSet();
2214}
2215
Paul Stewartc8860612012-09-28 07:36:21 -07002216TEST_F(DevicePortalDetectionTest, CancelledOnSelectService) {
2217 ExpectPortalDetectorSet();
2218 EXPECT_CALL(*service_.get(), state())
2219 .WillOnce(Return(Service::kStateIdle));
2220 EXPECT_CALL(*service_.get(), SetState(_));
2221 EXPECT_CALL(*service_.get(), SetConnection(_));
Ben Chancc225ef2014-09-30 13:26:51 -07002222 SelectService(nullptr);
Paul Stewartc8860612012-09-28 07:36:21 -07002223 ExpectPortalDetectorReset();
2224}
2225
Peter Qiub9256f32014-05-09 15:27:29 -07002226TEST_F(DevicePortalDetectionTest, PortalDetectionDNSFailure) {
Paul Stewart3b30ca52015-06-16 13:13:10 -07002227 const char* kGoogleDNSServers[] = { "8.8.8.8", "8.8.4.4" };
Peter Qiu6f5618b2014-06-05 15:19:01 -07002228 vector<string> fallback_dns_servers(kGoogleDNSServers, kGoogleDNSServers + 2);
Peter Qiub9256f32014-05-09 15:27:29 -07002229 const string kInterfaceName("int0");
2230 EXPECT_CALL(*connection_.get(), interface_name())
2231 .WillRepeatedly(ReturnRef(kInterfaceName));
Peter Qiub9256f32014-05-09 15:27:29 -07002232
Peter Qiu6f5618b2014-06-05 15:19:01 -07002233 // DNS Failure, start DNS test for fallback DNS servers.
Peter Qiub9256f32014-05-09 15:27:29 -07002234 EXPECT_CALL(*service_.get(), IsConnected())
2235 .WillOnce(Return(true));
Peter Qiu9b83c892014-08-09 23:06:02 -07002236 EXPECT_CALL(*service_.get(),
2237 SetPortalDetectionFailure(kPortalDetectionPhaseDns,
2238 kPortalDetectionStatusFailure));
Peter Qiub9256f32014-05-09 15:27:29 -07002239 EXPECT_CALL(*service_.get(), SetState(Service::kStatePortal));
2240 EXPECT_CALL(*connection_.get(), is_default())
2241 .WillOnce(Return(false));
Peter Qiub25083f2014-08-25 13:22:31 -07002242 EXPECT_CALL(*connection_.get(), IsIPv6())
2243 .WillOnce(Return(false));
Peter Qiu6f5618b2014-06-05 15:19:01 -07002244 EXPECT_CALL(*device_, StartDNSTest(fallback_dns_servers, false, _)).Times(1);
Rebecca Silberstein3d49ea42014-08-21 11:20:50 -07002245 PortalDetectorCallback(
2246 PortalDetector::Result(
2247 ConnectivityTrial::Result(
2248 ConnectivityTrial::kPhaseDNS,
2249 ConnectivityTrial::kStatusFailure),
2250 kPortalAttempts, true));
Alex Vakulenko0951ccb2014-12-10 12:52:31 -08002251 Mock::VerifyAndClearExpectations(device_.get());
Peter Qiub9256f32014-05-09 15:27:29 -07002252
Peter Qiu6f5618b2014-06-05 15:19:01 -07002253 // DNS Timeout, start DNS test for fallback DNS servers.
Peter Qiub9256f32014-05-09 15:27:29 -07002254 EXPECT_CALL(*service_.get(), IsConnected())
2255 .WillOnce(Return(true));
Peter Qiu9b83c892014-08-09 23:06:02 -07002256 EXPECT_CALL(*service_.get(),
2257 SetPortalDetectionFailure(kPortalDetectionPhaseDns,
2258 kPortalDetectionStatusTimeout));
Peter Qiub9256f32014-05-09 15:27:29 -07002259 EXPECT_CALL(*service_.get(), SetState(Service::kStatePortal));
2260 EXPECT_CALL(*connection_.get(), is_default())
2261 .WillOnce(Return(false));
Peter Qiub25083f2014-08-25 13:22:31 -07002262 EXPECT_CALL(*connection_.get(), IsIPv6())
2263 .WillOnce(Return(false));
Peter Qiu6f5618b2014-06-05 15:19:01 -07002264 EXPECT_CALL(*device_, StartDNSTest(fallback_dns_servers, false, _)).Times(1);
Rebecca Silberstein3d49ea42014-08-21 11:20:50 -07002265 PortalDetectorCallback(
2266 PortalDetector::Result(
2267 ConnectivityTrial::Result(
2268 ConnectivityTrial::kPhaseDNS,
2269 ConnectivityTrial::kStatusTimeout),
Peter Qiub9256f32014-05-09 15:27:29 -07002270 kPortalAttempts,
2271 true));
Alex Vakulenko0951ccb2014-12-10 12:52:31 -08002272 Mock::VerifyAndClearExpectations(device_.get());
Peter Qiub9256f32014-05-09 15:27:29 -07002273
Peter Qiud670d032014-06-03 15:04:43 -07002274 // Other Failure, DNS server tester not started.
Peter Qiub9256f32014-05-09 15:27:29 -07002275 EXPECT_CALL(*service_.get(), IsConnected())
2276 .WillOnce(Return(true));
Peter Qiu9b83c892014-08-09 23:06:02 -07002277 EXPECT_CALL(*service_.get(),
2278 SetPortalDetectionFailure(kPortalDetectionPhaseConnection,
2279 kPortalDetectionStatusFailure));
Peter Qiub9256f32014-05-09 15:27:29 -07002280 EXPECT_CALL(*service_.get(), SetState(Service::kStatePortal));
2281 EXPECT_CALL(*connection_.get(), is_default())
2282 .WillOnce(Return(false));
Peter Qiub25083f2014-08-25 13:22:31 -07002283 EXPECT_CALL(*connection_.get(), IsIPv6())
2284 .WillOnce(Return(false));
Peter Qiu6f5618b2014-06-05 15:19:01 -07002285 EXPECT_CALL(*device_, StartDNSTest(_, _, _)).Times(0);
Rebecca Silberstein3d49ea42014-08-21 11:20:50 -07002286 PortalDetectorCallback(
2287 PortalDetector::Result(
2288 ConnectivityTrial::Result(
2289 ConnectivityTrial::kPhaseConnection,
2290 ConnectivityTrial::kStatusFailure),
Peter Qiub9256f32014-05-09 15:27:29 -07002291 kPortalAttempts,
2292 true));
Alex Vakulenko0951ccb2014-12-10 12:52:31 -08002293 Mock::VerifyAndClearExpectations(device_.get());
Peter Qiub9256f32014-05-09 15:27:29 -07002294}
2295
Peter Qiud670d032014-06-03 15:04:43 -07002296TEST_F(DevicePortalDetectionTest, FallbackDNSResultCallback) {
Peter Qiua89154b2014-05-23 15:45:42 -07002297 scoped_refptr<MockIPConfig> ipconfig =
2298 new MockIPConfig(control_interface(), kDeviceName);
2299 device_->set_ipconfig(ipconfig);
2300
2301 // Fallback DNS test failed.
2302 EXPECT_CALL(*connection_.get(), UpdateDNSServers(_)).Times(0);
2303 EXPECT_CALL(*ipconfig, UpdateDNSServers(_)).Times(0);
Peter Qiu6f5618b2014-06-05 15:19:01 -07002304 EXPECT_CALL(*device_, StartDNSTest(_, _, _)).Times(0);
Peter Qiub9256f32014-05-09 15:27:29 -07002305 EXPECT_CALL(metrics_,
Peter Qiuf18e7712014-05-20 09:59:46 -07002306 NotifyFallbackDNSTestResult(_, Metrics::kFallbackDNSTestResultFailure))
2307 .Times(1);
Peter Qiud670d032014-06-03 15:04:43 -07002308 InvokeFallbackDNSResultCallback(DNSServerTester::kStatusFailure);
Peter Qiua89154b2014-05-23 15:45:42 -07002309 Mock::VerifyAndClearExpectations(connection_.get());
Alex Vakulenko0951ccb2014-12-10 12:52:31 -08002310 Mock::VerifyAndClearExpectations(ipconfig.get());
Peter Qiub9256f32014-05-09 15:27:29 -07002311 Mock::VerifyAndClearExpectations(&metrics_);
2312
Peter Qiua89154b2014-05-23 15:45:42 -07002313 // Fallback DNS test succeed with auto fallback disabled.
2314 EXPECT_CALL(*service_.get(), is_dns_auto_fallback_allowed())
2315 .WillOnce(Return(false));
2316 EXPECT_CALL(*connection_.get(), UpdateDNSServers(_)).Times(0);
2317 EXPECT_CALL(*ipconfig, UpdateDNSServers(_)).Times(0);
2318 EXPECT_CALL(*service_.get(), NotifyIPConfigChanges()).Times(0);
Peter Qiu6f5618b2014-06-05 15:19:01 -07002319 EXPECT_CALL(*device_, StartDNSTest(_, _, _)).Times(0);
Peter Qiub9256f32014-05-09 15:27:29 -07002320 EXPECT_CALL(metrics_,
Peter Qiuf18e7712014-05-20 09:59:46 -07002321 NotifyFallbackDNSTestResult(_, Metrics::kFallbackDNSTestResultSuccess))
2322 .Times(1);
Peter Qiud670d032014-06-03 15:04:43 -07002323 InvokeFallbackDNSResultCallback(DNSServerTester::kStatusSuccess);
Peter Qiua89154b2014-05-23 15:45:42 -07002324 Mock::VerifyAndClearExpectations(service_.get());
2325 Mock::VerifyAndClearExpectations(connection_.get());
Alex Vakulenko0951ccb2014-12-10 12:52:31 -08002326 Mock::VerifyAndClearExpectations(ipconfig.get());
Peter Qiua89154b2014-05-23 15:45:42 -07002327 Mock::VerifyAndClearExpectations(&metrics_);
2328
2329 // Fallback DNS test succeed with auto fallback enabled.
2330 EXPECT_CALL(*service_.get(), is_dns_auto_fallback_allowed())
2331 .WillOnce(Return(true));
2332 EXPECT_CALL(*service_.get(), IsPortalDetectionDisabled())
2333 .WillRepeatedly(Return(false));
2334 EXPECT_CALL(*service_.get(), IsPortalDetectionAuto())
2335 .WillRepeatedly(Return(true));
2336 EXPECT_CALL(manager_, IsPortalDetectionEnabled(device_->technology()))
2337 .WillRepeatedly(Return(true));
2338 EXPECT_CALL(*service_.get(), HasProxyConfig())
2339 .WillRepeatedly(Return(false));
2340 const string kPortalCheckURL("http://portal");
2341 EXPECT_CALL(manager_, GetPortalCheckURL())
2342 .WillOnce(ReturnRef(kPortalCheckURL));
2343 const string kInterfaceName("int0");
Peter Qiuf3a8f902014-08-20 10:05:42 -07002344 EXPECT_CALL(*connection_.get(), IsIPv6())
2345 .WillRepeatedly(Return(false));
Peter Qiua89154b2014-05-23 15:45:42 -07002346 EXPECT_CALL(*connection_.get(), interface_name())
2347 .WillRepeatedly(ReturnRef(kInterfaceName));
2348 const vector<string> kDNSServers;
2349 EXPECT_CALL(*connection_.get(), dns_servers())
2350 .WillRepeatedly(ReturnRef(kDNSServers));
2351
2352 EXPECT_CALL(*ipconfig, UpdateDNSServers(_)).Times(1);
2353 EXPECT_CALL(*connection_.get(), UpdateDNSServers(_)).Times(1);
2354 EXPECT_CALL(*service_.get(), NotifyIPConfigChanges()).Times(1);
Peter Qiu6f5618b2014-06-05 15:19:01 -07002355 EXPECT_CALL(*device_, StartDNSTest(_, true, _)).Times(1);
Peter Qiua89154b2014-05-23 15:45:42 -07002356 EXPECT_CALL(metrics_,
2357 NotifyFallbackDNSTestResult(_, Metrics::kFallbackDNSTestResultSuccess))
2358 .Times(1);
Peter Qiud670d032014-06-03 15:04:43 -07002359 InvokeFallbackDNSResultCallback(DNSServerTester::kStatusSuccess);
Peter Qiua89154b2014-05-23 15:45:42 -07002360 Mock::VerifyAndClearExpectations(service_.get());
2361 Mock::VerifyAndClearExpectations(connection_.get());
Alex Vakulenko0951ccb2014-12-10 12:52:31 -08002362 Mock::VerifyAndClearExpectations(ipconfig.get());
Peter Qiua89154b2014-05-23 15:45:42 -07002363 Mock::VerifyAndClearExpectations(&metrics_);
Peter Qiub9256f32014-05-09 15:27:29 -07002364}
2365
Peter Qiu6f5618b2014-06-05 15:19:01 -07002366TEST_F(DevicePortalDetectionTest, ConfigDNSResultCallback) {
2367 scoped_refptr<MockIPConfig> ipconfig =
2368 new MockIPConfig(control_interface(), kDeviceName);
2369 device_->set_ipconfig(ipconfig);
2370
2371 // DNS test failed for configured DNS servers.
2372 EXPECT_CALL(*connection_.get(), UpdateDNSServers(_)).Times(0);
2373 EXPECT_CALL(*ipconfig, UpdateDNSServers(_)).Times(0);
2374 InvokeConfigDNSResultCallback(DNSServerTester::kStatusFailure);
2375 Mock::VerifyAndClearExpectations(connection_.get());
Alex Vakulenko0951ccb2014-12-10 12:52:31 -08002376 Mock::VerifyAndClearExpectations(ipconfig.get());
Peter Qiu6f5618b2014-06-05 15:19:01 -07002377
2378 // DNS test succeed for configured DNS servers.
2379 EXPECT_CALL(*service_.get(), IsPortalDetectionDisabled())
2380 .WillRepeatedly(Return(false));
2381 EXPECT_CALL(*service_.get(), IsPortalDetectionAuto())
2382 .WillRepeatedly(Return(true));
2383 EXPECT_CALL(manager_, IsPortalDetectionEnabled(device_->technology()))
2384 .WillRepeatedly(Return(true));
2385 EXPECT_CALL(*service_.get(), HasProxyConfig())
2386 .WillRepeatedly(Return(false));
2387 const string kPortalCheckURL("http://portal");
2388 EXPECT_CALL(manager_, GetPortalCheckURL())
2389 .WillOnce(ReturnRef(kPortalCheckURL));
2390 const string kInterfaceName("int0");
Peter Qiuf3a8f902014-08-20 10:05:42 -07002391 EXPECT_CALL(*connection_.get(), IsIPv6())
2392 .WillRepeatedly(Return(false));
Peter Qiu6f5618b2014-06-05 15:19:01 -07002393 EXPECT_CALL(*connection_.get(), interface_name())
2394 .WillRepeatedly(ReturnRef(kInterfaceName));
2395 const vector<string> kDNSServers;
2396 EXPECT_CALL(*connection_.get(), dns_servers())
2397 .WillRepeatedly(ReturnRef(kDNSServers));
2398 EXPECT_CALL(*connection_.get(), UpdateDNSServers(_)).Times(1);
2399 EXPECT_CALL(*ipconfig, UpdateDNSServers(_)).Times(1);
2400 EXPECT_CALL(*service_.get(), NotifyIPConfigChanges()).Times(1);
2401 InvokeConfigDNSResultCallback(DNSServerTester::kStatusSuccess);
2402 Mock::VerifyAndClearExpectations(service_.get());
2403 Mock::VerifyAndClearExpectations(connection_.get());
Alex Vakulenko0951ccb2014-12-10 12:52:31 -08002404 Mock::VerifyAndClearExpectations(ipconfig.get());
Peter Qiu6f5618b2014-06-05 15:19:01 -07002405}
2406
Paul Stewarte8303eb2014-10-08 22:51:14 -07002407TEST_F(DevicePortalDetectionTest, DestroyConnection) {
2408 scoped_refptr<MockConnection> connection =
2409 new NiceMock<MockConnection>(&device_info_);
2410 // This test holds a single reference to the mock connection.
2411 EXPECT_TRUE(connection->HasOneRef());
2412
2413 SetConnection(connection);
2414
2415 EXPECT_CALL(*service_.get(), IsPortalDetectionDisabled())
2416 .WillOnce(Return(false));
2417 EXPECT_CALL(*service_.get(), IsConnected())
2418 .WillRepeatedly(Return(true));
2419 EXPECT_CALL(*service_.get(), HasProxyConfig())
2420 .WillOnce(Return(false));
2421 EXPECT_CALL(*service_.get(), IsPortalDetectionAuto())
2422 .WillOnce(Return(true));
2423 EXPECT_CALL(manager_, IsPortalDetectionEnabled(device_->technology()))
2424 .WillOnce(Return(true));
2425 const string portal_url(ConnectivityTrial::kDefaultURL);
2426 EXPECT_CALL(manager_, GetPortalCheckURL())
2427 .WillRepeatedly(ReturnRef(portal_url));
2428 const string kInterfaceName("int0");
2429 EXPECT_CALL(*connection.get(), interface_name())
2430 .WillRepeatedly(ReturnRef(kInterfaceName));
2431 EXPECT_CALL(*connection.get(), IsIPv6())
2432 .WillRepeatedly(Return(false));
2433 const vector<string> kDNSServers;
2434 EXPECT_CALL(*connection.get(), dns_servers())
2435 .WillRepeatedly(ReturnRef(kDNSServers));
2436
2437 EXPECT_TRUE(device_->StartConnectivityTest());
2438 EXPECT_TRUE(StartPortalDetection());
2439
2440 // Ensure that the DestroyConnection method removes all connection references
2441 // except the one left in this scope.
2442 EXPECT_CALL(*service_.get(), SetConnection(IsNullRefPtr()));
2443 DestroyConnection();
2444 EXPECT_TRUE(connection->HasOneRef());
2445}
2446
Paul Stewart6ff27f52012-07-11 06:51:41 -07002447class DeviceByteCountTest : public DeviceTest {
2448 public:
2449 DeviceByteCountTest()
2450 : manager_(control_interface(),
2451 dispatcher(),
2452 metrics(),
2453 glib()),
2454 rx_byte_count_(0),
2455 tx_byte_count_(0),
2456 rx_stored_byte_count_(0),
2457 tx_stored_byte_count_(0) {}
2458 virtual ~DeviceByteCountTest() {}
2459
2460 virtual void SetUp() {
2461 DeviceTest::SetUp();
2462 EXPECT_CALL(manager_, device_info()).WillRepeatedly(Return(&device_info_));
2463 EXPECT_CALL(device_info_, GetByteCounts(kDeviceInterfaceIndex, _, _))
2464 .WillRepeatedly(Invoke(this, &DeviceByteCountTest::ReturnByteCounts));
2465 const string id = device_->GetStorageIdentifier();
2466 EXPECT_CALL(storage_, ContainsGroup(id)).WillRepeatedly(Return(true));
2467 EXPECT_CALL(storage_, GetUint64(id, Device::kStorageReceiveByteCount, _))
2468 .WillRepeatedly(
2469 Invoke(this, &DeviceByteCountTest::GetStoredReceiveCount));
2470 EXPECT_CALL(storage_, GetUint64(id, Device::kStorageTransmitByteCount, _))
2471 .WillRepeatedly(
2472 Invoke(this, &DeviceByteCountTest::GetStoredTransmitCount));
2473 }
2474
Paul Stewart3b30ca52015-06-16 13:13:10 -07002475 bool ReturnByteCounts(int interface_index, uint64_t* rx, uint64_t* tx) {
Paul Stewart6ff27f52012-07-11 06:51:41 -07002476 *rx = rx_byte_count_;
2477 *tx = tx_byte_count_;
2478 return true;
2479 }
2480
2481 bool ExpectByteCounts(DeviceRefPtr device,
Ben Chan7fab8972014-08-10 17:14:46 -07002482 int64_t expected_rx, int64_t expected_tx) {
2483 int64_t actual_rx = device->GetReceiveByteCount();
2484 int64_t actual_tx = device->GetTransmitByteCount();
Paul Stewart6ff27f52012-07-11 06:51:41 -07002485 EXPECT_EQ(expected_rx, actual_rx);
2486 EXPECT_EQ(expected_tx, actual_tx);
2487 return expected_rx == actual_rx && expected_tx == actual_tx;
2488 }
2489
2490 void ExpectSavedCounts(DeviceRefPtr device,
Ben Chan7fab8972014-08-10 17:14:46 -07002491 int64_t expected_rx, int64_t expected_tx) {
Paul Stewart6ff27f52012-07-11 06:51:41 -07002492 EXPECT_CALL(storage_,
2493 SetUint64(_, Device::kStorageReceiveByteCount, expected_rx))
2494 .WillOnce(Return(true));
2495 EXPECT_CALL(storage_,
2496 SetUint64(_, Device::kStorageTransmitByteCount, expected_tx))
2497 .WillOnce(Return(true));
2498 EXPECT_TRUE(device->Save(&storage_));
2499 }
2500
2501
Paul Stewart3b30ca52015-06-16 13:13:10 -07002502 bool GetStoredReceiveCount(const string& group, const string& key,
2503 uint64_t* value) {
Paul Stewart6ff27f52012-07-11 06:51:41 -07002504 if (!rx_stored_byte_count_) {
2505 return false;
2506 }
2507 *value = rx_stored_byte_count_;
2508 return true;
2509 }
2510
Paul Stewart3b30ca52015-06-16 13:13:10 -07002511 bool GetStoredTransmitCount(const string& group, const string& key,
2512 uint64_t* value) {
Paul Stewart6ff27f52012-07-11 06:51:41 -07002513 if (!tx_stored_byte_count_) {
2514 return false;
2515 }
2516 *value = tx_stored_byte_count_;
2517 return true;
2518 }
2519
2520 protected:
2521 NiceMock<MockManager> manager_;
2522 NiceMock<MockStore> storage_;
Ben Chan7fab8972014-08-10 17:14:46 -07002523 uint64_t rx_byte_count_;
2524 uint64_t tx_byte_count_;
2525 uint64_t rx_stored_byte_count_;
2526 uint64_t tx_stored_byte_count_;
Paul Stewart6ff27f52012-07-11 06:51:41 -07002527};
2528
2529
2530TEST_F(DeviceByteCountTest, GetByteCounts) {
2531 // On Device initialization, byte counts should be zero, independent of
2532 // the byte counts reported by the interface.
2533 rx_byte_count_ = 123;
2534 tx_byte_count_ = 456;
2535 DeviceRefPtr device(new TestDevice(control_interface(),
2536 dispatcher(),
Ben Chancc225ef2014-09-30 13:26:51 -07002537 nullptr,
Paul Stewart6ff27f52012-07-11 06:51:41 -07002538 &manager_,
2539 kDeviceName,
2540 kDeviceAddress,
2541 kDeviceInterfaceIndex,
2542 Technology::kUnknown));
2543 EXPECT_TRUE(ExpectByteCounts(device, 0, 0));
2544
2545 // Device should report any increase in the byte counts reported in the
2546 // interface.
Ben Chan7fab8972014-08-10 17:14:46 -07002547 const int64_t delta_rx_count = 789;
2548 const int64_t delta_tx_count = 12;
Paul Stewart6ff27f52012-07-11 06:51:41 -07002549 rx_byte_count_ += delta_rx_count;
2550 tx_byte_count_ += delta_tx_count;
2551 EXPECT_TRUE(ExpectByteCounts(device, delta_rx_count, delta_tx_count));
2552
2553 // Expect the correct values to be saved to the profile.
2554 ExpectSavedCounts(device, delta_rx_count, delta_tx_count);
2555
2556 // If Device is loaded from a profile that does not contain stored byte
2557 // counts, the byte counts reported should remain unchanged.
2558 EXPECT_TRUE(device->Load(&storage_));
2559 EXPECT_TRUE(ExpectByteCounts(device, delta_rx_count, delta_tx_count));
2560
2561 // If Device is loaded from a profile that contains stored byte
2562 // counts, the byte counts reported should now reflect the stored values.
2563 rx_stored_byte_count_ = 345;
2564 tx_stored_byte_count_ = 678;
2565 EXPECT_TRUE(device->Load(&storage_));
2566 EXPECT_TRUE(ExpectByteCounts(
2567 device, rx_stored_byte_count_, tx_stored_byte_count_));
2568
2569 // Increases to the interface receive count should be reflected as offsets
2570 // to the stored byte counts.
2571 rx_byte_count_ += delta_rx_count;
2572 tx_byte_count_ += delta_tx_count;
2573 EXPECT_TRUE(ExpectByteCounts(device,
2574 rx_stored_byte_count_ + delta_rx_count,
2575 tx_stored_byte_count_ + delta_tx_count));
2576
2577 // Expect the correct values to be saved to the profile.
2578 ExpectSavedCounts(device,
2579 rx_stored_byte_count_ + delta_rx_count,
2580 tx_stored_byte_count_ + delta_tx_count);
2581
2582 // Expect that after resetting byte counts, read-back values return to zero,
2583 // and that the device requests this information to be persisted.
2584 EXPECT_CALL(manager_, UpdateDevice(device));
2585 device->ResetByteCounters();
2586 EXPECT_TRUE(ExpectByteCounts(device, 0, 0));
2587}
2588
Darin Petkovafa6fc42011-06-21 16:21:08 -07002589} // namespace shill