blob: fbdbd1d39cf8f2c9079e5b6bea0fc8994a795941 [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>
Gary Morain41780232012-07-31 15:08:31 -070013#include <linux/sockios.h>
Paul Stewartca876ee2012-04-21 08:55:58 -070014#include <net/if_arp.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[] = {
172 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
484 EXPECT_CALL(netlink_manager_,
485 SendMessage(IsGetInterfaceMessage(kTestDeviceIndex), _));
486 EXPECT_FALSE(CreateDevice(
Paul Stewart8c116a92012-05-02 18:30:03 -0700487 kTestDeviceName, "address", kTestDeviceIndex, Technology::kWifi));
488}
489
490TEST_F(DeviceInfoTest, CreateDeviceTunnelAccepted) {
491 IPAddress address = CreateInterfaceAddress();
492
493 // A VPN device should be offered to VPNProvider.
Darin Petkovc3505a52013-03-18 15:13:29 +0100494 MockVPNProvider *vpn_provider = new StrictMock<MockVPNProvider>;
495 SetVPNProvider(vpn_provider);
496 EXPECT_CALL(*vpn_provider,
Paul Stewart8c116a92012-05-02 18:30:03 -0700497 OnDeviceInfoAvailable(kTestDeviceName, kTestDeviceIndex))
498 .WillOnce(Return(true));
499 EXPECT_CALL(routing_table_, FlushRoutes(kTestDeviceIndex)).Times(1);
500 EXPECT_CALL(rtnl_handler_, RemoveInterfaceAddress(kTestDeviceIndex,
501 IsIPAddress(address)));
502 EXPECT_CALL(rtnl_handler_, RemoveInterface(_)).Times(0);
503 EXPECT_FALSE(CreateDevice(
504 kTestDeviceName, "address", kTestDeviceIndex, Technology::kTunnel));
505}
506
507TEST_F(DeviceInfoTest, CreateDeviceTunnelRejected) {
508 IPAddress address = CreateInterfaceAddress();
509
510 // A VPN device should be offered to VPNProvider.
Darin Petkovc3505a52013-03-18 15:13:29 +0100511 MockVPNProvider *vpn_provider = new StrictMock<MockVPNProvider>;
512 SetVPNProvider(vpn_provider);
513 EXPECT_CALL(*vpn_provider,
Paul Stewart8c116a92012-05-02 18:30:03 -0700514 OnDeviceInfoAvailable(kTestDeviceName, kTestDeviceIndex))
515 .WillOnce(Return(false));
516 EXPECT_CALL(routing_table_, FlushRoutes(kTestDeviceIndex)).Times(1);
517 EXPECT_CALL(rtnl_handler_, RemoveInterfaceAddress(kTestDeviceIndex,
518 IsIPAddress(address)));
519 // Since the device was rejected by the VPNProvider, DeviceInfo will
520 // remove the interface.
521 EXPECT_CALL(rtnl_handler_, RemoveInterface(kTestDeviceIndex)).Times(1);
522 EXPECT_FALSE(CreateDevice(
523 kTestDeviceName, "address", kTestDeviceIndex, Technology::kTunnel));
524}
525
526TEST_F(DeviceInfoTest, CreateDevicePPP) {
527 IPAddress address = CreateInterfaceAddress();
528
529 // A VPN device should be offered to VPNProvider.
Darin Petkovc3505a52013-03-18 15:13:29 +0100530 MockVPNProvider *vpn_provider = new StrictMock<MockVPNProvider>;
531 SetVPNProvider(vpn_provider);
532 EXPECT_CALL(*vpn_provider,
Paul Stewart8c116a92012-05-02 18:30:03 -0700533 OnDeviceInfoAvailable(kTestDeviceName, kTestDeviceIndex))
534 .WillOnce(Return(false));
535 EXPECT_CALL(routing_table_, FlushRoutes(kTestDeviceIndex)).Times(1);
536 EXPECT_CALL(rtnl_handler_, RemoveInterfaceAddress(kTestDeviceIndex,
537 IsIPAddress(address)));
538 // We do not remove PPP interfaces even if the provider does not accept it.
539 EXPECT_CALL(rtnl_handler_, RemoveInterface(_)).Times(0);
540 EXPECT_FALSE(CreateDevice(
541 kTestDeviceName, "address", kTestDeviceIndex, Technology::kPPP));
542}
543
544TEST_F(DeviceInfoTest, CreateDeviceLoopback) {
545 // A loopback device should be brought up, and nothing else done to it.
546 EXPECT_CALL(routing_table_, FlushRoutes(_)).Times(0);
547 EXPECT_CALL(rtnl_handler_, RemoveInterfaceAddress(_, _)).Times(0);
548 EXPECT_CALL(rtnl_handler_,
549 SetInterfaceFlags(kTestDeviceIndex, IFF_UP, IFF_UP)).Times(1);
550 EXPECT_FALSE(CreateDevice(
551 kTestDeviceName, "address", kTestDeviceIndex, Technology::kLoopback));
552}
553
Paul Stewart050cfc02012-07-06 20:38:54 -0700554TEST_F(DeviceInfoTest, CreateDeviceCDCEthernet) {
555 // A cdc_ether device should be postponed to a task.
556 EXPECT_CALL(manager_, modem_info()).Times(0);
557 EXPECT_CALL(routing_table_, FlushRoutes(_)).Times(0);
558 EXPECT_CALL(rtnl_handler_, RemoveInterfaceAddress(_, _)).Times(0);
559 EXPECT_CALL(dispatcher_,
Paul Stewart1ac4e842012-07-10 12:58:12 -0700560 PostDelayedTask(_, GetDelayedDeviceCreationMilliseconds()));
Paul Stewart050cfc02012-07-06 20:38:54 -0700561 EXPECT_TRUE(GetDelayedDevices().empty());
562 EXPECT_FALSE(CreateDevice(
563 kTestDeviceName, "address", kTestDeviceIndex, Technology::kCDCEthernet));
564 EXPECT_FALSE(GetDelayedDevices().empty());
565 EXPECT_EQ(1, GetDelayedDevices().size());
566 EXPECT_EQ(kTestDeviceIndex, *GetDelayedDevices().begin());
567}
568
Paul Stewart8c116a92012-05-02 18:30:03 -0700569TEST_F(DeviceInfoTest, CreateDeviceUnknown) {
570 IPAddress address = CreateInterfaceAddress();
571
572 // An unknown (blacklisted, unhandled, etc) device won't be flushed or
573 // registered.
574 EXPECT_CALL(routing_table_, FlushRoutes(_)).Times(0);
575 EXPECT_CALL(rtnl_handler_, RemoveInterfaceAddress(_, _)).Times(0);
576 EXPECT_TRUE(CreateDevice(
577 kTestDeviceName, "address", kTestDeviceIndex, Technology::kUnknown));
Chris Masone9be4a9d2011-05-16 15:44:09 -0700578}
579
mukesh agrawal8f317b62011-07-15 11:53:23 -0700580TEST_F(DeviceInfoTest, DeviceBlackList) {
581 device_info_.AddDeviceToBlackList(kTestDeviceName);
Paul Stewart9a908082011-08-31 12:18:48 -0700582 scoped_ptr<RTNLMessage> message(BuildLinkMessage(RTNLMessage::kModeAdd));
Darin Petkove6193c02011-08-11 12:42:40 -0700583 SendMessageToDeviceInfo(*message);
mukesh agrawal8f317b62011-07-15 11:53:23 -0700584
Darin Petkove6193c02011-08-11 12:42:40 -0700585 DeviceRefPtr device = device_info_.GetDevice(kTestDeviceIndex);
586 ASSERT_TRUE(device.get());
Joshua Krollda798622012-06-05 12:30:48 -0700587 EXPECT_TRUE(device->technology() == Technology::kBlacklisted);
mukesh agrawal8f317b62011-07-15 11:53:23 -0700588}
589
Paul Stewart9a908082011-08-31 12:18:48 -0700590TEST_F(DeviceInfoTest, DeviceAddressList) {
Paul Stewart9a908082011-08-31 12:18:48 -0700591 scoped_ptr<RTNLMessage> message(BuildLinkMessage(RTNLMessage::kModeAdd));
592 SendMessageToDeviceInfo(*message);
593
594 vector<DeviceInfo::AddressData> addresses;
595 EXPECT_TRUE(device_info_.GetAddresses(kTestDeviceIndex, &addresses));
596 EXPECT_TRUE(addresses.empty());
597
598 // Add an address to the device address list
Paul Stewart7355ce12011-09-02 10:47:01 -0700599 IPAddress ip_address0(IPAddress::kFamilyIPv4);
Paul Stewart9a908082011-08-31 12:18:48 -0700600 EXPECT_TRUE(ip_address0.SetAddressFromString(kTestIPAddress0));
601 ip_address0.set_prefix(kTestIPAddressPrefix0);
602 message.reset(BuildAddressMessage(RTNLMessage::kModeAdd, ip_address0, 0, 0));
603 SendMessageToDeviceInfo(*message);
604 EXPECT_TRUE(device_info_.GetAddresses(kTestDeviceIndex, &addresses));
605 EXPECT_EQ(1, addresses.size());
606 EXPECT_TRUE(ip_address0.Equals(addresses[0].address));
607
608 // Re-adding the same address shouldn't cause the address list to change
609 SendMessageToDeviceInfo(*message);
610 EXPECT_TRUE(device_info_.GetAddresses(kTestDeviceIndex, &addresses));
611 EXPECT_EQ(1, addresses.size());
612 EXPECT_TRUE(ip_address0.Equals(addresses[0].address));
613
614 // Adding a new address should expand the list
Paul Stewart7355ce12011-09-02 10:47:01 -0700615 IPAddress ip_address1(IPAddress::kFamilyIPv6);
Paul Stewart9a908082011-08-31 12:18:48 -0700616 EXPECT_TRUE(ip_address1.SetAddressFromString(kTestIPAddress1));
617 ip_address1.set_prefix(kTestIPAddressPrefix1);
618 message.reset(BuildAddressMessage(RTNLMessage::kModeAdd, ip_address1, 0, 0));
619 SendMessageToDeviceInfo(*message);
620 EXPECT_TRUE(device_info_.GetAddresses(kTestDeviceIndex, &addresses));
621 EXPECT_EQ(2, addresses.size());
622 EXPECT_TRUE(ip_address0.Equals(addresses[0].address));
623 EXPECT_TRUE(ip_address1.Equals(addresses[1].address));
624
625 // Deleting an address should reduce the list
626 message.reset(BuildAddressMessage(RTNLMessage::kModeDelete,
627 ip_address0,
628 0,
629 0));
630 SendMessageToDeviceInfo(*message);
631 EXPECT_TRUE(device_info_.GetAddresses(kTestDeviceIndex, &addresses));
632 EXPECT_EQ(1, addresses.size());
633 EXPECT_TRUE(ip_address1.Equals(addresses[0].address));
634
635 // Delete last item
636 message.reset(BuildAddressMessage(RTNLMessage::kModeDelete,
637 ip_address1,
638 0,
639 0));
640 SendMessageToDeviceInfo(*message);
641 EXPECT_TRUE(device_info_.GetAddresses(kTestDeviceIndex, &addresses));
642 EXPECT_TRUE(addresses.empty());
643
644 // Delete device
645 message.reset(BuildLinkMessage(RTNLMessage::kModeDelete));
Paul Stewart8c116a92012-05-02 18:30:03 -0700646 EXPECT_CALL(manager_, DeregisterDevice(_)).Times(1);
Paul Stewart9a908082011-08-31 12:18:48 -0700647 SendMessageToDeviceInfo(*message);
648
649 // Should be able to handle message for interface that doesn't exist
650 message.reset(BuildAddressMessage(RTNLMessage::kModeAdd, ip_address0, 0, 0));
651 SendMessageToDeviceInfo(*message);
652 EXPECT_FALSE(device_info_.GetDevice(kTestDeviceIndex).get());
Paul Stewart9a908082011-08-31 12:18:48 -0700653}
654
655TEST_F(DeviceInfoTest, FlushAddressList) {
Paul Stewart9a908082011-08-31 12:18:48 -0700656 scoped_ptr<RTNLMessage> message(BuildLinkMessage(RTNLMessage::kModeAdd));
657 SendMessageToDeviceInfo(*message);
658
Paul Stewart7355ce12011-09-02 10:47:01 -0700659 IPAddress address1(IPAddress::kFamilyIPv6);
Paul Stewart9a908082011-08-31 12:18:48 -0700660 EXPECT_TRUE(address1.SetAddressFromString(kTestIPAddress1));
661 address1.set_prefix(kTestIPAddressPrefix1);
662 message.reset(BuildAddressMessage(RTNLMessage::kModeAdd,
663 address1,
664 0,
665 RT_SCOPE_UNIVERSE));
666 SendMessageToDeviceInfo(*message);
Paul Stewart7355ce12011-09-02 10:47:01 -0700667 IPAddress address2(IPAddress::kFamilyIPv6);
Paul Stewart9a908082011-08-31 12:18:48 -0700668 EXPECT_TRUE(address2.SetAddressFromString(kTestIPAddress2));
669 message.reset(BuildAddressMessage(RTNLMessage::kModeAdd,
670 address2,
671 IFA_F_TEMPORARY,
672 RT_SCOPE_UNIVERSE));
673 SendMessageToDeviceInfo(*message);
Paul Stewart7355ce12011-09-02 10:47:01 -0700674 IPAddress address3(IPAddress::kFamilyIPv6);
Paul Stewart9a908082011-08-31 12:18:48 -0700675 EXPECT_TRUE(address3.SetAddressFromString(kTestIPAddress3));
676 message.reset(BuildAddressMessage(RTNLMessage::kModeAdd,
677 address3,
678 0,
679 RT_SCOPE_LINK));
680 SendMessageToDeviceInfo(*message);
Paul Stewart7355ce12011-09-02 10:47:01 -0700681 IPAddress address4(IPAddress::kFamilyIPv6);
Paul Stewart9a908082011-08-31 12:18:48 -0700682 EXPECT_TRUE(address4.SetAddressFromString(kTestIPAddress4));
683 message.reset(BuildAddressMessage(RTNLMessage::kModeAdd,
684 address4,
685 IFA_F_PERMANENT,
686 RT_SCOPE_UNIVERSE));
687 SendMessageToDeviceInfo(*message);
688
689 // DeviceInfo now has 4 addresses associated with it, but only two of
690 // them are valid for flush.
691 EXPECT_CALL(rtnl_handler_, RemoveInterfaceAddress(kTestDeviceIndex,
692 IsIPAddress(address1)));
693 EXPECT_CALL(rtnl_handler_, RemoveInterfaceAddress(kTestDeviceIndex,
694 IsIPAddress(address2)));
695 device_info_.FlushAddresses(kTestDeviceIndex);
Paul Stewart9a908082011-08-31 12:18:48 -0700696}
697
Paul Stewart05a42c22012-08-02 16:47:21 -0700698TEST_F(DeviceInfoTest, HasOtherAddress) {
699 scoped_ptr<RTNLMessage> message(BuildLinkMessage(RTNLMessage::kModeAdd));
700 SendMessageToDeviceInfo(*message);
701
702 IPAddress address0(IPAddress::kFamilyIPv4);
703 EXPECT_TRUE(address0.SetAddressFromString(kTestIPAddress0));
704
705 // There are no addresses on this interface.
706 EXPECT_FALSE(device_info_.HasOtherAddress(kTestDeviceIndex, address0));
707
708 message.reset(BuildAddressMessage(RTNLMessage::kModeAdd,
709 address0,
710 0,
711 RT_SCOPE_UNIVERSE));
712 SendMessageToDeviceInfo(*message);
713
714 IPAddress address1(IPAddress::kFamilyIPv6);
715 EXPECT_TRUE(address1.SetAddressFromString(kTestIPAddress1));
716 address1.set_prefix(kTestIPAddressPrefix1);
717 message.reset(BuildAddressMessage(RTNLMessage::kModeAdd,
718 address1,
719 0,
720 RT_SCOPE_LINK));
721 SendMessageToDeviceInfo(*message);
722
723 IPAddress address2(IPAddress::kFamilyIPv6);
724 EXPECT_TRUE(address2.SetAddressFromString(kTestIPAddress2));
725 message.reset(BuildAddressMessage(RTNLMessage::kModeAdd,
726 address2,
727 IFA_F_TEMPORARY,
728 RT_SCOPE_UNIVERSE));
729 SendMessageToDeviceInfo(*message);
730
731 IPAddress address3(IPAddress::kFamilyIPv6);
732 EXPECT_TRUE(address3.SetAddressFromString(kTestIPAddress3));
733
734 // The only IPv6 addresses on this interface are either flagged as
735 // temporary, or they are not universally scoped.
736 EXPECT_FALSE(device_info_.HasOtherAddress(kTestDeviceIndex, address3));
737
738
739 message.reset(BuildAddressMessage(RTNLMessage::kModeAdd,
740 address3,
741 0,
742 RT_SCOPE_UNIVERSE));
743 SendMessageToDeviceInfo(*message);
744
745 // address0 is on this interface.
746 EXPECT_FALSE(device_info_.HasOtherAddress(kTestDeviceIndex, address0));
747 // address1 is on this interface.
748 EXPECT_FALSE(device_info_.HasOtherAddress(kTestDeviceIndex, address1));
749 // address2 is on this interface.
750 EXPECT_FALSE(device_info_.HasOtherAddress(kTestDeviceIndex, address2));
751 // address3 is on this interface.
752 EXPECT_FALSE(device_info_.HasOtherAddress(kTestDeviceIndex, address3));
753
754 IPAddress address4(IPAddress::kFamilyIPv6);
755 EXPECT_TRUE(address4.SetAddressFromString(kTestIPAddress4));
756
757 // address4 is not on this interface, but address3 is, and is a qualified
758 // IPv6 address.
759 EXPECT_TRUE(device_info_.HasOtherAddress(kTestDeviceIndex, address4));
760
761 message.reset(BuildAddressMessage(RTNLMessage::kModeAdd,
762 address4,
763 IFA_F_PERMANENT,
764 RT_SCOPE_UNIVERSE));
765 SendMessageToDeviceInfo(*message);
766
767 // address4 is now on this interface.
768 EXPECT_FALSE(device_info_.HasOtherAddress(kTestDeviceIndex, address4));
769
770 IPAddress address5(IPAddress::kFamilyIPv4);
771 EXPECT_TRUE(address5.SetAddressFromString(kTestIPAddress5));
772 // address5 is not on this interface, but address0 is.
773 EXPECT_TRUE(device_info_.HasOtherAddress(kTestDeviceIndex, address5));
774
775 message.reset(BuildAddressMessage(RTNLMessage::kModeAdd,
776 address5,
777 IFA_F_PERMANENT,
778 RT_SCOPE_UNIVERSE));
779 SendMessageToDeviceInfo(*message);
780
781 // address5 is now on this interface.
782 EXPECT_FALSE(device_info_.HasOtherAddress(kTestDeviceIndex, address5));
783}
784
Thieu Leb27beee2012-04-20 09:19:06 -0700785TEST_F(DeviceInfoTest, HasSubdir) {
Paul Stewart5ad16062013-02-21 18:10:48 -0800786 base::ScopedTempDir temp_dir;
Thieu Le8f1c8352012-04-16 11:02:12 -0700787 EXPECT_TRUE(temp_dir.CreateUniqueTempDir());
Thieu Leb27beee2012-04-20 09:19:06 -0700788 EXPECT_TRUE(file_util::CreateDirectory(temp_dir.path().Append("child1")));
789 FilePath child2 = temp_dir.path().Append("child2");
790 EXPECT_TRUE(file_util::CreateDirectory(child2));
791 FilePath grandchild = child2.Append("grandchild");
Thieu Le8f1c8352012-04-16 11:02:12 -0700792 EXPECT_TRUE(file_util::CreateDirectory(grandchild));
793 EXPECT_TRUE(file_util::CreateDirectory(grandchild.Append("greatgrandchild")));
Thieu Leb27beee2012-04-20 09:19:06 -0700794 EXPECT_TRUE(DeviceInfo::HasSubdir(temp_dir.path(),
795 FilePath("grandchild")));
796 EXPECT_TRUE(DeviceInfo::HasSubdir(temp_dir.path(),
797 FilePath("greatgrandchild")));
798 EXPECT_FALSE(DeviceInfo::HasSubdir(temp_dir.path(),
799 FilePath("nonexistent")));
Thieu Le8f1c8352012-04-16 11:02:12 -0700800}
801
Gary Morain41780232012-07-31 15:08:31 -0700802TEST_F(DeviceInfoTest, GetMACAddressFromKernelUnknownDevice) {
803 SetSockets();
804 EXPECT_CALL(*mock_sockets_, Socket(PF_INET, SOCK_DGRAM, 0)).Times(0);
805 ByteString mac_address =
806 device_info_.GetMACAddressFromKernel(kTestDeviceIndex);
807 EXPECT_TRUE(mac_address.IsEmpty());
808}
809
810TEST_F(DeviceInfoTest, GetMACAddressFromKernelUnableToOpenSocket) {
811 SetSockets();
812 EXPECT_CALL(*mock_sockets_, Socket(PF_INET, SOCK_DGRAM, 0))
813 .WillOnce(Return(-1));
814 scoped_ptr<RTNLMessage> message(BuildLinkMessage(RTNLMessage::kModeAdd));
815 message->set_link_status(RTNLMessage::LinkStatus(0, IFF_LOWER_UP, 0));
816 SendMessageToDeviceInfo(*message);
817 EXPECT_TRUE(device_info_.GetDevice(kTestDeviceIndex).get());
818 ByteString mac_address =
819 device_info_.GetMACAddressFromKernel(kTestDeviceIndex);
820 EXPECT_TRUE(mac_address.IsEmpty());
821}
822
823TEST_F(DeviceInfoTest, GetMACAddressFromKernelIoctlFails) {
824 SetSockets();
825 const int kFd = 99;
826 EXPECT_CALL(*mock_sockets_, Socket(PF_INET, SOCK_DGRAM, 0))
827 .WillOnce(Return(kFd));
828 EXPECT_CALL(*mock_sockets_, Ioctl(kFd, SIOCGIFHWADDR, NotNull()))
829 .WillOnce(Return(-1));
830 EXPECT_CALL(*mock_sockets_, Close(kFd));
831
832 scoped_ptr<RTNLMessage> message(BuildLinkMessage(RTNLMessage::kModeAdd));
833 message->set_link_status(RTNLMessage::LinkStatus(0, IFF_LOWER_UP, 0));
834 SendMessageToDeviceInfo(*message);
835 EXPECT_TRUE(device_info_.GetDevice(kTestDeviceIndex).get());
836
837 ByteString mac_address =
838 device_info_.GetMACAddressFromKernel(kTestDeviceIndex);
839 EXPECT_TRUE(mac_address.IsEmpty());
840}
841
842MATCHER_P2(IfreqEquals, ifindex, ifname, "") {
843 const struct ifreq *const ifr = static_cast<struct ifreq *>(arg);
844 return (ifr != NULL) &&
845 (ifr->ifr_ifindex == ifindex) &&
846 (strcmp(ifname, ifr->ifr_name) == 0);
847}
848
849ACTION_P(SetIfreq, ifr) {
850 struct ifreq *const ifr_arg = static_cast<struct ifreq *>(arg2);
851 *ifr_arg = ifr;
852}
853
854TEST_F(DeviceInfoTest, GetMACAddressFromKernel) {
855 SetSockets();
856 const int kFd = 99;
857 struct ifreq ifr;
Han Shenfc349252012-08-30 11:36:04 -0700858 static uint8_t kMacAddress[] = {0x00, 0x01, 0x02, 0xaa, 0xbb, 0xcc};
Gary Morain41780232012-07-31 15:08:31 -0700859 memcpy(ifr.ifr_hwaddr.sa_data, kMacAddress, sizeof(kMacAddress));
860 EXPECT_CALL(*mock_sockets_, Socket(PF_INET, SOCK_DGRAM, 0))
861 .WillOnce(Return(kFd));
862 EXPECT_CALL(*mock_sockets_,
863 Ioctl(kFd, SIOCGIFHWADDR,
864 IfreqEquals(kTestDeviceIndex, kTestDeviceName)))
865 .WillOnce(DoAll(SetIfreq(ifr), Return(0)));
866 EXPECT_CALL(*mock_sockets_, Close(kFd));
867
868 scoped_ptr<RTNLMessage> message(BuildLinkMessage(RTNLMessage::kModeAdd));
869 message->set_link_status(RTNLMessage::LinkStatus(0, IFF_LOWER_UP, 0));
870 SendMessageToDeviceInfo(*message);
871 EXPECT_TRUE(device_info_.GetDevice(kTestDeviceIndex).get());
872
873 ByteString mac_address =
874 device_info_.GetMACAddressFromKernel(kTestDeviceIndex);
875 EXPECT_THAT(kMacAddress,
876 ElementsAreArray(mac_address.GetData(), sizeof(kMacAddress)));
877}
878
Paul Stewartca876ee2012-04-21 08:55:58 -0700879class DeviceInfoTechnologyTest : public DeviceInfoTest {
880 public:
Jason Glasgowabc54032012-04-20 16:08:32 -0400881 DeviceInfoTechnologyTest()
882 : DeviceInfoTest(),
883 test_device_name_(kTestDeviceName) {}
Paul Stewartca876ee2012-04-21 08:55:58 -0700884 virtual ~DeviceInfoTechnologyTest() {}
885
886 virtual void SetUp() {
887 temp_dir_.CreateUniqueTempDir();
888 device_info_root_ = temp_dir_.path().Append("sys/class/net");
889 device_info_.device_info_root_ = device_info_root_;
890 // Most tests require that the uevent file exist.
891 CreateInfoFile("uevent", "xxx");
892 }
893
894 Technology::Identifier GetDeviceTechnology() {
Jason Glasgowabc54032012-04-20 16:08:32 -0400895 return device_info_.GetDeviceTechnology(test_device_name_);
Paul Stewartca876ee2012-04-21 08:55:58 -0700896 }
897 FilePath GetInfoPath(const string &name);
898 void CreateInfoFile(const string &name, const string &contents);
899 void CreateInfoSymLink(const string &name, const string &contents);
Jason Glasgowabc54032012-04-20 16:08:32 -0400900 void SetDeviceName(const string &name) {
901 test_device_name_ = name;
902 SetUp();
903 }
Paul Stewartca876ee2012-04-21 08:55:58 -0700904
905 protected:
Paul Stewart5ad16062013-02-21 18:10:48 -0800906 base::ScopedTempDir temp_dir_;
Paul Stewartca876ee2012-04-21 08:55:58 -0700907 FilePath device_info_root_;
Jason Glasgowabc54032012-04-20 16:08:32 -0400908 string test_device_name_;
Paul Stewartca876ee2012-04-21 08:55:58 -0700909};
910
911FilePath DeviceInfoTechnologyTest::GetInfoPath(const string &name) {
Jason Glasgowabc54032012-04-20 16:08:32 -0400912 return device_info_root_.Append(test_device_name_).Append(name);
Paul Stewartca876ee2012-04-21 08:55:58 -0700913}
914
915void DeviceInfoTechnologyTest::CreateInfoFile(const string &name,
916 const string &contents) {
917 FilePath info_path = GetInfoPath(name);
918 EXPECT_TRUE(file_util::CreateDirectory(info_path.DirName()));
919 string contents_newline(contents + "\n");
920 EXPECT_TRUE(file_util::WriteFile(info_path, contents_newline.c_str(),
921 contents_newline.size()));
922}
923
924void DeviceInfoTechnologyTest::CreateInfoSymLink(const string &name,
925 const string &contents) {
926 FilePath info_path = GetInfoPath(name);
Paul Stewartca876ee2012-04-21 08:55:58 -0700927 EXPECT_TRUE(file_util::CreateDirectory(info_path.DirName()));
928 EXPECT_TRUE(file_util::CreateSymbolicLink(FilePath(contents), info_path));
929}
930
931TEST_F(DeviceInfoTechnologyTest, Unknown) {
932 EXPECT_EQ(Technology::kUnknown, GetDeviceTechnology());
933 // Should still be unknown even without a uevent file.
934 EXPECT_TRUE(file_util::Delete(GetInfoPath("uevent"), FALSE));
935 EXPECT_EQ(Technology::kUnknown, GetDeviceTechnology());
936}
937
938TEST_F(DeviceInfoTechnologyTest, Loopback) {
939 CreateInfoFile("type", base::IntToString(ARPHRD_LOOPBACK));
940 EXPECT_EQ(Technology::kLoopback, GetDeviceTechnology());
941}
942
943TEST_F(DeviceInfoTechnologyTest, PPP) {
944 CreateInfoFile("type", base::IntToString(ARPHRD_PPP));
945 EXPECT_EQ(Technology::kPPP, GetDeviceTechnology());
946}
947
948TEST_F(DeviceInfoTechnologyTest, Tunnel) {
949 CreateInfoFile("tun_flags", base::IntToString(IFF_TUN));
950 EXPECT_EQ(Technology::kTunnel, GetDeviceTechnology());
951}
952
953TEST_F(DeviceInfoTechnologyTest, WiFi) {
954 CreateInfoFile("uevent", "DEVTYPE=wlan");
955 EXPECT_EQ(Technology::kWifi, GetDeviceTechnology());
956 CreateInfoFile("uevent", "foo\nDEVTYPE=wlan");
957 EXPECT_EQ(Technology::kWifi, GetDeviceTechnology());
958 CreateInfoFile("type", base::IntToString(ARPHRD_IEEE80211_RADIOTAP));
959 EXPECT_EQ(Technology::kWiFiMonitor, GetDeviceTechnology());
960}
961
962TEST_F(DeviceInfoTechnologyTest, Ethernet) {
963 CreateInfoSymLink("device/driver", "xxx");
964 EXPECT_EQ(Technology::kEthernet, GetDeviceTechnology());
965}
966
Darin Petkove4b27022012-05-16 13:28:50 +0200967TEST_F(DeviceInfoTechnologyTest, WiMax) {
968 CreateInfoSymLink("device/driver", "gdm_wimax");
969 EXPECT_EQ(Technology::kWiMax, GetDeviceTechnology());
970}
971
Paul Stewartca876ee2012-04-21 08:55:58 -0700972TEST_F(DeviceInfoTechnologyTest, CellularGobi1) {
973 CreateInfoSymLink("device/driver", "blah/foo/gobi");
974 EXPECT_EQ(Technology::kCellular, GetDeviceTechnology());
975}
976
977TEST_F(DeviceInfoTechnologyTest, CellularGobi2) {
978 CreateInfoSymLink("device/driver", "../GobiNet");
979 EXPECT_EQ(Technology::kCellular, GetDeviceTechnology());
980}
981
982TEST_F(DeviceInfoTechnologyTest, QCUSB) {
983 CreateInfoSymLink("device/driver", "QCUSBNet2k");
984 EXPECT_EQ(Technology::kCellular, GetDeviceTechnology());
985}
986
Ben Chan226d46a2012-10-11 00:22:17 -0700987TEST_F(DeviceInfoTechnologyTest, CellularQmiWwan) {
988 CreateInfoSymLink("device/driver", "qmi_wwan");
989 EXPECT_EQ(Technology::kCellular, GetDeviceTechnology());
990}
991
Paul Stewartca876ee2012-04-21 08:55:58 -0700992// Modem with absolute driver path with top-level tty file:
993// /sys/class/net/dev0/device -> /sys/devices/virtual/0/00
994// /sys/devices/virtual/0/00/driver -> /drivers/cdc_ether
995// /sys/devices/virtual/0/01/tty [empty directory]
996TEST_F(DeviceInfoTechnologyTest, CDCEtherModem1) {
997 FilePath device_root(temp_dir_.path().Append("sys/devices/virtual/0"));
998 FilePath device_path(device_root.Append("00"));
999 EXPECT_TRUE(file_util::CreateDirectory(device_path));
1000 CreateInfoSymLink("device", device_path.value());
1001 EXPECT_TRUE(file_util::CreateSymbolicLink(FilePath("/drivers/cdc_ether"),
1002 device_path.Append("driver")));
1003 EXPECT_TRUE(file_util::CreateDirectory(device_root.Append("01/tty")));
1004 EXPECT_EQ(Technology::kCellular, GetDeviceTechnology());
1005}
1006
1007// Modem with relative driver path with top-level tty file.
1008// /sys/class/net/dev0/device -> ../../../device_dir/0/00
1009// /sys/device_dir/0/00/driver -> /drivers/cdc_ether
1010// /sys/device_dir/0/01/tty [empty directory]
1011TEST_F(DeviceInfoTechnologyTest, CDCEtherModem2) {
1012 CreateInfoSymLink("device", "../../../device_dir/0/00");
1013 FilePath device_root(temp_dir_.path().Append("sys/device_dir/0"));
1014 FilePath device_path(device_root.Append("00"));
1015 EXPECT_TRUE(file_util::CreateDirectory(device_path));
1016 EXPECT_TRUE(file_util::CreateSymbolicLink(FilePath("/drivers/cdc_ether"),
1017 device_path.Append("driver")));
1018 EXPECT_TRUE(file_util::CreateDirectory(device_root.Append("01/tty")));
1019 EXPECT_EQ(Technology::kCellular, GetDeviceTechnology());
1020}
1021
1022// Modem with relative driver path with lower-level tty file.
1023// /sys/class/net/dev0/device -> ../../../device_dir/0/00
1024// /sys/device_dir/0/00/driver -> /drivers/cdc_ether
1025// /sys/device_dir/0/01/yyy/tty [empty directory]
1026TEST_F(DeviceInfoTechnologyTest, CDCEtherModem3) {
1027 CreateInfoSymLink("device", "../../../device_dir/0/00");
1028 FilePath device_root(temp_dir_.path().Append("sys/device_dir/0"));
1029 FilePath device_path(device_root.Append("00"));
1030 EXPECT_TRUE(file_util::CreateDirectory(device_path));
1031 EXPECT_TRUE(file_util::CreateSymbolicLink(FilePath("/drivers/cdc_ether"),
1032 device_path.Append("driver")));
1033 EXPECT_TRUE(file_util::CreateDirectory(device_root.Append("01/yyy/tty")));
1034 EXPECT_EQ(Technology::kCellular, GetDeviceTechnology());
1035}
1036
1037TEST_F(DeviceInfoTechnologyTest, CDCEtherNonModem) {
1038 CreateInfoSymLink("device", "device_dir");
1039 CreateInfoSymLink("device_dir/driver", "cdc_ether");
Paul Stewart050cfc02012-07-06 20:38:54 -07001040 EXPECT_EQ(Technology::kCDCEthernet, GetDeviceTechnology());
Paul Stewartca876ee2012-04-21 08:55:58 -07001041}
1042
Jason Glasgowabc54032012-04-20 16:08:32 -04001043TEST_F(DeviceInfoTechnologyTest, PseudoModem) {
1044 SetDeviceName("pseudomodem");
1045 CreateInfoSymLink("device", "device_dir");
1046 CreateInfoSymLink("device_dir/driver", "cdc_ether");
1047 EXPECT_EQ(Technology::kCellular, GetDeviceTechnology());
1048
1049 SetDeviceName("pseudomodem9");
1050 CreateInfoSymLink("device", "device_dir");
1051 CreateInfoSymLink("device_dir/driver", "cdc_ether");
1052 EXPECT_EQ(Technology::kCellular, GetDeviceTechnology());
1053}
1054
Paul Stewart050cfc02012-07-06 20:38:54 -07001055class DeviceInfoForDelayedCreationTest : public DeviceInfo {
1056 public:
1057 DeviceInfoForDelayedCreationTest(ControlInterface *control_interface,
1058 EventDispatcher *dispatcher,
1059 Metrics *metrics,
1060 Manager *manager)
1061 : DeviceInfo(control_interface, dispatcher, metrics, manager) {}
1062 MOCK_METHOD4(CreateDevice, DeviceRefPtr(const std::string &link_name,
1063 const std::string &address,
1064 int interface_index,
1065 Technology::Identifier technology));
1066 MOCK_METHOD1(GetDeviceTechnology,
1067 Technology::Identifier(const string &iface_name));
1068};
1069
1070class DeviceInfoDelayedCreationTest : public DeviceInfoTest {
1071 public:
1072 DeviceInfoDelayedCreationTest()
1073 : DeviceInfoTest(),
1074 test_device_info_(
1075 &control_interface_, &dispatcher_, &metrics_, &manager_) {}
1076 virtual ~DeviceInfoDelayedCreationTest() {}
1077
1078 virtual std::set<int> &GetDelayedDevices() {
1079 return test_device_info_.delayed_devices_;
1080 }
1081
1082 void DelayedDeviceCreationTask() {
1083 test_device_info_.DelayedDeviceCreationTask();
1084 }
1085
1086 void AddDelayedDevice() {
1087 scoped_ptr<RTNLMessage> message(BuildLinkMessage(RTNLMessage::kModeAdd));
1088 EXPECT_CALL(test_device_info_, GetDeviceTechnology(kTestDeviceName))
1089 .WillOnce(Return(Technology::kCDCEthernet));
1090 EXPECT_CALL(test_device_info_, CreateDevice(
1091 kTestDeviceName, _, kTestDeviceIndex, Technology::kCDCEthernet))
1092 .WillOnce(Return(DeviceRefPtr()));
1093 test_device_info_.AddLinkMsgHandler(*message);
1094 Mock::VerifyAndClearExpectations(&test_device_info_);
1095 // We need to insert the device index ourselves since we have mocked
1096 // out CreateDevice. This insertion is tested in CreateDeviceCDCEthernet
1097 // above.
1098 GetDelayedDevices().insert(kTestDeviceIndex);
1099 }
1100
Paul Stewart2ddf2c62013-04-16 09:47:34 -07001101 void TriggerOnWiFiInterfaceInfoReceived(const NetlinkMessage &message) {
1102 test_device_info_.OnWiFiInterfaceInfoReceived(message);
1103 }
1104
Paul Stewart050cfc02012-07-06 20:38:54 -07001105 protected:
1106 DeviceInfoForDelayedCreationTest test_device_info_;
1107};
1108
1109TEST_F(DeviceInfoDelayedCreationTest, NoDevices) {
1110 EXPECT_TRUE(GetDelayedDevices().empty());
1111 EXPECT_CALL(test_device_info_, GetDeviceTechnology(_)).Times(0);
1112 DelayedDeviceCreationTask();
1113}
1114
1115TEST_F(DeviceInfoDelayedCreationTest, EthernetDevice) {
1116 AddDelayedDevice();
1117 EXPECT_CALL(test_device_info_, GetDeviceTechnology(_))
1118 .WillOnce(Return(Technology::kCDCEthernet));
1119 EXPECT_CALL(test_device_info_, CreateDevice(
1120 kTestDeviceName, _, kTestDeviceIndex, Technology::kEthernet))
1121 .WillOnce(Return(DeviceRefPtr()));
1122 DelayedDeviceCreationTask();
1123 EXPECT_TRUE(GetDelayedDevices().empty());
1124}
1125
1126TEST_F(DeviceInfoDelayedCreationTest, CellularDevice) {
1127 AddDelayedDevice();
1128 EXPECT_CALL(test_device_info_, GetDeviceTechnology(_))
1129 .WillOnce(Return(Technology::kCellular));
1130 EXPECT_CALL(test_device_info_, CreateDevice(
1131 kTestDeviceName, _, kTestDeviceIndex, Technology::kCellular))
1132 .WillOnce(Return(DeviceRefPtr()));
1133 DelayedDeviceCreationTask();
1134 EXPECT_TRUE(GetDelayedDevices().empty());
1135}
1136
Paul Stewart2ddf2c62013-04-16 09:47:34 -07001137TEST_F(DeviceInfoDelayedCreationTest, WiFiDevice) {
1138 ScopedMockLog log;
1139 EXPECT_CALL(manager_, RegisterDevice(_)).Times(0);
1140 EXPECT_CALL(log, Log(logging::LOG_ERROR, _,
1141 HasSubstr("Unknown message type received")));
1142 GenericNetlinkMessage non_nl80211_message(0, 0, "foo");
1143 TriggerOnWiFiInterfaceInfoReceived(non_nl80211_message);
1144 Mock::VerifyAndClearExpectations(&log);
1145
1146 EXPECT_CALL(log, Log(logging::LOG_ERROR, _,
1147 HasSubstr("Message is not a new interface response")));
1148 GetInterfaceMessage non_interface_response_message;
1149 TriggerOnWiFiInterfaceInfoReceived(non_interface_response_message);
1150 Mock::VerifyAndClearExpectations(&log);
1151
1152 EXPECT_CALL(log, Log(logging::LOG_ERROR, _,
1153 HasSubstr("Message contains no interface index")));
1154 NewInterfaceMessage message;
1155 TriggerOnWiFiInterfaceInfoReceived(message);
1156 Mock::VerifyAndClearExpectations(&log);
1157
1158 message.attributes()->CreateAttribute(
1159 NL80211_ATTR_IFINDEX, base::Bind(
1160 &NetlinkAttribute::NewNl80211AttributeFromId));
1161 message.attributes()->SetU32AttributeValue(NL80211_ATTR_IFINDEX,
1162 kTestDeviceIndex);
1163 EXPECT_CALL(log, Log(logging::LOG_ERROR, _,
1164 HasSubstr("Message contains no interface type")));
1165 TriggerOnWiFiInterfaceInfoReceived(message);
1166 Mock::VerifyAndClearExpectations(&log);
1167
1168 message.attributes()->CreateAttribute(
1169 NL80211_ATTR_IFTYPE, base::Bind(
1170 &NetlinkAttribute::NewNl80211AttributeFromId));
1171 message.attributes()->SetU32AttributeValue(NL80211_ATTR_IFTYPE,
1172 NL80211_IFTYPE_AP);
1173 EXPECT_CALL(log, Log(logging::LOG_ERROR, _,
1174 HasSubstr("Could not find device info for interface")));
1175 TriggerOnWiFiInterfaceInfoReceived(message);
1176 Mock::VerifyAndClearExpectations(&log);
1177
1178 // Use the AddDelayedDevice() method to create a device info entry with no
1179 // associated device.
1180 AddDelayedDevice();
1181
1182 EXPECT_CALL(log, Log(logging::LOG_INFO, _,
1183 HasSubstr("it is not in station mode")));
1184 TriggerOnWiFiInterfaceInfoReceived(message);
1185 Mock::VerifyAndClearExpectations(&log);
1186 Mock::VerifyAndClearExpectations(&manager_);
1187
1188 message.attributes()->SetU32AttributeValue(NL80211_ATTR_IFTYPE,
1189 NL80211_IFTYPE_STATION);
1190 EXPECT_CALL(manager_, RegisterDevice(_));
1191 EXPECT_CALL(manager_, device_info())
1192 .WillRepeatedly(Return(&test_device_info_));
1193 EXPECT_CALL(log, Log(_, _, _)).Times(AnyNumber());
1194 EXPECT_CALL(log, Log(logging::LOG_INFO, _,
1195 HasSubstr("Creating WiFi device")));
1196 TriggerOnWiFiInterfaceInfoReceived(message);
1197 Mock::VerifyAndClearExpectations(&log);
1198 Mock::VerifyAndClearExpectations(&manager_);
1199
1200 EXPECT_CALL(manager_, RegisterDevice(_)).Times(0);
1201 EXPECT_CALL(log, Log(logging::LOG_ERROR, _,
1202 HasSubstr("Device already created for interface")));
1203 TriggerOnWiFiInterfaceInfoReceived(message);
1204}
1205
Chris Masone9be4a9d2011-05-16 15:44:09 -07001206} // namespace shill