1c0beca55d290fe0b1c96d78cbbcf94b05c23f5a5Peter Qiu//
2c0beca55d290fe0b1c96d78cbbcf94b05c23f5a5Peter Qiu// Copyright (C) 2012 The Android Open Source Project
3c0beca55d290fe0b1c96d78cbbcf94b05c23f5a5Peter Qiu//
4c0beca55d290fe0b1c96d78cbbcf94b05c23f5a5Peter Qiu// Licensed under the Apache License, Version 2.0 (the "License");
5c0beca55d290fe0b1c96d78cbbcf94b05c23f5a5Peter Qiu// you may not use this file except in compliance with the License.
6c0beca55d290fe0b1c96d78cbbcf94b05c23f5a5Peter Qiu// You may obtain a copy of the License at
7c0beca55d290fe0b1c96d78cbbcf94b05c23f5a5Peter Qiu//
8c0beca55d290fe0b1c96d78cbbcf94b05c23f5a5Peter Qiu//      http://www.apache.org/licenses/LICENSE-2.0
9c0beca55d290fe0b1c96d78cbbcf94b05c23f5a5Peter Qiu//
10c0beca55d290fe0b1c96d78cbbcf94b05c23f5a5Peter Qiu// Unless required by applicable law or agreed to in writing, software
11c0beca55d290fe0b1c96d78cbbcf94b05c23f5a5Peter Qiu// distributed under the License is distributed on an "AS IS" BASIS,
12c0beca55d290fe0b1c96d78cbbcf94b05c23f5a5Peter Qiu// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13c0beca55d290fe0b1c96d78cbbcf94b05c23f5a5Peter Qiu// See the License for the specific language governing permissions and
14c0beca55d290fe0b1c96d78cbbcf94b05c23f5a5Peter Qiu// limitations under the License.
15c0beca55d290fe0b1c96d78cbbcf94b05c23f5a5Peter Qiu//
16633ac6f0d56a62f8fd21ba7d9a15818fe080fb2fDarin Petkov
172aa9707f114ab8166f45df5726bf05278df2aef6Chris Masone#include "shill/device_info.h"
182aa9707f114ab8166f45df5726bf05278df2aef6Chris Masone
19cd47732488cd101eaf0d3558dde5a7d4e4fc260bBen Chan#include <memory>
20cd47732488cd101eaf0d3558dde5a7d4e4fc260bBen Chan
21e6193c042652831cac90c3bbf2233877754b1eefDarin Petkov#include <linux/if.h>
22ca876ee6b11b38a3df7a8ab03efe9ed0bcab41d8Paul Stewart#include <linux/if_tun.h>
23633ac6f0d56a62f8fd21ba7d9a15818fe080fb2fDarin Petkov#include <linux/netlink.h>  // Needs typedefs from sys/socket.h.
24633ac6f0d56a62f8fd21ba7d9a15818fe080fb2fDarin Petkov#include <linux/rtnetlink.h>
254178023c4d627410777bdc259bfc7a31f2a4b8e9Gary Morain#include <linux/sockios.h>
26ca876ee6b11b38a3df7a8ab03efe9ed0bcab41d8Paul Stewart#include <net/if_arp.h>
277347bf2b466ae8058e47b29aaf0583390405d866Wade Guthrie#include <sys/socket.h>
289be4a9d1e87d64f850f15061123b2a4334477fa2Chris Masone
292ddf2c63751546aa554335a6733314a3859d5c2ePaul Stewart#include <base/bind.h>
3011c213f3cf64f27a0e42ee6da95e98bd1d4b3202Ben Chan#include <base/files/file_util.h>
315ad1606ad8b3f74b2b7960a3003a2d1ca75d52b8Paul Stewart#include <base/files/scoped_temp_dir.h>
329be4a9d1e87d64f850f15061123b2a4334477fa2Chris Masone#include <base/memory/ref_counted.h>
33a0ddf46e466bd4ba3d20952f0a6988c680c1af14Ben Chan#include <base/message_loop/message_loop.h>
343e20a2341d0aeb7681e4ee0f89eae6817ade2b3bEric Shienbrood#include <base/stl_util.h>
35a0ddf46e466bd4ba3d20952f0a6988c680c1af14Ben Chan#include <base/strings/string_number_conversions.h>
369be4a9d1e87d64f850f15061123b2a4334477fa2Chris Masone#include <gmock/gmock.h>
375086b9744e8330e7f3bd8ab91fe20b53dda28a1cBen Chan#include <gtest/gtest.h>
389be4a9d1e87d64f850f15061123b2a4334477fa2Chris Masone
39c54afe521739065a5d77e7c049acdb5e603f0592Ben Chan#include "shill/cellular/mock_modem_info.h"
40b691efd71561246065eae3cdd73a96ca1b8a528dChristopher Wiley#include "shill/logging.h"
41b50f0b9837c398b8edd5dc568eb01bdcff9a4d65Paul Stewart#include "shill/manager.h"
4246eaaf53d5e5b92f418b8d7cbfe7e847b575791fChris Masone#include "shill/mock_control.h"
435086b9744e8330e7f3bd8ab91fe20b53dda28a1cBen Chan#include "shill/mock_device.h"
442ddf2c63751546aa554335a6733314a3859d5c2ePaul Stewart#include "shill/mock_log.h"
452ae797d040b7261a5619c750e07037566bcb542bChris Masone#include "shill/mock_manager.h"
463426c8fc7a3943f2d8fcb2ec78f0593088b42bedThieu Le#include "shill/mock_metrics.h"
478c116a90d3a3536430b808b15e73275060918434Paul Stewart#include "shill/mock_routing_table.h"
488d6b59704591ba9fad57751858835dc332dbdd37Peter Qiu#include "shill/net/ip_address.h"
498d6b59704591ba9fad57751858835dc332dbdd37Peter Qiu#include "shill/net/mock_rtnl_handler.h"
508d6b59704591ba9fad57751858835dc332dbdd37Peter Qiu#include "shill/net/mock_sockets.h"
518d6b59704591ba9fad57751858835dc332dbdd37Peter Qiu#include "shill/net/mock_time.h"
528d6b59704591ba9fad57751858835dc332dbdd37Peter Qiu#include "shill/net/rtnl_message.h"
532240e8c03451c6b6f21eb8944d8a1c0747ac10b3Ben Chan#include "shill/vpn/mock_vpn_provider.h"
54c3d707d1ae4198d5538ff4deccd729a83f1bc805Ben Chan#include "shill/wimax/mock_wimax_provider.h"
55c3d707d1ae4198d5538ff4deccd729a83f1bc805Ben Chan#include "shill/wimax/wimax.h"
569be4a9d1e87d64f850f15061123b2a4334477fa2Chris Masone
571a72f5444e077ed21b8e085b17d7f9f1bc44fa5ePeter Qiu#if !defined(DISABLE_WIFI)
581a72f5444e077ed21b8e085b17d7f9f1bc44fa5ePeter Qiu#include "shill/net/mock_netlink_manager.h"
591a72f5444e077ed21b8e085b17d7f9f1bc44fa5ePeter Qiu#include "shill/net/netlink_attribute.h"
601a72f5444e077ed21b8e085b17d7f9f1bc44fa5ePeter Qiu#include "shill/net/nl80211_message.h"
611a72f5444e077ed21b8e085b17d7f9f1bc44fa5ePeter Qiu#endif  // DISABLE_WIFI
621a72f5444e077ed21b8e085b17d7f9f1bc44fa5ePeter Qiu
633e20a2341d0aeb7681e4ee0f89eae6817ade2b3bEric Shienbroodusing base::Callback;
640e1cdeae24dd678a5fe27c840802582c0ca45ec0Albert Chaulkusing base::FilePath;
65e6193c042652831cac90c3bbf2233877754b1eefDarin Petkovusing std::map;
665086b9744e8330e7f3bd8ab91fe20b53dda28a1cBen Chanusing std::set;
67633ac6f0d56a62f8fd21ba7d9a15818fe080fb2fDarin Petkovusing std::string;
68cd47732488cd101eaf0d3558dde5a7d4e4fc260bBen Chanusing std::unique_ptr;
699a908080fc2a72dbf06f995b878fc8a3693b725aPaul Stewartusing std::vector;
70633ac6f0d56a62f8fd21ba7d9a15818fe080fb2fDarin Petkovusing testing::_;
712ddf2c63751546aa554335a6733314a3859d5c2ePaul Stewartusing testing::AnyNumber;
725086b9744e8330e7f3bd8ab91fe20b53dda28a1cBen Chanusing testing::ContainerEq;
734178023c4d627410777bdc259bfc7a31f2a4b8e9Gary Morainusing testing::DoAll;
744178023c4d627410777bdc259bfc7a31f2a4b8e9Gary Morainusing testing::ElementsAreArray;
752ddf2c63751546aa554335a6733314a3859d5c2ePaul Stewartusing testing::HasSubstr;
768c116a90d3a3536430b808b15e73275060918434Paul Stewartusing testing::Mock;
774178023c4d627410777bdc259bfc7a31f2a4b8e9Gary Morainusing testing::NotNull;
78633ac6f0d56a62f8fd21ba7d9a15818fe080fb2fDarin Petkovusing testing::Return;
799855170e6e2de08db343640c82795c9b4020a166Peter Qiuusing testing::SetArgPointee;
809a908080fc2a72dbf06f995b878fc8a3693b725aPaul Stewartusing testing::StrictMock;
81633ac6f0d56a62f8fd21ba7d9a15818fe080fb2fDarin Petkovusing testing::Test;
82633ac6f0d56a62f8fd21ba7d9a15818fe080fb2fDarin Petkov
839be4a9d1e87d64f850f15061123b2a4334477fa2Chris Masonenamespace shill {
84633ac6f0d56a62f8fd21ba7d9a15818fe080fb2fDarin Petkov
85050cfc068fda2bd77df2ba08f7b2897bf0e0a6e0Paul Stewartclass TestEventDispatcherForDeviceInfo : public EventDispatcher {
86633ac6f0d56a62f8fd21ba7d9a15818fe080fb2fDarin Petkov public:
873b30ca58d13cf66b75ba0729b222ddc42ae68b33Paul Stewart  virtual IOHandler* CreateInputHandler(
881830fa1f2e8691073f4d07b0883f059a290a9cc2mukesh agrawal      int /*fd*/,
893b30ca58d13cf66b75ba0729b222ddc42ae68b33Paul Stewart      const IOHandler::InputCallback& /*input_callback*/,
903b30ca58d13cf66b75ba0729b222ddc42ae68b33Paul Stewart      const IOHandler::ErrorCallback& /*error_callback*/) {
91cc225ef3b77b5e098cc12c661a947e1737480777Ben Chan    return nullptr;
92633ac6f0d56a62f8fd21ba7d9a15818fe080fb2fDarin Petkov  }
933a62e235646ec19bee71e8dbee5208282dcd13b5Alex Vakulenko  MOCK_METHOD2(PostDelayedTask, void(const base::Closure& task,
947fab89734d88724a288e96a9996b15548c5294c7Ben Chan                                     int64_t delay_ms));
95633ac6f0d56a62f8fd21ba7d9a15818fe080fb2fDarin Petkov};
969be4a9d1e87d64f850f15061123b2a4334477fa2Chris Masone
979be4a9d1e87d64f850f15061123b2a4334477fa2Chris Masoneclass DeviceInfoTest : public Test {
989be4a9d1e87d64f850f15061123b2a4334477fa2Chris Masone public:
999be4a9d1e87d64f850f15061123b2a4334477fa2Chris Masone  DeviceInfoTest()
1006c1e3bbca64d642cb30ed9952203626942bc1451Thieu Le      : metrics_(&dispatcher_),
101bad1c10ffd2d4ac14f7bd9f4ef6a8982e711f566mukesh agrawal        manager_(&control_interface_, &dispatcher_, &metrics_),
1023426c8fc7a3943f2d8fcb2ec78f0593088b42bedThieu Le        device_info_(&control_interface_, &dispatcher_, &metrics_, &manager_) {
1039be4a9d1e87d64f850f15061123b2a4334477fa2Chris Masone  }
104ca876ee6b11b38a3df7a8ab03efe9ed0bcab41d8Paul Stewart  virtual ~DeviceInfoTest() {}
105633ac6f0d56a62f8fd21ba7d9a15818fe080fb2fDarin Petkov
1069a908080fc2a72dbf06f995b878fc8a3693b725aPaul Stewart  virtual void SetUp() {
1079a908080fc2a72dbf06f995b878fc8a3693b725aPaul Stewart    device_info_.rtnl_handler_ = &rtnl_handler_;
1088c116a90d3a3536430b808b15e73275060918434Paul Stewart    device_info_.routing_table_ = &routing_table_;
1091a72f5444e077ed21b8e085b17d7f9f1bc44fa5ePeter Qiu#if !defined(DISABLE_WIFI)
1102ddf2c63751546aa554335a6733314a3859d5c2ePaul Stewart    device_info_.netlink_manager_ = &netlink_manager_;
1111a72f5444e077ed21b8e085b17d7f9f1bc44fa5ePeter Qiu#endif  // DISABLE_WIFI
1129855170e6e2de08db343640c82795c9b4020a166Peter Qiu    device_info_.time_ = &time_;
113d4f26486b237fae831d4b682481de785fc99c66ePaul Stewart    manager_.set_mock_device_info(&device_info_);
1141ce231c71932200e4d02c71567f8e93788120781Paul Stewart    EXPECT_CALL(manager_, FilterPrependDNSServersByFamily(_))
1151ce231c71932200e4d02c71567f8e93788120781Paul Stewart      .WillRepeatedly(Return(vector<string>()));
1169a908080fc2a72dbf06f995b878fc8a3693b725aPaul Stewart  }
1179a908080fc2a72dbf06f995b878fc8a3693b725aPaul Stewart
1188c116a90d3a3536430b808b15e73275060918434Paul Stewart  IPAddress CreateInterfaceAddress() {
1198c116a90d3a3536430b808b15e73275060918434Paul Stewart    // Create an IP address entry (as if left-over from a previous connection
1208c116a90d3a3536430b808b15e73275060918434Paul Stewart    // manager).
1218c116a90d3a3536430b808b15e73275060918434Paul Stewart    IPAddress address(IPAddress::kFamilyIPv4);
1228c116a90d3a3536430b808b15e73275060918434Paul Stewart    EXPECT_TRUE(address.SetAddressFromString(kTestIPAddress0));
1238c116a90d3a3536430b808b15e73275060918434Paul Stewart    address.set_prefix(kTestIPAddressPrefix0);
1243b30ca58d13cf66b75ba0729b222ddc42ae68b33Paul Stewart    vector<DeviceInfo::AddressData>& addresses =
1258c116a90d3a3536430b808b15e73275060918434Paul Stewart        device_info_.infos_[kTestDeviceIndex].ip_addresses;
1268c116a90d3a3536430b808b15e73275060918434Paul Stewart    addresses.push_back(DeviceInfo::AddressData(address, 0, RT_SCOPE_UNIVERSE));
1278c116a90d3a3536430b808b15e73275060918434Paul Stewart    EXPECT_EQ(1, addresses.size());
1288c116a90d3a3536430b808b15e73275060918434Paul Stewart    return address;
1298c116a90d3a3536430b808b15e73275060918434Paul Stewart  }
1308c116a90d3a3536430b808b15e73275060918434Paul Stewart
1313b30ca58d13cf66b75ba0729b222ddc42ae68b33Paul Stewart  DeviceRefPtr CreateDevice(const std::string& link_name,
1323b30ca58d13cf66b75ba0729b222ddc42ae68b33Paul Stewart                            const std::string& address,
1338c116a90d3a3536430b808b15e73275060918434Paul Stewart                            int interface_index,
1348c116a90d3a3536430b808b15e73275060918434Paul Stewart                            Technology::Identifier technology) {
1358c116a90d3a3536430b808b15e73275060918434Paul Stewart    return device_info_.CreateDevice(link_name, address, interface_index,
1368c116a90d3a3536430b808b15e73275060918434Paul Stewart                                     technology);
1378c116a90d3a3536430b808b15e73275060918434Paul Stewart  }
1388c116a90d3a3536430b808b15e73275060918434Paul Stewart
1393b30ca58d13cf66b75ba0729b222ddc42ae68b33Paul Stewart  virtual std::set<int>& GetDelayedDevices() {
140050cfc068fda2bd77df2ba08f7b2897bf0e0a6e0Paul Stewart    return device_info_.delayed_devices_;
141050cfc068fda2bd77df2ba08f7b2897bf0e0a6e0Paul Stewart  }
142050cfc068fda2bd77df2ba08f7b2897bf0e0a6e0Paul Stewart
1431ac4e84148e03752d99aecea4f743abb094f28b0Paul Stewart  int GetDelayedDeviceCreationMilliseconds() {
144050cfc068fda2bd77df2ba08f7b2897bf0e0a6e0Paul Stewart    return DeviceInfo::kDelayedDeviceCreationSeconds * 1000;
145050cfc068fda2bd77df2ba08f7b2897bf0e0a6e0Paul Stewart  }
1468c116a90d3a3536430b808b15e73275060918434Paul Stewart
1474178023c4d627410777bdc259bfc7a31f2a4b8e9Gary Morain  void SetSockets() {
1484178023c4d627410777bdc259bfc7a31f2a4b8e9Gary Morain    mock_sockets_ = new MockSockets();
1494178023c4d627410777bdc259bfc7a31f2a4b8e9Gary Morain    device_info_.set_sockets(mock_sockets_);
1504178023c4d627410777bdc259bfc7a31f2a4b8e9Gary Morain  }
1514178023c4d627410777bdc259bfc7a31f2a4b8e9Gary Morain
152c3505a569e3f98ce56e4017300a3ce46bc714e4cDarin Petkov  // Takes ownership of |provider|.
1533b30ca58d13cf66b75ba0729b222ddc42ae68b33Paul Stewart  void SetVPNProvider(VPNProvider* provider) {
154c3505a569e3f98ce56e4017300a3ce46bc714e4cDarin Petkov    manager_.vpn_provider_.reset(provider);
155b87d22b774fe15b6580d13638d5f0514bde031fdPaul Stewart    manager_.UpdateProviderMapping();
156c3505a569e3f98ce56e4017300a3ce46bc714e4cDarin Petkov  }
157c3505a569e3f98ce56e4017300a3ce46bc714e4cDarin Petkov
158ebd709e7d7519915930404be7120cd8070b432c4Peter Qiu  void SetManagerRunning(bool running) {
159ebd709e7d7519915930404be7120cd8070b432c4Peter Qiu    manager_.running_ = running;
160ebd709e7d7519915930404be7120cd8070b432c4Peter Qiu  }
161ebd709e7d7519915930404be7120cd8070b432c4Peter Qiu
162a3c56f9f49e6c72ff55cc1224cccd60538e9b788Paul Stewart protected:
163b2e326bf37654683cdc8c0cbbab29d1af7910af8Chris Masone  static const int kTestDeviceIndex;
164633ac6f0d56a62f8fd21ba7d9a15818fe080fb2fDarin Petkov  static const char kTestDeviceName[];
165fc34925d45add6f1c81a42a7632621e69bfdc43eHan Shen  static const uint8_t kTestMACAddress[];
1669a908080fc2a72dbf06f995b878fc8a3693b725aPaul Stewart  static const char kTestIPAddress0[];
1679a908080fc2a72dbf06f995b878fc8a3693b725aPaul Stewart  static const int kTestIPAddressPrefix0;
1689a908080fc2a72dbf06f995b878fc8a3693b725aPaul Stewart  static const char kTestIPAddress1[];
1699a908080fc2a72dbf06f995b878fc8a3693b725aPaul Stewart  static const int kTestIPAddressPrefix1;
1709a908080fc2a72dbf06f995b878fc8a3693b725aPaul Stewart  static const char kTestIPAddress2[];
1719a908080fc2a72dbf06f995b878fc8a3693b725aPaul Stewart  static const char kTestIPAddress3[];
1729a908080fc2a72dbf06f995b878fc8a3693b725aPaul Stewart  static const char kTestIPAddress4[];
17305a42c23f1d37daa8689fc4240034e62ed89f8fcPaul Stewart  static const char kTestIPAddress5[];
174a0db0fff6ae05e1ba3facfdf3d5049ca1a277be4Paul Stewart  static const char kTestIPAddress6[];
175241e3f317fe3089dd7dcb4e7c5a34430926d4e2ePaul Stewart  static const char kTestIPAddress7[];
1761ac4e84148e03752d99aecea4f743abb094f28b0Paul Stewart  static const int kReceiveByteCount;
1771ac4e84148e03752d99aecea4f743abb094f28b0Paul Stewart  static const int kTransmitByteCount;
178633ac6f0d56a62f8fd21ba7d9a15818fe080fb2fDarin Petkov
1793b30ca58d13cf66b75ba0729b222ddc42ae68b33Paul Stewart  RTNLMessage* BuildLinkMessage(RTNLMessage::Mode mode);
1803b30ca58d13cf66b75ba0729b222ddc42ae68b33Paul Stewart  RTNLMessage* BuildLinkMessageWithInterfaceName(RTNLMessage::Mode mode,
1813b30ca58d13cf66b75ba0729b222ddc42ae68b33Paul Stewart                                                 const string& interface_name);
1823b30ca58d13cf66b75ba0729b222ddc42ae68b33Paul Stewart  RTNLMessage* BuildAddressMessage(RTNLMessage::Mode mode,
1833b30ca58d13cf66b75ba0729b222ddc42ae68b33Paul Stewart                                   const IPAddress& address,
1849a908080fc2a72dbf06f995b878fc8a3693b725aPaul Stewart                                   unsigned char flags,
1859a908080fc2a72dbf06f995b878fc8a3693b725aPaul Stewart                                   unsigned char scope);
1863b30ca58d13cf66b75ba0729b222ddc42ae68b33Paul Stewart  RTNLMessage* BuildRdnssMessage(RTNLMessage::Mode mode,
1877fab89734d88724a288e96a9996b15548c5294c7Ben Chan                                 uint32_t lifetime,
1883b30ca58d13cf66b75ba0729b222ddc42ae68b33Paul Stewart                                 const vector<IPAddress>& dns_servers);
1893b30ca58d13cf66b75ba0729b222ddc42ae68b33Paul Stewart  void SendMessageToDeviceInfo(const RTNLMessage& message);
190633ac6f0d56a62f8fd21ba7d9a15818fe080fb2fDarin Petkov
19146eaaf53d5e5b92f418b8d7cbfe7e847b575791fChris Masone  MockControl control_interface_;
1923426c8fc7a3943f2d8fcb2ec78f0593088b42bedThieu Le  MockMetrics metrics_;
1939a908080fc2a72dbf06f995b878fc8a3693b725aPaul Stewart  StrictMock<MockManager> manager_;
1949be4a9d1e87d64f850f15061123b2a4334477fa2Chris Masone  DeviceInfo device_info_;
195050cfc068fda2bd77df2ba08f7b2897bf0e0a6e0Paul Stewart  TestEventDispatcherForDeviceInfo dispatcher_;
1968c116a90d3a3536430b808b15e73275060918434Paul Stewart  MockRoutingTable routing_table_;
1971a72f5444e077ed21b8e085b17d7f9f1bc44fa5ePeter Qiu#if !defined(DISABLE_WIFI)
1982ddf2c63751546aa554335a6733314a3859d5c2ePaul Stewart  MockNetlinkManager netlink_manager_;
1991a72f5444e077ed21b8e085b17d7f9f1bc44fa5ePeter Qiu#endif  // DISABLE_WIFI
2009a908080fc2a72dbf06f995b878fc8a3693b725aPaul Stewart  StrictMock<MockRTNLHandler> rtnl_handler_;
2013b30ca58d13cf66b75ba0729b222ddc42ae68b33Paul Stewart  MockSockets* mock_sockets_;  // Owned by DeviceInfo.
2029855170e6e2de08db343640c82795c9b4020a166Peter Qiu  MockTime time_;
2039be4a9d1e87d64f850f15061123b2a4334477fa2Chris Masone};
2049be4a9d1e87d64f850f15061123b2a4334477fa2Chris Masone
205b2e326bf37654683cdc8c0cbbab29d1af7910af8Chris Masoneconst int DeviceInfoTest::kTestDeviceIndex = 123456;
206633ac6f0d56a62f8fd21ba7d9a15818fe080fb2fDarin Petkovconst char DeviceInfoTest::kTestDeviceName[] = "test-device";
207fc34925d45add6f1c81a42a7632621e69bfdc43eHan Shenconst uint8_t DeviceInfoTest::kTestMACAddress[] = {
2087347bf2b466ae8058e47b29aaf0583390405d866Wade Guthrie    0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff };
2099a908080fc2a72dbf06f995b878fc8a3693b725aPaul Stewartconst char DeviceInfoTest::kTestIPAddress0[] = "192.168.1.1";
2109a908080fc2a72dbf06f995b878fc8a3693b725aPaul Stewartconst int DeviceInfoTest::kTestIPAddressPrefix0 = 24;
2119a908080fc2a72dbf06f995b878fc8a3693b725aPaul Stewartconst char DeviceInfoTest::kTestIPAddress1[] = "fe80::1aa9:5ff:abcd:1234";
2129a908080fc2a72dbf06f995b878fc8a3693b725aPaul Stewartconst int DeviceInfoTest::kTestIPAddressPrefix1 = 64;
2139a908080fc2a72dbf06f995b878fc8a3693b725aPaul Stewartconst char DeviceInfoTest::kTestIPAddress2[] = "fe80::1aa9:5ff:abcd:1235";
2149a908080fc2a72dbf06f995b878fc8a3693b725aPaul Stewartconst char DeviceInfoTest::kTestIPAddress3[] = "fe80::1aa9:5ff:abcd:1236";
2159a908080fc2a72dbf06f995b878fc8a3693b725aPaul Stewartconst char DeviceInfoTest::kTestIPAddress4[] = "fe80::1aa9:5ff:abcd:1237";
21605a42c23f1d37daa8689fc4240034e62ed89f8fcPaul Stewartconst char DeviceInfoTest::kTestIPAddress5[] = "192.168.1.2";
217a0db0fff6ae05e1ba3facfdf3d5049ca1a277be4Paul Stewartconst char DeviceInfoTest::kTestIPAddress6[] = "192.168.2.2";
218241e3f317fe3089dd7dcb4e7c5a34430926d4e2ePaul Stewartconst char DeviceInfoTest::kTestIPAddress7[] = "fe80::1aa9:5ff:abcd:1238";
2191ac4e84148e03752d99aecea4f743abb094f28b0Paul Stewartconst int DeviceInfoTest::kReceiveByteCount = 1234;
2201ac4e84148e03752d99aecea4f743abb094f28b0Paul Stewartconst int DeviceInfoTest::kTransmitByteCount = 5678;
2219be4a9d1e87d64f850f15061123b2a4334477fa2Chris Masone
2223b30ca58d13cf66b75ba0729b222ddc42ae68b33Paul StewartRTNLMessage* DeviceInfoTest::BuildLinkMessageWithInterfaceName(
2233b30ca58d13cf66b75ba0729b222ddc42ae68b33Paul Stewart    RTNLMessage::Mode mode, const string& interface_name) {
2243b30ca58d13cf66b75ba0729b222ddc42ae68b33Paul Stewart  RTNLMessage* message = new RTNLMessage(
2259a908080fc2a72dbf06f995b878fc8a3693b725aPaul Stewart      RTNLMessage::kTypeLink,
2269a908080fc2a72dbf06f995b878fc8a3693b725aPaul Stewart      mode,
2279a908080fc2a72dbf06f995b878fc8a3693b725aPaul Stewart      0,
2289a908080fc2a72dbf06f995b878fc8a3693b725aPaul Stewart      0,
2299a908080fc2a72dbf06f995b878fc8a3693b725aPaul Stewart      0,
2309a908080fc2a72dbf06f995b878fc8a3693b725aPaul Stewart      kTestDeviceIndex,
2317355ce1937c504d836a303ac809bd436272212b3Paul Stewart      IPAddress::kFamilyIPv4);
2327fab89734d88724a288e96a9996b15548c5294c7Ben Chan  message->SetAttribute(static_cast<uint16_t>(IFLA_IFNAME),
233e81eb700f66563cb695b6e3682f20ac5a0cdb8c0Paul Stewart                        ByteString(interface_name, true));
2349a908080fc2a72dbf06f995b878fc8a3693b725aPaul Stewart  ByteString test_address(kTestMACAddress, sizeof(kTestMACAddress));
235626719f89881a949d8b5a8fa808beb924496489fChris Masone  message->SetAttribute(IFLA_ADDRESS, test_address);
2362aa9707f114ab8166f45df5726bf05278df2aef6Chris Masone  return message;
237633ac6f0d56a62f8fd21ba7d9a15818fe080fb2fDarin Petkov}
238633ac6f0d56a62f8fd21ba7d9a15818fe080fb2fDarin Petkov
2393b30ca58d13cf66b75ba0729b222ddc42ae68b33Paul StewartRTNLMessage* DeviceInfoTest::BuildLinkMessage(RTNLMessage::Mode mode) {
240e81eb700f66563cb695b6e3682f20ac5a0cdb8c0Paul Stewart  return BuildLinkMessageWithInterfaceName(mode, kTestDeviceName);
241e81eb700f66563cb695b6e3682f20ac5a0cdb8c0Paul Stewart}
242e81eb700f66563cb695b6e3682f20ac5a0cdb8c0Paul Stewart
2433b30ca58d13cf66b75ba0729b222ddc42ae68b33Paul StewartRTNLMessage* DeviceInfoTest::BuildAddressMessage(RTNLMessage::Mode mode,
2443b30ca58d13cf66b75ba0729b222ddc42ae68b33Paul Stewart                                                 const IPAddress& address,
2459a908080fc2a72dbf06f995b878fc8a3693b725aPaul Stewart                                                 unsigned char flags,
2469a908080fc2a72dbf06f995b878fc8a3693b725aPaul Stewart                                                 unsigned char scope) {
2473b30ca58d13cf66b75ba0729b222ddc42ae68b33Paul Stewart  RTNLMessage* message = new RTNLMessage(
2489a908080fc2a72dbf06f995b878fc8a3693b725aPaul Stewart      RTNLMessage::kTypeAddress,
2499a908080fc2a72dbf06f995b878fc8a3693b725aPaul Stewart      mode,
2509a908080fc2a72dbf06f995b878fc8a3693b725aPaul Stewart      0,
2519a908080fc2a72dbf06f995b878fc8a3693b725aPaul Stewart      0,
2529a908080fc2a72dbf06f995b878fc8a3693b725aPaul Stewart      0,
2539a908080fc2a72dbf06f995b878fc8a3693b725aPaul Stewart      kTestDeviceIndex,
2549a908080fc2a72dbf06f995b878fc8a3693b725aPaul Stewart      address.family());
2559a908080fc2a72dbf06f995b878fc8a3693b725aPaul Stewart  message->SetAttribute(IFA_ADDRESS, address.address());
2569a908080fc2a72dbf06f995b878fc8a3693b725aPaul Stewart  message->set_address_status(
2579a908080fc2a72dbf06f995b878fc8a3693b725aPaul Stewart      RTNLMessage::AddressStatus(address.prefix(), flags, scope));
2589a908080fc2a72dbf06f995b878fc8a3693b725aPaul Stewart  return message;
2599a908080fc2a72dbf06f995b878fc8a3693b725aPaul Stewart}
2609a908080fc2a72dbf06f995b878fc8a3693b725aPaul Stewart
2613b30ca58d13cf66b75ba0729b222ddc42ae68b33Paul StewartRTNLMessage* DeviceInfoTest::BuildRdnssMessage(RTNLMessage::Mode mode,
2623b30ca58d13cf66b75ba0729b222ddc42ae68b33Paul Stewart    uint32_t lifetime, const vector<IPAddress>& dns_servers) {
2633b30ca58d13cf66b75ba0729b222ddc42ae68b33Paul Stewart  RTNLMessage* message = new RTNLMessage(
2649855170e6e2de08db343640c82795c9b4020a166Peter Qiu      RTNLMessage::kTypeRdnss,
2659855170e6e2de08db343640c82795c9b4020a166Peter Qiu      mode,
2669855170e6e2de08db343640c82795c9b4020a166Peter Qiu      0,
2679855170e6e2de08db343640c82795c9b4020a166Peter Qiu      0,
2689855170e6e2de08db343640c82795c9b4020a166Peter Qiu      0,
2699855170e6e2de08db343640c82795c9b4020a166Peter Qiu      kTestDeviceIndex,
2709855170e6e2de08db343640c82795c9b4020a166Peter Qiu      IPAddress::kFamilyIPv6);
2719855170e6e2de08db343640c82795c9b4020a166Peter Qiu  message->set_rdnss_option(
2729855170e6e2de08db343640c82795c9b4020a166Peter Qiu      RTNLMessage::RdnssOption(lifetime, dns_servers));
2739855170e6e2de08db343640c82795c9b4020a166Peter Qiu  return message;
2749855170e6e2de08db343640c82795c9b4020a166Peter Qiu}
2759855170e6e2de08db343640c82795c9b4020a166Peter Qiu
2763b30ca58d13cf66b75ba0729b222ddc42ae68b33Paul Stewartvoid DeviceInfoTest::SendMessageToDeviceInfo(const RTNLMessage& message) {
2779a908080fc2a72dbf06f995b878fc8a3693b725aPaul Stewart  if (message.type() == RTNLMessage::kTypeLink) {
2789a908080fc2a72dbf06f995b878fc8a3693b725aPaul Stewart    device_info_.LinkMsgHandler(message);
2799a908080fc2a72dbf06f995b878fc8a3693b725aPaul Stewart  } else if (message.type() == RTNLMessage::kTypeAddress) {
2809a908080fc2a72dbf06f995b878fc8a3693b725aPaul Stewart    device_info_.AddressMsgHandler(message);
2819855170e6e2de08db343640c82795c9b4020a166Peter Qiu  } else if (message.type() == RTNLMessage::kTypeRdnss) {
2829855170e6e2de08db343640c82795c9b4020a166Peter Qiu    device_info_.RdnssMsgHandler(message);
2839a908080fc2a72dbf06f995b878fc8a3693b725aPaul Stewart  } else {
2849a908080fc2a72dbf06f995b878fc8a3693b725aPaul Stewart    NOTREACHED();
2859a908080fc2a72dbf06f995b878fc8a3693b725aPaul Stewart  }
2869a908080fc2a72dbf06f995b878fc8a3693b725aPaul Stewart}
2879a908080fc2a72dbf06f995b878fc8a3693b725aPaul Stewart
2889a908080fc2a72dbf06f995b878fc8a3693b725aPaul StewartMATCHER_P(IsIPAddress, address, "") {
2899a908080fc2a72dbf06f995b878fc8a3693b725aPaul Stewart  // NB: IPAddress objects don't support the "==" operator as per style, so
2909a908080fc2a72dbf06f995b878fc8a3693b725aPaul Stewart  // we need a custom matcher.
2919a908080fc2a72dbf06f995b878fc8a3693b725aPaul Stewart  return address.Equals(arg);
292633ac6f0d56a62f8fd21ba7d9a15818fe080fb2fDarin Petkov}
293633ac6f0d56a62f8fd21ba7d9a15818fe080fb2fDarin Petkov
2948c116a90d3a3536430b808b15e73275060918434Paul StewartTEST_F(DeviceInfoTest, StartStop) {
2958c116a90d3a3536430b808b15e73275060918434Paul Stewart  EXPECT_FALSE(device_info_.link_listener_.get());
2968c116a90d3a3536430b808b15e73275060918434Paul Stewart  EXPECT_FALSE(device_info_.address_listener_.get());
2978c116a90d3a3536430b808b15e73275060918434Paul Stewart  EXPECT_TRUE(device_info_.infos_.empty());
2988c116a90d3a3536430b808b15e73275060918434Paul Stewart
2998c116a90d3a3536430b808b15e73275060918434Paul Stewart  EXPECT_CALL(rtnl_handler_, RequestDump(RTNLHandler::kRequestLink |
3008c116a90d3a3536430b808b15e73275060918434Paul Stewart                                         RTNLHandler::kRequestAddr));
3011ac4e84148e03752d99aecea4f743abb094f28b0Paul Stewart  EXPECT_CALL(dispatcher_, PostDelayedTask(
302b061f89e7088c7fba50b49ee5ac876619c9e8a7eBen Chan      _, DeviceInfo::kRequestLinkStatisticsIntervalMilliseconds));
3039be4a9d1e87d64f850f15061123b2a4334477fa2Chris Masone  device_info_.Start();
3048c116a90d3a3536430b808b15e73275060918434Paul Stewart  EXPECT_TRUE(device_info_.link_listener_.get());
3058c116a90d3a3536430b808b15e73275060918434Paul Stewart  EXPECT_TRUE(device_info_.address_listener_.get());
3068c116a90d3a3536430b808b15e73275060918434Paul Stewart  EXPECT_TRUE(device_info_.infos_.empty());
3078c116a90d3a3536430b808b15e73275060918434Paul Stewart  Mock::VerifyAndClearExpectations(&rtnl_handler_);
3088c116a90d3a3536430b808b15e73275060918434Paul Stewart
3098c116a90d3a3536430b808b15e73275060918434Paul Stewart  CreateInterfaceAddress();
3108c116a90d3a3536430b808b15e73275060918434Paul Stewart  EXPECT_FALSE(device_info_.infos_.empty());
3118c116a90d3a3536430b808b15e73275060918434Paul Stewart
3128c116a90d3a3536430b808b15e73275060918434Paul Stewart  device_info_.Stop();
3138c116a90d3a3536430b808b15e73275060918434Paul Stewart  EXPECT_FALSE(device_info_.link_listener_.get());
3148c116a90d3a3536430b808b15e73275060918434Paul Stewart  EXPECT_FALSE(device_info_.address_listener_.get());
3158c116a90d3a3536430b808b15e73275060918434Paul Stewart  EXPECT_TRUE(device_info_.infos_.empty());
3168c116a90d3a3536430b808b15e73275060918434Paul Stewart}
3178c116a90d3a3536430b808b15e73275060918434Paul Stewart
3188ce932a8ebf3af11f17b814c4e544a305607afcaChristopher GrantTEST_F(DeviceInfoTest, RegisterDevice) {
3198ce932a8ebf3af11f17b814c4e544a305607afcaChristopher Grant  scoped_refptr<MockDevice> device0(new MockDevice(
3208ce932a8ebf3af11f17b814c4e544a305607afcaChristopher Grant      &control_interface_, &dispatcher_, &metrics_, &manager_,
3218ce932a8ebf3af11f17b814c4e544a305607afcaChristopher Grant      "null0", "addr0", kTestDeviceIndex));
3228ce932a8ebf3af11f17b814c4e544a305607afcaChristopher Grant
3238ce932a8ebf3af11f17b814c4e544a305607afcaChristopher Grant  EXPECT_CALL(*device0, Initialize());
3248ce932a8ebf3af11f17b814c4e544a305607afcaChristopher Grant  device_info_.RegisterDevice(device0);
3258ce932a8ebf3af11f17b814c4e544a305607afcaChristopher Grant}
3268ce932a8ebf3af11f17b814c4e544a305607afcaChristopher Grant
3271ac4e84148e03752d99aecea4f743abb094f28b0Paul StewartTEST_F(DeviceInfoTest, RequestLinkStatistics) {
3281ac4e84148e03752d99aecea4f743abb094f28b0Paul Stewart  EXPECT_CALL(rtnl_handler_, RequestDump(RTNLHandler::kRequestLink));
3291ac4e84148e03752d99aecea4f743abb094f28b0Paul Stewart  EXPECT_CALL(dispatcher_, PostDelayedTask(
330b061f89e7088c7fba50b49ee5ac876619c9e8a7eBen Chan      _, DeviceInfo::kRequestLinkStatisticsIntervalMilliseconds));
3311ac4e84148e03752d99aecea4f743abb094f28b0Paul Stewart  device_info_.RequestLinkStatistics();
3321ac4e84148e03752d99aecea4f743abb094f28b0Paul Stewart}
3331ac4e84148e03752d99aecea4f743abb094f28b0Paul Stewart
3348c116a90d3a3536430b808b15e73275060918434Paul StewartTEST_F(DeviceInfoTest, DeviceEnumeration) {
335cd47732488cd101eaf0d3558dde5a7d4e4fc260bBen Chan  unique_ptr<RTNLMessage> message(BuildLinkMessage(RTNLMessage::kModeAdd));
336e6193c042652831cac90c3bbf2233877754b1eefDarin Petkov  message->set_link_status(RTNLMessage::LinkStatus(0, IFF_LOWER_UP, 0));
337e6193c042652831cac90c3bbf2233877754b1eefDarin Petkov  EXPECT_FALSE(device_info_.GetDevice(kTestDeviceIndex).get());
338f8046b8f975417255baf5cc7cdd025c63aa2f918Darin Petkov  EXPECT_EQ(-1, device_info_.GetIndex(kTestDeviceName));
339e6193c042652831cac90c3bbf2233877754b1eefDarin Petkov  SendMessageToDeviceInfo(*message);
340e6193c042652831cac90c3bbf2233877754b1eefDarin Petkov  EXPECT_TRUE(device_info_.GetDevice(kTestDeviceIndex).get());
341e6193c042652831cac90c3bbf2233877754b1eefDarin Petkov  unsigned int flags = 0;
342e6193c042652831cac90c3bbf2233877754b1eefDarin Petkov  EXPECT_TRUE(device_info_.GetFlags(kTestDeviceIndex, &flags));
343e6193c042652831cac90c3bbf2233877754b1eefDarin Petkov  EXPECT_EQ(IFF_LOWER_UP, flags);
344e3e1cfaadc69ea67db55f11e55f404b11a70e354Darin Petkov  ByteString address;
3453285296e6624fa0b1b10699f2fa6466d4be10742Paul Stewart  EXPECT_TRUE(device_info_.GetMACAddress(kTestDeviceIndex, &address));
346e3e1cfaadc69ea67db55f11e55f404b11a70e354Darin Petkov  EXPECT_FALSE(address.IsEmpty());
3479a908080fc2a72dbf06f995b878fc8a3693b725aPaul Stewart  EXPECT_TRUE(address.Equals(ByteString(kTestMACAddress,
3489a908080fc2a72dbf06f995b878fc8a3693b725aPaul Stewart                                        sizeof(kTestMACAddress))));
349f8046b8f975417255baf5cc7cdd025c63aa2f918Darin Petkov  EXPECT_EQ(kTestDeviceIndex, device_info_.GetIndex(kTestDeviceName));
350a3c56f9f49e6c72ff55cc1224cccd60538e9b788Paul Stewart
3519a908080fc2a72dbf06f995b878fc8a3693b725aPaul Stewart  message.reset(BuildLinkMessage(RTNLMessage::kModeAdd));
352e6193c042652831cac90c3bbf2233877754b1eefDarin Petkov  message->set_link_status(RTNLMessage::LinkStatus(0, IFF_UP | IFF_RUNNING, 0));
353e6193c042652831cac90c3bbf2233877754b1eefDarin Petkov  SendMessageToDeviceInfo(*message);
354e6193c042652831cac90c3bbf2233877754b1eefDarin Petkov  EXPECT_TRUE(device_info_.GetFlags(kTestDeviceIndex, &flags));
355e6193c042652831cac90c3bbf2233877754b1eefDarin Petkov  EXPECT_EQ(IFF_UP | IFF_RUNNING, flags);
356a3c56f9f49e6c72ff55cc1224cccd60538e9b788Paul Stewart
3579a908080fc2a72dbf06f995b878fc8a3693b725aPaul Stewart  message.reset(BuildLinkMessage(RTNLMessage::kModeDelete));
3588c116a90d3a3536430b808b15e73275060918434Paul Stewart  EXPECT_CALL(manager_, DeregisterDevice(_)).Times(1);
359e6193c042652831cac90c3bbf2233877754b1eefDarin Petkov  SendMessageToDeviceInfo(*message);
360e6193c042652831cac90c3bbf2233877754b1eefDarin Petkov  EXPECT_FALSE(device_info_.GetDevice(kTestDeviceIndex).get());
361cc225ef3b77b5e098cc12c661a947e1737480777Ben Chan  EXPECT_FALSE(device_info_.GetFlags(kTestDeviceIndex, nullptr));
362f8046b8f975417255baf5cc7cdd025c63aa2f918Darin Petkov  EXPECT_EQ(-1, device_info_.GetIndex(kTestDeviceName));
3638c116a90d3a3536430b808b15e73275060918434Paul Stewart}
364a3c56f9f49e6c72ff55cc1224cccd60538e9b788Paul Stewart
3659f5159e07028a01e1353d68bc19da9817a6785fePeter QiuTEST_F(DeviceInfoTest, DeviceRemovedEvent) {
3669f5159e07028a01e1353d68bc19da9817a6785fePeter Qiu  // Remove a Wifi device.
3679f5159e07028a01e1353d68bc19da9817a6785fePeter Qiu  scoped_refptr<MockDevice> device0(new MockDevice(
3689f5159e07028a01e1353d68bc19da9817a6785fePeter Qiu      &control_interface_, &dispatcher_, &metrics_, &manager_,
3699f5159e07028a01e1353d68bc19da9817a6785fePeter Qiu      "null0", "addr0", kTestDeviceIndex));
3709f5159e07028a01e1353d68bc19da9817a6785fePeter Qiu  device_info_.infos_[kTestDeviceIndex].device = device0;
371cd47732488cd101eaf0d3558dde5a7d4e4fc260bBen Chan  unique_ptr<RTNLMessage> message(BuildLinkMessage(RTNLMessage::kModeDelete));
3729f5159e07028a01e1353d68bc19da9817a6785fePeter Qiu  EXPECT_CALL(*device0, technology()).WillRepeatedly(Return(Technology::kWifi));
3739f5159e07028a01e1353d68bc19da9817a6785fePeter Qiu  EXPECT_CALL(manager_, DeregisterDevice(_)).Times(1);
3749f5159e07028a01e1353d68bc19da9817a6785fePeter Qiu  EXPECT_CALL(metrics_, DeregisterDevice(kTestDeviceIndex)).Times(1);
3759f5159e07028a01e1353d68bc19da9817a6785fePeter Qiu  SendMessageToDeviceInfo(*message);
3760951ccbfca977a9cf218b2e4308aa26fb4d06ef9Alex Vakulenko  Mock::VerifyAndClearExpectations(device0.get());
3779f5159e07028a01e1353d68bc19da9817a6785fePeter Qiu
3789f5159e07028a01e1353d68bc19da9817a6785fePeter Qiu  // Deregister a Cellular device.
3799f5159e07028a01e1353d68bc19da9817a6785fePeter Qiu  scoped_refptr<MockDevice> device1(new MockDevice(
3809f5159e07028a01e1353d68bc19da9817a6785fePeter Qiu      &control_interface_, &dispatcher_, &metrics_, &manager_,
3819f5159e07028a01e1353d68bc19da9817a6785fePeter Qiu      "null0", "addr0", kTestDeviceIndex));
3829f5159e07028a01e1353d68bc19da9817a6785fePeter Qiu  device_info_.infos_[kTestDeviceIndex].device = device1;
3839f5159e07028a01e1353d68bc19da9817a6785fePeter Qiu  EXPECT_CALL(*device1, technology()).
3849f5159e07028a01e1353d68bc19da9817a6785fePeter Qiu      WillRepeatedly(Return(Technology::kCellular));
3859f5159e07028a01e1353d68bc19da9817a6785fePeter Qiu  EXPECT_CALL(manager_, DeregisterDevice(_)).Times(1);
3869f5159e07028a01e1353d68bc19da9817a6785fePeter Qiu  EXPECT_CALL(metrics_, DeregisterDevice(kTestDeviceIndex)).Times(1);
3879f5159e07028a01e1353d68bc19da9817a6785fePeter Qiu  device_info_.DeregisterDevice(device1);
3889f5159e07028a01e1353d68bc19da9817a6785fePeter Qiu}
3899f5159e07028a01e1353d68bc19da9817a6785fePeter Qiu
3905086b9744e8330e7f3bd8ab91fe20b53dda28a1cBen ChanTEST_F(DeviceInfoTest, GetUninitializedTechnologies) {
3915086b9744e8330e7f3bd8ab91fe20b53dda28a1cBen Chan  vector<string> technologies = device_info_.GetUninitializedTechnologies();
3925086b9744e8330e7f3bd8ab91fe20b53dda28a1cBen Chan  set<string> expected_technologies;
3935086b9744e8330e7f3bd8ab91fe20b53dda28a1cBen Chan
3945086b9744e8330e7f3bd8ab91fe20b53dda28a1cBen Chan  EXPECT_THAT(set<string>(technologies.begin(), technologies.end()),
3955086b9744e8330e7f3bd8ab91fe20b53dda28a1cBen Chan              ContainerEq(expected_technologies));
3965086b9744e8330e7f3bd8ab91fe20b53dda28a1cBen Chan
3975086b9744e8330e7f3bd8ab91fe20b53dda28a1cBen Chan  device_info_.infos_[0].technology = Technology::kUnknown;
3985086b9744e8330e7f3bd8ab91fe20b53dda28a1cBen Chan  EXPECT_THAT(set<string>(technologies.begin(), technologies.end()),
3995086b9744e8330e7f3bd8ab91fe20b53dda28a1cBen Chan              ContainerEq(expected_technologies));
4005086b9744e8330e7f3bd8ab91fe20b53dda28a1cBen Chan
4015086b9744e8330e7f3bd8ab91fe20b53dda28a1cBen Chan  device_info_.infos_[1].technology = Technology::kCellular;
4025086b9744e8330e7f3bd8ab91fe20b53dda28a1cBen Chan  technologies = device_info_.GetUninitializedTechnologies();
4035086b9744e8330e7f3bd8ab91fe20b53dda28a1cBen Chan  expected_technologies.insert(Technology::NameFromIdentifier(
4045086b9744e8330e7f3bd8ab91fe20b53dda28a1cBen Chan      Technology::kCellular));
4055086b9744e8330e7f3bd8ab91fe20b53dda28a1cBen Chan  EXPECT_THAT(set<string>(technologies.begin(), technologies.end()),
4065086b9744e8330e7f3bd8ab91fe20b53dda28a1cBen Chan              ContainerEq(expected_technologies));
4075086b9744e8330e7f3bd8ab91fe20b53dda28a1cBen Chan
4085086b9744e8330e7f3bd8ab91fe20b53dda28a1cBen Chan  device_info_.infos_[2].technology = Technology::kWiMax;
4095086b9744e8330e7f3bd8ab91fe20b53dda28a1cBen Chan  technologies = device_info_.GetUninitializedTechnologies();
4105086b9744e8330e7f3bd8ab91fe20b53dda28a1cBen Chan  expected_technologies.insert(Technology::NameFromIdentifier(
4115086b9744e8330e7f3bd8ab91fe20b53dda28a1cBen Chan      Technology::kWiMax));
4125086b9744e8330e7f3bd8ab91fe20b53dda28a1cBen Chan  EXPECT_THAT(set<string>(technologies.begin(), technologies.end()),
4135086b9744e8330e7f3bd8ab91fe20b53dda28a1cBen Chan              ContainerEq(expected_technologies));
4145086b9744e8330e7f3bd8ab91fe20b53dda28a1cBen Chan
4155086b9744e8330e7f3bd8ab91fe20b53dda28a1cBen Chan  scoped_refptr<MockDevice> device(new MockDevice(
4165086b9744e8330e7f3bd8ab91fe20b53dda28a1cBen Chan      &control_interface_, &dispatcher_, &metrics_, &manager_,
4175086b9744e8330e7f3bd8ab91fe20b53dda28a1cBen Chan      "null0", "addr0", 1));
4185086b9744e8330e7f3bd8ab91fe20b53dda28a1cBen Chan  device_info_.infos_[1].device = device;
4195086b9744e8330e7f3bd8ab91fe20b53dda28a1cBen Chan  technologies = device_info_.GetUninitializedTechnologies();
4205086b9744e8330e7f3bd8ab91fe20b53dda28a1cBen Chan  expected_technologies.erase(Technology::NameFromIdentifier(
4215086b9744e8330e7f3bd8ab91fe20b53dda28a1cBen Chan      Technology::kCellular));
4225086b9744e8330e7f3bd8ab91fe20b53dda28a1cBen Chan  EXPECT_THAT(set<string>(technologies.begin(), technologies.end()),
4235086b9744e8330e7f3bd8ab91fe20b53dda28a1cBen Chan              ContainerEq(expected_technologies));
4245086b9744e8330e7f3bd8ab91fe20b53dda28a1cBen Chan
4255086b9744e8330e7f3bd8ab91fe20b53dda28a1cBen Chan  device_info_.infos_[3].technology = Technology::kCellular;
4265086b9744e8330e7f3bd8ab91fe20b53dda28a1cBen Chan  technologies = device_info_.GetUninitializedTechnologies();
427b00c13d6444ba67154acffec537bdb466099f7b1Arman Uguray  EXPECT_THAT(set<string>(technologies.begin(), technologies.end()),
428b00c13d6444ba67154acffec537bdb466099f7b1Arman Uguray              ContainerEq(expected_technologies));
429b00c13d6444ba67154acffec537bdb466099f7b1Arman Uguray
430b00c13d6444ba67154acffec537bdb466099f7b1Arman Uguray  device_info_.infos_[3].device = device;
431cc225ef3b77b5e098cc12c661a947e1737480777Ben Chan  device_info_.infos_[1].device = nullptr;
432b00c13d6444ba67154acffec537bdb466099f7b1Arman Uguray  technologies = device_info_.GetUninitializedTechnologies();
4335086b9744e8330e7f3bd8ab91fe20b53dda28a1cBen Chan  EXPECT_THAT(set<string>(technologies.begin(), technologies.end()),
4345086b9744e8330e7f3bd8ab91fe20b53dda28a1cBen Chan              ContainerEq(expected_technologies));
4355086b9744e8330e7f3bd8ab91fe20b53dda28a1cBen Chan}
4365086b9744e8330e7f3bd8ab91fe20b53dda28a1cBen Chan
4371ac4e84148e03752d99aecea4f743abb094f28b0Paul StewartTEST_F(DeviceInfoTest, GetByteCounts) {
4387fab89734d88724a288e96a9996b15548c5294c7Ben Chan  uint64_t rx_bytes, tx_bytes;
4391ac4e84148e03752d99aecea4f743abb094f28b0Paul Stewart  EXPECT_FALSE(device_info_.GetByteCounts(
4401ac4e84148e03752d99aecea4f743abb094f28b0Paul Stewart      kTestDeviceIndex, &rx_bytes, &tx_bytes));
4411ac4e84148e03752d99aecea4f743abb094f28b0Paul Stewart
4421ac4e84148e03752d99aecea4f743abb094f28b0Paul Stewart  // No link statistics in the message.
443cd47732488cd101eaf0d3558dde5a7d4e4fc260bBen Chan  unique_ptr<RTNLMessage> message(BuildLinkMessage(RTNLMessage::kModeAdd));
4441ac4e84148e03752d99aecea4f743abb094f28b0Paul Stewart  SendMessageToDeviceInfo(*message);
4451ac4e84148e03752d99aecea4f743abb094f28b0Paul Stewart  EXPECT_TRUE(device_info_.GetByteCounts(
4461ac4e84148e03752d99aecea4f743abb094f28b0Paul Stewart      kTestDeviceIndex, &rx_bytes, &tx_bytes));
4471ac4e84148e03752d99aecea4f743abb094f28b0Paul Stewart  EXPECT_EQ(0, rx_bytes);
4481ac4e84148e03752d99aecea4f743abb094f28b0Paul Stewart  EXPECT_EQ(0, tx_bytes);
4491ac4e84148e03752d99aecea4f743abb094f28b0Paul Stewart
4501ac4e84148e03752d99aecea4f743abb094f28b0Paul Stewart  // Short link statistics message.
4511ac4e84148e03752d99aecea4f743abb094f28b0Paul Stewart  message.reset(BuildLinkMessage(RTNLMessage::kModeAdd));
4521ac4e84148e03752d99aecea4f743abb094f28b0Paul Stewart  struct rtnl_link_stats64 stats;
4531ac4e84148e03752d99aecea4f743abb094f28b0Paul Stewart  memset(&stats, 0, sizeof(stats));
4541ac4e84148e03752d99aecea4f743abb094f28b0Paul Stewart  stats.rx_bytes = kReceiveByteCount;
4551ac4e84148e03752d99aecea4f743abb094f28b0Paul Stewart  stats.tx_bytes = kTransmitByteCount;
4561ac4e84148e03752d99aecea4f743abb094f28b0Paul Stewart  ByteString stats_bytes0(reinterpret_cast<const unsigned char*>(&stats),
4571ac4e84148e03752d99aecea4f743abb094f28b0Paul Stewart                          sizeof(stats) - 1);
4581ac4e84148e03752d99aecea4f743abb094f28b0Paul Stewart  message->SetAttribute(IFLA_STATS64, stats_bytes0);
4591ac4e84148e03752d99aecea4f743abb094f28b0Paul Stewart  SendMessageToDeviceInfo(*message);
4601ac4e84148e03752d99aecea4f743abb094f28b0Paul Stewart  EXPECT_TRUE(device_info_.GetByteCounts(
4611ac4e84148e03752d99aecea4f743abb094f28b0Paul Stewart      kTestDeviceIndex, &rx_bytes, &tx_bytes));
4621ac4e84148e03752d99aecea4f743abb094f28b0Paul Stewart  EXPECT_EQ(0, rx_bytes);
4631ac4e84148e03752d99aecea4f743abb094f28b0Paul Stewart  EXPECT_EQ(0, tx_bytes);
4641ac4e84148e03752d99aecea4f743abb094f28b0Paul Stewart
4651ac4e84148e03752d99aecea4f743abb094f28b0Paul Stewart  // Correctly sized link statistics message.
4661ac4e84148e03752d99aecea4f743abb094f28b0Paul Stewart  message.reset(BuildLinkMessage(RTNLMessage::kModeAdd));
4671ac4e84148e03752d99aecea4f743abb094f28b0Paul Stewart  ByteString stats_bytes1(reinterpret_cast<const unsigned char*>(&stats),
4681ac4e84148e03752d99aecea4f743abb094f28b0Paul Stewart                          sizeof(stats));
4691ac4e84148e03752d99aecea4f743abb094f28b0Paul Stewart  message->SetAttribute(IFLA_STATS64, stats_bytes1);
4701ac4e84148e03752d99aecea4f743abb094f28b0Paul Stewart  SendMessageToDeviceInfo(*message);
4711ac4e84148e03752d99aecea4f743abb094f28b0Paul Stewart  EXPECT_TRUE(device_info_.GetByteCounts(
4721ac4e84148e03752d99aecea4f743abb094f28b0Paul Stewart      kTestDeviceIndex, &rx_bytes, &tx_bytes));
4731ac4e84148e03752d99aecea4f743abb094f28b0Paul Stewart  EXPECT_EQ(kReceiveByteCount, rx_bytes);
4741ac4e84148e03752d99aecea4f743abb094f28b0Paul Stewart  EXPECT_EQ(kTransmitByteCount, tx_bytes);
4751ac4e84148e03752d99aecea4f743abb094f28b0Paul Stewart}
4761ac4e84148e03752d99aecea4f743abb094f28b0Paul Stewart
4775742b24ab984464701fef0cc7024af2637357b04Ben Chan#if !defined(DISABLE_CELLULAR)
4785742b24ab984464701fef0cc7024af2637357b04Ben Chan
4798c116a90d3a3536430b808b15e73275060918434Paul StewartTEST_F(DeviceInfoTest, CreateDeviceCellular) {
4808c116a90d3a3536430b808b15e73275060918434Paul Stewart  IPAddress address = CreateInterfaceAddress();
4818c116a90d3a3536430b808b15e73275060918434Paul Stewart
4828c116a90d3a3536430b808b15e73275060918434Paul Stewart  // A cellular device should be offered to ModemInfo.
4838c116a90d3a3536430b808b15e73275060918434Paul Stewart  StrictMock<MockModemInfo> modem_info;
4848c116a90d3a3536430b808b15e73275060918434Paul Stewart  EXPECT_CALL(manager_, modem_info()).WillOnce(Return(&modem_info));
4858c116a90d3a3536430b808b15e73275060918434Paul Stewart  EXPECT_CALL(modem_info, OnDeviceInfoAvailable(kTestDeviceName)).Times(1);
4868c116a90d3a3536430b808b15e73275060918434Paul Stewart  EXPECT_CALL(routing_table_, FlushRoutes(kTestDeviceIndex)).Times(1);
4878c116a90d3a3536430b808b15e73275060918434Paul Stewart  EXPECT_CALL(rtnl_handler_, RemoveInterfaceAddress(kTestDeviceIndex,
4888c116a90d3a3536430b808b15e73275060918434Paul Stewart                                                    IsIPAddress(address)));
4898c116a90d3a3536430b808b15e73275060918434Paul Stewart  EXPECT_FALSE(CreateDevice(
4908c116a90d3a3536430b808b15e73275060918434Paul Stewart      kTestDeviceName, "address", kTestDeviceIndex, Technology::kCellular));
4918c116a90d3a3536430b808b15e73275060918434Paul Stewart}
4928c116a90d3a3536430b808b15e73275060918434Paul Stewart
4935742b24ab984464701fef0cc7024af2637357b04Ben Chan#endif  // DISABLE_CELLULAR
4945742b24ab984464701fef0cc7024af2637357b04Ben Chan
495520eb176ecc8548a9eb6a340fb46c06618ee8308Ben Chan#if !defined(DISABLE_WIMAX)
496520eb176ecc8548a9eb6a340fb46c06618ee8308Ben Chan
497e4b270274cba2a1976c7be6c733bd899e009c1d1Darin PetkovTEST_F(DeviceInfoTest, CreateDeviceWiMax) {
498e4b270274cba2a1976c7be6c733bd899e009c1d1Darin Petkov  IPAddress address = CreateInterfaceAddress();
499e4b270274cba2a1976c7be6c733bd899e009c1d1Darin Petkov
500e4b270274cba2a1976c7be6c733bd899e009c1d1Darin Petkov  // A WiMax device should be offered to WiMaxProvider.
501e4b270274cba2a1976c7be6c733bd899e009c1d1Darin Petkov  StrictMock<MockWiMaxProvider> wimax_provider;
502e4b270274cba2a1976c7be6c733bd899e009c1d1Darin Petkov  EXPECT_CALL(manager_, wimax_provider()).WillOnce(Return(&wimax_provider));
503e4b270274cba2a1976c7be6c733bd899e009c1d1Darin Petkov  EXPECT_CALL(wimax_provider, OnDeviceInfoAvailable(kTestDeviceName)).Times(1);
504e4b270274cba2a1976c7be6c733bd899e009c1d1Darin Petkov  EXPECT_CALL(routing_table_, FlushRoutes(kTestDeviceIndex)).Times(1);
505e4b270274cba2a1976c7be6c733bd899e009c1d1Darin Petkov  EXPECT_CALL(rtnl_handler_, RemoveInterfaceAddress(kTestDeviceIndex,
506e4b270274cba2a1976c7be6c733bd899e009c1d1Darin Petkov                                                    IsIPAddress(address)));
5074b28586abe9edee0179ea7672ac5ea9d9dc13ac7Ben Chan  device_info_.infos_[kTestDeviceIndex].mac_address =
5084b28586abe9edee0179ea7672ac5ea9d9dc13ac7Ben Chan      ByteString(kTestMACAddress, sizeof(kTestMACAddress));
509e4b270274cba2a1976c7be6c733bd899e009c1d1Darin Petkov  EXPECT_FALSE(CreateDevice(
510e4b270274cba2a1976c7be6c733bd899e009c1d1Darin Petkov      kTestDeviceName, "address", kTestDeviceIndex, Technology::kWiMax));
5114b28586abe9edee0179ea7672ac5ea9d9dc13ac7Ben Chan  // The MAC address is clear such that it is obtained via
5124b28586abe9edee0179ea7672ac5ea9d9dc13ac7Ben Chan  // GetMACAddressFromKernel() instead.
5134b28586abe9edee0179ea7672ac5ea9d9dc13ac7Ben Chan  EXPECT_TRUE(device_info_.infos_[kTestDeviceIndex].mac_address.IsEmpty());
514e4b270274cba2a1976c7be6c733bd899e009c1d1Darin Petkov}
515e4b270274cba2a1976c7be6c733bd899e009c1d1Darin Petkov
516520eb176ecc8548a9eb6a340fb46c06618ee8308Ben Chan#endif  // DISABLE_WIMAX
517520eb176ecc8548a9eb6a340fb46c06618ee8308Ben Chan
5188c116a90d3a3536430b808b15e73275060918434Paul StewartTEST_F(DeviceInfoTest, CreateDeviceEthernet) {
5198c116a90d3a3536430b808b15e73275060918434Paul Stewart  IPAddress address = CreateInterfaceAddress();
5208c116a90d3a3536430b808b15e73275060918434Paul Stewart
5218c116a90d3a3536430b808b15e73275060918434Paul Stewart  // An Ethernet device should cause routes and addresses to be flushed.
5228c116a90d3a3536430b808b15e73275060918434Paul Stewart  EXPECT_CALL(routing_table_, FlushRoutes(kTestDeviceIndex)).Times(1);
5238c116a90d3a3536430b808b15e73275060918434Paul Stewart  EXPECT_CALL(rtnl_handler_, RemoveInterfaceAddress(kTestDeviceIndex,
5248c116a90d3a3536430b808b15e73275060918434Paul Stewart                                                    IsIPAddress(address)));
5258c116a90d3a3536430b808b15e73275060918434Paul Stewart  DeviceRefPtr device = CreateDevice(
5268c116a90d3a3536430b808b15e73275060918434Paul Stewart      kTestDeviceName, "address", kTestDeviceIndex, Technology::kEthernet);
5278c116a90d3a3536430b808b15e73275060918434Paul Stewart  EXPECT_TRUE(device);
5288c116a90d3a3536430b808b15e73275060918434Paul Stewart  Mock::VerifyAndClearExpectations(&routing_table_);
5298c116a90d3a3536430b808b15e73275060918434Paul Stewart  Mock::VerifyAndClearExpectations(&rtnl_handler_);
5308c116a90d3a3536430b808b15e73275060918434Paul Stewart
531a06c65fa73e48e6ed02156ba6d62dcea2739a1a2Paul Stewart  // The Ethernet device destructor should not call DeregisterService()
532a06c65fa73e48e6ed02156ba6d62dcea2739a1a2Paul Stewart  // while being destructed, since the Manager may itself be partially
533a06c65fa73e48e6ed02156ba6d62dcea2739a1a2Paul Stewart  // destructed at this time.
534a06c65fa73e48e6ed02156ba6d62dcea2739a1a2Paul Stewart  EXPECT_CALL(manager_, DeregisterService(_)).Times(0);
535cc225ef3b77b5e098cc12c661a947e1737480777Ben Chan  device = nullptr;
5368c116a90d3a3536430b808b15e73275060918434Paul Stewart}
5378c116a90d3a3536430b808b15e73275060918434Paul Stewart
5388c116a90d3a3536430b808b15e73275060918434Paul StewartTEST_F(DeviceInfoTest, CreateDeviceVirtioEthernet) {
5398c116a90d3a3536430b808b15e73275060918434Paul Stewart  IPAddress address = CreateInterfaceAddress();
5408c116a90d3a3536430b808b15e73275060918434Paul Stewart
5418c116a90d3a3536430b808b15e73275060918434Paul Stewart  // VirtioEthernet is identical to Ethernet from the perspective of this test.
5428c116a90d3a3536430b808b15e73275060918434Paul Stewart  EXPECT_CALL(routing_table_, FlushRoutes(kTestDeviceIndex)).Times(1);
5438c116a90d3a3536430b808b15e73275060918434Paul Stewart  EXPECT_CALL(rtnl_handler_, RemoveInterfaceAddress(kTestDeviceIndex,
5448c116a90d3a3536430b808b15e73275060918434Paul Stewart                                                    IsIPAddress(address)));
5458c116a90d3a3536430b808b15e73275060918434Paul Stewart  DeviceRefPtr device = CreateDevice(
5468c116a90d3a3536430b808b15e73275060918434Paul Stewart      kTestDeviceName, "address", kTestDeviceIndex,
5478c116a90d3a3536430b808b15e73275060918434Paul Stewart      Technology::kVirtioEthernet);
5488c116a90d3a3536430b808b15e73275060918434Paul Stewart  EXPECT_TRUE(device);
5498c116a90d3a3536430b808b15e73275060918434Paul Stewart  Mock::VerifyAndClearExpectations(&routing_table_);
5508c116a90d3a3536430b808b15e73275060918434Paul Stewart  Mock::VerifyAndClearExpectations(&rtnl_handler_);
5518c116a90d3a3536430b808b15e73275060918434Paul Stewart}
5528c116a90d3a3536430b808b15e73275060918434Paul Stewart
5531a72f5444e077ed21b8e085b17d7f9f1bc44fa5ePeter Qiu#if !defined(DISABLE_WIFI)
5542ddf2c63751546aa554335a6733314a3859d5c2ePaul StewartMATCHER_P(IsGetInterfaceMessage, index, "") {
5552ddf2c63751546aa554335a6733314a3859d5c2ePaul Stewart  if (arg->message_type() != Nl80211Message::GetMessageType()) {
5562ddf2c63751546aa554335a6733314a3859d5c2ePaul Stewart    return false;
5572ddf2c63751546aa554335a6733314a3859d5c2ePaul Stewart  }
5583b30ca58d13cf66b75ba0729b222ddc42ae68b33Paul Stewart  const Nl80211Message* msg = reinterpret_cast<const Nl80211Message*>(arg);
5592ddf2c63751546aa554335a6733314a3859d5c2ePaul Stewart  if (msg->command() != NL80211_CMD_GET_INTERFACE) {
5602ddf2c63751546aa554335a6733314a3859d5c2ePaul Stewart    return false;
5612ddf2c63751546aa554335a6733314a3859d5c2ePaul Stewart  }
5622ddf2c63751546aa554335a6733314a3859d5c2ePaul Stewart  uint32_t interface_index;
5632ddf2c63751546aa554335a6733314a3859d5c2ePaul Stewart  if (!msg->const_attributes()->GetU32AttributeValue(NL80211_ATTR_IFINDEX,
5642ddf2c63751546aa554335a6733314a3859d5c2ePaul Stewart                                                     &interface_index)) {
5652ddf2c63751546aa554335a6733314a3859d5c2ePaul Stewart    return false;
5662ddf2c63751546aa554335a6733314a3859d5c2ePaul Stewart  }
5672ddf2c63751546aa554335a6733314a3859d5c2ePaul Stewart  // kInterfaceIndex is signed, but the attribute as handed from the kernel
5682ddf2c63751546aa554335a6733314a3859d5c2ePaul Stewart  // is unsigned.  We're silently casting it away with this assignment.
5692ddf2c63751546aa554335a6733314a3859d5c2ePaul Stewart  uint32_t test_interface_index = index;
5702ddf2c63751546aa554335a6733314a3859d5c2ePaul Stewart  return interface_index == test_interface_index;
5712ddf2c63751546aa554335a6733314a3859d5c2ePaul Stewart}
5722ddf2c63751546aa554335a6733314a3859d5c2ePaul Stewart
5738c116a90d3a3536430b808b15e73275060918434Paul StewartTEST_F(DeviceInfoTest, CreateDeviceWiFi) {
5748c116a90d3a3536430b808b15e73275060918434Paul Stewart  IPAddress address = CreateInterfaceAddress();
5758c116a90d3a3536430b808b15e73275060918434Paul Stewart
5768c116a90d3a3536430b808b15e73275060918434Paul Stewart  // WiFi looks a lot like Ethernet too.
5772ddf2c63751546aa554335a6733314a3859d5c2ePaul Stewart  EXPECT_CALL(routing_table_, FlushRoutes(kTestDeviceIndex));
5788c116a90d3a3536430b808b15e73275060918434Paul Stewart  EXPECT_CALL(rtnl_handler_, RemoveInterfaceAddress(kTestDeviceIndex,
5798c116a90d3a3536430b808b15e73275060918434Paul Stewart                                                    IsIPAddress(address)));
5802ddf2c63751546aa554335a6733314a3859d5c2ePaul Stewart
5812ddf2c63751546aa554335a6733314a3859d5c2ePaul Stewart  // Set the nl80211 message type to some non-default value.
5822ddf2c63751546aa554335a6733314a3859d5c2ePaul Stewart  Nl80211Message::SetMessageType(1234);
5832ddf2c63751546aa554335a6733314a3859d5c2ePaul Stewart
5847347bf2b466ae8058e47b29aaf0583390405d866Wade Guthrie  EXPECT_CALL(
5857347bf2b466ae8058e47b29aaf0583390405d866Wade Guthrie      netlink_manager_,
5865412de0a46893b44f60fee4058c5b0d744b74b4dSamuel Tan      SendNl80211Message(IsGetInterfaceMessage(kTestDeviceIndex), _, _, _));
5872ddf2c63751546aa554335a6733314a3859d5c2ePaul Stewart  EXPECT_FALSE(CreateDevice(
5888c116a90d3a3536430b808b15e73275060918434Paul Stewart      kTestDeviceName, "address", kTestDeviceIndex, Technology::kWifi));
5898c116a90d3a3536430b808b15e73275060918434Paul Stewart}
5901a72f5444e077ed21b8e085b17d7f9f1bc44fa5ePeter Qiu#endif  // DISABLE_WIFI
5918c116a90d3a3536430b808b15e73275060918434Paul Stewart
5928c116a90d3a3536430b808b15e73275060918434Paul StewartTEST_F(DeviceInfoTest, CreateDeviceTunnelAccepted) {
5938c116a90d3a3536430b808b15e73275060918434Paul Stewart  IPAddress address = CreateInterfaceAddress();
5948c116a90d3a3536430b808b15e73275060918434Paul Stewart
5958c116a90d3a3536430b808b15e73275060918434Paul Stewart  // A VPN device should be offered to VPNProvider.
5963b30ca58d13cf66b75ba0729b222ddc42ae68b33Paul Stewart  MockVPNProvider* vpn_provider = new StrictMock<MockVPNProvider>;
597c3505a569e3f98ce56e4017300a3ce46bc714e4cDarin Petkov  SetVPNProvider(vpn_provider);
598c3505a569e3f98ce56e4017300a3ce46bc714e4cDarin Petkov  EXPECT_CALL(*vpn_provider,
5998c116a90d3a3536430b808b15e73275060918434Paul Stewart              OnDeviceInfoAvailable(kTestDeviceName, kTestDeviceIndex))
6008c116a90d3a3536430b808b15e73275060918434Paul Stewart      .WillOnce(Return(true));
6018c116a90d3a3536430b808b15e73275060918434Paul Stewart  EXPECT_CALL(routing_table_, FlushRoutes(kTestDeviceIndex)).Times(1);
6028c116a90d3a3536430b808b15e73275060918434Paul Stewart  EXPECT_CALL(rtnl_handler_, RemoveInterfaceAddress(kTestDeviceIndex,
6038c116a90d3a3536430b808b15e73275060918434Paul Stewart                                                    IsIPAddress(address)));
6048c116a90d3a3536430b808b15e73275060918434Paul Stewart  EXPECT_CALL(rtnl_handler_, RemoveInterface(_)).Times(0);
6058c116a90d3a3536430b808b15e73275060918434Paul Stewart  EXPECT_FALSE(CreateDevice(
6068c116a90d3a3536430b808b15e73275060918434Paul Stewart      kTestDeviceName, "address", kTestDeviceIndex, Technology::kTunnel));
6078c116a90d3a3536430b808b15e73275060918434Paul Stewart}
6088c116a90d3a3536430b808b15e73275060918434Paul Stewart
6098c116a90d3a3536430b808b15e73275060918434Paul StewartTEST_F(DeviceInfoTest, CreateDeviceTunnelRejected) {
6108c116a90d3a3536430b808b15e73275060918434Paul Stewart  IPAddress address = CreateInterfaceAddress();
6118c116a90d3a3536430b808b15e73275060918434Paul Stewart
6128c116a90d3a3536430b808b15e73275060918434Paul Stewart  // A VPN device should be offered to VPNProvider.
6133b30ca58d13cf66b75ba0729b222ddc42ae68b33Paul Stewart  MockVPNProvider* vpn_provider = new StrictMock<MockVPNProvider>;
614c3505a569e3f98ce56e4017300a3ce46bc714e4cDarin Petkov  SetVPNProvider(vpn_provider);
615c3505a569e3f98ce56e4017300a3ce46bc714e4cDarin Petkov  EXPECT_CALL(*vpn_provider,
6168c116a90d3a3536430b808b15e73275060918434Paul Stewart              OnDeviceInfoAvailable(kTestDeviceName, kTestDeviceIndex))
6178c116a90d3a3536430b808b15e73275060918434Paul Stewart      .WillOnce(Return(false));
6188c116a90d3a3536430b808b15e73275060918434Paul Stewart  EXPECT_CALL(routing_table_, FlushRoutes(kTestDeviceIndex)).Times(1);
6198c116a90d3a3536430b808b15e73275060918434Paul Stewart  EXPECT_CALL(rtnl_handler_, RemoveInterfaceAddress(kTestDeviceIndex,
6208c116a90d3a3536430b808b15e73275060918434Paul Stewart                                                    IsIPAddress(address)));
6218c116a90d3a3536430b808b15e73275060918434Paul Stewart  // Since the device was rejected by the VPNProvider, DeviceInfo will
6228c116a90d3a3536430b808b15e73275060918434Paul Stewart  // remove the interface.
6238c116a90d3a3536430b808b15e73275060918434Paul Stewart  EXPECT_CALL(rtnl_handler_, RemoveInterface(kTestDeviceIndex)).Times(1);
6248c116a90d3a3536430b808b15e73275060918434Paul Stewart  EXPECT_FALSE(CreateDevice(
6258c116a90d3a3536430b808b15e73275060918434Paul Stewart      kTestDeviceName, "address", kTestDeviceIndex, Technology::kTunnel));
6268c116a90d3a3536430b808b15e73275060918434Paul Stewart}
6278c116a90d3a3536430b808b15e73275060918434Paul Stewart
6288c116a90d3a3536430b808b15e73275060918434Paul StewartTEST_F(DeviceInfoTest, CreateDevicePPP) {
6298c116a90d3a3536430b808b15e73275060918434Paul Stewart  IPAddress address = CreateInterfaceAddress();
6308c116a90d3a3536430b808b15e73275060918434Paul Stewart
6318c116a90d3a3536430b808b15e73275060918434Paul Stewart  // A VPN device should be offered to VPNProvider.
6323b30ca58d13cf66b75ba0729b222ddc42ae68b33Paul Stewart  MockVPNProvider* vpn_provider = new StrictMock<MockVPNProvider>;
633c3505a569e3f98ce56e4017300a3ce46bc714e4cDarin Petkov  SetVPNProvider(vpn_provider);
634c3505a569e3f98ce56e4017300a3ce46bc714e4cDarin Petkov  EXPECT_CALL(*vpn_provider,
6358c116a90d3a3536430b808b15e73275060918434Paul Stewart              OnDeviceInfoAvailable(kTestDeviceName, kTestDeviceIndex))
6368c116a90d3a3536430b808b15e73275060918434Paul Stewart      .WillOnce(Return(false));
6378c116a90d3a3536430b808b15e73275060918434Paul Stewart  EXPECT_CALL(routing_table_, FlushRoutes(kTestDeviceIndex)).Times(1);
6388c116a90d3a3536430b808b15e73275060918434Paul Stewart  EXPECT_CALL(rtnl_handler_, RemoveInterfaceAddress(kTestDeviceIndex,
6398c116a90d3a3536430b808b15e73275060918434Paul Stewart                                                    IsIPAddress(address)));
6408c116a90d3a3536430b808b15e73275060918434Paul Stewart  // We do not remove PPP interfaces even if the provider does not accept it.
6418c116a90d3a3536430b808b15e73275060918434Paul Stewart  EXPECT_CALL(rtnl_handler_, RemoveInterface(_)).Times(0);
6428c116a90d3a3536430b808b15e73275060918434Paul Stewart  EXPECT_FALSE(CreateDevice(
6438c116a90d3a3536430b808b15e73275060918434Paul Stewart      kTestDeviceName, "address", kTestDeviceIndex, Technology::kPPP));
6448c116a90d3a3536430b808b15e73275060918434Paul Stewart}
6458c116a90d3a3536430b808b15e73275060918434Paul Stewart
6468c116a90d3a3536430b808b15e73275060918434Paul StewartTEST_F(DeviceInfoTest, CreateDeviceLoopback) {
6478c116a90d3a3536430b808b15e73275060918434Paul Stewart  // A loopback device should be brought up, and nothing else done to it.
6488c116a90d3a3536430b808b15e73275060918434Paul Stewart  EXPECT_CALL(routing_table_, FlushRoutes(_)).Times(0);
6498c116a90d3a3536430b808b15e73275060918434Paul Stewart  EXPECT_CALL(rtnl_handler_, RemoveInterfaceAddress(_, _)).Times(0);
6508c116a90d3a3536430b808b15e73275060918434Paul Stewart  EXPECT_CALL(rtnl_handler_,
6518c116a90d3a3536430b808b15e73275060918434Paul Stewart              SetInterfaceFlags(kTestDeviceIndex, IFF_UP, IFF_UP)).Times(1);
6528c116a90d3a3536430b808b15e73275060918434Paul Stewart  EXPECT_FALSE(CreateDevice(
6538c116a90d3a3536430b808b15e73275060918434Paul Stewart      kTestDeviceName, "address", kTestDeviceIndex, Technology::kLoopback));
6548c116a90d3a3536430b808b15e73275060918434Paul Stewart}
6558c116a90d3a3536430b808b15e73275060918434Paul Stewart
656050cfc068fda2bd77df2ba08f7b2897bf0e0a6e0Paul StewartTEST_F(DeviceInfoTest, CreateDeviceCDCEthernet) {
6574eb4ddf7f26286e6b4d112f014718336559dfb7aBen Chan  // A cdc_ether / cdc_ncm device should be postponed to a task.
658050cfc068fda2bd77df2ba08f7b2897bf0e0a6e0Paul Stewart  EXPECT_CALL(manager_, modem_info()).Times(0);
659050cfc068fda2bd77df2ba08f7b2897bf0e0a6e0Paul Stewart  EXPECT_CALL(routing_table_, FlushRoutes(_)).Times(0);
660050cfc068fda2bd77df2ba08f7b2897bf0e0a6e0Paul Stewart  EXPECT_CALL(rtnl_handler_, RemoveInterfaceAddress(_, _)).Times(0);
661050cfc068fda2bd77df2ba08f7b2897bf0e0a6e0Paul Stewart  EXPECT_CALL(dispatcher_,
6621ac4e84148e03752d99aecea4f743abb094f28b0Paul Stewart              PostDelayedTask(_, GetDelayedDeviceCreationMilliseconds()));
663050cfc068fda2bd77df2ba08f7b2897bf0e0a6e0Paul Stewart  EXPECT_TRUE(GetDelayedDevices().empty());
664050cfc068fda2bd77df2ba08f7b2897bf0e0a6e0Paul Stewart  EXPECT_FALSE(CreateDevice(
665050cfc068fda2bd77df2ba08f7b2897bf0e0a6e0Paul Stewart      kTestDeviceName, "address", kTestDeviceIndex, Technology::kCDCEthernet));
666050cfc068fda2bd77df2ba08f7b2897bf0e0a6e0Paul Stewart  EXPECT_FALSE(GetDelayedDevices().empty());
667050cfc068fda2bd77df2ba08f7b2897bf0e0a6e0Paul Stewart  EXPECT_EQ(1, GetDelayedDevices().size());
668050cfc068fda2bd77df2ba08f7b2897bf0e0a6e0Paul Stewart  EXPECT_EQ(kTestDeviceIndex, *GetDelayedDevices().begin());
669050cfc068fda2bd77df2ba08f7b2897bf0e0a6e0Paul Stewart}
670050cfc068fda2bd77df2ba08f7b2897bf0e0a6e0Paul Stewart
6718c116a90d3a3536430b808b15e73275060918434Paul StewartTEST_F(DeviceInfoTest, CreateDeviceUnknown) {
6728c116a90d3a3536430b808b15e73275060918434Paul Stewart  IPAddress address = CreateInterfaceAddress();
6738c116a90d3a3536430b808b15e73275060918434Paul Stewart
6748c116a90d3a3536430b808b15e73275060918434Paul Stewart  // An unknown (blacklisted, unhandled, etc) device won't be flushed or
6758c116a90d3a3536430b808b15e73275060918434Paul Stewart  // registered.
6768c116a90d3a3536430b808b15e73275060918434Paul Stewart  EXPECT_CALL(routing_table_, FlushRoutes(_)).Times(0);
6778c116a90d3a3536430b808b15e73275060918434Paul Stewart  EXPECT_CALL(rtnl_handler_, RemoveInterfaceAddress(_, _)).Times(0);
6788c116a90d3a3536430b808b15e73275060918434Paul Stewart  EXPECT_TRUE(CreateDevice(
6798c116a90d3a3536430b808b15e73275060918434Paul Stewart      kTestDeviceName, "address", kTestDeviceIndex, Technology::kUnknown));
6809be4a9d1e87d64f850f15061123b2a4334477fa2Chris Masone}
6819be4a9d1e87d64f850f15061123b2a4334477fa2Chris Masone
6828f317b600a218afe05f2d73c59204bb98269a950mukesh agrawalTEST_F(DeviceInfoTest, DeviceBlackList) {
683ebd709e7d7519915930404be7120cd8070b432c4Peter Qiu  // Manager is not running by default.
684ebd709e7d7519915930404be7120cd8070b432c4Peter Qiu  EXPECT_CALL(rtnl_handler_, RequestDump(RTNLHandler::kRequestLink)).Times(0);
685ebd709e7d7519915930404be7120cd8070b432c4Peter Qiu  device_info_.AddDeviceToBlackList(kTestDeviceName);
686ebd709e7d7519915930404be7120cd8070b432c4Peter Qiu  unique_ptr<RTNLMessage> message(BuildLinkMessage(RTNLMessage::kModeAdd));
687ebd709e7d7519915930404be7120cd8070b432c4Peter Qiu  SendMessageToDeviceInfo(*message);
688ebd709e7d7519915930404be7120cd8070b432c4Peter Qiu
689ebd709e7d7519915930404be7120cd8070b432c4Peter Qiu  DeviceRefPtr device = device_info_.GetDevice(kTestDeviceIndex);
690ebd709e7d7519915930404be7120cd8070b432c4Peter Qiu  ASSERT_TRUE(device.get());
691ebd709e7d7519915930404be7120cd8070b432c4Peter Qiu  EXPECT_TRUE(device->technology() == Technology::kBlacklisted);
692ebd709e7d7519915930404be7120cd8070b432c4Peter Qiu}
693ebd709e7d7519915930404be7120cd8070b432c4Peter Qiu
694ebd709e7d7519915930404be7120cd8070b432c4Peter QiuTEST_F(DeviceInfoTest, AddDeviceToBlackListWithManagerRunning) {
695ebd709e7d7519915930404be7120cd8070b432c4Peter Qiu  SetManagerRunning(true);
6967e8b8ee34816575b9059dd041ef29f91fe1d15c8Peter Qiu  EXPECT_CALL(rtnl_handler_, RequestDump(RTNLHandler::kRequestLink)).Times(1);
6978f317b600a218afe05f2d73c59204bb98269a950mukesh agrawal  device_info_.AddDeviceToBlackList(kTestDeviceName);
698cd47732488cd101eaf0d3558dde5a7d4e4fc260bBen Chan  unique_ptr<RTNLMessage> message(BuildLinkMessage(RTNLMessage::kModeAdd));
699e6193c042652831cac90c3bbf2233877754b1eefDarin Petkov  SendMessageToDeviceInfo(*message);
7008f317b600a218afe05f2d73c59204bb98269a950mukesh agrawal
701e6193c042652831cac90c3bbf2233877754b1eefDarin Petkov  DeviceRefPtr device = device_info_.GetDevice(kTestDeviceIndex);
702e6193c042652831cac90c3bbf2233877754b1eefDarin Petkov  ASSERT_TRUE(device.get());
703da798623389b981130cd1922f880736f1e0e36baJoshua Kroll  EXPECT_TRUE(device->technology() == Technology::kBlacklisted);
7048f317b600a218afe05f2d73c59204bb98269a950mukesh agrawal}
7058f317b600a218afe05f2d73c59204bb98269a950mukesh agrawal
706d84f367304e8eec21f235392c57bfc1a30540609Paul StewartTEST_F(DeviceInfoTest, RenamedBlacklistedDevice) {
707d84f367304e8eec21f235392c57bfc1a30540609Paul Stewart  device_info_.AddDeviceToBlackList(kTestDeviceName);
708d84f367304e8eec21f235392c57bfc1a30540609Paul Stewart  unique_ptr<RTNLMessage> message(BuildLinkMessage(RTNLMessage::kModeAdd));
709d84f367304e8eec21f235392c57bfc1a30540609Paul Stewart  SendMessageToDeviceInfo(*message);
710d84f367304e8eec21f235392c57bfc1a30540609Paul Stewart
711d84f367304e8eec21f235392c57bfc1a30540609Paul Stewart  DeviceRefPtr device = device_info_.GetDevice(kTestDeviceIndex);
712d84f367304e8eec21f235392c57bfc1a30540609Paul Stewart  ASSERT_TRUE(device.get());
713d84f367304e8eec21f235392c57bfc1a30540609Paul Stewart  EXPECT_TRUE(device->technology() == Technology::kBlacklisted);
714d84f367304e8eec21f235392c57bfc1a30540609Paul Stewart
715d84f367304e8eec21f235392c57bfc1a30540609Paul Stewart  // Rename the test device.
716d84f367304e8eec21f235392c57bfc1a30540609Paul Stewart  const char kRenamedDeviceName[] = "renamed-device";
717d84f367304e8eec21f235392c57bfc1a30540609Paul Stewart  unique_ptr<RTNLMessage> rename_message(
718d84f367304e8eec21f235392c57bfc1a30540609Paul Stewart      BuildLinkMessageWithInterfaceName(
719d84f367304e8eec21f235392c57bfc1a30540609Paul Stewart          RTNLMessage::kModeAdd, kRenamedDeviceName));
720d84f367304e8eec21f235392c57bfc1a30540609Paul Stewart  EXPECT_CALL(manager_, DeregisterDevice(_));
721d84f367304e8eec21f235392c57bfc1a30540609Paul Stewart  EXPECT_CALL(metrics_, DeregisterDevice(kTestDeviceIndex));
722d84f367304e8eec21f235392c57bfc1a30540609Paul Stewart  SendMessageToDeviceInfo(*rename_message);
723d84f367304e8eec21f235392c57bfc1a30540609Paul Stewart
724d84f367304e8eec21f235392c57bfc1a30540609Paul Stewart  DeviceRefPtr renamed_device = device_info_.GetDevice(kTestDeviceIndex);
725d84f367304e8eec21f235392c57bfc1a30540609Paul Stewart  ASSERT_TRUE(renamed_device.get());
726d84f367304e8eec21f235392c57bfc1a30540609Paul Stewart
727d84f367304e8eec21f235392c57bfc1a30540609Paul Stewart  // Expect that a different device has been created.
728d84f367304e8eec21f235392c57bfc1a30540609Paul Stewart  EXPECT_NE(device.get(), renamed_device.get());
729d84f367304e8eec21f235392c57bfc1a30540609Paul Stewart
730d84f367304e8eec21f235392c57bfc1a30540609Paul Stewart  // Since we didn't create a uevent file for kRenamedDeviceName, its
731d84f367304e8eec21f235392c57bfc1a30540609Paul Stewart  // technology should be unknown.
732d84f367304e8eec21f235392c57bfc1a30540609Paul Stewart  EXPECT_TRUE(renamed_device->technology() == Technology::kUnknown);
733d84f367304e8eec21f235392c57bfc1a30540609Paul Stewart}
734d84f367304e8eec21f235392c57bfc1a30540609Paul Stewart
735d84f367304e8eec21f235392c57bfc1a30540609Paul StewartTEST_F(DeviceInfoTest, RenamedNonBlacklistedDevice) {
736d84f367304e8eec21f235392c57bfc1a30540609Paul Stewart  const char kInitialDeviceName[] = "initial-device";
737d84f367304e8eec21f235392c57bfc1a30540609Paul Stewart  unique_ptr<RTNLMessage> initial_message(
738d84f367304e8eec21f235392c57bfc1a30540609Paul Stewart      BuildLinkMessageWithInterfaceName(
739d84f367304e8eec21f235392c57bfc1a30540609Paul Stewart          RTNLMessage::kModeAdd, kInitialDeviceName));
740d84f367304e8eec21f235392c57bfc1a30540609Paul Stewart  SendMessageToDeviceInfo(*initial_message);
741d84f367304e8eec21f235392c57bfc1a30540609Paul Stewart  unique_ptr<RTNLMessage> message(BuildLinkMessage(RTNLMessage::kModeAdd));
742d84f367304e8eec21f235392c57bfc1a30540609Paul Stewart
743d84f367304e8eec21f235392c57bfc1a30540609Paul Stewart  DeviceRefPtr initial_device = device_info_.GetDevice(kTestDeviceIndex);
744d84f367304e8eec21f235392c57bfc1a30540609Paul Stewart  ASSERT_TRUE(initial_device.get());
745d84f367304e8eec21f235392c57bfc1a30540609Paul Stewart
746d84f367304e8eec21f235392c57bfc1a30540609Paul Stewart  // Since we didn't create a uevent file for kInitialDeviceName, its
747d84f367304e8eec21f235392c57bfc1a30540609Paul Stewart  // technology should be unknown.
748d84f367304e8eec21f235392c57bfc1a30540609Paul Stewart  EXPECT_TRUE(initial_device->technology() == Technology::kUnknown);
749d84f367304e8eec21f235392c57bfc1a30540609Paul Stewart
750d84f367304e8eec21f235392c57bfc1a30540609Paul Stewart  // Rename the test device.
751d84f367304e8eec21f235392c57bfc1a30540609Paul Stewart  const char kRenamedDeviceName[] = "renamed-device";
752d84f367304e8eec21f235392c57bfc1a30540609Paul Stewart  device_info_.AddDeviceToBlackList(kRenamedDeviceName);
753d84f367304e8eec21f235392c57bfc1a30540609Paul Stewart  unique_ptr<RTNLMessage> rename_message(
754d84f367304e8eec21f235392c57bfc1a30540609Paul Stewart      BuildLinkMessageWithInterfaceName(
755d84f367304e8eec21f235392c57bfc1a30540609Paul Stewart          RTNLMessage::kModeAdd, kRenamedDeviceName));
756d84f367304e8eec21f235392c57bfc1a30540609Paul Stewart  EXPECT_CALL(manager_, DeregisterDevice(_)).Times(0);
757d84f367304e8eec21f235392c57bfc1a30540609Paul Stewart  EXPECT_CALL(metrics_, DeregisterDevice(kTestDeviceIndex)).Times(0);
758d84f367304e8eec21f235392c57bfc1a30540609Paul Stewart  SendMessageToDeviceInfo(*rename_message);
759d84f367304e8eec21f235392c57bfc1a30540609Paul Stewart
760d84f367304e8eec21f235392c57bfc1a30540609Paul Stewart  DeviceRefPtr renamed_device = device_info_.GetDevice(kTestDeviceIndex);
761d84f367304e8eec21f235392c57bfc1a30540609Paul Stewart  ASSERT_TRUE(renamed_device.get());
762d84f367304e8eec21f235392c57bfc1a30540609Paul Stewart
763d84f367304e8eec21f235392c57bfc1a30540609Paul Stewart  // Expect that the the presence of a renamed device does not cause a new
764d84f367304e8eec21f235392c57bfc1a30540609Paul Stewart  // Device entry to be created if the initial device was not blacklisted.
765d84f367304e8eec21f235392c57bfc1a30540609Paul Stewart  EXPECT_EQ(initial_device.get(), renamed_device.get());
766d84f367304e8eec21f235392c57bfc1a30540609Paul Stewart  EXPECT_TRUE(initial_device->technology() == Technology::kUnknown);
767d84f367304e8eec21f235392c57bfc1a30540609Paul Stewart}
768d84f367304e8eec21f235392c57bfc1a30540609Paul Stewart
7699a908080fc2a72dbf06f995b878fc8a3693b725aPaul StewartTEST_F(DeviceInfoTest, DeviceAddressList) {
770cd47732488cd101eaf0d3558dde5a7d4e4fc260bBen Chan  unique_ptr<RTNLMessage> message(BuildLinkMessage(RTNLMessage::kModeAdd));
7719a908080fc2a72dbf06f995b878fc8a3693b725aPaul Stewart  SendMessageToDeviceInfo(*message);
7729a908080fc2a72dbf06f995b878fc8a3693b725aPaul Stewart
7739a908080fc2a72dbf06f995b878fc8a3693b725aPaul Stewart  vector<DeviceInfo::AddressData> addresses;
7749a908080fc2a72dbf06f995b878fc8a3693b725aPaul Stewart  EXPECT_TRUE(device_info_.GetAddresses(kTestDeviceIndex, &addresses));
7759a908080fc2a72dbf06f995b878fc8a3693b725aPaul Stewart  EXPECT_TRUE(addresses.empty());
7769a908080fc2a72dbf06f995b878fc8a3693b725aPaul Stewart
7779a908080fc2a72dbf06f995b878fc8a3693b725aPaul Stewart  // Add an address to the device address list
7787355ce1937c504d836a303ac809bd436272212b3Paul Stewart  IPAddress ip_address0(IPAddress::kFamilyIPv4);
7799a908080fc2a72dbf06f995b878fc8a3693b725aPaul Stewart  EXPECT_TRUE(ip_address0.SetAddressFromString(kTestIPAddress0));
7809a908080fc2a72dbf06f995b878fc8a3693b725aPaul Stewart  ip_address0.set_prefix(kTestIPAddressPrefix0);
7819a908080fc2a72dbf06f995b878fc8a3693b725aPaul Stewart  message.reset(BuildAddressMessage(RTNLMessage::kModeAdd, ip_address0, 0, 0));
7829a908080fc2a72dbf06f995b878fc8a3693b725aPaul Stewart  SendMessageToDeviceInfo(*message);
7839a908080fc2a72dbf06f995b878fc8a3693b725aPaul Stewart  EXPECT_TRUE(device_info_.GetAddresses(kTestDeviceIndex, &addresses));
7849a908080fc2a72dbf06f995b878fc8a3693b725aPaul Stewart  EXPECT_EQ(1, addresses.size());
7859a908080fc2a72dbf06f995b878fc8a3693b725aPaul Stewart  EXPECT_TRUE(ip_address0.Equals(addresses[0].address));
7869a908080fc2a72dbf06f995b878fc8a3693b725aPaul Stewart
7879a908080fc2a72dbf06f995b878fc8a3693b725aPaul Stewart  // Re-adding the same address shouldn't cause the address list to change
7889a908080fc2a72dbf06f995b878fc8a3693b725aPaul Stewart  SendMessageToDeviceInfo(*message);
7899a908080fc2a72dbf06f995b878fc8a3693b725aPaul Stewart  EXPECT_TRUE(device_info_.GetAddresses(kTestDeviceIndex, &addresses));
7909a908080fc2a72dbf06f995b878fc8a3693b725aPaul Stewart  EXPECT_EQ(1, addresses.size());
7919a908080fc2a72dbf06f995b878fc8a3693b725aPaul Stewart  EXPECT_TRUE(ip_address0.Equals(addresses[0].address));
7929a908080fc2a72dbf06f995b878fc8a3693b725aPaul Stewart
7939a908080fc2a72dbf06f995b878fc8a3693b725aPaul Stewart  // Adding a new address should expand the list
7947355ce1937c504d836a303ac809bd436272212b3Paul Stewart  IPAddress ip_address1(IPAddress::kFamilyIPv6);
7959a908080fc2a72dbf06f995b878fc8a3693b725aPaul Stewart  EXPECT_TRUE(ip_address1.SetAddressFromString(kTestIPAddress1));
7969a908080fc2a72dbf06f995b878fc8a3693b725aPaul Stewart  ip_address1.set_prefix(kTestIPAddressPrefix1);
7979a908080fc2a72dbf06f995b878fc8a3693b725aPaul Stewart  message.reset(BuildAddressMessage(RTNLMessage::kModeAdd, ip_address1, 0, 0));
7989a908080fc2a72dbf06f995b878fc8a3693b725aPaul Stewart  SendMessageToDeviceInfo(*message);
7999a908080fc2a72dbf06f995b878fc8a3693b725aPaul Stewart  EXPECT_TRUE(device_info_.GetAddresses(kTestDeviceIndex, &addresses));
8009a908080fc2a72dbf06f995b878fc8a3693b725aPaul Stewart  EXPECT_EQ(2, addresses.size());
8019a908080fc2a72dbf06f995b878fc8a3693b725aPaul Stewart  EXPECT_TRUE(ip_address0.Equals(addresses[0].address));
8029a908080fc2a72dbf06f995b878fc8a3693b725aPaul Stewart  EXPECT_TRUE(ip_address1.Equals(addresses[1].address));
8039a908080fc2a72dbf06f995b878fc8a3693b725aPaul Stewart
8049a908080fc2a72dbf06f995b878fc8a3693b725aPaul Stewart  // Deleting an address should reduce the list
8059a908080fc2a72dbf06f995b878fc8a3693b725aPaul Stewart  message.reset(BuildAddressMessage(RTNLMessage::kModeDelete,
8069a908080fc2a72dbf06f995b878fc8a3693b725aPaul Stewart                                    ip_address0,
8079a908080fc2a72dbf06f995b878fc8a3693b725aPaul Stewart                                    0,
8089a908080fc2a72dbf06f995b878fc8a3693b725aPaul Stewart                                    0));
8099a908080fc2a72dbf06f995b878fc8a3693b725aPaul Stewart  SendMessageToDeviceInfo(*message);
8109a908080fc2a72dbf06f995b878fc8a3693b725aPaul Stewart  EXPECT_TRUE(device_info_.GetAddresses(kTestDeviceIndex, &addresses));
8119a908080fc2a72dbf06f995b878fc8a3693b725aPaul Stewart  EXPECT_EQ(1, addresses.size());
8129a908080fc2a72dbf06f995b878fc8a3693b725aPaul Stewart  EXPECT_TRUE(ip_address1.Equals(addresses[0].address));
8139a908080fc2a72dbf06f995b878fc8a3693b725aPaul Stewart
8149a908080fc2a72dbf06f995b878fc8a3693b725aPaul Stewart  // Delete last item
8159a908080fc2a72dbf06f995b878fc8a3693b725aPaul Stewart  message.reset(BuildAddressMessage(RTNLMessage::kModeDelete,
8169a908080fc2a72dbf06f995b878fc8a3693b725aPaul Stewart                                    ip_address1,
8179a908080fc2a72dbf06f995b878fc8a3693b725aPaul Stewart                                    0,
8189a908080fc2a72dbf06f995b878fc8a3693b725aPaul Stewart                                    0));
8199a908080fc2a72dbf06f995b878fc8a3693b725aPaul Stewart  SendMessageToDeviceInfo(*message);
8209a908080fc2a72dbf06f995b878fc8a3693b725aPaul Stewart  EXPECT_TRUE(device_info_.GetAddresses(kTestDeviceIndex, &addresses));
8219a908080fc2a72dbf06f995b878fc8a3693b725aPaul Stewart  EXPECT_TRUE(addresses.empty());
8229a908080fc2a72dbf06f995b878fc8a3693b725aPaul Stewart
8239a908080fc2a72dbf06f995b878fc8a3693b725aPaul Stewart  // Delete device
8249a908080fc2a72dbf06f995b878fc8a3693b725aPaul Stewart  message.reset(BuildLinkMessage(RTNLMessage::kModeDelete));
8258c116a90d3a3536430b808b15e73275060918434Paul Stewart  EXPECT_CALL(manager_, DeregisterDevice(_)).Times(1);
8269a908080fc2a72dbf06f995b878fc8a3693b725aPaul Stewart  SendMessageToDeviceInfo(*message);
8279a908080fc2a72dbf06f995b878fc8a3693b725aPaul Stewart
8289a908080fc2a72dbf06f995b878fc8a3693b725aPaul Stewart  // Should be able to handle message for interface that doesn't exist
8299a908080fc2a72dbf06f995b878fc8a3693b725aPaul Stewart  message.reset(BuildAddressMessage(RTNLMessage::kModeAdd, ip_address0, 0, 0));
8309a908080fc2a72dbf06f995b878fc8a3693b725aPaul Stewart  SendMessageToDeviceInfo(*message);
8319a908080fc2a72dbf06f995b878fc8a3693b725aPaul Stewart  EXPECT_FALSE(device_info_.GetDevice(kTestDeviceIndex).get());
8329a908080fc2a72dbf06f995b878fc8a3693b725aPaul Stewart}
8339a908080fc2a72dbf06f995b878fc8a3693b725aPaul Stewart
8349a908080fc2a72dbf06f995b878fc8a3693b725aPaul StewartTEST_F(DeviceInfoTest, FlushAddressList) {
835cd47732488cd101eaf0d3558dde5a7d4e4fc260bBen Chan  unique_ptr<RTNLMessage> message(BuildLinkMessage(RTNLMessage::kModeAdd));
8369a908080fc2a72dbf06f995b878fc8a3693b725aPaul Stewart  SendMessageToDeviceInfo(*message);
8379a908080fc2a72dbf06f995b878fc8a3693b725aPaul Stewart
8387355ce1937c504d836a303ac809bd436272212b3Paul Stewart  IPAddress address1(IPAddress::kFamilyIPv6);
8399a908080fc2a72dbf06f995b878fc8a3693b725aPaul Stewart  EXPECT_TRUE(address1.SetAddressFromString(kTestIPAddress1));
8409a908080fc2a72dbf06f995b878fc8a3693b725aPaul Stewart  address1.set_prefix(kTestIPAddressPrefix1);
8419a908080fc2a72dbf06f995b878fc8a3693b725aPaul Stewart  message.reset(BuildAddressMessage(RTNLMessage::kModeAdd,
8429a908080fc2a72dbf06f995b878fc8a3693b725aPaul Stewart                                    address1,
8439a908080fc2a72dbf06f995b878fc8a3693b725aPaul Stewart                                    0,
8449a908080fc2a72dbf06f995b878fc8a3693b725aPaul Stewart                                    RT_SCOPE_UNIVERSE));
8459a908080fc2a72dbf06f995b878fc8a3693b725aPaul Stewart  SendMessageToDeviceInfo(*message);
8467355ce1937c504d836a303ac809bd436272212b3Paul Stewart  IPAddress address2(IPAddress::kFamilyIPv6);
8479a908080fc2a72dbf06f995b878fc8a3693b725aPaul Stewart  EXPECT_TRUE(address2.SetAddressFromString(kTestIPAddress2));
8489a908080fc2a72dbf06f995b878fc8a3693b725aPaul Stewart  message.reset(BuildAddressMessage(RTNLMessage::kModeAdd,
8499a908080fc2a72dbf06f995b878fc8a3693b725aPaul Stewart                                    address2,
8509a908080fc2a72dbf06f995b878fc8a3693b725aPaul Stewart                                    IFA_F_TEMPORARY,
8519a908080fc2a72dbf06f995b878fc8a3693b725aPaul Stewart                                    RT_SCOPE_UNIVERSE));
8529a908080fc2a72dbf06f995b878fc8a3693b725aPaul Stewart  SendMessageToDeviceInfo(*message);
8537355ce1937c504d836a303ac809bd436272212b3Paul Stewart  IPAddress address3(IPAddress::kFamilyIPv6);
8549a908080fc2a72dbf06f995b878fc8a3693b725aPaul Stewart  EXPECT_TRUE(address3.SetAddressFromString(kTestIPAddress3));
8559a908080fc2a72dbf06f995b878fc8a3693b725aPaul Stewart  message.reset(BuildAddressMessage(RTNLMessage::kModeAdd,
8569a908080fc2a72dbf06f995b878fc8a3693b725aPaul Stewart                                    address3,
8579a908080fc2a72dbf06f995b878fc8a3693b725aPaul Stewart                                    0,
8589a908080fc2a72dbf06f995b878fc8a3693b725aPaul Stewart                                    RT_SCOPE_LINK));
8599a908080fc2a72dbf06f995b878fc8a3693b725aPaul Stewart  SendMessageToDeviceInfo(*message);
8607355ce1937c504d836a303ac809bd436272212b3Paul Stewart  IPAddress address4(IPAddress::kFamilyIPv6);
8619a908080fc2a72dbf06f995b878fc8a3693b725aPaul Stewart  EXPECT_TRUE(address4.SetAddressFromString(kTestIPAddress4));
8629a908080fc2a72dbf06f995b878fc8a3693b725aPaul Stewart  message.reset(BuildAddressMessage(RTNLMessage::kModeAdd,
8639a908080fc2a72dbf06f995b878fc8a3693b725aPaul Stewart                                    address4,
8649a908080fc2a72dbf06f995b878fc8a3693b725aPaul Stewart                                    IFA_F_PERMANENT,
8659a908080fc2a72dbf06f995b878fc8a3693b725aPaul Stewart                                    RT_SCOPE_UNIVERSE));
8669a908080fc2a72dbf06f995b878fc8a3693b725aPaul Stewart  SendMessageToDeviceInfo(*message);
8679a908080fc2a72dbf06f995b878fc8a3693b725aPaul Stewart
8689a908080fc2a72dbf06f995b878fc8a3693b725aPaul Stewart  // DeviceInfo now has 4 addresses associated with it, but only two of
8699a908080fc2a72dbf06f995b878fc8a3693b725aPaul Stewart  // them are valid for flush.
8709a908080fc2a72dbf06f995b878fc8a3693b725aPaul Stewart  EXPECT_CALL(rtnl_handler_, RemoveInterfaceAddress(kTestDeviceIndex,
8719a908080fc2a72dbf06f995b878fc8a3693b725aPaul Stewart                                                    IsIPAddress(address1)));
8729a908080fc2a72dbf06f995b878fc8a3693b725aPaul Stewart  EXPECT_CALL(rtnl_handler_, RemoveInterfaceAddress(kTestDeviceIndex,
8739a908080fc2a72dbf06f995b878fc8a3693b725aPaul Stewart                                                    IsIPAddress(address2)));
8749a908080fc2a72dbf06f995b878fc8a3693b725aPaul Stewart  device_info_.FlushAddresses(kTestDeviceIndex);
8759a908080fc2a72dbf06f995b878fc8a3693b725aPaul Stewart}
8769a908080fc2a72dbf06f995b878fc8a3693b725aPaul Stewart
87705a42c23f1d37daa8689fc4240034e62ed89f8fcPaul StewartTEST_F(DeviceInfoTest, HasOtherAddress) {
878cd47732488cd101eaf0d3558dde5a7d4e4fc260bBen Chan  unique_ptr<RTNLMessage> message(BuildLinkMessage(RTNLMessage::kModeAdd));
87905a42c23f1d37daa8689fc4240034e62ed89f8fcPaul Stewart  SendMessageToDeviceInfo(*message);
88005a42c23f1d37daa8689fc4240034e62ed89f8fcPaul Stewart
88105a42c23f1d37daa8689fc4240034e62ed89f8fcPaul Stewart  IPAddress address0(IPAddress::kFamilyIPv4);
88205a42c23f1d37daa8689fc4240034e62ed89f8fcPaul Stewart  EXPECT_TRUE(address0.SetAddressFromString(kTestIPAddress0));
88305a42c23f1d37daa8689fc4240034e62ed89f8fcPaul Stewart
88405a42c23f1d37daa8689fc4240034e62ed89f8fcPaul Stewart  // There are no addresses on this interface.
88505a42c23f1d37daa8689fc4240034e62ed89f8fcPaul Stewart  EXPECT_FALSE(device_info_.HasOtherAddress(kTestDeviceIndex, address0));
88605a42c23f1d37daa8689fc4240034e62ed89f8fcPaul Stewart
88705a42c23f1d37daa8689fc4240034e62ed89f8fcPaul Stewart  message.reset(BuildAddressMessage(RTNLMessage::kModeAdd,
88805a42c23f1d37daa8689fc4240034e62ed89f8fcPaul Stewart                                    address0,
88905a42c23f1d37daa8689fc4240034e62ed89f8fcPaul Stewart                                    0,
89005a42c23f1d37daa8689fc4240034e62ed89f8fcPaul Stewart                                    RT_SCOPE_UNIVERSE));
89105a42c23f1d37daa8689fc4240034e62ed89f8fcPaul Stewart  SendMessageToDeviceInfo(*message);
89205a42c23f1d37daa8689fc4240034e62ed89f8fcPaul Stewart
89305a42c23f1d37daa8689fc4240034e62ed89f8fcPaul Stewart  IPAddress address1(IPAddress::kFamilyIPv6);
89405a42c23f1d37daa8689fc4240034e62ed89f8fcPaul Stewart  EXPECT_TRUE(address1.SetAddressFromString(kTestIPAddress1));
89505a42c23f1d37daa8689fc4240034e62ed89f8fcPaul Stewart  address1.set_prefix(kTestIPAddressPrefix1);
89605a42c23f1d37daa8689fc4240034e62ed89f8fcPaul Stewart  message.reset(BuildAddressMessage(RTNLMessage::kModeAdd,
89705a42c23f1d37daa8689fc4240034e62ed89f8fcPaul Stewart                                    address1,
89805a42c23f1d37daa8689fc4240034e62ed89f8fcPaul Stewart                                    0,
89905a42c23f1d37daa8689fc4240034e62ed89f8fcPaul Stewart                                    RT_SCOPE_LINK));
90005a42c23f1d37daa8689fc4240034e62ed89f8fcPaul Stewart  SendMessageToDeviceInfo(*message);
90105a42c23f1d37daa8689fc4240034e62ed89f8fcPaul Stewart
90205a42c23f1d37daa8689fc4240034e62ed89f8fcPaul Stewart  IPAddress address2(IPAddress::kFamilyIPv6);
90305a42c23f1d37daa8689fc4240034e62ed89f8fcPaul Stewart  EXPECT_TRUE(address2.SetAddressFromString(kTestIPAddress2));
90405a42c23f1d37daa8689fc4240034e62ed89f8fcPaul Stewart  message.reset(BuildAddressMessage(RTNLMessage::kModeAdd,
90505a42c23f1d37daa8689fc4240034e62ed89f8fcPaul Stewart                                    address2,
90605a42c23f1d37daa8689fc4240034e62ed89f8fcPaul Stewart                                    IFA_F_TEMPORARY,
90705a42c23f1d37daa8689fc4240034e62ed89f8fcPaul Stewart                                    RT_SCOPE_UNIVERSE));
90805a42c23f1d37daa8689fc4240034e62ed89f8fcPaul Stewart  SendMessageToDeviceInfo(*message);
90905a42c23f1d37daa8689fc4240034e62ed89f8fcPaul Stewart
91005a42c23f1d37daa8689fc4240034e62ed89f8fcPaul Stewart  IPAddress address3(IPAddress::kFamilyIPv6);
91105a42c23f1d37daa8689fc4240034e62ed89f8fcPaul Stewart  EXPECT_TRUE(address3.SetAddressFromString(kTestIPAddress3));
91205a42c23f1d37daa8689fc4240034e62ed89f8fcPaul Stewart
91305a42c23f1d37daa8689fc4240034e62ed89f8fcPaul Stewart  // The only IPv6 addresses on this interface are either flagged as
91405a42c23f1d37daa8689fc4240034e62ed89f8fcPaul Stewart  // temporary, or they are not universally scoped.
91505a42c23f1d37daa8689fc4240034e62ed89f8fcPaul Stewart  EXPECT_FALSE(device_info_.HasOtherAddress(kTestDeviceIndex, address3));
91605a42c23f1d37daa8689fc4240034e62ed89f8fcPaul Stewart
91705a42c23f1d37daa8689fc4240034e62ed89f8fcPaul Stewart
91805a42c23f1d37daa8689fc4240034e62ed89f8fcPaul Stewart  message.reset(BuildAddressMessage(RTNLMessage::kModeAdd,
91905a42c23f1d37daa8689fc4240034e62ed89f8fcPaul Stewart                                    address3,
92005a42c23f1d37daa8689fc4240034e62ed89f8fcPaul Stewart                                    0,
92105a42c23f1d37daa8689fc4240034e62ed89f8fcPaul Stewart                                    RT_SCOPE_UNIVERSE));
92205a42c23f1d37daa8689fc4240034e62ed89f8fcPaul Stewart  SendMessageToDeviceInfo(*message);
92305a42c23f1d37daa8689fc4240034e62ed89f8fcPaul Stewart
92405a42c23f1d37daa8689fc4240034e62ed89f8fcPaul Stewart  // address0 is on this interface.
92505a42c23f1d37daa8689fc4240034e62ed89f8fcPaul Stewart  EXPECT_FALSE(device_info_.HasOtherAddress(kTestDeviceIndex, address0));
92605a42c23f1d37daa8689fc4240034e62ed89f8fcPaul Stewart  // address1 is on this interface.
92705a42c23f1d37daa8689fc4240034e62ed89f8fcPaul Stewart  EXPECT_FALSE(device_info_.HasOtherAddress(kTestDeviceIndex, address1));
92805a42c23f1d37daa8689fc4240034e62ed89f8fcPaul Stewart  // address2 is on this interface.
92905a42c23f1d37daa8689fc4240034e62ed89f8fcPaul Stewart  EXPECT_FALSE(device_info_.HasOtherAddress(kTestDeviceIndex, address2));
93005a42c23f1d37daa8689fc4240034e62ed89f8fcPaul Stewart  // address3 is on this interface.
93105a42c23f1d37daa8689fc4240034e62ed89f8fcPaul Stewart  EXPECT_FALSE(device_info_.HasOtherAddress(kTestDeviceIndex, address3));
93205a42c23f1d37daa8689fc4240034e62ed89f8fcPaul Stewart
93305a42c23f1d37daa8689fc4240034e62ed89f8fcPaul Stewart  IPAddress address4(IPAddress::kFamilyIPv6);
93405a42c23f1d37daa8689fc4240034e62ed89f8fcPaul Stewart  EXPECT_TRUE(address4.SetAddressFromString(kTestIPAddress4));
93505a42c23f1d37daa8689fc4240034e62ed89f8fcPaul Stewart
93605a42c23f1d37daa8689fc4240034e62ed89f8fcPaul Stewart  // address4 is not on this interface, but address3 is, and is a qualified
93705a42c23f1d37daa8689fc4240034e62ed89f8fcPaul Stewart  // IPv6 address.
93805a42c23f1d37daa8689fc4240034e62ed89f8fcPaul Stewart  EXPECT_TRUE(device_info_.HasOtherAddress(kTestDeviceIndex, address4));
93905a42c23f1d37daa8689fc4240034e62ed89f8fcPaul Stewart
94005a42c23f1d37daa8689fc4240034e62ed89f8fcPaul Stewart  message.reset(BuildAddressMessage(RTNLMessage::kModeAdd,
94105a42c23f1d37daa8689fc4240034e62ed89f8fcPaul Stewart                                    address4,
94205a42c23f1d37daa8689fc4240034e62ed89f8fcPaul Stewart                                    IFA_F_PERMANENT,
94305a42c23f1d37daa8689fc4240034e62ed89f8fcPaul Stewart                                    RT_SCOPE_UNIVERSE));
94405a42c23f1d37daa8689fc4240034e62ed89f8fcPaul Stewart  SendMessageToDeviceInfo(*message);
94505a42c23f1d37daa8689fc4240034e62ed89f8fcPaul Stewart
94605a42c23f1d37daa8689fc4240034e62ed89f8fcPaul Stewart  // address4 is now on this interface.
94705a42c23f1d37daa8689fc4240034e62ed89f8fcPaul Stewart  EXPECT_FALSE(device_info_.HasOtherAddress(kTestDeviceIndex, address4));
94805a42c23f1d37daa8689fc4240034e62ed89f8fcPaul Stewart
94905a42c23f1d37daa8689fc4240034e62ed89f8fcPaul Stewart  IPAddress address5(IPAddress::kFamilyIPv4);
95005a42c23f1d37daa8689fc4240034e62ed89f8fcPaul Stewart  EXPECT_TRUE(address5.SetAddressFromString(kTestIPAddress5));
95105a42c23f1d37daa8689fc4240034e62ed89f8fcPaul Stewart  // address5 is not on this interface, but address0 is.
95205a42c23f1d37daa8689fc4240034e62ed89f8fcPaul Stewart  EXPECT_TRUE(device_info_.HasOtherAddress(kTestDeviceIndex, address5));
95305a42c23f1d37daa8689fc4240034e62ed89f8fcPaul Stewart
95405a42c23f1d37daa8689fc4240034e62ed89f8fcPaul Stewart  message.reset(BuildAddressMessage(RTNLMessage::kModeAdd,
95505a42c23f1d37daa8689fc4240034e62ed89f8fcPaul Stewart                                    address5,
95605a42c23f1d37daa8689fc4240034e62ed89f8fcPaul Stewart                                    IFA_F_PERMANENT,
95705a42c23f1d37daa8689fc4240034e62ed89f8fcPaul Stewart                                    RT_SCOPE_UNIVERSE));
95805a42c23f1d37daa8689fc4240034e62ed89f8fcPaul Stewart  SendMessageToDeviceInfo(*message);
95905a42c23f1d37daa8689fc4240034e62ed89f8fcPaul Stewart
96005a42c23f1d37daa8689fc4240034e62ed89f8fcPaul Stewart  // address5 is now on this interface.
96105a42c23f1d37daa8689fc4240034e62ed89f8fcPaul Stewart  EXPECT_FALSE(device_info_.HasOtherAddress(kTestDeviceIndex, address5));
96205a42c23f1d37daa8689fc4240034e62ed89f8fcPaul Stewart}
96305a42c23f1d37daa8689fc4240034e62ed89f8fcPaul Stewart
964a0db0fff6ae05e1ba3facfdf3d5049ca1a277be4Paul StewartTEST_F(DeviceInfoTest, HasDirectConnectivityTo) {
965cd47732488cd101eaf0d3558dde5a7d4e4fc260bBen Chan  unique_ptr<RTNLMessage> message(BuildLinkMessage(RTNLMessage::kModeAdd));
966a0db0fff6ae05e1ba3facfdf3d5049ca1a277be4Paul Stewart  SendMessageToDeviceInfo(*message);
967a0db0fff6ae05e1ba3facfdf3d5049ca1a277be4Paul Stewart
968a0db0fff6ae05e1ba3facfdf3d5049ca1a277be4Paul Stewart  IPAddress address0(IPAddress::kFamilyIPv4);
969a0db0fff6ae05e1ba3facfdf3d5049ca1a277be4Paul Stewart  EXPECT_TRUE(address0.SetAddressFromString(kTestIPAddress0));
970a0db0fff6ae05e1ba3facfdf3d5049ca1a277be4Paul Stewart
971a0db0fff6ae05e1ba3facfdf3d5049ca1a277be4Paul Stewart  // There are no addresses on this interface.
972a0db0fff6ae05e1ba3facfdf3d5049ca1a277be4Paul Stewart  EXPECT_FALSE(device_info_.HasDirectConnectivityTo(
973a0db0fff6ae05e1ba3facfdf3d5049ca1a277be4Paul Stewart      kTestDeviceIndex, address0));
974a0db0fff6ae05e1ba3facfdf3d5049ca1a277be4Paul Stewart
975a0db0fff6ae05e1ba3facfdf3d5049ca1a277be4Paul Stewart  IPAddress address1(IPAddress::kFamilyIPv6);
976a0db0fff6ae05e1ba3facfdf3d5049ca1a277be4Paul Stewart  EXPECT_TRUE(address1.SetAddressFromString(kTestIPAddress1));
977a0db0fff6ae05e1ba3facfdf3d5049ca1a277be4Paul Stewart  message.reset(BuildAddressMessage(RTNLMessage::kModeAdd,
978a0db0fff6ae05e1ba3facfdf3d5049ca1a277be4Paul Stewart                                    address1,
979a0db0fff6ae05e1ba3facfdf3d5049ca1a277be4Paul Stewart                                    IFA_F_PERMANENT,
980a0db0fff6ae05e1ba3facfdf3d5049ca1a277be4Paul Stewart                                    RT_SCOPE_UNIVERSE));
981a0db0fff6ae05e1ba3facfdf3d5049ca1a277be4Paul Stewart  SendMessageToDeviceInfo(*message);
982a0db0fff6ae05e1ba3facfdf3d5049ca1a277be4Paul Stewart
983a0db0fff6ae05e1ba3facfdf3d5049ca1a277be4Paul Stewart  // No current addresses are of the same family as |address0|.
984a0db0fff6ae05e1ba3facfdf3d5049ca1a277be4Paul Stewart  EXPECT_FALSE(device_info_.HasDirectConnectivityTo(
985a0db0fff6ae05e1ba3facfdf3d5049ca1a277be4Paul Stewart      kTestDeviceIndex, address0));
986a0db0fff6ae05e1ba3facfdf3d5049ca1a277be4Paul Stewart
987a0db0fff6ae05e1ba3facfdf3d5049ca1a277be4Paul Stewart  IPAddress address6(IPAddress::kFamilyIPv4);
988a0db0fff6ae05e1ba3facfdf3d5049ca1a277be4Paul Stewart  EXPECT_TRUE(address6.SetAddressFromString(kTestIPAddress6));
989a0db0fff6ae05e1ba3facfdf3d5049ca1a277be4Paul Stewart  address6.set_prefix(kTestIPAddressPrefix0);
990a0db0fff6ae05e1ba3facfdf3d5049ca1a277be4Paul Stewart  message.reset(BuildAddressMessage(RTNLMessage::kModeAdd,
991a0db0fff6ae05e1ba3facfdf3d5049ca1a277be4Paul Stewart                                    address6,
992a0db0fff6ae05e1ba3facfdf3d5049ca1a277be4Paul Stewart                                    IFA_F_PERMANENT,
993a0db0fff6ae05e1ba3facfdf3d5049ca1a277be4Paul Stewart                                    RT_SCOPE_UNIVERSE));
994a0db0fff6ae05e1ba3facfdf3d5049ca1a277be4Paul Stewart  SendMessageToDeviceInfo(*message);
995a0db0fff6ae05e1ba3facfdf3d5049ca1a277be4Paul Stewart
996a0db0fff6ae05e1ba3facfdf3d5049ca1a277be4Paul Stewart  // |address0| is not reachable from |address6|.
997a0db0fff6ae05e1ba3facfdf3d5049ca1a277be4Paul Stewart  EXPECT_FALSE(device_info_.HasDirectConnectivityTo(
998a0db0fff6ae05e1ba3facfdf3d5049ca1a277be4Paul Stewart      kTestDeviceIndex, address0));
999a0db0fff6ae05e1ba3facfdf3d5049ca1a277be4Paul Stewart
1000a0db0fff6ae05e1ba3facfdf3d5049ca1a277be4Paul Stewart  IPAddress address5(IPAddress::kFamilyIPv4);
1001a0db0fff6ae05e1ba3facfdf3d5049ca1a277be4Paul Stewart  EXPECT_TRUE(address5.SetAddressFromString(kTestIPAddress5));
1002a0db0fff6ae05e1ba3facfdf3d5049ca1a277be4Paul Stewart  address5.set_prefix(kTestIPAddressPrefix0);
1003a0db0fff6ae05e1ba3facfdf3d5049ca1a277be4Paul Stewart  message.reset(BuildAddressMessage(RTNLMessage::kModeAdd,
1004a0db0fff6ae05e1ba3facfdf3d5049ca1a277be4Paul Stewart                                    address5,
1005a0db0fff6ae05e1ba3facfdf3d5049ca1a277be4Paul Stewart                                    IFA_F_PERMANENT,
1006a0db0fff6ae05e1ba3facfdf3d5049ca1a277be4Paul Stewart                                    RT_SCOPE_UNIVERSE));
1007a0db0fff6ae05e1ba3facfdf3d5049ca1a277be4Paul Stewart  SendMessageToDeviceInfo(*message);
1008a0db0fff6ae05e1ba3facfdf3d5049ca1a277be4Paul Stewart
1009a0db0fff6ae05e1ba3facfdf3d5049ca1a277be4Paul Stewart  // |address0| is reachable from |address5| which is associated with the
1010a0db0fff6ae05e1ba3facfdf3d5049ca1a277be4Paul Stewart  // interface.
1011a0db0fff6ae05e1ba3facfdf3d5049ca1a277be4Paul Stewart  EXPECT_TRUE(device_info_.HasDirectConnectivityTo(
1012a0db0fff6ae05e1ba3facfdf3d5049ca1a277be4Paul Stewart      kTestDeviceIndex, address0));
1013a0db0fff6ae05e1ba3facfdf3d5049ca1a277be4Paul Stewart}
1014a0db0fff6ae05e1ba3facfdf3d5049ca1a277be4Paul Stewart
1015b27beee2e85a1ad3d68a1218c8c4fef4214626e8Thieu LeTEST_F(DeviceInfoTest, HasSubdir) {
10165ad1606ad8b3f74b2b7960a3003a2d1ca75d52b8Paul Stewart  base::ScopedTempDir temp_dir;
10178f1c835d879f82261a08257eb6f9677e6be51fdaThieu Le  EXPECT_TRUE(temp_dir.CreateUniqueTempDir());
1018a0ddf46e466bd4ba3d20952f0a6988c680c1af14Ben Chan  EXPECT_TRUE(base::CreateDirectory(temp_dir.path().Append("child1")));
1019b27beee2e85a1ad3d68a1218c8c4fef4214626e8Thieu Le  FilePath child2 = temp_dir.path().Append("child2");
1020a0ddf46e466bd4ba3d20952f0a6988c680c1af14Ben Chan  EXPECT_TRUE(base::CreateDirectory(child2));
1021b27beee2e85a1ad3d68a1218c8c4fef4214626e8Thieu Le  FilePath grandchild = child2.Append("grandchild");
1022a0ddf46e466bd4ba3d20952f0a6988c680c1af14Ben Chan  EXPECT_TRUE(base::CreateDirectory(grandchild));
1023a0ddf46e466bd4ba3d20952f0a6988c680c1af14Ben Chan  EXPECT_TRUE(base::CreateDirectory(grandchild.Append("greatgrandchild")));
1024b27beee2e85a1ad3d68a1218c8c4fef4214626e8Thieu Le  EXPECT_TRUE(DeviceInfo::HasSubdir(temp_dir.path(),
1025b27beee2e85a1ad3d68a1218c8c4fef4214626e8Thieu Le                                    FilePath("grandchild")));
1026b27beee2e85a1ad3d68a1218c8c4fef4214626e8Thieu Le  EXPECT_TRUE(DeviceInfo::HasSubdir(temp_dir.path(),
1027b27beee2e85a1ad3d68a1218c8c4fef4214626e8Thieu Le                                    FilePath("greatgrandchild")));
1028b27beee2e85a1ad3d68a1218c8c4fef4214626e8Thieu Le  EXPECT_FALSE(DeviceInfo::HasSubdir(temp_dir.path(),
1029b27beee2e85a1ad3d68a1218c8c4fef4214626e8Thieu Le                                     FilePath("nonexistent")));
10308f1c835d879f82261a08257eb6f9677e6be51fdaThieu Le}
10318f1c835d879f82261a08257eb6f9677e6be51fdaThieu Le
10324178023c4d627410777bdc259bfc7a31f2a4b8e9Gary MorainTEST_F(DeviceInfoTest, GetMACAddressFromKernelUnknownDevice) {
10334178023c4d627410777bdc259bfc7a31f2a4b8e9Gary Morain  SetSockets();
10344178023c4d627410777bdc259bfc7a31f2a4b8e9Gary Morain  EXPECT_CALL(*mock_sockets_, Socket(PF_INET, SOCK_DGRAM, 0)).Times(0);
10354178023c4d627410777bdc259bfc7a31f2a4b8e9Gary Morain  ByteString mac_address =
10364178023c4d627410777bdc259bfc7a31f2a4b8e9Gary Morain      device_info_.GetMACAddressFromKernel(kTestDeviceIndex);
10374178023c4d627410777bdc259bfc7a31f2a4b8e9Gary Morain  EXPECT_TRUE(mac_address.IsEmpty());
10384178023c4d627410777bdc259bfc7a31f2a4b8e9Gary Morain}
10394178023c4d627410777bdc259bfc7a31f2a4b8e9Gary Morain
10404178023c4d627410777bdc259bfc7a31f2a4b8e9Gary MorainTEST_F(DeviceInfoTest, GetMACAddressFromKernelUnableToOpenSocket) {
10414178023c4d627410777bdc259bfc7a31f2a4b8e9Gary Morain  SetSockets();
10424178023c4d627410777bdc259bfc7a31f2a4b8e9Gary Morain  EXPECT_CALL(*mock_sockets_, Socket(PF_INET, SOCK_DGRAM, 0))
10434178023c4d627410777bdc259bfc7a31f2a4b8e9Gary Morain      .WillOnce(Return(-1));
1044cd47732488cd101eaf0d3558dde5a7d4e4fc260bBen Chan  unique_ptr<RTNLMessage> message(BuildLinkMessage(RTNLMessage::kModeAdd));
10454178023c4d627410777bdc259bfc7a31f2a4b8e9Gary Morain  message->set_link_status(RTNLMessage::LinkStatus(0, IFF_LOWER_UP, 0));
10464178023c4d627410777bdc259bfc7a31f2a4b8e9Gary Morain  SendMessageToDeviceInfo(*message);
10474178023c4d627410777bdc259bfc7a31f2a4b8e9Gary Morain  EXPECT_TRUE(device_info_.GetDevice(kTestDeviceIndex).get());
10484178023c4d627410777bdc259bfc7a31f2a4b8e9Gary Morain  ByteString mac_address =
10494178023c4d627410777bdc259bfc7a31f2a4b8e9Gary Morain      device_info_.GetMACAddressFromKernel(kTestDeviceIndex);
10504178023c4d627410777bdc259bfc7a31f2a4b8e9Gary Morain  EXPECT_TRUE(mac_address.IsEmpty());
10514178023c4d627410777bdc259bfc7a31f2a4b8e9Gary Morain}
10524178023c4d627410777bdc259bfc7a31f2a4b8e9Gary Morain
10534178023c4d627410777bdc259bfc7a31f2a4b8e9Gary MorainTEST_F(DeviceInfoTest, GetMACAddressFromKernelIoctlFails) {
10544178023c4d627410777bdc259bfc7a31f2a4b8e9Gary Morain  SetSockets();
10554178023c4d627410777bdc259bfc7a31f2a4b8e9Gary Morain  const int kFd = 99;
10564178023c4d627410777bdc259bfc7a31f2a4b8e9Gary Morain  EXPECT_CALL(*mock_sockets_, Socket(PF_INET, SOCK_DGRAM, 0))
10574178023c4d627410777bdc259bfc7a31f2a4b8e9Gary Morain      .WillOnce(Return(kFd));
10584178023c4d627410777bdc259bfc7a31f2a4b8e9Gary Morain  EXPECT_CALL(*mock_sockets_, Ioctl(kFd, SIOCGIFHWADDR, NotNull()))
10594178023c4d627410777bdc259bfc7a31f2a4b8e9Gary Morain      .WillOnce(Return(-1));
10604178023c4d627410777bdc259bfc7a31f2a4b8e9Gary Morain  EXPECT_CALL(*mock_sockets_, Close(kFd));
10614178023c4d627410777bdc259bfc7a31f2a4b8e9Gary Morain
1062cd47732488cd101eaf0d3558dde5a7d4e4fc260bBen Chan  unique_ptr<RTNLMessage> message(BuildLinkMessage(RTNLMessage::kModeAdd));
10634178023c4d627410777bdc259bfc7a31f2a4b8e9Gary Morain  message->set_link_status(RTNLMessage::LinkStatus(0, IFF_LOWER_UP, 0));
10644178023c4d627410777bdc259bfc7a31f2a4b8e9Gary Morain  SendMessageToDeviceInfo(*message);
10654178023c4d627410777bdc259bfc7a31f2a4b8e9Gary Morain  EXPECT_TRUE(device_info_.GetDevice(kTestDeviceIndex).get());
10664178023c4d627410777bdc259bfc7a31f2a4b8e9Gary Morain
10674178023c4d627410777bdc259bfc7a31f2a4b8e9Gary Morain  ByteString mac_address =
10684178023c4d627410777bdc259bfc7a31f2a4b8e9Gary Morain      device_info_.GetMACAddressFromKernel(kTestDeviceIndex);
10694178023c4d627410777bdc259bfc7a31f2a4b8e9Gary Morain  EXPECT_TRUE(mac_address.IsEmpty());
10704178023c4d627410777bdc259bfc7a31f2a4b8e9Gary Morain}
10714178023c4d627410777bdc259bfc7a31f2a4b8e9Gary Morain
10724178023c4d627410777bdc259bfc7a31f2a4b8e9Gary MorainMATCHER_P2(IfreqEquals, ifindex, ifname, "") {
10733b30ca58d13cf66b75ba0729b222ddc42ae68b33Paul Stewart  const struct ifreq* const ifr = static_cast<struct ifreq*>(arg);
1074cc225ef3b77b5e098cc12c661a947e1737480777Ben Chan  return (ifr != nullptr) &&
10754178023c4d627410777bdc259bfc7a31f2a4b8e9Gary Morain      (ifr->ifr_ifindex == ifindex) &&
10764178023c4d627410777bdc259bfc7a31f2a4b8e9Gary Morain      (strcmp(ifname, ifr->ifr_name) == 0);
10774178023c4d627410777bdc259bfc7a31f2a4b8e9Gary Morain}
10784178023c4d627410777bdc259bfc7a31f2a4b8e9Gary Morain
10794178023c4d627410777bdc259bfc7a31f2a4b8e9Gary MorainACTION_P(SetIfreq, ifr) {
10803b30ca58d13cf66b75ba0729b222ddc42ae68b33Paul Stewart  struct ifreq* const ifr_arg = static_cast<struct ifreq*>(arg2);
10814178023c4d627410777bdc259bfc7a31f2a4b8e9Gary Morain  *ifr_arg = ifr;
10824178023c4d627410777bdc259bfc7a31f2a4b8e9Gary Morain}
10834178023c4d627410777bdc259bfc7a31f2a4b8e9Gary Morain
10844178023c4d627410777bdc259bfc7a31f2a4b8e9Gary MorainTEST_F(DeviceInfoTest, GetMACAddressFromKernel) {
10854178023c4d627410777bdc259bfc7a31f2a4b8e9Gary Morain  SetSockets();
10864178023c4d627410777bdc259bfc7a31f2a4b8e9Gary Morain  const int kFd = 99;
10874178023c4d627410777bdc259bfc7a31f2a4b8e9Gary Morain  struct ifreq ifr;
1088fc34925d45add6f1c81a42a7632621e69bfdc43eHan Shen  static uint8_t kMacAddress[] = {0x00, 0x01, 0x02, 0xaa, 0xbb, 0xcc};
10894178023c4d627410777bdc259bfc7a31f2a4b8e9Gary Morain  memcpy(ifr.ifr_hwaddr.sa_data, kMacAddress, sizeof(kMacAddress));
10904178023c4d627410777bdc259bfc7a31f2a4b8e9Gary Morain  EXPECT_CALL(*mock_sockets_, Socket(PF_INET, SOCK_DGRAM, 0))
10914178023c4d627410777bdc259bfc7a31f2a4b8e9Gary Morain      .WillOnce(Return(kFd));
10924178023c4d627410777bdc259bfc7a31f2a4b8e9Gary Morain  EXPECT_CALL(*mock_sockets_,
10934178023c4d627410777bdc259bfc7a31f2a4b8e9Gary Morain              Ioctl(kFd, SIOCGIFHWADDR,
10944178023c4d627410777bdc259bfc7a31f2a4b8e9Gary Morain                    IfreqEquals(kTestDeviceIndex, kTestDeviceName)))
10954178023c4d627410777bdc259bfc7a31f2a4b8e9Gary Morain      .WillOnce(DoAll(SetIfreq(ifr), Return(0)));
10964178023c4d627410777bdc259bfc7a31f2a4b8e9Gary Morain  EXPECT_CALL(*mock_sockets_, Close(kFd));
10974178023c4d627410777bdc259bfc7a31f2a4b8e9Gary Morain
1098cd47732488cd101eaf0d3558dde5a7d4e4fc260bBen Chan  unique_ptr<RTNLMessage> message(BuildLinkMessage(RTNLMessage::kModeAdd));
10994178023c4d627410777bdc259bfc7a31f2a4b8e9Gary Morain  message->set_link_status(RTNLMessage::LinkStatus(0, IFF_LOWER_UP, 0));
11004178023c4d627410777bdc259bfc7a31f2a4b8e9Gary Morain  SendMessageToDeviceInfo(*message);
11014178023c4d627410777bdc259bfc7a31f2a4b8e9Gary Morain  EXPECT_TRUE(device_info_.GetDevice(kTestDeviceIndex).get());
11024178023c4d627410777bdc259bfc7a31f2a4b8e9Gary Morain
11034178023c4d627410777bdc259bfc7a31f2a4b8e9Gary Morain  ByteString mac_address =
11044178023c4d627410777bdc259bfc7a31f2a4b8e9Gary Morain      device_info_.GetMACAddressFromKernel(kTestDeviceIndex);
11054178023c4d627410777bdc259bfc7a31f2a4b8e9Gary Morain  EXPECT_THAT(kMacAddress,
11064178023c4d627410777bdc259bfc7a31f2a4b8e9Gary Morain              ElementsAreArray(mac_address.GetData(), sizeof(kMacAddress)));
11074178023c4d627410777bdc259bfc7a31f2a4b8e9Gary Morain}
11084178023c4d627410777bdc259bfc7a31f2a4b8e9Gary Morain
11096950ba51e9a35b91687103fdc451e1539cdfb35dPaul StewartTEST_F(DeviceInfoTest, GetMACAddressOfPeerUnknownDevice) {
11106950ba51e9a35b91687103fdc451e1539cdfb35dPaul Stewart  SetSockets();
11116950ba51e9a35b91687103fdc451e1539cdfb35dPaul Stewart  EXPECT_CALL(*mock_sockets_, Socket(PF_INET, SOCK_DGRAM, 0)).Times(0);
11126950ba51e9a35b91687103fdc451e1539cdfb35dPaul Stewart  IPAddress address(IPAddress::kFamilyIPv4);
11136950ba51e9a35b91687103fdc451e1539cdfb35dPaul Stewart  EXPECT_TRUE(address.SetAddressFromString(kTestIPAddress0));
11146950ba51e9a35b91687103fdc451e1539cdfb35dPaul Stewart  ByteString mac_address;
11156950ba51e9a35b91687103fdc451e1539cdfb35dPaul Stewart  EXPECT_FALSE(device_info_.GetDevice(kTestDeviceIndex).get());
11166950ba51e9a35b91687103fdc451e1539cdfb35dPaul Stewart  EXPECT_FALSE(device_info_.GetMACAddressOfPeer(
11176950ba51e9a35b91687103fdc451e1539cdfb35dPaul Stewart      kTestDeviceIndex, address, &mac_address));
11186950ba51e9a35b91687103fdc451e1539cdfb35dPaul Stewart}
11196950ba51e9a35b91687103fdc451e1539cdfb35dPaul Stewart
11206950ba51e9a35b91687103fdc451e1539cdfb35dPaul StewartTEST_F(DeviceInfoTest, GetMACAddressOfPeerBadAddress) {
11216950ba51e9a35b91687103fdc451e1539cdfb35dPaul Stewart  SetSockets();
1122cd47732488cd101eaf0d3558dde5a7d4e4fc260bBen Chan  unique_ptr<RTNLMessage> message(BuildLinkMessage(RTNLMessage::kModeAdd));
11236950ba51e9a35b91687103fdc451e1539cdfb35dPaul Stewart  message->set_link_status(RTNLMessage::LinkStatus(0, IFF_LOWER_UP, 0));
11246950ba51e9a35b91687103fdc451e1539cdfb35dPaul Stewart  SendMessageToDeviceInfo(*message);
11256950ba51e9a35b91687103fdc451e1539cdfb35dPaul Stewart  EXPECT_TRUE(device_info_.GetDevice(kTestDeviceIndex).get());
11266950ba51e9a35b91687103fdc451e1539cdfb35dPaul Stewart
11276950ba51e9a35b91687103fdc451e1539cdfb35dPaul Stewart  EXPECT_CALL(*mock_sockets_, Socket(PF_INET, SOCK_DGRAM, 0)).Times(0);
11286950ba51e9a35b91687103fdc451e1539cdfb35dPaul Stewart
11296950ba51e9a35b91687103fdc451e1539cdfb35dPaul Stewart  // An improperly formatted IPv4 address should fail.
11306950ba51e9a35b91687103fdc451e1539cdfb35dPaul Stewart  IPAddress empty_ipv4_address(IPAddress::kFamilyIPv4);
11316950ba51e9a35b91687103fdc451e1539cdfb35dPaul Stewart  ByteString mac_address;
11326950ba51e9a35b91687103fdc451e1539cdfb35dPaul Stewart  EXPECT_FALSE(device_info_.GetMACAddressOfPeer(
11336950ba51e9a35b91687103fdc451e1539cdfb35dPaul Stewart      kTestDeviceIndex, empty_ipv4_address, &mac_address));
11346950ba51e9a35b91687103fdc451e1539cdfb35dPaul Stewart
11356950ba51e9a35b91687103fdc451e1539cdfb35dPaul Stewart  // IPv6 addresses are not supported.
11366950ba51e9a35b91687103fdc451e1539cdfb35dPaul Stewart  IPAddress valid_ipv6_address(IPAddress::kFamilyIPv6);
11376950ba51e9a35b91687103fdc451e1539cdfb35dPaul Stewart  EXPECT_TRUE(valid_ipv6_address.SetAddressFromString(kTestIPAddress1));
11386950ba51e9a35b91687103fdc451e1539cdfb35dPaul Stewart  EXPECT_FALSE(device_info_.GetMACAddressOfPeer(
11396950ba51e9a35b91687103fdc451e1539cdfb35dPaul Stewart      kTestDeviceIndex, valid_ipv6_address, &mac_address));
11406950ba51e9a35b91687103fdc451e1539cdfb35dPaul Stewart}
11416950ba51e9a35b91687103fdc451e1539cdfb35dPaul Stewart
11426950ba51e9a35b91687103fdc451e1539cdfb35dPaul StewartTEST_F(DeviceInfoTest, GetMACAddressOfPeerUnableToOpenSocket) {
11436950ba51e9a35b91687103fdc451e1539cdfb35dPaul Stewart  SetSockets();
11446950ba51e9a35b91687103fdc451e1539cdfb35dPaul Stewart  EXPECT_CALL(*mock_sockets_, Socket(PF_INET, SOCK_DGRAM, 0))
11456950ba51e9a35b91687103fdc451e1539cdfb35dPaul Stewart      .WillOnce(Return(-1));
1146cd47732488cd101eaf0d3558dde5a7d4e4fc260bBen Chan  unique_ptr<RTNLMessage> message(BuildLinkMessage(RTNLMessage::kModeAdd));
11476950ba51e9a35b91687103fdc451e1539cdfb35dPaul Stewart  message->set_link_status(RTNLMessage::LinkStatus(0, IFF_LOWER_UP, 0));
11486950ba51e9a35b91687103fdc451e1539cdfb35dPaul Stewart  SendMessageToDeviceInfo(*message);
11496950ba51e9a35b91687103fdc451e1539cdfb35dPaul Stewart  IPAddress ip_address(IPAddress::kFamilyIPv4);
11506950ba51e9a35b91687103fdc451e1539cdfb35dPaul Stewart  EXPECT_TRUE(ip_address.SetAddressFromString(kTestIPAddress0));
11516950ba51e9a35b91687103fdc451e1539cdfb35dPaul Stewart  ByteString mac_address;
11526950ba51e9a35b91687103fdc451e1539cdfb35dPaul Stewart  EXPECT_FALSE(device_info_.GetMACAddressOfPeer(
11536950ba51e9a35b91687103fdc451e1539cdfb35dPaul Stewart      kTestDeviceIndex, ip_address, &mac_address));
11546950ba51e9a35b91687103fdc451e1539cdfb35dPaul Stewart}
11556950ba51e9a35b91687103fdc451e1539cdfb35dPaul Stewart
11566950ba51e9a35b91687103fdc451e1539cdfb35dPaul StewartTEST_F(DeviceInfoTest, GetMACAddressOfPeerIoctlFails) {
11576950ba51e9a35b91687103fdc451e1539cdfb35dPaul Stewart  SetSockets();
11586950ba51e9a35b91687103fdc451e1539cdfb35dPaul Stewart  const int kFd = 99;
11596950ba51e9a35b91687103fdc451e1539cdfb35dPaul Stewart  EXPECT_CALL(*mock_sockets_, Socket(PF_INET, SOCK_DGRAM, 0))
11606950ba51e9a35b91687103fdc451e1539cdfb35dPaul Stewart      .WillOnce(Return(kFd));
11616950ba51e9a35b91687103fdc451e1539cdfb35dPaul Stewart  EXPECT_CALL(*mock_sockets_, Ioctl(kFd, SIOCGARP, NotNull()))
11626950ba51e9a35b91687103fdc451e1539cdfb35dPaul Stewart      .WillOnce(Return(-1));
1163cd47732488cd101eaf0d3558dde5a7d4e4fc260bBen Chan  unique_ptr<RTNLMessage> message(BuildLinkMessage(RTNLMessage::kModeAdd));
11646950ba51e9a35b91687103fdc451e1539cdfb35dPaul Stewart  message->set_link_status(RTNLMessage::LinkStatus(0, IFF_LOWER_UP, 0));
11656950ba51e9a35b91687103fdc451e1539cdfb35dPaul Stewart  SendMessageToDeviceInfo(*message);
11666950ba51e9a35b91687103fdc451e1539cdfb35dPaul Stewart  IPAddress ip_address(IPAddress::kFamilyIPv4);
11676950ba51e9a35b91687103fdc451e1539cdfb35dPaul Stewart  EXPECT_TRUE(ip_address.SetAddressFromString(kTestIPAddress0));
11686950ba51e9a35b91687103fdc451e1539cdfb35dPaul Stewart  ByteString mac_address;
11696950ba51e9a35b91687103fdc451e1539cdfb35dPaul Stewart  EXPECT_FALSE(device_info_.GetMACAddressOfPeer(
11706950ba51e9a35b91687103fdc451e1539cdfb35dPaul Stewart      kTestDeviceIndex, ip_address, &mac_address));
11716950ba51e9a35b91687103fdc451e1539cdfb35dPaul Stewart}
11726950ba51e9a35b91687103fdc451e1539cdfb35dPaul Stewart
11736950ba51e9a35b91687103fdc451e1539cdfb35dPaul StewartMATCHER_P2(ArpreqEquals, ifname, peer, "") {
11743b30ca58d13cf66b75ba0729b222ddc42ae68b33Paul Stewart  const struct arpreq* const areq = static_cast<struct arpreq*>(arg);
1175cc225ef3b77b5e098cc12c661a947e1737480777Ben Chan  if (areq == nullptr) {
11766950ba51e9a35b91687103fdc451e1539cdfb35dPaul Stewart    return false;
11776950ba51e9a35b91687103fdc451e1539cdfb35dPaul Stewart  }
11786950ba51e9a35b91687103fdc451e1539cdfb35dPaul Stewart
11793b30ca58d13cf66b75ba0729b222ddc42ae68b33Paul Stewart  const struct sockaddr_in* const protocol_address =
11803b30ca58d13cf66b75ba0729b222ddc42ae68b33Paul Stewart      reinterpret_cast<const struct sockaddr_in*>(&areq->arp_pa);
11813b30ca58d13cf66b75ba0729b222ddc42ae68b33Paul Stewart  const struct sockaddr_in* const hardware_address =
11823b30ca58d13cf66b75ba0729b222ddc42ae68b33Paul Stewart      reinterpret_cast<const struct sockaddr_in*>(&areq->arp_ha);
11836950ba51e9a35b91687103fdc451e1539cdfb35dPaul Stewart
11846950ba51e9a35b91687103fdc451e1539cdfb35dPaul Stewart  return
11856950ba51e9a35b91687103fdc451e1539cdfb35dPaul Stewart      strcmp(ifname, areq->arp_dev) == 0 &&
11866950ba51e9a35b91687103fdc451e1539cdfb35dPaul Stewart      protocol_address->sin_family == AF_INET &&
11876950ba51e9a35b91687103fdc451e1539cdfb35dPaul Stewart      memcmp(&protocol_address->sin_addr.s_addr,
11886950ba51e9a35b91687103fdc451e1539cdfb35dPaul Stewart             peer.address().GetConstData(),
11896950ba51e9a35b91687103fdc451e1539cdfb35dPaul Stewart             peer.address().GetLength()) == 0 &&
11906950ba51e9a35b91687103fdc451e1539cdfb35dPaul Stewart      hardware_address->sin_family == ARPHRD_ETHER;
11916950ba51e9a35b91687103fdc451e1539cdfb35dPaul Stewart}
11926950ba51e9a35b91687103fdc451e1539cdfb35dPaul Stewart
11936950ba51e9a35b91687103fdc451e1539cdfb35dPaul StewartACTION_P(SetArpreq, areq) {
11943b30ca58d13cf66b75ba0729b222ddc42ae68b33Paul Stewart  struct arpreq* const areq_arg = static_cast<struct arpreq*>(arg2);
11956950ba51e9a35b91687103fdc451e1539cdfb35dPaul Stewart  *areq_arg = areq;
11966950ba51e9a35b91687103fdc451e1539cdfb35dPaul Stewart}
11976950ba51e9a35b91687103fdc451e1539cdfb35dPaul Stewart
11986950ba51e9a35b91687103fdc451e1539cdfb35dPaul StewartTEST_F(DeviceInfoTest, GetMACAddressOfPeer) {
1199cd47732488cd101eaf0d3558dde5a7d4e4fc260bBen Chan  unique_ptr<RTNLMessage> message(BuildLinkMessage(RTNLMessage::kModeAdd));
12006950ba51e9a35b91687103fdc451e1539cdfb35dPaul Stewart  message->set_link_status(RTNLMessage::LinkStatus(0, IFF_LOWER_UP, 0));
12016950ba51e9a35b91687103fdc451e1539cdfb35dPaul Stewart  SendMessageToDeviceInfo(*message);
12026950ba51e9a35b91687103fdc451e1539cdfb35dPaul Stewart
12036950ba51e9a35b91687103fdc451e1539cdfb35dPaul Stewart  SetSockets();
12046950ba51e9a35b91687103fdc451e1539cdfb35dPaul Stewart
12056950ba51e9a35b91687103fdc451e1539cdfb35dPaul Stewart  const int kFd = 99;
12066950ba51e9a35b91687103fdc451e1539cdfb35dPaul Stewart  EXPECT_CALL(*mock_sockets_, Socket(PF_INET, SOCK_DGRAM, 0))
12076950ba51e9a35b91687103fdc451e1539cdfb35dPaul Stewart      .WillRepeatedly(Return(kFd));
12086950ba51e9a35b91687103fdc451e1539cdfb35dPaul Stewart
12096950ba51e9a35b91687103fdc451e1539cdfb35dPaul Stewart  IPAddress ip_address(IPAddress::kFamilyIPv4);
12106950ba51e9a35b91687103fdc451e1539cdfb35dPaul Stewart  EXPECT_TRUE(ip_address.SetAddressFromString(kTestIPAddress0));
12116950ba51e9a35b91687103fdc451e1539cdfb35dPaul Stewart
12126950ba51e9a35b91687103fdc451e1539cdfb35dPaul Stewart  static uint8_t kZeroMacAddress[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
12136950ba51e9a35b91687103fdc451e1539cdfb35dPaul Stewart  struct arpreq zero_areq_response;
12146950ba51e9a35b91687103fdc451e1539cdfb35dPaul Stewart  memcpy(zero_areq_response.arp_ha.sa_data, kZeroMacAddress,
12156950ba51e9a35b91687103fdc451e1539cdfb35dPaul Stewart         sizeof(kZeroMacAddress));
12166950ba51e9a35b91687103fdc451e1539cdfb35dPaul Stewart
12176950ba51e9a35b91687103fdc451e1539cdfb35dPaul Stewart  static uint8_t kMacAddress[] = {0x01, 0x02, 0x03, 0xaa, 0xbb, 0xcc};
12186950ba51e9a35b91687103fdc451e1539cdfb35dPaul Stewart  struct arpreq areq_response;
12196950ba51e9a35b91687103fdc451e1539cdfb35dPaul Stewart  memcpy(areq_response.arp_ha.sa_data, kMacAddress, sizeof(kMacAddress));
12206950ba51e9a35b91687103fdc451e1539cdfb35dPaul Stewart
12216950ba51e9a35b91687103fdc451e1539cdfb35dPaul Stewart  EXPECT_CALL(*mock_sockets_, Ioctl(
12226950ba51e9a35b91687103fdc451e1539cdfb35dPaul Stewart      kFd, SIOCGARP, ArpreqEquals(kTestDeviceName, ip_address)))
12236950ba51e9a35b91687103fdc451e1539cdfb35dPaul Stewart          .WillOnce(DoAll(SetArpreq(zero_areq_response), Return(0)))
12246950ba51e9a35b91687103fdc451e1539cdfb35dPaul Stewart          .WillOnce(DoAll(SetArpreq(areq_response), Return(0)));
12256950ba51e9a35b91687103fdc451e1539cdfb35dPaul Stewart
12266950ba51e9a35b91687103fdc451e1539cdfb35dPaul Stewart  ByteString mac_address;
12276950ba51e9a35b91687103fdc451e1539cdfb35dPaul Stewart  EXPECT_FALSE(device_info_.GetMACAddressOfPeer(
12286950ba51e9a35b91687103fdc451e1539cdfb35dPaul Stewart      kTestDeviceIndex, ip_address, &mac_address));
12296950ba51e9a35b91687103fdc451e1539cdfb35dPaul Stewart  EXPECT_TRUE(device_info_.GetMACAddressOfPeer(
12306950ba51e9a35b91687103fdc451e1539cdfb35dPaul Stewart      kTestDeviceIndex, ip_address, &mac_address));
12316950ba51e9a35b91687103fdc451e1539cdfb35dPaul Stewart  EXPECT_THAT(kMacAddress,
12326950ba51e9a35b91687103fdc451e1539cdfb35dPaul Stewart              ElementsAreArray(mac_address.GetData(), sizeof(kMacAddress)));
12336950ba51e9a35b91687103fdc451e1539cdfb35dPaul Stewart}
12346950ba51e9a35b91687103fdc451e1539cdfb35dPaul Stewart
1235d55f6ae45047f984457508d78c70abcd837307eaPaul StewartTEST_F(DeviceInfoTest, IPv6AddressChanged) {
1236d55f6ae45047f984457508d78c70abcd837307eaPaul Stewart  scoped_refptr<MockDevice> device(new MockDevice(
1237d55f6ae45047f984457508d78c70abcd837307eaPaul Stewart      &control_interface_, &dispatcher_, &metrics_, &manager_,
1238d55f6ae45047f984457508d78c70abcd837307eaPaul Stewart      "null0", "addr0", kTestDeviceIndex));
1239d55f6ae45047f984457508d78c70abcd837307eaPaul Stewart
1240d55f6ae45047f984457508d78c70abcd837307eaPaul Stewart  // Device info entry does not exist.
1241cc225ef3b77b5e098cc12c661a947e1737480777Ben Chan  EXPECT_FALSE(device_info_.GetPrimaryIPv6Address(kTestDeviceIndex, nullptr));
1242d55f6ae45047f984457508d78c70abcd837307eaPaul Stewart
1243d55f6ae45047f984457508d78c70abcd837307eaPaul Stewart  device_info_.infos_[kTestDeviceIndex].device = device;
1244d55f6ae45047f984457508d78c70abcd837307eaPaul Stewart
1245d55f6ae45047f984457508d78c70abcd837307eaPaul Stewart  // Device info entry contains no addresses.
1246cc225ef3b77b5e098cc12c661a947e1737480777Ben Chan  EXPECT_FALSE(device_info_.GetPrimaryIPv6Address(kTestDeviceIndex, nullptr));
1247d55f6ae45047f984457508d78c70abcd837307eaPaul Stewart
1248d55f6ae45047f984457508d78c70abcd837307eaPaul Stewart  IPAddress ipv4_address(IPAddress::kFamilyIPv4);
1249d55f6ae45047f984457508d78c70abcd837307eaPaul Stewart  EXPECT_TRUE(ipv4_address.SetAddressFromString(kTestIPAddress0));
1250cd47732488cd101eaf0d3558dde5a7d4e4fc260bBen Chan  unique_ptr<RTNLMessage> message(
1251cd47732488cd101eaf0d3558dde5a7d4e4fc260bBen Chan      BuildAddressMessage(RTNLMessage::kModeAdd, ipv4_address, 0, 0));
1252d55f6ae45047f984457508d78c70abcd837307eaPaul Stewart
1253d55f6ae45047f984457508d78c70abcd837307eaPaul Stewart  EXPECT_CALL(*device, OnIPv6AddressChanged()).Times(0);
1254d55f6ae45047f984457508d78c70abcd837307eaPaul Stewart
1255d55f6ae45047f984457508d78c70abcd837307eaPaul Stewart  // We should ignore IPv4 addresses.
1256d55f6ae45047f984457508d78c70abcd837307eaPaul Stewart  SendMessageToDeviceInfo(*message);
1257cc225ef3b77b5e098cc12c661a947e1737480777Ben Chan  EXPECT_FALSE(device_info_.GetPrimaryIPv6Address(kTestDeviceIndex, nullptr));
1258d55f6ae45047f984457508d78c70abcd837307eaPaul Stewart
1259d55f6ae45047f984457508d78c70abcd837307eaPaul Stewart  IPAddress ipv6_address1(IPAddress::kFamilyIPv6);
1260d55f6ae45047f984457508d78c70abcd837307eaPaul Stewart  EXPECT_TRUE(ipv6_address1.SetAddressFromString(kTestIPAddress1));
1261d55f6ae45047f984457508d78c70abcd837307eaPaul Stewart  message.reset(BuildAddressMessage(
1262d55f6ae45047f984457508d78c70abcd837307eaPaul Stewart      RTNLMessage::kModeAdd, ipv6_address1, 0, RT_SCOPE_LINK));
1263d55f6ae45047f984457508d78c70abcd837307eaPaul Stewart
1264d55f6ae45047f984457508d78c70abcd837307eaPaul Stewart  // We should ignore non-SCOPE_UNIVERSE messages for IPv6.
1265d55f6ae45047f984457508d78c70abcd837307eaPaul Stewart  SendMessageToDeviceInfo(*message);
1266cc225ef3b77b5e098cc12c661a947e1737480777Ben Chan  EXPECT_FALSE(device_info_.GetPrimaryIPv6Address(kTestDeviceIndex, nullptr));
1267d55f6ae45047f984457508d78c70abcd837307eaPaul Stewart
12680951ccbfca977a9cf218b2e4308aa26fb4d06ef9Alex Vakulenko  Mock::VerifyAndClearExpectations(device.get());
1269d55f6ae45047f984457508d78c70abcd837307eaPaul Stewart  IPAddress ipv6_address2(IPAddress::kFamilyIPv6);
1270d55f6ae45047f984457508d78c70abcd837307eaPaul Stewart  EXPECT_TRUE(ipv6_address2.SetAddressFromString(kTestIPAddress2));
1271d55f6ae45047f984457508d78c70abcd837307eaPaul Stewart  message.reset(BuildAddressMessage(
1272d55f6ae45047f984457508d78c70abcd837307eaPaul Stewart      RTNLMessage::kModeAdd, ipv6_address2, IFA_F_TEMPORARY,
1273d55f6ae45047f984457508d78c70abcd837307eaPaul Stewart      RT_SCOPE_UNIVERSE));
1274d55f6ae45047f984457508d78c70abcd837307eaPaul Stewart
1275d55f6ae45047f984457508d78c70abcd837307eaPaul Stewart  // Add a temporary address.
1276d55f6ae45047f984457508d78c70abcd837307eaPaul Stewart  EXPECT_CALL(*device, OnIPv6AddressChanged());
1277d55f6ae45047f984457508d78c70abcd837307eaPaul Stewart  SendMessageToDeviceInfo(*message);
1278d55f6ae45047f984457508d78c70abcd837307eaPaul Stewart  IPAddress address0(IPAddress::kFamilyUnknown);
1279d55f6ae45047f984457508d78c70abcd837307eaPaul Stewart  EXPECT_TRUE(device_info_.GetPrimaryIPv6Address(kTestDeviceIndex, &address0));
1280d55f6ae45047f984457508d78c70abcd837307eaPaul Stewart  EXPECT_TRUE(address0.Equals(ipv6_address2));
12810951ccbfca977a9cf218b2e4308aa26fb4d06ef9Alex Vakulenko  Mock::VerifyAndClearExpectations(device.get());
1282d55f6ae45047f984457508d78c70abcd837307eaPaul Stewart
1283d55f6ae45047f984457508d78c70abcd837307eaPaul Stewart  IPAddress ipv6_address3(IPAddress::kFamilyIPv6);
1284d55f6ae45047f984457508d78c70abcd837307eaPaul Stewart  EXPECT_TRUE(ipv6_address3.SetAddressFromString(kTestIPAddress3));
1285d55f6ae45047f984457508d78c70abcd837307eaPaul Stewart  message.reset(BuildAddressMessage(
1286d55f6ae45047f984457508d78c70abcd837307eaPaul Stewart      RTNLMessage::kModeAdd, ipv6_address3, 0, RT_SCOPE_UNIVERSE));
1287d55f6ae45047f984457508d78c70abcd837307eaPaul Stewart
1288d55f6ae45047f984457508d78c70abcd837307eaPaul Stewart  // Adding a non-temporary address alerts the Device, but does not override
1289d55f6ae45047f984457508d78c70abcd837307eaPaul Stewart  // the primary address since the previous one was temporary.
1290d55f6ae45047f984457508d78c70abcd837307eaPaul Stewart  EXPECT_CALL(*device, OnIPv6AddressChanged());
1291d55f6ae45047f984457508d78c70abcd837307eaPaul Stewart  SendMessageToDeviceInfo(*message);
1292d55f6ae45047f984457508d78c70abcd837307eaPaul Stewart  IPAddress address1(IPAddress::kFamilyUnknown);
1293d55f6ae45047f984457508d78c70abcd837307eaPaul Stewart  EXPECT_TRUE(device_info_.GetPrimaryIPv6Address(kTestDeviceIndex, &address1));
1294d55f6ae45047f984457508d78c70abcd837307eaPaul Stewart  EXPECT_TRUE(address1.Equals(ipv6_address2));
12950951ccbfca977a9cf218b2e4308aa26fb4d06ef9Alex Vakulenko  Mock::VerifyAndClearExpectations(device.get());
1296d55f6ae45047f984457508d78c70abcd837307eaPaul Stewart
1297d55f6ae45047f984457508d78c70abcd837307eaPaul Stewart  IPAddress ipv6_address4(IPAddress::kFamilyIPv6);
1298d55f6ae45047f984457508d78c70abcd837307eaPaul Stewart  EXPECT_TRUE(ipv6_address4.SetAddressFromString(kTestIPAddress4));
1299d55f6ae45047f984457508d78c70abcd837307eaPaul Stewart  message.reset(BuildAddressMessage(
1300241e3f317fe3089dd7dcb4e7c5a34430926d4e2ePaul Stewart      RTNLMessage::kModeAdd, ipv6_address4, IFA_F_TEMPORARY | IFA_F_DEPRECATED,
1301d55f6ae45047f984457508d78c70abcd837307eaPaul Stewart      RT_SCOPE_UNIVERSE));
1302d55f6ae45047f984457508d78c70abcd837307eaPaul Stewart
1303241e3f317fe3089dd7dcb4e7c5a34430926d4e2ePaul Stewart  // Adding a temporary deprecated address alerts the Device, but does not
1304241e3f317fe3089dd7dcb4e7c5a34430926d4e2ePaul Stewart  // override the primary address since the previous one was non-deprecated.
1305d55f6ae45047f984457508d78c70abcd837307eaPaul Stewart  EXPECT_CALL(*device, OnIPv6AddressChanged());
1306d55f6ae45047f984457508d78c70abcd837307eaPaul Stewart  SendMessageToDeviceInfo(*message);
1307d55f6ae45047f984457508d78c70abcd837307eaPaul Stewart  IPAddress address2(IPAddress::kFamilyUnknown);
1308d55f6ae45047f984457508d78c70abcd837307eaPaul Stewart  EXPECT_TRUE(device_info_.GetPrimaryIPv6Address(kTestDeviceIndex, &address2));
1309241e3f317fe3089dd7dcb4e7c5a34430926d4e2ePaul Stewart  EXPECT_TRUE(address2.Equals(ipv6_address2));
1310241e3f317fe3089dd7dcb4e7c5a34430926d4e2ePaul Stewart  Mock::VerifyAndClearExpectations(device.get());
1311241e3f317fe3089dd7dcb4e7c5a34430926d4e2ePaul Stewart
1312241e3f317fe3089dd7dcb4e7c5a34430926d4e2ePaul Stewart  IPAddress ipv6_address7(IPAddress::kFamilyIPv6);
1313241e3f317fe3089dd7dcb4e7c5a34430926d4e2ePaul Stewart  EXPECT_TRUE(ipv6_address7.SetAddressFromString(kTestIPAddress7));
1314241e3f317fe3089dd7dcb4e7c5a34430926d4e2ePaul Stewart  message.reset(BuildAddressMessage(
1315241e3f317fe3089dd7dcb4e7c5a34430926d4e2ePaul Stewart      RTNLMessage::kModeAdd, ipv6_address7, IFA_F_TEMPORARY,
1316241e3f317fe3089dd7dcb4e7c5a34430926d4e2ePaul Stewart      RT_SCOPE_UNIVERSE));
1317241e3f317fe3089dd7dcb4e7c5a34430926d4e2ePaul Stewart
1318241e3f317fe3089dd7dcb4e7c5a34430926d4e2ePaul Stewart  // Another temporary (non-deprecated) address alerts the Device, and will
1319241e3f317fe3089dd7dcb4e7c5a34430926d4e2ePaul Stewart  // override the previous primary address.
1320241e3f317fe3089dd7dcb4e7c5a34430926d4e2ePaul Stewart  EXPECT_CALL(*device, OnIPv6AddressChanged());
1321241e3f317fe3089dd7dcb4e7c5a34430926d4e2ePaul Stewart  SendMessageToDeviceInfo(*message);
1322241e3f317fe3089dd7dcb4e7c5a34430926d4e2ePaul Stewart  IPAddress address3(IPAddress::kFamilyUnknown);
1323241e3f317fe3089dd7dcb4e7c5a34430926d4e2ePaul Stewart  EXPECT_TRUE(device_info_.GetPrimaryIPv6Address(kTestDeviceIndex, &address3));
1324241e3f317fe3089dd7dcb4e7c5a34430926d4e2ePaul Stewart  EXPECT_TRUE(address3.Equals(ipv6_address7));
1325d55f6ae45047f984457508d78c70abcd837307eaPaul Stewart}
1326d55f6ae45047f984457508d78c70abcd837307eaPaul Stewart
13279855170e6e2de08db343640c82795c9b4020a166Peter Qiu
13289855170e6e2de08db343640c82795c9b4020a166Peter QiuTEST_F(DeviceInfoTest, IPv6DnsServerAddressesChanged) {
13299855170e6e2de08db343640c82795c9b4020a166Peter Qiu  scoped_refptr<MockDevice> device(new MockDevice(
13309855170e6e2de08db343640c82795c9b4020a166Peter Qiu      &control_interface_, &dispatcher_, &metrics_, &manager_,
13319855170e6e2de08db343640c82795c9b4020a166Peter Qiu      "null0", "addr0", kTestDeviceIndex));
13329855170e6e2de08db343640c82795c9b4020a166Peter Qiu  device_info_.time_ = &time_;
13339855170e6e2de08db343640c82795c9b4020a166Peter Qiu  vector<IPAddress> dns_server_addresses_out;
13347fab89734d88724a288e96a9996b15548c5294c7Ben Chan  uint32_t lifetime_out;
13359855170e6e2de08db343640c82795c9b4020a166Peter Qiu
13369855170e6e2de08db343640c82795c9b4020a166Peter Qiu  // Device info entry does not exist.
13379855170e6e2de08db343640c82795c9b4020a166Peter Qiu  EXPECT_FALSE(device_info_.GetIPv6DnsServerAddresses(
13389855170e6e2de08db343640c82795c9b4020a166Peter Qiu      kTestDeviceIndex, &dns_server_addresses_out, &lifetime_out));
13399855170e6e2de08db343640c82795c9b4020a166Peter Qiu
13409855170e6e2de08db343640c82795c9b4020a166Peter Qiu  device_info_.infos_[kTestDeviceIndex].device = device;
13419855170e6e2de08db343640c82795c9b4020a166Peter Qiu
13429855170e6e2de08db343640c82795c9b4020a166Peter Qiu  // Device info entry contains no IPv6 dns server addresses.
13439855170e6e2de08db343640c82795c9b4020a166Peter Qiu  EXPECT_FALSE(device_info_.GetIPv6DnsServerAddresses(
13449855170e6e2de08db343640c82795c9b4020a166Peter Qiu      kTestDeviceIndex, &dns_server_addresses_out, &lifetime_out));
13459855170e6e2de08db343640c82795c9b4020a166Peter Qiu
13469855170e6e2de08db343640c82795c9b4020a166Peter Qiu  // Setup IPv6 dns server addresses.
13479855170e6e2de08db343640c82795c9b4020a166Peter Qiu  IPAddress ipv6_address1(IPAddress::kFamilyIPv6);
13489855170e6e2de08db343640c82795c9b4020a166Peter Qiu  IPAddress ipv6_address2(IPAddress::kFamilyIPv6);
13499855170e6e2de08db343640c82795c9b4020a166Peter Qiu  EXPECT_TRUE(ipv6_address1.SetAddressFromString(kTestIPAddress1));
13509855170e6e2de08db343640c82795c9b4020a166Peter Qiu  EXPECT_TRUE(ipv6_address2.SetAddressFromString(kTestIPAddress2));
13519855170e6e2de08db343640c82795c9b4020a166Peter Qiu  vector<IPAddress> dns_server_addresses_in;
13529855170e6e2de08db343640c82795c9b4020a166Peter Qiu  dns_server_addresses_in.push_back(ipv6_address1);
13539855170e6e2de08db343640c82795c9b4020a166Peter Qiu  dns_server_addresses_in.push_back(ipv6_address2);
13549855170e6e2de08db343640c82795c9b4020a166Peter Qiu
13559855170e6e2de08db343640c82795c9b4020a166Peter Qiu  // Infinite lifetime
13567fab89734d88724a288e96a9996b15548c5294c7Ben Chan  const uint32_t kInfiniteLifetime = 0xffffffff;
1357cd47732488cd101eaf0d3558dde5a7d4e4fc260bBen Chan  unique_ptr<RTNLMessage> message(BuildRdnssMessage(
1358cd47732488cd101eaf0d3558dde5a7d4e4fc260bBen Chan      RTNLMessage::kModeAdd, kInfiniteLifetime, dns_server_addresses_in));
13599855170e6e2de08db343640c82795c9b4020a166Peter Qiu  EXPECT_CALL(time_, GetSecondsBoottime(_)).
13609855170e6e2de08db343640c82795c9b4020a166Peter Qiu      WillOnce(DoAll(SetArgPointee<0>(0), Return(true)));
13619855170e6e2de08db343640c82795c9b4020a166Peter Qiu  EXPECT_CALL(*device, OnIPv6DnsServerAddressesChanged()).Times(1);
13629855170e6e2de08db343640c82795c9b4020a166Peter Qiu  SendMessageToDeviceInfo(*message);
13639855170e6e2de08db343640c82795c9b4020a166Peter Qiu  EXPECT_CALL(time_, GetSecondsBoottime(_)).Times(0);
13649855170e6e2de08db343640c82795c9b4020a166Peter Qiu  EXPECT_TRUE(device_info_.GetIPv6DnsServerAddresses(
13659855170e6e2de08db343640c82795c9b4020a166Peter Qiu      kTestDeviceIndex, &dns_server_addresses_out, &lifetime_out));
13669855170e6e2de08db343640c82795c9b4020a166Peter Qiu  // Verify addresses and lifetime.
13679855170e6e2de08db343640c82795c9b4020a166Peter Qiu  EXPECT_EQ(kInfiniteLifetime, lifetime_out);
13689855170e6e2de08db343640c82795c9b4020a166Peter Qiu  EXPECT_EQ(2, dns_server_addresses_out.size());
13699855170e6e2de08db343640c82795c9b4020a166Peter Qiu  EXPECT_EQ(kTestIPAddress1, dns_server_addresses_out.at(0).ToString());
13709855170e6e2de08db343640c82795c9b4020a166Peter Qiu  EXPECT_EQ(kTestIPAddress2, dns_server_addresses_out.at(1).ToString());
13719855170e6e2de08db343640c82795c9b4020a166Peter Qiu
13729855170e6e2de08db343640c82795c9b4020a166Peter Qiu  // Lifetime of 120, retrieve DNS server addresses after 10 seconds.
13737fab89734d88724a288e96a9996b15548c5294c7Ben Chan  const uint32_t kLifetime120 = 120;
13747fab89734d88724a288e96a9996b15548c5294c7Ben Chan  const uint32_t kElapseTime10 = 10;
1375cd47732488cd101eaf0d3558dde5a7d4e4fc260bBen Chan  unique_ptr<RTNLMessage> message1(BuildRdnssMessage(
1376cd47732488cd101eaf0d3558dde5a7d4e4fc260bBen Chan      RTNLMessage::kModeAdd, kLifetime120, dns_server_addresses_in));
13779855170e6e2de08db343640c82795c9b4020a166Peter Qiu  EXPECT_CALL(time_, GetSecondsBoottime(_)).
13789855170e6e2de08db343640c82795c9b4020a166Peter Qiu      WillOnce(DoAll(SetArgPointee<0>(0), Return(true)));
13799855170e6e2de08db343640c82795c9b4020a166Peter Qiu  EXPECT_CALL(*device, OnIPv6DnsServerAddressesChanged()).Times(1);
13809855170e6e2de08db343640c82795c9b4020a166Peter Qiu  SendMessageToDeviceInfo(*message1);
13819855170e6e2de08db343640c82795c9b4020a166Peter Qiu  // 10 seconds passed when GetIPv6DnsServerAddreses is called.
13829855170e6e2de08db343640c82795c9b4020a166Peter Qiu  EXPECT_CALL(time_, GetSecondsBoottime(_)).
13839855170e6e2de08db343640c82795c9b4020a166Peter Qiu      WillOnce(DoAll(SetArgPointee<0>(kElapseTime10), Return(true)));
13849855170e6e2de08db343640c82795c9b4020a166Peter Qiu  EXPECT_TRUE(device_info_.GetIPv6DnsServerAddresses(
13859855170e6e2de08db343640c82795c9b4020a166Peter Qiu      kTestDeviceIndex, &dns_server_addresses_out, &lifetime_out));
13869855170e6e2de08db343640c82795c9b4020a166Peter Qiu  // Verify addresses and lifetime.
13879855170e6e2de08db343640c82795c9b4020a166Peter Qiu  EXPECT_EQ(kLifetime120 - kElapseTime10, lifetime_out);
13889855170e6e2de08db343640c82795c9b4020a166Peter Qiu  EXPECT_EQ(2, dns_server_addresses_out.size());
13899855170e6e2de08db343640c82795c9b4020a166Peter Qiu  EXPECT_EQ(kTestIPAddress1, dns_server_addresses_out.at(0).ToString());
13909855170e6e2de08db343640c82795c9b4020a166Peter Qiu  EXPECT_EQ(kTestIPAddress2, dns_server_addresses_out.at(1).ToString());
13919855170e6e2de08db343640c82795c9b4020a166Peter Qiu
13929855170e6e2de08db343640c82795c9b4020a166Peter Qiu  // Lifetime of 120, retrieve DNS server addresses after lifetime expired.
13939855170e6e2de08db343640c82795c9b4020a166Peter Qiu  EXPECT_CALL(time_, GetSecondsBoottime(_)).
13949855170e6e2de08db343640c82795c9b4020a166Peter Qiu      WillOnce(DoAll(SetArgPointee<0>(0), Return(true)));
13959855170e6e2de08db343640c82795c9b4020a166Peter Qiu  EXPECT_CALL(*device, OnIPv6DnsServerAddressesChanged()).Times(1);
13969855170e6e2de08db343640c82795c9b4020a166Peter Qiu  SendMessageToDeviceInfo(*message1);
13979855170e6e2de08db343640c82795c9b4020a166Peter Qiu  // 120 seconds passed when GetIPv6DnsServerAddreses is called.
13989855170e6e2de08db343640c82795c9b4020a166Peter Qiu  EXPECT_CALL(time_, GetSecondsBoottime(_)).
13999855170e6e2de08db343640c82795c9b4020a166Peter Qiu      WillOnce(DoAll(SetArgPointee<0>(kLifetime120), Return(true)));
14009855170e6e2de08db343640c82795c9b4020a166Peter Qiu  EXPECT_TRUE(device_info_.GetIPv6DnsServerAddresses(
14019855170e6e2de08db343640c82795c9b4020a166Peter Qiu      kTestDeviceIndex, &dns_server_addresses_out, &lifetime_out));
14029855170e6e2de08db343640c82795c9b4020a166Peter Qiu  // Verify addresses and lifetime.
14039855170e6e2de08db343640c82795c9b4020a166Peter Qiu  EXPECT_EQ(0, lifetime_out);
14049855170e6e2de08db343640c82795c9b4020a166Peter Qiu  EXPECT_EQ(2, dns_server_addresses_out.size());
14059855170e6e2de08db343640c82795c9b4020a166Peter Qiu  EXPECT_EQ(kTestIPAddress1, dns_server_addresses_out.at(0).ToString());
14069855170e6e2de08db343640c82795c9b4020a166Peter Qiu  EXPECT_EQ(kTestIPAddress2, dns_server_addresses_out.at(1).ToString());
14079855170e6e2de08db343640c82795c9b4020a166Peter Qiu}
14089855170e6e2de08db343640c82795c9b4020a166Peter Qiu
1409ca876ee6b11b38a3df7a8ab03efe9ed0bcab41d8Paul Stewartclass DeviceInfoTechnologyTest : public DeviceInfoTest {
1410ca876ee6b11b38a3df7a8ab03efe9ed0bcab41d8Paul Stewart public:
1411abc5403270e26fa898181301911a905758f8d758Jason Glasgow  DeviceInfoTechnologyTest()
1412abc5403270e26fa898181301911a905758f8d758Jason Glasgow      : DeviceInfoTest(),
1413abc5403270e26fa898181301911a905758f8d758Jason Glasgow        test_device_name_(kTestDeviceName) {}
1414ca876ee6b11b38a3df7a8ab03efe9ed0bcab41d8Paul Stewart  virtual ~DeviceInfoTechnologyTest() {}
1415ca876ee6b11b38a3df7a8ab03efe9ed0bcab41d8Paul Stewart
1416ca876ee6b11b38a3df7a8ab03efe9ed0bcab41d8Paul Stewart  virtual void SetUp() {
141762ba51cf8fed1be8f51092ecce6a9588a842cd29mukesh agrawal    CHECK(temp_dir_.CreateUniqueTempDir());
1418ca876ee6b11b38a3df7a8ab03efe9ed0bcab41d8Paul Stewart    device_info_root_ = temp_dir_.path().Append("sys/class/net");
1419ca876ee6b11b38a3df7a8ab03efe9ed0bcab41d8Paul Stewart    device_info_.device_info_root_ = device_info_root_;
1420ca876ee6b11b38a3df7a8ab03efe9ed0bcab41d8Paul Stewart    // Most tests require that the uevent file exist.
1421ca876ee6b11b38a3df7a8ab03efe9ed0bcab41d8Paul Stewart    CreateInfoFile("uevent", "xxx");
1422ca876ee6b11b38a3df7a8ab03efe9ed0bcab41d8Paul Stewart  }
1423ca876ee6b11b38a3df7a8ab03efe9ed0bcab41d8Paul Stewart
1424ca876ee6b11b38a3df7a8ab03efe9ed0bcab41d8Paul Stewart  Technology::Identifier GetDeviceTechnology() {
1425abc5403270e26fa898181301911a905758f8d758Jason Glasgow    return device_info_.GetDeviceTechnology(test_device_name_);
1426ca876ee6b11b38a3df7a8ab03efe9ed0bcab41d8Paul Stewart  }
14273b30ca58d13cf66b75ba0729b222ddc42ae68b33Paul Stewart  FilePath GetInfoPath(const string& name);
14283b30ca58d13cf66b75ba0729b222ddc42ae68b33Paul Stewart  void CreateInfoFile(const string& name, const string& contents);
14293b30ca58d13cf66b75ba0729b222ddc42ae68b33Paul Stewart  void CreateInfoSymLink(const string& name, const string& contents);
14303b30ca58d13cf66b75ba0729b222ddc42ae68b33Paul Stewart  void SetDeviceName(const string& name) {
1431abc5403270e26fa898181301911a905758f8d758Jason Glasgow    test_device_name_ = name;
143262ba51cf8fed1be8f51092ecce6a9588a842cd29mukesh agrawal    EXPECT_TRUE(temp_dir_.Delete());  // nuke old temp dir
1433abc5403270e26fa898181301911a905758f8d758Jason Glasgow    SetUp();
1434abc5403270e26fa898181301911a905758f8d758Jason Glasgow  }
1435ca876ee6b11b38a3df7a8ab03efe9ed0bcab41d8Paul Stewart
1436ca876ee6b11b38a3df7a8ab03efe9ed0bcab41d8Paul Stewart protected:
14375ad1606ad8b3f74b2b7960a3003a2d1ca75d52b8Paul Stewart  base::ScopedTempDir temp_dir_;
1438ca876ee6b11b38a3df7a8ab03efe9ed0bcab41d8Paul Stewart  FilePath device_info_root_;
1439abc5403270e26fa898181301911a905758f8d758Jason Glasgow  string test_device_name_;
1440ca876ee6b11b38a3df7a8ab03efe9ed0bcab41d8Paul Stewart};
1441ca876ee6b11b38a3df7a8ab03efe9ed0bcab41d8Paul Stewart
14423b30ca58d13cf66b75ba0729b222ddc42ae68b33Paul StewartFilePath DeviceInfoTechnologyTest::GetInfoPath(const string& name) {
1443abc5403270e26fa898181301911a905758f8d758Jason Glasgow  return device_info_root_.Append(test_device_name_).Append(name);
1444ca876ee6b11b38a3df7a8ab03efe9ed0bcab41d8Paul Stewart}
1445ca876ee6b11b38a3df7a8ab03efe9ed0bcab41d8Paul Stewart
14463b30ca58d13cf66b75ba0729b222ddc42ae68b33Paul Stewartvoid DeviceInfoTechnologyTest::CreateInfoFile(const string& name,
14473b30ca58d13cf66b75ba0729b222ddc42ae68b33Paul Stewart                                              const string& contents) {
1448ca876ee6b11b38a3df7a8ab03efe9ed0bcab41d8Paul Stewart  FilePath info_path = GetInfoPath(name);
1449a0ddf46e466bd4ba3d20952f0a6988c680c1af14Ben Chan  EXPECT_TRUE(base::CreateDirectory(info_path.DirName()));
1450ca876ee6b11b38a3df7a8ab03efe9ed0bcab41d8Paul Stewart  string contents_newline(contents + "\n");
14516fbf64f493a9aae7d743888039c61a57386203dbBen Chan  EXPECT_TRUE(base::WriteFile(info_path, contents_newline.c_str(),
14526fbf64f493a9aae7d743888039c61a57386203dbBen Chan                              contents_newline.size()));
1453ca876ee6b11b38a3df7a8ab03efe9ed0bcab41d8Paul Stewart}
1454ca876ee6b11b38a3df7a8ab03efe9ed0bcab41d8Paul Stewart
14553b30ca58d13cf66b75ba0729b222ddc42ae68b33Paul Stewartvoid DeviceInfoTechnologyTest::CreateInfoSymLink(const string& name,
14563b30ca58d13cf66b75ba0729b222ddc42ae68b33Paul Stewart                                                 const string& contents) {
1457ca876ee6b11b38a3df7a8ab03efe9ed0bcab41d8Paul Stewart  FilePath info_path = GetInfoPath(name);
1458a0ddf46e466bd4ba3d20952f0a6988c680c1af14Ben Chan  EXPECT_TRUE(base::CreateDirectory(info_path.DirName()));
1459a0ddf46e466bd4ba3d20952f0a6988c680c1af14Ben Chan  EXPECT_TRUE(base::CreateSymbolicLink(FilePath(contents), info_path));
1460ca876ee6b11b38a3df7a8ab03efe9ed0bcab41d8Paul Stewart}
1461ca876ee6b11b38a3df7a8ab03efe9ed0bcab41d8Paul Stewart
1462ca876ee6b11b38a3df7a8ab03efe9ed0bcab41d8Paul StewartTEST_F(DeviceInfoTechnologyTest, Unknown) {
1463a551451a88ec3a4746021c84c646dcf8206b2531Paul Stewart  // With a uevent file but no driver symlink, we should get a pseudo-technology
1464a551451a88ec3a4746021c84c646dcf8206b2531Paul Stewart  // which specifies this condition explicitly.
1465a551451a88ec3a4746021c84c646dcf8206b2531Paul Stewart  EXPECT_EQ(Technology::kNoDeviceSymlink, GetDeviceTechnology());
1466da8cbeef4735df05dd3a9a069c6ecccf37803e60Paul Stewart
1467da8cbeef4735df05dd3a9a069c6ecccf37803e60Paul Stewart  // Should be unknown without a uevent file.
1468a0ddf46e466bd4ba3d20952f0a6988c680c1af14Ben Chan  EXPECT_TRUE(base::DeleteFile(GetInfoPath("uevent"), false));
1469ca876ee6b11b38a3df7a8ab03efe9ed0bcab41d8Paul Stewart  EXPECT_EQ(Technology::kUnknown, GetDeviceTechnology());
1470ca876ee6b11b38a3df7a8ab03efe9ed0bcab41d8Paul Stewart}
1471ca876ee6b11b38a3df7a8ab03efe9ed0bcab41d8Paul Stewart
147283d625655edbc7c35fc436b8b8fe744886d0aae1Paul StewartTEST_F(DeviceInfoTechnologyTest, IgnoredPrefix) {
147383d625655edbc7c35fc436b8b8fe744886d0aae1Paul Stewart  test_device_name_ = "veth0";
147483d625655edbc7c35fc436b8b8fe744886d0aae1Paul Stewart  // A new uevent file is needed since the device name has changed.
147583d625655edbc7c35fc436b8b8fe744886d0aae1Paul Stewart  CreateInfoFile("uevent", "xxx");
147683d625655edbc7c35fc436b8b8fe744886d0aae1Paul Stewart  // A device with a "veth" prefix should be ignored.
147783d625655edbc7c35fc436b8b8fe744886d0aae1Paul Stewart  EXPECT_EQ(Technology::kUnknown, GetDeviceTechnology());
147883d625655edbc7c35fc436b8b8fe744886d0aae1Paul Stewart}
147983d625655edbc7c35fc436b8b8fe744886d0aae1Paul Stewart
1480ca876ee6b11b38a3df7a8ab03efe9ed0bcab41d8Paul StewartTEST_F(DeviceInfoTechnologyTest, Loopback) {
1481ca876ee6b11b38a3df7a8ab03efe9ed0bcab41d8Paul Stewart  CreateInfoFile("type", base::IntToString(ARPHRD_LOOPBACK));
1482ca876ee6b11b38a3df7a8ab03efe9ed0bcab41d8Paul Stewart  EXPECT_EQ(Technology::kLoopback, GetDeviceTechnology());
1483ca876ee6b11b38a3df7a8ab03efe9ed0bcab41d8Paul Stewart}
1484ca876ee6b11b38a3df7a8ab03efe9ed0bcab41d8Paul Stewart
1485ca876ee6b11b38a3df7a8ab03efe9ed0bcab41d8Paul StewartTEST_F(DeviceInfoTechnologyTest, PPP) {
1486ca876ee6b11b38a3df7a8ab03efe9ed0bcab41d8Paul Stewart  CreateInfoFile("type", base::IntToString(ARPHRD_PPP));
1487ca876ee6b11b38a3df7a8ab03efe9ed0bcab41d8Paul Stewart  EXPECT_EQ(Technology::kPPP, GetDeviceTechnology());
1488ca876ee6b11b38a3df7a8ab03efe9ed0bcab41d8Paul Stewart}
1489ca876ee6b11b38a3df7a8ab03efe9ed0bcab41d8Paul Stewart
1490ca876ee6b11b38a3df7a8ab03efe9ed0bcab41d8Paul StewartTEST_F(DeviceInfoTechnologyTest, Tunnel) {
1491ca876ee6b11b38a3df7a8ab03efe9ed0bcab41d8Paul Stewart  CreateInfoFile("tun_flags", base::IntToString(IFF_TUN));
1492ca876ee6b11b38a3df7a8ab03efe9ed0bcab41d8Paul Stewart  EXPECT_EQ(Technology::kTunnel, GetDeviceTechnology());
1493ca876ee6b11b38a3df7a8ab03efe9ed0bcab41d8Paul Stewart}
1494ca876ee6b11b38a3df7a8ab03efe9ed0bcab41d8Paul Stewart
1495ca876ee6b11b38a3df7a8ab03efe9ed0bcab41d8Paul StewartTEST_F(DeviceInfoTechnologyTest, WiFi) {
1496ca876ee6b11b38a3df7a8ab03efe9ed0bcab41d8Paul Stewart  CreateInfoFile("uevent", "DEVTYPE=wlan");
1497ca876ee6b11b38a3df7a8ab03efe9ed0bcab41d8Paul Stewart  EXPECT_EQ(Technology::kWifi, GetDeviceTechnology());
1498ca876ee6b11b38a3df7a8ab03efe9ed0bcab41d8Paul Stewart  CreateInfoFile("uevent", "foo\nDEVTYPE=wlan");
1499ca876ee6b11b38a3df7a8ab03efe9ed0bcab41d8Paul Stewart  EXPECT_EQ(Technology::kWifi, GetDeviceTechnology());
1500ca876ee6b11b38a3df7a8ab03efe9ed0bcab41d8Paul Stewart  CreateInfoFile("type", base::IntToString(ARPHRD_IEEE80211_RADIOTAP));
1501ca876ee6b11b38a3df7a8ab03efe9ed0bcab41d8Paul Stewart  EXPECT_EQ(Technology::kWiFiMonitor, GetDeviceTechnology());
1502ca876ee6b11b38a3df7a8ab03efe9ed0bcab41d8Paul Stewart}
1503ca876ee6b11b38a3df7a8ab03efe9ed0bcab41d8Paul Stewart
1504ca876ee6b11b38a3df7a8ab03efe9ed0bcab41d8Paul StewartTEST_F(DeviceInfoTechnologyTest, Ethernet) {
1505ca876ee6b11b38a3df7a8ab03efe9ed0bcab41d8Paul Stewart  CreateInfoSymLink("device/driver", "xxx");
1506ca876ee6b11b38a3df7a8ab03efe9ed0bcab41d8Paul Stewart  EXPECT_EQ(Technology::kEthernet, GetDeviceTechnology());
1507ca876ee6b11b38a3df7a8ab03efe9ed0bcab41d8Paul Stewart}
1508ca876ee6b11b38a3df7a8ab03efe9ed0bcab41d8Paul Stewart
1509e4b270274cba2a1976c7be6c733bd899e009c1d1Darin PetkovTEST_F(DeviceInfoTechnologyTest, WiMax) {
1510e4b270274cba2a1976c7be6c733bd899e009c1d1Darin Petkov  CreateInfoSymLink("device/driver", "gdm_wimax");
1511e4b270274cba2a1976c7be6c733bd899e009c1d1Darin Petkov  EXPECT_EQ(Technology::kWiMax, GetDeviceTechnology());
1512e4b270274cba2a1976c7be6c733bd899e009c1d1Darin Petkov}
1513e4b270274cba2a1976c7be6c733bd899e009c1d1Darin Petkov
1514ca876ee6b11b38a3df7a8ab03efe9ed0bcab41d8Paul StewartTEST_F(DeviceInfoTechnologyTest, CellularGobi1) {
1515ca876ee6b11b38a3df7a8ab03efe9ed0bcab41d8Paul Stewart  CreateInfoSymLink("device/driver", "blah/foo/gobi");
1516ca876ee6b11b38a3df7a8ab03efe9ed0bcab41d8Paul Stewart  EXPECT_EQ(Technology::kCellular, GetDeviceTechnology());
1517ca876ee6b11b38a3df7a8ab03efe9ed0bcab41d8Paul Stewart}
1518ca876ee6b11b38a3df7a8ab03efe9ed0bcab41d8Paul Stewart
1519ca876ee6b11b38a3df7a8ab03efe9ed0bcab41d8Paul StewartTEST_F(DeviceInfoTechnologyTest, CellularGobi2) {
1520ca876ee6b11b38a3df7a8ab03efe9ed0bcab41d8Paul Stewart  CreateInfoSymLink("device/driver", "../GobiNet");
1521ca876ee6b11b38a3df7a8ab03efe9ed0bcab41d8Paul Stewart  EXPECT_EQ(Technology::kCellular, GetDeviceTechnology());
1522ca876ee6b11b38a3df7a8ab03efe9ed0bcab41d8Paul Stewart}
1523ca876ee6b11b38a3df7a8ab03efe9ed0bcab41d8Paul Stewart
1524ca876ee6b11b38a3df7a8ab03efe9ed0bcab41d8Paul StewartTEST_F(DeviceInfoTechnologyTest, QCUSB) {
1525ca876ee6b11b38a3df7a8ab03efe9ed0bcab41d8Paul Stewart  CreateInfoSymLink("device/driver", "QCUSBNet2k");
1526ca876ee6b11b38a3df7a8ab03efe9ed0bcab41d8Paul Stewart  EXPECT_EQ(Technology::kCellular, GetDeviceTechnology());
1527ca876ee6b11b38a3df7a8ab03efe9ed0bcab41d8Paul Stewart}
1528ca876ee6b11b38a3df7a8ab03efe9ed0bcab41d8Paul Stewart
15290f90e0b62322ae95c1a419d5efef47438b4617c9Ben ChanTEST_F(DeviceInfoTechnologyTest, CellularCdcMbim) {
15300f90e0b62322ae95c1a419d5efef47438b4617c9Ben Chan  CreateInfoSymLink("device/driver", "cdc_mbim");
15310f90e0b62322ae95c1a419d5efef47438b4617c9Ben Chan  EXPECT_EQ(Technology::kCellular, GetDeviceTechnology());
15320f90e0b62322ae95c1a419d5efef47438b4617c9Ben Chan}
15330f90e0b62322ae95c1a419d5efef47438b4617c9Ben Chan
1534226d46a2e03d316e8a36f93cb261f708219aef07Ben ChanTEST_F(DeviceInfoTechnologyTest, CellularQmiWwan) {
1535226d46a2e03d316e8a36f93cb261f708219aef07Ben Chan  CreateInfoSymLink("device/driver", "qmi_wwan");
1536226d46a2e03d316e8a36f93cb261f708219aef07Ben Chan  EXPECT_EQ(Technology::kCellular, GetDeviceTechnology());
1537226d46a2e03d316e8a36f93cb261f708219aef07Ben Chan}
1538226d46a2e03d316e8a36f93cb261f708219aef07Ben Chan
1539ca876ee6b11b38a3df7a8ab03efe9ed0bcab41d8Paul Stewart// Modem with absolute driver path with top-level tty file:
1540ca876ee6b11b38a3df7a8ab03efe9ed0bcab41d8Paul Stewart//   /sys/class/net/dev0/device -> /sys/devices/virtual/0/00
15414eb4ddf7f26286e6b4d112f014718336559dfb7aBen Chan//   /sys/devices/virtual/0/00/driver -> /drivers/cdc_ether or /drivers/cdc_ncm
1542ca876ee6b11b38a3df7a8ab03efe9ed0bcab41d8Paul Stewart//   /sys/devices/virtual/0/01/tty [empty directory]
15434eb4ddf7f26286e6b4d112f014718336559dfb7aBen ChanTEST_F(DeviceInfoTechnologyTest, CDCEthernetModem1) {
1544ca876ee6b11b38a3df7a8ab03efe9ed0bcab41d8Paul Stewart  FilePath device_root(temp_dir_.path().Append("sys/devices/virtual/0"));
1545ca876ee6b11b38a3df7a8ab03efe9ed0bcab41d8Paul Stewart  FilePath device_path(device_root.Append("00"));
15464eb4ddf7f26286e6b4d112f014718336559dfb7aBen Chan  FilePath driver_symlink(device_path.Append("driver"));
1547a0ddf46e466bd4ba3d20952f0a6988c680c1af14Ben Chan  EXPECT_TRUE(base::CreateDirectory(device_path));
1548ca876ee6b11b38a3df7a8ab03efe9ed0bcab41d8Paul Stewart  CreateInfoSymLink("device", device_path.value());
1549a0ddf46e466bd4ba3d20952f0a6988c680c1af14Ben Chan  EXPECT_TRUE(base::CreateSymbolicLink(FilePath("/drivers/cdc_ether"),
1550a0ddf46e466bd4ba3d20952f0a6988c680c1af14Ben Chan                                       driver_symlink));
1551a0ddf46e466bd4ba3d20952f0a6988c680c1af14Ben Chan  EXPECT_TRUE(base::CreateDirectory(device_root.Append("01/tty")));
1552ca876ee6b11b38a3df7a8ab03efe9ed0bcab41d8Paul Stewart  EXPECT_EQ(Technology::kCellular, GetDeviceTechnology());
15534eb4ddf7f26286e6b4d112f014718336559dfb7aBen Chan
1554a0ddf46e466bd4ba3d20952f0a6988c680c1af14Ben Chan  EXPECT_TRUE(base::DeleteFile(driver_symlink, false));
1555a0ddf46e466bd4ba3d20952f0a6988c680c1af14Ben Chan  EXPECT_TRUE(base::CreateSymbolicLink(FilePath("/drivers/cdc_ncm"),
1556a0ddf46e466bd4ba3d20952f0a6988c680c1af14Ben Chan                                       driver_symlink));
15574eb4ddf7f26286e6b4d112f014718336559dfb7aBen Chan  EXPECT_EQ(Technology::kCellular, GetDeviceTechnology());
1558ca876ee6b11b38a3df7a8ab03efe9ed0bcab41d8Paul Stewart}
1559ca876ee6b11b38a3df7a8ab03efe9ed0bcab41d8Paul Stewart
1560ca876ee6b11b38a3df7a8ab03efe9ed0bcab41d8Paul Stewart// Modem with relative driver path with top-level tty file.
1561ca876ee6b11b38a3df7a8ab03efe9ed0bcab41d8Paul Stewart//   /sys/class/net/dev0/device -> ../../../device_dir/0/00
15624eb4ddf7f26286e6b4d112f014718336559dfb7aBen Chan//   /sys/device_dir/0/00/driver -> /drivers/cdc_ether or /drivers/cdc_ncm
1563ca876ee6b11b38a3df7a8ab03efe9ed0bcab41d8Paul Stewart//   /sys/device_dir/0/01/tty [empty directory]
15644eb4ddf7f26286e6b4d112f014718336559dfb7aBen ChanTEST_F(DeviceInfoTechnologyTest, CDCEthernetModem2) {
1565ca876ee6b11b38a3df7a8ab03efe9ed0bcab41d8Paul Stewart  CreateInfoSymLink("device", "../../../device_dir/0/00");
1566ca876ee6b11b38a3df7a8ab03efe9ed0bcab41d8Paul Stewart  FilePath device_root(temp_dir_.path().Append("sys/device_dir/0"));
1567ca876ee6b11b38a3df7a8ab03efe9ed0bcab41d8Paul Stewart  FilePath device_path(device_root.Append("00"));
15684eb4ddf7f26286e6b4d112f014718336559dfb7aBen Chan  FilePath driver_symlink(device_path.Append("driver"));
1569a0ddf46e466bd4ba3d20952f0a6988c680c1af14Ben Chan  EXPECT_TRUE(base::CreateDirectory(device_path));
1570a0ddf46e466bd4ba3d20952f0a6988c680c1af14Ben Chan  EXPECT_TRUE(base::CreateSymbolicLink(FilePath("/drivers/cdc_ether"),
1571a0ddf46e466bd4ba3d20952f0a6988c680c1af14Ben Chan                                       driver_symlink));
1572a0ddf46e466bd4ba3d20952f0a6988c680c1af14Ben Chan  EXPECT_TRUE(base::CreateDirectory(device_root.Append("01/tty")));
1573ca876ee6b11b38a3df7a8ab03efe9ed0bcab41d8Paul Stewart  EXPECT_EQ(Technology::kCellular, GetDeviceTechnology());
15744eb4ddf7f26286e6b4d112f014718336559dfb7aBen Chan
1575a0ddf46e466bd4ba3d20952f0a6988c680c1af14Ben Chan  EXPECT_TRUE(base::DeleteFile(driver_symlink, false));
1576a0ddf46e466bd4ba3d20952f0a6988c680c1af14Ben Chan  EXPECT_TRUE(base::CreateSymbolicLink(FilePath("/drivers/cdc_ncm"),
1577a0ddf46e466bd4ba3d20952f0a6988c680c1af14Ben Chan                                       driver_symlink));
15784eb4ddf7f26286e6b4d112f014718336559dfb7aBen Chan  EXPECT_EQ(Technology::kCellular, GetDeviceTechnology());
1579ca876ee6b11b38a3df7a8ab03efe9ed0bcab41d8Paul Stewart}
1580ca876ee6b11b38a3df7a8ab03efe9ed0bcab41d8Paul Stewart
1581ca876ee6b11b38a3df7a8ab03efe9ed0bcab41d8Paul Stewart// Modem with relative driver path with lower-level tty file.
1582ca876ee6b11b38a3df7a8ab03efe9ed0bcab41d8Paul Stewart//   /sys/class/net/dev0/device -> ../../../device_dir/0/00
15834eb4ddf7f26286e6b4d112f014718336559dfb7aBen Chan//   /sys/device_dir/0/00/driver -> /drivers/cdc_ether or /drivers/cdc_ncm
1584ca876ee6b11b38a3df7a8ab03efe9ed0bcab41d8Paul Stewart//   /sys/device_dir/0/01/yyy/tty [empty directory]
15854eb4ddf7f26286e6b4d112f014718336559dfb7aBen ChanTEST_F(DeviceInfoTechnologyTest, CDCEthernetModem3) {
1586ca876ee6b11b38a3df7a8ab03efe9ed0bcab41d8Paul Stewart  CreateInfoSymLink("device", "../../../device_dir/0/00");
1587ca876ee6b11b38a3df7a8ab03efe9ed0bcab41d8Paul Stewart  FilePath device_root(temp_dir_.path().Append("sys/device_dir/0"));
1588ca876ee6b11b38a3df7a8ab03efe9ed0bcab41d8Paul Stewart  FilePath device_path(device_root.Append("00"));
15894eb4ddf7f26286e6b4d112f014718336559dfb7aBen Chan  FilePath driver_symlink(device_path.Append("driver"));
1590a0ddf46e466bd4ba3d20952f0a6988c680c1af14Ben Chan  EXPECT_TRUE(base::CreateDirectory(device_path));
1591a0ddf46e466bd4ba3d20952f0a6988c680c1af14Ben Chan  EXPECT_TRUE(base::CreateSymbolicLink(FilePath("/drivers/cdc_ether"),
1592a0ddf46e466bd4ba3d20952f0a6988c680c1af14Ben Chan                                       driver_symlink));
1593a0ddf46e466bd4ba3d20952f0a6988c680c1af14Ben Chan  EXPECT_TRUE(base::CreateDirectory(device_root.Append("01/yyy/tty")));
1594ca876ee6b11b38a3df7a8ab03efe9ed0bcab41d8Paul Stewart  EXPECT_EQ(Technology::kCellular, GetDeviceTechnology());
15954eb4ddf7f26286e6b4d112f014718336559dfb7aBen Chan
1596a0ddf46e466bd4ba3d20952f0a6988c680c1af14Ben Chan  EXPECT_TRUE(base::DeleteFile(driver_symlink, false));
1597a0ddf46e466bd4ba3d20952f0a6988c680c1af14Ben Chan  EXPECT_TRUE(base::CreateSymbolicLink(FilePath("/drivers/cdc_ncm"),
1598a0ddf46e466bd4ba3d20952f0a6988c680c1af14Ben Chan                                       driver_symlink));
15994eb4ddf7f26286e6b4d112f014718336559dfb7aBen Chan  EXPECT_EQ(Technology::kCellular, GetDeviceTechnology());
1600ca876ee6b11b38a3df7a8ab03efe9ed0bcab41d8Paul Stewart}
1601ca876ee6b11b38a3df7a8ab03efe9ed0bcab41d8Paul Stewart
1602ca876ee6b11b38a3df7a8ab03efe9ed0bcab41d8Paul StewartTEST_F(DeviceInfoTechnologyTest, CDCEtherNonModem) {
1603ca876ee6b11b38a3df7a8ab03efe9ed0bcab41d8Paul Stewart  CreateInfoSymLink("device", "device_dir");
1604ca876ee6b11b38a3df7a8ab03efe9ed0bcab41d8Paul Stewart  CreateInfoSymLink("device_dir/driver", "cdc_ether");
1605050cfc068fda2bd77df2ba08f7b2897bf0e0a6e0Paul Stewart  EXPECT_EQ(Technology::kCDCEthernet, GetDeviceTechnology());
1606ca876ee6b11b38a3df7a8ab03efe9ed0bcab41d8Paul Stewart}
1607ca876ee6b11b38a3df7a8ab03efe9ed0bcab41d8Paul Stewart
16084eb4ddf7f26286e6b4d112f014718336559dfb7aBen ChanTEST_F(DeviceInfoTechnologyTest, CDCNcmNonModem) {
16094eb4ddf7f26286e6b4d112f014718336559dfb7aBen Chan  CreateInfoSymLink("device", "device_dir");
16104eb4ddf7f26286e6b4d112f014718336559dfb7aBen Chan  CreateInfoSymLink("device_dir/driver", "cdc_ncm");
16114eb4ddf7f26286e6b4d112f014718336559dfb7aBen Chan  EXPECT_EQ(Technology::kCDCEthernet, GetDeviceTechnology());
16124eb4ddf7f26286e6b4d112f014718336559dfb7aBen Chan}
16134eb4ddf7f26286e6b4d112f014718336559dfb7aBen Chan
1614abc5403270e26fa898181301911a905758f8d758Jason GlasgowTEST_F(DeviceInfoTechnologyTest, PseudoModem) {
1615abc5403270e26fa898181301911a905758f8d758Jason Glasgow  SetDeviceName("pseudomodem");
1616abc5403270e26fa898181301911a905758f8d758Jason Glasgow  CreateInfoSymLink("device", "device_dir");
1617abc5403270e26fa898181301911a905758f8d758Jason Glasgow  CreateInfoSymLink("device_dir/driver", "cdc_ether");
1618abc5403270e26fa898181301911a905758f8d758Jason Glasgow  EXPECT_EQ(Technology::kCellular, GetDeviceTechnology());
1619abc5403270e26fa898181301911a905758f8d758Jason Glasgow
1620abc5403270e26fa898181301911a905758f8d758Jason Glasgow  SetDeviceName("pseudomodem9");
1621abc5403270e26fa898181301911a905758f8d758Jason Glasgow  CreateInfoSymLink("device", "device_dir");
1622abc5403270e26fa898181301911a905758f8d758Jason Glasgow  CreateInfoSymLink("device_dir/driver", "cdc_ether");
1623abc5403270e26fa898181301911a905758f8d758Jason Glasgow  EXPECT_EQ(Technology::kCellular, GetDeviceTechnology());
1624abc5403270e26fa898181301911a905758f8d758Jason Glasgow}
1625abc5403270e26fa898181301911a905758f8d758Jason Glasgow
1626050cfc068fda2bd77df2ba08f7b2897bf0e0a6e0Paul Stewartclass DeviceInfoForDelayedCreationTest : public DeviceInfo {
1627050cfc068fda2bd77df2ba08f7b2897bf0e0a6e0Paul Stewart public:
16283b30ca58d13cf66b75ba0729b222ddc42ae68b33Paul Stewart  DeviceInfoForDelayedCreationTest(ControlInterface* control_interface,
16293b30ca58d13cf66b75ba0729b222ddc42ae68b33Paul Stewart                                   EventDispatcher* dispatcher,
16303b30ca58d13cf66b75ba0729b222ddc42ae68b33Paul Stewart                                   Metrics* metrics,
16313b30ca58d13cf66b75ba0729b222ddc42ae68b33Paul Stewart                                   Manager* manager)
1632050cfc068fda2bd77df2ba08f7b2897bf0e0a6e0Paul Stewart      : DeviceInfo(control_interface, dispatcher, metrics, manager) {}
16333b30ca58d13cf66b75ba0729b222ddc42ae68b33Paul Stewart  MOCK_METHOD4(CreateDevice, DeviceRefPtr(const std::string& link_name,
16343b30ca58d13cf66b75ba0729b222ddc42ae68b33Paul Stewart                                          const std::string& address,
1635050cfc068fda2bd77df2ba08f7b2897bf0e0a6e0Paul Stewart                                          int interface_index,
1636050cfc068fda2bd77df2ba08f7b2897bf0e0a6e0Paul Stewart                                          Technology::Identifier technology));
1637050cfc068fda2bd77df2ba08f7b2897bf0e0a6e0Paul Stewart  MOCK_METHOD1(GetDeviceTechnology,
16383b30ca58d13cf66b75ba0729b222ddc42ae68b33Paul Stewart               Technology::Identifier(const string& iface_name));
1639050cfc068fda2bd77df2ba08f7b2897bf0e0a6e0Paul Stewart};
1640050cfc068fda2bd77df2ba08f7b2897bf0e0a6e0Paul Stewart
1641050cfc068fda2bd77df2ba08f7b2897bf0e0a6e0Paul Stewartclass DeviceInfoDelayedCreationTest : public DeviceInfoTest {
1642050cfc068fda2bd77df2ba08f7b2897bf0e0a6e0Paul Stewart public:
1643050cfc068fda2bd77df2ba08f7b2897bf0e0a6e0Paul Stewart  DeviceInfoDelayedCreationTest()
1644050cfc068fda2bd77df2ba08f7b2897bf0e0a6e0Paul Stewart      : DeviceInfoTest(),
1645050cfc068fda2bd77df2ba08f7b2897bf0e0a6e0Paul Stewart        test_device_info_(
1646050cfc068fda2bd77df2ba08f7b2897bf0e0a6e0Paul Stewart            &control_interface_, &dispatcher_, &metrics_, &manager_) {}
1647050cfc068fda2bd77df2ba08f7b2897bf0e0a6e0Paul Stewart  virtual ~DeviceInfoDelayedCreationTest() {}
1648050cfc068fda2bd77df2ba08f7b2897bf0e0a6e0Paul Stewart
16493b30ca58d13cf66b75ba0729b222ddc42ae68b33Paul Stewart  virtual std::set<int>& GetDelayedDevices() {
1650050cfc068fda2bd77df2ba08f7b2897bf0e0a6e0Paul Stewart    return test_device_info_.delayed_devices_;
1651050cfc068fda2bd77df2ba08f7b2897bf0e0a6e0Paul Stewart  }
1652050cfc068fda2bd77df2ba08f7b2897bf0e0a6e0Paul Stewart
1653050cfc068fda2bd77df2ba08f7b2897bf0e0a6e0Paul Stewart  void DelayedDeviceCreationTask() {
1654050cfc068fda2bd77df2ba08f7b2897bf0e0a6e0Paul Stewart    test_device_info_.DelayedDeviceCreationTask();
1655050cfc068fda2bd77df2ba08f7b2897bf0e0a6e0Paul Stewart  }
1656050cfc068fda2bd77df2ba08f7b2897bf0e0a6e0Paul Stewart
1657a551451a88ec3a4746021c84c646dcf8206b2531Paul Stewart  void AddDelayedDevice(Technology::Identifier delayed_technology) {
1658cd47732488cd101eaf0d3558dde5a7d4e4fc260bBen Chan    unique_ptr<RTNLMessage> message(BuildLinkMessage(RTNLMessage::kModeAdd));
1659050cfc068fda2bd77df2ba08f7b2897bf0e0a6e0Paul Stewart    EXPECT_CALL(test_device_info_, GetDeviceTechnology(kTestDeviceName))
1660a551451a88ec3a4746021c84c646dcf8206b2531Paul Stewart        .WillOnce(Return(delayed_technology));
1661050cfc068fda2bd77df2ba08f7b2897bf0e0a6e0Paul Stewart    EXPECT_CALL(test_device_info_, CreateDevice(
1662a551451a88ec3a4746021c84c646dcf8206b2531Paul Stewart        kTestDeviceName, _, kTestDeviceIndex, delayed_technology))
1663050cfc068fda2bd77df2ba08f7b2897bf0e0a6e0Paul Stewart        .WillOnce(Return(DeviceRefPtr()));
1664050cfc068fda2bd77df2ba08f7b2897bf0e0a6e0Paul Stewart    test_device_info_.AddLinkMsgHandler(*message);
1665050cfc068fda2bd77df2ba08f7b2897bf0e0a6e0Paul Stewart    Mock::VerifyAndClearExpectations(&test_device_info_);
1666050cfc068fda2bd77df2ba08f7b2897bf0e0a6e0Paul Stewart    // We need to insert the device index ourselves since we have mocked
1667050cfc068fda2bd77df2ba08f7b2897bf0e0a6e0Paul Stewart    // out CreateDevice.  This insertion is tested in CreateDeviceCDCEthernet
1668050cfc068fda2bd77df2ba08f7b2897bf0e0a6e0Paul Stewart    // above.
1669050cfc068fda2bd77df2ba08f7b2897bf0e0a6e0Paul Stewart    GetDelayedDevices().insert(kTestDeviceIndex);
1670050cfc068fda2bd77df2ba08f7b2897bf0e0a6e0Paul Stewart  }
1671050cfc068fda2bd77df2ba08f7b2897bf0e0a6e0Paul Stewart
1672a551451a88ec3a4746021c84c646dcf8206b2531Paul Stewart  void EnsureDelayedDevice(Technology::Identifier reported_device_technology,
1673a551451a88ec3a4746021c84c646dcf8206b2531Paul Stewart                           Technology::Identifier created_device_technology) {
1674a551451a88ec3a4746021c84c646dcf8206b2531Paul Stewart    EXPECT_CALL(test_device_info_, GetDeviceTechnology(_))
1675a551451a88ec3a4746021c84c646dcf8206b2531Paul Stewart        .WillOnce(Return(reported_device_technology));
1676a551451a88ec3a4746021c84c646dcf8206b2531Paul Stewart    EXPECT_CALL(test_device_info_, CreateDevice(
1677a551451a88ec3a4746021c84c646dcf8206b2531Paul Stewart        kTestDeviceName, _, kTestDeviceIndex, created_device_technology))
1678a551451a88ec3a4746021c84c646dcf8206b2531Paul Stewart        .WillOnce(Return(DeviceRefPtr()));
1679a551451a88ec3a4746021c84c646dcf8206b2531Paul Stewart    DelayedDeviceCreationTask();
1680a551451a88ec3a4746021c84c646dcf8206b2531Paul Stewart    EXPECT_TRUE(GetDelayedDevices().empty());
1681a551451a88ec3a4746021c84c646dcf8206b2531Paul Stewart  }
1682a551451a88ec3a4746021c84c646dcf8206b2531Paul Stewart
16831a72f5444e077ed21b8e085b17d7f9f1bc44fa5ePeter Qiu#if !defined(DISABLE_WIFI)
16843b30ca58d13cf66b75ba0729b222ddc42ae68b33Paul Stewart  void TriggerOnWiFiInterfaceInfoReceived(const Nl80211Message& message) {
16852ddf2c63751546aa554335a6733314a3859d5c2ePaul Stewart    test_device_info_.OnWiFiInterfaceInfoReceived(message);
16862ddf2c63751546aa554335a6733314a3859d5c2ePaul Stewart  }
16871a72f5444e077ed21b8e085b17d7f9f1bc44fa5ePeter Qiu#endif  // DISABLE_WIFI
16882ddf2c63751546aa554335a6733314a3859d5c2ePaul Stewart
1689050cfc068fda2bd77df2ba08f7b2897bf0e0a6e0Paul Stewart protected:
1690050cfc068fda2bd77df2ba08f7b2897bf0e0a6e0Paul Stewart  DeviceInfoForDelayedCreationTest test_device_info_;
1691050cfc068fda2bd77df2ba08f7b2897bf0e0a6e0Paul Stewart};
1692050cfc068fda2bd77df2ba08f7b2897bf0e0a6e0Paul Stewart
1693050cfc068fda2bd77df2ba08f7b2897bf0e0a6e0Paul StewartTEST_F(DeviceInfoDelayedCreationTest, NoDevices) {
1694050cfc068fda2bd77df2ba08f7b2897bf0e0a6e0Paul Stewart  EXPECT_TRUE(GetDelayedDevices().empty());
1695050cfc068fda2bd77df2ba08f7b2897bf0e0a6e0Paul Stewart  EXPECT_CALL(test_device_info_, GetDeviceTechnology(_)).Times(0);
1696050cfc068fda2bd77df2ba08f7b2897bf0e0a6e0Paul Stewart  DelayedDeviceCreationTask();
1697050cfc068fda2bd77df2ba08f7b2897bf0e0a6e0Paul Stewart}
1698050cfc068fda2bd77df2ba08f7b2897bf0e0a6e0Paul Stewart
1699a551451a88ec3a4746021c84c646dcf8206b2531Paul StewartTEST_F(DeviceInfoDelayedCreationTest, CDCEthernetDevice) {
1700a551451a88ec3a4746021c84c646dcf8206b2531Paul Stewart  AddDelayedDevice(Technology::kCDCEthernet);
1701a551451a88ec3a4746021c84c646dcf8206b2531Paul Stewart  EnsureDelayedDevice(Technology::kCDCEthernet, Technology::kEthernet);
1702050cfc068fda2bd77df2ba08f7b2897bf0e0a6e0Paul Stewart}
1703050cfc068fda2bd77df2ba08f7b2897bf0e0a6e0Paul Stewart
1704050cfc068fda2bd77df2ba08f7b2897bf0e0a6e0Paul StewartTEST_F(DeviceInfoDelayedCreationTest, CellularDevice) {
1705a551451a88ec3a4746021c84c646dcf8206b2531Paul Stewart  AddDelayedDevice(Technology::kCDCEthernet);
1706a551451a88ec3a4746021c84c646dcf8206b2531Paul Stewart  EnsureDelayedDevice(Technology::kCellular, Technology::kCellular);
1707a551451a88ec3a4746021c84c646dcf8206b2531Paul Stewart}
1708a551451a88ec3a4746021c84c646dcf8206b2531Paul Stewart
1709a551451a88ec3a4746021c84c646dcf8206b2531Paul StewartTEST_F(DeviceInfoDelayedCreationTest, TunnelDevice) {
1710a551451a88ec3a4746021c84c646dcf8206b2531Paul Stewart  AddDelayedDevice(Technology::kNoDeviceSymlink);
1711a551451a88ec3a4746021c84c646dcf8206b2531Paul Stewart  EnsureDelayedDevice(Technology::kTunnel, Technology::kTunnel);
1712a551451a88ec3a4746021c84c646dcf8206b2531Paul Stewart}
1713a551451a88ec3a4746021c84c646dcf8206b2531Paul Stewart
1714a551451a88ec3a4746021c84c646dcf8206b2531Paul StewartTEST_F(DeviceInfoDelayedCreationTest, NoDeviceSymlinkEthernet) {
1715a551451a88ec3a4746021c84c646dcf8206b2531Paul Stewart  AddDelayedDevice(Technology::kNoDeviceSymlink);
1716a551451a88ec3a4746021c84c646dcf8206b2531Paul Stewart  EXPECT_CALL(manager_, ignore_unknown_ethernet())
1717a551451a88ec3a4746021c84c646dcf8206b2531Paul Stewart      .WillOnce(Return(false));
1718a551451a88ec3a4746021c84c646dcf8206b2531Paul Stewart  EnsureDelayedDevice(Technology::kNoDeviceSymlink, Technology::kEthernet);
1719a551451a88ec3a4746021c84c646dcf8206b2531Paul Stewart}
1720a551451a88ec3a4746021c84c646dcf8206b2531Paul Stewart
1721a551451a88ec3a4746021c84c646dcf8206b2531Paul StewartTEST_F(DeviceInfoDelayedCreationTest, NoDeviceSymlinkIgnored) {
1722a551451a88ec3a4746021c84c646dcf8206b2531Paul Stewart  AddDelayedDevice(Technology::kNoDeviceSymlink);
1723a551451a88ec3a4746021c84c646dcf8206b2531Paul Stewart  EXPECT_CALL(manager_, ignore_unknown_ethernet())
1724a551451a88ec3a4746021c84c646dcf8206b2531Paul Stewart      .WillOnce(Return(true));
1725a551451a88ec3a4746021c84c646dcf8206b2531Paul Stewart  EnsureDelayedDevice(Technology::kNoDeviceSymlink, Technology::kUnknown);
1726050cfc068fda2bd77df2ba08f7b2897bf0e0a6e0Paul Stewart}
1727050cfc068fda2bd77df2ba08f7b2897bf0e0a6e0Paul Stewart
17281a72f5444e077ed21b8e085b17d7f9f1bc44fa5ePeter Qiu#if !defined(DISABLE_WIFI)
17292ddf2c63751546aa554335a6733314a3859d5c2ePaul StewartTEST_F(DeviceInfoDelayedCreationTest, WiFiDevice) {
17302ddf2c63751546aa554335a6733314a3859d5c2ePaul Stewart  ScopedMockLog log;
17312ddf2c63751546aa554335a6733314a3859d5c2ePaul Stewart  EXPECT_CALL(log, Log(logging::LOG_ERROR, _,
17322ddf2c63751546aa554335a6733314a3859d5c2ePaul Stewart                       HasSubstr("Message is not a new interface response")));
17332ddf2c63751546aa554335a6733314a3859d5c2ePaul Stewart  GetInterfaceMessage non_interface_response_message;
17342ddf2c63751546aa554335a6733314a3859d5c2ePaul Stewart  TriggerOnWiFiInterfaceInfoReceived(non_interface_response_message);
17352ddf2c63751546aa554335a6733314a3859d5c2ePaul Stewart  Mock::VerifyAndClearExpectations(&log);
17362ddf2c63751546aa554335a6733314a3859d5c2ePaul Stewart
17372ddf2c63751546aa554335a6733314a3859d5c2ePaul Stewart  EXPECT_CALL(log, Log(logging::LOG_ERROR, _,
17382ddf2c63751546aa554335a6733314a3859d5c2ePaul Stewart                       HasSubstr("Message contains no interface index")));
17392ddf2c63751546aa554335a6733314a3859d5c2ePaul Stewart  NewInterfaceMessage message;
17402ddf2c63751546aa554335a6733314a3859d5c2ePaul Stewart  TriggerOnWiFiInterfaceInfoReceived(message);
17412ddf2c63751546aa554335a6733314a3859d5c2ePaul Stewart  Mock::VerifyAndClearExpectations(&log);
17422ddf2c63751546aa554335a6733314a3859d5c2ePaul Stewart
1743ba24e6fd0f0f2b974e0e73039d7d92bb475f6857Peter Qiu  message.attributes()->CreateNl80211Attribute(
1744900ab5eff3f23a18feb955210e8acc9fb5cfa292Samuel Tan      NL80211_ATTR_IFINDEX, NetlinkMessage::MessageContext());
17452ddf2c63751546aa554335a6733314a3859d5c2ePaul Stewart  message.attributes()->SetU32AttributeValue(NL80211_ATTR_IFINDEX,
17462ddf2c63751546aa554335a6733314a3859d5c2ePaul Stewart                                             kTestDeviceIndex);
17472ddf2c63751546aa554335a6733314a3859d5c2ePaul Stewart  EXPECT_CALL(log, Log(logging::LOG_ERROR, _,
17482ddf2c63751546aa554335a6733314a3859d5c2ePaul Stewart                       HasSubstr("Message contains no interface type")));
17492ddf2c63751546aa554335a6733314a3859d5c2ePaul Stewart  TriggerOnWiFiInterfaceInfoReceived(message);
17502ddf2c63751546aa554335a6733314a3859d5c2ePaul Stewart  Mock::VerifyAndClearExpectations(&log);
17512ddf2c63751546aa554335a6733314a3859d5c2ePaul Stewart
1752ba24e6fd0f0f2b974e0e73039d7d92bb475f6857Peter Qiu  message.attributes()->CreateNl80211Attribute(
1753900ab5eff3f23a18feb955210e8acc9fb5cfa292Samuel Tan      NL80211_ATTR_IFTYPE, NetlinkMessage::MessageContext());
17542ddf2c63751546aa554335a6733314a3859d5c2ePaul Stewart  message.attributes()->SetU32AttributeValue(NL80211_ATTR_IFTYPE,
17552ddf2c63751546aa554335a6733314a3859d5c2ePaul Stewart                                             NL80211_IFTYPE_AP);
17562ddf2c63751546aa554335a6733314a3859d5c2ePaul Stewart  EXPECT_CALL(log, Log(logging::LOG_ERROR, _,
17572ddf2c63751546aa554335a6733314a3859d5c2ePaul Stewart                       HasSubstr("Could not find device info for interface")));
17582ddf2c63751546aa554335a6733314a3859d5c2ePaul Stewart  TriggerOnWiFiInterfaceInfoReceived(message);
17592ddf2c63751546aa554335a6733314a3859d5c2ePaul Stewart  Mock::VerifyAndClearExpectations(&log);
17602ddf2c63751546aa554335a6733314a3859d5c2ePaul Stewart
17612ddf2c63751546aa554335a6733314a3859d5c2ePaul Stewart  // Use the AddDelayedDevice() method to create a device info entry with no
17622ddf2c63751546aa554335a6733314a3859d5c2ePaul Stewart  // associated device.
1763a551451a88ec3a4746021c84c646dcf8206b2531Paul Stewart  AddDelayedDevice(Technology::kNoDeviceSymlink);
17642ddf2c63751546aa554335a6733314a3859d5c2ePaul Stewart
17652ddf2c63751546aa554335a6733314a3859d5c2ePaul Stewart  EXPECT_CALL(log, Log(logging::LOG_INFO, _,
17662ddf2c63751546aa554335a6733314a3859d5c2ePaul Stewart                       HasSubstr("it is not in station mode")));
17672ddf2c63751546aa554335a6733314a3859d5c2ePaul Stewart  TriggerOnWiFiInterfaceInfoReceived(message);
17682ddf2c63751546aa554335a6733314a3859d5c2ePaul Stewart  Mock::VerifyAndClearExpectations(&log);
17692ddf2c63751546aa554335a6733314a3859d5c2ePaul Stewart  Mock::VerifyAndClearExpectations(&manager_);
17702ddf2c63751546aa554335a6733314a3859d5c2ePaul Stewart
17712ddf2c63751546aa554335a6733314a3859d5c2ePaul Stewart  message.attributes()->SetU32AttributeValue(NL80211_ATTR_IFTYPE,
17722ddf2c63751546aa554335a6733314a3859d5c2ePaul Stewart                                             NL80211_IFTYPE_STATION);
17732ddf2c63751546aa554335a6733314a3859d5c2ePaul Stewart  EXPECT_CALL(manager_, RegisterDevice(_));
17742ddf2c63751546aa554335a6733314a3859d5c2ePaul Stewart  EXPECT_CALL(manager_, device_info())
17752ddf2c63751546aa554335a6733314a3859d5c2ePaul Stewart      .WillRepeatedly(Return(&test_device_info_));
17762ddf2c63751546aa554335a6733314a3859d5c2ePaul Stewart  EXPECT_CALL(log, Log(_, _, _)).Times(AnyNumber());
17772ddf2c63751546aa554335a6733314a3859d5c2ePaul Stewart  EXPECT_CALL(log, Log(logging::LOG_INFO, _,
17782ddf2c63751546aa554335a6733314a3859d5c2ePaul Stewart                       HasSubstr("Creating WiFi device")));
17792ddf2c63751546aa554335a6733314a3859d5c2ePaul Stewart  TriggerOnWiFiInterfaceInfoReceived(message);
17802ddf2c63751546aa554335a6733314a3859d5c2ePaul Stewart  Mock::VerifyAndClearExpectations(&log);
17812ddf2c63751546aa554335a6733314a3859d5c2ePaul Stewart  Mock::VerifyAndClearExpectations(&manager_);
17822ddf2c63751546aa554335a6733314a3859d5c2ePaul Stewart
17832ddf2c63751546aa554335a6733314a3859d5c2ePaul Stewart  EXPECT_CALL(manager_, RegisterDevice(_)).Times(0);
17842ddf2c63751546aa554335a6733314a3859d5c2ePaul Stewart  EXPECT_CALL(log, Log(logging::LOG_ERROR, _,
17852ddf2c63751546aa554335a6733314a3859d5c2ePaul Stewart                       HasSubstr("Device already created for interface")));
17862ddf2c63751546aa554335a6733314a3859d5c2ePaul Stewart  TriggerOnWiFiInterfaceInfoReceived(message);
17872ddf2c63751546aa554335a6733314a3859d5c2ePaul Stewart}
17881a72f5444e077ed21b8e085b17d7f9f1bc44fa5ePeter Qiu#endif  // DISABLE_WIFI
17892ddf2c63751546aa554335a6733314a3859d5c2ePaul Stewart
17909be4a9d1e87d64f850f15061123b2a4334477fa2Chris Masone}  // namespace shill
1791