blob: fada965f62be0cd5e92826364427603ad5d8dd9c [file] [log] [blame]
Thieu Le3426c8f2012-01-11 17:35:11 -08001// Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
Chris Masone9be4a9d2011-05-16 15:44:09 -07002// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
Darin Petkov633ac6f2011-07-08 13:56:13 -07004
Chris Masone2aa97072011-08-09 17:35:08 -07005#include "shill/device_info.h"
6
Ben Chancd477322014-10-17 14:19:30 -07007#include <memory>
8
Chris Masone9be4a9d2011-05-16 15:44:09 -07009#include <glib.h>
Darin Petkove6193c02011-08-11 12:42:40 -070010#include <linux/if.h>
Paul Stewartca876ee2012-04-21 08:55:58 -070011#include <linux/if_tun.h>
Darin Petkov633ac6f2011-07-08 13:56:13 -070012#include <linux/netlink.h> // Needs typedefs from sys/socket.h.
13#include <linux/rtnetlink.h>
Gary Morain41780232012-07-31 15:08:31 -070014#include <linux/sockios.h>
Paul Stewartca876ee2012-04-21 08:55:58 -070015#include <net/if_arp.h>
Wade Guthrie7347bf22013-04-30 11:21:51 -070016#include <sys/socket.h>
Chris Masone9be4a9d2011-05-16 15:44:09 -070017
Paul Stewart2ddf2c62013-04-16 09:47:34 -070018#include <base/bind.h>
Ben Chan11c213f2014-09-05 08:21:06 -070019#include <base/files/file_util.h>
Paul Stewart5ad16062013-02-21 18:10:48 -080020#include <base/files/scoped_temp_dir.h>
Chris Masone9be4a9d2011-05-16 15:44:09 -070021#include <base/memory/ref_counted.h>
Ben Chana0ddf462014-02-06 11:32:42 -080022#include <base/message_loop/message_loop.h>
Eric Shienbrood3e20a232012-02-16 11:35:56 -050023#include <base/stl_util.h>
Ben Chana0ddf462014-02-06 11:32:42 -080024#include <base/strings/string_number_conversions.h>
Chris Masone9be4a9d2011-05-16 15:44:09 -070025#include <gmock/gmock.h>
Ben Chan5086b972013-01-15 21:51:38 -080026#include <gtest/gtest.h>
Chris Masone9be4a9d2011-05-16 15:44:09 -070027
Christopher Wileyb691efd2012-08-09 13:51:51 -070028#include "shill/logging.h"
Paul Stewartb50f0b92011-05-16 16:31:42 -070029#include "shill/manager.h"
Chris Masone46eaaf52011-05-24 13:08:30 -070030#include "shill/mock_control.h"
Ben Chan5086b972013-01-15 21:51:38 -080031#include "shill/mock_device.h"
Darin Petkovafa6fc42011-06-21 16:21:08 -070032#include "shill/mock_glib.h"
Paul Stewart2ddf2c62013-04-16 09:47:34 -070033#include "shill/mock_log.h"
Chris Masone2ae797d2011-08-23 20:41:00 -070034#include "shill/mock_manager.h"
Thieu Le3426c8f2012-01-11 17:35:11 -080035#include "shill/mock_metrics.h"
Paul Stewart8c116a92012-05-02 18:30:03 -070036#include "shill/mock_modem_info.h"
37#include "shill/mock_routing_table.h"
Paul Stewart8c116a92012-05-02 18:30:03 -070038#include "shill/mock_vpn_provider.h"
Peter Qiu8d6b5972014-10-28 15:33:34 -070039#include "shill/net/ip_address.h"
Peter Qiu02e3dc32014-10-31 10:15:00 -070040#include "shill/net/mock_netlink_manager.h"
Peter Qiu8d6b5972014-10-28 15:33:34 -070041#include "shill/net/mock_rtnl_handler.h"
42#include "shill/net/mock_sockets.h"
43#include "shill/net/mock_time.h"
Peter Qiu02e3dc32014-10-31 10:15:00 -070044#include "shill/net/netlink_attribute.h"
45#include "shill/net/nl80211_message.h"
Peter Qiu8d6b5972014-10-28 15:33:34 -070046#include "shill/net/rtnl_message.h"
Ben Chanc3d707d2014-10-31 08:56:05 -070047#include "shill/wimax/mock_wimax_provider.h"
48#include "shill/wimax/wimax.h"
Chris Masone9be4a9d2011-05-16 15:44:09 -070049
Eric Shienbrood3e20a232012-02-16 11:35:56 -050050using base::Callback;
Albert Chaulk0e1cdea2013-02-27 15:32:55 -080051using base::FilePath;
Darin Petkove6193c02011-08-11 12:42:40 -070052using std::map;
Ben Chan5086b972013-01-15 21:51:38 -080053using std::set;
Darin Petkov633ac6f2011-07-08 13:56:13 -070054using std::string;
Ben Chancd477322014-10-17 14:19:30 -070055using std::unique_ptr;
Paul Stewart9a908082011-08-31 12:18:48 -070056using std::vector;
Darin Petkov633ac6f2011-07-08 13:56:13 -070057using testing::_;
Paul Stewart2ddf2c62013-04-16 09:47:34 -070058using testing::AnyNumber;
Ben Chan5086b972013-01-15 21:51:38 -080059using testing::ContainerEq;
Gary Morain41780232012-07-31 15:08:31 -070060using testing::DoAll;
61using testing::ElementsAreArray;
Paul Stewart2ddf2c62013-04-16 09:47:34 -070062using testing::HasSubstr;
Paul Stewart8c116a92012-05-02 18:30:03 -070063using testing::Mock;
Gary Morain41780232012-07-31 15:08:31 -070064using testing::NotNull;
Darin Petkov633ac6f2011-07-08 13:56:13 -070065using testing::Return;
Peter Qiu98551702014-07-28 13:28:53 -070066using testing::SetArgPointee;
Paul Stewart9a908082011-08-31 12:18:48 -070067using testing::StrictMock;
Darin Petkov633ac6f2011-07-08 13:56:13 -070068using testing::Test;
69
Chris Masone9be4a9d2011-05-16 15:44:09 -070070namespace shill {
Darin Petkov633ac6f2011-07-08 13:56:13 -070071
Paul Stewart050cfc02012-07-06 20:38:54 -070072class TestEventDispatcherForDeviceInfo : public EventDispatcher {
Darin Petkov633ac6f2011-07-08 13:56:13 -070073 public:
Paul Stewart26b327e2011-10-19 11:38:09 -070074 virtual IOHandler *CreateInputHandler(
mukesh agrawal1830fa12011-09-26 14:31:40 -070075 int /*fd*/,
Paul Stewart5f06a0e2012-12-20 11:11:33 -080076 const IOHandler::InputCallback &/*input_callback*/,
77 const IOHandler::ErrorCallback &/*error_callback*/) {
Ben Chancc225ef2014-09-30 13:26:51 -070078 return nullptr;
Darin Petkov633ac6f2011-07-08 13:56:13 -070079 }
Paul Stewart050cfc02012-07-06 20:38:54 -070080 MOCK_METHOD2(PostDelayedTask, bool(const base::Closure &task,
Ben Chan7fab8972014-08-10 17:14:46 -070081 int64_t delay_ms));
Darin Petkov633ac6f2011-07-08 13:56:13 -070082};
Chris Masone9be4a9d2011-05-16 15:44:09 -070083
84class DeviceInfoTest : public Test {
85 public:
86 DeviceInfoTest()
Thieu Le6c1e3bb2013-02-06 15:20:35 -080087 : metrics_(&dispatcher_),
88 manager_(&control_interface_, &dispatcher_, &metrics_, &glib_),
Thieu Le3426c8f2012-01-11 17:35:11 -080089 device_info_(&control_interface_, &dispatcher_, &metrics_, &manager_) {
Chris Masone9be4a9d2011-05-16 15:44:09 -070090 }
Paul Stewartca876ee2012-04-21 08:55:58 -070091 virtual ~DeviceInfoTest() {}
Darin Petkov633ac6f2011-07-08 13:56:13 -070092
Paul Stewart9a908082011-08-31 12:18:48 -070093 virtual void SetUp() {
94 device_info_.rtnl_handler_ = &rtnl_handler_;
Paul Stewart8c116a92012-05-02 18:30:03 -070095 device_info_.routing_table_ = &routing_table_;
Paul Stewart2ddf2c62013-04-16 09:47:34 -070096 device_info_.netlink_manager_ = &netlink_manager_;
Peter Qiu98551702014-07-28 13:28:53 -070097 device_info_.time_ = &time_;
Paul Stewartd4f26482014-04-25 19:12:03 -070098 manager_.set_mock_device_info(&device_info_);
Paul Stewart9a908082011-08-31 12:18:48 -070099 }
100
Paul Stewart8c116a92012-05-02 18:30:03 -0700101 IPAddress CreateInterfaceAddress() {
102 // Create an IP address entry (as if left-over from a previous connection
103 // manager).
104 IPAddress address(IPAddress::kFamilyIPv4);
105 EXPECT_TRUE(address.SetAddressFromString(kTestIPAddress0));
106 address.set_prefix(kTestIPAddressPrefix0);
107 vector<DeviceInfo::AddressData> &addresses =
108 device_info_.infos_[kTestDeviceIndex].ip_addresses;
109 addresses.push_back(DeviceInfo::AddressData(address, 0, RT_SCOPE_UNIVERSE));
110 EXPECT_EQ(1, addresses.size());
111 return address;
112 }
113
114 DeviceRefPtr CreateDevice(const std::string &link_name,
115 const std::string &address,
116 int interface_index,
117 Technology::Identifier technology) {
118 return device_info_.CreateDevice(link_name, address, interface_index,
119 technology);
120 }
121
Paul Stewart050cfc02012-07-06 20:38:54 -0700122 virtual std::set<int> &GetDelayedDevices() {
123 return device_info_.delayed_devices_;
124 }
125
Paul Stewart1ac4e842012-07-10 12:58:12 -0700126 int GetDelayedDeviceCreationMilliseconds() {
Paul Stewart050cfc02012-07-06 20:38:54 -0700127 return DeviceInfo::kDelayedDeviceCreationSeconds * 1000;
128 }
Paul Stewart8c116a92012-05-02 18:30:03 -0700129
Gary Morain41780232012-07-31 15:08:31 -0700130 void SetSockets() {
131 mock_sockets_ = new MockSockets();
132 device_info_.set_sockets(mock_sockets_);
133 }
134
Darin Petkovc3505a52013-03-18 15:13:29 +0100135 // Takes ownership of |provider|.
136 void SetVPNProvider(VPNProvider *provider) {
137 manager_.vpn_provider_.reset(provider);
Paul Stewartb87d22b2013-07-29 11:11:37 -0700138 manager_.UpdateProviderMapping();
Darin Petkovc3505a52013-03-18 15:13:29 +0100139 }
140
Paul Stewarta3c56f92011-05-26 07:08:52 -0700141 protected:
Chris Masoneb2e326b2011-07-12 13:28:51 -0700142 static const int kTestDeviceIndex;
Darin Petkov633ac6f2011-07-08 13:56:13 -0700143 static const char kTestDeviceName[];
Han Shenfc349252012-08-30 11:36:04 -0700144 static const uint8_t kTestMACAddress[];
Paul Stewart9a908082011-08-31 12:18:48 -0700145 static const char kTestIPAddress0[];
146 static const int kTestIPAddressPrefix0;
147 static const char kTestIPAddress1[];
148 static const int kTestIPAddressPrefix1;
149 static const char kTestIPAddress2[];
150 static const char kTestIPAddress3[];
151 static const char kTestIPAddress4[];
Paul Stewart05a42c22012-08-02 16:47:21 -0700152 static const char kTestIPAddress5[];
Paul Stewarta0db0ff2013-12-09 09:48:47 -0800153 static const char kTestIPAddress6[];
Paul Stewart1ac4e842012-07-10 12:58:12 -0700154 static const int kReceiveByteCount;
155 static const int kTransmitByteCount;
Darin Petkov633ac6f2011-07-08 13:56:13 -0700156
Paul Stewart9a908082011-08-31 12:18:48 -0700157 RTNLMessage *BuildLinkMessage(RTNLMessage::Mode mode);
Paul Stewarte81eb702012-04-11 15:04:53 -0700158 RTNLMessage *BuildLinkMessageWithInterfaceName(RTNLMessage::Mode mode,
159 const string &interface_name);
Paul Stewart9a908082011-08-31 12:18:48 -0700160 RTNLMessage *BuildAddressMessage(RTNLMessage::Mode mode,
161 const IPAddress &address,
162 unsigned char flags,
163 unsigned char scope);
Peter Qiu98551702014-07-28 13:28:53 -0700164 RTNLMessage *BuildRdnssMessage(RTNLMessage::Mode mode,
Ben Chan7fab8972014-08-10 17:14:46 -0700165 uint32_t lifetime,
Peter Qiu98551702014-07-28 13:28:53 -0700166 const vector<IPAddress> &dns_servers);
Chris Masone2aa97072011-08-09 17:35:08 -0700167 void SendMessageToDeviceInfo(const RTNLMessage &message);
Darin Petkov633ac6f2011-07-08 13:56:13 -0700168
Darin Petkovafa6fc42011-06-21 16:21:08 -0700169 MockGLib glib_;
Chris Masone46eaaf52011-05-24 13:08:30 -0700170 MockControl control_interface_;
Thieu Le3426c8f2012-01-11 17:35:11 -0800171 MockMetrics metrics_;
Paul Stewart9a908082011-08-31 12:18:48 -0700172 StrictMock<MockManager> manager_;
Chris Masone9be4a9d2011-05-16 15:44:09 -0700173 DeviceInfo device_info_;
Paul Stewart050cfc02012-07-06 20:38:54 -0700174 TestEventDispatcherForDeviceInfo dispatcher_;
Paul Stewart8c116a92012-05-02 18:30:03 -0700175 MockRoutingTable routing_table_;
Paul Stewart2ddf2c62013-04-16 09:47:34 -0700176 MockNetlinkManager netlink_manager_;
Paul Stewart9a908082011-08-31 12:18:48 -0700177 StrictMock<MockRTNLHandler> rtnl_handler_;
Gary Morain41780232012-07-31 15:08:31 -0700178 MockSockets *mock_sockets_; // Owned by DeviceInfo.
Peter Qiu98551702014-07-28 13:28:53 -0700179 MockTime time_;
Chris Masone9be4a9d2011-05-16 15:44:09 -0700180};
181
Chris Masoneb2e326b2011-07-12 13:28:51 -0700182const int DeviceInfoTest::kTestDeviceIndex = 123456;
Darin Petkov633ac6f2011-07-08 13:56:13 -0700183const char DeviceInfoTest::kTestDeviceName[] = "test-device";
Han Shenfc349252012-08-30 11:36:04 -0700184const uint8_t DeviceInfoTest::kTestMACAddress[] = {
Wade Guthrie7347bf22013-04-30 11:21:51 -0700185 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff };
Paul Stewart9a908082011-08-31 12:18:48 -0700186const char DeviceInfoTest::kTestIPAddress0[] = "192.168.1.1";
187const int DeviceInfoTest::kTestIPAddressPrefix0 = 24;
188const char DeviceInfoTest::kTestIPAddress1[] = "fe80::1aa9:5ff:abcd:1234";
189const int DeviceInfoTest::kTestIPAddressPrefix1 = 64;
190const char DeviceInfoTest::kTestIPAddress2[] = "fe80::1aa9:5ff:abcd:1235";
191const char DeviceInfoTest::kTestIPAddress3[] = "fe80::1aa9:5ff:abcd:1236";
192const char DeviceInfoTest::kTestIPAddress4[] = "fe80::1aa9:5ff:abcd:1237";
Paul Stewart05a42c22012-08-02 16:47:21 -0700193const char DeviceInfoTest::kTestIPAddress5[] = "192.168.1.2";
Paul Stewarta0db0ff2013-12-09 09:48:47 -0800194const char DeviceInfoTest::kTestIPAddress6[] = "192.168.2.2";
Paul Stewart1ac4e842012-07-10 12:58:12 -0700195const int DeviceInfoTest::kReceiveByteCount = 1234;
196const int DeviceInfoTest::kTransmitByteCount = 5678;
Chris Masone9be4a9d2011-05-16 15:44:09 -0700197
Paul Stewarte81eb702012-04-11 15:04:53 -0700198RTNLMessage *DeviceInfoTest::BuildLinkMessageWithInterfaceName(
199 RTNLMessage::Mode mode, const string &interface_name) {
Paul Stewart9a908082011-08-31 12:18:48 -0700200 RTNLMessage *message = new RTNLMessage(
201 RTNLMessage::kTypeLink,
202 mode,
203 0,
204 0,
205 0,
206 kTestDeviceIndex,
Paul Stewart7355ce12011-09-02 10:47:01 -0700207 IPAddress::kFamilyIPv4);
Ben Chan7fab8972014-08-10 17:14:46 -0700208 message->SetAttribute(static_cast<uint16_t>(IFLA_IFNAME),
Paul Stewarte81eb702012-04-11 15:04:53 -0700209 ByteString(interface_name, true));
Paul Stewart9a908082011-08-31 12:18:48 -0700210 ByteString test_address(kTestMACAddress, sizeof(kTestMACAddress));
Chris Masone626719f2011-08-18 16:58:48 -0700211 message->SetAttribute(IFLA_ADDRESS, test_address);
Chris Masone2aa97072011-08-09 17:35:08 -0700212 return message;
Darin Petkov633ac6f2011-07-08 13:56:13 -0700213}
214
Paul Stewarte81eb702012-04-11 15:04:53 -0700215RTNLMessage *DeviceInfoTest::BuildLinkMessage(RTNLMessage::Mode mode) {
216 return BuildLinkMessageWithInterfaceName(mode, kTestDeviceName);
217}
218
Paul Stewart9a908082011-08-31 12:18:48 -0700219RTNLMessage *DeviceInfoTest::BuildAddressMessage(RTNLMessage::Mode mode,
220 const IPAddress &address,
221 unsigned char flags,
222 unsigned char scope) {
223 RTNLMessage *message = new RTNLMessage(
224 RTNLMessage::kTypeAddress,
225 mode,
226 0,
227 0,
228 0,
229 kTestDeviceIndex,
230 address.family());
231 message->SetAttribute(IFA_ADDRESS, address.address());
232 message->set_address_status(
233 RTNLMessage::AddressStatus(address.prefix(), flags, scope));
234 return message;
235}
236
Peter Qiu98551702014-07-28 13:28:53 -0700237RTNLMessage *DeviceInfoTest::BuildRdnssMessage(RTNLMessage::Mode mode,
Ben Chan7fab8972014-08-10 17:14:46 -0700238 uint32_t lifetime, const vector<IPAddress> &dns_servers) {
Peter Qiu98551702014-07-28 13:28:53 -0700239 RTNLMessage *message = new RTNLMessage(
240 RTNLMessage::kTypeRdnss,
241 mode,
242 0,
243 0,
244 0,
245 kTestDeviceIndex,
246 IPAddress::kFamilyIPv6);
247 message->set_rdnss_option(
248 RTNLMessage::RdnssOption(lifetime, dns_servers));
249 return message;
250}
251
Chris Masone2aa97072011-08-09 17:35:08 -0700252void DeviceInfoTest::SendMessageToDeviceInfo(const RTNLMessage &message) {
Paul Stewart9a908082011-08-31 12:18:48 -0700253 if (message.type() == RTNLMessage::kTypeLink) {
254 device_info_.LinkMsgHandler(message);
255 } else if (message.type() == RTNLMessage::kTypeAddress) {
256 device_info_.AddressMsgHandler(message);
Peter Qiu98551702014-07-28 13:28:53 -0700257 } else if (message.type() == RTNLMessage::kTypeRdnss) {
258 device_info_.RdnssMsgHandler(message);
Paul Stewart9a908082011-08-31 12:18:48 -0700259 } else {
260 NOTREACHED();
261 }
262}
263
264MATCHER_P(IsIPAddress, address, "") {
265 // NB: IPAddress objects don't support the "==" operator as per style, so
266 // we need a custom matcher.
267 return address.Equals(arg);
Darin Petkov633ac6f2011-07-08 13:56:13 -0700268}
269
Paul Stewart8c116a92012-05-02 18:30:03 -0700270TEST_F(DeviceInfoTest, StartStop) {
271 EXPECT_FALSE(device_info_.link_listener_.get());
272 EXPECT_FALSE(device_info_.address_listener_.get());
273 EXPECT_TRUE(device_info_.infos_.empty());
274
275 EXPECT_CALL(rtnl_handler_, RequestDump(RTNLHandler::kRequestLink |
276 RTNLHandler::kRequestAddr));
Paul Stewart1ac4e842012-07-10 12:58:12 -0700277 EXPECT_CALL(dispatcher_, PostDelayedTask(
Ben Chanb061f892013-02-27 17:46:55 -0800278 _, DeviceInfo::kRequestLinkStatisticsIntervalMilliseconds));
Chris Masone9be4a9d2011-05-16 15:44:09 -0700279 device_info_.Start();
Paul Stewart8c116a92012-05-02 18:30:03 -0700280 EXPECT_TRUE(device_info_.link_listener_.get());
281 EXPECT_TRUE(device_info_.address_listener_.get());
282 EXPECT_TRUE(device_info_.infos_.empty());
283 Mock::VerifyAndClearExpectations(&rtnl_handler_);
284
285 CreateInterfaceAddress();
286 EXPECT_FALSE(device_info_.infos_.empty());
287
288 device_info_.Stop();
289 EXPECT_FALSE(device_info_.link_listener_.get());
290 EXPECT_FALSE(device_info_.address_listener_.get());
291 EXPECT_TRUE(device_info_.infos_.empty());
292}
293
Paul Stewart1ac4e842012-07-10 12:58:12 -0700294TEST_F(DeviceInfoTest, RequestLinkStatistics) {
295 EXPECT_CALL(rtnl_handler_, RequestDump(RTNLHandler::kRequestLink));
296 EXPECT_CALL(dispatcher_, PostDelayedTask(
Ben Chanb061f892013-02-27 17:46:55 -0800297 _, DeviceInfo::kRequestLinkStatisticsIntervalMilliseconds));
Paul Stewart1ac4e842012-07-10 12:58:12 -0700298 device_info_.RequestLinkStatistics();
299}
300
Paul Stewart8c116a92012-05-02 18:30:03 -0700301TEST_F(DeviceInfoTest, DeviceEnumeration) {
Ben Chancd477322014-10-17 14:19:30 -0700302 unique_ptr<RTNLMessage> message(BuildLinkMessage(RTNLMessage::kModeAdd));
Darin Petkove6193c02011-08-11 12:42:40 -0700303 message->set_link_status(RTNLMessage::LinkStatus(0, IFF_LOWER_UP, 0));
304 EXPECT_FALSE(device_info_.GetDevice(kTestDeviceIndex).get());
Darin Petkovf8046b82012-04-24 16:29:23 +0200305 EXPECT_EQ(-1, device_info_.GetIndex(kTestDeviceName));
Darin Petkove6193c02011-08-11 12:42:40 -0700306 SendMessageToDeviceInfo(*message);
307 EXPECT_TRUE(device_info_.GetDevice(kTestDeviceIndex).get());
308 unsigned int flags = 0;
309 EXPECT_TRUE(device_info_.GetFlags(kTestDeviceIndex, &flags));
310 EXPECT_EQ(IFF_LOWER_UP, flags);
Darin Petkove3e1cfa2011-08-11 13:41:17 -0700311 ByteString address;
Paul Stewart32852962011-08-30 14:06:53 -0700312 EXPECT_TRUE(device_info_.GetMACAddress(kTestDeviceIndex, &address));
Darin Petkove3e1cfa2011-08-11 13:41:17 -0700313 EXPECT_FALSE(address.IsEmpty());
Paul Stewart9a908082011-08-31 12:18:48 -0700314 EXPECT_TRUE(address.Equals(ByteString(kTestMACAddress,
315 sizeof(kTestMACAddress))));
Darin Petkovf8046b82012-04-24 16:29:23 +0200316 EXPECT_EQ(kTestDeviceIndex, device_info_.GetIndex(kTestDeviceName));
Paul Stewarta3c56f92011-05-26 07:08:52 -0700317
Paul Stewart9a908082011-08-31 12:18:48 -0700318 message.reset(BuildLinkMessage(RTNLMessage::kModeAdd));
Darin Petkove6193c02011-08-11 12:42:40 -0700319 message->set_link_status(RTNLMessage::LinkStatus(0, IFF_UP | IFF_RUNNING, 0));
320 SendMessageToDeviceInfo(*message);
321 EXPECT_TRUE(device_info_.GetFlags(kTestDeviceIndex, &flags));
322 EXPECT_EQ(IFF_UP | IFF_RUNNING, flags);
Paul Stewartb50f0b92011-05-16 16:31:42 -0700323
Paul Stewart9a908082011-08-31 12:18:48 -0700324 message.reset(BuildLinkMessage(RTNLMessage::kModeDelete));
Paul Stewart8c116a92012-05-02 18:30:03 -0700325 EXPECT_CALL(manager_, DeregisterDevice(_)).Times(1);
Darin Petkove6193c02011-08-11 12:42:40 -0700326 SendMessageToDeviceInfo(*message);
327 EXPECT_FALSE(device_info_.GetDevice(kTestDeviceIndex).get());
Ben Chancc225ef2014-09-30 13:26:51 -0700328 EXPECT_FALSE(device_info_.GetFlags(kTestDeviceIndex, nullptr));
Darin Petkovf8046b82012-04-24 16:29:23 +0200329 EXPECT_EQ(-1, device_info_.GetIndex(kTestDeviceName));
Paul Stewart8c116a92012-05-02 18:30:03 -0700330}
Paul Stewarta3c56f92011-05-26 07:08:52 -0700331
Peter Qiu9f5159e2014-09-12 16:50:14 -0700332TEST_F(DeviceInfoTest, DeviceRemovedEvent) {
333 // Remove a Wifi device.
334 scoped_refptr<MockDevice> device0(new MockDevice(
335 &control_interface_, &dispatcher_, &metrics_, &manager_,
336 "null0", "addr0", kTestDeviceIndex));
337 device_info_.infos_[kTestDeviceIndex].device = device0;
Ben Chancd477322014-10-17 14:19:30 -0700338 unique_ptr<RTNLMessage> message(BuildLinkMessage(RTNLMessage::kModeDelete));
Peter Qiu9f5159e2014-09-12 16:50:14 -0700339 EXPECT_CALL(*device0, technology()).WillRepeatedly(Return(Technology::kWifi));
340 EXPECT_CALL(manager_, DeregisterDevice(_)).Times(1);
341 EXPECT_CALL(metrics_, DeregisterDevice(kTestDeviceIndex)).Times(1);
342 SendMessageToDeviceInfo(*message);
343 Mock::VerifyAndClearExpectations(device0);
344
345 // Deregister a Cellular device.
346 scoped_refptr<MockDevice> device1(new MockDevice(
347 &control_interface_, &dispatcher_, &metrics_, &manager_,
348 "null0", "addr0", kTestDeviceIndex));
349 device_info_.infos_[kTestDeviceIndex].device = device1;
350 EXPECT_CALL(*device1, technology()).
351 WillRepeatedly(Return(Technology::kCellular));
352 EXPECT_CALL(manager_, DeregisterDevice(_)).Times(1);
353 EXPECT_CALL(metrics_, DeregisterDevice(kTestDeviceIndex)).Times(1);
354 device_info_.DeregisterDevice(device1);
355}
356
Ben Chan5086b972013-01-15 21:51:38 -0800357TEST_F(DeviceInfoTest, GetUninitializedTechnologies) {
358 vector<string> technologies = device_info_.GetUninitializedTechnologies();
359 set<string> expected_technologies;
360
361 EXPECT_THAT(set<string>(technologies.begin(), technologies.end()),
362 ContainerEq(expected_technologies));
363
364 device_info_.infos_[0].technology = Technology::kUnknown;
365 EXPECT_THAT(set<string>(technologies.begin(), technologies.end()),
366 ContainerEq(expected_technologies));
367
368 device_info_.infos_[1].technology = Technology::kCellular;
369 technologies = device_info_.GetUninitializedTechnologies();
370 expected_technologies.insert(Technology::NameFromIdentifier(
371 Technology::kCellular));
372 EXPECT_THAT(set<string>(technologies.begin(), technologies.end()),
373 ContainerEq(expected_technologies));
374
375 device_info_.infos_[2].technology = Technology::kWiMax;
376 technologies = device_info_.GetUninitializedTechnologies();
377 expected_technologies.insert(Technology::NameFromIdentifier(
378 Technology::kWiMax));
379 EXPECT_THAT(set<string>(technologies.begin(), technologies.end()),
380 ContainerEq(expected_technologies));
381
382 scoped_refptr<MockDevice> device(new MockDevice(
383 &control_interface_, &dispatcher_, &metrics_, &manager_,
384 "null0", "addr0", 1));
385 device_info_.infos_[1].device = device;
386 technologies = device_info_.GetUninitializedTechnologies();
387 expected_technologies.erase(Technology::NameFromIdentifier(
388 Technology::kCellular));
389 EXPECT_THAT(set<string>(technologies.begin(), technologies.end()),
390 ContainerEq(expected_technologies));
391
392 device_info_.infos_[3].technology = Technology::kCellular;
393 technologies = device_info_.GetUninitializedTechnologies();
Arman Ugurayb00c13d2013-07-29 18:20:52 -0700394 EXPECT_THAT(set<string>(technologies.begin(), technologies.end()),
395 ContainerEq(expected_technologies));
396
397 device_info_.infos_[3].device = device;
Ben Chancc225ef2014-09-30 13:26:51 -0700398 device_info_.infos_[1].device = nullptr;
Arman Ugurayb00c13d2013-07-29 18:20:52 -0700399 technologies = device_info_.GetUninitializedTechnologies();
Ben Chan5086b972013-01-15 21:51:38 -0800400 EXPECT_THAT(set<string>(technologies.begin(), technologies.end()),
401 ContainerEq(expected_technologies));
402}
403
Paul Stewart1ac4e842012-07-10 12:58:12 -0700404TEST_F(DeviceInfoTest, GetByteCounts) {
Ben Chan7fab8972014-08-10 17:14:46 -0700405 uint64_t rx_bytes, tx_bytes;
Paul Stewart1ac4e842012-07-10 12:58:12 -0700406 EXPECT_FALSE(device_info_.GetByteCounts(
407 kTestDeviceIndex, &rx_bytes, &tx_bytes));
408
409 // No link statistics in the message.
Ben Chancd477322014-10-17 14:19:30 -0700410 unique_ptr<RTNLMessage> message(BuildLinkMessage(RTNLMessage::kModeAdd));
Paul Stewart1ac4e842012-07-10 12:58:12 -0700411 SendMessageToDeviceInfo(*message);
412 EXPECT_TRUE(device_info_.GetByteCounts(
413 kTestDeviceIndex, &rx_bytes, &tx_bytes));
414 EXPECT_EQ(0, rx_bytes);
415 EXPECT_EQ(0, tx_bytes);
416
417 // Short link statistics message.
418 message.reset(BuildLinkMessage(RTNLMessage::kModeAdd));
419 struct rtnl_link_stats64 stats;
420 memset(&stats, 0, sizeof(stats));
421 stats.rx_bytes = kReceiveByteCount;
422 stats.tx_bytes = kTransmitByteCount;
423 ByteString stats_bytes0(reinterpret_cast<const unsigned char*>(&stats),
424 sizeof(stats) - 1);
425 message->SetAttribute(IFLA_STATS64, stats_bytes0);
426 SendMessageToDeviceInfo(*message);
427 EXPECT_TRUE(device_info_.GetByteCounts(
428 kTestDeviceIndex, &rx_bytes, &tx_bytes));
429 EXPECT_EQ(0, rx_bytes);
430 EXPECT_EQ(0, tx_bytes);
431
432 // Correctly sized link statistics message.
433 message.reset(BuildLinkMessage(RTNLMessage::kModeAdd));
434 ByteString stats_bytes1(reinterpret_cast<const unsigned char*>(&stats),
435 sizeof(stats));
436 message->SetAttribute(IFLA_STATS64, stats_bytes1);
437 SendMessageToDeviceInfo(*message);
438 EXPECT_TRUE(device_info_.GetByteCounts(
439 kTestDeviceIndex, &rx_bytes, &tx_bytes));
440 EXPECT_EQ(kReceiveByteCount, rx_bytes);
441 EXPECT_EQ(kTransmitByteCount, tx_bytes);
442}
443
Ben Chan5742b242013-12-18 16:25:43 -0800444#if !defined(DISABLE_CELLULAR)
445
Paul Stewart8c116a92012-05-02 18:30:03 -0700446TEST_F(DeviceInfoTest, CreateDeviceCellular) {
447 IPAddress address = CreateInterfaceAddress();
448
449 // A cellular device should be offered to ModemInfo.
450 StrictMock<MockModemInfo> modem_info;
451 EXPECT_CALL(manager_, modem_info()).WillOnce(Return(&modem_info));
452 EXPECT_CALL(modem_info, OnDeviceInfoAvailable(kTestDeviceName)).Times(1);
453 EXPECT_CALL(routing_table_, FlushRoutes(kTestDeviceIndex)).Times(1);
454 EXPECT_CALL(rtnl_handler_, RemoveInterfaceAddress(kTestDeviceIndex,
455 IsIPAddress(address)));
456 EXPECT_FALSE(CreateDevice(
457 kTestDeviceName, "address", kTestDeviceIndex, Technology::kCellular));
458}
459
Ben Chan5742b242013-12-18 16:25:43 -0800460#endif // DISABLE_CELLULAR
461
Ben Chan520eb172013-10-30 20:51:04 -0700462#if !defined(DISABLE_WIMAX)
463
Darin Petkove4b27022012-05-16 13:28:50 +0200464TEST_F(DeviceInfoTest, CreateDeviceWiMax) {
465 IPAddress address = CreateInterfaceAddress();
466
467 // A WiMax device should be offered to WiMaxProvider.
468 StrictMock<MockWiMaxProvider> wimax_provider;
469 EXPECT_CALL(manager_, wimax_provider()).WillOnce(Return(&wimax_provider));
470 EXPECT_CALL(wimax_provider, OnDeviceInfoAvailable(kTestDeviceName)).Times(1);
471 EXPECT_CALL(routing_table_, FlushRoutes(kTestDeviceIndex)).Times(1);
472 EXPECT_CALL(rtnl_handler_, RemoveInterfaceAddress(kTestDeviceIndex,
473 IsIPAddress(address)));
Ben Chan4b285862012-10-10 22:52:16 -0700474 device_info_.infos_[kTestDeviceIndex].mac_address =
475 ByteString(kTestMACAddress, sizeof(kTestMACAddress));
Darin Petkove4b27022012-05-16 13:28:50 +0200476 EXPECT_FALSE(CreateDevice(
477 kTestDeviceName, "address", kTestDeviceIndex, Technology::kWiMax));
Ben Chan4b285862012-10-10 22:52:16 -0700478 // The MAC address is clear such that it is obtained via
479 // GetMACAddressFromKernel() instead.
480 EXPECT_TRUE(device_info_.infos_[kTestDeviceIndex].mac_address.IsEmpty());
Darin Petkove4b27022012-05-16 13:28:50 +0200481}
482
Ben Chan520eb172013-10-30 20:51:04 -0700483#endif // DISABLE_WIMAX
484
Paul Stewart8c116a92012-05-02 18:30:03 -0700485TEST_F(DeviceInfoTest, CreateDeviceEthernet) {
486 IPAddress address = CreateInterfaceAddress();
487
488 // An Ethernet device should cause routes and addresses to be flushed.
489 EXPECT_CALL(routing_table_, FlushRoutes(kTestDeviceIndex)).Times(1);
490 EXPECT_CALL(rtnl_handler_, RemoveInterfaceAddress(kTestDeviceIndex,
491 IsIPAddress(address)));
492 DeviceRefPtr device = CreateDevice(
493 kTestDeviceName, "address", kTestDeviceIndex, Technology::kEthernet);
494 EXPECT_TRUE(device);
495 Mock::VerifyAndClearExpectations(&routing_table_);
496 Mock::VerifyAndClearExpectations(&rtnl_handler_);
497
498 // The Ethernet device destructor notifies the manager.
499 EXPECT_CALL(manager_, UpdateEnabledTechnologies()).Times(1);
Ben Chancc225ef2014-09-30 13:26:51 -0700500 device = nullptr;
Paul Stewart8c116a92012-05-02 18:30:03 -0700501}
502
503TEST_F(DeviceInfoTest, CreateDeviceVirtioEthernet) {
504 IPAddress address = CreateInterfaceAddress();
505
506 // VirtioEthernet is identical to Ethernet from the perspective of this test.
507 EXPECT_CALL(routing_table_, FlushRoutes(kTestDeviceIndex)).Times(1);
508 EXPECT_CALL(rtnl_handler_, RemoveInterfaceAddress(kTestDeviceIndex,
509 IsIPAddress(address)));
510 DeviceRefPtr device = CreateDevice(
511 kTestDeviceName, "address", kTestDeviceIndex,
512 Technology::kVirtioEthernet);
513 EXPECT_TRUE(device);
514 Mock::VerifyAndClearExpectations(&routing_table_);
515 Mock::VerifyAndClearExpectations(&rtnl_handler_);
516
517 // The Ethernet device destructor notifies the manager.
518 EXPECT_CALL(manager_, UpdateEnabledTechnologies()).Times(1);
Ben Chancc225ef2014-09-30 13:26:51 -0700519 device = nullptr;
Paul Stewart8c116a92012-05-02 18:30:03 -0700520}
521
Paul Stewart2ddf2c62013-04-16 09:47:34 -0700522MATCHER_P(IsGetInterfaceMessage, index, "") {
523 if (arg->message_type() != Nl80211Message::GetMessageType()) {
524 return false;
525 }
526 const Nl80211Message *msg = reinterpret_cast<const Nl80211Message *>(arg);
527 if (msg->command() != NL80211_CMD_GET_INTERFACE) {
528 return false;
529 }
530 uint32_t interface_index;
531 if (!msg->const_attributes()->GetU32AttributeValue(NL80211_ATTR_IFINDEX,
532 &interface_index)) {
533 return false;
534 }
535 // kInterfaceIndex is signed, but the attribute as handed from the kernel
536 // is unsigned. We're silently casting it away with this assignment.
537 uint32_t test_interface_index = index;
538 return interface_index == test_interface_index;
539}
540
Paul Stewart8c116a92012-05-02 18:30:03 -0700541TEST_F(DeviceInfoTest, CreateDeviceWiFi) {
542 IPAddress address = CreateInterfaceAddress();
543
544 // WiFi looks a lot like Ethernet too.
Paul Stewart2ddf2c62013-04-16 09:47:34 -0700545 EXPECT_CALL(routing_table_, FlushRoutes(kTestDeviceIndex));
Paul Stewart8c116a92012-05-02 18:30:03 -0700546 EXPECT_CALL(rtnl_handler_, RemoveInterfaceAddress(kTestDeviceIndex,
547 IsIPAddress(address)));
Paul Stewart2ddf2c62013-04-16 09:47:34 -0700548
549 // Set the nl80211 message type to some non-default value.
550 Nl80211Message::SetMessageType(1234);
551
Wade Guthrie7347bf22013-04-30 11:21:51 -0700552 EXPECT_CALL(
553 netlink_manager_,
Samuel Tan5412de02014-08-15 17:56:26 -0700554 SendNl80211Message(IsGetInterfaceMessage(kTestDeviceIndex), _, _, _));
Paul Stewart2ddf2c62013-04-16 09:47:34 -0700555 EXPECT_FALSE(CreateDevice(
Paul Stewart8c116a92012-05-02 18:30:03 -0700556 kTestDeviceName, "address", kTestDeviceIndex, Technology::kWifi));
557}
558
559TEST_F(DeviceInfoTest, CreateDeviceTunnelAccepted) {
560 IPAddress address = CreateInterfaceAddress();
561
562 // A VPN device should be offered to VPNProvider.
Darin Petkovc3505a52013-03-18 15:13:29 +0100563 MockVPNProvider *vpn_provider = new StrictMock<MockVPNProvider>;
564 SetVPNProvider(vpn_provider);
565 EXPECT_CALL(*vpn_provider,
Paul Stewart8c116a92012-05-02 18:30:03 -0700566 OnDeviceInfoAvailable(kTestDeviceName, kTestDeviceIndex))
567 .WillOnce(Return(true));
568 EXPECT_CALL(routing_table_, FlushRoutes(kTestDeviceIndex)).Times(1);
569 EXPECT_CALL(rtnl_handler_, RemoveInterfaceAddress(kTestDeviceIndex,
570 IsIPAddress(address)));
571 EXPECT_CALL(rtnl_handler_, RemoveInterface(_)).Times(0);
572 EXPECT_FALSE(CreateDevice(
573 kTestDeviceName, "address", kTestDeviceIndex, Technology::kTunnel));
574}
575
576TEST_F(DeviceInfoTest, CreateDeviceTunnelRejected) {
577 IPAddress address = CreateInterfaceAddress();
578
579 // A VPN device should be offered to VPNProvider.
Darin Petkovc3505a52013-03-18 15:13:29 +0100580 MockVPNProvider *vpn_provider = new StrictMock<MockVPNProvider>;
581 SetVPNProvider(vpn_provider);
582 EXPECT_CALL(*vpn_provider,
Paul Stewart8c116a92012-05-02 18:30:03 -0700583 OnDeviceInfoAvailable(kTestDeviceName, kTestDeviceIndex))
584 .WillOnce(Return(false));
585 EXPECT_CALL(routing_table_, FlushRoutes(kTestDeviceIndex)).Times(1);
586 EXPECT_CALL(rtnl_handler_, RemoveInterfaceAddress(kTestDeviceIndex,
587 IsIPAddress(address)));
588 // Since the device was rejected by the VPNProvider, DeviceInfo will
589 // remove the interface.
590 EXPECT_CALL(rtnl_handler_, RemoveInterface(kTestDeviceIndex)).Times(1);
591 EXPECT_FALSE(CreateDevice(
592 kTestDeviceName, "address", kTestDeviceIndex, Technology::kTunnel));
593}
594
595TEST_F(DeviceInfoTest, CreateDevicePPP) {
596 IPAddress address = CreateInterfaceAddress();
597
598 // A VPN device should be offered to VPNProvider.
Darin Petkovc3505a52013-03-18 15:13:29 +0100599 MockVPNProvider *vpn_provider = new StrictMock<MockVPNProvider>;
600 SetVPNProvider(vpn_provider);
601 EXPECT_CALL(*vpn_provider,
Paul Stewart8c116a92012-05-02 18:30:03 -0700602 OnDeviceInfoAvailable(kTestDeviceName, kTestDeviceIndex))
603 .WillOnce(Return(false));
604 EXPECT_CALL(routing_table_, FlushRoutes(kTestDeviceIndex)).Times(1);
605 EXPECT_CALL(rtnl_handler_, RemoveInterfaceAddress(kTestDeviceIndex,
606 IsIPAddress(address)));
607 // We do not remove PPP interfaces even if the provider does not accept it.
608 EXPECT_CALL(rtnl_handler_, RemoveInterface(_)).Times(0);
609 EXPECT_FALSE(CreateDevice(
610 kTestDeviceName, "address", kTestDeviceIndex, Technology::kPPP));
611}
612
613TEST_F(DeviceInfoTest, CreateDeviceLoopback) {
614 // A loopback device should be brought up, and nothing else done to it.
615 EXPECT_CALL(routing_table_, FlushRoutes(_)).Times(0);
616 EXPECT_CALL(rtnl_handler_, RemoveInterfaceAddress(_, _)).Times(0);
617 EXPECT_CALL(rtnl_handler_,
618 SetInterfaceFlags(kTestDeviceIndex, IFF_UP, IFF_UP)).Times(1);
619 EXPECT_FALSE(CreateDevice(
620 kTestDeviceName, "address", kTestDeviceIndex, Technology::kLoopback));
621}
622
Paul Stewart050cfc02012-07-06 20:38:54 -0700623TEST_F(DeviceInfoTest, CreateDeviceCDCEthernet) {
Ben Chan4eb4ddf2013-06-20 22:16:56 -0700624 // A cdc_ether / cdc_ncm device should be postponed to a task.
Paul Stewart050cfc02012-07-06 20:38:54 -0700625 EXPECT_CALL(manager_, modem_info()).Times(0);
626 EXPECT_CALL(routing_table_, FlushRoutes(_)).Times(0);
627 EXPECT_CALL(rtnl_handler_, RemoveInterfaceAddress(_, _)).Times(0);
628 EXPECT_CALL(dispatcher_,
Paul Stewart1ac4e842012-07-10 12:58:12 -0700629 PostDelayedTask(_, GetDelayedDeviceCreationMilliseconds()));
Paul Stewart050cfc02012-07-06 20:38:54 -0700630 EXPECT_TRUE(GetDelayedDevices().empty());
631 EXPECT_FALSE(CreateDevice(
632 kTestDeviceName, "address", kTestDeviceIndex, Technology::kCDCEthernet));
633 EXPECT_FALSE(GetDelayedDevices().empty());
634 EXPECT_EQ(1, GetDelayedDevices().size());
635 EXPECT_EQ(kTestDeviceIndex, *GetDelayedDevices().begin());
636}
637
Paul Stewart8c116a92012-05-02 18:30:03 -0700638TEST_F(DeviceInfoTest, CreateDeviceUnknown) {
639 IPAddress address = CreateInterfaceAddress();
640
641 // An unknown (blacklisted, unhandled, etc) device won't be flushed or
642 // registered.
643 EXPECT_CALL(routing_table_, FlushRoutes(_)).Times(0);
644 EXPECT_CALL(rtnl_handler_, RemoveInterfaceAddress(_, _)).Times(0);
645 EXPECT_TRUE(CreateDevice(
646 kTestDeviceName, "address", kTestDeviceIndex, Technology::kUnknown));
Chris Masone9be4a9d2011-05-16 15:44:09 -0700647}
648
mukesh agrawal8f317b62011-07-15 11:53:23 -0700649TEST_F(DeviceInfoTest, DeviceBlackList) {
650 device_info_.AddDeviceToBlackList(kTestDeviceName);
Ben Chancd477322014-10-17 14:19:30 -0700651 unique_ptr<RTNLMessage> message(BuildLinkMessage(RTNLMessage::kModeAdd));
Darin Petkove6193c02011-08-11 12:42:40 -0700652 SendMessageToDeviceInfo(*message);
mukesh agrawal8f317b62011-07-15 11:53:23 -0700653
Darin Petkove6193c02011-08-11 12:42:40 -0700654 DeviceRefPtr device = device_info_.GetDevice(kTestDeviceIndex);
655 ASSERT_TRUE(device.get());
Joshua Krollda798622012-06-05 12:30:48 -0700656 EXPECT_TRUE(device->technology() == Technology::kBlacklisted);
mukesh agrawal8f317b62011-07-15 11:53:23 -0700657}
658
Paul Stewart9a908082011-08-31 12:18:48 -0700659TEST_F(DeviceInfoTest, DeviceAddressList) {
Ben Chancd477322014-10-17 14:19:30 -0700660 unique_ptr<RTNLMessage> message(BuildLinkMessage(RTNLMessage::kModeAdd));
Paul Stewart9a908082011-08-31 12:18:48 -0700661 SendMessageToDeviceInfo(*message);
662
663 vector<DeviceInfo::AddressData> addresses;
664 EXPECT_TRUE(device_info_.GetAddresses(kTestDeviceIndex, &addresses));
665 EXPECT_TRUE(addresses.empty());
666
667 // Add an address to the device address list
Paul Stewart7355ce12011-09-02 10:47:01 -0700668 IPAddress ip_address0(IPAddress::kFamilyIPv4);
Paul Stewart9a908082011-08-31 12:18:48 -0700669 EXPECT_TRUE(ip_address0.SetAddressFromString(kTestIPAddress0));
670 ip_address0.set_prefix(kTestIPAddressPrefix0);
671 message.reset(BuildAddressMessage(RTNLMessage::kModeAdd, ip_address0, 0, 0));
672 SendMessageToDeviceInfo(*message);
673 EXPECT_TRUE(device_info_.GetAddresses(kTestDeviceIndex, &addresses));
674 EXPECT_EQ(1, addresses.size());
675 EXPECT_TRUE(ip_address0.Equals(addresses[0].address));
676
677 // Re-adding the same address shouldn't cause the address list to change
678 SendMessageToDeviceInfo(*message);
679 EXPECT_TRUE(device_info_.GetAddresses(kTestDeviceIndex, &addresses));
680 EXPECT_EQ(1, addresses.size());
681 EXPECT_TRUE(ip_address0.Equals(addresses[0].address));
682
683 // Adding a new address should expand the list
Paul Stewart7355ce12011-09-02 10:47:01 -0700684 IPAddress ip_address1(IPAddress::kFamilyIPv6);
Paul Stewart9a908082011-08-31 12:18:48 -0700685 EXPECT_TRUE(ip_address1.SetAddressFromString(kTestIPAddress1));
686 ip_address1.set_prefix(kTestIPAddressPrefix1);
687 message.reset(BuildAddressMessage(RTNLMessage::kModeAdd, ip_address1, 0, 0));
688 SendMessageToDeviceInfo(*message);
689 EXPECT_TRUE(device_info_.GetAddresses(kTestDeviceIndex, &addresses));
690 EXPECT_EQ(2, addresses.size());
691 EXPECT_TRUE(ip_address0.Equals(addresses[0].address));
692 EXPECT_TRUE(ip_address1.Equals(addresses[1].address));
693
694 // Deleting an address should reduce the list
695 message.reset(BuildAddressMessage(RTNLMessage::kModeDelete,
696 ip_address0,
697 0,
698 0));
699 SendMessageToDeviceInfo(*message);
700 EXPECT_TRUE(device_info_.GetAddresses(kTestDeviceIndex, &addresses));
701 EXPECT_EQ(1, addresses.size());
702 EXPECT_TRUE(ip_address1.Equals(addresses[0].address));
703
704 // Delete last item
705 message.reset(BuildAddressMessage(RTNLMessage::kModeDelete,
706 ip_address1,
707 0,
708 0));
709 SendMessageToDeviceInfo(*message);
710 EXPECT_TRUE(device_info_.GetAddresses(kTestDeviceIndex, &addresses));
711 EXPECT_TRUE(addresses.empty());
712
713 // Delete device
714 message.reset(BuildLinkMessage(RTNLMessage::kModeDelete));
Paul Stewart8c116a92012-05-02 18:30:03 -0700715 EXPECT_CALL(manager_, DeregisterDevice(_)).Times(1);
Paul Stewart9a908082011-08-31 12:18:48 -0700716 SendMessageToDeviceInfo(*message);
717
718 // Should be able to handle message for interface that doesn't exist
719 message.reset(BuildAddressMessage(RTNLMessage::kModeAdd, ip_address0, 0, 0));
720 SendMessageToDeviceInfo(*message);
721 EXPECT_FALSE(device_info_.GetDevice(kTestDeviceIndex).get());
Paul Stewart9a908082011-08-31 12:18:48 -0700722}
723
724TEST_F(DeviceInfoTest, FlushAddressList) {
Ben Chancd477322014-10-17 14:19:30 -0700725 unique_ptr<RTNLMessage> message(BuildLinkMessage(RTNLMessage::kModeAdd));
Paul Stewart9a908082011-08-31 12:18:48 -0700726 SendMessageToDeviceInfo(*message);
727
Paul Stewart7355ce12011-09-02 10:47:01 -0700728 IPAddress address1(IPAddress::kFamilyIPv6);
Paul Stewart9a908082011-08-31 12:18:48 -0700729 EXPECT_TRUE(address1.SetAddressFromString(kTestIPAddress1));
730 address1.set_prefix(kTestIPAddressPrefix1);
731 message.reset(BuildAddressMessage(RTNLMessage::kModeAdd,
732 address1,
733 0,
734 RT_SCOPE_UNIVERSE));
735 SendMessageToDeviceInfo(*message);
Paul Stewart7355ce12011-09-02 10:47:01 -0700736 IPAddress address2(IPAddress::kFamilyIPv6);
Paul Stewart9a908082011-08-31 12:18:48 -0700737 EXPECT_TRUE(address2.SetAddressFromString(kTestIPAddress2));
738 message.reset(BuildAddressMessage(RTNLMessage::kModeAdd,
739 address2,
740 IFA_F_TEMPORARY,
741 RT_SCOPE_UNIVERSE));
742 SendMessageToDeviceInfo(*message);
Paul Stewart7355ce12011-09-02 10:47:01 -0700743 IPAddress address3(IPAddress::kFamilyIPv6);
Paul Stewart9a908082011-08-31 12:18:48 -0700744 EXPECT_TRUE(address3.SetAddressFromString(kTestIPAddress3));
745 message.reset(BuildAddressMessage(RTNLMessage::kModeAdd,
746 address3,
747 0,
748 RT_SCOPE_LINK));
749 SendMessageToDeviceInfo(*message);
Paul Stewart7355ce12011-09-02 10:47:01 -0700750 IPAddress address4(IPAddress::kFamilyIPv6);
Paul Stewart9a908082011-08-31 12:18:48 -0700751 EXPECT_TRUE(address4.SetAddressFromString(kTestIPAddress4));
752 message.reset(BuildAddressMessage(RTNLMessage::kModeAdd,
753 address4,
754 IFA_F_PERMANENT,
755 RT_SCOPE_UNIVERSE));
756 SendMessageToDeviceInfo(*message);
757
758 // DeviceInfo now has 4 addresses associated with it, but only two of
759 // them are valid for flush.
760 EXPECT_CALL(rtnl_handler_, RemoveInterfaceAddress(kTestDeviceIndex,
761 IsIPAddress(address1)));
762 EXPECT_CALL(rtnl_handler_, RemoveInterfaceAddress(kTestDeviceIndex,
763 IsIPAddress(address2)));
764 device_info_.FlushAddresses(kTestDeviceIndex);
Paul Stewart9a908082011-08-31 12:18:48 -0700765}
766
Paul Stewart05a42c22012-08-02 16:47:21 -0700767TEST_F(DeviceInfoTest, HasOtherAddress) {
Ben Chancd477322014-10-17 14:19:30 -0700768 unique_ptr<RTNLMessage> message(BuildLinkMessage(RTNLMessage::kModeAdd));
Paul Stewart05a42c22012-08-02 16:47:21 -0700769 SendMessageToDeviceInfo(*message);
770
771 IPAddress address0(IPAddress::kFamilyIPv4);
772 EXPECT_TRUE(address0.SetAddressFromString(kTestIPAddress0));
773
774 // There are no addresses on this interface.
775 EXPECT_FALSE(device_info_.HasOtherAddress(kTestDeviceIndex, address0));
776
777 message.reset(BuildAddressMessage(RTNLMessage::kModeAdd,
778 address0,
779 0,
780 RT_SCOPE_UNIVERSE));
781 SendMessageToDeviceInfo(*message);
782
783 IPAddress address1(IPAddress::kFamilyIPv6);
784 EXPECT_TRUE(address1.SetAddressFromString(kTestIPAddress1));
785 address1.set_prefix(kTestIPAddressPrefix1);
786 message.reset(BuildAddressMessage(RTNLMessage::kModeAdd,
787 address1,
788 0,
789 RT_SCOPE_LINK));
790 SendMessageToDeviceInfo(*message);
791
792 IPAddress address2(IPAddress::kFamilyIPv6);
793 EXPECT_TRUE(address2.SetAddressFromString(kTestIPAddress2));
794 message.reset(BuildAddressMessage(RTNLMessage::kModeAdd,
795 address2,
796 IFA_F_TEMPORARY,
797 RT_SCOPE_UNIVERSE));
798 SendMessageToDeviceInfo(*message);
799
800 IPAddress address3(IPAddress::kFamilyIPv6);
801 EXPECT_TRUE(address3.SetAddressFromString(kTestIPAddress3));
802
803 // The only IPv6 addresses on this interface are either flagged as
804 // temporary, or they are not universally scoped.
805 EXPECT_FALSE(device_info_.HasOtherAddress(kTestDeviceIndex, address3));
806
807
808 message.reset(BuildAddressMessage(RTNLMessage::kModeAdd,
809 address3,
810 0,
811 RT_SCOPE_UNIVERSE));
812 SendMessageToDeviceInfo(*message);
813
814 // address0 is on this interface.
815 EXPECT_FALSE(device_info_.HasOtherAddress(kTestDeviceIndex, address0));
816 // address1 is on this interface.
817 EXPECT_FALSE(device_info_.HasOtherAddress(kTestDeviceIndex, address1));
818 // address2 is on this interface.
819 EXPECT_FALSE(device_info_.HasOtherAddress(kTestDeviceIndex, address2));
820 // address3 is on this interface.
821 EXPECT_FALSE(device_info_.HasOtherAddress(kTestDeviceIndex, address3));
822
823 IPAddress address4(IPAddress::kFamilyIPv6);
824 EXPECT_TRUE(address4.SetAddressFromString(kTestIPAddress4));
825
826 // address4 is not on this interface, but address3 is, and is a qualified
827 // IPv6 address.
828 EXPECT_TRUE(device_info_.HasOtherAddress(kTestDeviceIndex, address4));
829
830 message.reset(BuildAddressMessage(RTNLMessage::kModeAdd,
831 address4,
832 IFA_F_PERMANENT,
833 RT_SCOPE_UNIVERSE));
834 SendMessageToDeviceInfo(*message);
835
836 // address4 is now on this interface.
837 EXPECT_FALSE(device_info_.HasOtherAddress(kTestDeviceIndex, address4));
838
839 IPAddress address5(IPAddress::kFamilyIPv4);
840 EXPECT_TRUE(address5.SetAddressFromString(kTestIPAddress5));
841 // address5 is not on this interface, but address0 is.
842 EXPECT_TRUE(device_info_.HasOtherAddress(kTestDeviceIndex, address5));
843
844 message.reset(BuildAddressMessage(RTNLMessage::kModeAdd,
845 address5,
846 IFA_F_PERMANENT,
847 RT_SCOPE_UNIVERSE));
848 SendMessageToDeviceInfo(*message);
849
850 // address5 is now on this interface.
851 EXPECT_FALSE(device_info_.HasOtherAddress(kTestDeviceIndex, address5));
852}
853
Paul Stewarta0db0ff2013-12-09 09:48:47 -0800854TEST_F(DeviceInfoTest, HasDirectConnectivityTo) {
Ben Chancd477322014-10-17 14:19:30 -0700855 unique_ptr<RTNLMessage> message(BuildLinkMessage(RTNLMessage::kModeAdd));
Paul Stewarta0db0ff2013-12-09 09:48:47 -0800856 SendMessageToDeviceInfo(*message);
857
858 IPAddress address0(IPAddress::kFamilyIPv4);
859 EXPECT_TRUE(address0.SetAddressFromString(kTestIPAddress0));
860
861 // There are no addresses on this interface.
862 EXPECT_FALSE(device_info_.HasDirectConnectivityTo(
863 kTestDeviceIndex, address0));
864
865 IPAddress address1(IPAddress::kFamilyIPv6);
866 EXPECT_TRUE(address1.SetAddressFromString(kTestIPAddress1));
867 message.reset(BuildAddressMessage(RTNLMessage::kModeAdd,
868 address1,
869 IFA_F_PERMANENT,
870 RT_SCOPE_UNIVERSE));
871 SendMessageToDeviceInfo(*message);
872
873 // No current addresses are of the same family as |address0|.
874 EXPECT_FALSE(device_info_.HasDirectConnectivityTo(
875 kTestDeviceIndex, address0));
876
877 IPAddress address6(IPAddress::kFamilyIPv4);
878 EXPECT_TRUE(address6.SetAddressFromString(kTestIPAddress6));
879 address6.set_prefix(kTestIPAddressPrefix0);
880 message.reset(BuildAddressMessage(RTNLMessage::kModeAdd,
881 address6,
882 IFA_F_PERMANENT,
883 RT_SCOPE_UNIVERSE));
884 SendMessageToDeviceInfo(*message);
885
886 // |address0| is not reachable from |address6|.
887 EXPECT_FALSE(device_info_.HasDirectConnectivityTo(
888 kTestDeviceIndex, address0));
889
890 IPAddress address5(IPAddress::kFamilyIPv4);
891 EXPECT_TRUE(address5.SetAddressFromString(kTestIPAddress5));
892 address5.set_prefix(kTestIPAddressPrefix0);
893 message.reset(BuildAddressMessage(RTNLMessage::kModeAdd,
894 address5,
895 IFA_F_PERMANENT,
896 RT_SCOPE_UNIVERSE));
897 SendMessageToDeviceInfo(*message);
898
899 // |address0| is reachable from |address5| which is associated with the
900 // interface.
901 EXPECT_TRUE(device_info_.HasDirectConnectivityTo(
902 kTestDeviceIndex, address0));
903}
904
Thieu Leb27beee2012-04-20 09:19:06 -0700905TEST_F(DeviceInfoTest, HasSubdir) {
Paul Stewart5ad16062013-02-21 18:10:48 -0800906 base::ScopedTempDir temp_dir;
Thieu Le8f1c8352012-04-16 11:02:12 -0700907 EXPECT_TRUE(temp_dir.CreateUniqueTempDir());
Ben Chana0ddf462014-02-06 11:32:42 -0800908 EXPECT_TRUE(base::CreateDirectory(temp_dir.path().Append("child1")));
Thieu Leb27beee2012-04-20 09:19:06 -0700909 FilePath child2 = temp_dir.path().Append("child2");
Ben Chana0ddf462014-02-06 11:32:42 -0800910 EXPECT_TRUE(base::CreateDirectory(child2));
Thieu Leb27beee2012-04-20 09:19:06 -0700911 FilePath grandchild = child2.Append("grandchild");
Ben Chana0ddf462014-02-06 11:32:42 -0800912 EXPECT_TRUE(base::CreateDirectory(grandchild));
913 EXPECT_TRUE(base::CreateDirectory(grandchild.Append("greatgrandchild")));
Thieu Leb27beee2012-04-20 09:19:06 -0700914 EXPECT_TRUE(DeviceInfo::HasSubdir(temp_dir.path(),
915 FilePath("grandchild")));
916 EXPECT_TRUE(DeviceInfo::HasSubdir(temp_dir.path(),
917 FilePath("greatgrandchild")));
918 EXPECT_FALSE(DeviceInfo::HasSubdir(temp_dir.path(),
919 FilePath("nonexistent")));
Thieu Le8f1c8352012-04-16 11:02:12 -0700920}
921
Gary Morain41780232012-07-31 15:08:31 -0700922TEST_F(DeviceInfoTest, GetMACAddressFromKernelUnknownDevice) {
923 SetSockets();
924 EXPECT_CALL(*mock_sockets_, Socket(PF_INET, SOCK_DGRAM, 0)).Times(0);
925 ByteString mac_address =
926 device_info_.GetMACAddressFromKernel(kTestDeviceIndex);
927 EXPECT_TRUE(mac_address.IsEmpty());
928}
929
930TEST_F(DeviceInfoTest, GetMACAddressFromKernelUnableToOpenSocket) {
931 SetSockets();
932 EXPECT_CALL(*mock_sockets_, Socket(PF_INET, SOCK_DGRAM, 0))
933 .WillOnce(Return(-1));
Ben Chancd477322014-10-17 14:19:30 -0700934 unique_ptr<RTNLMessage> message(BuildLinkMessage(RTNLMessage::kModeAdd));
Gary Morain41780232012-07-31 15:08:31 -0700935 message->set_link_status(RTNLMessage::LinkStatus(0, IFF_LOWER_UP, 0));
936 SendMessageToDeviceInfo(*message);
937 EXPECT_TRUE(device_info_.GetDevice(kTestDeviceIndex).get());
938 ByteString mac_address =
939 device_info_.GetMACAddressFromKernel(kTestDeviceIndex);
940 EXPECT_TRUE(mac_address.IsEmpty());
941}
942
943TEST_F(DeviceInfoTest, GetMACAddressFromKernelIoctlFails) {
944 SetSockets();
945 const int kFd = 99;
946 EXPECT_CALL(*mock_sockets_, Socket(PF_INET, SOCK_DGRAM, 0))
947 .WillOnce(Return(kFd));
948 EXPECT_CALL(*mock_sockets_, Ioctl(kFd, SIOCGIFHWADDR, NotNull()))
949 .WillOnce(Return(-1));
950 EXPECT_CALL(*mock_sockets_, Close(kFd));
951
Ben Chancd477322014-10-17 14:19:30 -0700952 unique_ptr<RTNLMessage> message(BuildLinkMessage(RTNLMessage::kModeAdd));
Gary Morain41780232012-07-31 15:08:31 -0700953 message->set_link_status(RTNLMessage::LinkStatus(0, IFF_LOWER_UP, 0));
954 SendMessageToDeviceInfo(*message);
955 EXPECT_TRUE(device_info_.GetDevice(kTestDeviceIndex).get());
956
957 ByteString mac_address =
958 device_info_.GetMACAddressFromKernel(kTestDeviceIndex);
959 EXPECT_TRUE(mac_address.IsEmpty());
960}
961
962MATCHER_P2(IfreqEquals, ifindex, ifname, "") {
963 const struct ifreq *const ifr = static_cast<struct ifreq *>(arg);
Ben Chancc225ef2014-09-30 13:26:51 -0700964 return (ifr != nullptr) &&
Gary Morain41780232012-07-31 15:08:31 -0700965 (ifr->ifr_ifindex == ifindex) &&
966 (strcmp(ifname, ifr->ifr_name) == 0);
967}
968
969ACTION_P(SetIfreq, ifr) {
970 struct ifreq *const ifr_arg = static_cast<struct ifreq *>(arg2);
971 *ifr_arg = ifr;
972}
973
974TEST_F(DeviceInfoTest, GetMACAddressFromKernel) {
975 SetSockets();
976 const int kFd = 99;
977 struct ifreq ifr;
Han Shenfc349252012-08-30 11:36:04 -0700978 static uint8_t kMacAddress[] = {0x00, 0x01, 0x02, 0xaa, 0xbb, 0xcc};
Gary Morain41780232012-07-31 15:08:31 -0700979 memcpy(ifr.ifr_hwaddr.sa_data, kMacAddress, sizeof(kMacAddress));
980 EXPECT_CALL(*mock_sockets_, Socket(PF_INET, SOCK_DGRAM, 0))
981 .WillOnce(Return(kFd));
982 EXPECT_CALL(*mock_sockets_,
983 Ioctl(kFd, SIOCGIFHWADDR,
984 IfreqEquals(kTestDeviceIndex, kTestDeviceName)))
985 .WillOnce(DoAll(SetIfreq(ifr), Return(0)));
986 EXPECT_CALL(*mock_sockets_, Close(kFd));
987
Ben Chancd477322014-10-17 14:19:30 -0700988 unique_ptr<RTNLMessage> message(BuildLinkMessage(RTNLMessage::kModeAdd));
Gary Morain41780232012-07-31 15:08:31 -0700989 message->set_link_status(RTNLMessage::LinkStatus(0, IFF_LOWER_UP, 0));
990 SendMessageToDeviceInfo(*message);
991 EXPECT_TRUE(device_info_.GetDevice(kTestDeviceIndex).get());
992
993 ByteString mac_address =
994 device_info_.GetMACAddressFromKernel(kTestDeviceIndex);
995 EXPECT_THAT(kMacAddress,
996 ElementsAreArray(mac_address.GetData(), sizeof(kMacAddress)));
997}
998
Paul Stewart6950ba52013-12-05 08:28:14 -0800999TEST_F(DeviceInfoTest, GetMACAddressOfPeerUnknownDevice) {
1000 SetSockets();
1001 EXPECT_CALL(*mock_sockets_, Socket(PF_INET, SOCK_DGRAM, 0)).Times(0);
1002 IPAddress address(IPAddress::kFamilyIPv4);
1003 EXPECT_TRUE(address.SetAddressFromString(kTestIPAddress0));
1004 ByteString mac_address;
1005 EXPECT_FALSE(device_info_.GetDevice(kTestDeviceIndex).get());
1006 EXPECT_FALSE(device_info_.GetMACAddressOfPeer(
1007 kTestDeviceIndex, address, &mac_address));
1008}
1009
1010TEST_F(DeviceInfoTest, GetMACAddressOfPeerBadAddress) {
1011 SetSockets();
Ben Chancd477322014-10-17 14:19:30 -07001012 unique_ptr<RTNLMessage> message(BuildLinkMessage(RTNLMessage::kModeAdd));
Paul Stewart6950ba52013-12-05 08:28:14 -08001013 message->set_link_status(RTNLMessage::LinkStatus(0, IFF_LOWER_UP, 0));
1014 SendMessageToDeviceInfo(*message);
1015 EXPECT_TRUE(device_info_.GetDevice(kTestDeviceIndex).get());
1016
1017 EXPECT_CALL(*mock_sockets_, Socket(PF_INET, SOCK_DGRAM, 0)).Times(0);
1018
1019 // An improperly formatted IPv4 address should fail.
1020 IPAddress empty_ipv4_address(IPAddress::kFamilyIPv4);
1021 ByteString mac_address;
1022 EXPECT_FALSE(device_info_.GetMACAddressOfPeer(
1023 kTestDeviceIndex, empty_ipv4_address, &mac_address));
1024
1025 // IPv6 addresses are not supported.
1026 IPAddress valid_ipv6_address(IPAddress::kFamilyIPv6);
1027 EXPECT_TRUE(valid_ipv6_address.SetAddressFromString(kTestIPAddress1));
1028 EXPECT_FALSE(device_info_.GetMACAddressOfPeer(
1029 kTestDeviceIndex, valid_ipv6_address, &mac_address));
1030}
1031
1032TEST_F(DeviceInfoTest, GetMACAddressOfPeerUnableToOpenSocket) {
1033 SetSockets();
1034 EXPECT_CALL(*mock_sockets_, Socket(PF_INET, SOCK_DGRAM, 0))
1035 .WillOnce(Return(-1));
Ben Chancd477322014-10-17 14:19:30 -07001036 unique_ptr<RTNLMessage> message(BuildLinkMessage(RTNLMessage::kModeAdd));
Paul Stewart6950ba52013-12-05 08:28:14 -08001037 message->set_link_status(RTNLMessage::LinkStatus(0, IFF_LOWER_UP, 0));
1038 SendMessageToDeviceInfo(*message);
1039 IPAddress ip_address(IPAddress::kFamilyIPv4);
1040 EXPECT_TRUE(ip_address.SetAddressFromString(kTestIPAddress0));
1041 ByteString mac_address;
1042 EXPECT_FALSE(device_info_.GetMACAddressOfPeer(
1043 kTestDeviceIndex, ip_address, &mac_address));
1044}
1045
1046TEST_F(DeviceInfoTest, GetMACAddressOfPeerIoctlFails) {
1047 SetSockets();
1048 const int kFd = 99;
1049 EXPECT_CALL(*mock_sockets_, Socket(PF_INET, SOCK_DGRAM, 0))
1050 .WillOnce(Return(kFd));
1051 EXPECT_CALL(*mock_sockets_, Ioctl(kFd, SIOCGARP, NotNull()))
1052 .WillOnce(Return(-1));
Ben Chancd477322014-10-17 14:19:30 -07001053 unique_ptr<RTNLMessage> message(BuildLinkMessage(RTNLMessage::kModeAdd));
Paul Stewart6950ba52013-12-05 08:28:14 -08001054 message->set_link_status(RTNLMessage::LinkStatus(0, IFF_LOWER_UP, 0));
1055 SendMessageToDeviceInfo(*message);
1056 IPAddress ip_address(IPAddress::kFamilyIPv4);
1057 EXPECT_TRUE(ip_address.SetAddressFromString(kTestIPAddress0));
1058 ByteString mac_address;
1059 EXPECT_FALSE(device_info_.GetMACAddressOfPeer(
1060 kTestDeviceIndex, ip_address, &mac_address));
1061}
1062
1063MATCHER_P2(ArpreqEquals, ifname, peer, "") {
1064 const struct arpreq *const areq = static_cast<struct arpreq *>(arg);
Ben Chancc225ef2014-09-30 13:26:51 -07001065 if (areq == nullptr) {
Paul Stewart6950ba52013-12-05 08:28:14 -08001066 return false;
1067 }
1068
1069 const struct sockaddr_in *const protocol_address =
1070 reinterpret_cast<const struct sockaddr_in *>(&areq->arp_pa);
1071 const struct sockaddr_in *const hardware_address =
1072 reinterpret_cast<const struct sockaddr_in *>(&areq->arp_ha);
1073
1074 return
1075 strcmp(ifname, areq->arp_dev) == 0 &&
1076 protocol_address->sin_family == AF_INET &&
1077 memcmp(&protocol_address->sin_addr.s_addr,
1078 peer.address().GetConstData(),
1079 peer.address().GetLength()) == 0 &&
1080 hardware_address->sin_family == ARPHRD_ETHER;
1081}
1082
1083ACTION_P(SetArpreq, areq) {
1084 struct arpreq *const areq_arg = static_cast<struct arpreq *>(arg2);
1085 *areq_arg = areq;
1086}
1087
1088TEST_F(DeviceInfoTest, GetMACAddressOfPeer) {
Ben Chancd477322014-10-17 14:19:30 -07001089 unique_ptr<RTNLMessage> message(BuildLinkMessage(RTNLMessage::kModeAdd));
Paul Stewart6950ba52013-12-05 08:28:14 -08001090 message->set_link_status(RTNLMessage::LinkStatus(0, IFF_LOWER_UP, 0));
1091 SendMessageToDeviceInfo(*message);
1092
1093 SetSockets();
1094
1095 const int kFd = 99;
1096 EXPECT_CALL(*mock_sockets_, Socket(PF_INET, SOCK_DGRAM, 0))
1097 .WillRepeatedly(Return(kFd));
1098
1099 IPAddress ip_address(IPAddress::kFamilyIPv4);
1100 EXPECT_TRUE(ip_address.SetAddressFromString(kTestIPAddress0));
1101
1102 static uint8_t kZeroMacAddress[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
1103 struct arpreq zero_areq_response;
1104 memcpy(zero_areq_response.arp_ha.sa_data, kZeroMacAddress,
1105 sizeof(kZeroMacAddress));
1106
1107 static uint8_t kMacAddress[] = {0x01, 0x02, 0x03, 0xaa, 0xbb, 0xcc};
1108 struct arpreq areq_response;
1109 memcpy(areq_response.arp_ha.sa_data, kMacAddress, sizeof(kMacAddress));
1110
1111 EXPECT_CALL(*mock_sockets_, Ioctl(
1112 kFd, SIOCGARP, ArpreqEquals(kTestDeviceName, ip_address)))
1113 .WillOnce(DoAll(SetArpreq(zero_areq_response), Return(0)))
1114 .WillOnce(DoAll(SetArpreq(areq_response), Return(0)));
1115
1116 ByteString mac_address;
1117 EXPECT_FALSE(device_info_.GetMACAddressOfPeer(
1118 kTestDeviceIndex, ip_address, &mac_address));
1119 EXPECT_TRUE(device_info_.GetMACAddressOfPeer(
1120 kTestDeviceIndex, ip_address, &mac_address));
1121 EXPECT_THAT(kMacAddress,
1122 ElementsAreArray(mac_address.GetData(), sizeof(kMacAddress)));
1123}
1124
Paul Stewartd55f6ae2014-04-24 16:34:21 -07001125TEST_F(DeviceInfoTest, IPv6AddressChanged) {
1126 scoped_refptr<MockDevice> device(new MockDevice(
1127 &control_interface_, &dispatcher_, &metrics_, &manager_,
1128 "null0", "addr0", kTestDeviceIndex));
1129
1130 // Device info entry does not exist.
Ben Chancc225ef2014-09-30 13:26:51 -07001131 EXPECT_FALSE(device_info_.GetPrimaryIPv6Address(kTestDeviceIndex, nullptr));
Paul Stewartd55f6ae2014-04-24 16:34:21 -07001132
1133 device_info_.infos_[kTestDeviceIndex].device = device;
1134
1135 // Device info entry contains no addresses.
Ben Chancc225ef2014-09-30 13:26:51 -07001136 EXPECT_FALSE(device_info_.GetPrimaryIPv6Address(kTestDeviceIndex, nullptr));
Paul Stewartd55f6ae2014-04-24 16:34:21 -07001137
1138 IPAddress ipv4_address(IPAddress::kFamilyIPv4);
1139 EXPECT_TRUE(ipv4_address.SetAddressFromString(kTestIPAddress0));
Ben Chancd477322014-10-17 14:19:30 -07001140 unique_ptr<RTNLMessage> message(
1141 BuildAddressMessage(RTNLMessage::kModeAdd, ipv4_address, 0, 0));
Paul Stewartd55f6ae2014-04-24 16:34:21 -07001142
1143 EXPECT_CALL(*device, OnIPv6AddressChanged()).Times(0);
1144
1145 // We should ignore IPv4 addresses.
1146 SendMessageToDeviceInfo(*message);
Ben Chancc225ef2014-09-30 13:26:51 -07001147 EXPECT_FALSE(device_info_.GetPrimaryIPv6Address(kTestDeviceIndex, nullptr));
Paul Stewartd55f6ae2014-04-24 16:34:21 -07001148
1149 IPAddress ipv6_address1(IPAddress::kFamilyIPv6);
1150 EXPECT_TRUE(ipv6_address1.SetAddressFromString(kTestIPAddress1));
1151 message.reset(BuildAddressMessage(
1152 RTNLMessage::kModeAdd, ipv6_address1, 0, RT_SCOPE_LINK));
1153
1154 // We should ignore non-SCOPE_UNIVERSE messages for IPv6.
1155 SendMessageToDeviceInfo(*message);
Ben Chancc225ef2014-09-30 13:26:51 -07001156 EXPECT_FALSE(device_info_.GetPrimaryIPv6Address(kTestDeviceIndex, nullptr));
Paul Stewartd55f6ae2014-04-24 16:34:21 -07001157
1158 Mock::VerifyAndClearExpectations(device);
1159 IPAddress ipv6_address2(IPAddress::kFamilyIPv6);
1160 EXPECT_TRUE(ipv6_address2.SetAddressFromString(kTestIPAddress2));
1161 message.reset(BuildAddressMessage(
1162 RTNLMessage::kModeAdd, ipv6_address2, IFA_F_TEMPORARY,
1163 RT_SCOPE_UNIVERSE));
1164
1165 // Add a temporary address.
1166 EXPECT_CALL(*device, OnIPv6AddressChanged());
1167 SendMessageToDeviceInfo(*message);
1168 IPAddress address0(IPAddress::kFamilyUnknown);
1169 EXPECT_TRUE(device_info_.GetPrimaryIPv6Address(kTestDeviceIndex, &address0));
1170 EXPECT_TRUE(address0.Equals(ipv6_address2));
1171 Mock::VerifyAndClearExpectations(device);
1172
1173 IPAddress ipv6_address3(IPAddress::kFamilyIPv6);
1174 EXPECT_TRUE(ipv6_address3.SetAddressFromString(kTestIPAddress3));
1175 message.reset(BuildAddressMessage(
1176 RTNLMessage::kModeAdd, ipv6_address3, 0, RT_SCOPE_UNIVERSE));
1177
1178 // Adding a non-temporary address alerts the Device, but does not override
1179 // the primary address since the previous one was temporary.
1180 EXPECT_CALL(*device, OnIPv6AddressChanged());
1181 SendMessageToDeviceInfo(*message);
1182 IPAddress address1(IPAddress::kFamilyUnknown);
1183 EXPECT_TRUE(device_info_.GetPrimaryIPv6Address(kTestDeviceIndex, &address1));
1184 EXPECT_TRUE(address1.Equals(ipv6_address2));
1185 Mock::VerifyAndClearExpectations(device);
1186
1187 IPAddress ipv6_address4(IPAddress::kFamilyIPv6);
1188 EXPECT_TRUE(ipv6_address4.SetAddressFromString(kTestIPAddress4));
1189 message.reset(BuildAddressMessage(
1190 RTNLMessage::kModeAdd, ipv6_address4, IFA_F_TEMPORARY,
1191 RT_SCOPE_UNIVERSE));
1192
1193 // Another temporary address alerts the Device, and will override
1194 // the primary address.
1195 EXPECT_CALL(*device, OnIPv6AddressChanged());
1196 SendMessageToDeviceInfo(*message);
1197 IPAddress address2(IPAddress::kFamilyUnknown);
1198 EXPECT_TRUE(device_info_.GetPrimaryIPv6Address(kTestDeviceIndex, &address2));
1199 EXPECT_TRUE(address2.Equals(ipv6_address4));
1200}
1201
Peter Qiu98551702014-07-28 13:28:53 -07001202
1203TEST_F(DeviceInfoTest, IPv6DnsServerAddressesChanged) {
1204 scoped_refptr<MockDevice> device(new MockDevice(
1205 &control_interface_, &dispatcher_, &metrics_, &manager_,
1206 "null0", "addr0", kTestDeviceIndex));
1207 device_info_.time_ = &time_;
1208 vector<IPAddress> dns_server_addresses_out;
Ben Chan7fab8972014-08-10 17:14:46 -07001209 uint32_t lifetime_out;
Peter Qiu98551702014-07-28 13:28:53 -07001210
1211 // Device info entry does not exist.
1212 EXPECT_FALSE(device_info_.GetIPv6DnsServerAddresses(
1213 kTestDeviceIndex, &dns_server_addresses_out, &lifetime_out));
1214
1215 device_info_.infos_[kTestDeviceIndex].device = device;
1216
1217 // Device info entry contains no IPv6 dns server addresses.
1218 EXPECT_FALSE(device_info_.GetIPv6DnsServerAddresses(
1219 kTestDeviceIndex, &dns_server_addresses_out, &lifetime_out));
1220
1221 // Setup IPv6 dns server addresses.
1222 IPAddress ipv6_address1(IPAddress::kFamilyIPv6);
1223 IPAddress ipv6_address2(IPAddress::kFamilyIPv6);
1224 EXPECT_TRUE(ipv6_address1.SetAddressFromString(kTestIPAddress1));
1225 EXPECT_TRUE(ipv6_address2.SetAddressFromString(kTestIPAddress2));
1226 vector<IPAddress> dns_server_addresses_in;
1227 dns_server_addresses_in.push_back(ipv6_address1);
1228 dns_server_addresses_in.push_back(ipv6_address2);
1229
1230 // Infinite lifetime
Ben Chan7fab8972014-08-10 17:14:46 -07001231 const uint32_t kInfiniteLifetime = 0xffffffff;
Ben Chancd477322014-10-17 14:19:30 -07001232 unique_ptr<RTNLMessage> message(BuildRdnssMessage(
1233 RTNLMessage::kModeAdd, kInfiniteLifetime, dns_server_addresses_in));
Peter Qiu98551702014-07-28 13:28:53 -07001234 EXPECT_CALL(time_, GetSecondsBoottime(_)).
1235 WillOnce(DoAll(SetArgPointee<0>(0), Return(true)));
1236 EXPECT_CALL(*device, OnIPv6DnsServerAddressesChanged()).Times(1);
1237 SendMessageToDeviceInfo(*message);
1238 EXPECT_CALL(time_, GetSecondsBoottime(_)).Times(0);
1239 EXPECT_TRUE(device_info_.GetIPv6DnsServerAddresses(
1240 kTestDeviceIndex, &dns_server_addresses_out, &lifetime_out));
1241 // Verify addresses and lifetime.
1242 EXPECT_EQ(kInfiniteLifetime, lifetime_out);
1243 EXPECT_EQ(2, dns_server_addresses_out.size());
1244 EXPECT_EQ(kTestIPAddress1, dns_server_addresses_out.at(0).ToString());
1245 EXPECT_EQ(kTestIPAddress2, dns_server_addresses_out.at(1).ToString());
1246
1247 // Lifetime of 120, retrieve DNS server addresses after 10 seconds.
Ben Chan7fab8972014-08-10 17:14:46 -07001248 const uint32_t kLifetime120 = 120;
1249 const uint32_t kElapseTime10 = 10;
Ben Chancd477322014-10-17 14:19:30 -07001250 unique_ptr<RTNLMessage> message1(BuildRdnssMessage(
1251 RTNLMessage::kModeAdd, kLifetime120, dns_server_addresses_in));
Peter Qiu98551702014-07-28 13:28:53 -07001252 EXPECT_CALL(time_, GetSecondsBoottime(_)).
1253 WillOnce(DoAll(SetArgPointee<0>(0), Return(true)));
1254 EXPECT_CALL(*device, OnIPv6DnsServerAddressesChanged()).Times(1);
1255 SendMessageToDeviceInfo(*message1);
1256 // 10 seconds passed when GetIPv6DnsServerAddreses is called.
1257 EXPECT_CALL(time_, GetSecondsBoottime(_)).
1258 WillOnce(DoAll(SetArgPointee<0>(kElapseTime10), Return(true)));
1259 EXPECT_TRUE(device_info_.GetIPv6DnsServerAddresses(
1260 kTestDeviceIndex, &dns_server_addresses_out, &lifetime_out));
1261 // Verify addresses and lifetime.
1262 EXPECT_EQ(kLifetime120 - kElapseTime10, lifetime_out);
1263 EXPECT_EQ(2, dns_server_addresses_out.size());
1264 EXPECT_EQ(kTestIPAddress1, dns_server_addresses_out.at(0).ToString());
1265 EXPECT_EQ(kTestIPAddress2, dns_server_addresses_out.at(1).ToString());
1266
1267 // Lifetime of 120, retrieve DNS server addresses after lifetime expired.
1268 EXPECT_CALL(time_, GetSecondsBoottime(_)).
1269 WillOnce(DoAll(SetArgPointee<0>(0), Return(true)));
1270 EXPECT_CALL(*device, OnIPv6DnsServerAddressesChanged()).Times(1);
1271 SendMessageToDeviceInfo(*message1);
1272 // 120 seconds passed when GetIPv6DnsServerAddreses is called.
1273 EXPECT_CALL(time_, GetSecondsBoottime(_)).
1274 WillOnce(DoAll(SetArgPointee<0>(kLifetime120), Return(true)));
1275 EXPECT_TRUE(device_info_.GetIPv6DnsServerAddresses(
1276 kTestDeviceIndex, &dns_server_addresses_out, &lifetime_out));
1277 // Verify addresses and lifetime.
1278 EXPECT_EQ(0, lifetime_out);
1279 EXPECT_EQ(2, dns_server_addresses_out.size());
1280 EXPECT_EQ(kTestIPAddress1, dns_server_addresses_out.at(0).ToString());
1281 EXPECT_EQ(kTestIPAddress2, dns_server_addresses_out.at(1).ToString());
1282}
1283
Paul Stewartca876ee2012-04-21 08:55:58 -07001284class DeviceInfoTechnologyTest : public DeviceInfoTest {
1285 public:
Jason Glasgowabc54032012-04-20 16:08:32 -04001286 DeviceInfoTechnologyTest()
1287 : DeviceInfoTest(),
1288 test_device_name_(kTestDeviceName) {}
Paul Stewartca876ee2012-04-21 08:55:58 -07001289 virtual ~DeviceInfoTechnologyTest() {}
1290
1291 virtual void SetUp() {
mukesh agrawal62ba51c2014-04-18 16:09:58 -07001292 CHECK(temp_dir_.CreateUniqueTempDir());
Paul Stewartca876ee2012-04-21 08:55:58 -07001293 device_info_root_ = temp_dir_.path().Append("sys/class/net");
1294 device_info_.device_info_root_ = device_info_root_;
1295 // Most tests require that the uevent file exist.
1296 CreateInfoFile("uevent", "xxx");
1297 }
1298
1299 Technology::Identifier GetDeviceTechnology() {
Jason Glasgowabc54032012-04-20 16:08:32 -04001300 return device_info_.GetDeviceTechnology(test_device_name_);
Paul Stewartca876ee2012-04-21 08:55:58 -07001301 }
1302 FilePath GetInfoPath(const string &name);
1303 void CreateInfoFile(const string &name, const string &contents);
1304 void CreateInfoSymLink(const string &name, const string &contents);
Jason Glasgowabc54032012-04-20 16:08:32 -04001305 void SetDeviceName(const string &name) {
1306 test_device_name_ = name;
mukesh agrawal62ba51c2014-04-18 16:09:58 -07001307 EXPECT_TRUE(temp_dir_.Delete()); // nuke old temp dir
Jason Glasgowabc54032012-04-20 16:08:32 -04001308 SetUp();
1309 }
Paul Stewartca876ee2012-04-21 08:55:58 -07001310
1311 protected:
Paul Stewart5ad16062013-02-21 18:10:48 -08001312 base::ScopedTempDir temp_dir_;
Paul Stewartca876ee2012-04-21 08:55:58 -07001313 FilePath device_info_root_;
Jason Glasgowabc54032012-04-20 16:08:32 -04001314 string test_device_name_;
Paul Stewartca876ee2012-04-21 08:55:58 -07001315};
1316
1317FilePath DeviceInfoTechnologyTest::GetInfoPath(const string &name) {
Jason Glasgowabc54032012-04-20 16:08:32 -04001318 return device_info_root_.Append(test_device_name_).Append(name);
Paul Stewartca876ee2012-04-21 08:55:58 -07001319}
1320
1321void DeviceInfoTechnologyTest::CreateInfoFile(const string &name,
1322 const string &contents) {
1323 FilePath info_path = GetInfoPath(name);
Ben Chana0ddf462014-02-06 11:32:42 -08001324 EXPECT_TRUE(base::CreateDirectory(info_path.DirName()));
Paul Stewartca876ee2012-04-21 08:55:58 -07001325 string contents_newline(contents + "\n");
Ben Chan6fbf64f2014-05-21 18:07:01 -07001326 EXPECT_TRUE(base::WriteFile(info_path, contents_newline.c_str(),
1327 contents_newline.size()));
Paul Stewartca876ee2012-04-21 08:55:58 -07001328}
1329
1330void DeviceInfoTechnologyTest::CreateInfoSymLink(const string &name,
1331 const string &contents) {
1332 FilePath info_path = GetInfoPath(name);
Ben Chana0ddf462014-02-06 11:32:42 -08001333 EXPECT_TRUE(base::CreateDirectory(info_path.DirName()));
1334 EXPECT_TRUE(base::CreateSymbolicLink(FilePath(contents), info_path));
Paul Stewartca876ee2012-04-21 08:55:58 -07001335}
1336
1337TEST_F(DeviceInfoTechnologyTest, Unknown) {
Paul Stewartda8cbee2014-10-20 11:44:03 -07001338 // With a uevent file but no driver symlink, we should act as if this
1339 // is a regular Ethernet driver.
1340 EXPECT_EQ(Technology::kEthernet, GetDeviceTechnology());
1341
1342 // Should be unknown without a uevent file.
Ben Chana0ddf462014-02-06 11:32:42 -08001343 EXPECT_TRUE(base::DeleteFile(GetInfoPath("uevent"), false));
Paul Stewartca876ee2012-04-21 08:55:58 -07001344 EXPECT_EQ(Technology::kUnknown, GetDeviceTechnology());
1345}
1346
1347TEST_F(DeviceInfoTechnologyTest, Loopback) {
1348 CreateInfoFile("type", base::IntToString(ARPHRD_LOOPBACK));
1349 EXPECT_EQ(Technology::kLoopback, GetDeviceTechnology());
1350}
1351
1352TEST_F(DeviceInfoTechnologyTest, PPP) {
1353 CreateInfoFile("type", base::IntToString(ARPHRD_PPP));
1354 EXPECT_EQ(Technology::kPPP, GetDeviceTechnology());
1355}
1356
1357TEST_F(DeviceInfoTechnologyTest, Tunnel) {
1358 CreateInfoFile("tun_flags", base::IntToString(IFF_TUN));
1359 EXPECT_EQ(Technology::kTunnel, GetDeviceTechnology());
1360}
1361
1362TEST_F(DeviceInfoTechnologyTest, WiFi) {
1363 CreateInfoFile("uevent", "DEVTYPE=wlan");
1364 EXPECT_EQ(Technology::kWifi, GetDeviceTechnology());
1365 CreateInfoFile("uevent", "foo\nDEVTYPE=wlan");
1366 EXPECT_EQ(Technology::kWifi, GetDeviceTechnology());
1367 CreateInfoFile("type", base::IntToString(ARPHRD_IEEE80211_RADIOTAP));
1368 EXPECT_EQ(Technology::kWiFiMonitor, GetDeviceTechnology());
1369}
1370
1371TEST_F(DeviceInfoTechnologyTest, Ethernet) {
1372 CreateInfoSymLink("device/driver", "xxx");
1373 EXPECT_EQ(Technology::kEthernet, GetDeviceTechnology());
1374}
1375
Darin Petkove4b27022012-05-16 13:28:50 +02001376TEST_F(DeviceInfoTechnologyTest, WiMax) {
1377 CreateInfoSymLink("device/driver", "gdm_wimax");
1378 EXPECT_EQ(Technology::kWiMax, GetDeviceTechnology());
1379}
1380
Paul Stewartca876ee2012-04-21 08:55:58 -07001381TEST_F(DeviceInfoTechnologyTest, CellularGobi1) {
1382 CreateInfoSymLink("device/driver", "blah/foo/gobi");
1383 EXPECT_EQ(Technology::kCellular, GetDeviceTechnology());
1384}
1385
1386TEST_F(DeviceInfoTechnologyTest, CellularGobi2) {
1387 CreateInfoSymLink("device/driver", "../GobiNet");
1388 EXPECT_EQ(Technology::kCellular, GetDeviceTechnology());
1389}
1390
1391TEST_F(DeviceInfoTechnologyTest, QCUSB) {
1392 CreateInfoSymLink("device/driver", "QCUSBNet2k");
1393 EXPECT_EQ(Technology::kCellular, GetDeviceTechnology());
1394}
1395
Ben Chan0f90e0b2013-06-26 23:37:16 -07001396TEST_F(DeviceInfoTechnologyTest, CellularCdcMbim) {
1397 CreateInfoSymLink("device/driver", "cdc_mbim");
1398 EXPECT_EQ(Technology::kCellular, GetDeviceTechnology());
1399}
1400
Ben Chan226d46a2012-10-11 00:22:17 -07001401TEST_F(DeviceInfoTechnologyTest, CellularQmiWwan) {
1402 CreateInfoSymLink("device/driver", "qmi_wwan");
1403 EXPECT_EQ(Technology::kCellular, GetDeviceTechnology());
1404}
1405
Paul Stewartca876ee2012-04-21 08:55:58 -07001406// Modem with absolute driver path with top-level tty file:
1407// /sys/class/net/dev0/device -> /sys/devices/virtual/0/00
Ben Chan4eb4ddf2013-06-20 22:16:56 -07001408// /sys/devices/virtual/0/00/driver -> /drivers/cdc_ether or /drivers/cdc_ncm
Paul Stewartca876ee2012-04-21 08:55:58 -07001409// /sys/devices/virtual/0/01/tty [empty directory]
Ben Chan4eb4ddf2013-06-20 22:16:56 -07001410TEST_F(DeviceInfoTechnologyTest, CDCEthernetModem1) {
Paul Stewartca876ee2012-04-21 08:55:58 -07001411 FilePath device_root(temp_dir_.path().Append("sys/devices/virtual/0"));
1412 FilePath device_path(device_root.Append("00"));
Ben Chan4eb4ddf2013-06-20 22:16:56 -07001413 FilePath driver_symlink(device_path.Append("driver"));
Ben Chana0ddf462014-02-06 11:32:42 -08001414 EXPECT_TRUE(base::CreateDirectory(device_path));
Paul Stewartca876ee2012-04-21 08:55:58 -07001415 CreateInfoSymLink("device", device_path.value());
Ben Chana0ddf462014-02-06 11:32:42 -08001416 EXPECT_TRUE(base::CreateSymbolicLink(FilePath("/drivers/cdc_ether"),
1417 driver_symlink));
1418 EXPECT_TRUE(base::CreateDirectory(device_root.Append("01/tty")));
Paul Stewartca876ee2012-04-21 08:55:58 -07001419 EXPECT_EQ(Technology::kCellular, GetDeviceTechnology());
Ben Chan4eb4ddf2013-06-20 22:16:56 -07001420
Ben Chana0ddf462014-02-06 11:32:42 -08001421 EXPECT_TRUE(base::DeleteFile(driver_symlink, false));
1422 EXPECT_TRUE(base::CreateSymbolicLink(FilePath("/drivers/cdc_ncm"),
1423 driver_symlink));
Ben Chan4eb4ddf2013-06-20 22:16:56 -07001424 EXPECT_EQ(Technology::kCellular, GetDeviceTechnology());
Paul Stewartca876ee2012-04-21 08:55:58 -07001425}
1426
1427// Modem with relative driver path with top-level tty file.
1428// /sys/class/net/dev0/device -> ../../../device_dir/0/00
Ben Chan4eb4ddf2013-06-20 22:16:56 -07001429// /sys/device_dir/0/00/driver -> /drivers/cdc_ether or /drivers/cdc_ncm
Paul Stewartca876ee2012-04-21 08:55:58 -07001430// /sys/device_dir/0/01/tty [empty directory]
Ben Chan4eb4ddf2013-06-20 22:16:56 -07001431TEST_F(DeviceInfoTechnologyTest, CDCEthernetModem2) {
Paul Stewartca876ee2012-04-21 08:55:58 -07001432 CreateInfoSymLink("device", "../../../device_dir/0/00");
1433 FilePath device_root(temp_dir_.path().Append("sys/device_dir/0"));
1434 FilePath device_path(device_root.Append("00"));
Ben Chan4eb4ddf2013-06-20 22:16:56 -07001435 FilePath driver_symlink(device_path.Append("driver"));
Ben Chana0ddf462014-02-06 11:32:42 -08001436 EXPECT_TRUE(base::CreateDirectory(device_path));
1437 EXPECT_TRUE(base::CreateSymbolicLink(FilePath("/drivers/cdc_ether"),
1438 driver_symlink));
1439 EXPECT_TRUE(base::CreateDirectory(device_root.Append("01/tty")));
Paul Stewartca876ee2012-04-21 08:55:58 -07001440 EXPECT_EQ(Technology::kCellular, GetDeviceTechnology());
Ben Chan4eb4ddf2013-06-20 22:16:56 -07001441
Ben Chana0ddf462014-02-06 11:32:42 -08001442 EXPECT_TRUE(base::DeleteFile(driver_symlink, false));
1443 EXPECT_TRUE(base::CreateSymbolicLink(FilePath("/drivers/cdc_ncm"),
1444 driver_symlink));
Ben Chan4eb4ddf2013-06-20 22:16:56 -07001445 EXPECT_EQ(Technology::kCellular, GetDeviceTechnology());
Paul Stewartca876ee2012-04-21 08:55:58 -07001446}
1447
1448// Modem with relative driver path with lower-level tty file.
1449// /sys/class/net/dev0/device -> ../../../device_dir/0/00
Ben Chan4eb4ddf2013-06-20 22:16:56 -07001450// /sys/device_dir/0/00/driver -> /drivers/cdc_ether or /drivers/cdc_ncm
Paul Stewartca876ee2012-04-21 08:55:58 -07001451// /sys/device_dir/0/01/yyy/tty [empty directory]
Ben Chan4eb4ddf2013-06-20 22:16:56 -07001452TEST_F(DeviceInfoTechnologyTest, CDCEthernetModem3) {
Paul Stewartca876ee2012-04-21 08:55:58 -07001453 CreateInfoSymLink("device", "../../../device_dir/0/00");
1454 FilePath device_root(temp_dir_.path().Append("sys/device_dir/0"));
1455 FilePath device_path(device_root.Append("00"));
Ben Chan4eb4ddf2013-06-20 22:16:56 -07001456 FilePath driver_symlink(device_path.Append("driver"));
Ben Chana0ddf462014-02-06 11:32:42 -08001457 EXPECT_TRUE(base::CreateDirectory(device_path));
1458 EXPECT_TRUE(base::CreateSymbolicLink(FilePath("/drivers/cdc_ether"),
1459 driver_symlink));
1460 EXPECT_TRUE(base::CreateDirectory(device_root.Append("01/yyy/tty")));
Paul Stewartca876ee2012-04-21 08:55:58 -07001461 EXPECT_EQ(Technology::kCellular, GetDeviceTechnology());
Ben Chan4eb4ddf2013-06-20 22:16:56 -07001462
Ben Chana0ddf462014-02-06 11:32:42 -08001463 EXPECT_TRUE(base::DeleteFile(driver_symlink, false));
1464 EXPECT_TRUE(base::CreateSymbolicLink(FilePath("/drivers/cdc_ncm"),
1465 driver_symlink));
Ben Chan4eb4ddf2013-06-20 22:16:56 -07001466 EXPECT_EQ(Technology::kCellular, GetDeviceTechnology());
Paul Stewartca876ee2012-04-21 08:55:58 -07001467}
1468
1469TEST_F(DeviceInfoTechnologyTest, CDCEtherNonModem) {
1470 CreateInfoSymLink("device", "device_dir");
1471 CreateInfoSymLink("device_dir/driver", "cdc_ether");
Paul Stewart050cfc02012-07-06 20:38:54 -07001472 EXPECT_EQ(Technology::kCDCEthernet, GetDeviceTechnology());
Paul Stewartca876ee2012-04-21 08:55:58 -07001473}
1474
Ben Chan4eb4ddf2013-06-20 22:16:56 -07001475TEST_F(DeviceInfoTechnologyTest, CDCNcmNonModem) {
1476 CreateInfoSymLink("device", "device_dir");
1477 CreateInfoSymLink("device_dir/driver", "cdc_ncm");
1478 EXPECT_EQ(Technology::kCDCEthernet, GetDeviceTechnology());
1479}
1480
Jason Glasgowabc54032012-04-20 16:08:32 -04001481TEST_F(DeviceInfoTechnologyTest, PseudoModem) {
1482 SetDeviceName("pseudomodem");
1483 CreateInfoSymLink("device", "device_dir");
1484 CreateInfoSymLink("device_dir/driver", "cdc_ether");
1485 EXPECT_EQ(Technology::kCellular, GetDeviceTechnology());
1486
1487 SetDeviceName("pseudomodem9");
1488 CreateInfoSymLink("device", "device_dir");
1489 CreateInfoSymLink("device_dir/driver", "cdc_ether");
1490 EXPECT_EQ(Technology::kCellular, GetDeviceTechnology());
1491}
1492
Paul Stewart050cfc02012-07-06 20:38:54 -07001493class DeviceInfoForDelayedCreationTest : public DeviceInfo {
1494 public:
1495 DeviceInfoForDelayedCreationTest(ControlInterface *control_interface,
1496 EventDispatcher *dispatcher,
1497 Metrics *metrics,
1498 Manager *manager)
1499 : DeviceInfo(control_interface, dispatcher, metrics, manager) {}
1500 MOCK_METHOD4(CreateDevice, DeviceRefPtr(const std::string &link_name,
1501 const std::string &address,
1502 int interface_index,
1503 Technology::Identifier technology));
1504 MOCK_METHOD1(GetDeviceTechnology,
1505 Technology::Identifier(const string &iface_name));
1506};
1507
1508class DeviceInfoDelayedCreationTest : public DeviceInfoTest {
1509 public:
1510 DeviceInfoDelayedCreationTest()
1511 : DeviceInfoTest(),
1512 test_device_info_(
1513 &control_interface_, &dispatcher_, &metrics_, &manager_) {}
1514 virtual ~DeviceInfoDelayedCreationTest() {}
1515
1516 virtual std::set<int> &GetDelayedDevices() {
1517 return test_device_info_.delayed_devices_;
1518 }
1519
1520 void DelayedDeviceCreationTask() {
1521 test_device_info_.DelayedDeviceCreationTask();
1522 }
1523
1524 void AddDelayedDevice() {
Ben Chancd477322014-10-17 14:19:30 -07001525 unique_ptr<RTNLMessage> message(BuildLinkMessage(RTNLMessage::kModeAdd));
Paul Stewart050cfc02012-07-06 20:38:54 -07001526 EXPECT_CALL(test_device_info_, GetDeviceTechnology(kTestDeviceName))
1527 .WillOnce(Return(Technology::kCDCEthernet));
1528 EXPECT_CALL(test_device_info_, CreateDevice(
1529 kTestDeviceName, _, kTestDeviceIndex, Technology::kCDCEthernet))
1530 .WillOnce(Return(DeviceRefPtr()));
1531 test_device_info_.AddLinkMsgHandler(*message);
1532 Mock::VerifyAndClearExpectations(&test_device_info_);
1533 // We need to insert the device index ourselves since we have mocked
1534 // out CreateDevice. This insertion is tested in CreateDeviceCDCEthernet
1535 // above.
1536 GetDelayedDevices().insert(kTestDeviceIndex);
1537 }
1538
Wade Guthrie7347bf22013-04-30 11:21:51 -07001539 void TriggerOnWiFiInterfaceInfoReceived(const Nl80211Message &message) {
Paul Stewart2ddf2c62013-04-16 09:47:34 -07001540 test_device_info_.OnWiFiInterfaceInfoReceived(message);
1541 }
1542
Paul Stewart050cfc02012-07-06 20:38:54 -07001543 protected:
1544 DeviceInfoForDelayedCreationTest test_device_info_;
1545};
1546
1547TEST_F(DeviceInfoDelayedCreationTest, NoDevices) {
1548 EXPECT_TRUE(GetDelayedDevices().empty());
1549 EXPECT_CALL(test_device_info_, GetDeviceTechnology(_)).Times(0);
1550 DelayedDeviceCreationTask();
1551}
1552
1553TEST_F(DeviceInfoDelayedCreationTest, EthernetDevice) {
1554 AddDelayedDevice();
1555 EXPECT_CALL(test_device_info_, GetDeviceTechnology(_))
1556 .WillOnce(Return(Technology::kCDCEthernet));
1557 EXPECT_CALL(test_device_info_, CreateDevice(
1558 kTestDeviceName, _, kTestDeviceIndex, Technology::kEthernet))
1559 .WillOnce(Return(DeviceRefPtr()));
1560 DelayedDeviceCreationTask();
1561 EXPECT_TRUE(GetDelayedDevices().empty());
1562}
1563
1564TEST_F(DeviceInfoDelayedCreationTest, CellularDevice) {
1565 AddDelayedDevice();
1566 EXPECT_CALL(test_device_info_, GetDeviceTechnology(_))
1567 .WillOnce(Return(Technology::kCellular));
1568 EXPECT_CALL(test_device_info_, CreateDevice(
1569 kTestDeviceName, _, kTestDeviceIndex, Technology::kCellular))
1570 .WillOnce(Return(DeviceRefPtr()));
1571 DelayedDeviceCreationTask();
1572 EXPECT_TRUE(GetDelayedDevices().empty());
1573}
1574
Paul Stewart2ddf2c62013-04-16 09:47:34 -07001575TEST_F(DeviceInfoDelayedCreationTest, WiFiDevice) {
1576 ScopedMockLog log;
Paul Stewart2ddf2c62013-04-16 09:47:34 -07001577 EXPECT_CALL(log, Log(logging::LOG_ERROR, _,
1578 HasSubstr("Message is not a new interface response")));
1579 GetInterfaceMessage non_interface_response_message;
1580 TriggerOnWiFiInterfaceInfoReceived(non_interface_response_message);
1581 Mock::VerifyAndClearExpectations(&log);
1582
1583 EXPECT_CALL(log, Log(logging::LOG_ERROR, _,
1584 HasSubstr("Message contains no interface index")));
1585 NewInterfaceMessage message;
1586 TriggerOnWiFiInterfaceInfoReceived(message);
1587 Mock::VerifyAndClearExpectations(&log);
1588
1589 message.attributes()->CreateAttribute(
1590 NL80211_ATTR_IFINDEX, base::Bind(
1591 &NetlinkAttribute::NewNl80211AttributeFromId));
1592 message.attributes()->SetU32AttributeValue(NL80211_ATTR_IFINDEX,
1593 kTestDeviceIndex);
1594 EXPECT_CALL(log, Log(logging::LOG_ERROR, _,
1595 HasSubstr("Message contains no interface type")));
1596 TriggerOnWiFiInterfaceInfoReceived(message);
1597 Mock::VerifyAndClearExpectations(&log);
1598
1599 message.attributes()->CreateAttribute(
1600 NL80211_ATTR_IFTYPE, base::Bind(
1601 &NetlinkAttribute::NewNl80211AttributeFromId));
1602 message.attributes()->SetU32AttributeValue(NL80211_ATTR_IFTYPE,
1603 NL80211_IFTYPE_AP);
1604 EXPECT_CALL(log, Log(logging::LOG_ERROR, _,
1605 HasSubstr("Could not find device info for interface")));
1606 TriggerOnWiFiInterfaceInfoReceived(message);
1607 Mock::VerifyAndClearExpectations(&log);
1608
1609 // Use the AddDelayedDevice() method to create a device info entry with no
1610 // associated device.
1611 AddDelayedDevice();
1612
1613 EXPECT_CALL(log, Log(logging::LOG_INFO, _,
1614 HasSubstr("it is not in station mode")));
1615 TriggerOnWiFiInterfaceInfoReceived(message);
1616 Mock::VerifyAndClearExpectations(&log);
1617 Mock::VerifyAndClearExpectations(&manager_);
1618
1619 message.attributes()->SetU32AttributeValue(NL80211_ATTR_IFTYPE,
1620 NL80211_IFTYPE_STATION);
1621 EXPECT_CALL(manager_, RegisterDevice(_));
1622 EXPECT_CALL(manager_, device_info())
1623 .WillRepeatedly(Return(&test_device_info_));
1624 EXPECT_CALL(log, Log(_, _, _)).Times(AnyNumber());
1625 EXPECT_CALL(log, Log(logging::LOG_INFO, _,
1626 HasSubstr("Creating WiFi device")));
1627 TriggerOnWiFiInterfaceInfoReceived(message);
1628 Mock::VerifyAndClearExpectations(&log);
1629 Mock::VerifyAndClearExpectations(&manager_);
1630
1631 EXPECT_CALL(manager_, RegisterDevice(_)).Times(0);
1632 EXPECT_CALL(log, Log(logging::LOG_ERROR, _,
1633 HasSubstr("Device already created for interface")));
1634 TriggerOnWiFiInterfaceInfoReceived(message);
1635}
1636
Chris Masone9be4a9d2011-05-16 15:44:09 -07001637} // namespace shill