1326b6cfba5ab73c9e41a7585d1bc95871631122aPeter Qiu// 2326b6cfba5ab73c9e41a7585d1bc95871631122aPeter Qiu// Copyright (C) 2014 The Android Open Source Project 3326b6cfba5ab73c9e41a7585d1bc95871631122aPeter Qiu// 4326b6cfba5ab73c9e41a7585d1bc95871631122aPeter Qiu// Licensed under the Apache License, Version 2.0 (the "License"); 5326b6cfba5ab73c9e41a7585d1bc95871631122aPeter Qiu// you may not use this file except in compliance with the License. 6326b6cfba5ab73c9e41a7585d1bc95871631122aPeter Qiu// You may obtain a copy of the License at 7326b6cfba5ab73c9e41a7585d1bc95871631122aPeter Qiu// 8326b6cfba5ab73c9e41a7585d1bc95871631122aPeter Qiu// http://www.apache.org/licenses/LICENSE-2.0 9326b6cfba5ab73c9e41a7585d1bc95871631122aPeter Qiu// 10326b6cfba5ab73c9e41a7585d1bc95871631122aPeter Qiu// Unless required by applicable law or agreed to in writing, software 11326b6cfba5ab73c9e41a7585d1bc95871631122aPeter Qiu// distributed under the License is distributed on an "AS IS" BASIS, 12326b6cfba5ab73c9e41a7585d1bc95871631122aPeter Qiu// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13326b6cfba5ab73c9e41a7585d1bc95871631122aPeter Qiu// See the License for the specific language governing permissions and 14326b6cfba5ab73c9e41a7585d1bc95871631122aPeter Qiu// limitations under the License. 15326b6cfba5ab73c9e41a7585d1bc95871631122aPeter Qiu// 16fb39ba4b2ef92f0c9d19f6910a350cd8a14405a0Peter Qiu 17fb39ba4b2ef92f0c9d19f6910a350cd8a14405a0Peter Qiu#include "apmanager/device_info.h" 18fb39ba4b2ef92f0c9d19f6910a350cd8a14405a0Peter Qiu 19fb39ba4b2ef92f0c9d19f6910a350cd8a14405a0Peter Qiu#include <linux/netlink.h> 20239395699b0d70ba278d49f40d13e15254924ea5Paul Stewart#include <linux/rtnetlink.h> 21fb39ba4b2ef92f0c9d19f6910a350cd8a14405a0Peter Qiu 22fb39ba4b2ef92f0c9d19f6910a350cd8a14405a0Peter Qiu#include <map> 23fb39ba4b2ef92f0c9d19f6910a350cd8a14405a0Peter Qiu#include <string> 24fb39ba4b2ef92f0c9d19f6910a350cd8a14405a0Peter Qiu#include <vector> 25fb39ba4b2ef92f0c9d19f6910a350cd8a14405a0Peter Qiu 26fb39ba4b2ef92f0c9d19f6910a350cd8a14405a0Peter Qiu#include <base/files/file_util.h> 27fb39ba4b2ef92f0c9d19f6910a350cd8a14405a0Peter Qiu#include <base/files/scoped_temp_dir.h> 28fb39ba4b2ef92f0c9d19f6910a350cd8a14405a0Peter Qiu#include <gmock/gmock.h> 29fb39ba4b2ef92f0c9d19f6910a350cd8a14405a0Peter Qiu#include <gtest/gtest.h> 30fb39ba4b2ef92f0c9d19f6910a350cd8a14405a0Peter Qiu#include <shill/net/byte_string.h> 31fb39ba4b2ef92f0c9d19f6910a350cd8a14405a0Peter Qiu#include <shill/net/mock_netlink_manager.h> 32fb39ba4b2ef92f0c9d19f6910a350cd8a14405a0Peter Qiu#include "shill/net/netlink_message_matchers.h" 33fb39ba4b2ef92f0c9d19f6910a350cd8a14405a0Peter Qiu#include "shill/net/nl80211_attribute.h" 34fb39ba4b2ef92f0c9d19f6910a350cd8a14405a0Peter Qiu#include "shill/net/nl80211_message.h" 35fb39ba4b2ef92f0c9d19f6910a350cd8a14405a0Peter Qiu#include <shill/net/rtnl_message.h> 36fb39ba4b2ef92f0c9d19f6910a350cd8a14405a0Peter Qiu 37f933540bb968efa2744ee48b40ab713ccd358d51Peter Qiu#include "apmanager/fake_device_adaptor.h" 38f933540bb968efa2744ee48b40ab713ccd358d51Peter Qiu#include "apmanager/mock_control.h" 39fb39ba4b2ef92f0c9d19f6910a350cd8a14405a0Peter Qiu#include "apmanager/mock_device.h" 40fb39ba4b2ef92f0c9d19f6910a350cd8a14405a0Peter Qiu#include "apmanager/mock_manager.h" 41fb39ba4b2ef92f0c9d19f6910a350cd8a14405a0Peter Qiu 42fb39ba4b2ef92f0c9d19f6910a350cd8a14405a0Peter Qiuusing shill::ByteString; 43fb39ba4b2ef92f0c9d19f6910a350cd8a14405a0Peter Qiuusing shill::Nl80211Message; 44fb39ba4b2ef92f0c9d19f6910a350cd8a14405a0Peter Qiuusing shill::RTNLMessage; 45fb39ba4b2ef92f0c9d19f6910a350cd8a14405a0Peter Qiuusing std::map; 46fb39ba4b2ef92f0c9d19f6910a350cd8a14405a0Peter Qiuusing std::string; 47fb39ba4b2ef92f0c9d19f6910a350cd8a14405a0Peter Qiuusing std::vector; 48fb39ba4b2ef92f0c9d19f6910a350cd8a14405a0Peter Qiuusing ::testing::_; 49fb39ba4b2ef92f0c9d19f6910a350cd8a14405a0Peter Qiuusing ::testing::Mock; 50f933540bb968efa2744ee48b40ab713ccd358d51Peter Qiuusing ::testing::ReturnNew; 51fb39ba4b2ef92f0c9d19f6910a350cd8a14405a0Peter Qiu 52fb39ba4b2ef92f0c9d19f6910a350cd8a14405a0Peter Qiunamespace apmanager { 53fb39ba4b2ef92f0c9d19f6910a350cd8a14405a0Peter Qiu 54fb39ba4b2ef92f0c9d19f6910a350cd8a14405a0Peter Qiunamespace { 55fb39ba4b2ef92f0c9d19f6910a350cd8a14405a0Peter Qiu 56fb39ba4b2ef92f0c9d19f6910a350cd8a14405a0Peter Qiuconst char kTestDeviceName[] = "test-phy"; 57fb39ba4b2ef92f0c9d19f6910a350cd8a14405a0Peter Qiuconst char kTestInterface0Name[] = "test-interface0"; 58fb39ba4b2ef92f0c9d19f6910a350cd8a14405a0Peter Qiuconst char kTestInterface1Name[] = "test-interface1"; 59fb39ba4b2ef92f0c9d19f6910a350cd8a14405a0Peter Qiuconst uint32_t kTestInterface0Index = 1000; 60fb39ba4b2ef92f0c9d19f6910a350cd8a14405a0Peter Qiuconst uint32_t kTestInterface1Index = 1001; 61fb39ba4b2ef92f0c9d19f6910a350cd8a14405a0Peter Qiu 62fb39ba4b2ef92f0c9d19f6910a350cd8a14405a0Peter Qiu} // namespace 63fb39ba4b2ef92f0c9d19f6910a350cd8a14405a0Peter Qiu 64fb39ba4b2ef92f0c9d19f6910a350cd8a14405a0Peter Qiuclass DeviceInfoTest : public testing::Test { 65fb39ba4b2ef92f0c9d19f6910a350cd8a14405a0Peter Qiu public: 66f933540bb968efa2744ee48b40ab713ccd358d51Peter Qiu DeviceInfoTest() 67f933540bb968efa2744ee48b40ab713ccd358d51Peter Qiu : manager_(&control_interface_), 68f933540bb968efa2744ee48b40ab713ccd358d51Peter Qiu device_info_(&manager_) {} 69fb39ba4b2ef92f0c9d19f6910a350cd8a14405a0Peter Qiu virtual ~DeviceInfoTest() {} 70fb39ba4b2ef92f0c9d19f6910a350cd8a14405a0Peter Qiu 71fb39ba4b2ef92f0c9d19f6910a350cd8a14405a0Peter Qiu virtual void SetUp() { 72fb39ba4b2ef92f0c9d19f6910a350cd8a14405a0Peter Qiu // Setup temporary directory for device info files. 73fb39ba4b2ef92f0c9d19f6910a350cd8a14405a0Peter Qiu CHECK(temp_dir_.CreateUniqueTempDir()); 74fb39ba4b2ef92f0c9d19f6910a350cd8a14405a0Peter Qiu device_info_root_ = temp_dir_.path().Append("sys/class/net"); 75fb39ba4b2ef92f0c9d19f6910a350cd8a14405a0Peter Qiu device_info_.device_info_root_ = device_info_root_; 76fb39ba4b2ef92f0c9d19f6910a350cd8a14405a0Peter Qiu 77fb39ba4b2ef92f0c9d19f6910a350cd8a14405a0Peter Qiu // Setup mock pointers; 78fb39ba4b2ef92f0c9d19f6910a350cd8a14405a0Peter Qiu device_info_.netlink_manager_ = &netlink_manager_; 79f933540bb968efa2744ee48b40ab713ccd358d51Peter Qiu 80f933540bb968efa2744ee48b40ab713ccd358d51Peter Qiu ON_CALL(control_interface_, CreateDeviceAdaptorRaw()) 81f933540bb968efa2744ee48b40ab713ccd358d51Peter Qiu .WillByDefault(ReturnNew<FakeDeviceAdaptor>()); 82fb39ba4b2ef92f0c9d19f6910a350cd8a14405a0Peter Qiu } 83fb39ba4b2ef92f0c9d19f6910a350cd8a14405a0Peter Qiu 84fb39ba4b2ef92f0c9d19f6910a350cd8a14405a0Peter Qiu bool IsWifiInterface(const string& interface_name) { 85fb39ba4b2ef92f0c9d19f6910a350cd8a14405a0Peter Qiu return device_info_.IsWifiInterface(interface_name); 86fb39ba4b2ef92f0c9d19f6910a350cd8a14405a0Peter Qiu } 87fb39ba4b2ef92f0c9d19f6910a350cd8a14405a0Peter Qiu 88fb39ba4b2ef92f0c9d19f6910a350cd8a14405a0Peter Qiu void CreateDeviceInfoFile(const string& interface_name, 89fb39ba4b2ef92f0c9d19f6910a350cd8a14405a0Peter Qiu const string& file_name, 90fb39ba4b2ef92f0c9d19f6910a350cd8a14405a0Peter Qiu const string& contents) { 91fb39ba4b2ef92f0c9d19f6910a350cd8a14405a0Peter Qiu base::FilePath info_path = 92fb39ba4b2ef92f0c9d19f6910a350cd8a14405a0Peter Qiu device_info_root_.Append(interface_name).Append(file_name); 93fb39ba4b2ef92f0c9d19f6910a350cd8a14405a0Peter Qiu EXPECT_TRUE(base::CreateDirectory(info_path.DirName())); 94fb39ba4b2ef92f0c9d19f6910a350cd8a14405a0Peter Qiu EXPECT_TRUE(base::WriteFile(info_path, contents.c_str(), contents.size())); 95fb39ba4b2ef92f0c9d19f6910a350cd8a14405a0Peter Qiu } 96fb39ba4b2ef92f0c9d19f6910a350cd8a14405a0Peter Qiu 97fb39ba4b2ef92f0c9d19f6910a350cd8a14405a0Peter Qiu void SendLinkMsg(RTNLMessage::Mode mode, 98fb39ba4b2ef92f0c9d19f6910a350cd8a14405a0Peter Qiu uint32_t interface_index, 99fb39ba4b2ef92f0c9d19f6910a350cd8a14405a0Peter Qiu const string& interface_name) { 100fb39ba4b2ef92f0c9d19f6910a350cd8a14405a0Peter Qiu RTNLMessage message(RTNLMessage::kTypeLink, 101fb39ba4b2ef92f0c9d19f6910a350cd8a14405a0Peter Qiu mode, 102fb39ba4b2ef92f0c9d19f6910a350cd8a14405a0Peter Qiu 0, 103fb39ba4b2ef92f0c9d19f6910a350cd8a14405a0Peter Qiu 0, 104fb39ba4b2ef92f0c9d19f6910a350cd8a14405a0Peter Qiu 0, 105fb39ba4b2ef92f0c9d19f6910a350cd8a14405a0Peter Qiu interface_index, 106fb39ba4b2ef92f0c9d19f6910a350cd8a14405a0Peter Qiu shill::IPAddress::kFamilyIPv4); 107fb39ba4b2ef92f0c9d19f6910a350cd8a14405a0Peter Qiu message.SetAttribute(static_cast<uint16_t>(IFLA_IFNAME), 108fb39ba4b2ef92f0c9d19f6910a350cd8a14405a0Peter Qiu ByteString(interface_name, true)); 109fb39ba4b2ef92f0c9d19f6910a350cd8a14405a0Peter Qiu device_info_.LinkMsgHandler(message); 110fb39ba4b2ef92f0c9d19f6910a350cd8a14405a0Peter Qiu } 111fb39ba4b2ef92f0c9d19f6910a350cd8a14405a0Peter Qiu 112fb39ba4b2ef92f0c9d19f6910a350cd8a14405a0Peter Qiu void VerifyInterfaceList(const vector<Device::WiFiInterface>& interfaces) { 113fb39ba4b2ef92f0c9d19f6910a350cd8a14405a0Peter Qiu // Verify number of elements in the interface infos map and interface index 114fb39ba4b2ef92f0c9d19f6910a350cd8a14405a0Peter Qiu // of the elements in the map. 115fb39ba4b2ef92f0c9d19f6910a350cd8a14405a0Peter Qiu EXPECT_EQ(interfaces.size(), device_info_.interface_infos_.size()); 116fb39ba4b2ef92f0c9d19f6910a350cd8a14405a0Peter Qiu for (const auto& interface : interfaces) { 117fb39ba4b2ef92f0c9d19f6910a350cd8a14405a0Peter Qiu map<uint32_t, Device::WiFiInterface>::iterator it = 118fb39ba4b2ef92f0c9d19f6910a350cd8a14405a0Peter Qiu device_info_.interface_infos_.find(interface.iface_index); 119fb39ba4b2ef92f0c9d19f6910a350cd8a14405a0Peter Qiu EXPECT_NE(device_info_.interface_infos_.end(), it); 120fb39ba4b2ef92f0c9d19f6910a350cd8a14405a0Peter Qiu EXPECT_TRUE(interface.Equals(it->second)); 121fb39ba4b2ef92f0c9d19f6910a350cd8a14405a0Peter Qiu } 122fb39ba4b2ef92f0c9d19f6910a350cd8a14405a0Peter Qiu } 123fb39ba4b2ef92f0c9d19f6910a350cd8a14405a0Peter Qiu 124fb39ba4b2ef92f0c9d19f6910a350cd8a14405a0Peter Qiu void VerifyDeviceList(const vector<scoped_refptr<Device>>& devices) { 125fb39ba4b2ef92f0c9d19f6910a350cd8a14405a0Peter Qiu // Verify number of elements in the device map and the elements in the map. 126fb39ba4b2ef92f0c9d19f6910a350cd8a14405a0Peter Qiu EXPECT_EQ(devices.size(), device_info_.devices_.size()); 127fb39ba4b2ef92f0c9d19f6910a350cd8a14405a0Peter Qiu for (const auto& device : devices) { 128fb39ba4b2ef92f0c9d19f6910a350cd8a14405a0Peter Qiu map<string, scoped_refptr<Device>>::iterator it = 129fb39ba4b2ef92f0c9d19f6910a350cd8a14405a0Peter Qiu device_info_.devices_.find(device->GetDeviceName()); 130fb39ba4b2ef92f0c9d19f6910a350cd8a14405a0Peter Qiu EXPECT_NE(device_info_.devices_.end(), it); 131fb39ba4b2ef92f0c9d19f6910a350cd8a14405a0Peter Qiu EXPECT_EQ(device, it->second); 132fb39ba4b2ef92f0c9d19f6910a350cd8a14405a0Peter Qiu } 133fb39ba4b2ef92f0c9d19f6910a350cd8a14405a0Peter Qiu } 134fb39ba4b2ef92f0c9d19f6910a350cd8a14405a0Peter Qiu void AddInterface(const Device::WiFiInterface& interface) { 135fb39ba4b2ef92f0c9d19f6910a350cd8a14405a0Peter Qiu device_info_.interface_infos_[interface.iface_index] = interface; 136fb39ba4b2ef92f0c9d19f6910a350cd8a14405a0Peter Qiu } 137fb39ba4b2ef92f0c9d19f6910a350cd8a14405a0Peter Qiu 1381ff67a70eb6dea94ba8a6a836add9810536bec31Peter Qiu void OnWiFiPhyInfoReceived(const Nl80211Message& message) { 1391ff67a70eb6dea94ba8a6a836add9810536bec31Peter Qiu device_info_.OnWiFiPhyInfoReceived(message); 1401ff67a70eb6dea94ba8a6a836add9810536bec31Peter Qiu } 1411ff67a70eb6dea94ba8a6a836add9810536bec31Peter Qiu 142fb39ba4b2ef92f0c9d19f6910a350cd8a14405a0Peter Qiu void OnWiFiInterfaceInfoReceived(const Nl80211Message& message) { 143fb39ba4b2ef92f0c9d19f6910a350cd8a14405a0Peter Qiu device_info_.OnWiFiInterfaceInfoReceived(message); 144fb39ba4b2ef92f0c9d19f6910a350cd8a14405a0Peter Qiu } 145fb39ba4b2ef92f0c9d19f6910a350cd8a14405a0Peter Qiu 146fb39ba4b2ef92f0c9d19f6910a350cd8a14405a0Peter Qiu void OnWiFiInterfacePhyInfoReceived(uint32_t interface_index, 147fb39ba4b2ef92f0c9d19f6910a350cd8a14405a0Peter Qiu const Nl80211Message& message) { 148fb39ba4b2ef92f0c9d19f6910a350cd8a14405a0Peter Qiu device_info_.OnWiFiInterfacePhyInfoReceived(interface_index, message); 149fb39ba4b2ef92f0c9d19f6910a350cd8a14405a0Peter Qiu } 150fb39ba4b2ef92f0c9d19f6910a350cd8a14405a0Peter Qiu 151fb39ba4b2ef92f0c9d19f6910a350cd8a14405a0Peter Qiu void RegisterDevice(scoped_refptr<Device> device) { 152fb39ba4b2ef92f0c9d19f6910a350cd8a14405a0Peter Qiu device_info_.RegisterDevice(device); 153fb39ba4b2ef92f0c9d19f6910a350cd8a14405a0Peter Qiu } 154fb39ba4b2ef92f0c9d19f6910a350cd8a14405a0Peter Qiu 155fb39ba4b2ef92f0c9d19f6910a350cd8a14405a0Peter Qiu protected: 156f933540bb968efa2744ee48b40ab713ccd358d51Peter Qiu MockControl control_interface_; 157fb39ba4b2ef92f0c9d19f6910a350cd8a14405a0Peter Qiu MockManager manager_; 158f933540bb968efa2744ee48b40ab713ccd358d51Peter Qiu 159fb39ba4b2ef92f0c9d19f6910a350cd8a14405a0Peter Qiu shill::MockNetlinkManager netlink_manager_; 160fb39ba4b2ef92f0c9d19f6910a350cd8a14405a0Peter Qiu base::ScopedTempDir temp_dir_; 161fb39ba4b2ef92f0c9d19f6910a350cd8a14405a0Peter Qiu base::FilePath device_info_root_; 162f933540bb968efa2744ee48b40ab713ccd358d51Peter Qiu DeviceInfo device_info_; 163fb39ba4b2ef92f0c9d19f6910a350cd8a14405a0Peter Qiu}; 164fb39ba4b2ef92f0c9d19f6910a350cd8a14405a0Peter Qiu 165fb39ba4b2ef92f0c9d19f6910a350cd8a14405a0Peter QiuMATCHER_P2(IsGetInfoMessage, command, index, "") { 166fb39ba4b2ef92f0c9d19f6910a350cd8a14405a0Peter Qiu if (arg->message_type() != Nl80211Message::GetMessageType()) { 167fb39ba4b2ef92f0c9d19f6910a350cd8a14405a0Peter Qiu return false; 168fb39ba4b2ef92f0c9d19f6910a350cd8a14405a0Peter Qiu } 169fb39ba4b2ef92f0c9d19f6910a350cd8a14405a0Peter Qiu const Nl80211Message *msg = reinterpret_cast<const Nl80211Message *>(arg); 170fb39ba4b2ef92f0c9d19f6910a350cd8a14405a0Peter Qiu if (msg->command() != command) { 171fb39ba4b2ef92f0c9d19f6910a350cd8a14405a0Peter Qiu return false; 172fb39ba4b2ef92f0c9d19f6910a350cd8a14405a0Peter Qiu } 173fb39ba4b2ef92f0c9d19f6910a350cd8a14405a0Peter Qiu uint32_t interface_index; 174fb39ba4b2ef92f0c9d19f6910a350cd8a14405a0Peter Qiu if (!msg->const_attributes()->GetU32AttributeValue(NL80211_ATTR_IFINDEX, 175fb39ba4b2ef92f0c9d19f6910a350cd8a14405a0Peter Qiu &interface_index)) { 176fb39ba4b2ef92f0c9d19f6910a350cd8a14405a0Peter Qiu return false; 177fb39ba4b2ef92f0c9d19f6910a350cd8a14405a0Peter Qiu } 178fb39ba4b2ef92f0c9d19f6910a350cd8a14405a0Peter Qiu // kInterfaceIndex is signed, but the attribute as handed from the kernel 179fb39ba4b2ef92f0c9d19f6910a350cd8a14405a0Peter Qiu // is unsigned. We're silently casting it away with this assignment. 180fb39ba4b2ef92f0c9d19f6910a350cd8a14405a0Peter Qiu uint32_t test_interface_index = index; 181fb39ba4b2ef92f0c9d19f6910a350cd8a14405a0Peter Qiu return interface_index == test_interface_index; 182fb39ba4b2ef92f0c9d19f6910a350cd8a14405a0Peter Qiu} 183fb39ba4b2ef92f0c9d19f6910a350cd8a14405a0Peter Qiu 184fb39ba4b2ef92f0c9d19f6910a350cd8a14405a0Peter QiuMATCHER_P(IsInterface, interface, "") { 185fb39ba4b2ef92f0c9d19f6910a350cd8a14405a0Peter Qiu return arg.Equals(interface); 186fb39ba4b2ef92f0c9d19f6910a350cd8a14405a0Peter Qiu} 187fb39ba4b2ef92f0c9d19f6910a350cd8a14405a0Peter Qiu 1881ff67a70eb6dea94ba8a6a836add9810536bec31Peter QiuMATCHER_P(IsDevice, device_name, "") { 1891ff67a70eb6dea94ba8a6a836add9810536bec31Peter Qiu return arg->GetDeviceName() == device_name; 1901ff67a70eb6dea94ba8a6a836add9810536bec31Peter Qiu} 1911ff67a70eb6dea94ba8a6a836add9810536bec31Peter Qiu 1921ff67a70eb6dea94ba8a6a836add9810536bec31Peter QiuTEST_F(DeviceInfoTest, EnumerateDevices) { 1931ff67a70eb6dea94ba8a6a836add9810536bec31Peter Qiu shill::NewWiphyMessage message; 1941ff67a70eb6dea94ba8a6a836add9810536bec31Peter Qiu 1951ff67a70eb6dea94ba8a6a836add9810536bec31Peter Qiu // No device name in the message, failed to create device. 1961ff67a70eb6dea94ba8a6a836add9810536bec31Peter Qiu EXPECT_CALL(manager_, RegisterDevice(_)).Times(0); 1971ff67a70eb6dea94ba8a6a836add9810536bec31Peter Qiu OnWiFiPhyInfoReceived(message); 1981ff67a70eb6dea94ba8a6a836add9810536bec31Peter Qiu 1991ff67a70eb6dea94ba8a6a836add9810536bec31Peter Qiu // Device name in the message, device should be created/register to manager. 200310966665c47886033c8267ddcbed2bf164daf6dSamuel Tan message.attributes()->CreateNl80211Attribute( 201310966665c47886033c8267ddcbed2bf164daf6dSamuel Tan NL80211_ATTR_WIPHY_NAME, shill::NetlinkMessage::MessageContext()); 2021ff67a70eb6dea94ba8a6a836add9810536bec31Peter Qiu message.attributes()->SetStringAttributeValue(NL80211_ATTR_WIPHY_NAME, 2031ff67a70eb6dea94ba8a6a836add9810536bec31Peter Qiu kTestDeviceName); 2041ff67a70eb6dea94ba8a6a836add9810536bec31Peter Qiu EXPECT_CALL(manager_, RegisterDevice(IsDevice(kTestDeviceName))).Times(1); 2051ff67a70eb6dea94ba8a6a836add9810536bec31Peter Qiu OnWiFiPhyInfoReceived(message); 2061ff67a70eb6dea94ba8a6a836add9810536bec31Peter Qiu Mock::VerifyAndClearExpectations(&manager_); 2071ff67a70eb6dea94ba8a6a836add9810536bec31Peter Qiu 2081ff67a70eb6dea94ba8a6a836add9810536bec31Peter Qiu // Receive a message for a device already created, should not create/register 2091ff67a70eb6dea94ba8a6a836add9810536bec31Peter Qiu // device again. 2101ff67a70eb6dea94ba8a6a836add9810536bec31Peter Qiu EXPECT_CALL(manager_, RegisterDevice(_)).Times(0); 2111ff67a70eb6dea94ba8a6a836add9810536bec31Peter Qiu OnWiFiPhyInfoReceived(message); 2121ff67a70eb6dea94ba8a6a836add9810536bec31Peter Qiu} 2131ff67a70eb6dea94ba8a6a836add9810536bec31Peter Qiu 214fb39ba4b2ef92f0c9d19f6910a350cd8a14405a0Peter QiuTEST_F(DeviceInfoTest, IsWiFiInterface) { 215fb39ba4b2ef92f0c9d19f6910a350cd8a14405a0Peter Qiu // No device info file exist, not a wifi interface. 216fb39ba4b2ef92f0c9d19f6910a350cd8a14405a0Peter Qiu EXPECT_FALSE(IsWifiInterface(kTestInterface0Name)); 217fb39ba4b2ef92f0c9d19f6910a350cd8a14405a0Peter Qiu 218fb39ba4b2ef92f0c9d19f6910a350cd8a14405a0Peter Qiu // Device info for an ethernet device, not a wifi interface 219fb39ba4b2ef92f0c9d19f6910a350cd8a14405a0Peter Qiu CreateDeviceInfoFile(kTestInterface0Name, "uevent", "INTERFACE=eth0\n"); 220fb39ba4b2ef92f0c9d19f6910a350cd8a14405a0Peter Qiu EXPECT_FALSE(IsWifiInterface(kTestInterface0Name)); 221fb39ba4b2ef92f0c9d19f6910a350cd8a14405a0Peter Qiu 222fb39ba4b2ef92f0c9d19f6910a350cd8a14405a0Peter Qiu // Device info for a wifi interface. 223fb39ba4b2ef92f0c9d19f6910a350cd8a14405a0Peter Qiu CreateDeviceInfoFile(kTestInterface1Name, "uevent", "DEVTYPE=wlan\n"); 224fb39ba4b2ef92f0c9d19f6910a350cd8a14405a0Peter Qiu EXPECT_TRUE(IsWifiInterface(kTestInterface1Name)); 225fb39ba4b2ef92f0c9d19f6910a350cd8a14405a0Peter Qiu} 226fb39ba4b2ef92f0c9d19f6910a350cd8a14405a0Peter Qiu 227fb39ba4b2ef92f0c9d19f6910a350cd8a14405a0Peter QiuTEST_F(DeviceInfoTest, InterfaceDetection) { 228fb39ba4b2ef92f0c9d19f6910a350cd8a14405a0Peter Qiu vector<Device::WiFiInterface> interface_list; 229fb39ba4b2ef92f0c9d19f6910a350cd8a14405a0Peter Qiu // Ignore non-wifi interface. 230fb39ba4b2ef92f0c9d19f6910a350cd8a14405a0Peter Qiu SendLinkMsg(RTNLMessage::kModeAdd, 231fb39ba4b2ef92f0c9d19f6910a350cd8a14405a0Peter Qiu kTestInterface0Index, 232fb39ba4b2ef92f0c9d19f6910a350cd8a14405a0Peter Qiu kTestInterface0Name); 233fb39ba4b2ef92f0c9d19f6910a350cd8a14405a0Peter Qiu VerifyInterfaceList(interface_list); 234fb39ba4b2ef92f0c9d19f6910a350cd8a14405a0Peter Qiu 235fb39ba4b2ef92f0c9d19f6910a350cd8a14405a0Peter Qiu // AddLink event for wifi interface. 236fb39ba4b2ef92f0c9d19f6910a350cd8a14405a0Peter Qiu CreateDeviceInfoFile(kTestInterface0Name, "uevent", "DEVTYPE=wlan\n"); 237fb39ba4b2ef92f0c9d19f6910a350cd8a14405a0Peter Qiu EXPECT_CALL(netlink_manager_, SendNl80211Message( 238fb39ba4b2ef92f0c9d19f6910a350cd8a14405a0Peter Qiu IsGetInfoMessage(NL80211_CMD_GET_INTERFACE, kTestInterface0Index), 239fb39ba4b2ef92f0c9d19f6910a350cd8a14405a0Peter Qiu _, _, _)).Times(1); 240fb39ba4b2ef92f0c9d19f6910a350cd8a14405a0Peter Qiu SendLinkMsg(RTNLMessage::kModeAdd, 241fb39ba4b2ef92f0c9d19f6910a350cd8a14405a0Peter Qiu kTestInterface0Index, 242fb39ba4b2ef92f0c9d19f6910a350cd8a14405a0Peter Qiu kTestInterface0Name); 243fb39ba4b2ef92f0c9d19f6910a350cd8a14405a0Peter Qiu interface_list.push_back(Device::WiFiInterface( 244fb39ba4b2ef92f0c9d19f6910a350cd8a14405a0Peter Qiu kTestInterface0Name, "", kTestInterface0Index, 0)); 245fb39ba4b2ef92f0c9d19f6910a350cd8a14405a0Peter Qiu VerifyInterfaceList(interface_list); 246fb39ba4b2ef92f0c9d19f6910a350cd8a14405a0Peter Qiu Mock::VerifyAndClearExpectations(&netlink_manager_); 247fb39ba4b2ef92f0c9d19f6910a350cd8a14405a0Peter Qiu 248fb39ba4b2ef92f0c9d19f6910a350cd8a14405a0Peter Qiu // AddLink event for another wifi interface. 249fb39ba4b2ef92f0c9d19f6910a350cd8a14405a0Peter Qiu CreateDeviceInfoFile(kTestInterface1Name, "uevent", "DEVTYPE=wlan\n"); 250fb39ba4b2ef92f0c9d19f6910a350cd8a14405a0Peter Qiu EXPECT_CALL(netlink_manager_, SendNl80211Message( 251fb39ba4b2ef92f0c9d19f6910a350cd8a14405a0Peter Qiu IsGetInfoMessage(NL80211_CMD_GET_INTERFACE, kTestInterface1Index), 252fb39ba4b2ef92f0c9d19f6910a350cd8a14405a0Peter Qiu _, _, _)).Times(1); 253fb39ba4b2ef92f0c9d19f6910a350cd8a14405a0Peter Qiu SendLinkMsg(RTNLMessage::kModeAdd, 254fb39ba4b2ef92f0c9d19f6910a350cd8a14405a0Peter Qiu kTestInterface1Index, 255fb39ba4b2ef92f0c9d19f6910a350cd8a14405a0Peter Qiu kTestInterface1Name); 256fb39ba4b2ef92f0c9d19f6910a350cd8a14405a0Peter Qiu interface_list.push_back(Device::WiFiInterface( 257fb39ba4b2ef92f0c9d19f6910a350cd8a14405a0Peter Qiu kTestInterface1Name, "", kTestInterface1Index, 0)); 258fb39ba4b2ef92f0c9d19f6910a350cd8a14405a0Peter Qiu VerifyInterfaceList(interface_list); 259fb39ba4b2ef92f0c9d19f6910a350cd8a14405a0Peter Qiu Mock::VerifyAndClearExpectations(&netlink_manager_); 260fb39ba4b2ef92f0c9d19f6910a350cd8a14405a0Peter Qiu 261fb39ba4b2ef92f0c9d19f6910a350cd8a14405a0Peter Qiu // AddLink event for an interface that's already added, no change to interface 262fb39ba4b2ef92f0c9d19f6910a350cd8a14405a0Peter Qiu // list. 263fb39ba4b2ef92f0c9d19f6910a350cd8a14405a0Peter Qiu EXPECT_CALL(netlink_manager_, SendNl80211Message(_, _, _, _)).Times(0); 264fb39ba4b2ef92f0c9d19f6910a350cd8a14405a0Peter Qiu SendLinkMsg(RTNLMessage::kModeAdd, 265fb39ba4b2ef92f0c9d19f6910a350cd8a14405a0Peter Qiu kTestInterface0Index, 266fb39ba4b2ef92f0c9d19f6910a350cd8a14405a0Peter Qiu kTestInterface0Name); 267fb39ba4b2ef92f0c9d19f6910a350cd8a14405a0Peter Qiu VerifyInterfaceList(interface_list); 268fb39ba4b2ef92f0c9d19f6910a350cd8a14405a0Peter Qiu Mock::VerifyAndClearExpectations(&netlink_manager_); 269fb39ba4b2ef92f0c9d19f6910a350cd8a14405a0Peter Qiu 270fb39ba4b2ef92f0c9d19f6910a350cd8a14405a0Peter Qiu // Remove the first wifi interface. 271fb39ba4b2ef92f0c9d19f6910a350cd8a14405a0Peter Qiu SendLinkMsg(RTNLMessage::kModeDelete, 272fb39ba4b2ef92f0c9d19f6910a350cd8a14405a0Peter Qiu kTestInterface0Index, 273fb39ba4b2ef92f0c9d19f6910a350cd8a14405a0Peter Qiu kTestInterface0Name); 274fb39ba4b2ef92f0c9d19f6910a350cd8a14405a0Peter Qiu interface_list.clear(); 275fb39ba4b2ef92f0c9d19f6910a350cd8a14405a0Peter Qiu interface_list.push_back(Device::WiFiInterface( 276fb39ba4b2ef92f0c9d19f6910a350cd8a14405a0Peter Qiu kTestInterface1Name, "", kTestInterface1Index, 0)); 277fb39ba4b2ef92f0c9d19f6910a350cd8a14405a0Peter Qiu VerifyInterfaceList(interface_list); 278fb39ba4b2ef92f0c9d19f6910a350cd8a14405a0Peter Qiu 279fb39ba4b2ef92f0c9d19f6910a350cd8a14405a0Peter Qiu // Remove the non-exist interface, no change to the list. 280fb39ba4b2ef92f0c9d19f6910a350cd8a14405a0Peter Qiu SendLinkMsg(RTNLMessage::kModeDelete, 281fb39ba4b2ef92f0c9d19f6910a350cd8a14405a0Peter Qiu kTestInterface0Index, 282fb39ba4b2ef92f0c9d19f6910a350cd8a14405a0Peter Qiu kTestInterface0Name); 283fb39ba4b2ef92f0c9d19f6910a350cd8a14405a0Peter Qiu VerifyInterfaceList(interface_list); 284fb39ba4b2ef92f0c9d19f6910a350cd8a14405a0Peter Qiu 285fb39ba4b2ef92f0c9d19f6910a350cd8a14405a0Peter Qiu // Remove the last interface, list should be empty now. 286fb39ba4b2ef92f0c9d19f6910a350cd8a14405a0Peter Qiu SendLinkMsg(RTNLMessage::kModeDelete, 287fb39ba4b2ef92f0c9d19f6910a350cd8a14405a0Peter Qiu kTestInterface1Index, 288fb39ba4b2ef92f0c9d19f6910a350cd8a14405a0Peter Qiu kTestInterface1Name); 289fb39ba4b2ef92f0c9d19f6910a350cd8a14405a0Peter Qiu interface_list.clear(); 290fb39ba4b2ef92f0c9d19f6910a350cd8a14405a0Peter Qiu VerifyInterfaceList(interface_list); 291fb39ba4b2ef92f0c9d19f6910a350cd8a14405a0Peter Qiu} 292fb39ba4b2ef92f0c9d19f6910a350cd8a14405a0Peter Qiu 293fb39ba4b2ef92f0c9d19f6910a350cd8a14405a0Peter QiuTEST_F(DeviceInfoTest, ParseWifiInterfaceInfo) { 294fb39ba4b2ef92f0c9d19f6910a350cd8a14405a0Peter Qiu // Add an interface without interface type info. 295fb39ba4b2ef92f0c9d19f6910a350cd8a14405a0Peter Qiu Device::WiFiInterface interface( 296fb39ba4b2ef92f0c9d19f6910a350cd8a14405a0Peter Qiu kTestInterface0Name, "", kTestInterface0Index, 0); 297fb39ba4b2ef92f0c9d19f6910a350cd8a14405a0Peter Qiu AddInterface(interface); 298fb39ba4b2ef92f0c9d19f6910a350cd8a14405a0Peter Qiu vector<Device::WiFiInterface> interface_list; 299fb39ba4b2ef92f0c9d19f6910a350cd8a14405a0Peter Qiu interface_list.push_back(interface); 300fb39ba4b2ef92f0c9d19f6910a350cd8a14405a0Peter Qiu 301fb39ba4b2ef92f0c9d19f6910a350cd8a14405a0Peter Qiu // Message contain no interface index, no change to the interface info. 302fb39ba4b2ef92f0c9d19f6910a350cd8a14405a0Peter Qiu shill::NewInterfaceMessage message; 303fb39ba4b2ef92f0c9d19f6910a350cd8a14405a0Peter Qiu OnWiFiInterfaceInfoReceived(message); 304fb39ba4b2ef92f0c9d19f6910a350cd8a14405a0Peter Qiu VerifyInterfaceList(interface_list); 305fb39ba4b2ef92f0c9d19f6910a350cd8a14405a0Peter Qiu 306fb39ba4b2ef92f0c9d19f6910a350cd8a14405a0Peter Qiu // Message contain no interface type, no change to the interface info. 307310966665c47886033c8267ddcbed2bf164daf6dSamuel Tan message.attributes()->CreateNl80211Attribute( 308310966665c47886033c8267ddcbed2bf164daf6dSamuel Tan NL80211_ATTR_IFINDEX, shill::NetlinkMessage::MessageContext()); 309fb39ba4b2ef92f0c9d19f6910a350cd8a14405a0Peter Qiu message.attributes()->SetU32AttributeValue(NL80211_ATTR_IFINDEX, 310fb39ba4b2ef92f0c9d19f6910a350cd8a14405a0Peter Qiu kTestInterface0Index); 311fb39ba4b2ef92f0c9d19f6910a350cd8a14405a0Peter Qiu OnWiFiInterfaceInfoReceived(message); 312fb39ba4b2ef92f0c9d19f6910a350cd8a14405a0Peter Qiu 313fb39ba4b2ef92f0c9d19f6910a350cd8a14405a0Peter Qiu // Message contain interface type, interface info should be updated with 314fb39ba4b2ef92f0c9d19f6910a350cd8a14405a0Peter Qiu // the interface type, and a new Nl80211 message should be send to query for 315fb39ba4b2ef92f0c9d19f6910a350cd8a14405a0Peter Qiu // the PHY info. 316fb39ba4b2ef92f0c9d19f6910a350cd8a14405a0Peter Qiu EXPECT_CALL(netlink_manager_, SendNl80211Message( 317fb39ba4b2ef92f0c9d19f6910a350cd8a14405a0Peter Qiu IsGetInfoMessage(NL80211_CMD_GET_WIPHY, kTestInterface0Index), 318fb39ba4b2ef92f0c9d19f6910a350cd8a14405a0Peter Qiu _, _, _)).Times(1); 319310966665c47886033c8267ddcbed2bf164daf6dSamuel Tan message.attributes()->CreateNl80211Attribute( 320310966665c47886033c8267ddcbed2bf164daf6dSamuel Tan NL80211_ATTR_IFTYPE, shill::NetlinkMessage::MessageContext()); 321fb39ba4b2ef92f0c9d19f6910a350cd8a14405a0Peter Qiu message.attributes()->SetU32AttributeValue(NL80211_ATTR_IFTYPE, 322fb39ba4b2ef92f0c9d19f6910a350cd8a14405a0Peter Qiu NL80211_IFTYPE_AP); 323fb39ba4b2ef92f0c9d19f6910a350cd8a14405a0Peter Qiu OnWiFiInterfaceInfoReceived(message); 324fb39ba4b2ef92f0c9d19f6910a350cd8a14405a0Peter Qiu interface_list[0].iface_type = NL80211_IFTYPE_AP; 325fb39ba4b2ef92f0c9d19f6910a350cd8a14405a0Peter Qiu VerifyInterfaceList(interface_list); 326fb39ba4b2ef92f0c9d19f6910a350cd8a14405a0Peter Qiu} 327fb39ba4b2ef92f0c9d19f6910a350cd8a14405a0Peter Qiu 328fb39ba4b2ef92f0c9d19f6910a350cd8a14405a0Peter QiuTEST_F(DeviceInfoTest, ParsePhyInfoForWifiInterface) { 329fb39ba4b2ef92f0c9d19f6910a350cd8a14405a0Peter Qiu // Register a mock device. 330f933540bb968efa2744ee48b40ab713ccd358d51Peter Qiu scoped_refptr<MockDevice> device = new MockDevice(&manager_); 331fb39ba4b2ef92f0c9d19f6910a350cd8a14405a0Peter Qiu device->SetDeviceName(kTestDeviceName); 332fb39ba4b2ef92f0c9d19f6910a350cd8a14405a0Peter Qiu EXPECT_CALL(manager_, RegisterDevice(_)).Times(1); 333fb39ba4b2ef92f0c9d19f6910a350cd8a14405a0Peter Qiu RegisterDevice(device); 334fb39ba4b2ef92f0c9d19f6910a350cd8a14405a0Peter Qiu 335fb39ba4b2ef92f0c9d19f6910a350cd8a14405a0Peter Qiu // PHY info message. 336fb39ba4b2ef92f0c9d19f6910a350cd8a14405a0Peter Qiu shill::NewWiphyMessage message; 337310966665c47886033c8267ddcbed2bf164daf6dSamuel Tan message.attributes()->CreateNl80211Attribute( 338310966665c47886033c8267ddcbed2bf164daf6dSamuel Tan NL80211_ATTR_WIPHY_NAME, shill::NetlinkMessage::MessageContext()); 339fb39ba4b2ef92f0c9d19f6910a350cd8a14405a0Peter Qiu message.attributes()->SetStringAttributeValue(NL80211_ATTR_WIPHY_NAME, 340fb39ba4b2ef92f0c9d19f6910a350cd8a14405a0Peter Qiu kTestDeviceName); 341fb39ba4b2ef92f0c9d19f6910a350cd8a14405a0Peter Qiu 342fb39ba4b2ef92f0c9d19f6910a350cd8a14405a0Peter Qiu // Receive PHY info message for an interface that have not been detected yet. 343fb39ba4b2ef92f0c9d19f6910a350cd8a14405a0Peter Qiu EXPECT_CALL(*device.get(), RegisterInterface(_)).Times(0); 344fb39ba4b2ef92f0c9d19f6910a350cd8a14405a0Peter Qiu OnWiFiInterfacePhyInfoReceived(kTestInterface0Index, message); 345fb39ba4b2ef92f0c9d19f6910a350cd8a14405a0Peter Qiu 346fb39ba4b2ef92f0c9d19f6910a350cd8a14405a0Peter Qiu // Pretend interface is detected through AddLink with interface info already 347fb39ba4b2ef92f0c9d19f6910a350cd8a14405a0Peter Qiu // received (interface type), and still missing PHY info for that interface. 348fb39ba4b2ef92f0c9d19f6910a350cd8a14405a0Peter Qiu Device::WiFiInterface interface( 349fb39ba4b2ef92f0c9d19f6910a350cd8a14405a0Peter Qiu kTestInterface0Name, "", kTestInterface0Index, NL80211_IFTYPE_AP); 350fb39ba4b2ef92f0c9d19f6910a350cd8a14405a0Peter Qiu AddInterface(interface); 351fb39ba4b2ef92f0c9d19f6910a350cd8a14405a0Peter Qiu 352fb39ba4b2ef92f0c9d19f6910a350cd8a14405a0Peter Qiu // PHY info is received for a detected interface, should register that 353fb39ba4b2ef92f0c9d19f6910a350cd8a14405a0Peter Qiu // interface to the corresponding Device. 354fb39ba4b2ef92f0c9d19f6910a350cd8a14405a0Peter Qiu interface.device_name = kTestDeviceName; 355fb39ba4b2ef92f0c9d19f6910a350cd8a14405a0Peter Qiu EXPECT_CALL(*device.get(), 356fb39ba4b2ef92f0c9d19f6910a350cd8a14405a0Peter Qiu RegisterInterface(IsInterface(interface))).Times(1); 357fb39ba4b2ef92f0c9d19f6910a350cd8a14405a0Peter Qiu OnWiFiInterfacePhyInfoReceived(kTestInterface0Index, message); 358fb39ba4b2ef92f0c9d19f6910a350cd8a14405a0Peter Qiu} 359fb39ba4b2ef92f0c9d19f6910a350cd8a14405a0Peter Qiu 360fb39ba4b2ef92f0c9d19f6910a350cd8a14405a0Peter QiuTEST_F(DeviceInfoTest, ReceivePhyInfoBeforePhyIsEnumerated) { 361fb39ba4b2ef92f0c9d19f6910a350cd8a14405a0Peter Qiu // New interface is detected. 362fb39ba4b2ef92f0c9d19f6910a350cd8a14405a0Peter Qiu Device::WiFiInterface interface( 363fb39ba4b2ef92f0c9d19f6910a350cd8a14405a0Peter Qiu kTestInterface0Name, "", kTestInterface0Index, NL80211_IFTYPE_AP); 364fb39ba4b2ef92f0c9d19f6910a350cd8a14405a0Peter Qiu AddInterface(interface); 3651ff67a70eb6dea94ba8a6a836add9810536bec31Peter Qiu vector<Device::WiFiInterface> interface_list; 3661ff67a70eb6dea94ba8a6a836add9810536bec31Peter Qiu interface_list.push_back(interface); 367fb39ba4b2ef92f0c9d19f6910a350cd8a14405a0Peter Qiu 368fb39ba4b2ef92f0c9d19f6910a350cd8a14405a0Peter Qiu // Received PHY info for the interface when the corresponding PHY is not 3691ff67a70eb6dea94ba8a6a836add9810536bec31Peter Qiu // enumerated yet, new device should be created and register to manager. 370fb39ba4b2ef92f0c9d19f6910a350cd8a14405a0Peter Qiu shill::NewWiphyMessage message; 371310966665c47886033c8267ddcbed2bf164daf6dSamuel Tan message.attributes()->CreateNl80211Attribute( 372310966665c47886033c8267ddcbed2bf164daf6dSamuel Tan NL80211_ATTR_WIPHY_NAME, shill::NetlinkMessage::MessageContext()); 373fb39ba4b2ef92f0c9d19f6910a350cd8a14405a0Peter Qiu message.attributes()->SetStringAttributeValue(NL80211_ATTR_WIPHY_NAME, 374fb39ba4b2ef92f0c9d19f6910a350cd8a14405a0Peter Qiu kTestDeviceName); 3751ff67a70eb6dea94ba8a6a836add9810536bec31Peter Qiu EXPECT_CALL(manager_, RegisterDevice(IsDevice(kTestDeviceName))).Times(1); 376fb39ba4b2ef92f0c9d19f6910a350cd8a14405a0Peter Qiu OnWiFiInterfacePhyInfoReceived(kTestInterface0Index, message); 3771ff67a70eb6dea94ba8a6a836add9810536bec31Peter Qiu interface_list[0].device_name = kTestDeviceName; 3781ff67a70eb6dea94ba8a6a836add9810536bec31Peter Qiu VerifyInterfaceList(interface_list); 379fb39ba4b2ef92f0c9d19f6910a350cd8a14405a0Peter Qiu} 380fb39ba4b2ef92f0c9d19f6910a350cd8a14405a0Peter Qiu 381fb39ba4b2ef92f0c9d19f6910a350cd8a14405a0Peter QiuTEST_F(DeviceInfoTest, RegisterDevice) { 382fb39ba4b2ef92f0c9d19f6910a350cd8a14405a0Peter Qiu vector<scoped_refptr<Device>> device_list; 383fb39ba4b2ef92f0c9d19f6910a350cd8a14405a0Peter Qiu 384fb39ba4b2ef92f0c9d19f6910a350cd8a14405a0Peter Qiu // Register a nullptr. 385fb39ba4b2ef92f0c9d19f6910a350cd8a14405a0Peter Qiu RegisterDevice(nullptr); 386fb39ba4b2ef92f0c9d19f6910a350cd8a14405a0Peter Qiu VerifyDeviceList(device_list); 387fb39ba4b2ef92f0c9d19f6910a350cd8a14405a0Peter Qiu 388fb39ba4b2ef92f0c9d19f6910a350cd8a14405a0Peter Qiu // Register a device. 389f933540bb968efa2744ee48b40ab713ccd358d51Peter Qiu device_list.push_back(new Device(&manager_, kTestDeviceName, 0)); 390fb39ba4b2ef92f0c9d19f6910a350cd8a14405a0Peter Qiu EXPECT_CALL(manager_, RegisterDevice(device_list[0])); 391fb39ba4b2ef92f0c9d19f6910a350cd8a14405a0Peter Qiu RegisterDevice(device_list[0]); 392fb39ba4b2ef92f0c9d19f6910a350cd8a14405a0Peter Qiu VerifyDeviceList(device_list); 393fb39ba4b2ef92f0c9d19f6910a350cd8a14405a0Peter Qiu} 394fb39ba4b2ef92f0c9d19f6910a350cd8a14405a0Peter Qiu 395fb39ba4b2ef92f0c9d19f6910a350cd8a14405a0Peter Qiu} // namespace apmanager 396