blob: 7e9bcfa010cdc0fdeccfc2915e2d1d6abe37d308 [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>
Thieu Le8f1c8352012-04-16 11:02:12 -070017#include <base/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>
20#include <base/message_loop.h>
Eric Shienbrood3e20a232012-02-16 11:35:56 -050021#include <base/stl_util.h>
Paul Stewartca876ee2012-04-21 08:55:58 -070022#include <base/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"
Paul Stewart8c116a92012-05-02 18:30:03 -070040#include "shill/mock_vpn_provider.h"
Darin Petkove4b27022012-05-16 13:28:50 +020041#include "shill/mock_wimax_provider.h"
Paul Stewart2ddf2c62013-04-16 09:47:34 -070042#include "shill/netlink_attribute.h"
43#include "shill/nl80211_message.h"
Chris Masone2aa97072011-08-09 17:35:08 -070044#include "shill/rtnl_message.h"
Darin Petkovc63dcf02012-05-24 11:51:43 +020045#include "shill/wimax.h"
Chris Masone9be4a9d2011-05-16 15:44:09 -070046
Eric Shienbrood3e20a232012-02-16 11:35:56 -050047using base::Callback;
Albert Chaulk0e1cdea2013-02-27 15:32:55 -080048using base::FilePath;
Darin Petkove6193c02011-08-11 12:42:40 -070049using std::map;
Ben Chan5086b972013-01-15 21:51:38 -080050using std::set;
Darin Petkov633ac6f2011-07-08 13:56:13 -070051using std::string;
Paul Stewart9a908082011-08-31 12:18:48 -070052using std::vector;
Darin Petkov633ac6f2011-07-08 13:56:13 -070053using testing::_;
Paul Stewart2ddf2c62013-04-16 09:47:34 -070054using testing::AnyNumber;
Ben Chan5086b972013-01-15 21:51:38 -080055using testing::ContainerEq;
Gary Morain41780232012-07-31 15:08:31 -070056using testing::DoAll;
57using testing::ElementsAreArray;
Paul Stewart2ddf2c62013-04-16 09:47:34 -070058using testing::HasSubstr;
Paul Stewart8c116a92012-05-02 18:30:03 -070059using testing::Mock;
Gary Morain41780232012-07-31 15:08:31 -070060using testing::NotNull;
Darin Petkov633ac6f2011-07-08 13:56:13 -070061using testing::Return;
Paul Stewart9a908082011-08-31 12:18:48 -070062using testing::StrictMock;
Darin Petkov633ac6f2011-07-08 13:56:13 -070063using testing::Test;
64
Chris Masone9be4a9d2011-05-16 15:44:09 -070065namespace shill {
Darin Petkov633ac6f2011-07-08 13:56:13 -070066
Paul Stewart050cfc02012-07-06 20:38:54 -070067class TestEventDispatcherForDeviceInfo : public EventDispatcher {
Darin Petkov633ac6f2011-07-08 13:56:13 -070068 public:
Paul Stewart26b327e2011-10-19 11:38:09 -070069 virtual IOHandler *CreateInputHandler(
mukesh agrawal1830fa12011-09-26 14:31:40 -070070 int /*fd*/,
Paul Stewart5f06a0e2012-12-20 11:11:33 -080071 const IOHandler::InputCallback &/*input_callback*/,
72 const IOHandler::ErrorCallback &/*error_callback*/) {
Darin Petkov633ac6f2011-07-08 13:56:13 -070073 return NULL;
74 }
Paul Stewart050cfc02012-07-06 20:38:54 -070075 MOCK_METHOD2(PostDelayedTask, bool(const base::Closure &task,
76 int64 delay_ms));
Darin Petkov633ac6f2011-07-08 13:56:13 -070077};
Chris Masone9be4a9d2011-05-16 15:44:09 -070078
79class DeviceInfoTest : public Test {
80 public:
81 DeviceInfoTest()
Thieu Le6c1e3bb2013-02-06 15:20:35 -080082 : metrics_(&dispatcher_),
83 manager_(&control_interface_, &dispatcher_, &metrics_, &glib_),
Thieu Le3426c8f2012-01-11 17:35:11 -080084 device_info_(&control_interface_, &dispatcher_, &metrics_, &manager_) {
Chris Masone9be4a9d2011-05-16 15:44:09 -070085 }
Paul Stewartca876ee2012-04-21 08:55:58 -070086 virtual ~DeviceInfoTest() {}
Darin Petkov633ac6f2011-07-08 13:56:13 -070087
Paul Stewart9a908082011-08-31 12:18:48 -070088 virtual void SetUp() {
89 device_info_.rtnl_handler_ = &rtnl_handler_;
Paul Stewart8c116a92012-05-02 18:30:03 -070090 device_info_.routing_table_ = &routing_table_;
Paul Stewart2ddf2c62013-04-16 09:47:34 -070091 device_info_.netlink_manager_ = &netlink_manager_;
Paul Stewart9a908082011-08-31 12:18:48 -070092 }
93
Paul Stewart8c116a92012-05-02 18:30:03 -070094 IPAddress CreateInterfaceAddress() {
95 // Create an IP address entry (as if left-over from a previous connection
96 // manager).
97 IPAddress address(IPAddress::kFamilyIPv4);
98 EXPECT_TRUE(address.SetAddressFromString(kTestIPAddress0));
99 address.set_prefix(kTestIPAddressPrefix0);
100 vector<DeviceInfo::AddressData> &addresses =
101 device_info_.infos_[kTestDeviceIndex].ip_addresses;
102 addresses.push_back(DeviceInfo::AddressData(address, 0, RT_SCOPE_UNIVERSE));
103 EXPECT_EQ(1, addresses.size());
104 return address;
105 }
106
107 DeviceRefPtr CreateDevice(const std::string &link_name,
108 const std::string &address,
109 int interface_index,
110 Technology::Identifier technology) {
111 return device_info_.CreateDevice(link_name, address, interface_index,
112 technology);
113 }
114
Paul Stewart050cfc02012-07-06 20:38:54 -0700115 virtual std::set<int> &GetDelayedDevices() {
116 return device_info_.delayed_devices_;
117 }
118
Paul Stewart1ac4e842012-07-10 12:58:12 -0700119 int GetDelayedDeviceCreationMilliseconds() {
Paul Stewart050cfc02012-07-06 20:38:54 -0700120 return DeviceInfo::kDelayedDeviceCreationSeconds * 1000;
121 }
Paul Stewart8c116a92012-05-02 18:30:03 -0700122
Gary Morain41780232012-07-31 15:08:31 -0700123 void SetSockets() {
124 mock_sockets_ = new MockSockets();
125 device_info_.set_sockets(mock_sockets_);
126 }
127
Darin Petkovc3505a52013-03-18 15:13:29 +0100128 // Takes ownership of |provider|.
129 void SetVPNProvider(VPNProvider *provider) {
130 manager_.vpn_provider_.reset(provider);
131 }
132
Paul Stewarta3c56f92011-05-26 07:08:52 -0700133 protected:
Chris Masoneb2e326b2011-07-12 13:28:51 -0700134 static const int kTestDeviceIndex;
Darin Petkov633ac6f2011-07-08 13:56:13 -0700135 static const char kTestDeviceName[];
Han Shenfc349252012-08-30 11:36:04 -0700136 static const uint8_t kTestMACAddress[];
Paul Stewart9a908082011-08-31 12:18:48 -0700137 static const char kTestIPAddress0[];
138 static const int kTestIPAddressPrefix0;
139 static const char kTestIPAddress1[];
140 static const int kTestIPAddressPrefix1;
141 static const char kTestIPAddress2[];
142 static const char kTestIPAddress3[];
143 static const char kTestIPAddress4[];
Paul Stewart05a42c22012-08-02 16:47:21 -0700144 static const char kTestIPAddress5[];
Paul Stewart1ac4e842012-07-10 12:58:12 -0700145 static const int kReceiveByteCount;
146 static const int kTransmitByteCount;
Darin Petkov633ac6f2011-07-08 13:56:13 -0700147
Paul Stewart9a908082011-08-31 12:18:48 -0700148 RTNLMessage *BuildLinkMessage(RTNLMessage::Mode mode);
Paul Stewarte81eb702012-04-11 15:04:53 -0700149 RTNLMessage *BuildLinkMessageWithInterfaceName(RTNLMessage::Mode mode,
150 const string &interface_name);
Paul Stewart9a908082011-08-31 12:18:48 -0700151 RTNLMessage *BuildAddressMessage(RTNLMessage::Mode mode,
152 const IPAddress &address,
153 unsigned char flags,
154 unsigned char scope);
Chris Masone2aa97072011-08-09 17:35:08 -0700155 void SendMessageToDeviceInfo(const RTNLMessage &message);
Darin Petkov633ac6f2011-07-08 13:56:13 -0700156
Darin Petkovafa6fc42011-06-21 16:21:08 -0700157 MockGLib glib_;
Chris Masone46eaaf52011-05-24 13:08:30 -0700158 MockControl control_interface_;
Thieu Le3426c8f2012-01-11 17:35:11 -0800159 MockMetrics metrics_;
Paul Stewart9a908082011-08-31 12:18:48 -0700160 StrictMock<MockManager> manager_;
Chris Masone9be4a9d2011-05-16 15:44:09 -0700161 DeviceInfo device_info_;
Paul Stewart050cfc02012-07-06 20:38:54 -0700162 TestEventDispatcherForDeviceInfo dispatcher_;
Paul Stewart8c116a92012-05-02 18:30:03 -0700163 MockRoutingTable routing_table_;
Paul Stewart2ddf2c62013-04-16 09:47:34 -0700164 MockNetlinkManager netlink_manager_;
Paul Stewart9a908082011-08-31 12:18:48 -0700165 StrictMock<MockRTNLHandler> rtnl_handler_;
Gary Morain41780232012-07-31 15:08:31 -0700166 MockSockets *mock_sockets_; // Owned by DeviceInfo.
Chris Masone9be4a9d2011-05-16 15:44:09 -0700167};
168
Chris Masoneb2e326b2011-07-12 13:28:51 -0700169const int DeviceInfoTest::kTestDeviceIndex = 123456;
Darin Petkov633ac6f2011-07-08 13:56:13 -0700170const char DeviceInfoTest::kTestDeviceName[] = "test-device";
Han Shenfc349252012-08-30 11:36:04 -0700171const uint8_t DeviceInfoTest::kTestMACAddress[] = {
Wade Guthrie7347bf22013-04-30 11:21:51 -0700172 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff };
Paul Stewart9a908082011-08-31 12:18:48 -0700173const char DeviceInfoTest::kTestIPAddress0[] = "192.168.1.1";
174const int DeviceInfoTest::kTestIPAddressPrefix0 = 24;
175const char DeviceInfoTest::kTestIPAddress1[] = "fe80::1aa9:5ff:abcd:1234";
176const int DeviceInfoTest::kTestIPAddressPrefix1 = 64;
177const char DeviceInfoTest::kTestIPAddress2[] = "fe80::1aa9:5ff:abcd:1235";
178const char DeviceInfoTest::kTestIPAddress3[] = "fe80::1aa9:5ff:abcd:1236";
179const char DeviceInfoTest::kTestIPAddress4[] = "fe80::1aa9:5ff:abcd:1237";
Paul Stewart05a42c22012-08-02 16:47:21 -0700180const char DeviceInfoTest::kTestIPAddress5[] = "192.168.1.2";
Paul Stewart1ac4e842012-07-10 12:58:12 -0700181const int DeviceInfoTest::kReceiveByteCount = 1234;
182const int DeviceInfoTest::kTransmitByteCount = 5678;
Chris Masone9be4a9d2011-05-16 15:44:09 -0700183
Paul Stewarte81eb702012-04-11 15:04:53 -0700184RTNLMessage *DeviceInfoTest::BuildLinkMessageWithInterfaceName(
185 RTNLMessage::Mode mode, const string &interface_name) {
Paul Stewart9a908082011-08-31 12:18:48 -0700186 RTNLMessage *message = new RTNLMessage(
187 RTNLMessage::kTypeLink,
188 mode,
189 0,
190 0,
191 0,
192 kTestDeviceIndex,
Paul Stewart7355ce12011-09-02 10:47:01 -0700193 IPAddress::kFamilyIPv4);
Chris Masone2aa97072011-08-09 17:35:08 -0700194 message->SetAttribute(static_cast<uint16>(IFLA_IFNAME),
Paul Stewarte81eb702012-04-11 15:04:53 -0700195 ByteString(interface_name, true));
Paul Stewart9a908082011-08-31 12:18:48 -0700196 ByteString test_address(kTestMACAddress, sizeof(kTestMACAddress));
Chris Masone626719f2011-08-18 16:58:48 -0700197 message->SetAttribute(IFLA_ADDRESS, test_address);
Chris Masone2aa97072011-08-09 17:35:08 -0700198 return message;
Darin Petkov633ac6f2011-07-08 13:56:13 -0700199}
200
Paul Stewarte81eb702012-04-11 15:04:53 -0700201RTNLMessage *DeviceInfoTest::BuildLinkMessage(RTNLMessage::Mode mode) {
202 return BuildLinkMessageWithInterfaceName(mode, kTestDeviceName);
203}
204
Paul Stewart9a908082011-08-31 12:18:48 -0700205RTNLMessage *DeviceInfoTest::BuildAddressMessage(RTNLMessage::Mode mode,
206 const IPAddress &address,
207 unsigned char flags,
208 unsigned char scope) {
209 RTNLMessage *message = new RTNLMessage(
210 RTNLMessage::kTypeAddress,
211 mode,
212 0,
213 0,
214 0,
215 kTestDeviceIndex,
216 address.family());
217 message->SetAttribute(IFA_ADDRESS, address.address());
218 message->set_address_status(
219 RTNLMessage::AddressStatus(address.prefix(), flags, scope));
220 return message;
221}
222
Chris Masone2aa97072011-08-09 17:35:08 -0700223void DeviceInfoTest::SendMessageToDeviceInfo(const RTNLMessage &message) {
Paul Stewart9a908082011-08-31 12:18:48 -0700224 if (message.type() == RTNLMessage::kTypeLink) {
225 device_info_.LinkMsgHandler(message);
226 } else if (message.type() == RTNLMessage::kTypeAddress) {
227 device_info_.AddressMsgHandler(message);
228 } else {
229 NOTREACHED();
230 }
231}
232
233MATCHER_P(IsIPAddress, address, "") {
234 // NB: IPAddress objects don't support the "==" operator as per style, so
235 // we need a custom matcher.
236 return address.Equals(arg);
Darin Petkov633ac6f2011-07-08 13:56:13 -0700237}
238
Paul Stewart8c116a92012-05-02 18:30:03 -0700239TEST_F(DeviceInfoTest, StartStop) {
240 EXPECT_FALSE(device_info_.link_listener_.get());
241 EXPECT_FALSE(device_info_.address_listener_.get());
242 EXPECT_TRUE(device_info_.infos_.empty());
243
244 EXPECT_CALL(rtnl_handler_, RequestDump(RTNLHandler::kRequestLink |
245 RTNLHandler::kRequestAddr));
Paul Stewart1ac4e842012-07-10 12:58:12 -0700246 EXPECT_CALL(dispatcher_, PostDelayedTask(
Ben Chanb061f892013-02-27 17:46:55 -0800247 _, DeviceInfo::kRequestLinkStatisticsIntervalMilliseconds));
Chris Masone9be4a9d2011-05-16 15:44:09 -0700248 device_info_.Start();
Paul Stewart8c116a92012-05-02 18:30:03 -0700249 EXPECT_TRUE(device_info_.link_listener_.get());
250 EXPECT_TRUE(device_info_.address_listener_.get());
251 EXPECT_TRUE(device_info_.infos_.empty());
252 Mock::VerifyAndClearExpectations(&rtnl_handler_);
253
254 CreateInterfaceAddress();
255 EXPECT_FALSE(device_info_.infos_.empty());
256
257 device_info_.Stop();
258 EXPECT_FALSE(device_info_.link_listener_.get());
259 EXPECT_FALSE(device_info_.address_listener_.get());
260 EXPECT_TRUE(device_info_.infos_.empty());
261}
262
Paul Stewart1ac4e842012-07-10 12:58:12 -0700263TEST_F(DeviceInfoTest, RequestLinkStatistics) {
264 EXPECT_CALL(rtnl_handler_, RequestDump(RTNLHandler::kRequestLink));
265 EXPECT_CALL(dispatcher_, PostDelayedTask(
Ben Chanb061f892013-02-27 17:46:55 -0800266 _, DeviceInfo::kRequestLinkStatisticsIntervalMilliseconds));
Paul Stewart1ac4e842012-07-10 12:58:12 -0700267 device_info_.RequestLinkStatistics();
268}
269
Paul Stewart8c116a92012-05-02 18:30:03 -0700270TEST_F(DeviceInfoTest, DeviceEnumeration) {
Paul Stewart9a908082011-08-31 12:18:48 -0700271 scoped_ptr<RTNLMessage> message(BuildLinkMessage(RTNLMessage::kModeAdd));
Darin Petkove6193c02011-08-11 12:42:40 -0700272 message->set_link_status(RTNLMessage::LinkStatus(0, IFF_LOWER_UP, 0));
273 EXPECT_FALSE(device_info_.GetDevice(kTestDeviceIndex).get());
Darin Petkovf8046b82012-04-24 16:29:23 +0200274 EXPECT_EQ(-1, device_info_.GetIndex(kTestDeviceName));
Darin Petkove6193c02011-08-11 12:42:40 -0700275 SendMessageToDeviceInfo(*message);
276 EXPECT_TRUE(device_info_.GetDevice(kTestDeviceIndex).get());
277 unsigned int flags = 0;
278 EXPECT_TRUE(device_info_.GetFlags(kTestDeviceIndex, &flags));
279 EXPECT_EQ(IFF_LOWER_UP, flags);
Darin Petkove3e1cfa2011-08-11 13:41:17 -0700280 ByteString address;
Paul Stewart32852962011-08-30 14:06:53 -0700281 EXPECT_TRUE(device_info_.GetMACAddress(kTestDeviceIndex, &address));
Darin Petkove3e1cfa2011-08-11 13:41:17 -0700282 EXPECT_FALSE(address.IsEmpty());
Paul Stewart9a908082011-08-31 12:18:48 -0700283 EXPECT_TRUE(address.Equals(ByteString(kTestMACAddress,
284 sizeof(kTestMACAddress))));
Darin Petkovf8046b82012-04-24 16:29:23 +0200285 EXPECT_EQ(kTestDeviceIndex, device_info_.GetIndex(kTestDeviceName));
Paul Stewarta3c56f92011-05-26 07:08:52 -0700286
Paul Stewart9a908082011-08-31 12:18:48 -0700287 message.reset(BuildLinkMessage(RTNLMessage::kModeAdd));
Darin Petkove6193c02011-08-11 12:42:40 -0700288 message->set_link_status(RTNLMessage::LinkStatus(0, IFF_UP | IFF_RUNNING, 0));
289 SendMessageToDeviceInfo(*message);
290 EXPECT_TRUE(device_info_.GetFlags(kTestDeviceIndex, &flags));
291 EXPECT_EQ(IFF_UP | IFF_RUNNING, flags);
Paul Stewartb50f0b92011-05-16 16:31:42 -0700292
Paul Stewart9a908082011-08-31 12:18:48 -0700293 message.reset(BuildLinkMessage(RTNLMessage::kModeDelete));
Paul Stewart8c116a92012-05-02 18:30:03 -0700294 EXPECT_CALL(manager_, DeregisterDevice(_)).Times(1);
Darin Petkove6193c02011-08-11 12:42:40 -0700295 SendMessageToDeviceInfo(*message);
296 EXPECT_FALSE(device_info_.GetDevice(kTestDeviceIndex).get());
297 EXPECT_FALSE(device_info_.GetFlags(kTestDeviceIndex, NULL));
Darin Petkovf8046b82012-04-24 16:29:23 +0200298 EXPECT_EQ(-1, device_info_.GetIndex(kTestDeviceName));
Paul Stewart8c116a92012-05-02 18:30:03 -0700299}
Paul Stewarta3c56f92011-05-26 07:08:52 -0700300
Ben Chan5086b972013-01-15 21:51:38 -0800301TEST_F(DeviceInfoTest, GetUninitializedTechnologies) {
302 vector<string> technologies = device_info_.GetUninitializedTechnologies();
303 set<string> expected_technologies;
304
305 EXPECT_THAT(set<string>(technologies.begin(), technologies.end()),
306 ContainerEq(expected_technologies));
307
308 device_info_.infos_[0].technology = Technology::kUnknown;
309 EXPECT_THAT(set<string>(technologies.begin(), technologies.end()),
310 ContainerEq(expected_technologies));
311
312 device_info_.infos_[1].technology = Technology::kCellular;
313 technologies = device_info_.GetUninitializedTechnologies();
314 expected_technologies.insert(Technology::NameFromIdentifier(
315 Technology::kCellular));
316 EXPECT_THAT(set<string>(technologies.begin(), technologies.end()),
317 ContainerEq(expected_technologies));
318
319 device_info_.infos_[2].technology = Technology::kWiMax;
320 technologies = device_info_.GetUninitializedTechnologies();
321 expected_technologies.insert(Technology::NameFromIdentifier(
322 Technology::kWiMax));
323 EXPECT_THAT(set<string>(technologies.begin(), technologies.end()),
324 ContainerEq(expected_technologies));
325
326 scoped_refptr<MockDevice> device(new MockDevice(
327 &control_interface_, &dispatcher_, &metrics_, &manager_,
328 "null0", "addr0", 1));
329 device_info_.infos_[1].device = device;
330 technologies = device_info_.GetUninitializedTechnologies();
331 expected_technologies.erase(Technology::NameFromIdentifier(
332 Technology::kCellular));
333 EXPECT_THAT(set<string>(technologies.begin(), technologies.end()),
334 ContainerEq(expected_technologies));
335
336 device_info_.infos_[3].technology = Technology::kCellular;
337 technologies = device_info_.GetUninitializedTechnologies();
338 expected_technologies.insert(Technology::NameFromIdentifier(
339 Technology::kCellular));
340 EXPECT_THAT(set<string>(technologies.begin(), technologies.end()),
341 ContainerEq(expected_technologies));
342}
343
Paul Stewart1ac4e842012-07-10 12:58:12 -0700344TEST_F(DeviceInfoTest, GetByteCounts) {
345 uint64 rx_bytes, tx_bytes;
346 EXPECT_FALSE(device_info_.GetByteCounts(
347 kTestDeviceIndex, &rx_bytes, &tx_bytes));
348
349 // No link statistics in the message.
350 scoped_ptr<RTNLMessage> message(BuildLinkMessage(RTNLMessage::kModeAdd));
351 SendMessageToDeviceInfo(*message);
352 EXPECT_TRUE(device_info_.GetByteCounts(
353 kTestDeviceIndex, &rx_bytes, &tx_bytes));
354 EXPECT_EQ(0, rx_bytes);
355 EXPECT_EQ(0, tx_bytes);
356
357 // Short link statistics message.
358 message.reset(BuildLinkMessage(RTNLMessage::kModeAdd));
359 struct rtnl_link_stats64 stats;
360 memset(&stats, 0, sizeof(stats));
361 stats.rx_bytes = kReceiveByteCount;
362 stats.tx_bytes = kTransmitByteCount;
363 ByteString stats_bytes0(reinterpret_cast<const unsigned char*>(&stats),
364 sizeof(stats) - 1);
365 message->SetAttribute(IFLA_STATS64, stats_bytes0);
366 SendMessageToDeviceInfo(*message);
367 EXPECT_TRUE(device_info_.GetByteCounts(
368 kTestDeviceIndex, &rx_bytes, &tx_bytes));
369 EXPECT_EQ(0, rx_bytes);
370 EXPECT_EQ(0, tx_bytes);
371
372 // Correctly sized link statistics message.
373 message.reset(BuildLinkMessage(RTNLMessage::kModeAdd));
374 ByteString stats_bytes1(reinterpret_cast<const unsigned char*>(&stats),
375 sizeof(stats));
376 message->SetAttribute(IFLA_STATS64, stats_bytes1);
377 SendMessageToDeviceInfo(*message);
378 EXPECT_TRUE(device_info_.GetByteCounts(
379 kTestDeviceIndex, &rx_bytes, &tx_bytes));
380 EXPECT_EQ(kReceiveByteCount, rx_bytes);
381 EXPECT_EQ(kTransmitByteCount, tx_bytes);
382}
383
Paul Stewart8c116a92012-05-02 18:30:03 -0700384TEST_F(DeviceInfoTest, CreateDeviceCellular) {
385 IPAddress address = CreateInterfaceAddress();
386
387 // A cellular device should be offered to ModemInfo.
388 StrictMock<MockModemInfo> modem_info;
389 EXPECT_CALL(manager_, modem_info()).WillOnce(Return(&modem_info));
390 EXPECT_CALL(modem_info, OnDeviceInfoAvailable(kTestDeviceName)).Times(1);
391 EXPECT_CALL(routing_table_, FlushRoutes(kTestDeviceIndex)).Times(1);
392 EXPECT_CALL(rtnl_handler_, RemoveInterfaceAddress(kTestDeviceIndex,
393 IsIPAddress(address)));
394 EXPECT_FALSE(CreateDevice(
395 kTestDeviceName, "address", kTestDeviceIndex, Technology::kCellular));
396}
397
Darin Petkove4b27022012-05-16 13:28:50 +0200398TEST_F(DeviceInfoTest, CreateDeviceWiMax) {
399 IPAddress address = CreateInterfaceAddress();
400
401 // A WiMax device should be offered to WiMaxProvider.
402 StrictMock<MockWiMaxProvider> wimax_provider;
403 EXPECT_CALL(manager_, wimax_provider()).WillOnce(Return(&wimax_provider));
404 EXPECT_CALL(wimax_provider, OnDeviceInfoAvailable(kTestDeviceName)).Times(1);
405 EXPECT_CALL(routing_table_, FlushRoutes(kTestDeviceIndex)).Times(1);
406 EXPECT_CALL(rtnl_handler_, RemoveInterfaceAddress(kTestDeviceIndex,
407 IsIPAddress(address)));
Ben Chan4b285862012-10-10 22:52:16 -0700408 device_info_.infos_[kTestDeviceIndex].mac_address =
409 ByteString(kTestMACAddress, sizeof(kTestMACAddress));
Darin Petkove4b27022012-05-16 13:28:50 +0200410 EXPECT_FALSE(CreateDevice(
411 kTestDeviceName, "address", kTestDeviceIndex, Technology::kWiMax));
Ben Chan4b285862012-10-10 22:52:16 -0700412 // The MAC address is clear such that it is obtained via
413 // GetMACAddressFromKernel() instead.
414 EXPECT_TRUE(device_info_.infos_[kTestDeviceIndex].mac_address.IsEmpty());
Darin Petkove4b27022012-05-16 13:28:50 +0200415}
416
Paul Stewart8c116a92012-05-02 18:30:03 -0700417TEST_F(DeviceInfoTest, CreateDeviceEthernet) {
418 IPAddress address = CreateInterfaceAddress();
419
420 // An Ethernet device should cause routes and addresses to be flushed.
421 EXPECT_CALL(routing_table_, FlushRoutes(kTestDeviceIndex)).Times(1);
422 EXPECT_CALL(rtnl_handler_, RemoveInterfaceAddress(kTestDeviceIndex,
423 IsIPAddress(address)));
424 DeviceRefPtr device = CreateDevice(
425 kTestDeviceName, "address", kTestDeviceIndex, Technology::kEthernet);
426 EXPECT_TRUE(device);
427 Mock::VerifyAndClearExpectations(&routing_table_);
428 Mock::VerifyAndClearExpectations(&rtnl_handler_);
429
430 // The Ethernet device destructor notifies the manager.
431 EXPECT_CALL(manager_, UpdateEnabledTechnologies()).Times(1);
432 device = NULL;
433}
434
435TEST_F(DeviceInfoTest, CreateDeviceVirtioEthernet) {
436 IPAddress address = CreateInterfaceAddress();
437
438 // VirtioEthernet is identical to Ethernet from the perspective of this test.
439 EXPECT_CALL(routing_table_, FlushRoutes(kTestDeviceIndex)).Times(1);
440 EXPECT_CALL(rtnl_handler_, RemoveInterfaceAddress(kTestDeviceIndex,
441 IsIPAddress(address)));
442 DeviceRefPtr device = CreateDevice(
443 kTestDeviceName, "address", kTestDeviceIndex,
444 Technology::kVirtioEthernet);
445 EXPECT_TRUE(device);
446 Mock::VerifyAndClearExpectations(&routing_table_);
447 Mock::VerifyAndClearExpectations(&rtnl_handler_);
448
449 // The Ethernet device destructor notifies the manager.
450 EXPECT_CALL(manager_, UpdateEnabledTechnologies()).Times(1);
451 device = NULL;
452}
453
Paul Stewart2ddf2c62013-04-16 09:47:34 -0700454MATCHER_P(IsGetInterfaceMessage, index, "") {
455 if (arg->message_type() != Nl80211Message::GetMessageType()) {
456 return false;
457 }
458 const Nl80211Message *msg = reinterpret_cast<const Nl80211Message *>(arg);
459 if (msg->command() != NL80211_CMD_GET_INTERFACE) {
460 return false;
461 }
462 uint32_t interface_index;
463 if (!msg->const_attributes()->GetU32AttributeValue(NL80211_ATTR_IFINDEX,
464 &interface_index)) {
465 return false;
466 }
467 // kInterfaceIndex is signed, but the attribute as handed from the kernel
468 // is unsigned. We're silently casting it away with this assignment.
469 uint32_t test_interface_index = index;
470 return interface_index == test_interface_index;
471}
472
Paul Stewart8c116a92012-05-02 18:30:03 -0700473TEST_F(DeviceInfoTest, CreateDeviceWiFi) {
474 IPAddress address = CreateInterfaceAddress();
475
476 // WiFi looks a lot like Ethernet too.
Paul Stewart2ddf2c62013-04-16 09:47:34 -0700477 EXPECT_CALL(routing_table_, FlushRoutes(kTestDeviceIndex));
Paul Stewart8c116a92012-05-02 18:30:03 -0700478 EXPECT_CALL(rtnl_handler_, RemoveInterfaceAddress(kTestDeviceIndex,
479 IsIPAddress(address)));
Paul Stewart2ddf2c62013-04-16 09:47:34 -0700480
481 // Set the nl80211 message type to some non-default value.
482 Nl80211Message::SetMessageType(1234);
483
Wade Guthrie7347bf22013-04-30 11:21:51 -0700484 EXPECT_CALL(
485 netlink_manager_,
486 SendNl80211Message(IsGetInterfaceMessage(kTestDeviceIndex), _, _));
Paul Stewart2ddf2c62013-04-16 09:47:34 -0700487 EXPECT_FALSE(CreateDevice(
Paul Stewart8c116a92012-05-02 18:30:03 -0700488 kTestDeviceName, "address", kTestDeviceIndex, Technology::kWifi));
489}
490
491TEST_F(DeviceInfoTest, CreateDeviceTunnelAccepted) {
492 IPAddress address = CreateInterfaceAddress();
493
494 // A VPN device should be offered to VPNProvider.
Darin Petkovc3505a52013-03-18 15:13:29 +0100495 MockVPNProvider *vpn_provider = new StrictMock<MockVPNProvider>;
496 SetVPNProvider(vpn_provider);
497 EXPECT_CALL(*vpn_provider,
Paul Stewart8c116a92012-05-02 18:30:03 -0700498 OnDeviceInfoAvailable(kTestDeviceName, kTestDeviceIndex))
499 .WillOnce(Return(true));
500 EXPECT_CALL(routing_table_, FlushRoutes(kTestDeviceIndex)).Times(1);
501 EXPECT_CALL(rtnl_handler_, RemoveInterfaceAddress(kTestDeviceIndex,
502 IsIPAddress(address)));
503 EXPECT_CALL(rtnl_handler_, RemoveInterface(_)).Times(0);
504 EXPECT_FALSE(CreateDevice(
505 kTestDeviceName, "address", kTestDeviceIndex, Technology::kTunnel));
506}
507
508TEST_F(DeviceInfoTest, CreateDeviceTunnelRejected) {
509 IPAddress address = CreateInterfaceAddress();
510
511 // A VPN device should be offered to VPNProvider.
Darin Petkovc3505a52013-03-18 15:13:29 +0100512 MockVPNProvider *vpn_provider = new StrictMock<MockVPNProvider>;
513 SetVPNProvider(vpn_provider);
514 EXPECT_CALL(*vpn_provider,
Paul Stewart8c116a92012-05-02 18:30:03 -0700515 OnDeviceInfoAvailable(kTestDeviceName, kTestDeviceIndex))
516 .WillOnce(Return(false));
517 EXPECT_CALL(routing_table_, FlushRoutes(kTestDeviceIndex)).Times(1);
518 EXPECT_CALL(rtnl_handler_, RemoveInterfaceAddress(kTestDeviceIndex,
519 IsIPAddress(address)));
520 // Since the device was rejected by the VPNProvider, DeviceInfo will
521 // remove the interface.
522 EXPECT_CALL(rtnl_handler_, RemoveInterface(kTestDeviceIndex)).Times(1);
523 EXPECT_FALSE(CreateDevice(
524 kTestDeviceName, "address", kTestDeviceIndex, Technology::kTunnel));
525}
526
527TEST_F(DeviceInfoTest, CreateDevicePPP) {
528 IPAddress address = CreateInterfaceAddress();
529
530 // A VPN device should be offered to VPNProvider.
Darin Petkovc3505a52013-03-18 15:13:29 +0100531 MockVPNProvider *vpn_provider = new StrictMock<MockVPNProvider>;
532 SetVPNProvider(vpn_provider);
533 EXPECT_CALL(*vpn_provider,
Paul Stewart8c116a92012-05-02 18:30:03 -0700534 OnDeviceInfoAvailable(kTestDeviceName, kTestDeviceIndex))
535 .WillOnce(Return(false));
536 EXPECT_CALL(routing_table_, FlushRoutes(kTestDeviceIndex)).Times(1);
537 EXPECT_CALL(rtnl_handler_, RemoveInterfaceAddress(kTestDeviceIndex,
538 IsIPAddress(address)));
539 // We do not remove PPP interfaces even if the provider does not accept it.
540 EXPECT_CALL(rtnl_handler_, RemoveInterface(_)).Times(0);
541 EXPECT_FALSE(CreateDevice(
542 kTestDeviceName, "address", kTestDeviceIndex, Technology::kPPP));
543}
544
545TEST_F(DeviceInfoTest, CreateDeviceLoopback) {
546 // A loopback device should be brought up, and nothing else done to it.
547 EXPECT_CALL(routing_table_, FlushRoutes(_)).Times(0);
548 EXPECT_CALL(rtnl_handler_, RemoveInterfaceAddress(_, _)).Times(0);
549 EXPECT_CALL(rtnl_handler_,
550 SetInterfaceFlags(kTestDeviceIndex, IFF_UP, IFF_UP)).Times(1);
551 EXPECT_FALSE(CreateDevice(
552 kTestDeviceName, "address", kTestDeviceIndex, Technology::kLoopback));
553}
554
Paul Stewart050cfc02012-07-06 20:38:54 -0700555TEST_F(DeviceInfoTest, CreateDeviceCDCEthernet) {
Ben Chan4eb4ddf2013-06-20 22:16:56 -0700556 // A cdc_ether / cdc_ncm device should be postponed to a task.
Paul Stewart050cfc02012-07-06 20:38:54 -0700557 EXPECT_CALL(manager_, modem_info()).Times(0);
558 EXPECT_CALL(routing_table_, FlushRoutes(_)).Times(0);
559 EXPECT_CALL(rtnl_handler_, RemoveInterfaceAddress(_, _)).Times(0);
560 EXPECT_CALL(dispatcher_,
Paul Stewart1ac4e842012-07-10 12:58:12 -0700561 PostDelayedTask(_, GetDelayedDeviceCreationMilliseconds()));
Paul Stewart050cfc02012-07-06 20:38:54 -0700562 EXPECT_TRUE(GetDelayedDevices().empty());
563 EXPECT_FALSE(CreateDevice(
564 kTestDeviceName, "address", kTestDeviceIndex, Technology::kCDCEthernet));
565 EXPECT_FALSE(GetDelayedDevices().empty());
566 EXPECT_EQ(1, GetDelayedDevices().size());
567 EXPECT_EQ(kTestDeviceIndex, *GetDelayedDevices().begin());
568}
569
Paul Stewart8c116a92012-05-02 18:30:03 -0700570TEST_F(DeviceInfoTest, CreateDeviceUnknown) {
571 IPAddress address = CreateInterfaceAddress();
572
573 // An unknown (blacklisted, unhandled, etc) device won't be flushed or
574 // registered.
575 EXPECT_CALL(routing_table_, FlushRoutes(_)).Times(0);
576 EXPECT_CALL(rtnl_handler_, RemoveInterfaceAddress(_, _)).Times(0);
577 EXPECT_TRUE(CreateDevice(
578 kTestDeviceName, "address", kTestDeviceIndex, Technology::kUnknown));
Chris Masone9be4a9d2011-05-16 15:44:09 -0700579}
580
mukesh agrawal8f317b62011-07-15 11:53:23 -0700581TEST_F(DeviceInfoTest, DeviceBlackList) {
582 device_info_.AddDeviceToBlackList(kTestDeviceName);
Paul Stewart9a908082011-08-31 12:18:48 -0700583 scoped_ptr<RTNLMessage> message(BuildLinkMessage(RTNLMessage::kModeAdd));
Darin Petkove6193c02011-08-11 12:42:40 -0700584 SendMessageToDeviceInfo(*message);
mukesh agrawal8f317b62011-07-15 11:53:23 -0700585
Darin Petkove6193c02011-08-11 12:42:40 -0700586 DeviceRefPtr device = device_info_.GetDevice(kTestDeviceIndex);
587 ASSERT_TRUE(device.get());
Joshua Krollda798622012-06-05 12:30:48 -0700588 EXPECT_TRUE(device->technology() == Technology::kBlacklisted);
mukesh agrawal8f317b62011-07-15 11:53:23 -0700589}
590
Paul Stewart9a908082011-08-31 12:18:48 -0700591TEST_F(DeviceInfoTest, DeviceAddressList) {
Paul Stewart9a908082011-08-31 12:18:48 -0700592 scoped_ptr<RTNLMessage> message(BuildLinkMessage(RTNLMessage::kModeAdd));
593 SendMessageToDeviceInfo(*message);
594
595 vector<DeviceInfo::AddressData> addresses;
596 EXPECT_TRUE(device_info_.GetAddresses(kTestDeviceIndex, &addresses));
597 EXPECT_TRUE(addresses.empty());
598
599 // Add an address to the device address list
Paul Stewart7355ce12011-09-02 10:47:01 -0700600 IPAddress ip_address0(IPAddress::kFamilyIPv4);
Paul Stewart9a908082011-08-31 12:18:48 -0700601 EXPECT_TRUE(ip_address0.SetAddressFromString(kTestIPAddress0));
602 ip_address0.set_prefix(kTestIPAddressPrefix0);
603 message.reset(BuildAddressMessage(RTNLMessage::kModeAdd, ip_address0, 0, 0));
604 SendMessageToDeviceInfo(*message);
605 EXPECT_TRUE(device_info_.GetAddresses(kTestDeviceIndex, &addresses));
606 EXPECT_EQ(1, addresses.size());
607 EXPECT_TRUE(ip_address0.Equals(addresses[0].address));
608
609 // Re-adding the same address shouldn't cause the address list to change
610 SendMessageToDeviceInfo(*message);
611 EXPECT_TRUE(device_info_.GetAddresses(kTestDeviceIndex, &addresses));
612 EXPECT_EQ(1, addresses.size());
613 EXPECT_TRUE(ip_address0.Equals(addresses[0].address));
614
615 // Adding a new address should expand the list
Paul Stewart7355ce12011-09-02 10:47:01 -0700616 IPAddress ip_address1(IPAddress::kFamilyIPv6);
Paul Stewart9a908082011-08-31 12:18:48 -0700617 EXPECT_TRUE(ip_address1.SetAddressFromString(kTestIPAddress1));
618 ip_address1.set_prefix(kTestIPAddressPrefix1);
619 message.reset(BuildAddressMessage(RTNLMessage::kModeAdd, ip_address1, 0, 0));
620 SendMessageToDeviceInfo(*message);
621 EXPECT_TRUE(device_info_.GetAddresses(kTestDeviceIndex, &addresses));
622 EXPECT_EQ(2, addresses.size());
623 EXPECT_TRUE(ip_address0.Equals(addresses[0].address));
624 EXPECT_TRUE(ip_address1.Equals(addresses[1].address));
625
626 // Deleting an address should reduce the list
627 message.reset(BuildAddressMessage(RTNLMessage::kModeDelete,
628 ip_address0,
629 0,
630 0));
631 SendMessageToDeviceInfo(*message);
632 EXPECT_TRUE(device_info_.GetAddresses(kTestDeviceIndex, &addresses));
633 EXPECT_EQ(1, addresses.size());
634 EXPECT_TRUE(ip_address1.Equals(addresses[0].address));
635
636 // Delete last item
637 message.reset(BuildAddressMessage(RTNLMessage::kModeDelete,
638 ip_address1,
639 0,
640 0));
641 SendMessageToDeviceInfo(*message);
642 EXPECT_TRUE(device_info_.GetAddresses(kTestDeviceIndex, &addresses));
643 EXPECT_TRUE(addresses.empty());
644
645 // Delete device
646 message.reset(BuildLinkMessage(RTNLMessage::kModeDelete));
Paul Stewart8c116a92012-05-02 18:30:03 -0700647 EXPECT_CALL(manager_, DeregisterDevice(_)).Times(1);
Paul Stewart9a908082011-08-31 12:18:48 -0700648 SendMessageToDeviceInfo(*message);
649
650 // Should be able to handle message for interface that doesn't exist
651 message.reset(BuildAddressMessage(RTNLMessage::kModeAdd, ip_address0, 0, 0));
652 SendMessageToDeviceInfo(*message);
653 EXPECT_FALSE(device_info_.GetDevice(kTestDeviceIndex).get());
Paul Stewart9a908082011-08-31 12:18:48 -0700654}
655
656TEST_F(DeviceInfoTest, FlushAddressList) {
Paul Stewart9a908082011-08-31 12:18:48 -0700657 scoped_ptr<RTNLMessage> message(BuildLinkMessage(RTNLMessage::kModeAdd));
658 SendMessageToDeviceInfo(*message);
659
Paul Stewart7355ce12011-09-02 10:47:01 -0700660 IPAddress address1(IPAddress::kFamilyIPv6);
Paul Stewart9a908082011-08-31 12:18:48 -0700661 EXPECT_TRUE(address1.SetAddressFromString(kTestIPAddress1));
662 address1.set_prefix(kTestIPAddressPrefix1);
663 message.reset(BuildAddressMessage(RTNLMessage::kModeAdd,
664 address1,
665 0,
666 RT_SCOPE_UNIVERSE));
667 SendMessageToDeviceInfo(*message);
Paul Stewart7355ce12011-09-02 10:47:01 -0700668 IPAddress address2(IPAddress::kFamilyIPv6);
Paul Stewart9a908082011-08-31 12:18:48 -0700669 EXPECT_TRUE(address2.SetAddressFromString(kTestIPAddress2));
670 message.reset(BuildAddressMessage(RTNLMessage::kModeAdd,
671 address2,
672 IFA_F_TEMPORARY,
673 RT_SCOPE_UNIVERSE));
674 SendMessageToDeviceInfo(*message);
Paul Stewart7355ce12011-09-02 10:47:01 -0700675 IPAddress address3(IPAddress::kFamilyIPv6);
Paul Stewart9a908082011-08-31 12:18:48 -0700676 EXPECT_TRUE(address3.SetAddressFromString(kTestIPAddress3));
677 message.reset(BuildAddressMessage(RTNLMessage::kModeAdd,
678 address3,
679 0,
680 RT_SCOPE_LINK));
681 SendMessageToDeviceInfo(*message);
Paul Stewart7355ce12011-09-02 10:47:01 -0700682 IPAddress address4(IPAddress::kFamilyIPv6);
Paul Stewart9a908082011-08-31 12:18:48 -0700683 EXPECT_TRUE(address4.SetAddressFromString(kTestIPAddress4));
684 message.reset(BuildAddressMessage(RTNLMessage::kModeAdd,
685 address4,
686 IFA_F_PERMANENT,
687 RT_SCOPE_UNIVERSE));
688 SendMessageToDeviceInfo(*message);
689
690 // DeviceInfo now has 4 addresses associated with it, but only two of
691 // them are valid for flush.
692 EXPECT_CALL(rtnl_handler_, RemoveInterfaceAddress(kTestDeviceIndex,
693 IsIPAddress(address1)));
694 EXPECT_CALL(rtnl_handler_, RemoveInterfaceAddress(kTestDeviceIndex,
695 IsIPAddress(address2)));
696 device_info_.FlushAddresses(kTestDeviceIndex);
Paul Stewart9a908082011-08-31 12:18:48 -0700697}
698
Paul Stewart05a42c22012-08-02 16:47:21 -0700699TEST_F(DeviceInfoTest, HasOtherAddress) {
700 scoped_ptr<RTNLMessage> message(BuildLinkMessage(RTNLMessage::kModeAdd));
701 SendMessageToDeviceInfo(*message);
702
703 IPAddress address0(IPAddress::kFamilyIPv4);
704 EXPECT_TRUE(address0.SetAddressFromString(kTestIPAddress0));
705
706 // There are no addresses on this interface.
707 EXPECT_FALSE(device_info_.HasOtherAddress(kTestDeviceIndex, address0));
708
709 message.reset(BuildAddressMessage(RTNLMessage::kModeAdd,
710 address0,
711 0,
712 RT_SCOPE_UNIVERSE));
713 SendMessageToDeviceInfo(*message);
714
715 IPAddress address1(IPAddress::kFamilyIPv6);
716 EXPECT_TRUE(address1.SetAddressFromString(kTestIPAddress1));
717 address1.set_prefix(kTestIPAddressPrefix1);
718 message.reset(BuildAddressMessage(RTNLMessage::kModeAdd,
719 address1,
720 0,
721 RT_SCOPE_LINK));
722 SendMessageToDeviceInfo(*message);
723
724 IPAddress address2(IPAddress::kFamilyIPv6);
725 EXPECT_TRUE(address2.SetAddressFromString(kTestIPAddress2));
726 message.reset(BuildAddressMessage(RTNLMessage::kModeAdd,
727 address2,
728 IFA_F_TEMPORARY,
729 RT_SCOPE_UNIVERSE));
730 SendMessageToDeviceInfo(*message);
731
732 IPAddress address3(IPAddress::kFamilyIPv6);
733 EXPECT_TRUE(address3.SetAddressFromString(kTestIPAddress3));
734
735 // The only IPv6 addresses on this interface are either flagged as
736 // temporary, or they are not universally scoped.
737 EXPECT_FALSE(device_info_.HasOtherAddress(kTestDeviceIndex, address3));
738
739
740 message.reset(BuildAddressMessage(RTNLMessage::kModeAdd,
741 address3,
742 0,
743 RT_SCOPE_UNIVERSE));
744 SendMessageToDeviceInfo(*message);
745
746 // address0 is on this interface.
747 EXPECT_FALSE(device_info_.HasOtherAddress(kTestDeviceIndex, address0));
748 // address1 is on this interface.
749 EXPECT_FALSE(device_info_.HasOtherAddress(kTestDeviceIndex, address1));
750 // address2 is on this interface.
751 EXPECT_FALSE(device_info_.HasOtherAddress(kTestDeviceIndex, address2));
752 // address3 is on this interface.
753 EXPECT_FALSE(device_info_.HasOtherAddress(kTestDeviceIndex, address3));
754
755 IPAddress address4(IPAddress::kFamilyIPv6);
756 EXPECT_TRUE(address4.SetAddressFromString(kTestIPAddress4));
757
758 // address4 is not on this interface, but address3 is, and is a qualified
759 // IPv6 address.
760 EXPECT_TRUE(device_info_.HasOtherAddress(kTestDeviceIndex, address4));
761
762 message.reset(BuildAddressMessage(RTNLMessage::kModeAdd,
763 address4,
764 IFA_F_PERMANENT,
765 RT_SCOPE_UNIVERSE));
766 SendMessageToDeviceInfo(*message);
767
768 // address4 is now on this interface.
769 EXPECT_FALSE(device_info_.HasOtherAddress(kTestDeviceIndex, address4));
770
771 IPAddress address5(IPAddress::kFamilyIPv4);
772 EXPECT_TRUE(address5.SetAddressFromString(kTestIPAddress5));
773 // address5 is not on this interface, but address0 is.
774 EXPECT_TRUE(device_info_.HasOtherAddress(kTestDeviceIndex, address5));
775
776 message.reset(BuildAddressMessage(RTNLMessage::kModeAdd,
777 address5,
778 IFA_F_PERMANENT,
779 RT_SCOPE_UNIVERSE));
780 SendMessageToDeviceInfo(*message);
781
782 // address5 is now on this interface.
783 EXPECT_FALSE(device_info_.HasOtherAddress(kTestDeviceIndex, address5));
784}
785
Thieu Leb27beee2012-04-20 09:19:06 -0700786TEST_F(DeviceInfoTest, HasSubdir) {
Paul Stewart5ad16062013-02-21 18:10:48 -0800787 base::ScopedTempDir temp_dir;
Thieu Le8f1c8352012-04-16 11:02:12 -0700788 EXPECT_TRUE(temp_dir.CreateUniqueTempDir());
Thieu Leb27beee2012-04-20 09:19:06 -0700789 EXPECT_TRUE(file_util::CreateDirectory(temp_dir.path().Append("child1")));
790 FilePath child2 = temp_dir.path().Append("child2");
791 EXPECT_TRUE(file_util::CreateDirectory(child2));
792 FilePath grandchild = child2.Append("grandchild");
Thieu Le8f1c8352012-04-16 11:02:12 -0700793 EXPECT_TRUE(file_util::CreateDirectory(grandchild));
794 EXPECT_TRUE(file_util::CreateDirectory(grandchild.Append("greatgrandchild")));
Thieu Leb27beee2012-04-20 09:19:06 -0700795 EXPECT_TRUE(DeviceInfo::HasSubdir(temp_dir.path(),
796 FilePath("grandchild")));
797 EXPECT_TRUE(DeviceInfo::HasSubdir(temp_dir.path(),
798 FilePath("greatgrandchild")));
799 EXPECT_FALSE(DeviceInfo::HasSubdir(temp_dir.path(),
800 FilePath("nonexistent")));
Thieu Le8f1c8352012-04-16 11:02:12 -0700801}
802
Gary Morain41780232012-07-31 15:08:31 -0700803TEST_F(DeviceInfoTest, GetMACAddressFromKernelUnknownDevice) {
804 SetSockets();
805 EXPECT_CALL(*mock_sockets_, Socket(PF_INET, SOCK_DGRAM, 0)).Times(0);
806 ByteString mac_address =
807 device_info_.GetMACAddressFromKernel(kTestDeviceIndex);
808 EXPECT_TRUE(mac_address.IsEmpty());
809}
810
811TEST_F(DeviceInfoTest, GetMACAddressFromKernelUnableToOpenSocket) {
812 SetSockets();
813 EXPECT_CALL(*mock_sockets_, Socket(PF_INET, SOCK_DGRAM, 0))
814 .WillOnce(Return(-1));
815 scoped_ptr<RTNLMessage> message(BuildLinkMessage(RTNLMessage::kModeAdd));
816 message->set_link_status(RTNLMessage::LinkStatus(0, IFF_LOWER_UP, 0));
817 SendMessageToDeviceInfo(*message);
818 EXPECT_TRUE(device_info_.GetDevice(kTestDeviceIndex).get());
819 ByteString mac_address =
820 device_info_.GetMACAddressFromKernel(kTestDeviceIndex);
821 EXPECT_TRUE(mac_address.IsEmpty());
822}
823
824TEST_F(DeviceInfoTest, GetMACAddressFromKernelIoctlFails) {
825 SetSockets();
826 const int kFd = 99;
827 EXPECT_CALL(*mock_sockets_, Socket(PF_INET, SOCK_DGRAM, 0))
828 .WillOnce(Return(kFd));
829 EXPECT_CALL(*mock_sockets_, Ioctl(kFd, SIOCGIFHWADDR, NotNull()))
830 .WillOnce(Return(-1));
831 EXPECT_CALL(*mock_sockets_, Close(kFd));
832
833 scoped_ptr<RTNLMessage> message(BuildLinkMessage(RTNLMessage::kModeAdd));
834 message->set_link_status(RTNLMessage::LinkStatus(0, IFF_LOWER_UP, 0));
835 SendMessageToDeviceInfo(*message);
836 EXPECT_TRUE(device_info_.GetDevice(kTestDeviceIndex).get());
837
838 ByteString mac_address =
839 device_info_.GetMACAddressFromKernel(kTestDeviceIndex);
840 EXPECT_TRUE(mac_address.IsEmpty());
841}
842
843MATCHER_P2(IfreqEquals, ifindex, ifname, "") {
844 const struct ifreq *const ifr = static_cast<struct ifreq *>(arg);
845 return (ifr != NULL) &&
846 (ifr->ifr_ifindex == ifindex) &&
847 (strcmp(ifname, ifr->ifr_name) == 0);
848}
849
850ACTION_P(SetIfreq, ifr) {
851 struct ifreq *const ifr_arg = static_cast<struct ifreq *>(arg2);
852 *ifr_arg = ifr;
853}
854
855TEST_F(DeviceInfoTest, GetMACAddressFromKernel) {
856 SetSockets();
857 const int kFd = 99;
858 struct ifreq ifr;
Han Shenfc349252012-08-30 11:36:04 -0700859 static uint8_t kMacAddress[] = {0x00, 0x01, 0x02, 0xaa, 0xbb, 0xcc};
Gary Morain41780232012-07-31 15:08:31 -0700860 memcpy(ifr.ifr_hwaddr.sa_data, kMacAddress, sizeof(kMacAddress));
861 EXPECT_CALL(*mock_sockets_, Socket(PF_INET, SOCK_DGRAM, 0))
862 .WillOnce(Return(kFd));
863 EXPECT_CALL(*mock_sockets_,
864 Ioctl(kFd, SIOCGIFHWADDR,
865 IfreqEquals(kTestDeviceIndex, kTestDeviceName)))
866 .WillOnce(DoAll(SetIfreq(ifr), Return(0)));
867 EXPECT_CALL(*mock_sockets_, Close(kFd));
868
869 scoped_ptr<RTNLMessage> message(BuildLinkMessage(RTNLMessage::kModeAdd));
870 message->set_link_status(RTNLMessage::LinkStatus(0, IFF_LOWER_UP, 0));
871 SendMessageToDeviceInfo(*message);
872 EXPECT_TRUE(device_info_.GetDevice(kTestDeviceIndex).get());
873
874 ByteString mac_address =
875 device_info_.GetMACAddressFromKernel(kTestDeviceIndex);
876 EXPECT_THAT(kMacAddress,
877 ElementsAreArray(mac_address.GetData(), sizeof(kMacAddress)));
878}
879
Paul Stewartca876ee2012-04-21 08:55:58 -0700880class DeviceInfoTechnologyTest : public DeviceInfoTest {
881 public:
Jason Glasgowabc54032012-04-20 16:08:32 -0400882 DeviceInfoTechnologyTest()
883 : DeviceInfoTest(),
884 test_device_name_(kTestDeviceName) {}
Paul Stewartca876ee2012-04-21 08:55:58 -0700885 virtual ~DeviceInfoTechnologyTest() {}
886
887 virtual void SetUp() {
888 temp_dir_.CreateUniqueTempDir();
889 device_info_root_ = temp_dir_.path().Append("sys/class/net");
890 device_info_.device_info_root_ = device_info_root_;
891 // Most tests require that the uevent file exist.
892 CreateInfoFile("uevent", "xxx");
893 }
894
895 Technology::Identifier GetDeviceTechnology() {
Jason Glasgowabc54032012-04-20 16:08:32 -0400896 return device_info_.GetDeviceTechnology(test_device_name_);
Paul Stewartca876ee2012-04-21 08:55:58 -0700897 }
898 FilePath GetInfoPath(const string &name);
899 void CreateInfoFile(const string &name, const string &contents);
900 void CreateInfoSymLink(const string &name, const string &contents);
Jason Glasgowabc54032012-04-20 16:08:32 -0400901 void SetDeviceName(const string &name) {
902 test_device_name_ = name;
903 SetUp();
904 }
Paul Stewartca876ee2012-04-21 08:55:58 -0700905
906 protected:
Paul Stewart5ad16062013-02-21 18:10:48 -0800907 base::ScopedTempDir temp_dir_;
Paul Stewartca876ee2012-04-21 08:55:58 -0700908 FilePath device_info_root_;
Jason Glasgowabc54032012-04-20 16:08:32 -0400909 string test_device_name_;
Paul Stewartca876ee2012-04-21 08:55:58 -0700910};
911
912FilePath DeviceInfoTechnologyTest::GetInfoPath(const string &name) {
Jason Glasgowabc54032012-04-20 16:08:32 -0400913 return device_info_root_.Append(test_device_name_).Append(name);
Paul Stewartca876ee2012-04-21 08:55:58 -0700914}
915
916void DeviceInfoTechnologyTest::CreateInfoFile(const string &name,
917 const string &contents) {
918 FilePath info_path = GetInfoPath(name);
919 EXPECT_TRUE(file_util::CreateDirectory(info_path.DirName()));
920 string contents_newline(contents + "\n");
921 EXPECT_TRUE(file_util::WriteFile(info_path, contents_newline.c_str(),
922 contents_newline.size()));
923}
924
925void DeviceInfoTechnologyTest::CreateInfoSymLink(const string &name,
926 const string &contents) {
927 FilePath info_path = GetInfoPath(name);
Paul Stewartca876ee2012-04-21 08:55:58 -0700928 EXPECT_TRUE(file_util::CreateDirectory(info_path.DirName()));
929 EXPECT_TRUE(file_util::CreateSymbolicLink(FilePath(contents), info_path));
930}
931
932TEST_F(DeviceInfoTechnologyTest, Unknown) {
933 EXPECT_EQ(Technology::kUnknown, GetDeviceTechnology());
934 // Should still be unknown even without a uevent file.
Ben Chan4eb4ddf2013-06-20 22:16:56 -0700935 EXPECT_TRUE(file_util::Delete(GetInfoPath("uevent"), false));
Paul Stewartca876ee2012-04-21 08:55:58 -0700936 EXPECT_EQ(Technology::kUnknown, GetDeviceTechnology());
937}
938
939TEST_F(DeviceInfoTechnologyTest, Loopback) {
940 CreateInfoFile("type", base::IntToString(ARPHRD_LOOPBACK));
941 EXPECT_EQ(Technology::kLoopback, GetDeviceTechnology());
942}
943
944TEST_F(DeviceInfoTechnologyTest, PPP) {
945 CreateInfoFile("type", base::IntToString(ARPHRD_PPP));
946 EXPECT_EQ(Technology::kPPP, GetDeviceTechnology());
947}
948
949TEST_F(DeviceInfoTechnologyTest, Tunnel) {
950 CreateInfoFile("tun_flags", base::IntToString(IFF_TUN));
951 EXPECT_EQ(Technology::kTunnel, GetDeviceTechnology());
952}
953
954TEST_F(DeviceInfoTechnologyTest, WiFi) {
955 CreateInfoFile("uevent", "DEVTYPE=wlan");
956 EXPECT_EQ(Technology::kWifi, GetDeviceTechnology());
957 CreateInfoFile("uevent", "foo\nDEVTYPE=wlan");
958 EXPECT_EQ(Technology::kWifi, GetDeviceTechnology());
959 CreateInfoFile("type", base::IntToString(ARPHRD_IEEE80211_RADIOTAP));
960 EXPECT_EQ(Technology::kWiFiMonitor, GetDeviceTechnology());
961}
962
963TEST_F(DeviceInfoTechnologyTest, Ethernet) {
964 CreateInfoSymLink("device/driver", "xxx");
965 EXPECT_EQ(Technology::kEthernet, GetDeviceTechnology());
966}
967
Darin Petkove4b27022012-05-16 13:28:50 +0200968TEST_F(DeviceInfoTechnologyTest, WiMax) {
969 CreateInfoSymLink("device/driver", "gdm_wimax");
970 EXPECT_EQ(Technology::kWiMax, GetDeviceTechnology());
971}
972
Paul Stewartca876ee2012-04-21 08:55:58 -0700973TEST_F(DeviceInfoTechnologyTest, CellularGobi1) {
974 CreateInfoSymLink("device/driver", "blah/foo/gobi");
975 EXPECT_EQ(Technology::kCellular, GetDeviceTechnology());
976}
977
978TEST_F(DeviceInfoTechnologyTest, CellularGobi2) {
979 CreateInfoSymLink("device/driver", "../GobiNet");
980 EXPECT_EQ(Technology::kCellular, GetDeviceTechnology());
981}
982
983TEST_F(DeviceInfoTechnologyTest, QCUSB) {
984 CreateInfoSymLink("device/driver", "QCUSBNet2k");
985 EXPECT_EQ(Technology::kCellular, GetDeviceTechnology());
986}
987
Ben Chan0f90e0b2013-06-26 23:37:16 -0700988TEST_F(DeviceInfoTechnologyTest, CellularCdcMbim) {
989 CreateInfoSymLink("device/driver", "cdc_mbim");
990 EXPECT_EQ(Technology::kCellular, GetDeviceTechnology());
991}
992
Ben Chan226d46a2012-10-11 00:22:17 -0700993TEST_F(DeviceInfoTechnologyTest, CellularQmiWwan) {
994 CreateInfoSymLink("device/driver", "qmi_wwan");
995 EXPECT_EQ(Technology::kCellular, GetDeviceTechnology());
996}
997
Paul Stewartca876ee2012-04-21 08:55:58 -0700998// Modem with absolute driver path with top-level tty file:
999// /sys/class/net/dev0/device -> /sys/devices/virtual/0/00
Ben Chan4eb4ddf2013-06-20 22:16:56 -07001000// /sys/devices/virtual/0/00/driver -> /drivers/cdc_ether or /drivers/cdc_ncm
Paul Stewartca876ee2012-04-21 08:55:58 -07001001// /sys/devices/virtual/0/01/tty [empty directory]
Ben Chan4eb4ddf2013-06-20 22:16:56 -07001002TEST_F(DeviceInfoTechnologyTest, CDCEthernetModem1) {
Paul Stewartca876ee2012-04-21 08:55:58 -07001003 FilePath device_root(temp_dir_.path().Append("sys/devices/virtual/0"));
1004 FilePath device_path(device_root.Append("00"));
Ben Chan4eb4ddf2013-06-20 22:16:56 -07001005 FilePath driver_symlink(device_path.Append("driver"));
Paul Stewartca876ee2012-04-21 08:55:58 -07001006 EXPECT_TRUE(file_util::CreateDirectory(device_path));
1007 CreateInfoSymLink("device", device_path.value());
1008 EXPECT_TRUE(file_util::CreateSymbolicLink(FilePath("/drivers/cdc_ether"),
Ben Chan4eb4ddf2013-06-20 22:16:56 -07001009 driver_symlink));
Paul Stewartca876ee2012-04-21 08:55:58 -07001010 EXPECT_TRUE(file_util::CreateDirectory(device_root.Append("01/tty")));
1011 EXPECT_EQ(Technology::kCellular, GetDeviceTechnology());
Ben Chan4eb4ddf2013-06-20 22:16:56 -07001012
1013 EXPECT_TRUE(file_util::Delete(driver_symlink, false));
1014 EXPECT_TRUE(file_util::CreateSymbolicLink(FilePath("/drivers/cdc_ncm"),
1015 driver_symlink));
1016 EXPECT_EQ(Technology::kCellular, GetDeviceTechnology());
Paul Stewartca876ee2012-04-21 08:55:58 -07001017}
1018
1019// Modem with relative driver path with top-level tty file.
1020// /sys/class/net/dev0/device -> ../../../device_dir/0/00
Ben Chan4eb4ddf2013-06-20 22:16:56 -07001021// /sys/device_dir/0/00/driver -> /drivers/cdc_ether or /drivers/cdc_ncm
Paul Stewartca876ee2012-04-21 08:55:58 -07001022// /sys/device_dir/0/01/tty [empty directory]
Ben Chan4eb4ddf2013-06-20 22:16:56 -07001023TEST_F(DeviceInfoTechnologyTest, CDCEthernetModem2) {
Paul Stewartca876ee2012-04-21 08:55:58 -07001024 CreateInfoSymLink("device", "../../../device_dir/0/00");
1025 FilePath device_root(temp_dir_.path().Append("sys/device_dir/0"));
1026 FilePath device_path(device_root.Append("00"));
Ben Chan4eb4ddf2013-06-20 22:16:56 -07001027 FilePath driver_symlink(device_path.Append("driver"));
Paul Stewartca876ee2012-04-21 08:55:58 -07001028 EXPECT_TRUE(file_util::CreateDirectory(device_path));
1029 EXPECT_TRUE(file_util::CreateSymbolicLink(FilePath("/drivers/cdc_ether"),
Ben Chan4eb4ddf2013-06-20 22:16:56 -07001030 driver_symlink));
Paul Stewartca876ee2012-04-21 08:55:58 -07001031 EXPECT_TRUE(file_util::CreateDirectory(device_root.Append("01/tty")));
1032 EXPECT_EQ(Technology::kCellular, GetDeviceTechnology());
Ben Chan4eb4ddf2013-06-20 22:16:56 -07001033
1034 EXPECT_TRUE(file_util::Delete(driver_symlink, false));
1035 EXPECT_TRUE(file_util::CreateSymbolicLink(FilePath("/drivers/cdc_ncm"),
1036 driver_symlink));
1037 EXPECT_EQ(Technology::kCellular, GetDeviceTechnology());
Paul Stewartca876ee2012-04-21 08:55:58 -07001038}
1039
1040// Modem with relative driver path with lower-level tty file.
1041// /sys/class/net/dev0/device -> ../../../device_dir/0/00
Ben Chan4eb4ddf2013-06-20 22:16:56 -07001042// /sys/device_dir/0/00/driver -> /drivers/cdc_ether or /drivers/cdc_ncm
Paul Stewartca876ee2012-04-21 08:55:58 -07001043// /sys/device_dir/0/01/yyy/tty [empty directory]
Ben Chan4eb4ddf2013-06-20 22:16:56 -07001044TEST_F(DeviceInfoTechnologyTest, CDCEthernetModem3) {
Paul Stewartca876ee2012-04-21 08:55:58 -07001045 CreateInfoSymLink("device", "../../../device_dir/0/00");
1046 FilePath device_root(temp_dir_.path().Append("sys/device_dir/0"));
1047 FilePath device_path(device_root.Append("00"));
Ben Chan4eb4ddf2013-06-20 22:16:56 -07001048 FilePath driver_symlink(device_path.Append("driver"));
Paul Stewartca876ee2012-04-21 08:55:58 -07001049 EXPECT_TRUE(file_util::CreateDirectory(device_path));
1050 EXPECT_TRUE(file_util::CreateSymbolicLink(FilePath("/drivers/cdc_ether"),
Ben Chan4eb4ddf2013-06-20 22:16:56 -07001051 driver_symlink));
Paul Stewartca876ee2012-04-21 08:55:58 -07001052 EXPECT_TRUE(file_util::CreateDirectory(device_root.Append("01/yyy/tty")));
1053 EXPECT_EQ(Technology::kCellular, GetDeviceTechnology());
Ben Chan4eb4ddf2013-06-20 22:16:56 -07001054
1055 EXPECT_TRUE(file_util::Delete(driver_symlink, false));
1056 EXPECT_TRUE(file_util::CreateSymbolicLink(FilePath("/drivers/cdc_ncm"),
1057 driver_symlink));
1058 EXPECT_EQ(Technology::kCellular, GetDeviceTechnology());
Paul Stewartca876ee2012-04-21 08:55:58 -07001059}
1060
1061TEST_F(DeviceInfoTechnologyTest, CDCEtherNonModem) {
1062 CreateInfoSymLink("device", "device_dir");
1063 CreateInfoSymLink("device_dir/driver", "cdc_ether");
Paul Stewart050cfc02012-07-06 20:38:54 -07001064 EXPECT_EQ(Technology::kCDCEthernet, GetDeviceTechnology());
Paul Stewartca876ee2012-04-21 08:55:58 -07001065}
1066
Ben Chan4eb4ddf2013-06-20 22:16:56 -07001067TEST_F(DeviceInfoTechnologyTest, CDCNcmNonModem) {
1068 CreateInfoSymLink("device", "device_dir");
1069 CreateInfoSymLink("device_dir/driver", "cdc_ncm");
1070 EXPECT_EQ(Technology::kCDCEthernet, GetDeviceTechnology());
1071}
1072
Jason Glasgowabc54032012-04-20 16:08:32 -04001073TEST_F(DeviceInfoTechnologyTest, PseudoModem) {
1074 SetDeviceName("pseudomodem");
1075 CreateInfoSymLink("device", "device_dir");
1076 CreateInfoSymLink("device_dir/driver", "cdc_ether");
1077 EXPECT_EQ(Technology::kCellular, GetDeviceTechnology());
1078
1079 SetDeviceName("pseudomodem9");
1080 CreateInfoSymLink("device", "device_dir");
1081 CreateInfoSymLink("device_dir/driver", "cdc_ether");
1082 EXPECT_EQ(Technology::kCellular, GetDeviceTechnology());
1083}
1084
Paul Stewart050cfc02012-07-06 20:38:54 -07001085class DeviceInfoForDelayedCreationTest : public DeviceInfo {
1086 public:
1087 DeviceInfoForDelayedCreationTest(ControlInterface *control_interface,
1088 EventDispatcher *dispatcher,
1089 Metrics *metrics,
1090 Manager *manager)
1091 : DeviceInfo(control_interface, dispatcher, metrics, manager) {}
1092 MOCK_METHOD4(CreateDevice, DeviceRefPtr(const std::string &link_name,
1093 const std::string &address,
1094 int interface_index,
1095 Technology::Identifier technology));
1096 MOCK_METHOD1(GetDeviceTechnology,
1097 Technology::Identifier(const string &iface_name));
1098};
1099
1100class DeviceInfoDelayedCreationTest : public DeviceInfoTest {
1101 public:
1102 DeviceInfoDelayedCreationTest()
1103 : DeviceInfoTest(),
1104 test_device_info_(
1105 &control_interface_, &dispatcher_, &metrics_, &manager_) {}
1106 virtual ~DeviceInfoDelayedCreationTest() {}
1107
1108 virtual std::set<int> &GetDelayedDevices() {
1109 return test_device_info_.delayed_devices_;
1110 }
1111
1112 void DelayedDeviceCreationTask() {
1113 test_device_info_.DelayedDeviceCreationTask();
1114 }
1115
1116 void AddDelayedDevice() {
1117 scoped_ptr<RTNLMessage> message(BuildLinkMessage(RTNLMessage::kModeAdd));
1118 EXPECT_CALL(test_device_info_, GetDeviceTechnology(kTestDeviceName))
1119 .WillOnce(Return(Technology::kCDCEthernet));
1120 EXPECT_CALL(test_device_info_, CreateDevice(
1121 kTestDeviceName, _, kTestDeviceIndex, Technology::kCDCEthernet))
1122 .WillOnce(Return(DeviceRefPtr()));
1123 test_device_info_.AddLinkMsgHandler(*message);
1124 Mock::VerifyAndClearExpectations(&test_device_info_);
1125 // We need to insert the device index ourselves since we have mocked
1126 // out CreateDevice. This insertion is tested in CreateDeviceCDCEthernet
1127 // above.
1128 GetDelayedDevices().insert(kTestDeviceIndex);
1129 }
1130
Wade Guthrie7347bf22013-04-30 11:21:51 -07001131 void TriggerOnWiFiInterfaceInfoReceived(const Nl80211Message &message) {
Paul Stewart2ddf2c62013-04-16 09:47:34 -07001132 test_device_info_.OnWiFiInterfaceInfoReceived(message);
1133 }
1134
Paul Stewart050cfc02012-07-06 20:38:54 -07001135 protected:
1136 DeviceInfoForDelayedCreationTest test_device_info_;
1137};
1138
1139TEST_F(DeviceInfoDelayedCreationTest, NoDevices) {
1140 EXPECT_TRUE(GetDelayedDevices().empty());
1141 EXPECT_CALL(test_device_info_, GetDeviceTechnology(_)).Times(0);
1142 DelayedDeviceCreationTask();
1143}
1144
1145TEST_F(DeviceInfoDelayedCreationTest, EthernetDevice) {
1146 AddDelayedDevice();
1147 EXPECT_CALL(test_device_info_, GetDeviceTechnology(_))
1148 .WillOnce(Return(Technology::kCDCEthernet));
1149 EXPECT_CALL(test_device_info_, CreateDevice(
1150 kTestDeviceName, _, kTestDeviceIndex, Technology::kEthernet))
1151 .WillOnce(Return(DeviceRefPtr()));
1152 DelayedDeviceCreationTask();
1153 EXPECT_TRUE(GetDelayedDevices().empty());
1154}
1155
1156TEST_F(DeviceInfoDelayedCreationTest, CellularDevice) {
1157 AddDelayedDevice();
1158 EXPECT_CALL(test_device_info_, GetDeviceTechnology(_))
1159 .WillOnce(Return(Technology::kCellular));
1160 EXPECT_CALL(test_device_info_, CreateDevice(
1161 kTestDeviceName, _, kTestDeviceIndex, Technology::kCellular))
1162 .WillOnce(Return(DeviceRefPtr()));
1163 DelayedDeviceCreationTask();
1164 EXPECT_TRUE(GetDelayedDevices().empty());
1165}
1166
Paul Stewart2ddf2c62013-04-16 09:47:34 -07001167TEST_F(DeviceInfoDelayedCreationTest, WiFiDevice) {
1168 ScopedMockLog log;
Paul Stewart2ddf2c62013-04-16 09:47:34 -07001169 EXPECT_CALL(log, Log(logging::LOG_ERROR, _,
1170 HasSubstr("Message is not a new interface response")));
1171 GetInterfaceMessage non_interface_response_message;
1172 TriggerOnWiFiInterfaceInfoReceived(non_interface_response_message);
1173 Mock::VerifyAndClearExpectations(&log);
1174
1175 EXPECT_CALL(log, Log(logging::LOG_ERROR, _,
1176 HasSubstr("Message contains no interface index")));
1177 NewInterfaceMessage message;
1178 TriggerOnWiFiInterfaceInfoReceived(message);
1179 Mock::VerifyAndClearExpectations(&log);
1180
1181 message.attributes()->CreateAttribute(
1182 NL80211_ATTR_IFINDEX, base::Bind(
1183 &NetlinkAttribute::NewNl80211AttributeFromId));
1184 message.attributes()->SetU32AttributeValue(NL80211_ATTR_IFINDEX,
1185 kTestDeviceIndex);
1186 EXPECT_CALL(log, Log(logging::LOG_ERROR, _,
1187 HasSubstr("Message contains no interface type")));
1188 TriggerOnWiFiInterfaceInfoReceived(message);
1189 Mock::VerifyAndClearExpectations(&log);
1190
1191 message.attributes()->CreateAttribute(
1192 NL80211_ATTR_IFTYPE, base::Bind(
1193 &NetlinkAttribute::NewNl80211AttributeFromId));
1194 message.attributes()->SetU32AttributeValue(NL80211_ATTR_IFTYPE,
1195 NL80211_IFTYPE_AP);
1196 EXPECT_CALL(log, Log(logging::LOG_ERROR, _,
1197 HasSubstr("Could not find device info for interface")));
1198 TriggerOnWiFiInterfaceInfoReceived(message);
1199 Mock::VerifyAndClearExpectations(&log);
1200
1201 // Use the AddDelayedDevice() method to create a device info entry with no
1202 // associated device.
1203 AddDelayedDevice();
1204
1205 EXPECT_CALL(log, Log(logging::LOG_INFO, _,
1206 HasSubstr("it is not in station mode")));
1207 TriggerOnWiFiInterfaceInfoReceived(message);
1208 Mock::VerifyAndClearExpectations(&log);
1209 Mock::VerifyAndClearExpectations(&manager_);
1210
1211 message.attributes()->SetU32AttributeValue(NL80211_ATTR_IFTYPE,
1212 NL80211_IFTYPE_STATION);
1213 EXPECT_CALL(manager_, RegisterDevice(_));
1214 EXPECT_CALL(manager_, device_info())
1215 .WillRepeatedly(Return(&test_device_info_));
1216 EXPECT_CALL(log, Log(_, _, _)).Times(AnyNumber());
1217 EXPECT_CALL(log, Log(logging::LOG_INFO, _,
1218 HasSubstr("Creating WiFi device")));
1219 TriggerOnWiFiInterfaceInfoReceived(message);
1220 Mock::VerifyAndClearExpectations(&log);
1221 Mock::VerifyAndClearExpectations(&manager_);
1222
1223 EXPECT_CALL(manager_, RegisterDevice(_)).Times(0);
1224 EXPECT_CALL(log, Log(logging::LOG_ERROR, _,
1225 HasSubstr("Device already created for interface")));
1226 TriggerOnWiFiInterfaceInfoReceived(message);
1227}
1228
Chris Masone9be4a9d2011-05-16 15:44:09 -07001229} // namespace shill