blob: 9641f9227f8c4bf729478b061885bac1c27e3f80 [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
Chris Masone9be4a9d2011-05-16 15:44:09 -07007#include <glib.h>
Darin Petkove6193c02011-08-11 12:42:40 -07008#include <linux/if.h>
Paul Stewartca876ee2012-04-21 08:55:58 -07009#include <linux/if_tun.h>
Darin Petkov633ac6f2011-07-08 13:56:13 -070010#include <linux/netlink.h> // Needs typedefs from sys/socket.h.
11#include <linux/rtnetlink.h>
Gary Morain41780232012-07-31 15:08:31 -070012#include <linux/sockios.h>
Paul Stewartca876ee2012-04-21 08:55:58 -070013#include <net/if_arp.h>
Wade Guthrie7347bf22013-04-30 11:21:51 -070014#include <sys/socket.h>
Chris Masone9be4a9d2011-05-16 15:44:09 -070015
Paul Stewart2ddf2c62013-04-16 09:47:34 -070016#include <base/bind.h>
Ben Chan11c213f2014-09-05 08:21:06 -070017#include <base/files/file_util.h>
Paul Stewart5ad16062013-02-21 18:10:48 -080018#include <base/files/scoped_temp_dir.h>
Chris Masone9be4a9d2011-05-16 15:44:09 -070019#include <base/memory/ref_counted.h>
Ben Chana0ddf462014-02-06 11:32:42 -080020#include <base/message_loop/message_loop.h>
Eric Shienbrood3e20a232012-02-16 11:35:56 -050021#include <base/stl_util.h>
Ben Chana0ddf462014-02-06 11:32:42 -080022#include <base/strings/string_number_conversions.h>
Chris Masone9be4a9d2011-05-16 15:44:09 -070023#include <gmock/gmock.h>
Ben Chan5086b972013-01-15 21:51:38 -080024#include <gtest/gtest.h>
Chris Masone9be4a9d2011-05-16 15:44:09 -070025
Paul Stewart9a908082011-08-31 12:18:48 -070026#include "shill/ip_address.h"
Christopher Wileyb691efd2012-08-09 13:51:51 -070027#include "shill/logging.h"
Paul Stewartb50f0b92011-05-16 16:31:42 -070028#include "shill/manager.h"
Chris Masone46eaaf52011-05-24 13:08:30 -070029#include "shill/mock_control.h"
Ben Chan5086b972013-01-15 21:51:38 -080030#include "shill/mock_device.h"
Darin Petkovafa6fc42011-06-21 16:21:08 -070031#include "shill/mock_glib.h"
Paul Stewart2ddf2c62013-04-16 09:47:34 -070032#include "shill/mock_log.h"
Chris Masone2ae797d2011-08-23 20:41:00 -070033#include "shill/mock_manager.h"
Thieu Le3426c8f2012-01-11 17:35:11 -080034#include "shill/mock_metrics.h"
Paul Stewart8c116a92012-05-02 18:30:03 -070035#include "shill/mock_modem_info.h"
Paul Stewart2ddf2c62013-04-16 09:47:34 -070036#include "shill/mock_netlink_manager.h"
Paul Stewart8c116a92012-05-02 18:30:03 -070037#include "shill/mock_routing_table.h"
Paul Stewart9a908082011-08-31 12:18:48 -070038#include "shill/mock_rtnl_handler.h"
Darin Petkov633ac6f2011-07-08 13:56:13 -070039#include "shill/mock_sockets.h"
Peter Qiu98551702014-07-28 13:28:53 -070040#include "shill/mock_time.h"
Paul Stewart8c116a92012-05-02 18:30:03 -070041#include "shill/mock_vpn_provider.h"
Darin Petkove4b27022012-05-16 13:28:50 +020042#include "shill/mock_wimax_provider.h"
Paul Stewart2ddf2c62013-04-16 09:47:34 -070043#include "shill/netlink_attribute.h"
44#include "shill/nl80211_message.h"
Chris Masone2aa97072011-08-09 17:35:08 -070045#include "shill/rtnl_message.h"
Darin Petkovc63dcf02012-05-24 11:51:43 +020046#include "shill/wimax.h"
Chris Masone9be4a9d2011-05-16 15:44:09 -070047
Eric Shienbrood3e20a232012-02-16 11:35:56 -050048using base::Callback;
Albert Chaulk0e1cdea2013-02-27 15:32:55 -080049using base::FilePath;
Darin Petkove6193c02011-08-11 12:42:40 -070050using std::map;
Ben Chan5086b972013-01-15 21:51:38 -080051using std::set;
Darin Petkov633ac6f2011-07-08 13:56:13 -070052using std::string;
Paul Stewart9a908082011-08-31 12:18:48 -070053using std::vector;
Darin Petkov633ac6f2011-07-08 13:56:13 -070054using testing::_;
Paul Stewart2ddf2c62013-04-16 09:47:34 -070055using testing::AnyNumber;
Ben Chan5086b972013-01-15 21:51:38 -080056using testing::ContainerEq;
Gary Morain41780232012-07-31 15:08:31 -070057using testing::DoAll;
58using testing::ElementsAreArray;
Paul Stewart2ddf2c62013-04-16 09:47:34 -070059using testing::HasSubstr;
Paul Stewart8c116a92012-05-02 18:30:03 -070060using testing::Mock;
Gary Morain41780232012-07-31 15:08:31 -070061using testing::NotNull;
Darin Petkov633ac6f2011-07-08 13:56:13 -070062using testing::Return;
Peter Qiu98551702014-07-28 13:28:53 -070063using testing::SetArgPointee;
Paul Stewart9a908082011-08-31 12:18:48 -070064using testing::StrictMock;
Darin Petkov633ac6f2011-07-08 13:56:13 -070065using testing::Test;
66
Chris Masone9be4a9d2011-05-16 15:44:09 -070067namespace shill {
Darin Petkov633ac6f2011-07-08 13:56:13 -070068
Paul Stewart050cfc02012-07-06 20:38:54 -070069class TestEventDispatcherForDeviceInfo : public EventDispatcher {
Darin Petkov633ac6f2011-07-08 13:56:13 -070070 public:
Paul Stewart26b327e2011-10-19 11:38:09 -070071 virtual IOHandler *CreateInputHandler(
mukesh agrawal1830fa12011-09-26 14:31:40 -070072 int /*fd*/,
Paul Stewart5f06a0e2012-12-20 11:11:33 -080073 const IOHandler::InputCallback &/*input_callback*/,
74 const IOHandler::ErrorCallback &/*error_callback*/) {
Darin Petkov633ac6f2011-07-08 13:56:13 -070075 return NULL;
76 }
Paul Stewart050cfc02012-07-06 20:38:54 -070077 MOCK_METHOD2(PostDelayedTask, bool(const base::Closure &task,
Ben Chan7fab8972014-08-10 17:14:46 -070078 int64_t delay_ms));
Darin Petkov633ac6f2011-07-08 13:56:13 -070079};
Chris Masone9be4a9d2011-05-16 15:44:09 -070080
81class DeviceInfoTest : public Test {
82 public:
83 DeviceInfoTest()
Thieu Le6c1e3bb2013-02-06 15:20:35 -080084 : metrics_(&dispatcher_),
85 manager_(&control_interface_, &dispatcher_, &metrics_, &glib_),
Thieu Le3426c8f2012-01-11 17:35:11 -080086 device_info_(&control_interface_, &dispatcher_, &metrics_, &manager_) {
Chris Masone9be4a9d2011-05-16 15:44:09 -070087 }
Paul Stewartca876ee2012-04-21 08:55:58 -070088 virtual ~DeviceInfoTest() {}
Darin Petkov633ac6f2011-07-08 13:56:13 -070089
Paul Stewart9a908082011-08-31 12:18:48 -070090 virtual void SetUp() {
91 device_info_.rtnl_handler_ = &rtnl_handler_;
Paul Stewart8c116a92012-05-02 18:30:03 -070092 device_info_.routing_table_ = &routing_table_;
Paul Stewart2ddf2c62013-04-16 09:47:34 -070093 device_info_.netlink_manager_ = &netlink_manager_;
Peter Qiu98551702014-07-28 13:28:53 -070094 device_info_.time_ = &time_;
Paul Stewartd4f26482014-04-25 19:12:03 -070095 manager_.set_mock_device_info(&device_info_);
Paul Stewart9a908082011-08-31 12:18:48 -070096 }
97
Paul Stewart8c116a92012-05-02 18:30:03 -070098 IPAddress CreateInterfaceAddress() {
99 // Create an IP address entry (as if left-over from a previous connection
100 // manager).
101 IPAddress address(IPAddress::kFamilyIPv4);
102 EXPECT_TRUE(address.SetAddressFromString(kTestIPAddress0));
103 address.set_prefix(kTestIPAddressPrefix0);
104 vector<DeviceInfo::AddressData> &addresses =
105 device_info_.infos_[kTestDeviceIndex].ip_addresses;
106 addresses.push_back(DeviceInfo::AddressData(address, 0, RT_SCOPE_UNIVERSE));
107 EXPECT_EQ(1, addresses.size());
108 return address;
109 }
110
111 DeviceRefPtr CreateDevice(const std::string &link_name,
112 const std::string &address,
113 int interface_index,
114 Technology::Identifier technology) {
115 return device_info_.CreateDevice(link_name, address, interface_index,
116 technology);
117 }
118
Paul Stewart050cfc02012-07-06 20:38:54 -0700119 virtual std::set<int> &GetDelayedDevices() {
120 return device_info_.delayed_devices_;
121 }
122
Paul Stewart1ac4e842012-07-10 12:58:12 -0700123 int GetDelayedDeviceCreationMilliseconds() {
Paul Stewart050cfc02012-07-06 20:38:54 -0700124 return DeviceInfo::kDelayedDeviceCreationSeconds * 1000;
125 }
Paul Stewart8c116a92012-05-02 18:30:03 -0700126
Gary Morain41780232012-07-31 15:08:31 -0700127 void SetSockets() {
128 mock_sockets_ = new MockSockets();
129 device_info_.set_sockets(mock_sockets_);
130 }
131
Darin Petkovc3505a52013-03-18 15:13:29 +0100132 // Takes ownership of |provider|.
133 void SetVPNProvider(VPNProvider *provider) {
134 manager_.vpn_provider_.reset(provider);
Paul Stewartb87d22b2013-07-29 11:11:37 -0700135 manager_.UpdateProviderMapping();
Darin Petkovc3505a52013-03-18 15:13:29 +0100136 }
137
Paul Stewarta3c56f92011-05-26 07:08:52 -0700138 protected:
Chris Masoneb2e326b2011-07-12 13:28:51 -0700139 static const int kTestDeviceIndex;
Darin Petkov633ac6f2011-07-08 13:56:13 -0700140 static const char kTestDeviceName[];
Han Shenfc349252012-08-30 11:36:04 -0700141 static const uint8_t kTestMACAddress[];
Paul Stewart9a908082011-08-31 12:18:48 -0700142 static const char kTestIPAddress0[];
143 static const int kTestIPAddressPrefix0;
144 static const char kTestIPAddress1[];
145 static const int kTestIPAddressPrefix1;
146 static const char kTestIPAddress2[];
147 static const char kTestIPAddress3[];
148 static const char kTestIPAddress4[];
Paul Stewart05a42c22012-08-02 16:47:21 -0700149 static const char kTestIPAddress5[];
Paul Stewarta0db0ff2013-12-09 09:48:47 -0800150 static const char kTestIPAddress6[];
Paul Stewart1ac4e842012-07-10 12:58:12 -0700151 static const int kReceiveByteCount;
152 static const int kTransmitByteCount;
Darin Petkov633ac6f2011-07-08 13:56:13 -0700153
Paul Stewart9a908082011-08-31 12:18:48 -0700154 RTNLMessage *BuildLinkMessage(RTNLMessage::Mode mode);
Paul Stewarte81eb702012-04-11 15:04:53 -0700155 RTNLMessage *BuildLinkMessageWithInterfaceName(RTNLMessage::Mode mode,
156 const string &interface_name);
Paul Stewart9a908082011-08-31 12:18:48 -0700157 RTNLMessage *BuildAddressMessage(RTNLMessage::Mode mode,
158 const IPAddress &address,
159 unsigned char flags,
160 unsigned char scope);
Peter Qiu98551702014-07-28 13:28:53 -0700161 RTNLMessage *BuildRdnssMessage(RTNLMessage::Mode mode,
Ben Chan7fab8972014-08-10 17:14:46 -0700162 uint32_t lifetime,
Peter Qiu98551702014-07-28 13:28:53 -0700163 const vector<IPAddress> &dns_servers);
Chris Masone2aa97072011-08-09 17:35:08 -0700164 void SendMessageToDeviceInfo(const RTNLMessage &message);
Darin Petkov633ac6f2011-07-08 13:56:13 -0700165
Darin Petkovafa6fc42011-06-21 16:21:08 -0700166 MockGLib glib_;
Chris Masone46eaaf52011-05-24 13:08:30 -0700167 MockControl control_interface_;
Thieu Le3426c8f2012-01-11 17:35:11 -0800168 MockMetrics metrics_;
Paul Stewart9a908082011-08-31 12:18:48 -0700169 StrictMock<MockManager> manager_;
Chris Masone9be4a9d2011-05-16 15:44:09 -0700170 DeviceInfo device_info_;
Paul Stewart050cfc02012-07-06 20:38:54 -0700171 TestEventDispatcherForDeviceInfo dispatcher_;
Paul Stewart8c116a92012-05-02 18:30:03 -0700172 MockRoutingTable routing_table_;
Paul Stewart2ddf2c62013-04-16 09:47:34 -0700173 MockNetlinkManager netlink_manager_;
Paul Stewart9a908082011-08-31 12:18:48 -0700174 StrictMock<MockRTNLHandler> rtnl_handler_;
Gary Morain41780232012-07-31 15:08:31 -0700175 MockSockets *mock_sockets_; // Owned by DeviceInfo.
Peter Qiu98551702014-07-28 13:28:53 -0700176 MockTime time_;
Chris Masone9be4a9d2011-05-16 15:44:09 -0700177};
178
Chris Masoneb2e326b2011-07-12 13:28:51 -0700179const int DeviceInfoTest::kTestDeviceIndex = 123456;
Darin Petkov633ac6f2011-07-08 13:56:13 -0700180const char DeviceInfoTest::kTestDeviceName[] = "test-device";
Han Shenfc349252012-08-30 11:36:04 -0700181const uint8_t DeviceInfoTest::kTestMACAddress[] = {
Wade Guthrie7347bf22013-04-30 11:21:51 -0700182 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff };
Paul Stewart9a908082011-08-31 12:18:48 -0700183const char DeviceInfoTest::kTestIPAddress0[] = "192.168.1.1";
184const int DeviceInfoTest::kTestIPAddressPrefix0 = 24;
185const char DeviceInfoTest::kTestIPAddress1[] = "fe80::1aa9:5ff:abcd:1234";
186const int DeviceInfoTest::kTestIPAddressPrefix1 = 64;
187const char DeviceInfoTest::kTestIPAddress2[] = "fe80::1aa9:5ff:abcd:1235";
188const char DeviceInfoTest::kTestIPAddress3[] = "fe80::1aa9:5ff:abcd:1236";
189const char DeviceInfoTest::kTestIPAddress4[] = "fe80::1aa9:5ff:abcd:1237";
Paul Stewart05a42c22012-08-02 16:47:21 -0700190const char DeviceInfoTest::kTestIPAddress5[] = "192.168.1.2";
Paul Stewarta0db0ff2013-12-09 09:48:47 -0800191const char DeviceInfoTest::kTestIPAddress6[] = "192.168.2.2";
Paul Stewart1ac4e842012-07-10 12:58:12 -0700192const int DeviceInfoTest::kReceiveByteCount = 1234;
193const int DeviceInfoTest::kTransmitByteCount = 5678;
Chris Masone9be4a9d2011-05-16 15:44:09 -0700194
Paul Stewarte81eb702012-04-11 15:04:53 -0700195RTNLMessage *DeviceInfoTest::BuildLinkMessageWithInterfaceName(
196 RTNLMessage::Mode mode, const string &interface_name) {
Paul Stewart9a908082011-08-31 12:18:48 -0700197 RTNLMessage *message = new RTNLMessage(
198 RTNLMessage::kTypeLink,
199 mode,
200 0,
201 0,
202 0,
203 kTestDeviceIndex,
Paul Stewart7355ce12011-09-02 10:47:01 -0700204 IPAddress::kFamilyIPv4);
Ben Chan7fab8972014-08-10 17:14:46 -0700205 message->SetAttribute(static_cast<uint16_t>(IFLA_IFNAME),
Paul Stewarte81eb702012-04-11 15:04:53 -0700206 ByteString(interface_name, true));
Paul Stewart9a908082011-08-31 12:18:48 -0700207 ByteString test_address(kTestMACAddress, sizeof(kTestMACAddress));
Chris Masone626719f2011-08-18 16:58:48 -0700208 message->SetAttribute(IFLA_ADDRESS, test_address);
Chris Masone2aa97072011-08-09 17:35:08 -0700209 return message;
Darin Petkov633ac6f2011-07-08 13:56:13 -0700210}
211
Paul Stewarte81eb702012-04-11 15:04:53 -0700212RTNLMessage *DeviceInfoTest::BuildLinkMessage(RTNLMessage::Mode mode) {
213 return BuildLinkMessageWithInterfaceName(mode, kTestDeviceName);
214}
215
Paul Stewart9a908082011-08-31 12:18:48 -0700216RTNLMessage *DeviceInfoTest::BuildAddressMessage(RTNLMessage::Mode mode,
217 const IPAddress &address,
218 unsigned char flags,
219 unsigned char scope) {
220 RTNLMessage *message = new RTNLMessage(
221 RTNLMessage::kTypeAddress,
222 mode,
223 0,
224 0,
225 0,
226 kTestDeviceIndex,
227 address.family());
228 message->SetAttribute(IFA_ADDRESS, address.address());
229 message->set_address_status(
230 RTNLMessage::AddressStatus(address.prefix(), flags, scope));
231 return message;
232}
233
Peter Qiu98551702014-07-28 13:28:53 -0700234RTNLMessage *DeviceInfoTest::BuildRdnssMessage(RTNLMessage::Mode mode,
Ben Chan7fab8972014-08-10 17:14:46 -0700235 uint32_t lifetime, const vector<IPAddress> &dns_servers) {
Peter Qiu98551702014-07-28 13:28:53 -0700236 RTNLMessage *message = new RTNLMessage(
237 RTNLMessage::kTypeRdnss,
238 mode,
239 0,
240 0,
241 0,
242 kTestDeviceIndex,
243 IPAddress::kFamilyIPv6);
244 message->set_rdnss_option(
245 RTNLMessage::RdnssOption(lifetime, dns_servers));
246 return message;
247}
248
Chris Masone2aa97072011-08-09 17:35:08 -0700249void DeviceInfoTest::SendMessageToDeviceInfo(const RTNLMessage &message) {
Paul Stewart9a908082011-08-31 12:18:48 -0700250 if (message.type() == RTNLMessage::kTypeLink) {
251 device_info_.LinkMsgHandler(message);
252 } else if (message.type() == RTNLMessage::kTypeAddress) {
253 device_info_.AddressMsgHandler(message);
Peter Qiu98551702014-07-28 13:28:53 -0700254 } else if (message.type() == RTNLMessage::kTypeRdnss) {
255 device_info_.RdnssMsgHandler(message);
Paul Stewart9a908082011-08-31 12:18:48 -0700256 } else {
257 NOTREACHED();
258 }
259}
260
261MATCHER_P(IsIPAddress, address, "") {
262 // NB: IPAddress objects don't support the "==" operator as per style, so
263 // we need a custom matcher.
264 return address.Equals(arg);
Darin Petkov633ac6f2011-07-08 13:56:13 -0700265}
266
Paul Stewart8c116a92012-05-02 18:30:03 -0700267TEST_F(DeviceInfoTest, StartStop) {
268 EXPECT_FALSE(device_info_.link_listener_.get());
269 EXPECT_FALSE(device_info_.address_listener_.get());
270 EXPECT_TRUE(device_info_.infos_.empty());
271
272 EXPECT_CALL(rtnl_handler_, RequestDump(RTNLHandler::kRequestLink |
273 RTNLHandler::kRequestAddr));
Paul Stewart1ac4e842012-07-10 12:58:12 -0700274 EXPECT_CALL(dispatcher_, PostDelayedTask(
Ben Chanb061f892013-02-27 17:46:55 -0800275 _, DeviceInfo::kRequestLinkStatisticsIntervalMilliseconds));
Chris Masone9be4a9d2011-05-16 15:44:09 -0700276 device_info_.Start();
Paul Stewart8c116a92012-05-02 18:30:03 -0700277 EXPECT_TRUE(device_info_.link_listener_.get());
278 EXPECT_TRUE(device_info_.address_listener_.get());
279 EXPECT_TRUE(device_info_.infos_.empty());
280 Mock::VerifyAndClearExpectations(&rtnl_handler_);
281
282 CreateInterfaceAddress();
283 EXPECT_FALSE(device_info_.infos_.empty());
284
285 device_info_.Stop();
286 EXPECT_FALSE(device_info_.link_listener_.get());
287 EXPECT_FALSE(device_info_.address_listener_.get());
288 EXPECT_TRUE(device_info_.infos_.empty());
289}
290
Paul Stewart1ac4e842012-07-10 12:58:12 -0700291TEST_F(DeviceInfoTest, RequestLinkStatistics) {
292 EXPECT_CALL(rtnl_handler_, RequestDump(RTNLHandler::kRequestLink));
293 EXPECT_CALL(dispatcher_, PostDelayedTask(
Ben Chanb061f892013-02-27 17:46:55 -0800294 _, DeviceInfo::kRequestLinkStatisticsIntervalMilliseconds));
Paul Stewart1ac4e842012-07-10 12:58:12 -0700295 device_info_.RequestLinkStatistics();
296}
297
Paul Stewart8c116a92012-05-02 18:30:03 -0700298TEST_F(DeviceInfoTest, DeviceEnumeration) {
Paul Stewart9a908082011-08-31 12:18:48 -0700299 scoped_ptr<RTNLMessage> message(BuildLinkMessage(RTNLMessage::kModeAdd));
Darin Petkove6193c02011-08-11 12:42:40 -0700300 message->set_link_status(RTNLMessage::LinkStatus(0, IFF_LOWER_UP, 0));
301 EXPECT_FALSE(device_info_.GetDevice(kTestDeviceIndex).get());
Darin Petkovf8046b82012-04-24 16:29:23 +0200302 EXPECT_EQ(-1, device_info_.GetIndex(kTestDeviceName));
Darin Petkove6193c02011-08-11 12:42:40 -0700303 SendMessageToDeviceInfo(*message);
304 EXPECT_TRUE(device_info_.GetDevice(kTestDeviceIndex).get());
305 unsigned int flags = 0;
306 EXPECT_TRUE(device_info_.GetFlags(kTestDeviceIndex, &flags));
307 EXPECT_EQ(IFF_LOWER_UP, flags);
Darin Petkove3e1cfa2011-08-11 13:41:17 -0700308 ByteString address;
Paul Stewart32852962011-08-30 14:06:53 -0700309 EXPECT_TRUE(device_info_.GetMACAddress(kTestDeviceIndex, &address));
Darin Petkove3e1cfa2011-08-11 13:41:17 -0700310 EXPECT_FALSE(address.IsEmpty());
Paul Stewart9a908082011-08-31 12:18:48 -0700311 EXPECT_TRUE(address.Equals(ByteString(kTestMACAddress,
312 sizeof(kTestMACAddress))));
Darin Petkovf8046b82012-04-24 16:29:23 +0200313 EXPECT_EQ(kTestDeviceIndex, device_info_.GetIndex(kTestDeviceName));
Paul Stewarta3c56f92011-05-26 07:08:52 -0700314
Paul Stewart9a908082011-08-31 12:18:48 -0700315 message.reset(BuildLinkMessage(RTNLMessage::kModeAdd));
Darin Petkove6193c02011-08-11 12:42:40 -0700316 message->set_link_status(RTNLMessage::LinkStatus(0, IFF_UP | IFF_RUNNING, 0));
317 SendMessageToDeviceInfo(*message);
318 EXPECT_TRUE(device_info_.GetFlags(kTestDeviceIndex, &flags));
319 EXPECT_EQ(IFF_UP | IFF_RUNNING, flags);
Paul Stewartb50f0b92011-05-16 16:31:42 -0700320
Paul Stewart9a908082011-08-31 12:18:48 -0700321 message.reset(BuildLinkMessage(RTNLMessage::kModeDelete));
Paul Stewart8c116a92012-05-02 18:30:03 -0700322 EXPECT_CALL(manager_, DeregisterDevice(_)).Times(1);
Darin Petkove6193c02011-08-11 12:42:40 -0700323 SendMessageToDeviceInfo(*message);
324 EXPECT_FALSE(device_info_.GetDevice(kTestDeviceIndex).get());
325 EXPECT_FALSE(device_info_.GetFlags(kTestDeviceIndex, NULL));
Darin Petkovf8046b82012-04-24 16:29:23 +0200326 EXPECT_EQ(-1, device_info_.GetIndex(kTestDeviceName));
Paul Stewart8c116a92012-05-02 18:30:03 -0700327}
Paul Stewarta3c56f92011-05-26 07:08:52 -0700328
Ben Chan5086b972013-01-15 21:51:38 -0800329TEST_F(DeviceInfoTest, GetUninitializedTechnologies) {
330 vector<string> technologies = device_info_.GetUninitializedTechnologies();
331 set<string> expected_technologies;
332
333 EXPECT_THAT(set<string>(technologies.begin(), technologies.end()),
334 ContainerEq(expected_technologies));
335
336 device_info_.infos_[0].technology = Technology::kUnknown;
337 EXPECT_THAT(set<string>(technologies.begin(), technologies.end()),
338 ContainerEq(expected_technologies));
339
340 device_info_.infos_[1].technology = Technology::kCellular;
341 technologies = device_info_.GetUninitializedTechnologies();
342 expected_technologies.insert(Technology::NameFromIdentifier(
343 Technology::kCellular));
344 EXPECT_THAT(set<string>(technologies.begin(), technologies.end()),
345 ContainerEq(expected_technologies));
346
347 device_info_.infos_[2].technology = Technology::kWiMax;
348 technologies = device_info_.GetUninitializedTechnologies();
349 expected_technologies.insert(Technology::NameFromIdentifier(
350 Technology::kWiMax));
351 EXPECT_THAT(set<string>(technologies.begin(), technologies.end()),
352 ContainerEq(expected_technologies));
353
354 scoped_refptr<MockDevice> device(new MockDevice(
355 &control_interface_, &dispatcher_, &metrics_, &manager_,
356 "null0", "addr0", 1));
357 device_info_.infos_[1].device = device;
358 technologies = device_info_.GetUninitializedTechnologies();
359 expected_technologies.erase(Technology::NameFromIdentifier(
360 Technology::kCellular));
361 EXPECT_THAT(set<string>(technologies.begin(), technologies.end()),
362 ContainerEq(expected_technologies));
363
364 device_info_.infos_[3].technology = Technology::kCellular;
365 technologies = device_info_.GetUninitializedTechnologies();
Arman Ugurayb00c13d2013-07-29 18:20:52 -0700366 EXPECT_THAT(set<string>(technologies.begin(), technologies.end()),
367 ContainerEq(expected_technologies));
368
369 device_info_.infos_[3].device = device;
370 device_info_.infos_[1].device = NULL;
371 technologies = device_info_.GetUninitializedTechnologies();
Ben Chan5086b972013-01-15 21:51:38 -0800372 EXPECT_THAT(set<string>(technologies.begin(), technologies.end()),
373 ContainerEq(expected_technologies));
374}
375
Paul Stewart1ac4e842012-07-10 12:58:12 -0700376TEST_F(DeviceInfoTest, GetByteCounts) {
Ben Chan7fab8972014-08-10 17:14:46 -0700377 uint64_t rx_bytes, tx_bytes;
Paul Stewart1ac4e842012-07-10 12:58:12 -0700378 EXPECT_FALSE(device_info_.GetByteCounts(
379 kTestDeviceIndex, &rx_bytes, &tx_bytes));
380
381 // No link statistics in the message.
382 scoped_ptr<RTNLMessage> message(BuildLinkMessage(RTNLMessage::kModeAdd));
383 SendMessageToDeviceInfo(*message);
384 EXPECT_TRUE(device_info_.GetByteCounts(
385 kTestDeviceIndex, &rx_bytes, &tx_bytes));
386 EXPECT_EQ(0, rx_bytes);
387 EXPECT_EQ(0, tx_bytes);
388
389 // Short link statistics message.
390 message.reset(BuildLinkMessage(RTNLMessage::kModeAdd));
391 struct rtnl_link_stats64 stats;
392 memset(&stats, 0, sizeof(stats));
393 stats.rx_bytes = kReceiveByteCount;
394 stats.tx_bytes = kTransmitByteCount;
395 ByteString stats_bytes0(reinterpret_cast<const unsigned char*>(&stats),
396 sizeof(stats) - 1);
397 message->SetAttribute(IFLA_STATS64, stats_bytes0);
398 SendMessageToDeviceInfo(*message);
399 EXPECT_TRUE(device_info_.GetByteCounts(
400 kTestDeviceIndex, &rx_bytes, &tx_bytes));
401 EXPECT_EQ(0, rx_bytes);
402 EXPECT_EQ(0, tx_bytes);
403
404 // Correctly sized link statistics message.
405 message.reset(BuildLinkMessage(RTNLMessage::kModeAdd));
406 ByteString stats_bytes1(reinterpret_cast<const unsigned char*>(&stats),
407 sizeof(stats));
408 message->SetAttribute(IFLA_STATS64, stats_bytes1);
409 SendMessageToDeviceInfo(*message);
410 EXPECT_TRUE(device_info_.GetByteCounts(
411 kTestDeviceIndex, &rx_bytes, &tx_bytes));
412 EXPECT_EQ(kReceiveByteCount, rx_bytes);
413 EXPECT_EQ(kTransmitByteCount, tx_bytes);
414}
415
Ben Chan5742b242013-12-18 16:25:43 -0800416#if !defined(DISABLE_CELLULAR)
417
Paul Stewart8c116a92012-05-02 18:30:03 -0700418TEST_F(DeviceInfoTest, CreateDeviceCellular) {
419 IPAddress address = CreateInterfaceAddress();
420
421 // A cellular device should be offered to ModemInfo.
422 StrictMock<MockModemInfo> modem_info;
423 EXPECT_CALL(manager_, modem_info()).WillOnce(Return(&modem_info));
424 EXPECT_CALL(modem_info, OnDeviceInfoAvailable(kTestDeviceName)).Times(1);
425 EXPECT_CALL(routing_table_, FlushRoutes(kTestDeviceIndex)).Times(1);
426 EXPECT_CALL(rtnl_handler_, RemoveInterfaceAddress(kTestDeviceIndex,
427 IsIPAddress(address)));
428 EXPECT_FALSE(CreateDevice(
429 kTestDeviceName, "address", kTestDeviceIndex, Technology::kCellular));
430}
431
Ben Chan5742b242013-12-18 16:25:43 -0800432#endif // DISABLE_CELLULAR
433
Ben Chan520eb172013-10-30 20:51:04 -0700434#if !defined(DISABLE_WIMAX)
435
Darin Petkove4b27022012-05-16 13:28:50 +0200436TEST_F(DeviceInfoTest, CreateDeviceWiMax) {
437 IPAddress address = CreateInterfaceAddress();
438
439 // A WiMax device should be offered to WiMaxProvider.
440 StrictMock<MockWiMaxProvider> wimax_provider;
441 EXPECT_CALL(manager_, wimax_provider()).WillOnce(Return(&wimax_provider));
442 EXPECT_CALL(wimax_provider, OnDeviceInfoAvailable(kTestDeviceName)).Times(1);
443 EXPECT_CALL(routing_table_, FlushRoutes(kTestDeviceIndex)).Times(1);
444 EXPECT_CALL(rtnl_handler_, RemoveInterfaceAddress(kTestDeviceIndex,
445 IsIPAddress(address)));
Ben Chan4b285862012-10-10 22:52:16 -0700446 device_info_.infos_[kTestDeviceIndex].mac_address =
447 ByteString(kTestMACAddress, sizeof(kTestMACAddress));
Darin Petkove4b27022012-05-16 13:28:50 +0200448 EXPECT_FALSE(CreateDevice(
449 kTestDeviceName, "address", kTestDeviceIndex, Technology::kWiMax));
Ben Chan4b285862012-10-10 22:52:16 -0700450 // The MAC address is clear such that it is obtained via
451 // GetMACAddressFromKernel() instead.
452 EXPECT_TRUE(device_info_.infos_[kTestDeviceIndex].mac_address.IsEmpty());
Darin Petkove4b27022012-05-16 13:28:50 +0200453}
454
Ben Chan520eb172013-10-30 20:51:04 -0700455#endif // DISABLE_WIMAX
456
Paul Stewart8c116a92012-05-02 18:30:03 -0700457TEST_F(DeviceInfoTest, CreateDeviceEthernet) {
458 IPAddress address = CreateInterfaceAddress();
459
460 // An Ethernet device should cause routes and addresses to be flushed.
461 EXPECT_CALL(routing_table_, FlushRoutes(kTestDeviceIndex)).Times(1);
462 EXPECT_CALL(rtnl_handler_, RemoveInterfaceAddress(kTestDeviceIndex,
463 IsIPAddress(address)));
464 DeviceRefPtr device = CreateDevice(
465 kTestDeviceName, "address", kTestDeviceIndex, Technology::kEthernet);
466 EXPECT_TRUE(device);
467 Mock::VerifyAndClearExpectations(&routing_table_);
468 Mock::VerifyAndClearExpectations(&rtnl_handler_);
469
470 // The Ethernet device destructor notifies the manager.
471 EXPECT_CALL(manager_, UpdateEnabledTechnologies()).Times(1);
472 device = NULL;
473}
474
475TEST_F(DeviceInfoTest, CreateDeviceVirtioEthernet) {
476 IPAddress address = CreateInterfaceAddress();
477
478 // VirtioEthernet is identical to Ethernet from the perspective of this test.
479 EXPECT_CALL(routing_table_, FlushRoutes(kTestDeviceIndex)).Times(1);
480 EXPECT_CALL(rtnl_handler_, RemoveInterfaceAddress(kTestDeviceIndex,
481 IsIPAddress(address)));
482 DeviceRefPtr device = CreateDevice(
483 kTestDeviceName, "address", kTestDeviceIndex,
484 Technology::kVirtioEthernet);
485 EXPECT_TRUE(device);
486 Mock::VerifyAndClearExpectations(&routing_table_);
487 Mock::VerifyAndClearExpectations(&rtnl_handler_);
488
489 // The Ethernet device destructor notifies the manager.
490 EXPECT_CALL(manager_, UpdateEnabledTechnologies()).Times(1);
491 device = NULL;
492}
493
Paul Stewart2ddf2c62013-04-16 09:47:34 -0700494MATCHER_P(IsGetInterfaceMessage, index, "") {
495 if (arg->message_type() != Nl80211Message::GetMessageType()) {
496 return false;
497 }
498 const Nl80211Message *msg = reinterpret_cast<const Nl80211Message *>(arg);
499 if (msg->command() != NL80211_CMD_GET_INTERFACE) {
500 return false;
501 }
502 uint32_t interface_index;
503 if (!msg->const_attributes()->GetU32AttributeValue(NL80211_ATTR_IFINDEX,
504 &interface_index)) {
505 return false;
506 }
507 // kInterfaceIndex is signed, but the attribute as handed from the kernel
508 // is unsigned. We're silently casting it away with this assignment.
509 uint32_t test_interface_index = index;
510 return interface_index == test_interface_index;
511}
512
Paul Stewart8c116a92012-05-02 18:30:03 -0700513TEST_F(DeviceInfoTest, CreateDeviceWiFi) {
514 IPAddress address = CreateInterfaceAddress();
515
516 // WiFi looks a lot like Ethernet too.
Paul Stewart2ddf2c62013-04-16 09:47:34 -0700517 EXPECT_CALL(routing_table_, FlushRoutes(kTestDeviceIndex));
Paul Stewart8c116a92012-05-02 18:30:03 -0700518 EXPECT_CALL(rtnl_handler_, RemoveInterfaceAddress(kTestDeviceIndex,
519 IsIPAddress(address)));
Paul Stewart2ddf2c62013-04-16 09:47:34 -0700520
521 // Set the nl80211 message type to some non-default value.
522 Nl80211Message::SetMessageType(1234);
523
Wade Guthrie7347bf22013-04-30 11:21:51 -0700524 EXPECT_CALL(
525 netlink_manager_,
Samuel Tan5412de02014-08-15 17:56:26 -0700526 SendNl80211Message(IsGetInterfaceMessage(kTestDeviceIndex), _, _, _));
Paul Stewart2ddf2c62013-04-16 09:47:34 -0700527 EXPECT_FALSE(CreateDevice(
Paul Stewart8c116a92012-05-02 18:30:03 -0700528 kTestDeviceName, "address", kTestDeviceIndex, Technology::kWifi));
529}
530
531TEST_F(DeviceInfoTest, CreateDeviceTunnelAccepted) {
532 IPAddress address = CreateInterfaceAddress();
533
534 // A VPN device should be offered to VPNProvider.
Darin Petkovc3505a52013-03-18 15:13:29 +0100535 MockVPNProvider *vpn_provider = new StrictMock<MockVPNProvider>;
536 SetVPNProvider(vpn_provider);
537 EXPECT_CALL(*vpn_provider,
Paul Stewart8c116a92012-05-02 18:30:03 -0700538 OnDeviceInfoAvailable(kTestDeviceName, kTestDeviceIndex))
539 .WillOnce(Return(true));
540 EXPECT_CALL(routing_table_, FlushRoutes(kTestDeviceIndex)).Times(1);
541 EXPECT_CALL(rtnl_handler_, RemoveInterfaceAddress(kTestDeviceIndex,
542 IsIPAddress(address)));
543 EXPECT_CALL(rtnl_handler_, RemoveInterface(_)).Times(0);
544 EXPECT_FALSE(CreateDevice(
545 kTestDeviceName, "address", kTestDeviceIndex, Technology::kTunnel));
546}
547
548TEST_F(DeviceInfoTest, CreateDeviceTunnelRejected) {
549 IPAddress address = CreateInterfaceAddress();
550
551 // A VPN device should be offered to VPNProvider.
Darin Petkovc3505a52013-03-18 15:13:29 +0100552 MockVPNProvider *vpn_provider = new StrictMock<MockVPNProvider>;
553 SetVPNProvider(vpn_provider);
554 EXPECT_CALL(*vpn_provider,
Paul Stewart8c116a92012-05-02 18:30:03 -0700555 OnDeviceInfoAvailable(kTestDeviceName, kTestDeviceIndex))
556 .WillOnce(Return(false));
557 EXPECT_CALL(routing_table_, FlushRoutes(kTestDeviceIndex)).Times(1);
558 EXPECT_CALL(rtnl_handler_, RemoveInterfaceAddress(kTestDeviceIndex,
559 IsIPAddress(address)));
560 // Since the device was rejected by the VPNProvider, DeviceInfo will
561 // remove the interface.
562 EXPECT_CALL(rtnl_handler_, RemoveInterface(kTestDeviceIndex)).Times(1);
563 EXPECT_FALSE(CreateDevice(
564 kTestDeviceName, "address", kTestDeviceIndex, Technology::kTunnel));
565}
566
567TEST_F(DeviceInfoTest, CreateDevicePPP) {
568 IPAddress address = CreateInterfaceAddress();
569
570 // A VPN device should be offered to VPNProvider.
Darin Petkovc3505a52013-03-18 15:13:29 +0100571 MockVPNProvider *vpn_provider = new StrictMock<MockVPNProvider>;
572 SetVPNProvider(vpn_provider);
573 EXPECT_CALL(*vpn_provider,
Paul Stewart8c116a92012-05-02 18:30:03 -0700574 OnDeviceInfoAvailable(kTestDeviceName, kTestDeviceIndex))
575 .WillOnce(Return(false));
576 EXPECT_CALL(routing_table_, FlushRoutes(kTestDeviceIndex)).Times(1);
577 EXPECT_CALL(rtnl_handler_, RemoveInterfaceAddress(kTestDeviceIndex,
578 IsIPAddress(address)));
579 // We do not remove PPP interfaces even if the provider does not accept it.
580 EXPECT_CALL(rtnl_handler_, RemoveInterface(_)).Times(0);
581 EXPECT_FALSE(CreateDevice(
582 kTestDeviceName, "address", kTestDeviceIndex, Technology::kPPP));
583}
584
585TEST_F(DeviceInfoTest, CreateDeviceLoopback) {
586 // A loopback device should be brought up, and nothing else done to it.
587 EXPECT_CALL(routing_table_, FlushRoutes(_)).Times(0);
588 EXPECT_CALL(rtnl_handler_, RemoveInterfaceAddress(_, _)).Times(0);
589 EXPECT_CALL(rtnl_handler_,
590 SetInterfaceFlags(kTestDeviceIndex, IFF_UP, IFF_UP)).Times(1);
591 EXPECT_FALSE(CreateDevice(
592 kTestDeviceName, "address", kTestDeviceIndex, Technology::kLoopback));
593}
594
Paul Stewart050cfc02012-07-06 20:38:54 -0700595TEST_F(DeviceInfoTest, CreateDeviceCDCEthernet) {
Ben Chan4eb4ddf2013-06-20 22:16:56 -0700596 // A cdc_ether / cdc_ncm device should be postponed to a task.
Paul Stewart050cfc02012-07-06 20:38:54 -0700597 EXPECT_CALL(manager_, modem_info()).Times(0);
598 EXPECT_CALL(routing_table_, FlushRoutes(_)).Times(0);
599 EXPECT_CALL(rtnl_handler_, RemoveInterfaceAddress(_, _)).Times(0);
600 EXPECT_CALL(dispatcher_,
Paul Stewart1ac4e842012-07-10 12:58:12 -0700601 PostDelayedTask(_, GetDelayedDeviceCreationMilliseconds()));
Paul Stewart050cfc02012-07-06 20:38:54 -0700602 EXPECT_TRUE(GetDelayedDevices().empty());
603 EXPECT_FALSE(CreateDevice(
604 kTestDeviceName, "address", kTestDeviceIndex, Technology::kCDCEthernet));
605 EXPECT_FALSE(GetDelayedDevices().empty());
606 EXPECT_EQ(1, GetDelayedDevices().size());
607 EXPECT_EQ(kTestDeviceIndex, *GetDelayedDevices().begin());
608}
609
Paul Stewart8c116a92012-05-02 18:30:03 -0700610TEST_F(DeviceInfoTest, CreateDeviceUnknown) {
611 IPAddress address = CreateInterfaceAddress();
612
613 // An unknown (blacklisted, unhandled, etc) device won't be flushed or
614 // registered.
615 EXPECT_CALL(routing_table_, FlushRoutes(_)).Times(0);
616 EXPECT_CALL(rtnl_handler_, RemoveInterfaceAddress(_, _)).Times(0);
617 EXPECT_TRUE(CreateDevice(
618 kTestDeviceName, "address", kTestDeviceIndex, Technology::kUnknown));
Chris Masone9be4a9d2011-05-16 15:44:09 -0700619}
620
mukesh agrawal8f317b62011-07-15 11:53:23 -0700621TEST_F(DeviceInfoTest, DeviceBlackList) {
622 device_info_.AddDeviceToBlackList(kTestDeviceName);
Paul Stewart9a908082011-08-31 12:18:48 -0700623 scoped_ptr<RTNLMessage> message(BuildLinkMessage(RTNLMessage::kModeAdd));
Darin Petkove6193c02011-08-11 12:42:40 -0700624 SendMessageToDeviceInfo(*message);
mukesh agrawal8f317b62011-07-15 11:53:23 -0700625
Darin Petkove6193c02011-08-11 12:42:40 -0700626 DeviceRefPtr device = device_info_.GetDevice(kTestDeviceIndex);
627 ASSERT_TRUE(device.get());
Joshua Krollda798622012-06-05 12:30:48 -0700628 EXPECT_TRUE(device->technology() == Technology::kBlacklisted);
mukesh agrawal8f317b62011-07-15 11:53:23 -0700629}
630
Paul Stewart9a908082011-08-31 12:18:48 -0700631TEST_F(DeviceInfoTest, DeviceAddressList) {
Paul Stewart9a908082011-08-31 12:18:48 -0700632 scoped_ptr<RTNLMessage> message(BuildLinkMessage(RTNLMessage::kModeAdd));
633 SendMessageToDeviceInfo(*message);
634
635 vector<DeviceInfo::AddressData> addresses;
636 EXPECT_TRUE(device_info_.GetAddresses(kTestDeviceIndex, &addresses));
637 EXPECT_TRUE(addresses.empty());
638
639 // Add an address to the device address list
Paul Stewart7355ce12011-09-02 10:47:01 -0700640 IPAddress ip_address0(IPAddress::kFamilyIPv4);
Paul Stewart9a908082011-08-31 12:18:48 -0700641 EXPECT_TRUE(ip_address0.SetAddressFromString(kTestIPAddress0));
642 ip_address0.set_prefix(kTestIPAddressPrefix0);
643 message.reset(BuildAddressMessage(RTNLMessage::kModeAdd, ip_address0, 0, 0));
644 SendMessageToDeviceInfo(*message);
645 EXPECT_TRUE(device_info_.GetAddresses(kTestDeviceIndex, &addresses));
646 EXPECT_EQ(1, addresses.size());
647 EXPECT_TRUE(ip_address0.Equals(addresses[0].address));
648
649 // Re-adding the same address shouldn't cause the address list to change
650 SendMessageToDeviceInfo(*message);
651 EXPECT_TRUE(device_info_.GetAddresses(kTestDeviceIndex, &addresses));
652 EXPECT_EQ(1, addresses.size());
653 EXPECT_TRUE(ip_address0.Equals(addresses[0].address));
654
655 // Adding a new address should expand the list
Paul Stewart7355ce12011-09-02 10:47:01 -0700656 IPAddress ip_address1(IPAddress::kFamilyIPv6);
Paul Stewart9a908082011-08-31 12:18:48 -0700657 EXPECT_TRUE(ip_address1.SetAddressFromString(kTestIPAddress1));
658 ip_address1.set_prefix(kTestIPAddressPrefix1);
659 message.reset(BuildAddressMessage(RTNLMessage::kModeAdd, ip_address1, 0, 0));
660 SendMessageToDeviceInfo(*message);
661 EXPECT_TRUE(device_info_.GetAddresses(kTestDeviceIndex, &addresses));
662 EXPECT_EQ(2, addresses.size());
663 EXPECT_TRUE(ip_address0.Equals(addresses[0].address));
664 EXPECT_TRUE(ip_address1.Equals(addresses[1].address));
665
666 // Deleting an address should reduce the list
667 message.reset(BuildAddressMessage(RTNLMessage::kModeDelete,
668 ip_address0,
669 0,
670 0));
671 SendMessageToDeviceInfo(*message);
672 EXPECT_TRUE(device_info_.GetAddresses(kTestDeviceIndex, &addresses));
673 EXPECT_EQ(1, addresses.size());
674 EXPECT_TRUE(ip_address1.Equals(addresses[0].address));
675
676 // Delete last item
677 message.reset(BuildAddressMessage(RTNLMessage::kModeDelete,
678 ip_address1,
679 0,
680 0));
681 SendMessageToDeviceInfo(*message);
682 EXPECT_TRUE(device_info_.GetAddresses(kTestDeviceIndex, &addresses));
683 EXPECT_TRUE(addresses.empty());
684
685 // Delete device
686 message.reset(BuildLinkMessage(RTNLMessage::kModeDelete));
Paul Stewart8c116a92012-05-02 18:30:03 -0700687 EXPECT_CALL(manager_, DeregisterDevice(_)).Times(1);
Paul Stewart9a908082011-08-31 12:18:48 -0700688 SendMessageToDeviceInfo(*message);
689
690 // Should be able to handle message for interface that doesn't exist
691 message.reset(BuildAddressMessage(RTNLMessage::kModeAdd, ip_address0, 0, 0));
692 SendMessageToDeviceInfo(*message);
693 EXPECT_FALSE(device_info_.GetDevice(kTestDeviceIndex).get());
Paul Stewart9a908082011-08-31 12:18:48 -0700694}
695
696TEST_F(DeviceInfoTest, FlushAddressList) {
Paul Stewart9a908082011-08-31 12:18:48 -0700697 scoped_ptr<RTNLMessage> message(BuildLinkMessage(RTNLMessage::kModeAdd));
698 SendMessageToDeviceInfo(*message);
699
Paul Stewart7355ce12011-09-02 10:47:01 -0700700 IPAddress address1(IPAddress::kFamilyIPv6);
Paul Stewart9a908082011-08-31 12:18:48 -0700701 EXPECT_TRUE(address1.SetAddressFromString(kTestIPAddress1));
702 address1.set_prefix(kTestIPAddressPrefix1);
703 message.reset(BuildAddressMessage(RTNLMessage::kModeAdd,
704 address1,
705 0,
706 RT_SCOPE_UNIVERSE));
707 SendMessageToDeviceInfo(*message);
Paul Stewart7355ce12011-09-02 10:47:01 -0700708 IPAddress address2(IPAddress::kFamilyIPv6);
Paul Stewart9a908082011-08-31 12:18:48 -0700709 EXPECT_TRUE(address2.SetAddressFromString(kTestIPAddress2));
710 message.reset(BuildAddressMessage(RTNLMessage::kModeAdd,
711 address2,
712 IFA_F_TEMPORARY,
713 RT_SCOPE_UNIVERSE));
714 SendMessageToDeviceInfo(*message);
Paul Stewart7355ce12011-09-02 10:47:01 -0700715 IPAddress address3(IPAddress::kFamilyIPv6);
Paul Stewart9a908082011-08-31 12:18:48 -0700716 EXPECT_TRUE(address3.SetAddressFromString(kTestIPAddress3));
717 message.reset(BuildAddressMessage(RTNLMessage::kModeAdd,
718 address3,
719 0,
720 RT_SCOPE_LINK));
721 SendMessageToDeviceInfo(*message);
Paul Stewart7355ce12011-09-02 10:47:01 -0700722 IPAddress address4(IPAddress::kFamilyIPv6);
Paul Stewart9a908082011-08-31 12:18:48 -0700723 EXPECT_TRUE(address4.SetAddressFromString(kTestIPAddress4));
724 message.reset(BuildAddressMessage(RTNLMessage::kModeAdd,
725 address4,
726 IFA_F_PERMANENT,
727 RT_SCOPE_UNIVERSE));
728 SendMessageToDeviceInfo(*message);
729
730 // DeviceInfo now has 4 addresses associated with it, but only two of
731 // them are valid for flush.
732 EXPECT_CALL(rtnl_handler_, RemoveInterfaceAddress(kTestDeviceIndex,
733 IsIPAddress(address1)));
734 EXPECT_CALL(rtnl_handler_, RemoveInterfaceAddress(kTestDeviceIndex,
735 IsIPAddress(address2)));
736 device_info_.FlushAddresses(kTestDeviceIndex);
Paul Stewart9a908082011-08-31 12:18:48 -0700737}
738
Paul Stewart05a42c22012-08-02 16:47:21 -0700739TEST_F(DeviceInfoTest, HasOtherAddress) {
740 scoped_ptr<RTNLMessage> message(BuildLinkMessage(RTNLMessage::kModeAdd));
741 SendMessageToDeviceInfo(*message);
742
743 IPAddress address0(IPAddress::kFamilyIPv4);
744 EXPECT_TRUE(address0.SetAddressFromString(kTestIPAddress0));
745
746 // There are no addresses on this interface.
747 EXPECT_FALSE(device_info_.HasOtherAddress(kTestDeviceIndex, address0));
748
749 message.reset(BuildAddressMessage(RTNLMessage::kModeAdd,
750 address0,
751 0,
752 RT_SCOPE_UNIVERSE));
753 SendMessageToDeviceInfo(*message);
754
755 IPAddress address1(IPAddress::kFamilyIPv6);
756 EXPECT_TRUE(address1.SetAddressFromString(kTestIPAddress1));
757 address1.set_prefix(kTestIPAddressPrefix1);
758 message.reset(BuildAddressMessage(RTNLMessage::kModeAdd,
759 address1,
760 0,
761 RT_SCOPE_LINK));
762 SendMessageToDeviceInfo(*message);
763
764 IPAddress address2(IPAddress::kFamilyIPv6);
765 EXPECT_TRUE(address2.SetAddressFromString(kTestIPAddress2));
766 message.reset(BuildAddressMessage(RTNLMessage::kModeAdd,
767 address2,
768 IFA_F_TEMPORARY,
769 RT_SCOPE_UNIVERSE));
770 SendMessageToDeviceInfo(*message);
771
772 IPAddress address3(IPAddress::kFamilyIPv6);
773 EXPECT_TRUE(address3.SetAddressFromString(kTestIPAddress3));
774
775 // The only IPv6 addresses on this interface are either flagged as
776 // temporary, or they are not universally scoped.
777 EXPECT_FALSE(device_info_.HasOtherAddress(kTestDeviceIndex, address3));
778
779
780 message.reset(BuildAddressMessage(RTNLMessage::kModeAdd,
781 address3,
782 0,
783 RT_SCOPE_UNIVERSE));
784 SendMessageToDeviceInfo(*message);
785
786 // address0 is on this interface.
787 EXPECT_FALSE(device_info_.HasOtherAddress(kTestDeviceIndex, address0));
788 // address1 is on this interface.
789 EXPECT_FALSE(device_info_.HasOtherAddress(kTestDeviceIndex, address1));
790 // address2 is on this interface.
791 EXPECT_FALSE(device_info_.HasOtherAddress(kTestDeviceIndex, address2));
792 // address3 is on this interface.
793 EXPECT_FALSE(device_info_.HasOtherAddress(kTestDeviceIndex, address3));
794
795 IPAddress address4(IPAddress::kFamilyIPv6);
796 EXPECT_TRUE(address4.SetAddressFromString(kTestIPAddress4));
797
798 // address4 is not on this interface, but address3 is, and is a qualified
799 // IPv6 address.
800 EXPECT_TRUE(device_info_.HasOtherAddress(kTestDeviceIndex, address4));
801
802 message.reset(BuildAddressMessage(RTNLMessage::kModeAdd,
803 address4,
804 IFA_F_PERMANENT,
805 RT_SCOPE_UNIVERSE));
806 SendMessageToDeviceInfo(*message);
807
808 // address4 is now on this interface.
809 EXPECT_FALSE(device_info_.HasOtherAddress(kTestDeviceIndex, address4));
810
811 IPAddress address5(IPAddress::kFamilyIPv4);
812 EXPECT_TRUE(address5.SetAddressFromString(kTestIPAddress5));
813 // address5 is not on this interface, but address0 is.
814 EXPECT_TRUE(device_info_.HasOtherAddress(kTestDeviceIndex, address5));
815
816 message.reset(BuildAddressMessage(RTNLMessage::kModeAdd,
817 address5,
818 IFA_F_PERMANENT,
819 RT_SCOPE_UNIVERSE));
820 SendMessageToDeviceInfo(*message);
821
822 // address5 is now on this interface.
823 EXPECT_FALSE(device_info_.HasOtherAddress(kTestDeviceIndex, address5));
824}
825
Paul Stewarta0db0ff2013-12-09 09:48:47 -0800826TEST_F(DeviceInfoTest, HasDirectConnectivityTo) {
827 scoped_ptr<RTNLMessage> message(BuildLinkMessage(RTNLMessage::kModeAdd));
828 SendMessageToDeviceInfo(*message);
829
830 IPAddress address0(IPAddress::kFamilyIPv4);
831 EXPECT_TRUE(address0.SetAddressFromString(kTestIPAddress0));
832
833 // There are no addresses on this interface.
834 EXPECT_FALSE(device_info_.HasDirectConnectivityTo(
835 kTestDeviceIndex, address0));
836
837 IPAddress address1(IPAddress::kFamilyIPv6);
838 EXPECT_TRUE(address1.SetAddressFromString(kTestIPAddress1));
839 message.reset(BuildAddressMessage(RTNLMessage::kModeAdd,
840 address1,
841 IFA_F_PERMANENT,
842 RT_SCOPE_UNIVERSE));
843 SendMessageToDeviceInfo(*message);
844
845 // No current addresses are of the same family as |address0|.
846 EXPECT_FALSE(device_info_.HasDirectConnectivityTo(
847 kTestDeviceIndex, address0));
848
849 IPAddress address6(IPAddress::kFamilyIPv4);
850 EXPECT_TRUE(address6.SetAddressFromString(kTestIPAddress6));
851 address6.set_prefix(kTestIPAddressPrefix0);
852 message.reset(BuildAddressMessage(RTNLMessage::kModeAdd,
853 address6,
854 IFA_F_PERMANENT,
855 RT_SCOPE_UNIVERSE));
856 SendMessageToDeviceInfo(*message);
857
858 // |address0| is not reachable from |address6|.
859 EXPECT_FALSE(device_info_.HasDirectConnectivityTo(
860 kTestDeviceIndex, address0));
861
862 IPAddress address5(IPAddress::kFamilyIPv4);
863 EXPECT_TRUE(address5.SetAddressFromString(kTestIPAddress5));
864 address5.set_prefix(kTestIPAddressPrefix0);
865 message.reset(BuildAddressMessage(RTNLMessage::kModeAdd,
866 address5,
867 IFA_F_PERMANENT,
868 RT_SCOPE_UNIVERSE));
869 SendMessageToDeviceInfo(*message);
870
871 // |address0| is reachable from |address5| which is associated with the
872 // interface.
873 EXPECT_TRUE(device_info_.HasDirectConnectivityTo(
874 kTestDeviceIndex, address0));
875}
876
Thieu Leb27beee2012-04-20 09:19:06 -0700877TEST_F(DeviceInfoTest, HasSubdir) {
Paul Stewart5ad16062013-02-21 18:10:48 -0800878 base::ScopedTempDir temp_dir;
Thieu Le8f1c8352012-04-16 11:02:12 -0700879 EXPECT_TRUE(temp_dir.CreateUniqueTempDir());
Ben Chana0ddf462014-02-06 11:32:42 -0800880 EXPECT_TRUE(base::CreateDirectory(temp_dir.path().Append("child1")));
Thieu Leb27beee2012-04-20 09:19:06 -0700881 FilePath child2 = temp_dir.path().Append("child2");
Ben Chana0ddf462014-02-06 11:32:42 -0800882 EXPECT_TRUE(base::CreateDirectory(child2));
Thieu Leb27beee2012-04-20 09:19:06 -0700883 FilePath grandchild = child2.Append("grandchild");
Ben Chana0ddf462014-02-06 11:32:42 -0800884 EXPECT_TRUE(base::CreateDirectory(grandchild));
885 EXPECT_TRUE(base::CreateDirectory(grandchild.Append("greatgrandchild")));
Thieu Leb27beee2012-04-20 09:19:06 -0700886 EXPECT_TRUE(DeviceInfo::HasSubdir(temp_dir.path(),
887 FilePath("grandchild")));
888 EXPECT_TRUE(DeviceInfo::HasSubdir(temp_dir.path(),
889 FilePath("greatgrandchild")));
890 EXPECT_FALSE(DeviceInfo::HasSubdir(temp_dir.path(),
891 FilePath("nonexistent")));
Thieu Le8f1c8352012-04-16 11:02:12 -0700892}
893
Gary Morain41780232012-07-31 15:08:31 -0700894TEST_F(DeviceInfoTest, GetMACAddressFromKernelUnknownDevice) {
895 SetSockets();
896 EXPECT_CALL(*mock_sockets_, Socket(PF_INET, SOCK_DGRAM, 0)).Times(0);
897 ByteString mac_address =
898 device_info_.GetMACAddressFromKernel(kTestDeviceIndex);
899 EXPECT_TRUE(mac_address.IsEmpty());
900}
901
902TEST_F(DeviceInfoTest, GetMACAddressFromKernelUnableToOpenSocket) {
903 SetSockets();
904 EXPECT_CALL(*mock_sockets_, Socket(PF_INET, SOCK_DGRAM, 0))
905 .WillOnce(Return(-1));
906 scoped_ptr<RTNLMessage> message(BuildLinkMessage(RTNLMessage::kModeAdd));
907 message->set_link_status(RTNLMessage::LinkStatus(0, IFF_LOWER_UP, 0));
908 SendMessageToDeviceInfo(*message);
909 EXPECT_TRUE(device_info_.GetDevice(kTestDeviceIndex).get());
910 ByteString mac_address =
911 device_info_.GetMACAddressFromKernel(kTestDeviceIndex);
912 EXPECT_TRUE(mac_address.IsEmpty());
913}
914
915TEST_F(DeviceInfoTest, GetMACAddressFromKernelIoctlFails) {
916 SetSockets();
917 const int kFd = 99;
918 EXPECT_CALL(*mock_sockets_, Socket(PF_INET, SOCK_DGRAM, 0))
919 .WillOnce(Return(kFd));
920 EXPECT_CALL(*mock_sockets_, Ioctl(kFd, SIOCGIFHWADDR, NotNull()))
921 .WillOnce(Return(-1));
922 EXPECT_CALL(*mock_sockets_, Close(kFd));
923
924 scoped_ptr<RTNLMessage> message(BuildLinkMessage(RTNLMessage::kModeAdd));
925 message->set_link_status(RTNLMessage::LinkStatus(0, IFF_LOWER_UP, 0));
926 SendMessageToDeviceInfo(*message);
927 EXPECT_TRUE(device_info_.GetDevice(kTestDeviceIndex).get());
928
929 ByteString mac_address =
930 device_info_.GetMACAddressFromKernel(kTestDeviceIndex);
931 EXPECT_TRUE(mac_address.IsEmpty());
932}
933
934MATCHER_P2(IfreqEquals, ifindex, ifname, "") {
935 const struct ifreq *const ifr = static_cast<struct ifreq *>(arg);
936 return (ifr != NULL) &&
937 (ifr->ifr_ifindex == ifindex) &&
938 (strcmp(ifname, ifr->ifr_name) == 0);
939}
940
941ACTION_P(SetIfreq, ifr) {
942 struct ifreq *const ifr_arg = static_cast<struct ifreq *>(arg2);
943 *ifr_arg = ifr;
944}
945
946TEST_F(DeviceInfoTest, GetMACAddressFromKernel) {
947 SetSockets();
948 const int kFd = 99;
949 struct ifreq ifr;
Han Shenfc349252012-08-30 11:36:04 -0700950 static uint8_t kMacAddress[] = {0x00, 0x01, 0x02, 0xaa, 0xbb, 0xcc};
Gary Morain41780232012-07-31 15:08:31 -0700951 memcpy(ifr.ifr_hwaddr.sa_data, kMacAddress, sizeof(kMacAddress));
952 EXPECT_CALL(*mock_sockets_, Socket(PF_INET, SOCK_DGRAM, 0))
953 .WillOnce(Return(kFd));
954 EXPECT_CALL(*mock_sockets_,
955 Ioctl(kFd, SIOCGIFHWADDR,
956 IfreqEquals(kTestDeviceIndex, kTestDeviceName)))
957 .WillOnce(DoAll(SetIfreq(ifr), Return(0)));
958 EXPECT_CALL(*mock_sockets_, Close(kFd));
959
960 scoped_ptr<RTNLMessage> message(BuildLinkMessage(RTNLMessage::kModeAdd));
961 message->set_link_status(RTNLMessage::LinkStatus(0, IFF_LOWER_UP, 0));
962 SendMessageToDeviceInfo(*message);
963 EXPECT_TRUE(device_info_.GetDevice(kTestDeviceIndex).get());
964
965 ByteString mac_address =
966 device_info_.GetMACAddressFromKernel(kTestDeviceIndex);
967 EXPECT_THAT(kMacAddress,
968 ElementsAreArray(mac_address.GetData(), sizeof(kMacAddress)));
969}
970
Paul Stewart6950ba52013-12-05 08:28:14 -0800971TEST_F(DeviceInfoTest, GetMACAddressOfPeerUnknownDevice) {
972 SetSockets();
973 EXPECT_CALL(*mock_sockets_, Socket(PF_INET, SOCK_DGRAM, 0)).Times(0);
974 IPAddress address(IPAddress::kFamilyIPv4);
975 EXPECT_TRUE(address.SetAddressFromString(kTestIPAddress0));
976 ByteString mac_address;
977 EXPECT_FALSE(device_info_.GetDevice(kTestDeviceIndex).get());
978 EXPECT_FALSE(device_info_.GetMACAddressOfPeer(
979 kTestDeviceIndex, address, &mac_address));
980}
981
982TEST_F(DeviceInfoTest, GetMACAddressOfPeerBadAddress) {
983 SetSockets();
984 scoped_ptr<RTNLMessage> message(BuildLinkMessage(RTNLMessage::kModeAdd));
985 message->set_link_status(RTNLMessage::LinkStatus(0, IFF_LOWER_UP, 0));
986 SendMessageToDeviceInfo(*message);
987 EXPECT_TRUE(device_info_.GetDevice(kTestDeviceIndex).get());
988
989 EXPECT_CALL(*mock_sockets_, Socket(PF_INET, SOCK_DGRAM, 0)).Times(0);
990
991 // An improperly formatted IPv4 address should fail.
992 IPAddress empty_ipv4_address(IPAddress::kFamilyIPv4);
993 ByteString mac_address;
994 EXPECT_FALSE(device_info_.GetMACAddressOfPeer(
995 kTestDeviceIndex, empty_ipv4_address, &mac_address));
996
997 // IPv6 addresses are not supported.
998 IPAddress valid_ipv6_address(IPAddress::kFamilyIPv6);
999 EXPECT_TRUE(valid_ipv6_address.SetAddressFromString(kTestIPAddress1));
1000 EXPECT_FALSE(device_info_.GetMACAddressOfPeer(
1001 kTestDeviceIndex, valid_ipv6_address, &mac_address));
1002}
1003
1004TEST_F(DeviceInfoTest, GetMACAddressOfPeerUnableToOpenSocket) {
1005 SetSockets();
1006 EXPECT_CALL(*mock_sockets_, Socket(PF_INET, SOCK_DGRAM, 0))
1007 .WillOnce(Return(-1));
1008 scoped_ptr<RTNLMessage> message(BuildLinkMessage(RTNLMessage::kModeAdd));
1009 message->set_link_status(RTNLMessage::LinkStatus(0, IFF_LOWER_UP, 0));
1010 SendMessageToDeviceInfo(*message);
1011 IPAddress ip_address(IPAddress::kFamilyIPv4);
1012 EXPECT_TRUE(ip_address.SetAddressFromString(kTestIPAddress0));
1013 ByteString mac_address;
1014 EXPECT_FALSE(device_info_.GetMACAddressOfPeer(
1015 kTestDeviceIndex, ip_address, &mac_address));
1016}
1017
1018TEST_F(DeviceInfoTest, GetMACAddressOfPeerIoctlFails) {
1019 SetSockets();
1020 const int kFd = 99;
1021 EXPECT_CALL(*mock_sockets_, Socket(PF_INET, SOCK_DGRAM, 0))
1022 .WillOnce(Return(kFd));
1023 EXPECT_CALL(*mock_sockets_, Ioctl(kFd, SIOCGARP, NotNull()))
1024 .WillOnce(Return(-1));
1025 scoped_ptr<RTNLMessage> message(BuildLinkMessage(RTNLMessage::kModeAdd));
1026 message->set_link_status(RTNLMessage::LinkStatus(0, IFF_LOWER_UP, 0));
1027 SendMessageToDeviceInfo(*message);
1028 IPAddress ip_address(IPAddress::kFamilyIPv4);
1029 EXPECT_TRUE(ip_address.SetAddressFromString(kTestIPAddress0));
1030 ByteString mac_address;
1031 EXPECT_FALSE(device_info_.GetMACAddressOfPeer(
1032 kTestDeviceIndex, ip_address, &mac_address));
1033}
1034
1035MATCHER_P2(ArpreqEquals, ifname, peer, "") {
1036 const struct arpreq *const areq = static_cast<struct arpreq *>(arg);
1037 if (areq == NULL) {
1038 return false;
1039 }
1040
1041 const struct sockaddr_in *const protocol_address =
1042 reinterpret_cast<const struct sockaddr_in *>(&areq->arp_pa);
1043 const struct sockaddr_in *const hardware_address =
1044 reinterpret_cast<const struct sockaddr_in *>(&areq->arp_ha);
1045
1046 return
1047 strcmp(ifname, areq->arp_dev) == 0 &&
1048 protocol_address->sin_family == AF_INET &&
1049 memcmp(&protocol_address->sin_addr.s_addr,
1050 peer.address().GetConstData(),
1051 peer.address().GetLength()) == 0 &&
1052 hardware_address->sin_family == ARPHRD_ETHER;
1053}
1054
1055ACTION_P(SetArpreq, areq) {
1056 struct arpreq *const areq_arg = static_cast<struct arpreq *>(arg2);
1057 *areq_arg = areq;
1058}
1059
1060TEST_F(DeviceInfoTest, GetMACAddressOfPeer) {
1061 scoped_ptr<RTNLMessage> message(BuildLinkMessage(RTNLMessage::kModeAdd));
1062 message->set_link_status(RTNLMessage::LinkStatus(0, IFF_LOWER_UP, 0));
1063 SendMessageToDeviceInfo(*message);
1064
1065 SetSockets();
1066
1067 const int kFd = 99;
1068 EXPECT_CALL(*mock_sockets_, Socket(PF_INET, SOCK_DGRAM, 0))
1069 .WillRepeatedly(Return(kFd));
1070
1071 IPAddress ip_address(IPAddress::kFamilyIPv4);
1072 EXPECT_TRUE(ip_address.SetAddressFromString(kTestIPAddress0));
1073
1074 static uint8_t kZeroMacAddress[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
1075 struct arpreq zero_areq_response;
1076 memcpy(zero_areq_response.arp_ha.sa_data, kZeroMacAddress,
1077 sizeof(kZeroMacAddress));
1078
1079 static uint8_t kMacAddress[] = {0x01, 0x02, 0x03, 0xaa, 0xbb, 0xcc};
1080 struct arpreq areq_response;
1081 memcpy(areq_response.arp_ha.sa_data, kMacAddress, sizeof(kMacAddress));
1082
1083 EXPECT_CALL(*mock_sockets_, Ioctl(
1084 kFd, SIOCGARP, ArpreqEquals(kTestDeviceName, ip_address)))
1085 .WillOnce(DoAll(SetArpreq(zero_areq_response), Return(0)))
1086 .WillOnce(DoAll(SetArpreq(areq_response), Return(0)));
1087
1088 ByteString mac_address;
1089 EXPECT_FALSE(device_info_.GetMACAddressOfPeer(
1090 kTestDeviceIndex, ip_address, &mac_address));
1091 EXPECT_TRUE(device_info_.GetMACAddressOfPeer(
1092 kTestDeviceIndex, ip_address, &mac_address));
1093 EXPECT_THAT(kMacAddress,
1094 ElementsAreArray(mac_address.GetData(), sizeof(kMacAddress)));
1095}
1096
Paul Stewartd55f6ae2014-04-24 16:34:21 -07001097TEST_F(DeviceInfoTest, IPv6AddressChanged) {
1098 scoped_refptr<MockDevice> device(new MockDevice(
1099 &control_interface_, &dispatcher_, &metrics_, &manager_,
1100 "null0", "addr0", kTestDeviceIndex));
1101
1102 // Device info entry does not exist.
1103 EXPECT_FALSE(device_info_.GetPrimaryIPv6Address(kTestDeviceIndex, NULL));
1104
1105 device_info_.infos_[kTestDeviceIndex].device = device;
1106
1107 // Device info entry contains no addresses.
1108 EXPECT_FALSE(device_info_.GetPrimaryIPv6Address(kTestDeviceIndex, NULL));
1109
1110 IPAddress ipv4_address(IPAddress::kFamilyIPv4);
1111 EXPECT_TRUE(ipv4_address.SetAddressFromString(kTestIPAddress0));
1112 auto message(make_scoped_ptr(BuildAddressMessage(
1113 RTNLMessage::kModeAdd, ipv4_address, 0, 0)));
1114
1115 EXPECT_CALL(*device, OnIPv6AddressChanged()).Times(0);
1116
1117 // We should ignore IPv4 addresses.
1118 SendMessageToDeviceInfo(*message);
1119 EXPECT_FALSE(device_info_.GetPrimaryIPv6Address(kTestDeviceIndex, NULL));
1120
1121 IPAddress ipv6_address1(IPAddress::kFamilyIPv6);
1122 EXPECT_TRUE(ipv6_address1.SetAddressFromString(kTestIPAddress1));
1123 message.reset(BuildAddressMessage(
1124 RTNLMessage::kModeAdd, ipv6_address1, 0, RT_SCOPE_LINK));
1125
1126 // We should ignore non-SCOPE_UNIVERSE messages for IPv6.
1127 SendMessageToDeviceInfo(*message);
1128 EXPECT_FALSE(device_info_.GetPrimaryIPv6Address(kTestDeviceIndex, NULL));
1129
1130 Mock::VerifyAndClearExpectations(device);
1131 IPAddress ipv6_address2(IPAddress::kFamilyIPv6);
1132 EXPECT_TRUE(ipv6_address2.SetAddressFromString(kTestIPAddress2));
1133 message.reset(BuildAddressMessage(
1134 RTNLMessage::kModeAdd, ipv6_address2, IFA_F_TEMPORARY,
1135 RT_SCOPE_UNIVERSE));
1136
1137 // Add a temporary address.
1138 EXPECT_CALL(*device, OnIPv6AddressChanged());
1139 SendMessageToDeviceInfo(*message);
1140 IPAddress address0(IPAddress::kFamilyUnknown);
1141 EXPECT_TRUE(device_info_.GetPrimaryIPv6Address(kTestDeviceIndex, &address0));
1142 EXPECT_TRUE(address0.Equals(ipv6_address2));
1143 Mock::VerifyAndClearExpectations(device);
1144
1145 IPAddress ipv6_address3(IPAddress::kFamilyIPv6);
1146 EXPECT_TRUE(ipv6_address3.SetAddressFromString(kTestIPAddress3));
1147 message.reset(BuildAddressMessage(
1148 RTNLMessage::kModeAdd, ipv6_address3, 0, RT_SCOPE_UNIVERSE));
1149
1150 // Adding a non-temporary address alerts the Device, but does not override
1151 // the primary address since the previous one was temporary.
1152 EXPECT_CALL(*device, OnIPv6AddressChanged());
1153 SendMessageToDeviceInfo(*message);
1154 IPAddress address1(IPAddress::kFamilyUnknown);
1155 EXPECT_TRUE(device_info_.GetPrimaryIPv6Address(kTestDeviceIndex, &address1));
1156 EXPECT_TRUE(address1.Equals(ipv6_address2));
1157 Mock::VerifyAndClearExpectations(device);
1158
1159 IPAddress ipv6_address4(IPAddress::kFamilyIPv6);
1160 EXPECT_TRUE(ipv6_address4.SetAddressFromString(kTestIPAddress4));
1161 message.reset(BuildAddressMessage(
1162 RTNLMessage::kModeAdd, ipv6_address4, IFA_F_TEMPORARY,
1163 RT_SCOPE_UNIVERSE));
1164
1165 // Another temporary address alerts the Device, and will override
1166 // the primary address.
1167 EXPECT_CALL(*device, OnIPv6AddressChanged());
1168 SendMessageToDeviceInfo(*message);
1169 IPAddress address2(IPAddress::kFamilyUnknown);
1170 EXPECT_TRUE(device_info_.GetPrimaryIPv6Address(kTestDeviceIndex, &address2));
1171 EXPECT_TRUE(address2.Equals(ipv6_address4));
1172}
1173
Peter Qiu98551702014-07-28 13:28:53 -07001174
1175TEST_F(DeviceInfoTest, IPv6DnsServerAddressesChanged) {
1176 scoped_refptr<MockDevice> device(new MockDevice(
1177 &control_interface_, &dispatcher_, &metrics_, &manager_,
1178 "null0", "addr0", kTestDeviceIndex));
1179 device_info_.time_ = &time_;
1180 vector<IPAddress> dns_server_addresses_out;
Ben Chan7fab8972014-08-10 17:14:46 -07001181 uint32_t lifetime_out;
Peter Qiu98551702014-07-28 13:28:53 -07001182
1183 // Device info entry does not exist.
1184 EXPECT_FALSE(device_info_.GetIPv6DnsServerAddresses(
1185 kTestDeviceIndex, &dns_server_addresses_out, &lifetime_out));
1186
1187 device_info_.infos_[kTestDeviceIndex].device = device;
1188
1189 // Device info entry contains no IPv6 dns server addresses.
1190 EXPECT_FALSE(device_info_.GetIPv6DnsServerAddresses(
1191 kTestDeviceIndex, &dns_server_addresses_out, &lifetime_out));
1192
1193 // Setup IPv6 dns server addresses.
1194 IPAddress ipv6_address1(IPAddress::kFamilyIPv6);
1195 IPAddress ipv6_address2(IPAddress::kFamilyIPv6);
1196 EXPECT_TRUE(ipv6_address1.SetAddressFromString(kTestIPAddress1));
1197 EXPECT_TRUE(ipv6_address2.SetAddressFromString(kTestIPAddress2));
1198 vector<IPAddress> dns_server_addresses_in;
1199 dns_server_addresses_in.push_back(ipv6_address1);
1200 dns_server_addresses_in.push_back(ipv6_address2);
1201
1202 // Infinite lifetime
Ben Chan7fab8972014-08-10 17:14:46 -07001203 const uint32_t kInfiniteLifetime = 0xffffffff;
Peter Qiu98551702014-07-28 13:28:53 -07001204 auto message(make_scoped_ptr(BuildRdnssMessage(
1205 RTNLMessage::kModeAdd, kInfiniteLifetime, dns_server_addresses_in)));
1206 EXPECT_CALL(time_, GetSecondsBoottime(_)).
1207 WillOnce(DoAll(SetArgPointee<0>(0), Return(true)));
1208 EXPECT_CALL(*device, OnIPv6DnsServerAddressesChanged()).Times(1);
1209 SendMessageToDeviceInfo(*message);
1210 EXPECT_CALL(time_, GetSecondsBoottime(_)).Times(0);
1211 EXPECT_TRUE(device_info_.GetIPv6DnsServerAddresses(
1212 kTestDeviceIndex, &dns_server_addresses_out, &lifetime_out));
1213 // Verify addresses and lifetime.
1214 EXPECT_EQ(kInfiniteLifetime, lifetime_out);
1215 EXPECT_EQ(2, dns_server_addresses_out.size());
1216 EXPECT_EQ(kTestIPAddress1, dns_server_addresses_out.at(0).ToString());
1217 EXPECT_EQ(kTestIPAddress2, dns_server_addresses_out.at(1).ToString());
1218
1219 // Lifetime of 120, retrieve DNS server addresses after 10 seconds.
Ben Chan7fab8972014-08-10 17:14:46 -07001220 const uint32_t kLifetime120 = 120;
1221 const uint32_t kElapseTime10 = 10;
Peter Qiu98551702014-07-28 13:28:53 -07001222 auto message1(make_scoped_ptr(BuildRdnssMessage(
1223 RTNLMessage::kModeAdd, kLifetime120, dns_server_addresses_in)));
1224 EXPECT_CALL(time_, GetSecondsBoottime(_)).
1225 WillOnce(DoAll(SetArgPointee<0>(0), Return(true)));
1226 EXPECT_CALL(*device, OnIPv6DnsServerAddressesChanged()).Times(1);
1227 SendMessageToDeviceInfo(*message1);
1228 // 10 seconds passed when GetIPv6DnsServerAddreses is called.
1229 EXPECT_CALL(time_, GetSecondsBoottime(_)).
1230 WillOnce(DoAll(SetArgPointee<0>(kElapseTime10), Return(true)));
1231 EXPECT_TRUE(device_info_.GetIPv6DnsServerAddresses(
1232 kTestDeviceIndex, &dns_server_addresses_out, &lifetime_out));
1233 // Verify addresses and lifetime.
1234 EXPECT_EQ(kLifetime120 - kElapseTime10, lifetime_out);
1235 EXPECT_EQ(2, dns_server_addresses_out.size());
1236 EXPECT_EQ(kTestIPAddress1, dns_server_addresses_out.at(0).ToString());
1237 EXPECT_EQ(kTestIPAddress2, dns_server_addresses_out.at(1).ToString());
1238
1239 // Lifetime of 120, retrieve DNS server addresses after lifetime expired.
1240 EXPECT_CALL(time_, GetSecondsBoottime(_)).
1241 WillOnce(DoAll(SetArgPointee<0>(0), Return(true)));
1242 EXPECT_CALL(*device, OnIPv6DnsServerAddressesChanged()).Times(1);
1243 SendMessageToDeviceInfo(*message1);
1244 // 120 seconds passed when GetIPv6DnsServerAddreses is called.
1245 EXPECT_CALL(time_, GetSecondsBoottime(_)).
1246 WillOnce(DoAll(SetArgPointee<0>(kLifetime120), Return(true)));
1247 EXPECT_TRUE(device_info_.GetIPv6DnsServerAddresses(
1248 kTestDeviceIndex, &dns_server_addresses_out, &lifetime_out));
1249 // Verify addresses and lifetime.
1250 EXPECT_EQ(0, lifetime_out);
1251 EXPECT_EQ(2, dns_server_addresses_out.size());
1252 EXPECT_EQ(kTestIPAddress1, dns_server_addresses_out.at(0).ToString());
1253 EXPECT_EQ(kTestIPAddress2, dns_server_addresses_out.at(1).ToString());
1254}
1255
Paul Stewartca876ee2012-04-21 08:55:58 -07001256class DeviceInfoTechnologyTest : public DeviceInfoTest {
1257 public:
Jason Glasgowabc54032012-04-20 16:08:32 -04001258 DeviceInfoTechnologyTest()
1259 : DeviceInfoTest(),
1260 test_device_name_(kTestDeviceName) {}
Paul Stewartca876ee2012-04-21 08:55:58 -07001261 virtual ~DeviceInfoTechnologyTest() {}
1262
1263 virtual void SetUp() {
mukesh agrawal62ba51c2014-04-18 16:09:58 -07001264 CHECK(temp_dir_.CreateUniqueTempDir());
Paul Stewartca876ee2012-04-21 08:55:58 -07001265 device_info_root_ = temp_dir_.path().Append("sys/class/net");
1266 device_info_.device_info_root_ = device_info_root_;
1267 // Most tests require that the uevent file exist.
1268 CreateInfoFile("uevent", "xxx");
1269 }
1270
1271 Technology::Identifier GetDeviceTechnology() {
Jason Glasgowabc54032012-04-20 16:08:32 -04001272 return device_info_.GetDeviceTechnology(test_device_name_);
Paul Stewartca876ee2012-04-21 08:55:58 -07001273 }
1274 FilePath GetInfoPath(const string &name);
1275 void CreateInfoFile(const string &name, const string &contents);
1276 void CreateInfoSymLink(const string &name, const string &contents);
Jason Glasgowabc54032012-04-20 16:08:32 -04001277 void SetDeviceName(const string &name) {
1278 test_device_name_ = name;
mukesh agrawal62ba51c2014-04-18 16:09:58 -07001279 EXPECT_TRUE(temp_dir_.Delete()); // nuke old temp dir
Jason Glasgowabc54032012-04-20 16:08:32 -04001280 SetUp();
1281 }
Paul Stewartca876ee2012-04-21 08:55:58 -07001282
1283 protected:
Paul Stewart5ad16062013-02-21 18:10:48 -08001284 base::ScopedTempDir temp_dir_;
Paul Stewartca876ee2012-04-21 08:55:58 -07001285 FilePath device_info_root_;
Jason Glasgowabc54032012-04-20 16:08:32 -04001286 string test_device_name_;
Paul Stewartca876ee2012-04-21 08:55:58 -07001287};
1288
1289FilePath DeviceInfoTechnologyTest::GetInfoPath(const string &name) {
Jason Glasgowabc54032012-04-20 16:08:32 -04001290 return device_info_root_.Append(test_device_name_).Append(name);
Paul Stewartca876ee2012-04-21 08:55:58 -07001291}
1292
1293void DeviceInfoTechnologyTest::CreateInfoFile(const string &name,
1294 const string &contents) {
1295 FilePath info_path = GetInfoPath(name);
Ben Chana0ddf462014-02-06 11:32:42 -08001296 EXPECT_TRUE(base::CreateDirectory(info_path.DirName()));
Paul Stewartca876ee2012-04-21 08:55:58 -07001297 string contents_newline(contents + "\n");
Ben Chan6fbf64f2014-05-21 18:07:01 -07001298 EXPECT_TRUE(base::WriteFile(info_path, contents_newline.c_str(),
1299 contents_newline.size()));
Paul Stewartca876ee2012-04-21 08:55:58 -07001300}
1301
1302void DeviceInfoTechnologyTest::CreateInfoSymLink(const string &name,
1303 const string &contents) {
1304 FilePath info_path = GetInfoPath(name);
Ben Chana0ddf462014-02-06 11:32:42 -08001305 EXPECT_TRUE(base::CreateDirectory(info_path.DirName()));
1306 EXPECT_TRUE(base::CreateSymbolicLink(FilePath(contents), info_path));
Paul Stewartca876ee2012-04-21 08:55:58 -07001307}
1308
1309TEST_F(DeviceInfoTechnologyTest, Unknown) {
1310 EXPECT_EQ(Technology::kUnknown, GetDeviceTechnology());
1311 // Should still be unknown even without a uevent file.
Ben Chana0ddf462014-02-06 11:32:42 -08001312 EXPECT_TRUE(base::DeleteFile(GetInfoPath("uevent"), false));
Paul Stewartca876ee2012-04-21 08:55:58 -07001313 EXPECT_EQ(Technology::kUnknown, GetDeviceTechnology());
1314}
1315
1316TEST_F(DeviceInfoTechnologyTest, Loopback) {
1317 CreateInfoFile("type", base::IntToString(ARPHRD_LOOPBACK));
1318 EXPECT_EQ(Technology::kLoopback, GetDeviceTechnology());
1319}
1320
1321TEST_F(DeviceInfoTechnologyTest, PPP) {
1322 CreateInfoFile("type", base::IntToString(ARPHRD_PPP));
1323 EXPECT_EQ(Technology::kPPP, GetDeviceTechnology());
1324}
1325
1326TEST_F(DeviceInfoTechnologyTest, Tunnel) {
1327 CreateInfoFile("tun_flags", base::IntToString(IFF_TUN));
1328 EXPECT_EQ(Technology::kTunnel, GetDeviceTechnology());
1329}
1330
1331TEST_F(DeviceInfoTechnologyTest, WiFi) {
1332 CreateInfoFile("uevent", "DEVTYPE=wlan");
1333 EXPECT_EQ(Technology::kWifi, GetDeviceTechnology());
1334 CreateInfoFile("uevent", "foo\nDEVTYPE=wlan");
1335 EXPECT_EQ(Technology::kWifi, GetDeviceTechnology());
1336 CreateInfoFile("type", base::IntToString(ARPHRD_IEEE80211_RADIOTAP));
1337 EXPECT_EQ(Technology::kWiFiMonitor, GetDeviceTechnology());
1338}
1339
1340TEST_F(DeviceInfoTechnologyTest, Ethernet) {
1341 CreateInfoSymLink("device/driver", "xxx");
1342 EXPECT_EQ(Technology::kEthernet, GetDeviceTechnology());
1343}
1344
Darin Petkove4b27022012-05-16 13:28:50 +02001345TEST_F(DeviceInfoTechnologyTest, WiMax) {
1346 CreateInfoSymLink("device/driver", "gdm_wimax");
1347 EXPECT_EQ(Technology::kWiMax, GetDeviceTechnology());
1348}
1349
Paul Stewartca876ee2012-04-21 08:55:58 -07001350TEST_F(DeviceInfoTechnologyTest, CellularGobi1) {
1351 CreateInfoSymLink("device/driver", "blah/foo/gobi");
1352 EXPECT_EQ(Technology::kCellular, GetDeviceTechnology());
1353}
1354
1355TEST_F(DeviceInfoTechnologyTest, CellularGobi2) {
1356 CreateInfoSymLink("device/driver", "../GobiNet");
1357 EXPECT_EQ(Technology::kCellular, GetDeviceTechnology());
1358}
1359
1360TEST_F(DeviceInfoTechnologyTest, QCUSB) {
1361 CreateInfoSymLink("device/driver", "QCUSBNet2k");
1362 EXPECT_EQ(Technology::kCellular, GetDeviceTechnology());
1363}
1364
Ben Chan0f90e0b2013-06-26 23:37:16 -07001365TEST_F(DeviceInfoTechnologyTest, CellularCdcMbim) {
1366 CreateInfoSymLink("device/driver", "cdc_mbim");
1367 EXPECT_EQ(Technology::kCellular, GetDeviceTechnology());
1368}
1369
Ben Chan226d46a2012-10-11 00:22:17 -07001370TEST_F(DeviceInfoTechnologyTest, CellularQmiWwan) {
1371 CreateInfoSymLink("device/driver", "qmi_wwan");
1372 EXPECT_EQ(Technology::kCellular, GetDeviceTechnology());
1373}
1374
Paul Stewartca876ee2012-04-21 08:55:58 -07001375// Modem with absolute driver path with top-level tty file:
1376// /sys/class/net/dev0/device -> /sys/devices/virtual/0/00
Ben Chan4eb4ddf2013-06-20 22:16:56 -07001377// /sys/devices/virtual/0/00/driver -> /drivers/cdc_ether or /drivers/cdc_ncm
Paul Stewartca876ee2012-04-21 08:55:58 -07001378// /sys/devices/virtual/0/01/tty [empty directory]
Ben Chan4eb4ddf2013-06-20 22:16:56 -07001379TEST_F(DeviceInfoTechnologyTest, CDCEthernetModem1) {
Paul Stewartca876ee2012-04-21 08:55:58 -07001380 FilePath device_root(temp_dir_.path().Append("sys/devices/virtual/0"));
1381 FilePath device_path(device_root.Append("00"));
Ben Chan4eb4ddf2013-06-20 22:16:56 -07001382 FilePath driver_symlink(device_path.Append("driver"));
Ben Chana0ddf462014-02-06 11:32:42 -08001383 EXPECT_TRUE(base::CreateDirectory(device_path));
Paul Stewartca876ee2012-04-21 08:55:58 -07001384 CreateInfoSymLink("device", device_path.value());
Ben Chana0ddf462014-02-06 11:32:42 -08001385 EXPECT_TRUE(base::CreateSymbolicLink(FilePath("/drivers/cdc_ether"),
1386 driver_symlink));
1387 EXPECT_TRUE(base::CreateDirectory(device_root.Append("01/tty")));
Paul Stewartca876ee2012-04-21 08:55:58 -07001388 EXPECT_EQ(Technology::kCellular, GetDeviceTechnology());
Ben Chan4eb4ddf2013-06-20 22:16:56 -07001389
Ben Chana0ddf462014-02-06 11:32:42 -08001390 EXPECT_TRUE(base::DeleteFile(driver_symlink, false));
1391 EXPECT_TRUE(base::CreateSymbolicLink(FilePath("/drivers/cdc_ncm"),
1392 driver_symlink));
Ben Chan4eb4ddf2013-06-20 22:16:56 -07001393 EXPECT_EQ(Technology::kCellular, GetDeviceTechnology());
Paul Stewartca876ee2012-04-21 08:55:58 -07001394}
1395
1396// Modem with relative driver path with top-level tty file.
1397// /sys/class/net/dev0/device -> ../../../device_dir/0/00
Ben Chan4eb4ddf2013-06-20 22:16:56 -07001398// /sys/device_dir/0/00/driver -> /drivers/cdc_ether or /drivers/cdc_ncm
Paul Stewartca876ee2012-04-21 08:55:58 -07001399// /sys/device_dir/0/01/tty [empty directory]
Ben Chan4eb4ddf2013-06-20 22:16:56 -07001400TEST_F(DeviceInfoTechnologyTest, CDCEthernetModem2) {
Paul Stewartca876ee2012-04-21 08:55:58 -07001401 CreateInfoSymLink("device", "../../../device_dir/0/00");
1402 FilePath device_root(temp_dir_.path().Append("sys/device_dir/0"));
1403 FilePath device_path(device_root.Append("00"));
Ben Chan4eb4ddf2013-06-20 22:16:56 -07001404 FilePath driver_symlink(device_path.Append("driver"));
Ben Chana0ddf462014-02-06 11:32:42 -08001405 EXPECT_TRUE(base::CreateDirectory(device_path));
1406 EXPECT_TRUE(base::CreateSymbolicLink(FilePath("/drivers/cdc_ether"),
1407 driver_symlink));
1408 EXPECT_TRUE(base::CreateDirectory(device_root.Append("01/tty")));
Paul Stewartca876ee2012-04-21 08:55:58 -07001409 EXPECT_EQ(Technology::kCellular, GetDeviceTechnology());
Ben Chan4eb4ddf2013-06-20 22:16:56 -07001410
Ben Chana0ddf462014-02-06 11:32:42 -08001411 EXPECT_TRUE(base::DeleteFile(driver_symlink, false));
1412 EXPECT_TRUE(base::CreateSymbolicLink(FilePath("/drivers/cdc_ncm"),
1413 driver_symlink));
Ben Chan4eb4ddf2013-06-20 22:16:56 -07001414 EXPECT_EQ(Technology::kCellular, GetDeviceTechnology());
Paul Stewartca876ee2012-04-21 08:55:58 -07001415}
1416
1417// Modem with relative driver path with lower-level tty file.
1418// /sys/class/net/dev0/device -> ../../../device_dir/0/00
Ben Chan4eb4ddf2013-06-20 22:16:56 -07001419// /sys/device_dir/0/00/driver -> /drivers/cdc_ether or /drivers/cdc_ncm
Paul Stewartca876ee2012-04-21 08:55:58 -07001420// /sys/device_dir/0/01/yyy/tty [empty directory]
Ben Chan4eb4ddf2013-06-20 22:16:56 -07001421TEST_F(DeviceInfoTechnologyTest, CDCEthernetModem3) {
Paul Stewartca876ee2012-04-21 08:55:58 -07001422 CreateInfoSymLink("device", "../../../device_dir/0/00");
1423 FilePath device_root(temp_dir_.path().Append("sys/device_dir/0"));
1424 FilePath device_path(device_root.Append("00"));
Ben Chan4eb4ddf2013-06-20 22:16:56 -07001425 FilePath driver_symlink(device_path.Append("driver"));
Ben Chana0ddf462014-02-06 11:32:42 -08001426 EXPECT_TRUE(base::CreateDirectory(device_path));
1427 EXPECT_TRUE(base::CreateSymbolicLink(FilePath("/drivers/cdc_ether"),
1428 driver_symlink));
1429 EXPECT_TRUE(base::CreateDirectory(device_root.Append("01/yyy/tty")));
Paul Stewartca876ee2012-04-21 08:55:58 -07001430 EXPECT_EQ(Technology::kCellular, GetDeviceTechnology());
Ben Chan4eb4ddf2013-06-20 22:16:56 -07001431
Ben Chana0ddf462014-02-06 11:32:42 -08001432 EXPECT_TRUE(base::DeleteFile(driver_symlink, false));
1433 EXPECT_TRUE(base::CreateSymbolicLink(FilePath("/drivers/cdc_ncm"),
1434 driver_symlink));
Ben Chan4eb4ddf2013-06-20 22:16:56 -07001435 EXPECT_EQ(Technology::kCellular, GetDeviceTechnology());
Paul Stewartca876ee2012-04-21 08:55:58 -07001436}
1437
1438TEST_F(DeviceInfoTechnologyTest, CDCEtherNonModem) {
1439 CreateInfoSymLink("device", "device_dir");
1440 CreateInfoSymLink("device_dir/driver", "cdc_ether");
Paul Stewart050cfc02012-07-06 20:38:54 -07001441 EXPECT_EQ(Technology::kCDCEthernet, GetDeviceTechnology());
Paul Stewartca876ee2012-04-21 08:55:58 -07001442}
1443
Ben Chan4eb4ddf2013-06-20 22:16:56 -07001444TEST_F(DeviceInfoTechnologyTest, CDCNcmNonModem) {
1445 CreateInfoSymLink("device", "device_dir");
1446 CreateInfoSymLink("device_dir/driver", "cdc_ncm");
1447 EXPECT_EQ(Technology::kCDCEthernet, GetDeviceTechnology());
1448}
1449
Jason Glasgowabc54032012-04-20 16:08:32 -04001450TEST_F(DeviceInfoTechnologyTest, PseudoModem) {
1451 SetDeviceName("pseudomodem");
1452 CreateInfoSymLink("device", "device_dir");
1453 CreateInfoSymLink("device_dir/driver", "cdc_ether");
1454 EXPECT_EQ(Technology::kCellular, GetDeviceTechnology());
1455
1456 SetDeviceName("pseudomodem9");
1457 CreateInfoSymLink("device", "device_dir");
1458 CreateInfoSymLink("device_dir/driver", "cdc_ether");
1459 EXPECT_EQ(Technology::kCellular, GetDeviceTechnology());
1460}
1461
Paul Stewart050cfc02012-07-06 20:38:54 -07001462class DeviceInfoForDelayedCreationTest : public DeviceInfo {
1463 public:
1464 DeviceInfoForDelayedCreationTest(ControlInterface *control_interface,
1465 EventDispatcher *dispatcher,
1466 Metrics *metrics,
1467 Manager *manager)
1468 : DeviceInfo(control_interface, dispatcher, metrics, manager) {}
1469 MOCK_METHOD4(CreateDevice, DeviceRefPtr(const std::string &link_name,
1470 const std::string &address,
1471 int interface_index,
1472 Technology::Identifier technology));
1473 MOCK_METHOD1(GetDeviceTechnology,
1474 Technology::Identifier(const string &iface_name));
1475};
1476
1477class DeviceInfoDelayedCreationTest : public DeviceInfoTest {
1478 public:
1479 DeviceInfoDelayedCreationTest()
1480 : DeviceInfoTest(),
1481 test_device_info_(
1482 &control_interface_, &dispatcher_, &metrics_, &manager_) {}
1483 virtual ~DeviceInfoDelayedCreationTest() {}
1484
1485 virtual std::set<int> &GetDelayedDevices() {
1486 return test_device_info_.delayed_devices_;
1487 }
1488
1489 void DelayedDeviceCreationTask() {
1490 test_device_info_.DelayedDeviceCreationTask();
1491 }
1492
1493 void AddDelayedDevice() {
1494 scoped_ptr<RTNLMessage> message(BuildLinkMessage(RTNLMessage::kModeAdd));
1495 EXPECT_CALL(test_device_info_, GetDeviceTechnology(kTestDeviceName))
1496 .WillOnce(Return(Technology::kCDCEthernet));
1497 EXPECT_CALL(test_device_info_, CreateDevice(
1498 kTestDeviceName, _, kTestDeviceIndex, Technology::kCDCEthernet))
1499 .WillOnce(Return(DeviceRefPtr()));
1500 test_device_info_.AddLinkMsgHandler(*message);
1501 Mock::VerifyAndClearExpectations(&test_device_info_);
1502 // We need to insert the device index ourselves since we have mocked
1503 // out CreateDevice. This insertion is tested in CreateDeviceCDCEthernet
1504 // above.
1505 GetDelayedDevices().insert(kTestDeviceIndex);
1506 }
1507
Wade Guthrie7347bf22013-04-30 11:21:51 -07001508 void TriggerOnWiFiInterfaceInfoReceived(const Nl80211Message &message) {
Paul Stewart2ddf2c62013-04-16 09:47:34 -07001509 test_device_info_.OnWiFiInterfaceInfoReceived(message);
1510 }
1511
Paul Stewart050cfc02012-07-06 20:38:54 -07001512 protected:
1513 DeviceInfoForDelayedCreationTest test_device_info_;
1514};
1515
1516TEST_F(DeviceInfoDelayedCreationTest, NoDevices) {
1517 EXPECT_TRUE(GetDelayedDevices().empty());
1518 EXPECT_CALL(test_device_info_, GetDeviceTechnology(_)).Times(0);
1519 DelayedDeviceCreationTask();
1520}
1521
1522TEST_F(DeviceInfoDelayedCreationTest, EthernetDevice) {
1523 AddDelayedDevice();
1524 EXPECT_CALL(test_device_info_, GetDeviceTechnology(_))
1525 .WillOnce(Return(Technology::kCDCEthernet));
1526 EXPECT_CALL(test_device_info_, CreateDevice(
1527 kTestDeviceName, _, kTestDeviceIndex, Technology::kEthernet))
1528 .WillOnce(Return(DeviceRefPtr()));
1529 DelayedDeviceCreationTask();
1530 EXPECT_TRUE(GetDelayedDevices().empty());
1531}
1532
1533TEST_F(DeviceInfoDelayedCreationTest, CellularDevice) {
1534 AddDelayedDevice();
1535 EXPECT_CALL(test_device_info_, GetDeviceTechnology(_))
1536 .WillOnce(Return(Technology::kCellular));
1537 EXPECT_CALL(test_device_info_, CreateDevice(
1538 kTestDeviceName, _, kTestDeviceIndex, Technology::kCellular))
1539 .WillOnce(Return(DeviceRefPtr()));
1540 DelayedDeviceCreationTask();
1541 EXPECT_TRUE(GetDelayedDevices().empty());
1542}
1543
Paul Stewart2ddf2c62013-04-16 09:47:34 -07001544TEST_F(DeviceInfoDelayedCreationTest, WiFiDevice) {
1545 ScopedMockLog log;
Paul Stewart2ddf2c62013-04-16 09:47:34 -07001546 EXPECT_CALL(log, Log(logging::LOG_ERROR, _,
1547 HasSubstr("Message is not a new interface response")));
1548 GetInterfaceMessage non_interface_response_message;
1549 TriggerOnWiFiInterfaceInfoReceived(non_interface_response_message);
1550 Mock::VerifyAndClearExpectations(&log);
1551
1552 EXPECT_CALL(log, Log(logging::LOG_ERROR, _,
1553 HasSubstr("Message contains no interface index")));
1554 NewInterfaceMessage message;
1555 TriggerOnWiFiInterfaceInfoReceived(message);
1556 Mock::VerifyAndClearExpectations(&log);
1557
1558 message.attributes()->CreateAttribute(
1559 NL80211_ATTR_IFINDEX, base::Bind(
1560 &NetlinkAttribute::NewNl80211AttributeFromId));
1561 message.attributes()->SetU32AttributeValue(NL80211_ATTR_IFINDEX,
1562 kTestDeviceIndex);
1563 EXPECT_CALL(log, Log(logging::LOG_ERROR, _,
1564 HasSubstr("Message contains no interface type")));
1565 TriggerOnWiFiInterfaceInfoReceived(message);
1566 Mock::VerifyAndClearExpectations(&log);
1567
1568 message.attributes()->CreateAttribute(
1569 NL80211_ATTR_IFTYPE, base::Bind(
1570 &NetlinkAttribute::NewNl80211AttributeFromId));
1571 message.attributes()->SetU32AttributeValue(NL80211_ATTR_IFTYPE,
1572 NL80211_IFTYPE_AP);
1573 EXPECT_CALL(log, Log(logging::LOG_ERROR, _,
1574 HasSubstr("Could not find device info for interface")));
1575 TriggerOnWiFiInterfaceInfoReceived(message);
1576 Mock::VerifyAndClearExpectations(&log);
1577
1578 // Use the AddDelayedDevice() method to create a device info entry with no
1579 // associated device.
1580 AddDelayedDevice();
1581
1582 EXPECT_CALL(log, Log(logging::LOG_INFO, _,
1583 HasSubstr("it is not in station mode")));
1584 TriggerOnWiFiInterfaceInfoReceived(message);
1585 Mock::VerifyAndClearExpectations(&log);
1586 Mock::VerifyAndClearExpectations(&manager_);
1587
1588 message.attributes()->SetU32AttributeValue(NL80211_ATTR_IFTYPE,
1589 NL80211_IFTYPE_STATION);
1590 EXPECT_CALL(manager_, RegisterDevice(_));
1591 EXPECT_CALL(manager_, device_info())
1592 .WillRepeatedly(Return(&test_device_info_));
1593 EXPECT_CALL(log, Log(_, _, _)).Times(AnyNumber());
1594 EXPECT_CALL(log, Log(logging::LOG_INFO, _,
1595 HasSubstr("Creating WiFi device")));
1596 TriggerOnWiFiInterfaceInfoReceived(message);
1597 Mock::VerifyAndClearExpectations(&log);
1598 Mock::VerifyAndClearExpectations(&manager_);
1599
1600 EXPECT_CALL(manager_, RegisterDevice(_)).Times(0);
1601 EXPECT_CALL(log, Log(logging::LOG_ERROR, _,
1602 HasSubstr("Device already created for interface")));
1603 TriggerOnWiFiInterfaceInfoReceived(message);
1604}
1605
Chris Masone9be4a9d2011-05-16 15:44:09 -07001606} // namespace shill