blob: ecb791a320c0baa981363e916bb13c9e807d3fbc [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 Petkov633ac6f2011-07-08 13:56:13 -07008#include <sys/socket.h>
Darin Petkove6193c02011-08-11 12:42:40 -07009#include <linux/if.h>
Paul Stewartca876ee2012-04-21 08:55:58 -070010#include <linux/if_tun.h>
Darin Petkov633ac6f2011-07-08 13:56:13 -070011#include <linux/netlink.h> // Needs typedefs from sys/socket.h.
12#include <linux/rtnetlink.h>
Paul Stewartca876ee2012-04-21 08:55:58 -070013#include <net/if_arp.h>
Chris Masone9be4a9d2011-05-16 15:44:09 -070014
Thieu Le8f1c8352012-04-16 11:02:12 -070015#include <base/file_util.h>
Chris Masone9be4a9d2011-05-16 15:44:09 -070016#include <base/memory/ref_counted.h>
17#include <base/message_loop.h>
Thieu Le8f1c8352012-04-16 11:02:12 -070018#include <base/scoped_temp_dir.h>
Eric Shienbrood3e20a232012-02-16 11:35:56 -050019#include <base/stl_util.h>
Paul Stewartca876ee2012-04-21 08:55:58 -070020#include <base/string_number_conversions.h>
Chris Masone9be4a9d2011-05-16 15:44:09 -070021#include <gtest/gtest.h>
22#include <gmock/gmock.h>
23
Paul Stewart9a908082011-08-31 12:18:48 -070024#include "shill/ip_address.h"
Christopher Wileyb691efd2012-08-09 13:51:51 -070025#include "shill/logging.h"
Paul Stewartb50f0b92011-05-16 16:31:42 -070026#include "shill/manager.h"
Chris Masone46eaaf52011-05-24 13:08:30 -070027#include "shill/mock_control.h"
Darin Petkovafa6fc42011-06-21 16:21:08 -070028#include "shill/mock_glib.h"
Chris Masone2ae797d2011-08-23 20:41:00 -070029#include "shill/mock_manager.h"
Thieu Le3426c8f2012-01-11 17:35:11 -080030#include "shill/mock_metrics.h"
Paul Stewart8c116a92012-05-02 18:30:03 -070031#include "shill/mock_modem_info.h"
32#include "shill/mock_routing_table.h"
Paul Stewart9a908082011-08-31 12:18:48 -070033#include "shill/mock_rtnl_handler.h"
Darin Petkov633ac6f2011-07-08 13:56:13 -070034#include "shill/mock_sockets.h"
Paul Stewart8c116a92012-05-02 18:30:03 -070035#include "shill/mock_vpn_provider.h"
Darin Petkove4b27022012-05-16 13:28:50 +020036#include "shill/mock_wimax_provider.h"
Chris Masone2aa97072011-08-09 17:35:08 -070037#include "shill/rtnl_message.h"
Darin Petkovc63dcf02012-05-24 11:51:43 +020038#include "shill/wimax.h"
Chris Masone9be4a9d2011-05-16 15:44:09 -070039
Eric Shienbrood3e20a232012-02-16 11:35:56 -050040using base::Callback;
Darin Petkove6193c02011-08-11 12:42:40 -070041using std::map;
Darin Petkov633ac6f2011-07-08 13:56:13 -070042using std::string;
Paul Stewart9a908082011-08-31 12:18:48 -070043using std::vector;
Darin Petkov633ac6f2011-07-08 13:56:13 -070044using testing::_;
Paul Stewart8c116a92012-05-02 18:30:03 -070045using testing::Mock;
Darin Petkov633ac6f2011-07-08 13:56:13 -070046using testing::Return;
Paul Stewart9a908082011-08-31 12:18:48 -070047using testing::StrictMock;
Darin Petkov633ac6f2011-07-08 13:56:13 -070048using testing::Test;
49
Chris Masone9be4a9d2011-05-16 15:44:09 -070050namespace shill {
Darin Petkov633ac6f2011-07-08 13:56:13 -070051
Paul Stewart050cfc02012-07-06 20:38:54 -070052class TestEventDispatcherForDeviceInfo : public EventDispatcher {
Darin Petkov633ac6f2011-07-08 13:56:13 -070053 public:
Paul Stewart26b327e2011-10-19 11:38:09 -070054 virtual IOHandler *CreateInputHandler(
mukesh agrawal1830fa12011-09-26 14:31:40 -070055 int /*fd*/,
Eric Shienbrood3e20a232012-02-16 11:35:56 -050056 const Callback<void(InputData*)> &/*callback*/) {
Darin Petkov633ac6f2011-07-08 13:56:13 -070057 return NULL;
58 }
Paul Stewart050cfc02012-07-06 20:38:54 -070059 MOCK_METHOD2(PostDelayedTask, bool(const base::Closure &task,
60 int64 delay_ms));
Darin Petkov633ac6f2011-07-08 13:56:13 -070061};
Chris Masone9be4a9d2011-05-16 15:44:09 -070062
63class DeviceInfoTest : public Test {
64 public:
65 DeviceInfoTest()
Thieu Le3426c8f2012-01-11 17:35:11 -080066 : manager_(&control_interface_, &dispatcher_, &metrics_, &glib_),
67 device_info_(&control_interface_, &dispatcher_, &metrics_, &manager_) {
Chris Masone9be4a9d2011-05-16 15:44:09 -070068 }
Paul Stewartca876ee2012-04-21 08:55:58 -070069 virtual ~DeviceInfoTest() {}
Darin Petkov633ac6f2011-07-08 13:56:13 -070070
Paul Stewart9a908082011-08-31 12:18:48 -070071 virtual void SetUp() {
72 device_info_.rtnl_handler_ = &rtnl_handler_;
Paul Stewart8c116a92012-05-02 18:30:03 -070073 device_info_.routing_table_ = &routing_table_;
Paul Stewart9a908082011-08-31 12:18:48 -070074 }
75
Paul Stewart8c116a92012-05-02 18:30:03 -070076 IPAddress CreateInterfaceAddress() {
77 // Create an IP address entry (as if left-over from a previous connection
78 // manager).
79 IPAddress address(IPAddress::kFamilyIPv4);
80 EXPECT_TRUE(address.SetAddressFromString(kTestIPAddress0));
81 address.set_prefix(kTestIPAddressPrefix0);
82 vector<DeviceInfo::AddressData> &addresses =
83 device_info_.infos_[kTestDeviceIndex].ip_addresses;
84 addresses.push_back(DeviceInfo::AddressData(address, 0, RT_SCOPE_UNIVERSE));
85 EXPECT_EQ(1, addresses.size());
86 return address;
87 }
88
89 DeviceRefPtr CreateDevice(const std::string &link_name,
90 const std::string &address,
91 int interface_index,
92 Technology::Identifier technology) {
93 return device_info_.CreateDevice(link_name, address, interface_index,
94 technology);
95 }
96
Paul Stewart050cfc02012-07-06 20:38:54 -070097 virtual std::set<int> &GetDelayedDevices() {
98 return device_info_.delayed_devices_;
99 }
100
Paul Stewart1ac4e842012-07-10 12:58:12 -0700101 int GetDelayedDeviceCreationMilliseconds() {
Paul Stewart050cfc02012-07-06 20:38:54 -0700102 return DeviceInfo::kDelayedDeviceCreationSeconds * 1000;
103 }
Paul Stewart8c116a92012-05-02 18:30:03 -0700104
Paul Stewart1ac4e842012-07-10 12:58:12 -0700105 int GetRequestLinkStatisticsIntervalMilliseconds() {
106 return DeviceInfo::kRequestLinkStatisticsIntervalSeconds * 1000;
107 }
108
Paul Stewarta3c56f92011-05-26 07:08:52 -0700109 protected:
Chris Masoneb2e326b2011-07-12 13:28:51 -0700110 static const int kTestDeviceIndex;
Darin Petkov633ac6f2011-07-08 13:56:13 -0700111 static const char kTestDeviceName[];
Paul Stewart9a908082011-08-31 12:18:48 -0700112 static const char kTestMACAddress[];
113 static const char kTestIPAddress0[];
114 static const int kTestIPAddressPrefix0;
115 static const char kTestIPAddress1[];
116 static const int kTestIPAddressPrefix1;
117 static const char kTestIPAddress2[];
118 static const char kTestIPAddress3[];
119 static const char kTestIPAddress4[];
Paul Stewart05a42c22012-08-02 16:47:21 -0700120 static const char kTestIPAddress5[];
Paul Stewart1ac4e842012-07-10 12:58:12 -0700121 static const int kReceiveByteCount;
122 static const int kTransmitByteCount;
Darin Petkov633ac6f2011-07-08 13:56:13 -0700123
Paul Stewart9a908082011-08-31 12:18:48 -0700124 RTNLMessage *BuildLinkMessage(RTNLMessage::Mode mode);
Paul Stewarte81eb702012-04-11 15:04:53 -0700125 RTNLMessage *BuildLinkMessageWithInterfaceName(RTNLMessage::Mode mode,
126 const string &interface_name);
Paul Stewart9a908082011-08-31 12:18:48 -0700127 RTNLMessage *BuildAddressMessage(RTNLMessage::Mode mode,
128 const IPAddress &address,
129 unsigned char flags,
130 unsigned char scope);
Chris Masone2aa97072011-08-09 17:35:08 -0700131 void SendMessageToDeviceInfo(const RTNLMessage &message);
Darin Petkov633ac6f2011-07-08 13:56:13 -0700132
Darin Petkovafa6fc42011-06-21 16:21:08 -0700133 MockGLib glib_;
Chris Masone46eaaf52011-05-24 13:08:30 -0700134 MockControl control_interface_;
Thieu Le3426c8f2012-01-11 17:35:11 -0800135 MockMetrics metrics_;
Paul Stewart9a908082011-08-31 12:18:48 -0700136 StrictMock<MockManager> manager_;
Chris Masone9be4a9d2011-05-16 15:44:09 -0700137 DeviceInfo device_info_;
Paul Stewart050cfc02012-07-06 20:38:54 -0700138 TestEventDispatcherForDeviceInfo dispatcher_;
Paul Stewart8c116a92012-05-02 18:30:03 -0700139 MockRoutingTable routing_table_;
Paul Stewart9a908082011-08-31 12:18:48 -0700140 StrictMock<MockRTNLHandler> rtnl_handler_;
Chris Masone9be4a9d2011-05-16 15:44:09 -0700141};
142
Chris Masoneb2e326b2011-07-12 13:28:51 -0700143const int DeviceInfoTest::kTestDeviceIndex = 123456;
Darin Petkov633ac6f2011-07-08 13:56:13 -0700144const char DeviceInfoTest::kTestDeviceName[] = "test-device";
Paul Stewart9a908082011-08-31 12:18:48 -0700145const char DeviceInfoTest::kTestMACAddress[] = {
Darin Petkove3e1cfa2011-08-11 13:41:17 -0700146 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff };
Paul Stewart9a908082011-08-31 12:18:48 -0700147const char DeviceInfoTest::kTestIPAddress0[] = "192.168.1.1";
148const int DeviceInfoTest::kTestIPAddressPrefix0 = 24;
149const char DeviceInfoTest::kTestIPAddress1[] = "fe80::1aa9:5ff:abcd:1234";
150const int DeviceInfoTest::kTestIPAddressPrefix1 = 64;
151const char DeviceInfoTest::kTestIPAddress2[] = "fe80::1aa9:5ff:abcd:1235";
152const char DeviceInfoTest::kTestIPAddress3[] = "fe80::1aa9:5ff:abcd:1236";
153const char DeviceInfoTest::kTestIPAddress4[] = "fe80::1aa9:5ff:abcd:1237";
Paul Stewart05a42c22012-08-02 16:47:21 -0700154const char DeviceInfoTest::kTestIPAddress5[] = "192.168.1.2";
Paul Stewart1ac4e842012-07-10 12:58:12 -0700155const int DeviceInfoTest::kReceiveByteCount = 1234;
156const int DeviceInfoTest::kTransmitByteCount = 5678;
Chris Masone9be4a9d2011-05-16 15:44:09 -0700157
Paul Stewarte81eb702012-04-11 15:04:53 -0700158RTNLMessage *DeviceInfoTest::BuildLinkMessageWithInterfaceName(
159 RTNLMessage::Mode mode, const string &interface_name) {
Paul Stewart9a908082011-08-31 12:18:48 -0700160 RTNLMessage *message = new RTNLMessage(
161 RTNLMessage::kTypeLink,
162 mode,
163 0,
164 0,
165 0,
166 kTestDeviceIndex,
Paul Stewart7355ce12011-09-02 10:47:01 -0700167 IPAddress::kFamilyIPv4);
Chris Masone2aa97072011-08-09 17:35:08 -0700168 message->SetAttribute(static_cast<uint16>(IFLA_IFNAME),
Paul Stewarte81eb702012-04-11 15:04:53 -0700169 ByteString(interface_name, true));
Paul Stewart9a908082011-08-31 12:18:48 -0700170 ByteString test_address(kTestMACAddress, sizeof(kTestMACAddress));
Chris Masone626719f2011-08-18 16:58:48 -0700171 message->SetAttribute(IFLA_ADDRESS, test_address);
Chris Masone2aa97072011-08-09 17:35:08 -0700172 return message;
Darin Petkov633ac6f2011-07-08 13:56:13 -0700173}
174
Paul Stewarte81eb702012-04-11 15:04:53 -0700175RTNLMessage *DeviceInfoTest::BuildLinkMessage(RTNLMessage::Mode mode) {
176 return BuildLinkMessageWithInterfaceName(mode, kTestDeviceName);
177}
178
Paul Stewart9a908082011-08-31 12:18:48 -0700179RTNLMessage *DeviceInfoTest::BuildAddressMessage(RTNLMessage::Mode mode,
180 const IPAddress &address,
181 unsigned char flags,
182 unsigned char scope) {
183 RTNLMessage *message = new RTNLMessage(
184 RTNLMessage::kTypeAddress,
185 mode,
186 0,
187 0,
188 0,
189 kTestDeviceIndex,
190 address.family());
191 message->SetAttribute(IFA_ADDRESS, address.address());
192 message->set_address_status(
193 RTNLMessage::AddressStatus(address.prefix(), flags, scope));
194 return message;
195}
196
Chris Masone2aa97072011-08-09 17:35:08 -0700197void DeviceInfoTest::SendMessageToDeviceInfo(const RTNLMessage &message) {
Paul Stewart9a908082011-08-31 12:18:48 -0700198 if (message.type() == RTNLMessage::kTypeLink) {
199 device_info_.LinkMsgHandler(message);
200 } else if (message.type() == RTNLMessage::kTypeAddress) {
201 device_info_.AddressMsgHandler(message);
202 } else {
203 NOTREACHED();
204 }
205}
206
207MATCHER_P(IsIPAddress, address, "") {
208 // NB: IPAddress objects don't support the "==" operator as per style, so
209 // we need a custom matcher.
210 return address.Equals(arg);
Darin Petkov633ac6f2011-07-08 13:56:13 -0700211}
212
Paul Stewart8c116a92012-05-02 18:30:03 -0700213TEST_F(DeviceInfoTest, StartStop) {
214 EXPECT_FALSE(device_info_.link_listener_.get());
215 EXPECT_FALSE(device_info_.address_listener_.get());
216 EXPECT_TRUE(device_info_.infos_.empty());
217
218 EXPECT_CALL(rtnl_handler_, RequestDump(RTNLHandler::kRequestLink |
219 RTNLHandler::kRequestAddr));
Paul Stewart1ac4e842012-07-10 12:58:12 -0700220 EXPECT_CALL(dispatcher_, PostDelayedTask(
221 _, GetRequestLinkStatisticsIntervalMilliseconds()));
Chris Masone9be4a9d2011-05-16 15:44:09 -0700222 device_info_.Start();
Paul Stewart8c116a92012-05-02 18:30:03 -0700223 EXPECT_TRUE(device_info_.link_listener_.get());
224 EXPECT_TRUE(device_info_.address_listener_.get());
225 EXPECT_TRUE(device_info_.infos_.empty());
226 Mock::VerifyAndClearExpectations(&rtnl_handler_);
227
228 CreateInterfaceAddress();
229 EXPECT_FALSE(device_info_.infos_.empty());
230
231 device_info_.Stop();
232 EXPECT_FALSE(device_info_.link_listener_.get());
233 EXPECT_FALSE(device_info_.address_listener_.get());
234 EXPECT_TRUE(device_info_.infos_.empty());
235}
236
Paul Stewart1ac4e842012-07-10 12:58:12 -0700237TEST_F(DeviceInfoTest, RequestLinkStatistics) {
238 EXPECT_CALL(rtnl_handler_, RequestDump(RTNLHandler::kRequestLink));
239 EXPECT_CALL(dispatcher_, PostDelayedTask(
240 _, GetRequestLinkStatisticsIntervalMilliseconds()));
241 device_info_.RequestLinkStatistics();
242}
243
Paul Stewart8c116a92012-05-02 18:30:03 -0700244TEST_F(DeviceInfoTest, DeviceEnumeration) {
Paul Stewart9a908082011-08-31 12:18:48 -0700245 scoped_ptr<RTNLMessage> message(BuildLinkMessage(RTNLMessage::kModeAdd));
Darin Petkove6193c02011-08-11 12:42:40 -0700246 message->set_link_status(RTNLMessage::LinkStatus(0, IFF_LOWER_UP, 0));
247 EXPECT_FALSE(device_info_.GetDevice(kTestDeviceIndex).get());
Darin Petkovf8046b82012-04-24 16:29:23 +0200248 EXPECT_EQ(-1, device_info_.GetIndex(kTestDeviceName));
Darin Petkove6193c02011-08-11 12:42:40 -0700249 SendMessageToDeviceInfo(*message);
250 EXPECT_TRUE(device_info_.GetDevice(kTestDeviceIndex).get());
251 unsigned int flags = 0;
252 EXPECT_TRUE(device_info_.GetFlags(kTestDeviceIndex, &flags));
253 EXPECT_EQ(IFF_LOWER_UP, flags);
Darin Petkove3e1cfa2011-08-11 13:41:17 -0700254 ByteString address;
Paul Stewart32852962011-08-30 14:06:53 -0700255 EXPECT_TRUE(device_info_.GetMACAddress(kTestDeviceIndex, &address));
Darin Petkove3e1cfa2011-08-11 13:41:17 -0700256 EXPECT_FALSE(address.IsEmpty());
Paul Stewart9a908082011-08-31 12:18:48 -0700257 EXPECT_TRUE(address.Equals(ByteString(kTestMACAddress,
258 sizeof(kTestMACAddress))));
Darin Petkovf8046b82012-04-24 16:29:23 +0200259 EXPECT_EQ(kTestDeviceIndex, device_info_.GetIndex(kTestDeviceName));
Paul Stewarta3c56f92011-05-26 07:08:52 -0700260
Paul Stewart9a908082011-08-31 12:18:48 -0700261 message.reset(BuildLinkMessage(RTNLMessage::kModeAdd));
Darin Petkove6193c02011-08-11 12:42:40 -0700262 message->set_link_status(RTNLMessage::LinkStatus(0, IFF_UP | IFF_RUNNING, 0));
263 SendMessageToDeviceInfo(*message);
264 EXPECT_TRUE(device_info_.GetFlags(kTestDeviceIndex, &flags));
265 EXPECT_EQ(IFF_UP | IFF_RUNNING, flags);
Paul Stewartb50f0b92011-05-16 16:31:42 -0700266
Paul Stewart9a908082011-08-31 12:18:48 -0700267 message.reset(BuildLinkMessage(RTNLMessage::kModeDelete));
Paul Stewart8c116a92012-05-02 18:30:03 -0700268 EXPECT_CALL(manager_, DeregisterDevice(_)).Times(1);
Darin Petkove6193c02011-08-11 12:42:40 -0700269 SendMessageToDeviceInfo(*message);
270 EXPECT_FALSE(device_info_.GetDevice(kTestDeviceIndex).get());
271 EXPECT_FALSE(device_info_.GetFlags(kTestDeviceIndex, NULL));
Darin Petkovf8046b82012-04-24 16:29:23 +0200272 EXPECT_EQ(-1, device_info_.GetIndex(kTestDeviceName));
Paul Stewart8c116a92012-05-02 18:30:03 -0700273}
Paul Stewarta3c56f92011-05-26 07:08:52 -0700274
Paul Stewart1ac4e842012-07-10 12:58:12 -0700275TEST_F(DeviceInfoTest, GetByteCounts) {
276 uint64 rx_bytes, tx_bytes;
277 EXPECT_FALSE(device_info_.GetByteCounts(
278 kTestDeviceIndex, &rx_bytes, &tx_bytes));
279
280 // No link statistics in the message.
281 scoped_ptr<RTNLMessage> message(BuildLinkMessage(RTNLMessage::kModeAdd));
282 SendMessageToDeviceInfo(*message);
283 EXPECT_TRUE(device_info_.GetByteCounts(
284 kTestDeviceIndex, &rx_bytes, &tx_bytes));
285 EXPECT_EQ(0, rx_bytes);
286 EXPECT_EQ(0, tx_bytes);
287
288 // Short link statistics message.
289 message.reset(BuildLinkMessage(RTNLMessage::kModeAdd));
290 struct rtnl_link_stats64 stats;
291 memset(&stats, 0, sizeof(stats));
292 stats.rx_bytes = kReceiveByteCount;
293 stats.tx_bytes = kTransmitByteCount;
294 ByteString stats_bytes0(reinterpret_cast<const unsigned char*>(&stats),
295 sizeof(stats) - 1);
296 message->SetAttribute(IFLA_STATS64, stats_bytes0);
297 SendMessageToDeviceInfo(*message);
298 EXPECT_TRUE(device_info_.GetByteCounts(
299 kTestDeviceIndex, &rx_bytes, &tx_bytes));
300 EXPECT_EQ(0, rx_bytes);
301 EXPECT_EQ(0, tx_bytes);
302
303 // Correctly sized link statistics message.
304 message.reset(BuildLinkMessage(RTNLMessage::kModeAdd));
305 ByteString stats_bytes1(reinterpret_cast<const unsigned char*>(&stats),
306 sizeof(stats));
307 message->SetAttribute(IFLA_STATS64, stats_bytes1);
308 SendMessageToDeviceInfo(*message);
309 EXPECT_TRUE(device_info_.GetByteCounts(
310 kTestDeviceIndex, &rx_bytes, &tx_bytes));
311 EXPECT_EQ(kReceiveByteCount, rx_bytes);
312 EXPECT_EQ(kTransmitByteCount, tx_bytes);
313}
314
Paul Stewart8c116a92012-05-02 18:30:03 -0700315TEST_F(DeviceInfoTest, CreateDeviceCellular) {
316 IPAddress address = CreateInterfaceAddress();
317
318 // A cellular device should be offered to ModemInfo.
319 StrictMock<MockModemInfo> modem_info;
320 EXPECT_CALL(manager_, modem_info()).WillOnce(Return(&modem_info));
321 EXPECT_CALL(modem_info, OnDeviceInfoAvailable(kTestDeviceName)).Times(1);
322 EXPECT_CALL(routing_table_, FlushRoutes(kTestDeviceIndex)).Times(1);
323 EXPECT_CALL(rtnl_handler_, RemoveInterfaceAddress(kTestDeviceIndex,
324 IsIPAddress(address)));
325 EXPECT_FALSE(CreateDevice(
326 kTestDeviceName, "address", kTestDeviceIndex, Technology::kCellular));
327}
328
Darin Petkove4b27022012-05-16 13:28:50 +0200329TEST_F(DeviceInfoTest, CreateDeviceWiMax) {
330 IPAddress address = CreateInterfaceAddress();
331
332 // A WiMax device should be offered to WiMaxProvider.
333 StrictMock<MockWiMaxProvider> wimax_provider;
334 EXPECT_CALL(manager_, wimax_provider()).WillOnce(Return(&wimax_provider));
335 EXPECT_CALL(wimax_provider, OnDeviceInfoAvailable(kTestDeviceName)).Times(1);
336 EXPECT_CALL(routing_table_, FlushRoutes(kTestDeviceIndex)).Times(1);
337 EXPECT_CALL(rtnl_handler_, RemoveInterfaceAddress(kTestDeviceIndex,
338 IsIPAddress(address)));
339 EXPECT_FALSE(CreateDevice(
340 kTestDeviceName, "address", kTestDeviceIndex, Technology::kWiMax));
341}
342
Paul Stewart8c116a92012-05-02 18:30:03 -0700343TEST_F(DeviceInfoTest, CreateDeviceEthernet) {
344 IPAddress address = CreateInterfaceAddress();
345
346 // An Ethernet device should cause routes and addresses to be flushed.
347 EXPECT_CALL(routing_table_, FlushRoutes(kTestDeviceIndex)).Times(1);
348 EXPECT_CALL(rtnl_handler_, RemoveInterfaceAddress(kTestDeviceIndex,
349 IsIPAddress(address)));
350 DeviceRefPtr device = CreateDevice(
351 kTestDeviceName, "address", kTestDeviceIndex, Technology::kEthernet);
352 EXPECT_TRUE(device);
353 Mock::VerifyAndClearExpectations(&routing_table_);
354 Mock::VerifyAndClearExpectations(&rtnl_handler_);
355
356 // The Ethernet device destructor notifies the manager.
357 EXPECT_CALL(manager_, UpdateEnabledTechnologies()).Times(1);
358 device = NULL;
359}
360
361TEST_F(DeviceInfoTest, CreateDeviceVirtioEthernet) {
362 IPAddress address = CreateInterfaceAddress();
363
364 // VirtioEthernet is identical to Ethernet from the perspective of this test.
365 EXPECT_CALL(routing_table_, FlushRoutes(kTestDeviceIndex)).Times(1);
366 EXPECT_CALL(rtnl_handler_, RemoveInterfaceAddress(kTestDeviceIndex,
367 IsIPAddress(address)));
368 DeviceRefPtr device = CreateDevice(
369 kTestDeviceName, "address", kTestDeviceIndex,
370 Technology::kVirtioEthernet);
371 EXPECT_TRUE(device);
372 Mock::VerifyAndClearExpectations(&routing_table_);
373 Mock::VerifyAndClearExpectations(&rtnl_handler_);
374
375 // The Ethernet device destructor notifies the manager.
376 EXPECT_CALL(manager_, UpdateEnabledTechnologies()).Times(1);
377 device = NULL;
378}
379
380TEST_F(DeviceInfoTest, CreateDeviceWiFi) {
381 IPAddress address = CreateInterfaceAddress();
382
383 // WiFi looks a lot like Ethernet too.
384 EXPECT_CALL(routing_table_, FlushRoutes(kTestDeviceIndex)).Times(1);
385 EXPECT_CALL(rtnl_handler_, RemoveInterfaceAddress(kTestDeviceIndex,
386 IsIPAddress(address)));
387 EXPECT_TRUE(CreateDevice(
388 kTestDeviceName, "address", kTestDeviceIndex, Technology::kWifi));
389}
390
391TEST_F(DeviceInfoTest, CreateDeviceTunnelAccepted) {
392 IPAddress address = CreateInterfaceAddress();
393
394 // A VPN device should be offered to VPNProvider.
395 StrictMock<MockVPNProvider> vpn_provider;
396 EXPECT_CALL(manager_, vpn_provider()).WillOnce(Return(&vpn_provider));
397 EXPECT_CALL(vpn_provider,
398 OnDeviceInfoAvailable(kTestDeviceName, kTestDeviceIndex))
399 .WillOnce(Return(true));
400 EXPECT_CALL(routing_table_, FlushRoutes(kTestDeviceIndex)).Times(1);
401 EXPECT_CALL(rtnl_handler_, RemoveInterfaceAddress(kTestDeviceIndex,
402 IsIPAddress(address)));
403 EXPECT_CALL(rtnl_handler_, RemoveInterface(_)).Times(0);
404 EXPECT_FALSE(CreateDevice(
405 kTestDeviceName, "address", kTestDeviceIndex, Technology::kTunnel));
406}
407
408TEST_F(DeviceInfoTest, CreateDeviceTunnelRejected) {
409 IPAddress address = CreateInterfaceAddress();
410
411 // A VPN device should be offered to VPNProvider.
412 StrictMock<MockVPNProvider> vpn_provider;
413 EXPECT_CALL(manager_, vpn_provider()).WillOnce(Return(&vpn_provider));
414 EXPECT_CALL(vpn_provider,
415 OnDeviceInfoAvailable(kTestDeviceName, kTestDeviceIndex))
416 .WillOnce(Return(false));
417 EXPECT_CALL(routing_table_, FlushRoutes(kTestDeviceIndex)).Times(1);
418 EXPECT_CALL(rtnl_handler_, RemoveInterfaceAddress(kTestDeviceIndex,
419 IsIPAddress(address)));
420 // Since the device was rejected by the VPNProvider, DeviceInfo will
421 // remove the interface.
422 EXPECT_CALL(rtnl_handler_, RemoveInterface(kTestDeviceIndex)).Times(1);
423 EXPECT_FALSE(CreateDevice(
424 kTestDeviceName, "address", kTestDeviceIndex, Technology::kTunnel));
425}
426
427TEST_F(DeviceInfoTest, CreateDevicePPP) {
428 IPAddress address = CreateInterfaceAddress();
429
430 // A VPN device should be offered to VPNProvider.
431 StrictMock<MockVPNProvider> vpn_provider;
432 EXPECT_CALL(manager_, vpn_provider()).WillOnce(Return(&vpn_provider));
433 EXPECT_CALL(vpn_provider,
434 OnDeviceInfoAvailable(kTestDeviceName, kTestDeviceIndex))
435 .WillOnce(Return(false));
436 EXPECT_CALL(routing_table_, FlushRoutes(kTestDeviceIndex)).Times(1);
437 EXPECT_CALL(rtnl_handler_, RemoveInterfaceAddress(kTestDeviceIndex,
438 IsIPAddress(address)));
439 // We do not remove PPP interfaces even if the provider does not accept it.
440 EXPECT_CALL(rtnl_handler_, RemoveInterface(_)).Times(0);
441 EXPECT_FALSE(CreateDevice(
442 kTestDeviceName, "address", kTestDeviceIndex, Technology::kPPP));
443}
444
445TEST_F(DeviceInfoTest, CreateDeviceLoopback) {
446 // A loopback device should be brought up, and nothing else done to it.
447 EXPECT_CALL(routing_table_, FlushRoutes(_)).Times(0);
448 EXPECT_CALL(rtnl_handler_, RemoveInterfaceAddress(_, _)).Times(0);
449 EXPECT_CALL(rtnl_handler_,
450 SetInterfaceFlags(kTestDeviceIndex, IFF_UP, IFF_UP)).Times(1);
451 EXPECT_FALSE(CreateDevice(
452 kTestDeviceName, "address", kTestDeviceIndex, Technology::kLoopback));
453}
454
Paul Stewart050cfc02012-07-06 20:38:54 -0700455TEST_F(DeviceInfoTest, CreateDeviceCDCEthernet) {
456 // A cdc_ether device should be postponed to a task.
457 EXPECT_CALL(manager_, modem_info()).Times(0);
458 EXPECT_CALL(routing_table_, FlushRoutes(_)).Times(0);
459 EXPECT_CALL(rtnl_handler_, RemoveInterfaceAddress(_, _)).Times(0);
460 EXPECT_CALL(dispatcher_,
Paul Stewart1ac4e842012-07-10 12:58:12 -0700461 PostDelayedTask(_, GetDelayedDeviceCreationMilliseconds()));
Paul Stewart050cfc02012-07-06 20:38:54 -0700462 EXPECT_TRUE(GetDelayedDevices().empty());
463 EXPECT_FALSE(CreateDevice(
464 kTestDeviceName, "address", kTestDeviceIndex, Technology::kCDCEthernet));
465 EXPECT_FALSE(GetDelayedDevices().empty());
466 EXPECT_EQ(1, GetDelayedDevices().size());
467 EXPECT_EQ(kTestDeviceIndex, *GetDelayedDevices().begin());
468}
469
Paul Stewart8c116a92012-05-02 18:30:03 -0700470TEST_F(DeviceInfoTest, CreateDeviceUnknown) {
471 IPAddress address = CreateInterfaceAddress();
472
473 // An unknown (blacklisted, unhandled, etc) device won't be flushed or
474 // registered.
475 EXPECT_CALL(routing_table_, FlushRoutes(_)).Times(0);
476 EXPECT_CALL(rtnl_handler_, RemoveInterfaceAddress(_, _)).Times(0);
477 EXPECT_TRUE(CreateDevice(
478 kTestDeviceName, "address", kTestDeviceIndex, Technology::kUnknown));
Chris Masone9be4a9d2011-05-16 15:44:09 -0700479}
480
mukesh agrawal8f317b62011-07-15 11:53:23 -0700481TEST_F(DeviceInfoTest, DeviceBlackList) {
482 device_info_.AddDeviceToBlackList(kTestDeviceName);
Paul Stewart9a908082011-08-31 12:18:48 -0700483 scoped_ptr<RTNLMessage> message(BuildLinkMessage(RTNLMessage::kModeAdd));
Darin Petkove6193c02011-08-11 12:42:40 -0700484 SendMessageToDeviceInfo(*message);
mukesh agrawal8f317b62011-07-15 11:53:23 -0700485
Darin Petkove6193c02011-08-11 12:42:40 -0700486 DeviceRefPtr device = device_info_.GetDevice(kTestDeviceIndex);
487 ASSERT_TRUE(device.get());
Joshua Krollda798622012-06-05 12:30:48 -0700488 EXPECT_TRUE(device->technology() == Technology::kBlacklisted);
mukesh agrawal8f317b62011-07-15 11:53:23 -0700489}
490
Paul Stewart9a908082011-08-31 12:18:48 -0700491TEST_F(DeviceInfoTest, DeviceAddressList) {
Paul Stewart9a908082011-08-31 12:18:48 -0700492 scoped_ptr<RTNLMessage> message(BuildLinkMessage(RTNLMessage::kModeAdd));
493 SendMessageToDeviceInfo(*message);
494
495 vector<DeviceInfo::AddressData> addresses;
496 EXPECT_TRUE(device_info_.GetAddresses(kTestDeviceIndex, &addresses));
497 EXPECT_TRUE(addresses.empty());
498
499 // Add an address to the device address list
Paul Stewart7355ce12011-09-02 10:47:01 -0700500 IPAddress ip_address0(IPAddress::kFamilyIPv4);
Paul Stewart9a908082011-08-31 12:18:48 -0700501 EXPECT_TRUE(ip_address0.SetAddressFromString(kTestIPAddress0));
502 ip_address0.set_prefix(kTestIPAddressPrefix0);
503 message.reset(BuildAddressMessage(RTNLMessage::kModeAdd, ip_address0, 0, 0));
504 SendMessageToDeviceInfo(*message);
505 EXPECT_TRUE(device_info_.GetAddresses(kTestDeviceIndex, &addresses));
506 EXPECT_EQ(1, addresses.size());
507 EXPECT_TRUE(ip_address0.Equals(addresses[0].address));
508
509 // Re-adding the same address shouldn't cause the address list to change
510 SendMessageToDeviceInfo(*message);
511 EXPECT_TRUE(device_info_.GetAddresses(kTestDeviceIndex, &addresses));
512 EXPECT_EQ(1, addresses.size());
513 EXPECT_TRUE(ip_address0.Equals(addresses[0].address));
514
515 // Adding a new address should expand the list
Paul Stewart7355ce12011-09-02 10:47:01 -0700516 IPAddress ip_address1(IPAddress::kFamilyIPv6);
Paul Stewart9a908082011-08-31 12:18:48 -0700517 EXPECT_TRUE(ip_address1.SetAddressFromString(kTestIPAddress1));
518 ip_address1.set_prefix(kTestIPAddressPrefix1);
519 message.reset(BuildAddressMessage(RTNLMessage::kModeAdd, ip_address1, 0, 0));
520 SendMessageToDeviceInfo(*message);
521 EXPECT_TRUE(device_info_.GetAddresses(kTestDeviceIndex, &addresses));
522 EXPECT_EQ(2, addresses.size());
523 EXPECT_TRUE(ip_address0.Equals(addresses[0].address));
524 EXPECT_TRUE(ip_address1.Equals(addresses[1].address));
525
526 // Deleting an address should reduce the list
527 message.reset(BuildAddressMessage(RTNLMessage::kModeDelete,
528 ip_address0,
529 0,
530 0));
531 SendMessageToDeviceInfo(*message);
532 EXPECT_TRUE(device_info_.GetAddresses(kTestDeviceIndex, &addresses));
533 EXPECT_EQ(1, addresses.size());
534 EXPECT_TRUE(ip_address1.Equals(addresses[0].address));
535
536 // Delete last item
537 message.reset(BuildAddressMessage(RTNLMessage::kModeDelete,
538 ip_address1,
539 0,
540 0));
541 SendMessageToDeviceInfo(*message);
542 EXPECT_TRUE(device_info_.GetAddresses(kTestDeviceIndex, &addresses));
543 EXPECT_TRUE(addresses.empty());
544
545 // Delete device
546 message.reset(BuildLinkMessage(RTNLMessage::kModeDelete));
Paul Stewart8c116a92012-05-02 18:30:03 -0700547 EXPECT_CALL(manager_, DeregisterDevice(_)).Times(1);
Paul Stewart9a908082011-08-31 12:18:48 -0700548 SendMessageToDeviceInfo(*message);
549
550 // Should be able to handle message for interface that doesn't exist
551 message.reset(BuildAddressMessage(RTNLMessage::kModeAdd, ip_address0, 0, 0));
552 SendMessageToDeviceInfo(*message);
553 EXPECT_FALSE(device_info_.GetDevice(kTestDeviceIndex).get());
Paul Stewart9a908082011-08-31 12:18:48 -0700554}
555
556TEST_F(DeviceInfoTest, FlushAddressList) {
Paul Stewart9a908082011-08-31 12:18:48 -0700557 scoped_ptr<RTNLMessage> message(BuildLinkMessage(RTNLMessage::kModeAdd));
558 SendMessageToDeviceInfo(*message);
559
Paul Stewart7355ce12011-09-02 10:47:01 -0700560 IPAddress address1(IPAddress::kFamilyIPv6);
Paul Stewart9a908082011-08-31 12:18:48 -0700561 EXPECT_TRUE(address1.SetAddressFromString(kTestIPAddress1));
562 address1.set_prefix(kTestIPAddressPrefix1);
563 message.reset(BuildAddressMessage(RTNLMessage::kModeAdd,
564 address1,
565 0,
566 RT_SCOPE_UNIVERSE));
567 SendMessageToDeviceInfo(*message);
Paul Stewart7355ce12011-09-02 10:47:01 -0700568 IPAddress address2(IPAddress::kFamilyIPv6);
Paul Stewart9a908082011-08-31 12:18:48 -0700569 EXPECT_TRUE(address2.SetAddressFromString(kTestIPAddress2));
570 message.reset(BuildAddressMessage(RTNLMessage::kModeAdd,
571 address2,
572 IFA_F_TEMPORARY,
573 RT_SCOPE_UNIVERSE));
574 SendMessageToDeviceInfo(*message);
Paul Stewart7355ce12011-09-02 10:47:01 -0700575 IPAddress address3(IPAddress::kFamilyIPv6);
Paul Stewart9a908082011-08-31 12:18:48 -0700576 EXPECT_TRUE(address3.SetAddressFromString(kTestIPAddress3));
577 message.reset(BuildAddressMessage(RTNLMessage::kModeAdd,
578 address3,
579 0,
580 RT_SCOPE_LINK));
581 SendMessageToDeviceInfo(*message);
Paul Stewart7355ce12011-09-02 10:47:01 -0700582 IPAddress address4(IPAddress::kFamilyIPv6);
Paul Stewart9a908082011-08-31 12:18:48 -0700583 EXPECT_TRUE(address4.SetAddressFromString(kTestIPAddress4));
584 message.reset(BuildAddressMessage(RTNLMessage::kModeAdd,
585 address4,
586 IFA_F_PERMANENT,
587 RT_SCOPE_UNIVERSE));
588 SendMessageToDeviceInfo(*message);
589
590 // DeviceInfo now has 4 addresses associated with it, but only two of
591 // them are valid for flush.
592 EXPECT_CALL(rtnl_handler_, RemoveInterfaceAddress(kTestDeviceIndex,
593 IsIPAddress(address1)));
594 EXPECT_CALL(rtnl_handler_, RemoveInterfaceAddress(kTestDeviceIndex,
595 IsIPAddress(address2)));
596 device_info_.FlushAddresses(kTestDeviceIndex);
Paul Stewart9a908082011-08-31 12:18:48 -0700597}
598
Paul Stewart05a42c22012-08-02 16:47:21 -0700599TEST_F(DeviceInfoTest, HasOtherAddress) {
600 scoped_ptr<RTNLMessage> message(BuildLinkMessage(RTNLMessage::kModeAdd));
601 SendMessageToDeviceInfo(*message);
602
603 IPAddress address0(IPAddress::kFamilyIPv4);
604 EXPECT_TRUE(address0.SetAddressFromString(kTestIPAddress0));
605
606 // There are no addresses on this interface.
607 EXPECT_FALSE(device_info_.HasOtherAddress(kTestDeviceIndex, address0));
608
609 message.reset(BuildAddressMessage(RTNLMessage::kModeAdd,
610 address0,
611 0,
612 RT_SCOPE_UNIVERSE));
613 SendMessageToDeviceInfo(*message);
614
615 IPAddress address1(IPAddress::kFamilyIPv6);
616 EXPECT_TRUE(address1.SetAddressFromString(kTestIPAddress1));
617 address1.set_prefix(kTestIPAddressPrefix1);
618 message.reset(BuildAddressMessage(RTNLMessage::kModeAdd,
619 address1,
620 0,
621 RT_SCOPE_LINK));
622 SendMessageToDeviceInfo(*message);
623
624 IPAddress address2(IPAddress::kFamilyIPv6);
625 EXPECT_TRUE(address2.SetAddressFromString(kTestIPAddress2));
626 message.reset(BuildAddressMessage(RTNLMessage::kModeAdd,
627 address2,
628 IFA_F_TEMPORARY,
629 RT_SCOPE_UNIVERSE));
630 SendMessageToDeviceInfo(*message);
631
632 IPAddress address3(IPAddress::kFamilyIPv6);
633 EXPECT_TRUE(address3.SetAddressFromString(kTestIPAddress3));
634
635 // The only IPv6 addresses on this interface are either flagged as
636 // temporary, or they are not universally scoped.
637 EXPECT_FALSE(device_info_.HasOtherAddress(kTestDeviceIndex, address3));
638
639
640 message.reset(BuildAddressMessage(RTNLMessage::kModeAdd,
641 address3,
642 0,
643 RT_SCOPE_UNIVERSE));
644 SendMessageToDeviceInfo(*message);
645
646 // address0 is on this interface.
647 EXPECT_FALSE(device_info_.HasOtherAddress(kTestDeviceIndex, address0));
648 // address1 is on this interface.
649 EXPECT_FALSE(device_info_.HasOtherAddress(kTestDeviceIndex, address1));
650 // address2 is on this interface.
651 EXPECT_FALSE(device_info_.HasOtherAddress(kTestDeviceIndex, address2));
652 // address3 is on this interface.
653 EXPECT_FALSE(device_info_.HasOtherAddress(kTestDeviceIndex, address3));
654
655 IPAddress address4(IPAddress::kFamilyIPv6);
656 EXPECT_TRUE(address4.SetAddressFromString(kTestIPAddress4));
657
658 // address4 is not on this interface, but address3 is, and is a qualified
659 // IPv6 address.
660 EXPECT_TRUE(device_info_.HasOtherAddress(kTestDeviceIndex, address4));
661
662 message.reset(BuildAddressMessage(RTNLMessage::kModeAdd,
663 address4,
664 IFA_F_PERMANENT,
665 RT_SCOPE_UNIVERSE));
666 SendMessageToDeviceInfo(*message);
667
668 // address4 is now on this interface.
669 EXPECT_FALSE(device_info_.HasOtherAddress(kTestDeviceIndex, address4));
670
671 IPAddress address5(IPAddress::kFamilyIPv4);
672 EXPECT_TRUE(address5.SetAddressFromString(kTestIPAddress5));
673 // address5 is not on this interface, but address0 is.
674 EXPECT_TRUE(device_info_.HasOtherAddress(kTestDeviceIndex, address5));
675
676 message.reset(BuildAddressMessage(RTNLMessage::kModeAdd,
677 address5,
678 IFA_F_PERMANENT,
679 RT_SCOPE_UNIVERSE));
680 SendMessageToDeviceInfo(*message);
681
682 // address5 is now on this interface.
683 EXPECT_FALSE(device_info_.HasOtherAddress(kTestDeviceIndex, address5));
684}
685
Thieu Leb27beee2012-04-20 09:19:06 -0700686TEST_F(DeviceInfoTest, HasSubdir) {
Thieu Le8f1c8352012-04-16 11:02:12 -0700687 ScopedTempDir temp_dir;
688 EXPECT_TRUE(temp_dir.CreateUniqueTempDir());
Thieu Leb27beee2012-04-20 09:19:06 -0700689 EXPECT_TRUE(file_util::CreateDirectory(temp_dir.path().Append("child1")));
690 FilePath child2 = temp_dir.path().Append("child2");
691 EXPECT_TRUE(file_util::CreateDirectory(child2));
692 FilePath grandchild = child2.Append("grandchild");
Thieu Le8f1c8352012-04-16 11:02:12 -0700693 EXPECT_TRUE(file_util::CreateDirectory(grandchild));
694 EXPECT_TRUE(file_util::CreateDirectory(grandchild.Append("greatgrandchild")));
Thieu Leb27beee2012-04-20 09:19:06 -0700695 EXPECT_TRUE(DeviceInfo::HasSubdir(temp_dir.path(),
696 FilePath("grandchild")));
697 EXPECT_TRUE(DeviceInfo::HasSubdir(temp_dir.path(),
698 FilePath("greatgrandchild")));
699 EXPECT_FALSE(DeviceInfo::HasSubdir(temp_dir.path(),
700 FilePath("nonexistent")));
Thieu Le8f1c8352012-04-16 11:02:12 -0700701}
702
Paul Stewartca876ee2012-04-21 08:55:58 -0700703class DeviceInfoTechnologyTest : public DeviceInfoTest {
704 public:
Jason Glasgowabc54032012-04-20 16:08:32 -0400705 DeviceInfoTechnologyTest()
706 : DeviceInfoTest(),
707 test_device_name_(kTestDeviceName) {}
Paul Stewartca876ee2012-04-21 08:55:58 -0700708 virtual ~DeviceInfoTechnologyTest() {}
709
710 virtual void SetUp() {
711 temp_dir_.CreateUniqueTempDir();
712 device_info_root_ = temp_dir_.path().Append("sys/class/net");
713 device_info_.device_info_root_ = device_info_root_;
714 // Most tests require that the uevent file exist.
715 CreateInfoFile("uevent", "xxx");
716 }
717
718 Technology::Identifier GetDeviceTechnology() {
Jason Glasgowabc54032012-04-20 16:08:32 -0400719 return device_info_.GetDeviceTechnology(test_device_name_);
Paul Stewartca876ee2012-04-21 08:55:58 -0700720 }
721 FilePath GetInfoPath(const string &name);
722 void CreateInfoFile(const string &name, const string &contents);
723 void CreateInfoSymLink(const string &name, const string &contents);
Jason Glasgowabc54032012-04-20 16:08:32 -0400724 void SetDeviceName(const string &name) {
725 test_device_name_ = name;
726 SetUp();
727 }
Paul Stewartca876ee2012-04-21 08:55:58 -0700728
729 protected:
730 ScopedTempDir temp_dir_;
731 FilePath device_info_root_;
Jason Glasgowabc54032012-04-20 16:08:32 -0400732 string test_device_name_;
Paul Stewartca876ee2012-04-21 08:55:58 -0700733};
734
735FilePath DeviceInfoTechnologyTest::GetInfoPath(const string &name) {
Jason Glasgowabc54032012-04-20 16:08:32 -0400736 return device_info_root_.Append(test_device_name_).Append(name);
Paul Stewartca876ee2012-04-21 08:55:58 -0700737}
738
739void DeviceInfoTechnologyTest::CreateInfoFile(const string &name,
740 const string &contents) {
741 FilePath info_path = GetInfoPath(name);
742 EXPECT_TRUE(file_util::CreateDirectory(info_path.DirName()));
743 string contents_newline(contents + "\n");
744 EXPECT_TRUE(file_util::WriteFile(info_path, contents_newline.c_str(),
745 contents_newline.size()));
746}
747
748void DeviceInfoTechnologyTest::CreateInfoSymLink(const string &name,
749 const string &contents) {
750 FilePath info_path = GetInfoPath(name);
Paul Stewartca876ee2012-04-21 08:55:58 -0700751 EXPECT_TRUE(file_util::CreateDirectory(info_path.DirName()));
752 EXPECT_TRUE(file_util::CreateSymbolicLink(FilePath(contents), info_path));
753}
754
755TEST_F(DeviceInfoTechnologyTest, Unknown) {
756 EXPECT_EQ(Technology::kUnknown, GetDeviceTechnology());
757 // Should still be unknown even without a uevent file.
758 EXPECT_TRUE(file_util::Delete(GetInfoPath("uevent"), FALSE));
759 EXPECT_EQ(Technology::kUnknown, GetDeviceTechnology());
760}
761
762TEST_F(DeviceInfoTechnologyTest, Loopback) {
763 CreateInfoFile("type", base::IntToString(ARPHRD_LOOPBACK));
764 EXPECT_EQ(Technology::kLoopback, GetDeviceTechnology());
765}
766
767TEST_F(DeviceInfoTechnologyTest, PPP) {
768 CreateInfoFile("type", base::IntToString(ARPHRD_PPP));
769 EXPECT_EQ(Technology::kPPP, GetDeviceTechnology());
770}
771
772TEST_F(DeviceInfoTechnologyTest, Tunnel) {
773 CreateInfoFile("tun_flags", base::IntToString(IFF_TUN));
774 EXPECT_EQ(Technology::kTunnel, GetDeviceTechnology());
775}
776
777TEST_F(DeviceInfoTechnologyTest, WiFi) {
778 CreateInfoFile("uevent", "DEVTYPE=wlan");
779 EXPECT_EQ(Technology::kWifi, GetDeviceTechnology());
780 CreateInfoFile("uevent", "foo\nDEVTYPE=wlan");
781 EXPECT_EQ(Technology::kWifi, GetDeviceTechnology());
782 CreateInfoFile("type", base::IntToString(ARPHRD_IEEE80211_RADIOTAP));
783 EXPECT_EQ(Technology::kWiFiMonitor, GetDeviceTechnology());
784}
785
786TEST_F(DeviceInfoTechnologyTest, Ethernet) {
787 CreateInfoSymLink("device/driver", "xxx");
788 EXPECT_EQ(Technology::kEthernet, GetDeviceTechnology());
789}
790
Darin Petkove4b27022012-05-16 13:28:50 +0200791TEST_F(DeviceInfoTechnologyTest, WiMax) {
792 CreateInfoSymLink("device/driver", "gdm_wimax");
793 EXPECT_EQ(Technology::kWiMax, GetDeviceTechnology());
794}
795
Paul Stewartca876ee2012-04-21 08:55:58 -0700796TEST_F(DeviceInfoTechnologyTest, CellularGobi1) {
797 CreateInfoSymLink("device/driver", "blah/foo/gobi");
798 EXPECT_EQ(Technology::kCellular, GetDeviceTechnology());
799}
800
801TEST_F(DeviceInfoTechnologyTest, CellularGobi2) {
802 CreateInfoSymLink("device/driver", "../GobiNet");
803 EXPECT_EQ(Technology::kCellular, GetDeviceTechnology());
804}
805
806TEST_F(DeviceInfoTechnologyTest, QCUSB) {
807 CreateInfoSymLink("device/driver", "QCUSBNet2k");
808 EXPECT_EQ(Technology::kCellular, GetDeviceTechnology());
809}
810
811// Modem with absolute driver path with top-level tty file:
812// /sys/class/net/dev0/device -> /sys/devices/virtual/0/00
813// /sys/devices/virtual/0/00/driver -> /drivers/cdc_ether
814// /sys/devices/virtual/0/01/tty [empty directory]
815TEST_F(DeviceInfoTechnologyTest, CDCEtherModem1) {
816 FilePath device_root(temp_dir_.path().Append("sys/devices/virtual/0"));
817 FilePath device_path(device_root.Append("00"));
818 EXPECT_TRUE(file_util::CreateDirectory(device_path));
819 CreateInfoSymLink("device", device_path.value());
820 EXPECT_TRUE(file_util::CreateSymbolicLink(FilePath("/drivers/cdc_ether"),
821 device_path.Append("driver")));
822 EXPECT_TRUE(file_util::CreateDirectory(device_root.Append("01/tty")));
823 EXPECT_EQ(Technology::kCellular, GetDeviceTechnology());
824}
825
826// Modem with relative driver path with top-level tty file.
827// /sys/class/net/dev0/device -> ../../../device_dir/0/00
828// /sys/device_dir/0/00/driver -> /drivers/cdc_ether
829// /sys/device_dir/0/01/tty [empty directory]
830TEST_F(DeviceInfoTechnologyTest, CDCEtherModem2) {
831 CreateInfoSymLink("device", "../../../device_dir/0/00");
832 FilePath device_root(temp_dir_.path().Append("sys/device_dir/0"));
833 FilePath device_path(device_root.Append("00"));
834 EXPECT_TRUE(file_util::CreateDirectory(device_path));
835 EXPECT_TRUE(file_util::CreateSymbolicLink(FilePath("/drivers/cdc_ether"),
836 device_path.Append("driver")));
837 EXPECT_TRUE(file_util::CreateDirectory(device_root.Append("01/tty")));
838 EXPECT_EQ(Technology::kCellular, GetDeviceTechnology());
839}
840
841// Modem with relative driver path with lower-level tty file.
842// /sys/class/net/dev0/device -> ../../../device_dir/0/00
843// /sys/device_dir/0/00/driver -> /drivers/cdc_ether
844// /sys/device_dir/0/01/yyy/tty [empty directory]
845TEST_F(DeviceInfoTechnologyTest, CDCEtherModem3) {
846 CreateInfoSymLink("device", "../../../device_dir/0/00");
847 FilePath device_root(temp_dir_.path().Append("sys/device_dir/0"));
848 FilePath device_path(device_root.Append("00"));
849 EXPECT_TRUE(file_util::CreateDirectory(device_path));
850 EXPECT_TRUE(file_util::CreateSymbolicLink(FilePath("/drivers/cdc_ether"),
851 device_path.Append("driver")));
852 EXPECT_TRUE(file_util::CreateDirectory(device_root.Append("01/yyy/tty")));
853 EXPECT_EQ(Technology::kCellular, GetDeviceTechnology());
854}
855
856TEST_F(DeviceInfoTechnologyTest, CDCEtherNonModem) {
857 CreateInfoSymLink("device", "device_dir");
858 CreateInfoSymLink("device_dir/driver", "cdc_ether");
Paul Stewart050cfc02012-07-06 20:38:54 -0700859 EXPECT_EQ(Technology::kCDCEthernet, GetDeviceTechnology());
Paul Stewartca876ee2012-04-21 08:55:58 -0700860}
861
Jason Glasgowabc54032012-04-20 16:08:32 -0400862TEST_F(DeviceInfoTechnologyTest, PseudoModem) {
863 SetDeviceName("pseudomodem");
864 CreateInfoSymLink("device", "device_dir");
865 CreateInfoSymLink("device_dir/driver", "cdc_ether");
866 EXPECT_EQ(Technology::kCellular, GetDeviceTechnology());
867
868 SetDeviceName("pseudomodem9");
869 CreateInfoSymLink("device", "device_dir");
870 CreateInfoSymLink("device_dir/driver", "cdc_ether");
871 EXPECT_EQ(Technology::kCellular, GetDeviceTechnology());
872}
873
Paul Stewart050cfc02012-07-06 20:38:54 -0700874class DeviceInfoForDelayedCreationTest : public DeviceInfo {
875 public:
876 DeviceInfoForDelayedCreationTest(ControlInterface *control_interface,
877 EventDispatcher *dispatcher,
878 Metrics *metrics,
879 Manager *manager)
880 : DeviceInfo(control_interface, dispatcher, metrics, manager) {}
881 MOCK_METHOD4(CreateDevice, DeviceRefPtr(const std::string &link_name,
882 const std::string &address,
883 int interface_index,
884 Technology::Identifier technology));
885 MOCK_METHOD1(GetDeviceTechnology,
886 Technology::Identifier(const string &iface_name));
887};
888
889class DeviceInfoDelayedCreationTest : public DeviceInfoTest {
890 public:
891 DeviceInfoDelayedCreationTest()
892 : DeviceInfoTest(),
893 test_device_info_(
894 &control_interface_, &dispatcher_, &metrics_, &manager_) {}
895 virtual ~DeviceInfoDelayedCreationTest() {}
896
897 virtual std::set<int> &GetDelayedDevices() {
898 return test_device_info_.delayed_devices_;
899 }
900
901 void DelayedDeviceCreationTask() {
902 test_device_info_.DelayedDeviceCreationTask();
903 }
904
905 void AddDelayedDevice() {
906 scoped_ptr<RTNLMessage> message(BuildLinkMessage(RTNLMessage::kModeAdd));
907 EXPECT_CALL(test_device_info_, GetDeviceTechnology(kTestDeviceName))
908 .WillOnce(Return(Technology::kCDCEthernet));
909 EXPECT_CALL(test_device_info_, CreateDevice(
910 kTestDeviceName, _, kTestDeviceIndex, Technology::kCDCEthernet))
911 .WillOnce(Return(DeviceRefPtr()));
912 test_device_info_.AddLinkMsgHandler(*message);
913 Mock::VerifyAndClearExpectations(&test_device_info_);
914 // We need to insert the device index ourselves since we have mocked
915 // out CreateDevice. This insertion is tested in CreateDeviceCDCEthernet
916 // above.
917 GetDelayedDevices().insert(kTestDeviceIndex);
918 }
919
920 protected:
921 DeviceInfoForDelayedCreationTest test_device_info_;
922};
923
924TEST_F(DeviceInfoDelayedCreationTest, NoDevices) {
925 EXPECT_TRUE(GetDelayedDevices().empty());
926 EXPECT_CALL(test_device_info_, GetDeviceTechnology(_)).Times(0);
927 DelayedDeviceCreationTask();
928}
929
930TEST_F(DeviceInfoDelayedCreationTest, EthernetDevice) {
931 AddDelayedDevice();
932 EXPECT_CALL(test_device_info_, GetDeviceTechnology(_))
933 .WillOnce(Return(Technology::kCDCEthernet));
934 EXPECT_CALL(test_device_info_, CreateDevice(
935 kTestDeviceName, _, kTestDeviceIndex, Technology::kEthernet))
936 .WillOnce(Return(DeviceRefPtr()));
937 DelayedDeviceCreationTask();
938 EXPECT_TRUE(GetDelayedDevices().empty());
939}
940
941TEST_F(DeviceInfoDelayedCreationTest, CellularDevice) {
942 AddDelayedDevice();
943 EXPECT_CALL(test_device_info_, GetDeviceTechnology(_))
944 .WillOnce(Return(Technology::kCellular));
945 EXPECT_CALL(test_device_info_, CreateDevice(
946 kTestDeviceName, _, kTestDeviceIndex, Technology::kCellular))
947 .WillOnce(Return(DeviceRefPtr()));
948 DelayedDeviceCreationTask();
949 EXPECT_TRUE(GetDelayedDevices().empty());
950}
951
Chris Masone9be4a9d2011-05-16 15:44:09 -0700952} // namespace shill