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:
DeviceInfoTest()51 DeviceInfoTest() {}
52
SetUp()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
ACTION_P(SetIfreq,ifr)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
TEST_F(DeviceInfoTest,GetDeviceInfoSucceed)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
TEST_F(DeviceInfoTest,GetDeviceInfoNameTooLong)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
TEST_F(DeviceInfoTest,GetDeviceInfoFailedToCreateSocket)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
TEST_F(DeviceInfoTest,GetDeviceInfoFailedToGetHardwareAddr)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
TEST_F(DeviceInfoTest,GetDeviceInfoFailedToGetInterfaceIndex)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