blob: d8a0d94ab28234026f42669ab64b61021961c1e2 [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
Ben Chanc54afe52014-11-05 10:28:08 -080028#include "shill/cellular/mock_modem_info.h"
Christopher Wileyb691efd2012-08-09 13:51:51 -070029#include "shill/logging.h"
Paul Stewartb50f0b92011-05-16 16:31:42 -070030#include "shill/manager.h"
Chris Masone46eaaf52011-05-24 13:08:30 -070031#include "shill/mock_control.h"
Ben Chan5086b972013-01-15 21:51:38 -080032#include "shill/mock_device.h"
Darin Petkovafa6fc42011-06-21 16:21:08 -070033#include "shill/mock_glib.h"
Paul Stewart2ddf2c62013-04-16 09:47:34 -070034#include "shill/mock_log.h"
Chris Masone2ae797d2011-08-23 20:41:00 -070035#include "shill/mock_manager.h"
Thieu Le3426c8f2012-01-11 17:35:11 -080036#include "shill/mock_metrics.h"
Paul Stewart8c116a92012-05-02 18:30:03 -070037#include "shill/mock_routing_table.h"
Peter Qiu8d6b5972014-10-28 15:33:34 -070038#include "shill/net/ip_address.h"
39#include "shill/net/mock_rtnl_handler.h"
40#include "shill/net/mock_sockets.h"
41#include "shill/net/mock_time.h"
42#include "shill/net/rtnl_message.h"
Ben Chan2240e8c2014-11-06 13:37:18 -080043#include "shill/vpn/mock_vpn_provider.h"
Ben Chanc3d707d2014-10-31 08:56:05 -070044#include "shill/wimax/mock_wimax_provider.h"
45#include "shill/wimax/wimax.h"
Chris Masone9be4a9d2011-05-16 15:44:09 -070046
Peter Qiu1a72f542015-04-14 16:31:36 -070047#if !defined(DISABLE_WIFI)
48#include "shill/net/mock_netlink_manager.h"
49#include "shill/net/netlink_attribute.h"
50#include "shill/net/nl80211_message.h"
51#endif // DISABLE_WIFI
52
Eric Shienbrood3e20a232012-02-16 11:35:56 -050053using base::Callback;
Albert Chaulk0e1cdea2013-02-27 15:32:55 -080054using base::FilePath;
Darin Petkove6193c02011-08-11 12:42:40 -070055using std::map;
Ben Chan5086b972013-01-15 21:51:38 -080056using std::set;
Darin Petkov633ac6f2011-07-08 13:56:13 -070057using std::string;
Ben Chancd477322014-10-17 14:19:30 -070058using std::unique_ptr;
Paul Stewart9a908082011-08-31 12:18:48 -070059using std::vector;
Darin Petkov633ac6f2011-07-08 13:56:13 -070060using testing::_;
Paul Stewart2ddf2c62013-04-16 09:47:34 -070061using testing::AnyNumber;
Ben Chan5086b972013-01-15 21:51:38 -080062using testing::ContainerEq;
Gary Morain41780232012-07-31 15:08:31 -070063using testing::DoAll;
64using testing::ElementsAreArray;
Paul Stewart2ddf2c62013-04-16 09:47:34 -070065using testing::HasSubstr;
Paul Stewart8c116a92012-05-02 18:30:03 -070066using testing::Mock;
Gary Morain41780232012-07-31 15:08:31 -070067using testing::NotNull;
Darin Petkov633ac6f2011-07-08 13:56:13 -070068using testing::Return;
Peter Qiu98551702014-07-28 13:28:53 -070069using testing::SetArgPointee;
Paul Stewart9a908082011-08-31 12:18:48 -070070using testing::StrictMock;
Darin Petkov633ac6f2011-07-08 13:56:13 -070071using testing::Test;
72
Chris Masone9be4a9d2011-05-16 15:44:09 -070073namespace shill {
Darin Petkov633ac6f2011-07-08 13:56:13 -070074
Paul Stewart050cfc02012-07-06 20:38:54 -070075class TestEventDispatcherForDeviceInfo : public EventDispatcher {
Darin Petkov633ac6f2011-07-08 13:56:13 -070076 public:
Paul Stewart3b30ca52015-06-16 13:13:10 -070077 virtual IOHandler* CreateInputHandler(
mukesh agrawal1830fa12011-09-26 14:31:40 -070078 int /*fd*/,
Paul Stewart3b30ca52015-06-16 13:13:10 -070079 const IOHandler::InputCallback& /*input_callback*/,
80 const IOHandler::ErrorCallback& /*error_callback*/) {
Ben Chancc225ef2014-09-30 13:26:51 -070081 return nullptr;
Darin Petkov633ac6f2011-07-08 13:56:13 -070082 }
Paul Stewart3b30ca52015-06-16 13:13:10 -070083 MOCK_METHOD2(PostDelayedTask, bool(const base::Closure& task,
Ben Chan7fab8972014-08-10 17:14:46 -070084 int64_t delay_ms));
Darin Petkov633ac6f2011-07-08 13:56:13 -070085};
Chris Masone9be4a9d2011-05-16 15:44:09 -070086
87class DeviceInfoTest : public Test {
88 public:
89 DeviceInfoTest()
Thieu Le6c1e3bb2013-02-06 15:20:35 -080090 : metrics_(&dispatcher_),
91 manager_(&control_interface_, &dispatcher_, &metrics_, &glib_),
Thieu Le3426c8f2012-01-11 17:35:11 -080092 device_info_(&control_interface_, &dispatcher_, &metrics_, &manager_) {
Chris Masone9be4a9d2011-05-16 15:44:09 -070093 }
Paul Stewartca876ee2012-04-21 08:55:58 -070094 virtual ~DeviceInfoTest() {}
Darin Petkov633ac6f2011-07-08 13:56:13 -070095
Paul Stewart9a908082011-08-31 12:18:48 -070096 virtual void SetUp() {
97 device_info_.rtnl_handler_ = &rtnl_handler_;
Paul Stewart8c116a92012-05-02 18:30:03 -070098 device_info_.routing_table_ = &routing_table_;
Peter Qiu1a72f542015-04-14 16:31:36 -070099#if !defined(DISABLE_WIFI)
Paul Stewart2ddf2c62013-04-16 09:47:34 -0700100 device_info_.netlink_manager_ = &netlink_manager_;
Peter Qiu1a72f542015-04-14 16:31:36 -0700101#endif // DISABLE_WIFI
Peter Qiu98551702014-07-28 13:28:53 -0700102 device_info_.time_ = &time_;
Paul Stewartd4f26482014-04-25 19:12:03 -0700103 manager_.set_mock_device_info(&device_info_);
Paul Stewart1ce231c2015-06-12 19:44:22 -0700104 EXPECT_CALL(manager_, FilterPrependDNSServersByFamily(_))
105 .WillRepeatedly(Return(vector<string>()));
Paul Stewart9a908082011-08-31 12:18:48 -0700106 }
107
Paul Stewart8c116a92012-05-02 18:30:03 -0700108 IPAddress CreateInterfaceAddress() {
109 // Create an IP address entry (as if left-over from a previous connection
110 // manager).
111 IPAddress address(IPAddress::kFamilyIPv4);
112 EXPECT_TRUE(address.SetAddressFromString(kTestIPAddress0));
113 address.set_prefix(kTestIPAddressPrefix0);
Paul Stewart3b30ca52015-06-16 13:13:10 -0700114 vector<DeviceInfo::AddressData>& addresses =
Paul Stewart8c116a92012-05-02 18:30:03 -0700115 device_info_.infos_[kTestDeviceIndex].ip_addresses;
116 addresses.push_back(DeviceInfo::AddressData(address, 0, RT_SCOPE_UNIVERSE));
117 EXPECT_EQ(1, addresses.size());
118 return address;
119 }
120
Paul Stewart3b30ca52015-06-16 13:13:10 -0700121 DeviceRefPtr CreateDevice(const std::string& link_name,
122 const std::string& address,
Paul Stewart8c116a92012-05-02 18:30:03 -0700123 int interface_index,
124 Technology::Identifier technology) {
125 return device_info_.CreateDevice(link_name, address, interface_index,
126 technology);
127 }
128
Paul Stewart3b30ca52015-06-16 13:13:10 -0700129 virtual std::set<int>& GetDelayedDevices() {
Paul Stewart050cfc02012-07-06 20:38:54 -0700130 return device_info_.delayed_devices_;
131 }
132
Paul Stewart1ac4e842012-07-10 12:58:12 -0700133 int GetDelayedDeviceCreationMilliseconds() {
Paul Stewart050cfc02012-07-06 20:38:54 -0700134 return DeviceInfo::kDelayedDeviceCreationSeconds * 1000;
135 }
Paul Stewart8c116a92012-05-02 18:30:03 -0700136
Gary Morain41780232012-07-31 15:08:31 -0700137 void SetSockets() {
138 mock_sockets_ = new MockSockets();
139 device_info_.set_sockets(mock_sockets_);
140 }
141
Darin Petkovc3505a52013-03-18 15:13:29 +0100142 // Takes ownership of |provider|.
Paul Stewart3b30ca52015-06-16 13:13:10 -0700143 void SetVPNProvider(VPNProvider* provider) {
Darin Petkovc3505a52013-03-18 15:13:29 +0100144 manager_.vpn_provider_.reset(provider);
Paul Stewartb87d22b2013-07-29 11:11:37 -0700145 manager_.UpdateProviderMapping();
Darin Petkovc3505a52013-03-18 15:13:29 +0100146 }
147
Peter Qiuebd709e2015-03-16 14:03:37 -0700148 void SetManagerRunning(bool running) {
149 manager_.running_ = running;
150 }
151
Paul Stewarta3c56f92011-05-26 07:08:52 -0700152 protected:
Chris Masoneb2e326b2011-07-12 13:28:51 -0700153 static const int kTestDeviceIndex;
Darin Petkov633ac6f2011-07-08 13:56:13 -0700154 static const char kTestDeviceName[];
Han Shenfc349252012-08-30 11:36:04 -0700155 static const uint8_t kTestMACAddress[];
Paul Stewart9a908082011-08-31 12:18:48 -0700156 static const char kTestIPAddress0[];
157 static const int kTestIPAddressPrefix0;
158 static const char kTestIPAddress1[];
159 static const int kTestIPAddressPrefix1;
160 static const char kTestIPAddress2[];
161 static const char kTestIPAddress3[];
162 static const char kTestIPAddress4[];
Paul Stewart05a42c22012-08-02 16:47:21 -0700163 static const char kTestIPAddress5[];
Paul Stewarta0db0ff2013-12-09 09:48:47 -0800164 static const char kTestIPAddress6[];
Paul Stewart1ac4e842012-07-10 12:58:12 -0700165 static const int kReceiveByteCount;
166 static const int kTransmitByteCount;
Darin Petkov633ac6f2011-07-08 13:56:13 -0700167
Paul Stewart3b30ca52015-06-16 13:13:10 -0700168 RTNLMessage* BuildLinkMessage(RTNLMessage::Mode mode);
169 RTNLMessage* BuildLinkMessageWithInterfaceName(RTNLMessage::Mode mode,
170 const string& interface_name);
171 RTNLMessage* BuildAddressMessage(RTNLMessage::Mode mode,
172 const IPAddress& address,
Paul Stewart9a908082011-08-31 12:18:48 -0700173 unsigned char flags,
174 unsigned char scope);
Paul Stewart3b30ca52015-06-16 13:13:10 -0700175 RTNLMessage* BuildRdnssMessage(RTNLMessage::Mode mode,
Ben Chan7fab8972014-08-10 17:14:46 -0700176 uint32_t lifetime,
Paul Stewart3b30ca52015-06-16 13:13:10 -0700177 const vector<IPAddress>& dns_servers);
178 void SendMessageToDeviceInfo(const RTNLMessage& message);
Darin Petkov633ac6f2011-07-08 13:56:13 -0700179
Darin Petkovafa6fc42011-06-21 16:21:08 -0700180 MockGLib glib_;
Chris Masone46eaaf52011-05-24 13:08:30 -0700181 MockControl control_interface_;
Thieu Le3426c8f2012-01-11 17:35:11 -0800182 MockMetrics metrics_;
Paul Stewart9a908082011-08-31 12:18:48 -0700183 StrictMock<MockManager> manager_;
Chris Masone9be4a9d2011-05-16 15:44:09 -0700184 DeviceInfo device_info_;
Paul Stewart050cfc02012-07-06 20:38:54 -0700185 TestEventDispatcherForDeviceInfo dispatcher_;
Paul Stewart8c116a92012-05-02 18:30:03 -0700186 MockRoutingTable routing_table_;
Peter Qiu1a72f542015-04-14 16:31:36 -0700187#if !defined(DISABLE_WIFI)
Paul Stewart2ddf2c62013-04-16 09:47:34 -0700188 MockNetlinkManager netlink_manager_;
Peter Qiu1a72f542015-04-14 16:31:36 -0700189#endif // DISABLE_WIFI
Paul Stewart9a908082011-08-31 12:18:48 -0700190 StrictMock<MockRTNLHandler> rtnl_handler_;
Paul Stewart3b30ca52015-06-16 13:13:10 -0700191 MockSockets* mock_sockets_; // Owned by DeviceInfo.
Peter Qiu98551702014-07-28 13:28:53 -0700192 MockTime time_;
Chris Masone9be4a9d2011-05-16 15:44:09 -0700193};
194
Chris Masoneb2e326b2011-07-12 13:28:51 -0700195const int DeviceInfoTest::kTestDeviceIndex = 123456;
Darin Petkov633ac6f2011-07-08 13:56:13 -0700196const char DeviceInfoTest::kTestDeviceName[] = "test-device";
Han Shenfc349252012-08-30 11:36:04 -0700197const uint8_t DeviceInfoTest::kTestMACAddress[] = {
Wade Guthrie7347bf22013-04-30 11:21:51 -0700198 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff };
Paul Stewart9a908082011-08-31 12:18:48 -0700199const char DeviceInfoTest::kTestIPAddress0[] = "192.168.1.1";
200const int DeviceInfoTest::kTestIPAddressPrefix0 = 24;
201const char DeviceInfoTest::kTestIPAddress1[] = "fe80::1aa9:5ff:abcd:1234";
202const int DeviceInfoTest::kTestIPAddressPrefix1 = 64;
203const char DeviceInfoTest::kTestIPAddress2[] = "fe80::1aa9:5ff:abcd:1235";
204const char DeviceInfoTest::kTestIPAddress3[] = "fe80::1aa9:5ff:abcd:1236";
205const char DeviceInfoTest::kTestIPAddress4[] = "fe80::1aa9:5ff:abcd:1237";
Paul Stewart05a42c22012-08-02 16:47:21 -0700206const char DeviceInfoTest::kTestIPAddress5[] = "192.168.1.2";
Paul Stewarta0db0ff2013-12-09 09:48:47 -0800207const char DeviceInfoTest::kTestIPAddress6[] = "192.168.2.2";
Paul Stewart1ac4e842012-07-10 12:58:12 -0700208const int DeviceInfoTest::kReceiveByteCount = 1234;
209const int DeviceInfoTest::kTransmitByteCount = 5678;
Chris Masone9be4a9d2011-05-16 15:44:09 -0700210
Paul Stewart3b30ca52015-06-16 13:13:10 -0700211RTNLMessage* DeviceInfoTest::BuildLinkMessageWithInterfaceName(
212 RTNLMessage::Mode mode, const string& interface_name) {
213 RTNLMessage* message = new RTNLMessage(
Paul Stewart9a908082011-08-31 12:18:48 -0700214 RTNLMessage::kTypeLink,
215 mode,
216 0,
217 0,
218 0,
219 kTestDeviceIndex,
Paul Stewart7355ce12011-09-02 10:47:01 -0700220 IPAddress::kFamilyIPv4);
Ben Chan7fab8972014-08-10 17:14:46 -0700221 message->SetAttribute(static_cast<uint16_t>(IFLA_IFNAME),
Paul Stewarte81eb702012-04-11 15:04:53 -0700222 ByteString(interface_name, true));
Paul Stewart9a908082011-08-31 12:18:48 -0700223 ByteString test_address(kTestMACAddress, sizeof(kTestMACAddress));
Chris Masone626719f2011-08-18 16:58:48 -0700224 message->SetAttribute(IFLA_ADDRESS, test_address);
Chris Masone2aa97072011-08-09 17:35:08 -0700225 return message;
Darin Petkov633ac6f2011-07-08 13:56:13 -0700226}
227
Paul Stewart3b30ca52015-06-16 13:13:10 -0700228RTNLMessage* DeviceInfoTest::BuildLinkMessage(RTNLMessage::Mode mode) {
Paul Stewarte81eb702012-04-11 15:04:53 -0700229 return BuildLinkMessageWithInterfaceName(mode, kTestDeviceName);
230}
231
Paul Stewart3b30ca52015-06-16 13:13:10 -0700232RTNLMessage* DeviceInfoTest::BuildAddressMessage(RTNLMessage::Mode mode,
233 const IPAddress& address,
Paul Stewart9a908082011-08-31 12:18:48 -0700234 unsigned char flags,
235 unsigned char scope) {
Paul Stewart3b30ca52015-06-16 13:13:10 -0700236 RTNLMessage* message = new RTNLMessage(
Paul Stewart9a908082011-08-31 12:18:48 -0700237 RTNLMessage::kTypeAddress,
238 mode,
239 0,
240 0,
241 0,
242 kTestDeviceIndex,
243 address.family());
244 message->SetAttribute(IFA_ADDRESS, address.address());
245 message->set_address_status(
246 RTNLMessage::AddressStatus(address.prefix(), flags, scope));
247 return message;
248}
249
Paul Stewart3b30ca52015-06-16 13:13:10 -0700250RTNLMessage* DeviceInfoTest::BuildRdnssMessage(RTNLMessage::Mode mode,
251 uint32_t lifetime, const vector<IPAddress>& dns_servers) {
252 RTNLMessage* message = new RTNLMessage(
Peter Qiu98551702014-07-28 13:28:53 -0700253 RTNLMessage::kTypeRdnss,
254 mode,
255 0,
256 0,
257 0,
258 kTestDeviceIndex,
259 IPAddress::kFamilyIPv6);
260 message->set_rdnss_option(
261 RTNLMessage::RdnssOption(lifetime, dns_servers));
262 return message;
263}
264
Paul Stewart3b30ca52015-06-16 13:13:10 -0700265void DeviceInfoTest::SendMessageToDeviceInfo(const RTNLMessage& message) {
Paul Stewart9a908082011-08-31 12:18:48 -0700266 if (message.type() == RTNLMessage::kTypeLink) {
267 device_info_.LinkMsgHandler(message);
268 } else if (message.type() == RTNLMessage::kTypeAddress) {
269 device_info_.AddressMsgHandler(message);
Peter Qiu98551702014-07-28 13:28:53 -0700270 } else if (message.type() == RTNLMessage::kTypeRdnss) {
271 device_info_.RdnssMsgHandler(message);
Paul Stewart9a908082011-08-31 12:18:48 -0700272 } else {
273 NOTREACHED();
274 }
275}
276
277MATCHER_P(IsIPAddress, address, "") {
278 // NB: IPAddress objects don't support the "==" operator as per style, so
279 // we need a custom matcher.
280 return address.Equals(arg);
Darin Petkov633ac6f2011-07-08 13:56:13 -0700281}
282
Paul Stewart8c116a92012-05-02 18:30:03 -0700283TEST_F(DeviceInfoTest, StartStop) {
284 EXPECT_FALSE(device_info_.link_listener_.get());
285 EXPECT_FALSE(device_info_.address_listener_.get());
286 EXPECT_TRUE(device_info_.infos_.empty());
287
288 EXPECT_CALL(rtnl_handler_, RequestDump(RTNLHandler::kRequestLink |
289 RTNLHandler::kRequestAddr));
Paul Stewart1ac4e842012-07-10 12:58:12 -0700290 EXPECT_CALL(dispatcher_, PostDelayedTask(
Ben Chanb061f892013-02-27 17:46:55 -0800291 _, DeviceInfo::kRequestLinkStatisticsIntervalMilliseconds));
Chris Masone9be4a9d2011-05-16 15:44:09 -0700292 device_info_.Start();
Paul Stewart8c116a92012-05-02 18:30:03 -0700293 EXPECT_TRUE(device_info_.link_listener_.get());
294 EXPECT_TRUE(device_info_.address_listener_.get());
295 EXPECT_TRUE(device_info_.infos_.empty());
296 Mock::VerifyAndClearExpectations(&rtnl_handler_);
297
298 CreateInterfaceAddress();
299 EXPECT_FALSE(device_info_.infos_.empty());
300
301 device_info_.Stop();
302 EXPECT_FALSE(device_info_.link_listener_.get());
303 EXPECT_FALSE(device_info_.address_listener_.get());
304 EXPECT_TRUE(device_info_.infos_.empty());
305}
306
Paul Stewart1ac4e842012-07-10 12:58:12 -0700307TEST_F(DeviceInfoTest, RequestLinkStatistics) {
308 EXPECT_CALL(rtnl_handler_, RequestDump(RTNLHandler::kRequestLink));
309 EXPECT_CALL(dispatcher_, PostDelayedTask(
Ben Chanb061f892013-02-27 17:46:55 -0800310 _, DeviceInfo::kRequestLinkStatisticsIntervalMilliseconds));
Paul Stewart1ac4e842012-07-10 12:58:12 -0700311 device_info_.RequestLinkStatistics();
312}
313
Paul Stewart8c116a92012-05-02 18:30:03 -0700314TEST_F(DeviceInfoTest, DeviceEnumeration) {
Ben Chancd477322014-10-17 14:19:30 -0700315 unique_ptr<RTNLMessage> message(BuildLinkMessage(RTNLMessage::kModeAdd));
Darin Petkove6193c02011-08-11 12:42:40 -0700316 message->set_link_status(RTNLMessage::LinkStatus(0, IFF_LOWER_UP, 0));
317 EXPECT_FALSE(device_info_.GetDevice(kTestDeviceIndex).get());
Darin Petkovf8046b82012-04-24 16:29:23 +0200318 EXPECT_EQ(-1, device_info_.GetIndex(kTestDeviceName));
Darin Petkove6193c02011-08-11 12:42:40 -0700319 SendMessageToDeviceInfo(*message);
320 EXPECT_TRUE(device_info_.GetDevice(kTestDeviceIndex).get());
321 unsigned int flags = 0;
322 EXPECT_TRUE(device_info_.GetFlags(kTestDeviceIndex, &flags));
323 EXPECT_EQ(IFF_LOWER_UP, flags);
Darin Petkove3e1cfa2011-08-11 13:41:17 -0700324 ByteString address;
Paul Stewart32852962011-08-30 14:06:53 -0700325 EXPECT_TRUE(device_info_.GetMACAddress(kTestDeviceIndex, &address));
Darin Petkove3e1cfa2011-08-11 13:41:17 -0700326 EXPECT_FALSE(address.IsEmpty());
Paul Stewart9a908082011-08-31 12:18:48 -0700327 EXPECT_TRUE(address.Equals(ByteString(kTestMACAddress,
328 sizeof(kTestMACAddress))));
Darin Petkovf8046b82012-04-24 16:29:23 +0200329 EXPECT_EQ(kTestDeviceIndex, device_info_.GetIndex(kTestDeviceName));
Paul Stewarta3c56f92011-05-26 07:08:52 -0700330
Paul Stewart9a908082011-08-31 12:18:48 -0700331 message.reset(BuildLinkMessage(RTNLMessage::kModeAdd));
Darin Petkove6193c02011-08-11 12:42:40 -0700332 message->set_link_status(RTNLMessage::LinkStatus(0, IFF_UP | IFF_RUNNING, 0));
333 SendMessageToDeviceInfo(*message);
334 EXPECT_TRUE(device_info_.GetFlags(kTestDeviceIndex, &flags));
335 EXPECT_EQ(IFF_UP | IFF_RUNNING, flags);
Paul Stewartb50f0b92011-05-16 16:31:42 -0700336
Paul Stewart9a908082011-08-31 12:18:48 -0700337 message.reset(BuildLinkMessage(RTNLMessage::kModeDelete));
Paul Stewart8c116a92012-05-02 18:30:03 -0700338 EXPECT_CALL(manager_, DeregisterDevice(_)).Times(1);
Darin Petkove6193c02011-08-11 12:42:40 -0700339 SendMessageToDeviceInfo(*message);
340 EXPECT_FALSE(device_info_.GetDevice(kTestDeviceIndex).get());
Ben Chancc225ef2014-09-30 13:26:51 -0700341 EXPECT_FALSE(device_info_.GetFlags(kTestDeviceIndex, nullptr));
Darin Petkovf8046b82012-04-24 16:29:23 +0200342 EXPECT_EQ(-1, device_info_.GetIndex(kTestDeviceName));
Paul Stewart8c116a92012-05-02 18:30:03 -0700343}
Paul Stewarta3c56f92011-05-26 07:08:52 -0700344
Peter Qiu9f5159e2014-09-12 16:50:14 -0700345TEST_F(DeviceInfoTest, DeviceRemovedEvent) {
346 // Remove a Wifi device.
347 scoped_refptr<MockDevice> device0(new MockDevice(
348 &control_interface_, &dispatcher_, &metrics_, &manager_,
349 "null0", "addr0", kTestDeviceIndex));
350 device_info_.infos_[kTestDeviceIndex].device = device0;
Ben Chancd477322014-10-17 14:19:30 -0700351 unique_ptr<RTNLMessage> message(BuildLinkMessage(RTNLMessage::kModeDelete));
Peter Qiu9f5159e2014-09-12 16:50:14 -0700352 EXPECT_CALL(*device0, technology()).WillRepeatedly(Return(Technology::kWifi));
353 EXPECT_CALL(manager_, DeregisterDevice(_)).Times(1);
354 EXPECT_CALL(metrics_, DeregisterDevice(kTestDeviceIndex)).Times(1);
355 SendMessageToDeviceInfo(*message);
Alex Vakulenko0951ccb2014-12-10 12:52:31 -0800356 Mock::VerifyAndClearExpectations(device0.get());
Peter Qiu9f5159e2014-09-12 16:50:14 -0700357
358 // Deregister a Cellular device.
359 scoped_refptr<MockDevice> device1(new MockDevice(
360 &control_interface_, &dispatcher_, &metrics_, &manager_,
361 "null0", "addr0", kTestDeviceIndex));
362 device_info_.infos_[kTestDeviceIndex].device = device1;
363 EXPECT_CALL(*device1, technology()).
364 WillRepeatedly(Return(Technology::kCellular));
365 EXPECT_CALL(manager_, DeregisterDevice(_)).Times(1);
366 EXPECT_CALL(metrics_, DeregisterDevice(kTestDeviceIndex)).Times(1);
367 device_info_.DeregisterDevice(device1);
368}
369
Ben Chan5086b972013-01-15 21:51:38 -0800370TEST_F(DeviceInfoTest, GetUninitializedTechnologies) {
371 vector<string> technologies = device_info_.GetUninitializedTechnologies();
372 set<string> expected_technologies;
373
374 EXPECT_THAT(set<string>(technologies.begin(), technologies.end()),
375 ContainerEq(expected_technologies));
376
377 device_info_.infos_[0].technology = Technology::kUnknown;
378 EXPECT_THAT(set<string>(technologies.begin(), technologies.end()),
379 ContainerEq(expected_technologies));
380
381 device_info_.infos_[1].technology = Technology::kCellular;
382 technologies = device_info_.GetUninitializedTechnologies();
383 expected_technologies.insert(Technology::NameFromIdentifier(
384 Technology::kCellular));
385 EXPECT_THAT(set<string>(technologies.begin(), technologies.end()),
386 ContainerEq(expected_technologies));
387
388 device_info_.infos_[2].technology = Technology::kWiMax;
389 technologies = device_info_.GetUninitializedTechnologies();
390 expected_technologies.insert(Technology::NameFromIdentifier(
391 Technology::kWiMax));
392 EXPECT_THAT(set<string>(technologies.begin(), technologies.end()),
393 ContainerEq(expected_technologies));
394
395 scoped_refptr<MockDevice> device(new MockDevice(
396 &control_interface_, &dispatcher_, &metrics_, &manager_,
397 "null0", "addr0", 1));
398 device_info_.infos_[1].device = device;
399 technologies = device_info_.GetUninitializedTechnologies();
400 expected_technologies.erase(Technology::NameFromIdentifier(
401 Technology::kCellular));
402 EXPECT_THAT(set<string>(technologies.begin(), technologies.end()),
403 ContainerEq(expected_technologies));
404
405 device_info_.infos_[3].technology = Technology::kCellular;
406 technologies = device_info_.GetUninitializedTechnologies();
Arman Ugurayb00c13d2013-07-29 18:20:52 -0700407 EXPECT_THAT(set<string>(technologies.begin(), technologies.end()),
408 ContainerEq(expected_technologies));
409
410 device_info_.infos_[3].device = device;
Ben Chancc225ef2014-09-30 13:26:51 -0700411 device_info_.infos_[1].device = nullptr;
Arman Ugurayb00c13d2013-07-29 18:20:52 -0700412 technologies = device_info_.GetUninitializedTechnologies();
Ben Chan5086b972013-01-15 21:51:38 -0800413 EXPECT_THAT(set<string>(technologies.begin(), technologies.end()),
414 ContainerEq(expected_technologies));
415}
416
Paul Stewart1ac4e842012-07-10 12:58:12 -0700417TEST_F(DeviceInfoTest, GetByteCounts) {
Ben Chan7fab8972014-08-10 17:14:46 -0700418 uint64_t rx_bytes, tx_bytes;
Paul Stewart1ac4e842012-07-10 12:58:12 -0700419 EXPECT_FALSE(device_info_.GetByteCounts(
420 kTestDeviceIndex, &rx_bytes, &tx_bytes));
421
422 // No link statistics in the message.
Ben Chancd477322014-10-17 14:19:30 -0700423 unique_ptr<RTNLMessage> message(BuildLinkMessage(RTNLMessage::kModeAdd));
Paul Stewart1ac4e842012-07-10 12:58:12 -0700424 SendMessageToDeviceInfo(*message);
425 EXPECT_TRUE(device_info_.GetByteCounts(
426 kTestDeviceIndex, &rx_bytes, &tx_bytes));
427 EXPECT_EQ(0, rx_bytes);
428 EXPECT_EQ(0, tx_bytes);
429
430 // Short link statistics message.
431 message.reset(BuildLinkMessage(RTNLMessage::kModeAdd));
432 struct rtnl_link_stats64 stats;
433 memset(&stats, 0, sizeof(stats));
434 stats.rx_bytes = kReceiveByteCount;
435 stats.tx_bytes = kTransmitByteCount;
436 ByteString stats_bytes0(reinterpret_cast<const unsigned char*>(&stats),
437 sizeof(stats) - 1);
438 message->SetAttribute(IFLA_STATS64, stats_bytes0);
439 SendMessageToDeviceInfo(*message);
440 EXPECT_TRUE(device_info_.GetByteCounts(
441 kTestDeviceIndex, &rx_bytes, &tx_bytes));
442 EXPECT_EQ(0, rx_bytes);
443 EXPECT_EQ(0, tx_bytes);
444
445 // Correctly sized link statistics message.
446 message.reset(BuildLinkMessage(RTNLMessage::kModeAdd));
447 ByteString stats_bytes1(reinterpret_cast<const unsigned char*>(&stats),
448 sizeof(stats));
449 message->SetAttribute(IFLA_STATS64, stats_bytes1);
450 SendMessageToDeviceInfo(*message);
451 EXPECT_TRUE(device_info_.GetByteCounts(
452 kTestDeviceIndex, &rx_bytes, &tx_bytes));
453 EXPECT_EQ(kReceiveByteCount, rx_bytes);
454 EXPECT_EQ(kTransmitByteCount, tx_bytes);
455}
456
Ben Chan5742b242013-12-18 16:25:43 -0800457#if !defined(DISABLE_CELLULAR)
458
Paul Stewart8c116a92012-05-02 18:30:03 -0700459TEST_F(DeviceInfoTest, CreateDeviceCellular) {
460 IPAddress address = CreateInterfaceAddress();
461
462 // A cellular device should be offered to ModemInfo.
463 StrictMock<MockModemInfo> modem_info;
464 EXPECT_CALL(manager_, modem_info()).WillOnce(Return(&modem_info));
465 EXPECT_CALL(modem_info, OnDeviceInfoAvailable(kTestDeviceName)).Times(1);
466 EXPECT_CALL(routing_table_, FlushRoutes(kTestDeviceIndex)).Times(1);
467 EXPECT_CALL(rtnl_handler_, RemoveInterfaceAddress(kTestDeviceIndex,
468 IsIPAddress(address)));
469 EXPECT_FALSE(CreateDevice(
470 kTestDeviceName, "address", kTestDeviceIndex, Technology::kCellular));
471}
472
Ben Chan5742b242013-12-18 16:25:43 -0800473#endif // DISABLE_CELLULAR
474
Ben Chan520eb172013-10-30 20:51:04 -0700475#if !defined(DISABLE_WIMAX)
476
Darin Petkove4b27022012-05-16 13:28:50 +0200477TEST_F(DeviceInfoTest, CreateDeviceWiMax) {
478 IPAddress address = CreateInterfaceAddress();
479
480 // A WiMax device should be offered to WiMaxProvider.
481 StrictMock<MockWiMaxProvider> wimax_provider;
482 EXPECT_CALL(manager_, wimax_provider()).WillOnce(Return(&wimax_provider));
483 EXPECT_CALL(wimax_provider, OnDeviceInfoAvailable(kTestDeviceName)).Times(1);
484 EXPECT_CALL(routing_table_, FlushRoutes(kTestDeviceIndex)).Times(1);
485 EXPECT_CALL(rtnl_handler_, RemoveInterfaceAddress(kTestDeviceIndex,
486 IsIPAddress(address)));
Ben Chan4b285862012-10-10 22:52:16 -0700487 device_info_.infos_[kTestDeviceIndex].mac_address =
488 ByteString(kTestMACAddress, sizeof(kTestMACAddress));
Darin Petkove4b27022012-05-16 13:28:50 +0200489 EXPECT_FALSE(CreateDevice(
490 kTestDeviceName, "address", kTestDeviceIndex, Technology::kWiMax));
Ben Chan4b285862012-10-10 22:52:16 -0700491 // The MAC address is clear such that it is obtained via
492 // GetMACAddressFromKernel() instead.
493 EXPECT_TRUE(device_info_.infos_[kTestDeviceIndex].mac_address.IsEmpty());
Darin Petkove4b27022012-05-16 13:28:50 +0200494}
495
Ben Chan520eb172013-10-30 20:51:04 -0700496#endif // DISABLE_WIMAX
497
Paul Stewart8c116a92012-05-02 18:30:03 -0700498TEST_F(DeviceInfoTest, CreateDeviceEthernet) {
499 IPAddress address = CreateInterfaceAddress();
500
501 // An Ethernet device should cause routes and addresses to be flushed.
502 EXPECT_CALL(routing_table_, FlushRoutes(kTestDeviceIndex)).Times(1);
503 EXPECT_CALL(rtnl_handler_, RemoveInterfaceAddress(kTestDeviceIndex,
504 IsIPAddress(address)));
505 DeviceRefPtr device = CreateDevice(
506 kTestDeviceName, "address", kTestDeviceIndex, Technology::kEthernet);
507 EXPECT_TRUE(device);
508 Mock::VerifyAndClearExpectations(&routing_table_);
509 Mock::VerifyAndClearExpectations(&rtnl_handler_);
510
Paul Stewarta06c65f2014-12-10 11:37:43 -0800511 // The Ethernet device destructor should not call DeregisterService()
512 // while being destructed, since the Manager may itself be partially
513 // destructed at this time.
514 EXPECT_CALL(manager_, DeregisterService(_)).Times(0);
Ben Chancc225ef2014-09-30 13:26:51 -0700515 device = nullptr;
Paul Stewart8c116a92012-05-02 18:30:03 -0700516}
517
518TEST_F(DeviceInfoTest, CreateDeviceVirtioEthernet) {
519 IPAddress address = CreateInterfaceAddress();
520
521 // VirtioEthernet is identical to Ethernet from the perspective of this test.
522 EXPECT_CALL(routing_table_, FlushRoutes(kTestDeviceIndex)).Times(1);
523 EXPECT_CALL(rtnl_handler_, RemoveInterfaceAddress(kTestDeviceIndex,
524 IsIPAddress(address)));
525 DeviceRefPtr device = CreateDevice(
526 kTestDeviceName, "address", kTestDeviceIndex,
527 Technology::kVirtioEthernet);
528 EXPECT_TRUE(device);
529 Mock::VerifyAndClearExpectations(&routing_table_);
530 Mock::VerifyAndClearExpectations(&rtnl_handler_);
Paul Stewart8c116a92012-05-02 18:30:03 -0700531}
532
Peter Qiu1a72f542015-04-14 16:31:36 -0700533#if !defined(DISABLE_WIFI)
Paul Stewart2ddf2c62013-04-16 09:47:34 -0700534MATCHER_P(IsGetInterfaceMessage, index, "") {
535 if (arg->message_type() != Nl80211Message::GetMessageType()) {
536 return false;
537 }
Paul Stewart3b30ca52015-06-16 13:13:10 -0700538 const Nl80211Message* msg = reinterpret_cast<const Nl80211Message*>(arg);
Paul Stewart2ddf2c62013-04-16 09:47:34 -0700539 if (msg->command() != NL80211_CMD_GET_INTERFACE) {
540 return false;
541 }
542 uint32_t interface_index;
543 if (!msg->const_attributes()->GetU32AttributeValue(NL80211_ATTR_IFINDEX,
544 &interface_index)) {
545 return false;
546 }
547 // kInterfaceIndex is signed, but the attribute as handed from the kernel
548 // is unsigned. We're silently casting it away with this assignment.
549 uint32_t test_interface_index = index;
550 return interface_index == test_interface_index;
551}
552
Paul Stewart8c116a92012-05-02 18:30:03 -0700553TEST_F(DeviceInfoTest, CreateDeviceWiFi) {
554 IPAddress address = CreateInterfaceAddress();
555
556 // WiFi looks a lot like Ethernet too.
Paul Stewart2ddf2c62013-04-16 09:47:34 -0700557 EXPECT_CALL(routing_table_, FlushRoutes(kTestDeviceIndex));
Paul Stewart8c116a92012-05-02 18:30:03 -0700558 EXPECT_CALL(rtnl_handler_, RemoveInterfaceAddress(kTestDeviceIndex,
559 IsIPAddress(address)));
Paul Stewart2ddf2c62013-04-16 09:47:34 -0700560
561 // Set the nl80211 message type to some non-default value.
562 Nl80211Message::SetMessageType(1234);
563
Wade Guthrie7347bf22013-04-30 11:21:51 -0700564 EXPECT_CALL(
565 netlink_manager_,
Samuel Tan5412de02014-08-15 17:56:26 -0700566 SendNl80211Message(IsGetInterfaceMessage(kTestDeviceIndex), _, _, _));
Paul Stewart2ddf2c62013-04-16 09:47:34 -0700567 EXPECT_FALSE(CreateDevice(
Paul Stewart8c116a92012-05-02 18:30:03 -0700568 kTestDeviceName, "address", kTestDeviceIndex, Technology::kWifi));
569}
Peter Qiu1a72f542015-04-14 16:31:36 -0700570#endif // DISABLE_WIFI
Paul Stewart8c116a92012-05-02 18:30:03 -0700571
572TEST_F(DeviceInfoTest, CreateDeviceTunnelAccepted) {
573 IPAddress address = CreateInterfaceAddress();
574
575 // A VPN device should be offered to VPNProvider.
Paul Stewart3b30ca52015-06-16 13:13:10 -0700576 MockVPNProvider* vpn_provider = new StrictMock<MockVPNProvider>;
Darin Petkovc3505a52013-03-18 15:13:29 +0100577 SetVPNProvider(vpn_provider);
578 EXPECT_CALL(*vpn_provider,
Paul Stewart8c116a92012-05-02 18:30:03 -0700579 OnDeviceInfoAvailable(kTestDeviceName, kTestDeviceIndex))
580 .WillOnce(Return(true));
581 EXPECT_CALL(routing_table_, FlushRoutes(kTestDeviceIndex)).Times(1);
582 EXPECT_CALL(rtnl_handler_, RemoveInterfaceAddress(kTestDeviceIndex,
583 IsIPAddress(address)));
584 EXPECT_CALL(rtnl_handler_, RemoveInterface(_)).Times(0);
585 EXPECT_FALSE(CreateDevice(
586 kTestDeviceName, "address", kTestDeviceIndex, Technology::kTunnel));
587}
588
589TEST_F(DeviceInfoTest, CreateDeviceTunnelRejected) {
590 IPAddress address = CreateInterfaceAddress();
591
592 // A VPN device should be offered to VPNProvider.
Paul Stewart3b30ca52015-06-16 13:13:10 -0700593 MockVPNProvider* vpn_provider = new StrictMock<MockVPNProvider>;
Darin Petkovc3505a52013-03-18 15:13:29 +0100594 SetVPNProvider(vpn_provider);
595 EXPECT_CALL(*vpn_provider,
Paul Stewart8c116a92012-05-02 18:30:03 -0700596 OnDeviceInfoAvailable(kTestDeviceName, kTestDeviceIndex))
597 .WillOnce(Return(false));
598 EXPECT_CALL(routing_table_, FlushRoutes(kTestDeviceIndex)).Times(1);
599 EXPECT_CALL(rtnl_handler_, RemoveInterfaceAddress(kTestDeviceIndex,
600 IsIPAddress(address)));
601 // Since the device was rejected by the VPNProvider, DeviceInfo will
602 // remove the interface.
603 EXPECT_CALL(rtnl_handler_, RemoveInterface(kTestDeviceIndex)).Times(1);
604 EXPECT_FALSE(CreateDevice(
605 kTestDeviceName, "address", kTestDeviceIndex, Technology::kTunnel));
606}
607
608TEST_F(DeviceInfoTest, CreateDevicePPP) {
609 IPAddress address = CreateInterfaceAddress();
610
611 // A VPN device should be offered to VPNProvider.
Paul Stewart3b30ca52015-06-16 13:13:10 -0700612 MockVPNProvider* vpn_provider = new StrictMock<MockVPNProvider>;
Darin Petkovc3505a52013-03-18 15:13:29 +0100613 SetVPNProvider(vpn_provider);
614 EXPECT_CALL(*vpn_provider,
Paul Stewart8c116a92012-05-02 18:30:03 -0700615 OnDeviceInfoAvailable(kTestDeviceName, kTestDeviceIndex))
616 .WillOnce(Return(false));
617 EXPECT_CALL(routing_table_, FlushRoutes(kTestDeviceIndex)).Times(1);
618 EXPECT_CALL(rtnl_handler_, RemoveInterfaceAddress(kTestDeviceIndex,
619 IsIPAddress(address)));
620 // We do not remove PPP interfaces even if the provider does not accept it.
621 EXPECT_CALL(rtnl_handler_, RemoveInterface(_)).Times(0);
622 EXPECT_FALSE(CreateDevice(
623 kTestDeviceName, "address", kTestDeviceIndex, Technology::kPPP));
624}
625
626TEST_F(DeviceInfoTest, CreateDeviceLoopback) {
627 // A loopback device should be brought up, and nothing else done to it.
628 EXPECT_CALL(routing_table_, FlushRoutes(_)).Times(0);
629 EXPECT_CALL(rtnl_handler_, RemoveInterfaceAddress(_, _)).Times(0);
630 EXPECT_CALL(rtnl_handler_,
631 SetInterfaceFlags(kTestDeviceIndex, IFF_UP, IFF_UP)).Times(1);
632 EXPECT_FALSE(CreateDevice(
633 kTestDeviceName, "address", kTestDeviceIndex, Technology::kLoopback));
634}
635
Paul Stewart050cfc02012-07-06 20:38:54 -0700636TEST_F(DeviceInfoTest, CreateDeviceCDCEthernet) {
Ben Chan4eb4ddf2013-06-20 22:16:56 -0700637 // A cdc_ether / cdc_ncm device should be postponed to a task.
Paul Stewart050cfc02012-07-06 20:38:54 -0700638 EXPECT_CALL(manager_, modem_info()).Times(0);
639 EXPECT_CALL(routing_table_, FlushRoutes(_)).Times(0);
640 EXPECT_CALL(rtnl_handler_, RemoveInterfaceAddress(_, _)).Times(0);
641 EXPECT_CALL(dispatcher_,
Paul Stewart1ac4e842012-07-10 12:58:12 -0700642 PostDelayedTask(_, GetDelayedDeviceCreationMilliseconds()));
Paul Stewart050cfc02012-07-06 20:38:54 -0700643 EXPECT_TRUE(GetDelayedDevices().empty());
644 EXPECT_FALSE(CreateDevice(
645 kTestDeviceName, "address", kTestDeviceIndex, Technology::kCDCEthernet));
646 EXPECT_FALSE(GetDelayedDevices().empty());
647 EXPECT_EQ(1, GetDelayedDevices().size());
648 EXPECT_EQ(kTestDeviceIndex, *GetDelayedDevices().begin());
649}
650
Paul Stewart8c116a92012-05-02 18:30:03 -0700651TEST_F(DeviceInfoTest, CreateDeviceUnknown) {
652 IPAddress address = CreateInterfaceAddress();
653
654 // An unknown (blacklisted, unhandled, etc) device won't be flushed or
655 // registered.
656 EXPECT_CALL(routing_table_, FlushRoutes(_)).Times(0);
657 EXPECT_CALL(rtnl_handler_, RemoveInterfaceAddress(_, _)).Times(0);
658 EXPECT_TRUE(CreateDevice(
659 kTestDeviceName, "address", kTestDeviceIndex, Technology::kUnknown));
Chris Masone9be4a9d2011-05-16 15:44:09 -0700660}
661
mukesh agrawal8f317b62011-07-15 11:53:23 -0700662TEST_F(DeviceInfoTest, DeviceBlackList) {
Peter Qiuebd709e2015-03-16 14:03:37 -0700663 // Manager is not running by default.
664 EXPECT_CALL(rtnl_handler_, RequestDump(RTNLHandler::kRequestLink)).Times(0);
665 device_info_.AddDeviceToBlackList(kTestDeviceName);
666 unique_ptr<RTNLMessage> message(BuildLinkMessage(RTNLMessage::kModeAdd));
667 SendMessageToDeviceInfo(*message);
668
669 DeviceRefPtr device = device_info_.GetDevice(kTestDeviceIndex);
670 ASSERT_TRUE(device.get());
671 EXPECT_TRUE(device->technology() == Technology::kBlacklisted);
672}
673
674TEST_F(DeviceInfoTest, AddDeviceToBlackListWithManagerRunning) {
675 SetManagerRunning(true);
Peter Qiu7e8b8ee2014-11-25 13:55:57 -0800676 EXPECT_CALL(rtnl_handler_, RequestDump(RTNLHandler::kRequestLink)).Times(1);
mukesh agrawal8f317b62011-07-15 11:53:23 -0700677 device_info_.AddDeviceToBlackList(kTestDeviceName);
Ben Chancd477322014-10-17 14:19:30 -0700678 unique_ptr<RTNLMessage> message(BuildLinkMessage(RTNLMessage::kModeAdd));
Darin Petkove6193c02011-08-11 12:42:40 -0700679 SendMessageToDeviceInfo(*message);
mukesh agrawal8f317b62011-07-15 11:53:23 -0700680
Darin Petkove6193c02011-08-11 12:42:40 -0700681 DeviceRefPtr device = device_info_.GetDevice(kTestDeviceIndex);
682 ASSERT_TRUE(device.get());
Joshua Krollda798622012-06-05 12:30:48 -0700683 EXPECT_TRUE(device->technology() == Technology::kBlacklisted);
mukesh agrawal8f317b62011-07-15 11:53:23 -0700684}
685
Paul Stewart9a908082011-08-31 12:18:48 -0700686TEST_F(DeviceInfoTest, DeviceAddressList) {
Ben Chancd477322014-10-17 14:19:30 -0700687 unique_ptr<RTNLMessage> message(BuildLinkMessage(RTNLMessage::kModeAdd));
Paul Stewart9a908082011-08-31 12:18:48 -0700688 SendMessageToDeviceInfo(*message);
689
690 vector<DeviceInfo::AddressData> addresses;
691 EXPECT_TRUE(device_info_.GetAddresses(kTestDeviceIndex, &addresses));
692 EXPECT_TRUE(addresses.empty());
693
694 // Add an address to the device address list
Paul Stewart7355ce12011-09-02 10:47:01 -0700695 IPAddress ip_address0(IPAddress::kFamilyIPv4);
Paul Stewart9a908082011-08-31 12:18:48 -0700696 EXPECT_TRUE(ip_address0.SetAddressFromString(kTestIPAddress0));
697 ip_address0.set_prefix(kTestIPAddressPrefix0);
698 message.reset(BuildAddressMessage(RTNLMessage::kModeAdd, ip_address0, 0, 0));
699 SendMessageToDeviceInfo(*message);
700 EXPECT_TRUE(device_info_.GetAddresses(kTestDeviceIndex, &addresses));
701 EXPECT_EQ(1, addresses.size());
702 EXPECT_TRUE(ip_address0.Equals(addresses[0].address));
703
704 // Re-adding the same address shouldn't cause the address list to change
705 SendMessageToDeviceInfo(*message);
706 EXPECT_TRUE(device_info_.GetAddresses(kTestDeviceIndex, &addresses));
707 EXPECT_EQ(1, addresses.size());
708 EXPECT_TRUE(ip_address0.Equals(addresses[0].address));
709
710 // Adding a new address should expand the list
Paul Stewart7355ce12011-09-02 10:47:01 -0700711 IPAddress ip_address1(IPAddress::kFamilyIPv6);
Paul Stewart9a908082011-08-31 12:18:48 -0700712 EXPECT_TRUE(ip_address1.SetAddressFromString(kTestIPAddress1));
713 ip_address1.set_prefix(kTestIPAddressPrefix1);
714 message.reset(BuildAddressMessage(RTNLMessage::kModeAdd, ip_address1, 0, 0));
715 SendMessageToDeviceInfo(*message);
716 EXPECT_TRUE(device_info_.GetAddresses(kTestDeviceIndex, &addresses));
717 EXPECT_EQ(2, addresses.size());
718 EXPECT_TRUE(ip_address0.Equals(addresses[0].address));
719 EXPECT_TRUE(ip_address1.Equals(addresses[1].address));
720
721 // Deleting an address should reduce the list
722 message.reset(BuildAddressMessage(RTNLMessage::kModeDelete,
723 ip_address0,
724 0,
725 0));
726 SendMessageToDeviceInfo(*message);
727 EXPECT_TRUE(device_info_.GetAddresses(kTestDeviceIndex, &addresses));
728 EXPECT_EQ(1, addresses.size());
729 EXPECT_TRUE(ip_address1.Equals(addresses[0].address));
730
731 // Delete last item
732 message.reset(BuildAddressMessage(RTNLMessage::kModeDelete,
733 ip_address1,
734 0,
735 0));
736 SendMessageToDeviceInfo(*message);
737 EXPECT_TRUE(device_info_.GetAddresses(kTestDeviceIndex, &addresses));
738 EXPECT_TRUE(addresses.empty());
739
740 // Delete device
741 message.reset(BuildLinkMessage(RTNLMessage::kModeDelete));
Paul Stewart8c116a92012-05-02 18:30:03 -0700742 EXPECT_CALL(manager_, DeregisterDevice(_)).Times(1);
Paul Stewart9a908082011-08-31 12:18:48 -0700743 SendMessageToDeviceInfo(*message);
744
745 // Should be able to handle message for interface that doesn't exist
746 message.reset(BuildAddressMessage(RTNLMessage::kModeAdd, ip_address0, 0, 0));
747 SendMessageToDeviceInfo(*message);
748 EXPECT_FALSE(device_info_.GetDevice(kTestDeviceIndex).get());
Paul Stewart9a908082011-08-31 12:18:48 -0700749}
750
751TEST_F(DeviceInfoTest, FlushAddressList) {
Ben Chancd477322014-10-17 14:19:30 -0700752 unique_ptr<RTNLMessage> message(BuildLinkMessage(RTNLMessage::kModeAdd));
Paul Stewart9a908082011-08-31 12:18:48 -0700753 SendMessageToDeviceInfo(*message);
754
Paul Stewart7355ce12011-09-02 10:47:01 -0700755 IPAddress address1(IPAddress::kFamilyIPv6);
Paul Stewart9a908082011-08-31 12:18:48 -0700756 EXPECT_TRUE(address1.SetAddressFromString(kTestIPAddress1));
757 address1.set_prefix(kTestIPAddressPrefix1);
758 message.reset(BuildAddressMessage(RTNLMessage::kModeAdd,
759 address1,
760 0,
761 RT_SCOPE_UNIVERSE));
762 SendMessageToDeviceInfo(*message);
Paul Stewart7355ce12011-09-02 10:47:01 -0700763 IPAddress address2(IPAddress::kFamilyIPv6);
Paul Stewart9a908082011-08-31 12:18:48 -0700764 EXPECT_TRUE(address2.SetAddressFromString(kTestIPAddress2));
765 message.reset(BuildAddressMessage(RTNLMessage::kModeAdd,
766 address2,
767 IFA_F_TEMPORARY,
768 RT_SCOPE_UNIVERSE));
769 SendMessageToDeviceInfo(*message);
Paul Stewart7355ce12011-09-02 10:47:01 -0700770 IPAddress address3(IPAddress::kFamilyIPv6);
Paul Stewart9a908082011-08-31 12:18:48 -0700771 EXPECT_TRUE(address3.SetAddressFromString(kTestIPAddress3));
772 message.reset(BuildAddressMessage(RTNLMessage::kModeAdd,
773 address3,
774 0,
775 RT_SCOPE_LINK));
776 SendMessageToDeviceInfo(*message);
Paul Stewart7355ce12011-09-02 10:47:01 -0700777 IPAddress address4(IPAddress::kFamilyIPv6);
Paul Stewart9a908082011-08-31 12:18:48 -0700778 EXPECT_TRUE(address4.SetAddressFromString(kTestIPAddress4));
779 message.reset(BuildAddressMessage(RTNLMessage::kModeAdd,
780 address4,
781 IFA_F_PERMANENT,
782 RT_SCOPE_UNIVERSE));
783 SendMessageToDeviceInfo(*message);
784
785 // DeviceInfo now has 4 addresses associated with it, but only two of
786 // them are valid for flush.
787 EXPECT_CALL(rtnl_handler_, RemoveInterfaceAddress(kTestDeviceIndex,
788 IsIPAddress(address1)));
789 EXPECT_CALL(rtnl_handler_, RemoveInterfaceAddress(kTestDeviceIndex,
790 IsIPAddress(address2)));
791 device_info_.FlushAddresses(kTestDeviceIndex);
Paul Stewart9a908082011-08-31 12:18:48 -0700792}
793
Paul Stewart05a42c22012-08-02 16:47:21 -0700794TEST_F(DeviceInfoTest, HasOtherAddress) {
Ben Chancd477322014-10-17 14:19:30 -0700795 unique_ptr<RTNLMessage> message(BuildLinkMessage(RTNLMessage::kModeAdd));
Paul Stewart05a42c22012-08-02 16:47:21 -0700796 SendMessageToDeviceInfo(*message);
797
798 IPAddress address0(IPAddress::kFamilyIPv4);
799 EXPECT_TRUE(address0.SetAddressFromString(kTestIPAddress0));
800
801 // There are no addresses on this interface.
802 EXPECT_FALSE(device_info_.HasOtherAddress(kTestDeviceIndex, address0));
803
804 message.reset(BuildAddressMessage(RTNLMessage::kModeAdd,
805 address0,
806 0,
807 RT_SCOPE_UNIVERSE));
808 SendMessageToDeviceInfo(*message);
809
810 IPAddress address1(IPAddress::kFamilyIPv6);
811 EXPECT_TRUE(address1.SetAddressFromString(kTestIPAddress1));
812 address1.set_prefix(kTestIPAddressPrefix1);
813 message.reset(BuildAddressMessage(RTNLMessage::kModeAdd,
814 address1,
815 0,
816 RT_SCOPE_LINK));
817 SendMessageToDeviceInfo(*message);
818
819 IPAddress address2(IPAddress::kFamilyIPv6);
820 EXPECT_TRUE(address2.SetAddressFromString(kTestIPAddress2));
821 message.reset(BuildAddressMessage(RTNLMessage::kModeAdd,
822 address2,
823 IFA_F_TEMPORARY,
824 RT_SCOPE_UNIVERSE));
825 SendMessageToDeviceInfo(*message);
826
827 IPAddress address3(IPAddress::kFamilyIPv6);
828 EXPECT_TRUE(address3.SetAddressFromString(kTestIPAddress3));
829
830 // The only IPv6 addresses on this interface are either flagged as
831 // temporary, or they are not universally scoped.
832 EXPECT_FALSE(device_info_.HasOtherAddress(kTestDeviceIndex, address3));
833
834
835 message.reset(BuildAddressMessage(RTNLMessage::kModeAdd,
836 address3,
837 0,
838 RT_SCOPE_UNIVERSE));
839 SendMessageToDeviceInfo(*message);
840
841 // address0 is on this interface.
842 EXPECT_FALSE(device_info_.HasOtherAddress(kTestDeviceIndex, address0));
843 // address1 is on this interface.
844 EXPECT_FALSE(device_info_.HasOtherAddress(kTestDeviceIndex, address1));
845 // address2 is on this interface.
846 EXPECT_FALSE(device_info_.HasOtherAddress(kTestDeviceIndex, address2));
847 // address3 is on this interface.
848 EXPECT_FALSE(device_info_.HasOtherAddress(kTestDeviceIndex, address3));
849
850 IPAddress address4(IPAddress::kFamilyIPv6);
851 EXPECT_TRUE(address4.SetAddressFromString(kTestIPAddress4));
852
853 // address4 is not on this interface, but address3 is, and is a qualified
854 // IPv6 address.
855 EXPECT_TRUE(device_info_.HasOtherAddress(kTestDeviceIndex, address4));
856
857 message.reset(BuildAddressMessage(RTNLMessage::kModeAdd,
858 address4,
859 IFA_F_PERMANENT,
860 RT_SCOPE_UNIVERSE));
861 SendMessageToDeviceInfo(*message);
862
863 // address4 is now on this interface.
864 EXPECT_FALSE(device_info_.HasOtherAddress(kTestDeviceIndex, address4));
865
866 IPAddress address5(IPAddress::kFamilyIPv4);
867 EXPECT_TRUE(address5.SetAddressFromString(kTestIPAddress5));
868 // address5 is not on this interface, but address0 is.
869 EXPECT_TRUE(device_info_.HasOtherAddress(kTestDeviceIndex, address5));
870
871 message.reset(BuildAddressMessage(RTNLMessage::kModeAdd,
872 address5,
873 IFA_F_PERMANENT,
874 RT_SCOPE_UNIVERSE));
875 SendMessageToDeviceInfo(*message);
876
877 // address5 is now on this interface.
878 EXPECT_FALSE(device_info_.HasOtherAddress(kTestDeviceIndex, address5));
879}
880
Paul Stewarta0db0ff2013-12-09 09:48:47 -0800881TEST_F(DeviceInfoTest, HasDirectConnectivityTo) {
Ben Chancd477322014-10-17 14:19:30 -0700882 unique_ptr<RTNLMessage> message(BuildLinkMessage(RTNLMessage::kModeAdd));
Paul Stewarta0db0ff2013-12-09 09:48:47 -0800883 SendMessageToDeviceInfo(*message);
884
885 IPAddress address0(IPAddress::kFamilyIPv4);
886 EXPECT_TRUE(address0.SetAddressFromString(kTestIPAddress0));
887
888 // There are no addresses on this interface.
889 EXPECT_FALSE(device_info_.HasDirectConnectivityTo(
890 kTestDeviceIndex, address0));
891
892 IPAddress address1(IPAddress::kFamilyIPv6);
893 EXPECT_TRUE(address1.SetAddressFromString(kTestIPAddress1));
894 message.reset(BuildAddressMessage(RTNLMessage::kModeAdd,
895 address1,
896 IFA_F_PERMANENT,
897 RT_SCOPE_UNIVERSE));
898 SendMessageToDeviceInfo(*message);
899
900 // No current addresses are of the same family as |address0|.
901 EXPECT_FALSE(device_info_.HasDirectConnectivityTo(
902 kTestDeviceIndex, address0));
903
904 IPAddress address6(IPAddress::kFamilyIPv4);
905 EXPECT_TRUE(address6.SetAddressFromString(kTestIPAddress6));
906 address6.set_prefix(kTestIPAddressPrefix0);
907 message.reset(BuildAddressMessage(RTNLMessage::kModeAdd,
908 address6,
909 IFA_F_PERMANENT,
910 RT_SCOPE_UNIVERSE));
911 SendMessageToDeviceInfo(*message);
912
913 // |address0| is not reachable from |address6|.
914 EXPECT_FALSE(device_info_.HasDirectConnectivityTo(
915 kTestDeviceIndex, address0));
916
917 IPAddress address5(IPAddress::kFamilyIPv4);
918 EXPECT_TRUE(address5.SetAddressFromString(kTestIPAddress5));
919 address5.set_prefix(kTestIPAddressPrefix0);
920 message.reset(BuildAddressMessage(RTNLMessage::kModeAdd,
921 address5,
922 IFA_F_PERMANENT,
923 RT_SCOPE_UNIVERSE));
924 SendMessageToDeviceInfo(*message);
925
926 // |address0| is reachable from |address5| which is associated with the
927 // interface.
928 EXPECT_TRUE(device_info_.HasDirectConnectivityTo(
929 kTestDeviceIndex, address0));
930}
931
Thieu Leb27beee2012-04-20 09:19:06 -0700932TEST_F(DeviceInfoTest, HasSubdir) {
Paul Stewart5ad16062013-02-21 18:10:48 -0800933 base::ScopedTempDir temp_dir;
Thieu Le8f1c8352012-04-16 11:02:12 -0700934 EXPECT_TRUE(temp_dir.CreateUniqueTempDir());
Ben Chana0ddf462014-02-06 11:32:42 -0800935 EXPECT_TRUE(base::CreateDirectory(temp_dir.path().Append("child1")));
Thieu Leb27beee2012-04-20 09:19:06 -0700936 FilePath child2 = temp_dir.path().Append("child2");
Ben Chana0ddf462014-02-06 11:32:42 -0800937 EXPECT_TRUE(base::CreateDirectory(child2));
Thieu Leb27beee2012-04-20 09:19:06 -0700938 FilePath grandchild = child2.Append("grandchild");
Ben Chana0ddf462014-02-06 11:32:42 -0800939 EXPECT_TRUE(base::CreateDirectory(grandchild));
940 EXPECT_TRUE(base::CreateDirectory(grandchild.Append("greatgrandchild")));
Thieu Leb27beee2012-04-20 09:19:06 -0700941 EXPECT_TRUE(DeviceInfo::HasSubdir(temp_dir.path(),
942 FilePath("grandchild")));
943 EXPECT_TRUE(DeviceInfo::HasSubdir(temp_dir.path(),
944 FilePath("greatgrandchild")));
945 EXPECT_FALSE(DeviceInfo::HasSubdir(temp_dir.path(),
946 FilePath("nonexistent")));
Thieu Le8f1c8352012-04-16 11:02:12 -0700947}
948
Gary Morain41780232012-07-31 15:08:31 -0700949TEST_F(DeviceInfoTest, GetMACAddressFromKernelUnknownDevice) {
950 SetSockets();
951 EXPECT_CALL(*mock_sockets_, Socket(PF_INET, SOCK_DGRAM, 0)).Times(0);
952 ByteString mac_address =
953 device_info_.GetMACAddressFromKernel(kTestDeviceIndex);
954 EXPECT_TRUE(mac_address.IsEmpty());
955}
956
957TEST_F(DeviceInfoTest, GetMACAddressFromKernelUnableToOpenSocket) {
958 SetSockets();
959 EXPECT_CALL(*mock_sockets_, Socket(PF_INET, SOCK_DGRAM, 0))
960 .WillOnce(Return(-1));
Ben Chancd477322014-10-17 14:19:30 -0700961 unique_ptr<RTNLMessage> message(BuildLinkMessage(RTNLMessage::kModeAdd));
Gary Morain41780232012-07-31 15:08:31 -0700962 message->set_link_status(RTNLMessage::LinkStatus(0, IFF_LOWER_UP, 0));
963 SendMessageToDeviceInfo(*message);
964 EXPECT_TRUE(device_info_.GetDevice(kTestDeviceIndex).get());
965 ByteString mac_address =
966 device_info_.GetMACAddressFromKernel(kTestDeviceIndex);
967 EXPECT_TRUE(mac_address.IsEmpty());
968}
969
970TEST_F(DeviceInfoTest, GetMACAddressFromKernelIoctlFails) {
971 SetSockets();
972 const int kFd = 99;
973 EXPECT_CALL(*mock_sockets_, Socket(PF_INET, SOCK_DGRAM, 0))
974 .WillOnce(Return(kFd));
975 EXPECT_CALL(*mock_sockets_, Ioctl(kFd, SIOCGIFHWADDR, NotNull()))
976 .WillOnce(Return(-1));
977 EXPECT_CALL(*mock_sockets_, Close(kFd));
978
Ben Chancd477322014-10-17 14:19:30 -0700979 unique_ptr<RTNLMessage> message(BuildLinkMessage(RTNLMessage::kModeAdd));
Gary Morain41780232012-07-31 15:08:31 -0700980 message->set_link_status(RTNLMessage::LinkStatus(0, IFF_LOWER_UP, 0));
981 SendMessageToDeviceInfo(*message);
982 EXPECT_TRUE(device_info_.GetDevice(kTestDeviceIndex).get());
983
984 ByteString mac_address =
985 device_info_.GetMACAddressFromKernel(kTestDeviceIndex);
986 EXPECT_TRUE(mac_address.IsEmpty());
987}
988
989MATCHER_P2(IfreqEquals, ifindex, ifname, "") {
Paul Stewart3b30ca52015-06-16 13:13:10 -0700990 const struct ifreq* const ifr = static_cast<struct ifreq*>(arg);
Ben Chancc225ef2014-09-30 13:26:51 -0700991 return (ifr != nullptr) &&
Gary Morain41780232012-07-31 15:08:31 -0700992 (ifr->ifr_ifindex == ifindex) &&
993 (strcmp(ifname, ifr->ifr_name) == 0);
994}
995
996ACTION_P(SetIfreq, ifr) {
Paul Stewart3b30ca52015-06-16 13:13:10 -0700997 struct ifreq* const ifr_arg = static_cast<struct ifreq*>(arg2);
Gary Morain41780232012-07-31 15:08:31 -0700998 *ifr_arg = ifr;
999}
1000
1001TEST_F(DeviceInfoTest, GetMACAddressFromKernel) {
1002 SetSockets();
1003 const int kFd = 99;
1004 struct ifreq ifr;
Han Shenfc349252012-08-30 11:36:04 -07001005 static uint8_t kMacAddress[] = {0x00, 0x01, 0x02, 0xaa, 0xbb, 0xcc};
Gary Morain41780232012-07-31 15:08:31 -07001006 memcpy(ifr.ifr_hwaddr.sa_data, kMacAddress, sizeof(kMacAddress));
1007 EXPECT_CALL(*mock_sockets_, Socket(PF_INET, SOCK_DGRAM, 0))
1008 .WillOnce(Return(kFd));
1009 EXPECT_CALL(*mock_sockets_,
1010 Ioctl(kFd, SIOCGIFHWADDR,
1011 IfreqEquals(kTestDeviceIndex, kTestDeviceName)))
1012 .WillOnce(DoAll(SetIfreq(ifr), Return(0)));
1013 EXPECT_CALL(*mock_sockets_, Close(kFd));
1014
Ben Chancd477322014-10-17 14:19:30 -07001015 unique_ptr<RTNLMessage> message(BuildLinkMessage(RTNLMessage::kModeAdd));
Gary Morain41780232012-07-31 15:08:31 -07001016 message->set_link_status(RTNLMessage::LinkStatus(0, IFF_LOWER_UP, 0));
1017 SendMessageToDeviceInfo(*message);
1018 EXPECT_TRUE(device_info_.GetDevice(kTestDeviceIndex).get());
1019
1020 ByteString mac_address =
1021 device_info_.GetMACAddressFromKernel(kTestDeviceIndex);
1022 EXPECT_THAT(kMacAddress,
1023 ElementsAreArray(mac_address.GetData(), sizeof(kMacAddress)));
1024}
1025
Paul Stewart6950ba52013-12-05 08:28:14 -08001026TEST_F(DeviceInfoTest, GetMACAddressOfPeerUnknownDevice) {
1027 SetSockets();
1028 EXPECT_CALL(*mock_sockets_, Socket(PF_INET, SOCK_DGRAM, 0)).Times(0);
1029 IPAddress address(IPAddress::kFamilyIPv4);
1030 EXPECT_TRUE(address.SetAddressFromString(kTestIPAddress0));
1031 ByteString mac_address;
1032 EXPECT_FALSE(device_info_.GetDevice(kTestDeviceIndex).get());
1033 EXPECT_FALSE(device_info_.GetMACAddressOfPeer(
1034 kTestDeviceIndex, address, &mac_address));
1035}
1036
1037TEST_F(DeviceInfoTest, GetMACAddressOfPeerBadAddress) {
1038 SetSockets();
Ben Chancd477322014-10-17 14:19:30 -07001039 unique_ptr<RTNLMessage> message(BuildLinkMessage(RTNLMessage::kModeAdd));
Paul Stewart6950ba52013-12-05 08:28:14 -08001040 message->set_link_status(RTNLMessage::LinkStatus(0, IFF_LOWER_UP, 0));
1041 SendMessageToDeviceInfo(*message);
1042 EXPECT_TRUE(device_info_.GetDevice(kTestDeviceIndex).get());
1043
1044 EXPECT_CALL(*mock_sockets_, Socket(PF_INET, SOCK_DGRAM, 0)).Times(0);
1045
1046 // An improperly formatted IPv4 address should fail.
1047 IPAddress empty_ipv4_address(IPAddress::kFamilyIPv4);
1048 ByteString mac_address;
1049 EXPECT_FALSE(device_info_.GetMACAddressOfPeer(
1050 kTestDeviceIndex, empty_ipv4_address, &mac_address));
1051
1052 // IPv6 addresses are not supported.
1053 IPAddress valid_ipv6_address(IPAddress::kFamilyIPv6);
1054 EXPECT_TRUE(valid_ipv6_address.SetAddressFromString(kTestIPAddress1));
1055 EXPECT_FALSE(device_info_.GetMACAddressOfPeer(
1056 kTestDeviceIndex, valid_ipv6_address, &mac_address));
1057}
1058
1059TEST_F(DeviceInfoTest, GetMACAddressOfPeerUnableToOpenSocket) {
1060 SetSockets();
1061 EXPECT_CALL(*mock_sockets_, Socket(PF_INET, SOCK_DGRAM, 0))
1062 .WillOnce(Return(-1));
Ben Chancd477322014-10-17 14:19:30 -07001063 unique_ptr<RTNLMessage> message(BuildLinkMessage(RTNLMessage::kModeAdd));
Paul Stewart6950ba52013-12-05 08:28:14 -08001064 message->set_link_status(RTNLMessage::LinkStatus(0, IFF_LOWER_UP, 0));
1065 SendMessageToDeviceInfo(*message);
1066 IPAddress ip_address(IPAddress::kFamilyIPv4);
1067 EXPECT_TRUE(ip_address.SetAddressFromString(kTestIPAddress0));
1068 ByteString mac_address;
1069 EXPECT_FALSE(device_info_.GetMACAddressOfPeer(
1070 kTestDeviceIndex, ip_address, &mac_address));
1071}
1072
1073TEST_F(DeviceInfoTest, GetMACAddressOfPeerIoctlFails) {
1074 SetSockets();
1075 const int kFd = 99;
1076 EXPECT_CALL(*mock_sockets_, Socket(PF_INET, SOCK_DGRAM, 0))
1077 .WillOnce(Return(kFd));
1078 EXPECT_CALL(*mock_sockets_, Ioctl(kFd, SIOCGARP, NotNull()))
1079 .WillOnce(Return(-1));
Ben Chancd477322014-10-17 14:19:30 -07001080 unique_ptr<RTNLMessage> message(BuildLinkMessage(RTNLMessage::kModeAdd));
Paul Stewart6950ba52013-12-05 08:28:14 -08001081 message->set_link_status(RTNLMessage::LinkStatus(0, IFF_LOWER_UP, 0));
1082 SendMessageToDeviceInfo(*message);
1083 IPAddress ip_address(IPAddress::kFamilyIPv4);
1084 EXPECT_TRUE(ip_address.SetAddressFromString(kTestIPAddress0));
1085 ByteString mac_address;
1086 EXPECT_FALSE(device_info_.GetMACAddressOfPeer(
1087 kTestDeviceIndex, ip_address, &mac_address));
1088}
1089
1090MATCHER_P2(ArpreqEquals, ifname, peer, "") {
Paul Stewart3b30ca52015-06-16 13:13:10 -07001091 const struct arpreq* const areq = static_cast<struct arpreq*>(arg);
Ben Chancc225ef2014-09-30 13:26:51 -07001092 if (areq == nullptr) {
Paul Stewart6950ba52013-12-05 08:28:14 -08001093 return false;
1094 }
1095
Paul Stewart3b30ca52015-06-16 13:13:10 -07001096 const struct sockaddr_in* const protocol_address =
1097 reinterpret_cast<const struct sockaddr_in*>(&areq->arp_pa);
1098 const struct sockaddr_in* const hardware_address =
1099 reinterpret_cast<const struct sockaddr_in*>(&areq->arp_ha);
Paul Stewart6950ba52013-12-05 08:28:14 -08001100
1101 return
1102 strcmp(ifname, areq->arp_dev) == 0 &&
1103 protocol_address->sin_family == AF_INET &&
1104 memcmp(&protocol_address->sin_addr.s_addr,
1105 peer.address().GetConstData(),
1106 peer.address().GetLength()) == 0 &&
1107 hardware_address->sin_family == ARPHRD_ETHER;
1108}
1109
1110ACTION_P(SetArpreq, areq) {
Paul Stewart3b30ca52015-06-16 13:13:10 -07001111 struct arpreq* const areq_arg = static_cast<struct arpreq*>(arg2);
Paul Stewart6950ba52013-12-05 08:28:14 -08001112 *areq_arg = areq;
1113}
1114
1115TEST_F(DeviceInfoTest, GetMACAddressOfPeer) {
Ben Chancd477322014-10-17 14:19:30 -07001116 unique_ptr<RTNLMessage> message(BuildLinkMessage(RTNLMessage::kModeAdd));
Paul Stewart6950ba52013-12-05 08:28:14 -08001117 message->set_link_status(RTNLMessage::LinkStatus(0, IFF_LOWER_UP, 0));
1118 SendMessageToDeviceInfo(*message);
1119
1120 SetSockets();
1121
1122 const int kFd = 99;
1123 EXPECT_CALL(*mock_sockets_, Socket(PF_INET, SOCK_DGRAM, 0))
1124 .WillRepeatedly(Return(kFd));
1125
1126 IPAddress ip_address(IPAddress::kFamilyIPv4);
1127 EXPECT_TRUE(ip_address.SetAddressFromString(kTestIPAddress0));
1128
1129 static uint8_t kZeroMacAddress[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
1130 struct arpreq zero_areq_response;
1131 memcpy(zero_areq_response.arp_ha.sa_data, kZeroMacAddress,
1132 sizeof(kZeroMacAddress));
1133
1134 static uint8_t kMacAddress[] = {0x01, 0x02, 0x03, 0xaa, 0xbb, 0xcc};
1135 struct arpreq areq_response;
1136 memcpy(areq_response.arp_ha.sa_data, kMacAddress, sizeof(kMacAddress));
1137
1138 EXPECT_CALL(*mock_sockets_, Ioctl(
1139 kFd, SIOCGARP, ArpreqEquals(kTestDeviceName, ip_address)))
1140 .WillOnce(DoAll(SetArpreq(zero_areq_response), Return(0)))
1141 .WillOnce(DoAll(SetArpreq(areq_response), Return(0)));
1142
1143 ByteString mac_address;
1144 EXPECT_FALSE(device_info_.GetMACAddressOfPeer(
1145 kTestDeviceIndex, ip_address, &mac_address));
1146 EXPECT_TRUE(device_info_.GetMACAddressOfPeer(
1147 kTestDeviceIndex, ip_address, &mac_address));
1148 EXPECT_THAT(kMacAddress,
1149 ElementsAreArray(mac_address.GetData(), sizeof(kMacAddress)));
1150}
1151
Paul Stewartd55f6ae2014-04-24 16:34:21 -07001152TEST_F(DeviceInfoTest, IPv6AddressChanged) {
1153 scoped_refptr<MockDevice> device(new MockDevice(
1154 &control_interface_, &dispatcher_, &metrics_, &manager_,
1155 "null0", "addr0", kTestDeviceIndex));
1156
1157 // Device info entry does not exist.
Ben Chancc225ef2014-09-30 13:26:51 -07001158 EXPECT_FALSE(device_info_.GetPrimaryIPv6Address(kTestDeviceIndex, nullptr));
Paul Stewartd55f6ae2014-04-24 16:34:21 -07001159
1160 device_info_.infos_[kTestDeviceIndex].device = device;
1161
1162 // Device info entry contains no addresses.
Ben Chancc225ef2014-09-30 13:26:51 -07001163 EXPECT_FALSE(device_info_.GetPrimaryIPv6Address(kTestDeviceIndex, nullptr));
Paul Stewartd55f6ae2014-04-24 16:34:21 -07001164
1165 IPAddress ipv4_address(IPAddress::kFamilyIPv4);
1166 EXPECT_TRUE(ipv4_address.SetAddressFromString(kTestIPAddress0));
Ben Chancd477322014-10-17 14:19:30 -07001167 unique_ptr<RTNLMessage> message(
1168 BuildAddressMessage(RTNLMessage::kModeAdd, ipv4_address, 0, 0));
Paul Stewartd55f6ae2014-04-24 16:34:21 -07001169
1170 EXPECT_CALL(*device, OnIPv6AddressChanged()).Times(0);
1171
1172 // We should ignore IPv4 addresses.
1173 SendMessageToDeviceInfo(*message);
Ben Chancc225ef2014-09-30 13:26:51 -07001174 EXPECT_FALSE(device_info_.GetPrimaryIPv6Address(kTestDeviceIndex, nullptr));
Paul Stewartd55f6ae2014-04-24 16:34:21 -07001175
1176 IPAddress ipv6_address1(IPAddress::kFamilyIPv6);
1177 EXPECT_TRUE(ipv6_address1.SetAddressFromString(kTestIPAddress1));
1178 message.reset(BuildAddressMessage(
1179 RTNLMessage::kModeAdd, ipv6_address1, 0, RT_SCOPE_LINK));
1180
1181 // We should ignore non-SCOPE_UNIVERSE messages for IPv6.
1182 SendMessageToDeviceInfo(*message);
Ben Chancc225ef2014-09-30 13:26:51 -07001183 EXPECT_FALSE(device_info_.GetPrimaryIPv6Address(kTestDeviceIndex, nullptr));
Paul Stewartd55f6ae2014-04-24 16:34:21 -07001184
Alex Vakulenko0951ccb2014-12-10 12:52:31 -08001185 Mock::VerifyAndClearExpectations(device.get());
Paul Stewartd55f6ae2014-04-24 16:34:21 -07001186 IPAddress ipv6_address2(IPAddress::kFamilyIPv6);
1187 EXPECT_TRUE(ipv6_address2.SetAddressFromString(kTestIPAddress2));
1188 message.reset(BuildAddressMessage(
1189 RTNLMessage::kModeAdd, ipv6_address2, IFA_F_TEMPORARY,
1190 RT_SCOPE_UNIVERSE));
1191
1192 // Add a temporary address.
1193 EXPECT_CALL(*device, OnIPv6AddressChanged());
1194 SendMessageToDeviceInfo(*message);
1195 IPAddress address0(IPAddress::kFamilyUnknown);
1196 EXPECT_TRUE(device_info_.GetPrimaryIPv6Address(kTestDeviceIndex, &address0));
1197 EXPECT_TRUE(address0.Equals(ipv6_address2));
Alex Vakulenko0951ccb2014-12-10 12:52:31 -08001198 Mock::VerifyAndClearExpectations(device.get());
Paul Stewartd55f6ae2014-04-24 16:34:21 -07001199
1200 IPAddress ipv6_address3(IPAddress::kFamilyIPv6);
1201 EXPECT_TRUE(ipv6_address3.SetAddressFromString(kTestIPAddress3));
1202 message.reset(BuildAddressMessage(
1203 RTNLMessage::kModeAdd, ipv6_address3, 0, RT_SCOPE_UNIVERSE));
1204
1205 // Adding a non-temporary address alerts the Device, but does not override
1206 // the primary address since the previous one was temporary.
1207 EXPECT_CALL(*device, OnIPv6AddressChanged());
1208 SendMessageToDeviceInfo(*message);
1209 IPAddress address1(IPAddress::kFamilyUnknown);
1210 EXPECT_TRUE(device_info_.GetPrimaryIPv6Address(kTestDeviceIndex, &address1));
1211 EXPECT_TRUE(address1.Equals(ipv6_address2));
Alex Vakulenko0951ccb2014-12-10 12:52:31 -08001212 Mock::VerifyAndClearExpectations(device.get());
Paul Stewartd55f6ae2014-04-24 16:34:21 -07001213
1214 IPAddress ipv6_address4(IPAddress::kFamilyIPv6);
1215 EXPECT_TRUE(ipv6_address4.SetAddressFromString(kTestIPAddress4));
1216 message.reset(BuildAddressMessage(
1217 RTNLMessage::kModeAdd, ipv6_address4, IFA_F_TEMPORARY,
1218 RT_SCOPE_UNIVERSE));
1219
1220 // Another temporary address alerts the Device, and will override
1221 // the primary address.
1222 EXPECT_CALL(*device, OnIPv6AddressChanged());
1223 SendMessageToDeviceInfo(*message);
1224 IPAddress address2(IPAddress::kFamilyUnknown);
1225 EXPECT_TRUE(device_info_.GetPrimaryIPv6Address(kTestDeviceIndex, &address2));
1226 EXPECT_TRUE(address2.Equals(ipv6_address4));
1227}
1228
Peter Qiu98551702014-07-28 13:28:53 -07001229
1230TEST_F(DeviceInfoTest, IPv6DnsServerAddressesChanged) {
1231 scoped_refptr<MockDevice> device(new MockDevice(
1232 &control_interface_, &dispatcher_, &metrics_, &manager_,
1233 "null0", "addr0", kTestDeviceIndex));
1234 device_info_.time_ = &time_;
1235 vector<IPAddress> dns_server_addresses_out;
Ben Chan7fab8972014-08-10 17:14:46 -07001236 uint32_t lifetime_out;
Peter Qiu98551702014-07-28 13:28:53 -07001237
1238 // Device info entry does not exist.
1239 EXPECT_FALSE(device_info_.GetIPv6DnsServerAddresses(
1240 kTestDeviceIndex, &dns_server_addresses_out, &lifetime_out));
1241
1242 device_info_.infos_[kTestDeviceIndex].device = device;
1243
1244 // Device info entry contains no IPv6 dns server addresses.
1245 EXPECT_FALSE(device_info_.GetIPv6DnsServerAddresses(
1246 kTestDeviceIndex, &dns_server_addresses_out, &lifetime_out));
1247
1248 // Setup IPv6 dns server addresses.
1249 IPAddress ipv6_address1(IPAddress::kFamilyIPv6);
1250 IPAddress ipv6_address2(IPAddress::kFamilyIPv6);
1251 EXPECT_TRUE(ipv6_address1.SetAddressFromString(kTestIPAddress1));
1252 EXPECT_TRUE(ipv6_address2.SetAddressFromString(kTestIPAddress2));
1253 vector<IPAddress> dns_server_addresses_in;
1254 dns_server_addresses_in.push_back(ipv6_address1);
1255 dns_server_addresses_in.push_back(ipv6_address2);
1256
1257 // Infinite lifetime
Ben Chan7fab8972014-08-10 17:14:46 -07001258 const uint32_t kInfiniteLifetime = 0xffffffff;
Ben Chancd477322014-10-17 14:19:30 -07001259 unique_ptr<RTNLMessage> message(BuildRdnssMessage(
1260 RTNLMessage::kModeAdd, kInfiniteLifetime, dns_server_addresses_in));
Peter Qiu98551702014-07-28 13:28:53 -07001261 EXPECT_CALL(time_, GetSecondsBoottime(_)).
1262 WillOnce(DoAll(SetArgPointee<0>(0), Return(true)));
1263 EXPECT_CALL(*device, OnIPv6DnsServerAddressesChanged()).Times(1);
1264 SendMessageToDeviceInfo(*message);
1265 EXPECT_CALL(time_, GetSecondsBoottime(_)).Times(0);
1266 EXPECT_TRUE(device_info_.GetIPv6DnsServerAddresses(
1267 kTestDeviceIndex, &dns_server_addresses_out, &lifetime_out));
1268 // Verify addresses and lifetime.
1269 EXPECT_EQ(kInfiniteLifetime, lifetime_out);
1270 EXPECT_EQ(2, dns_server_addresses_out.size());
1271 EXPECT_EQ(kTestIPAddress1, dns_server_addresses_out.at(0).ToString());
1272 EXPECT_EQ(kTestIPAddress2, dns_server_addresses_out.at(1).ToString());
1273
1274 // Lifetime of 120, retrieve DNS server addresses after 10 seconds.
Ben Chan7fab8972014-08-10 17:14:46 -07001275 const uint32_t kLifetime120 = 120;
1276 const uint32_t kElapseTime10 = 10;
Ben Chancd477322014-10-17 14:19:30 -07001277 unique_ptr<RTNLMessage> message1(BuildRdnssMessage(
1278 RTNLMessage::kModeAdd, kLifetime120, dns_server_addresses_in));
Peter Qiu98551702014-07-28 13:28:53 -07001279 EXPECT_CALL(time_, GetSecondsBoottime(_)).
1280 WillOnce(DoAll(SetArgPointee<0>(0), Return(true)));
1281 EXPECT_CALL(*device, OnIPv6DnsServerAddressesChanged()).Times(1);
1282 SendMessageToDeviceInfo(*message1);
1283 // 10 seconds passed when GetIPv6DnsServerAddreses is called.
1284 EXPECT_CALL(time_, GetSecondsBoottime(_)).
1285 WillOnce(DoAll(SetArgPointee<0>(kElapseTime10), Return(true)));
1286 EXPECT_TRUE(device_info_.GetIPv6DnsServerAddresses(
1287 kTestDeviceIndex, &dns_server_addresses_out, &lifetime_out));
1288 // Verify addresses and lifetime.
1289 EXPECT_EQ(kLifetime120 - kElapseTime10, lifetime_out);
1290 EXPECT_EQ(2, dns_server_addresses_out.size());
1291 EXPECT_EQ(kTestIPAddress1, dns_server_addresses_out.at(0).ToString());
1292 EXPECT_EQ(kTestIPAddress2, dns_server_addresses_out.at(1).ToString());
1293
1294 // Lifetime of 120, retrieve DNS server addresses after lifetime expired.
1295 EXPECT_CALL(time_, GetSecondsBoottime(_)).
1296 WillOnce(DoAll(SetArgPointee<0>(0), Return(true)));
1297 EXPECT_CALL(*device, OnIPv6DnsServerAddressesChanged()).Times(1);
1298 SendMessageToDeviceInfo(*message1);
1299 // 120 seconds passed when GetIPv6DnsServerAddreses is called.
1300 EXPECT_CALL(time_, GetSecondsBoottime(_)).
1301 WillOnce(DoAll(SetArgPointee<0>(kLifetime120), Return(true)));
1302 EXPECT_TRUE(device_info_.GetIPv6DnsServerAddresses(
1303 kTestDeviceIndex, &dns_server_addresses_out, &lifetime_out));
1304 // Verify addresses and lifetime.
1305 EXPECT_EQ(0, lifetime_out);
1306 EXPECT_EQ(2, dns_server_addresses_out.size());
1307 EXPECT_EQ(kTestIPAddress1, dns_server_addresses_out.at(0).ToString());
1308 EXPECT_EQ(kTestIPAddress2, dns_server_addresses_out.at(1).ToString());
1309}
1310
Paul Stewartca876ee2012-04-21 08:55:58 -07001311class DeviceInfoTechnologyTest : public DeviceInfoTest {
1312 public:
Jason Glasgowabc54032012-04-20 16:08:32 -04001313 DeviceInfoTechnologyTest()
1314 : DeviceInfoTest(),
1315 test_device_name_(kTestDeviceName) {}
Paul Stewartca876ee2012-04-21 08:55:58 -07001316 virtual ~DeviceInfoTechnologyTest() {}
1317
1318 virtual void SetUp() {
mukesh agrawal62ba51c2014-04-18 16:09:58 -07001319 CHECK(temp_dir_.CreateUniqueTempDir());
Paul Stewartca876ee2012-04-21 08:55:58 -07001320 device_info_root_ = temp_dir_.path().Append("sys/class/net");
1321 device_info_.device_info_root_ = device_info_root_;
1322 // Most tests require that the uevent file exist.
1323 CreateInfoFile("uevent", "xxx");
1324 }
1325
1326 Technology::Identifier GetDeviceTechnology() {
Jason Glasgowabc54032012-04-20 16:08:32 -04001327 return device_info_.GetDeviceTechnology(test_device_name_);
Paul Stewartca876ee2012-04-21 08:55:58 -07001328 }
Paul Stewart3b30ca52015-06-16 13:13:10 -07001329 FilePath GetInfoPath(const string& name);
1330 void CreateInfoFile(const string& name, const string& contents);
1331 void CreateInfoSymLink(const string& name, const string& contents);
1332 void SetDeviceName(const string& name) {
Jason Glasgowabc54032012-04-20 16:08:32 -04001333 test_device_name_ = name;
mukesh agrawal62ba51c2014-04-18 16:09:58 -07001334 EXPECT_TRUE(temp_dir_.Delete()); // nuke old temp dir
Jason Glasgowabc54032012-04-20 16:08:32 -04001335 SetUp();
1336 }
Paul Stewartca876ee2012-04-21 08:55:58 -07001337
1338 protected:
Paul Stewart5ad16062013-02-21 18:10:48 -08001339 base::ScopedTempDir temp_dir_;
Paul Stewartca876ee2012-04-21 08:55:58 -07001340 FilePath device_info_root_;
Jason Glasgowabc54032012-04-20 16:08:32 -04001341 string test_device_name_;
Paul Stewartca876ee2012-04-21 08:55:58 -07001342};
1343
Paul Stewart3b30ca52015-06-16 13:13:10 -07001344FilePath DeviceInfoTechnologyTest::GetInfoPath(const string& name) {
Jason Glasgowabc54032012-04-20 16:08:32 -04001345 return device_info_root_.Append(test_device_name_).Append(name);
Paul Stewartca876ee2012-04-21 08:55:58 -07001346}
1347
Paul Stewart3b30ca52015-06-16 13:13:10 -07001348void DeviceInfoTechnologyTest::CreateInfoFile(const string& name,
1349 const string& contents) {
Paul Stewartca876ee2012-04-21 08:55:58 -07001350 FilePath info_path = GetInfoPath(name);
Ben Chana0ddf462014-02-06 11:32:42 -08001351 EXPECT_TRUE(base::CreateDirectory(info_path.DirName()));
Paul Stewartca876ee2012-04-21 08:55:58 -07001352 string contents_newline(contents + "\n");
Ben Chan6fbf64f2014-05-21 18:07:01 -07001353 EXPECT_TRUE(base::WriteFile(info_path, contents_newline.c_str(),
1354 contents_newline.size()));
Paul Stewartca876ee2012-04-21 08:55:58 -07001355}
1356
Paul Stewart3b30ca52015-06-16 13:13:10 -07001357void DeviceInfoTechnologyTest::CreateInfoSymLink(const string& name,
1358 const string& contents) {
Paul Stewartca876ee2012-04-21 08:55:58 -07001359 FilePath info_path = GetInfoPath(name);
Ben Chana0ddf462014-02-06 11:32:42 -08001360 EXPECT_TRUE(base::CreateDirectory(info_path.DirName()));
1361 EXPECT_TRUE(base::CreateSymbolicLink(FilePath(contents), info_path));
Paul Stewartca876ee2012-04-21 08:55:58 -07001362}
1363
1364TEST_F(DeviceInfoTechnologyTest, Unknown) {
Paul Stewartda8cbee2014-10-20 11:44:03 -07001365 // With a uevent file but no driver symlink, we should act as if this
Paul Stewart83d62562015-02-09 19:57:47 -08001366 // is a regular Ethernet driver by default.
Paul Stewart1ce231c2015-06-12 19:44:22 -07001367 EXPECT_CALL(manager_, ignore_unknown_ethernet())
1368 .WillRepeatedly(Return(false));
Paul Stewartda8cbee2014-10-20 11:44:03 -07001369 EXPECT_EQ(Technology::kEthernet, GetDeviceTechnology());
1370
1371 // Should be unknown without a uevent file.
Ben Chana0ddf462014-02-06 11:32:42 -08001372 EXPECT_TRUE(base::DeleteFile(GetInfoPath("uevent"), false));
Paul Stewartca876ee2012-04-21 08:55:58 -07001373 EXPECT_EQ(Technology::kUnknown, GetDeviceTechnology());
1374}
1375
Paul Stewart83d62562015-02-09 19:57:47 -08001376TEST_F(DeviceInfoTechnologyTest, UnknownWithNoSymlink) {
1377 // If the manager is setup to ignore devices with no device symlink,
1378 // this device should instead be unknown.
Paul Stewart1ce231c2015-06-12 19:44:22 -07001379 EXPECT_CALL(manager_, ignore_unknown_ethernet()).WillOnce(Return(true));
Paul Stewart83d62562015-02-09 19:57:47 -08001380 EXPECT_EQ(Technology::kUnknown, GetDeviceTechnology());
1381}
1382
1383TEST_F(DeviceInfoTechnologyTest, IgnoredPrefix) {
1384 test_device_name_ = "veth0";
1385 // A new uevent file is needed since the device name has changed.
1386 CreateInfoFile("uevent", "xxx");
1387 // A device with a "veth" prefix should be ignored.
1388 EXPECT_EQ(Technology::kUnknown, GetDeviceTechnology());
1389}
1390
Paul Stewartca876ee2012-04-21 08:55:58 -07001391TEST_F(DeviceInfoTechnologyTest, Loopback) {
1392 CreateInfoFile("type", base::IntToString(ARPHRD_LOOPBACK));
1393 EXPECT_EQ(Technology::kLoopback, GetDeviceTechnology());
1394}
1395
1396TEST_F(DeviceInfoTechnologyTest, PPP) {
1397 CreateInfoFile("type", base::IntToString(ARPHRD_PPP));
1398 EXPECT_EQ(Technology::kPPP, GetDeviceTechnology());
1399}
1400
1401TEST_F(DeviceInfoTechnologyTest, Tunnel) {
1402 CreateInfoFile("tun_flags", base::IntToString(IFF_TUN));
1403 EXPECT_EQ(Technology::kTunnel, GetDeviceTechnology());
1404}
1405
1406TEST_F(DeviceInfoTechnologyTest, WiFi) {
1407 CreateInfoFile("uevent", "DEVTYPE=wlan");
1408 EXPECT_EQ(Technology::kWifi, GetDeviceTechnology());
1409 CreateInfoFile("uevent", "foo\nDEVTYPE=wlan");
1410 EXPECT_EQ(Technology::kWifi, GetDeviceTechnology());
1411 CreateInfoFile("type", base::IntToString(ARPHRD_IEEE80211_RADIOTAP));
1412 EXPECT_EQ(Technology::kWiFiMonitor, GetDeviceTechnology());
1413}
1414
1415TEST_F(DeviceInfoTechnologyTest, Ethernet) {
1416 CreateInfoSymLink("device/driver", "xxx");
1417 EXPECT_EQ(Technology::kEthernet, GetDeviceTechnology());
1418}
1419
Darin Petkove4b27022012-05-16 13:28:50 +02001420TEST_F(DeviceInfoTechnologyTest, WiMax) {
1421 CreateInfoSymLink("device/driver", "gdm_wimax");
1422 EXPECT_EQ(Technology::kWiMax, GetDeviceTechnology());
1423}
1424
Paul Stewartca876ee2012-04-21 08:55:58 -07001425TEST_F(DeviceInfoTechnologyTest, CellularGobi1) {
1426 CreateInfoSymLink("device/driver", "blah/foo/gobi");
1427 EXPECT_EQ(Technology::kCellular, GetDeviceTechnology());
1428}
1429
1430TEST_F(DeviceInfoTechnologyTest, CellularGobi2) {
1431 CreateInfoSymLink("device/driver", "../GobiNet");
1432 EXPECT_EQ(Technology::kCellular, GetDeviceTechnology());
1433}
1434
1435TEST_F(DeviceInfoTechnologyTest, QCUSB) {
1436 CreateInfoSymLink("device/driver", "QCUSBNet2k");
1437 EXPECT_EQ(Technology::kCellular, GetDeviceTechnology());
1438}
1439
Ben Chan0f90e0b2013-06-26 23:37:16 -07001440TEST_F(DeviceInfoTechnologyTest, CellularCdcMbim) {
1441 CreateInfoSymLink("device/driver", "cdc_mbim");
1442 EXPECT_EQ(Technology::kCellular, GetDeviceTechnology());
1443}
1444
Ben Chan226d46a2012-10-11 00:22:17 -07001445TEST_F(DeviceInfoTechnologyTest, CellularQmiWwan) {
1446 CreateInfoSymLink("device/driver", "qmi_wwan");
1447 EXPECT_EQ(Technology::kCellular, GetDeviceTechnology());
1448}
1449
Paul Stewartca876ee2012-04-21 08:55:58 -07001450// Modem with absolute driver path with top-level tty file:
1451// /sys/class/net/dev0/device -> /sys/devices/virtual/0/00
Ben Chan4eb4ddf2013-06-20 22:16:56 -07001452// /sys/devices/virtual/0/00/driver -> /drivers/cdc_ether or /drivers/cdc_ncm
Paul Stewartca876ee2012-04-21 08:55:58 -07001453// /sys/devices/virtual/0/01/tty [empty directory]
Ben Chan4eb4ddf2013-06-20 22:16:56 -07001454TEST_F(DeviceInfoTechnologyTest, CDCEthernetModem1) {
Paul Stewartca876ee2012-04-21 08:55:58 -07001455 FilePath device_root(temp_dir_.path().Append("sys/devices/virtual/0"));
1456 FilePath device_path(device_root.Append("00"));
Ben Chan4eb4ddf2013-06-20 22:16:56 -07001457 FilePath driver_symlink(device_path.Append("driver"));
Ben Chana0ddf462014-02-06 11:32:42 -08001458 EXPECT_TRUE(base::CreateDirectory(device_path));
Paul Stewartca876ee2012-04-21 08:55:58 -07001459 CreateInfoSymLink("device", device_path.value());
Ben Chana0ddf462014-02-06 11:32:42 -08001460 EXPECT_TRUE(base::CreateSymbolicLink(FilePath("/drivers/cdc_ether"),
1461 driver_symlink));
1462 EXPECT_TRUE(base::CreateDirectory(device_root.Append("01/tty")));
Paul Stewartca876ee2012-04-21 08:55:58 -07001463 EXPECT_EQ(Technology::kCellular, GetDeviceTechnology());
Ben Chan4eb4ddf2013-06-20 22:16:56 -07001464
Ben Chana0ddf462014-02-06 11:32:42 -08001465 EXPECT_TRUE(base::DeleteFile(driver_symlink, false));
1466 EXPECT_TRUE(base::CreateSymbolicLink(FilePath("/drivers/cdc_ncm"),
1467 driver_symlink));
Ben Chan4eb4ddf2013-06-20 22:16:56 -07001468 EXPECT_EQ(Technology::kCellular, GetDeviceTechnology());
Paul Stewartca876ee2012-04-21 08:55:58 -07001469}
1470
1471// Modem with relative driver path with top-level tty file.
1472// /sys/class/net/dev0/device -> ../../../device_dir/0/00
Ben Chan4eb4ddf2013-06-20 22:16:56 -07001473// /sys/device_dir/0/00/driver -> /drivers/cdc_ether or /drivers/cdc_ncm
Paul Stewartca876ee2012-04-21 08:55:58 -07001474// /sys/device_dir/0/01/tty [empty directory]
Ben Chan4eb4ddf2013-06-20 22:16:56 -07001475TEST_F(DeviceInfoTechnologyTest, CDCEthernetModem2) {
Paul Stewartca876ee2012-04-21 08:55:58 -07001476 CreateInfoSymLink("device", "../../../device_dir/0/00");
1477 FilePath device_root(temp_dir_.path().Append("sys/device_dir/0"));
1478 FilePath device_path(device_root.Append("00"));
Ben Chan4eb4ddf2013-06-20 22:16:56 -07001479 FilePath driver_symlink(device_path.Append("driver"));
Ben Chana0ddf462014-02-06 11:32:42 -08001480 EXPECT_TRUE(base::CreateDirectory(device_path));
1481 EXPECT_TRUE(base::CreateSymbolicLink(FilePath("/drivers/cdc_ether"),
1482 driver_symlink));
1483 EXPECT_TRUE(base::CreateDirectory(device_root.Append("01/tty")));
Paul Stewartca876ee2012-04-21 08:55:58 -07001484 EXPECT_EQ(Technology::kCellular, GetDeviceTechnology());
Ben Chan4eb4ddf2013-06-20 22:16:56 -07001485
Ben Chana0ddf462014-02-06 11:32:42 -08001486 EXPECT_TRUE(base::DeleteFile(driver_symlink, false));
1487 EXPECT_TRUE(base::CreateSymbolicLink(FilePath("/drivers/cdc_ncm"),
1488 driver_symlink));
Ben Chan4eb4ddf2013-06-20 22:16:56 -07001489 EXPECT_EQ(Technology::kCellular, GetDeviceTechnology());
Paul Stewartca876ee2012-04-21 08:55:58 -07001490}
1491
1492// Modem with relative driver path with lower-level tty file.
1493// /sys/class/net/dev0/device -> ../../../device_dir/0/00
Ben Chan4eb4ddf2013-06-20 22:16:56 -07001494// /sys/device_dir/0/00/driver -> /drivers/cdc_ether or /drivers/cdc_ncm
Paul Stewartca876ee2012-04-21 08:55:58 -07001495// /sys/device_dir/0/01/yyy/tty [empty directory]
Ben Chan4eb4ddf2013-06-20 22:16:56 -07001496TEST_F(DeviceInfoTechnologyTest, CDCEthernetModem3) {
Paul Stewartca876ee2012-04-21 08:55:58 -07001497 CreateInfoSymLink("device", "../../../device_dir/0/00");
1498 FilePath device_root(temp_dir_.path().Append("sys/device_dir/0"));
1499 FilePath device_path(device_root.Append("00"));
Ben Chan4eb4ddf2013-06-20 22:16:56 -07001500 FilePath driver_symlink(device_path.Append("driver"));
Ben Chana0ddf462014-02-06 11:32:42 -08001501 EXPECT_TRUE(base::CreateDirectory(device_path));
1502 EXPECT_TRUE(base::CreateSymbolicLink(FilePath("/drivers/cdc_ether"),
1503 driver_symlink));
1504 EXPECT_TRUE(base::CreateDirectory(device_root.Append("01/yyy/tty")));
Paul Stewartca876ee2012-04-21 08:55:58 -07001505 EXPECT_EQ(Technology::kCellular, GetDeviceTechnology());
Ben Chan4eb4ddf2013-06-20 22:16:56 -07001506
Ben Chana0ddf462014-02-06 11:32:42 -08001507 EXPECT_TRUE(base::DeleteFile(driver_symlink, false));
1508 EXPECT_TRUE(base::CreateSymbolicLink(FilePath("/drivers/cdc_ncm"),
1509 driver_symlink));
Ben Chan4eb4ddf2013-06-20 22:16:56 -07001510 EXPECT_EQ(Technology::kCellular, GetDeviceTechnology());
Paul Stewartca876ee2012-04-21 08:55:58 -07001511}
1512
1513TEST_F(DeviceInfoTechnologyTest, CDCEtherNonModem) {
1514 CreateInfoSymLink("device", "device_dir");
1515 CreateInfoSymLink("device_dir/driver", "cdc_ether");
Paul Stewart050cfc02012-07-06 20:38:54 -07001516 EXPECT_EQ(Technology::kCDCEthernet, GetDeviceTechnology());
Paul Stewartca876ee2012-04-21 08:55:58 -07001517}
1518
Ben Chan4eb4ddf2013-06-20 22:16:56 -07001519TEST_F(DeviceInfoTechnologyTest, CDCNcmNonModem) {
1520 CreateInfoSymLink("device", "device_dir");
1521 CreateInfoSymLink("device_dir/driver", "cdc_ncm");
1522 EXPECT_EQ(Technology::kCDCEthernet, GetDeviceTechnology());
1523}
1524
Jason Glasgowabc54032012-04-20 16:08:32 -04001525TEST_F(DeviceInfoTechnologyTest, PseudoModem) {
1526 SetDeviceName("pseudomodem");
1527 CreateInfoSymLink("device", "device_dir");
1528 CreateInfoSymLink("device_dir/driver", "cdc_ether");
1529 EXPECT_EQ(Technology::kCellular, GetDeviceTechnology());
1530
1531 SetDeviceName("pseudomodem9");
1532 CreateInfoSymLink("device", "device_dir");
1533 CreateInfoSymLink("device_dir/driver", "cdc_ether");
1534 EXPECT_EQ(Technology::kCellular, GetDeviceTechnology());
1535}
1536
Paul Stewart050cfc02012-07-06 20:38:54 -07001537class DeviceInfoForDelayedCreationTest : public DeviceInfo {
1538 public:
Paul Stewart3b30ca52015-06-16 13:13:10 -07001539 DeviceInfoForDelayedCreationTest(ControlInterface* control_interface,
1540 EventDispatcher* dispatcher,
1541 Metrics* metrics,
1542 Manager* manager)
Paul Stewart050cfc02012-07-06 20:38:54 -07001543 : DeviceInfo(control_interface, dispatcher, metrics, manager) {}
Paul Stewart3b30ca52015-06-16 13:13:10 -07001544 MOCK_METHOD4(CreateDevice, DeviceRefPtr(const std::string& link_name,
1545 const std::string& address,
Paul Stewart050cfc02012-07-06 20:38:54 -07001546 int interface_index,
1547 Technology::Identifier technology));
1548 MOCK_METHOD1(GetDeviceTechnology,
Paul Stewart3b30ca52015-06-16 13:13:10 -07001549 Technology::Identifier(const string& iface_name));
Paul Stewart050cfc02012-07-06 20:38:54 -07001550};
1551
1552class DeviceInfoDelayedCreationTest : public DeviceInfoTest {
1553 public:
1554 DeviceInfoDelayedCreationTest()
1555 : DeviceInfoTest(),
1556 test_device_info_(
1557 &control_interface_, &dispatcher_, &metrics_, &manager_) {}
1558 virtual ~DeviceInfoDelayedCreationTest() {}
1559
Paul Stewart3b30ca52015-06-16 13:13:10 -07001560 virtual std::set<int>& GetDelayedDevices() {
Paul Stewart050cfc02012-07-06 20:38:54 -07001561 return test_device_info_.delayed_devices_;
1562 }
1563
1564 void DelayedDeviceCreationTask() {
1565 test_device_info_.DelayedDeviceCreationTask();
1566 }
1567
1568 void AddDelayedDevice() {
Ben Chancd477322014-10-17 14:19:30 -07001569 unique_ptr<RTNLMessage> message(BuildLinkMessage(RTNLMessage::kModeAdd));
Paul Stewart050cfc02012-07-06 20:38:54 -07001570 EXPECT_CALL(test_device_info_, GetDeviceTechnology(kTestDeviceName))
1571 .WillOnce(Return(Technology::kCDCEthernet));
1572 EXPECT_CALL(test_device_info_, CreateDevice(
1573 kTestDeviceName, _, kTestDeviceIndex, Technology::kCDCEthernet))
1574 .WillOnce(Return(DeviceRefPtr()));
1575 test_device_info_.AddLinkMsgHandler(*message);
1576 Mock::VerifyAndClearExpectations(&test_device_info_);
1577 // We need to insert the device index ourselves since we have mocked
1578 // out CreateDevice. This insertion is tested in CreateDeviceCDCEthernet
1579 // above.
1580 GetDelayedDevices().insert(kTestDeviceIndex);
1581 }
1582
Peter Qiu1a72f542015-04-14 16:31:36 -07001583#if !defined(DISABLE_WIFI)
Paul Stewart3b30ca52015-06-16 13:13:10 -07001584 void TriggerOnWiFiInterfaceInfoReceived(const Nl80211Message& message) {
Paul Stewart2ddf2c62013-04-16 09:47:34 -07001585 test_device_info_.OnWiFiInterfaceInfoReceived(message);
1586 }
Peter Qiu1a72f542015-04-14 16:31:36 -07001587#endif // DISABLE_WIFI
Paul Stewart2ddf2c62013-04-16 09:47:34 -07001588
Paul Stewart050cfc02012-07-06 20:38:54 -07001589 protected:
1590 DeviceInfoForDelayedCreationTest test_device_info_;
1591};
1592
1593TEST_F(DeviceInfoDelayedCreationTest, NoDevices) {
1594 EXPECT_TRUE(GetDelayedDevices().empty());
1595 EXPECT_CALL(test_device_info_, GetDeviceTechnology(_)).Times(0);
1596 DelayedDeviceCreationTask();
1597}
1598
1599TEST_F(DeviceInfoDelayedCreationTest, EthernetDevice) {
1600 AddDelayedDevice();
1601 EXPECT_CALL(test_device_info_, GetDeviceTechnology(_))
1602 .WillOnce(Return(Technology::kCDCEthernet));
1603 EXPECT_CALL(test_device_info_, CreateDevice(
1604 kTestDeviceName, _, kTestDeviceIndex, Technology::kEthernet))
1605 .WillOnce(Return(DeviceRefPtr()));
1606 DelayedDeviceCreationTask();
1607 EXPECT_TRUE(GetDelayedDevices().empty());
1608}
1609
1610TEST_F(DeviceInfoDelayedCreationTest, CellularDevice) {
1611 AddDelayedDevice();
1612 EXPECT_CALL(test_device_info_, GetDeviceTechnology(_))
1613 .WillOnce(Return(Technology::kCellular));
1614 EXPECT_CALL(test_device_info_, CreateDevice(
1615 kTestDeviceName, _, kTestDeviceIndex, Technology::kCellular))
1616 .WillOnce(Return(DeviceRefPtr()));
1617 DelayedDeviceCreationTask();
1618 EXPECT_TRUE(GetDelayedDevices().empty());
1619}
1620
Peter Qiu1a72f542015-04-14 16:31:36 -07001621#if !defined(DISABLE_WIFI)
Paul Stewart2ddf2c62013-04-16 09:47:34 -07001622TEST_F(DeviceInfoDelayedCreationTest, WiFiDevice) {
1623 ScopedMockLog log;
Paul Stewart2ddf2c62013-04-16 09:47:34 -07001624 EXPECT_CALL(log, Log(logging::LOG_ERROR, _,
1625 HasSubstr("Message is not a new interface response")));
1626 GetInterfaceMessage non_interface_response_message;
1627 TriggerOnWiFiInterfaceInfoReceived(non_interface_response_message);
1628 Mock::VerifyAndClearExpectations(&log);
1629
1630 EXPECT_CALL(log, Log(logging::LOG_ERROR, _,
1631 HasSubstr("Message contains no interface index")));
1632 NewInterfaceMessage message;
1633 TriggerOnWiFiInterfaceInfoReceived(message);
1634 Mock::VerifyAndClearExpectations(&log);
1635
Peter Qiuba24e6f2014-11-17 10:26:35 -08001636 message.attributes()->CreateNl80211Attribute(
Samuel Tan900ab5e2015-02-04 14:44:10 -08001637 NL80211_ATTR_IFINDEX, NetlinkMessage::MessageContext());
Paul Stewart2ddf2c62013-04-16 09:47:34 -07001638 message.attributes()->SetU32AttributeValue(NL80211_ATTR_IFINDEX,
1639 kTestDeviceIndex);
1640 EXPECT_CALL(log, Log(logging::LOG_ERROR, _,
1641 HasSubstr("Message contains no interface type")));
1642 TriggerOnWiFiInterfaceInfoReceived(message);
1643 Mock::VerifyAndClearExpectations(&log);
1644
Peter Qiuba24e6f2014-11-17 10:26:35 -08001645 message.attributes()->CreateNl80211Attribute(
Samuel Tan900ab5e2015-02-04 14:44:10 -08001646 NL80211_ATTR_IFTYPE, NetlinkMessage::MessageContext());
Paul Stewart2ddf2c62013-04-16 09:47:34 -07001647 message.attributes()->SetU32AttributeValue(NL80211_ATTR_IFTYPE,
1648 NL80211_IFTYPE_AP);
1649 EXPECT_CALL(log, Log(logging::LOG_ERROR, _,
1650 HasSubstr("Could not find device info for interface")));
1651 TriggerOnWiFiInterfaceInfoReceived(message);
1652 Mock::VerifyAndClearExpectations(&log);
1653
1654 // Use the AddDelayedDevice() method to create a device info entry with no
1655 // associated device.
1656 AddDelayedDevice();
1657
1658 EXPECT_CALL(log, Log(logging::LOG_INFO, _,
1659 HasSubstr("it is not in station mode")));
1660 TriggerOnWiFiInterfaceInfoReceived(message);
1661 Mock::VerifyAndClearExpectations(&log);
1662 Mock::VerifyAndClearExpectations(&manager_);
1663
1664 message.attributes()->SetU32AttributeValue(NL80211_ATTR_IFTYPE,
1665 NL80211_IFTYPE_STATION);
1666 EXPECT_CALL(manager_, RegisterDevice(_));
1667 EXPECT_CALL(manager_, device_info())
1668 .WillRepeatedly(Return(&test_device_info_));
1669 EXPECT_CALL(log, Log(_, _, _)).Times(AnyNumber());
1670 EXPECT_CALL(log, Log(logging::LOG_INFO, _,
1671 HasSubstr("Creating WiFi device")));
1672 TriggerOnWiFiInterfaceInfoReceived(message);
1673 Mock::VerifyAndClearExpectations(&log);
1674 Mock::VerifyAndClearExpectations(&manager_);
1675
1676 EXPECT_CALL(manager_, RegisterDevice(_)).Times(0);
1677 EXPECT_CALL(log, Log(logging::LOG_ERROR, _,
1678 HasSubstr("Device already created for interface")));
1679 TriggerOnWiFiInterfaceInfoReceived(message);
1680}
Peter Qiu1a72f542015-04-14 16:31:36 -07001681#endif // DISABLE_WIFI
Paul Stewart2ddf2c62013-04-16 09:47:34 -07001682
Chris Masone9be4a9d2011-05-16 15:44:09 -07001683} // namespace shill