1// 2// Copyright (C) 2015 The Android Open Source Project 3// 4// Licensed under the Apache License, Version 2.0 (the "License"); 5// you may not use this file except in compliance with the License. 6// You may obtain a copy of the License at 7// 8// http://www.apache.org/licenses/LICENSE-2.0 9// 10// Unless required by applicable law or agreed to in writing, software 11// distributed under the License is distributed on an "AS IS" BASIS, 12// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13// See the License for the specific language governing permissions and 14// limitations under the License. 15// 16 17#include <dhcp_client/device_info.h> 18 19#include <net/if.h> 20#include <sys/ioctl.h> 21 22#include <gmock/gmock.h> 23#include <gtest/gtest.h> 24 25#include <shill/net/byte_string.h> 26#include <shill/net/mock_sockets.h> 27#include <shill/net/mock_rtnl_handler.h> 28 29using shill::ByteString; 30using shill::MockRTNLHandler; 31using shill::MockSockets; 32using ::testing::_; 33using ::testing::DoAll; 34using ::testing::ElementsAreArray; 35using ::testing::Return; 36 37namespace { 38 39const int kFakeFd = 99; 40const unsigned int kFakeInterfaceIndex = 1; 41const std::string kFakeDeviceName = "eth0"; 42const std::string kFakeLongDeviceName = "a_long_device_name"; 43const uint8_t kFakeMacAddress[] = {0x00, 0x01, 0x02, 0xaa, 0xbb, 0xcc}; 44 45} 46 47namespace dhcp_client { 48 49class DeviceInfoTest : public testing::Test { 50 public: 51 DeviceInfoTest() {} 52 53 void SetUp() { 54 device_info_ = DeviceInfo::GetInstance(); 55 sockets_ = new MockSockets(); 56 device_info_->sockets_.reset(sockets_); 57 device_info_->rtnl_handler_ = &rtnl_handler_; 58 } 59 60 protected: 61 DeviceInfo* device_info_; 62 MockRTNLHandler rtnl_handler_; 63 MockSockets* sockets_; // Owned by device_info_. 64}; 65 66ACTION_P(SetIfreq, ifr) { 67 struct ifreq* const ifr_arg = static_cast<struct ifreq*>(arg2); 68 *ifr_arg = ifr; 69} 70 71MATCHER_P(IfreqEquals, ifname, "") { 72 const struct ifreq* const ifr = static_cast<struct ifreq*>(arg); 73 return (ifr != nullptr) && 74 (strcmp(ifname, ifr->ifr_name) == 0); 75} 76 77TEST_F(DeviceInfoTest, GetDeviceInfoSucceed) { 78 ByteString mac_address; 79 unsigned int interface_index; 80 struct ifreq ifr; 81 memcpy(ifr.ifr_hwaddr.sa_data, kFakeMacAddress, sizeof(kFakeMacAddress)); 82 EXPECT_CALL(*sockets_, Socket(AF_INET, SOCK_DGRAM, 0)) 83 .WillOnce(Return(kFakeFd)); 84 EXPECT_CALL(*sockets_, Ioctl(kFakeFd, 85 SIOCGIFHWADDR, 86 IfreqEquals(kFakeDeviceName.c_str()))) 87 .WillOnce(DoAll(SetIfreq(ifr), Return(0))); 88 EXPECT_CALL(rtnl_handler_, GetInterfaceIndex(kFakeDeviceName)) 89 .WillOnce(Return(kFakeInterfaceIndex)); 90 EXPECT_TRUE(device_info_->GetDeviceInfo(kFakeDeviceName, 91 &mac_address, 92 &interface_index)); 93 EXPECT_EQ(interface_index, kFakeInterfaceIndex); 94 EXPECT_THAT(kFakeMacAddress, 95 ElementsAreArray(mac_address.GetConstData(), 96 sizeof(kFakeMacAddress))); 97} 98 99TEST_F(DeviceInfoTest, GetDeviceInfoNameTooLong) { 100 ByteString mac_address; 101 unsigned int interface_index; 102 EXPECT_FALSE(device_info_->GetDeviceInfo(kFakeLongDeviceName, 103 &mac_address, 104 &interface_index)); 105} 106 107TEST_F(DeviceInfoTest, GetDeviceInfoFailedToCreateSocket) { 108 ByteString mac_address; 109 unsigned int interface_index; 110 EXPECT_CALL(*sockets_, Socket(AF_INET, SOCK_DGRAM, 0)).WillOnce(Return(-1)); 111 EXPECT_FALSE(device_info_->GetDeviceInfo(kFakeDeviceName, 112 &mac_address, 113 &interface_index)); 114} 115 116TEST_F(DeviceInfoTest, GetDeviceInfoFailedToGetHardwareAddr) { 117 ByteString mac_address; 118 unsigned int interface_index; 119 EXPECT_CALL(*sockets_, Socket(AF_INET, SOCK_DGRAM, 0)) 120 .WillOnce(Return(kFakeFd)); 121 EXPECT_CALL(*sockets_, Ioctl(kFakeFd, SIOCGIFHWADDR, _)).WillOnce(Return(-1)); 122 EXPECT_FALSE(device_info_->GetDeviceInfo(kFakeDeviceName, 123 &mac_address, 124 &interface_index)); 125} 126 127TEST_F(DeviceInfoTest, GetDeviceInfoFailedToGetInterfaceIndex) { 128 ByteString mac_address; 129 unsigned int interface_index; 130 EXPECT_CALL(*sockets_, Socket(AF_INET, SOCK_DGRAM, 0)) 131 .WillOnce(Return(kFakeFd)); 132 EXPECT_CALL(*sockets_, Ioctl(kFakeFd, SIOCGIFHWADDR, _)).WillOnce(Return(0)); 133 EXPECT_CALL(rtnl_handler_, GetInterfaceIndex(kFakeDeviceName)) 134 .WillOnce(Return(-1)); 135 EXPECT_FALSE(device_info_->GetDeviceInfo(kFakeDeviceName, 136 &mac_address, 137 &interface_index)); 138} 139 140} // namespace dhcp_client 141