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 29 using shill::ByteString; 30 using shill::MockRTNLHandler; 31 using shill::MockSockets; 32 using ::testing::_; 33 using ::testing::DoAll; 34 using ::testing::ElementsAreArray; 35 using ::testing::Return; 36 37 namespace { 38 39 const int kFakeFd = 99; 40 const unsigned int kFakeInterfaceIndex = 1; 41 const std::string kFakeDeviceName = "eth0"; 42 const std::string kFakeLongDeviceName = "a_long_device_name"; 43 const uint8_t kFakeMacAddress[] = {0x00, 0x01, 0x02, 0xaa, 0xbb, 0xcc}; 44 45 } 46 47 namespace dhcp_client { 48 49 class 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 66 ACTION_P(SetIfreq, ifr) { 67 struct ifreq* const ifr_arg = static_cast<struct ifreq*>(arg2); 68 *ifr_arg = ifr; 69 } 70 71 MATCHER_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 77 TEST_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 99 TEST_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 107 TEST_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 116 TEST_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 127 TEST_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