OSDN Git Service

Add unit tests for NetlinkUtils::GetWiphyInfo() am: 38632b29f9 am: 8548413e2b am...
[android-x86/system-connectivity-wificond.git] / tests / netlink_utils_unittest.cpp
1 /*
2  * Copyright (C) 2016, 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 <memory>
18 #include <string>
19 #include <vector>
20
21 #include <linux/netlink.h>
22 #include <linux/nl80211.h>
23
24 #include <gtest/gtest.h>
25
26 #include "wificond/net/netlink_utils.h"
27 #include "wificond/tests/mock_netlink_manager.h"
28
29 using std::string;
30 using std::unique_ptr;
31 using std::vector;
32 using testing::DoAll;
33 using testing::NiceMock;
34 using testing::Return;
35 using testing::_;
36
37 namespace android {
38 namespace wificond {
39
40 namespace {
41
42 constexpr uint8_t kFakeMaxNumScanSSIDs = 10;
43 constexpr uint8_t kFakeMaxNumSchedScanSSIDs = 16;
44 constexpr uint8_t kFakeMaxMatchSets = 18;
45 constexpr uint16_t kFakeFamilyId = 14;
46 constexpr uint32_t kFakeFrequency1 = 2412;
47 constexpr uint32_t kFakeFrequency2 = 2437;
48 constexpr uint32_t kFakeFrequency3 = 2484;
49 constexpr uint32_t kFakeFrequency4 = 5200;
50 constexpr uint32_t kFakeFrequency5 = 5400;
51 constexpr uint32_t kFakeFrequency6 = 5600;
52 constexpr uint32_t kFakeSequenceNumber = 162;
53 constexpr uint16_t kFakeWiphyIndex = 8;
54 constexpr int kFakeErrorCode = EIO;
55 const char kFakeInterfaceName[] = "testif0";
56 const uint32_t kFakeInterfaceIndex = 34;
57 const uint8_t kFakeInterfaceMacAddress[] = {0x45, 0x54, 0xad, 0x67, 0x98, 0xf6};
58
59 // Currently, control messages are only created by the kernel and sent to us.
60 // Therefore NL80211Packet doesn't have corresponding constructor.
61 // For test we manually create control messages using this helper function.
62 NL80211Packet CreateControlMessageError(int error_code) {
63   vector<uint8_t> data;
64   data.resize(NLMSG_HDRLEN + NLA_ALIGN(sizeof(int)), 0);
65   // Initialize length field.
66   nlmsghdr* nl_header = reinterpret_cast<nlmsghdr*>(data.data());
67   nl_header->nlmsg_len = data.size();
68   nl_header->nlmsg_type = NLMSG_ERROR;
69   nl_header->nlmsg_seq = kFakeSequenceNumber;
70   nl_header->nlmsg_pid = getpid();
71   int* error_field = reinterpret_cast<int*>(data.data() + NLMSG_HDRLEN);
72   *error_field = -error_code;
73
74   return NL80211Packet(data);
75 }
76
77 }  // namespace
78
79 class NetlinkUtilsTest : public ::testing::Test {
80  protected:
81   std::unique_ptr<NiceMock<MockNetlinkManager>> netlink_manager_;
82   std::unique_ptr<NetlinkUtils> netlink_utils_;
83
84   virtual void SetUp() {
85     netlink_manager_.reset(new NiceMock<MockNetlinkManager>());
86     netlink_utils_.reset(new NetlinkUtils(netlink_manager_.get()));
87
88     ON_CALL(*netlink_manager_,
89             GetSequenceNumber()).WillByDefault(Return(kFakeSequenceNumber));
90     ON_CALL(*netlink_manager_,
91             GetFamilyId()).WillByDefault(Return(kFakeFamilyId));
92   }
93 };
94
95 // This mocks the behavior of SendMessageAndGetResponses(), which returns a
96 // vector of NL80211Packet using passed in pointer.
97 ACTION_P(MakeupResponse, response) {
98   // arg1 is the second parameter: vector<unique_ptr<const NL80211Packet>>* responses.
99   for (auto& pkt : response) {
100     arg1->push_back(unique_ptr<NL80211Packet>(new NL80211Packet(pkt)));
101   }
102 }
103
104 TEST_F(NetlinkUtilsTest, CanGetWiphyIndex) {
105   NL80211Packet new_wiphy(
106       netlink_manager_->GetFamilyId(),
107       NL80211_CMD_NEW_WIPHY,
108       netlink_manager_->GetSequenceNumber(),
109       getpid());
110   // Insert wiphy_index attribute.
111   NL80211Attr<uint32_t> wiphy_index_attr(NL80211_ATTR_WIPHY, kFakeWiphyIndex);
112   new_wiphy.AddAttribute(wiphy_index_attr);
113   // Mock a valid response from kernel.
114   vector<NL80211Packet> response = {new_wiphy};
115
116   EXPECT_CALL(*netlink_manager_, SendMessageAndGetResponses(_, _)).
117       WillOnce(DoAll(MakeupResponse(response), Return(true)));
118
119   uint32_t wiphy_index;
120   EXPECT_TRUE(netlink_utils_->GetWiphyIndex(&wiphy_index));
121   EXPECT_EQ(kFakeWiphyIndex, wiphy_index);
122 }
123
124 TEST_F(NetlinkUtilsTest, CanHandleGetWiphyIndexError) {
125   // Mock an error response from kernel.
126   vector<NL80211Packet> response = {CreateControlMessageError(kFakeErrorCode)};
127
128   EXPECT_CALL(*netlink_manager_, SendMessageAndGetResponses(_, _)).
129       WillOnce(DoAll(MakeupResponse(response), Return(true)));
130
131   uint32_t wiphy_index;
132   EXPECT_FALSE(netlink_utils_->GetWiphyIndex(&wiphy_index));
133 }
134
135 TEST_F(NetlinkUtilsTest, CanGetInterfaceInfo) {
136   NL80211Packet new_interface(
137       netlink_manager_->GetFamilyId(),
138       NL80211_CMD_NEW_INTERFACE,
139       netlink_manager_->GetSequenceNumber(),
140       getpid());
141   // Insert interface name attribute.
142   NL80211Attr<string> if_name_attr(NL80211_ATTR_IFNAME, string(kFakeInterfaceName));
143   new_interface.AddAttribute(if_name_attr);
144   // Insert interface index attribute.
145   NL80211Attr<uint32_t> if_index_attr(NL80211_ATTR_IFINDEX, kFakeInterfaceIndex);
146   new_interface.AddAttribute(if_index_attr);
147   // Insert mac address attribute.
148   std::vector<uint8_t> if_mac_addr;
149   if_mac_addr.assign(
150       kFakeInterfaceMacAddress,
151       kFakeInterfaceMacAddress + sizeof(kFakeInterfaceMacAddress));
152   NL80211Attr<vector<uint8_t>> if_mac_attr(NL80211_ATTR_MAC, if_mac_addr);
153   new_interface.AddAttribute(if_mac_attr);
154
155   // Mock a valid response from kernel.
156   vector<NL80211Packet> response = {new_interface};
157
158   EXPECT_CALL(*netlink_manager_, SendMessageAndGetResponses(_, _)).
159       WillOnce(DoAll(MakeupResponse(response), Return(true)));
160
161   string interface_name;
162   uint32_t interface_index;
163   vector<uint8_t> interface_mac_addr;
164   EXPECT_TRUE(netlink_utils_->GetInterfaceInfo(kFakeWiphyIndex,
165                                                &interface_name,
166                                                &interface_index,
167                                                &interface_mac_addr));
168   EXPECT_EQ(string(kFakeInterfaceName), interface_name);
169   EXPECT_EQ(kFakeInterfaceIndex, interface_index);
170   EXPECT_EQ(if_mac_addr, interface_mac_addr);
171 }
172
173 TEST_F(NetlinkUtilsTest, HandlesPseudoDevicesInInterfaceInfoQuery) {
174   // Some kernels will have extra responses ahead of the expected packet.
175   NL80211Packet psuedo_interface(
176       netlink_manager_->GetFamilyId(),
177       NL80211_CMD_NEW_INTERFACE,
178       netlink_manager_->GetSequenceNumber(),
179       getpid());
180   psuedo_interface.AddAttribute(NL80211Attr<uint64_t>(
181       NL80211_ATTR_WDEV, 0));
182
183   // This is the packet we're looking for
184   NL80211Packet expected_interface(
185       netlink_manager_->GetFamilyId(),
186       NL80211_CMD_NEW_INTERFACE,
187       netlink_manager_->GetSequenceNumber(),
188       getpid());
189   expected_interface.AddAttribute(NL80211Attr<string>(
190       NL80211_ATTR_IFNAME, string(kFakeInterfaceName)));
191   expected_interface.AddAttribute(NL80211Attr<uint32_t>(
192       NL80211_ATTR_IFINDEX, kFakeInterfaceIndex));
193   std::vector<uint8_t> if_mac_addr;
194   if_mac_addr.assign(
195       kFakeInterfaceMacAddress,
196       kFakeInterfaceMacAddress + sizeof(kFakeInterfaceMacAddress));
197   expected_interface.AddAttribute(
198       NL80211Attr<vector<uint8_t>>(NL80211_ATTR_MAC, if_mac_addr));
199
200   // Kernel can send us the pseduo interface packet first
201   vector<NL80211Packet> response = {psuedo_interface, expected_interface};
202
203   EXPECT_CALL(*netlink_manager_, SendMessageAndGetResponses(_, _)).
204       WillOnce(DoAll(MakeupResponse(response), Return(true)));
205
206   string interface_name;
207   uint32_t interface_index;
208   vector<uint8_t> interface_mac_addr;
209   EXPECT_TRUE(netlink_utils_->GetInterfaceInfo(
210       kFakeWiphyIndex, &interface_name, &interface_index, &interface_mac_addr));
211   EXPECT_EQ(string(kFakeInterfaceName), interface_name);
212   EXPECT_EQ(kFakeInterfaceIndex, interface_index);
213   EXPECT_EQ(if_mac_addr, interface_mac_addr);
214 }
215
216 TEST_F(NetlinkUtilsTest, HandleP2p0WhenGetInterfaceInfo) {
217   NL80211Packet new_interface(
218       netlink_manager_->GetFamilyId(),
219       NL80211_CMD_NEW_INTERFACE,
220       netlink_manager_->GetSequenceNumber(),
221       getpid());
222   // Insert interface name attribute.
223   NL80211Attr<string> if_name_attr(NL80211_ATTR_IFNAME, string(kFakeInterfaceName));
224   new_interface.AddAttribute(if_name_attr);
225   // Insert interface index attribute.
226   NL80211Attr<uint32_t> if_index_attr(NL80211_ATTR_IFINDEX, kFakeInterfaceIndex);
227   new_interface.AddAttribute(if_index_attr);
228   // Insert mac address attribute.
229   std::vector<uint8_t> if_mac_addr;
230   if_mac_addr.assign(
231       kFakeInterfaceMacAddress,
232       kFakeInterfaceMacAddress + sizeof(kFakeInterfaceMacAddress));
233   NL80211Attr<vector<uint8_t>> if_mac_attr(NL80211_ATTR_MAC, if_mac_addr);
234   new_interface.AddAttribute(if_mac_attr);
235
236   // Create a new interface packet for p2p0.
237   NL80211Packet new_interface_p2p0(
238       netlink_manager_->GetFamilyId(),
239       NL80211_CMD_NEW_INTERFACE,
240       netlink_manager_->GetSequenceNumber(),
241       getpid());
242   NL80211Attr<string> if_name_attr_p2p0(NL80211_ATTR_IFNAME, "p2p0");
243   new_interface_p2p0.AddAttribute(if_name_attr_p2p0);
244   // Mock response from kernel, including 2 interfaces.
245   vector<NL80211Packet> response = {new_interface_p2p0, new_interface};
246
247   EXPECT_CALL(*netlink_manager_, SendMessageAndGetResponses(_, _)).
248       WillOnce(DoAll(MakeupResponse(response), Return(true)));
249
250   string interface_name;
251   uint32_t interface_index;
252   vector<uint8_t> interface_mac_addr;
253   EXPECT_TRUE(netlink_utils_->GetInterfaceInfo(kFakeWiphyIndex,
254                                                &interface_name,
255                                                &interface_index,
256                                                &interface_mac_addr));
257   EXPECT_EQ(string(kFakeInterfaceName), interface_name);
258   EXPECT_EQ(kFakeInterfaceIndex, interface_index);
259   EXPECT_EQ(if_mac_addr, interface_mac_addr);
260 }
261
262 TEST_F(NetlinkUtilsTest, CanHandleGetInterfaceInfoError) {
263   // Mock an error response from kernel.
264   vector<NL80211Packet> response = {CreateControlMessageError(kFakeErrorCode)};
265
266   EXPECT_CALL(*netlink_manager_, SendMessageAndGetResponses(_, _)).
267       WillOnce(DoAll(MakeupResponse(response), Return(true)));
268
269   string interface_name;
270   uint32_t interface_index;
271   vector<uint8_t> interface_mac_addr;
272   EXPECT_FALSE(netlink_utils_->GetInterfaceInfo(kFakeWiphyIndex,
273                                                 &interface_name,
274                                                 &interface_index,
275                                                 &interface_mac_addr));
276 }
277
278 TEST_F(NetlinkUtilsTest, CanGetWiphyInfo) {
279   NL80211Packet new_wiphy(
280       netlink_manager_->GetFamilyId(),
281       NL80211_CMD_NEW_WIPHY,
282       netlink_manager_->GetSequenceNumber(),
283       getpid());
284   new_wiphy.AddAttribute(NL80211Attr<uint32_t>(NL80211_ATTR_WIPHY,
285                                                kFakeWiphyIndex));
286
287   // Insert band information to mock netlink response.
288
289   NL80211NestedAttr freq_2g_1(1);
290   NL80211NestedAttr freq_2g_2(2);
291   NL80211NestedAttr freq_2g_3(3);
292   NL80211NestedAttr freq_5g_1(4);
293   NL80211NestedAttr freq_5g_2(5);
294   NL80211NestedAttr freq_dfs_1(6);
295   freq_2g_1.AddAttribute(NL80211Attr<uint32_t>(NL80211_FREQUENCY_ATTR_FREQ,
296                                                kFakeFrequency1));
297   freq_2g_2.AddAttribute(NL80211Attr<uint32_t>(NL80211_FREQUENCY_ATTR_FREQ,
298                                                kFakeFrequency2));
299   freq_2g_3.AddAttribute(NL80211Attr<uint32_t>(NL80211_FREQUENCY_ATTR_FREQ,
300                                                kFakeFrequency3));
301   freq_5g_1.AddAttribute(NL80211Attr<uint32_t>(NL80211_FREQUENCY_ATTR_FREQ,
302                                                kFakeFrequency4));
303   freq_5g_2.AddAttribute(NL80211Attr<uint32_t>(NL80211_FREQUENCY_ATTR_FREQ,
304                                                kFakeFrequency5));
305   // DFS frequency.
306   freq_dfs_1.AddAttribute(NL80211Attr<uint32_t>(NL80211_FREQUENCY_ATTR_FREQ,
307                                                 kFakeFrequency6));
308   freq_dfs_1.AddAttribute(NL80211Attr<uint32_t>(
309       NL80211_FREQUENCY_ATTR_DFS_STATE,
310       NL80211_DFS_USABLE));
311
312   NL80211NestedAttr band_2g_freqs(NL80211_BAND_ATTR_FREQS);
313   NL80211NestedAttr band_5g_freqs(NL80211_BAND_ATTR_FREQS);
314   band_2g_freqs.AddAttribute(freq_2g_1);
315   band_2g_freqs.AddAttribute(freq_2g_2);
316   band_2g_freqs.AddAttribute(freq_2g_3);
317   band_5g_freqs.AddAttribute(freq_5g_1);
318   band_5g_freqs.AddAttribute(freq_5g_2);
319   band_5g_freqs.AddAttribute(freq_dfs_1);
320
321   NL80211NestedAttr band_2g_attr(1);
322   NL80211NestedAttr band_5g_attr(2);
323   band_2g_attr.AddAttribute(band_2g_freqs);
324   band_5g_attr.AddAttribute(band_5g_freqs);
325
326   NL80211NestedAttr band_attr(NL80211_ATTR_WIPHY_BANDS);
327   band_attr.AddAttribute(band_2g_attr);
328   band_attr.AddAttribute(band_5g_attr);
329
330   new_wiphy.AddAttribute(band_attr);
331
332   // Insert scan capabilities to mock netlink response.
333   new_wiphy.AddAttribute(NL80211Attr<uint8_t>(NL80211_ATTR_MAX_NUM_SCAN_SSIDS,
334                                               kFakeMaxNumScanSSIDs));
335   new_wiphy.AddAttribute(NL80211Attr<uint8_t>(
336       NL80211_ATTR_MAX_NUM_SCHED_SCAN_SSIDS,
337       kFakeMaxNumSchedScanSSIDs));
338   new_wiphy.AddAttribute(NL80211Attr<uint8_t>(NL80211_ATTR_MAX_MATCH_SETS,
339                                               kFakeMaxMatchSets));
340
341   // Insert wiphy features to mock netlink response.
342   new_wiphy.AddAttribute(NL80211Attr<uint32_t>(
343       NL80211_ATTR_FEATURE_FLAGS,
344       NL80211_FEATURE_SCAN_RANDOM_MAC_ADDR));
345
346   vector<NL80211Packet> response = {new_wiphy};
347
348   EXPECT_CALL(*netlink_manager_, SendMessageAndGetResponses(_, _)).
349       WillOnce(DoAll(MakeupResponse(response), Return(true)));
350
351   BandInfo band_info;
352   ScanCapabilities scan_capabilities;
353   WiphyFeatures wiphy_features;
354   EXPECT_TRUE(netlink_utils_->GetWiphyInfo(kFakeWiphyIndex,
355                                            &band_info,
356                                            &scan_capabilities,
357                                            &wiphy_features));
358
359   // Verify band information.
360   vector<uint32_t> band_2g_expected = {kFakeFrequency1,
361       kFakeFrequency2, kFakeFrequency3};
362   vector<uint32_t> band_5g_expected = {kFakeFrequency4, kFakeFrequency5};
363   vector<uint32_t> band_dfs_expected = {kFakeFrequency6};
364   EXPECT_EQ(band_info.band_2g, band_2g_expected);
365   EXPECT_EQ(band_info.band_5g, band_5g_expected);
366   EXPECT_EQ(band_info.band_dfs, band_dfs_expected);
367
368   // Verify scan capabilities.
369   EXPECT_EQ(scan_capabilities.max_num_scan_ssids,
370             kFakeMaxNumScanSSIDs);
371   EXPECT_EQ(scan_capabilities.max_num_sched_scan_ssids,
372             kFakeMaxNumSchedScanSSIDs);
373   EXPECT_EQ(scan_capabilities.max_match_sets,
374             kFakeMaxMatchSets);
375
376   // Verify wiphy features.
377   EXPECT_TRUE(wiphy_features.supports_random_mac_oneshot_scan);
378   EXPECT_FALSE(wiphy_features.supports_random_mac_sched_scan);
379 }
380
381 TEST_F(NetlinkUtilsTest, CanHandleGetWiphyInfoError) {
382   // Mock an error response from kernel.
383   vector<NL80211Packet> response = {CreateControlMessageError(kFakeErrorCode)};
384
385   EXPECT_CALL(*netlink_manager_, SendMessageAndGetResponses(_, _)).
386       WillOnce(DoAll(MakeupResponse(response), Return(true)));
387
388   BandInfo band_info;
389   ScanCapabilities scan_capabilities;
390   WiphyFeatures wiphy_features;
391   EXPECT_FALSE(netlink_utils_->GetWiphyInfo(kFakeWiphyIndex,
392                                            &band_info,
393                                            &scan_capabilities,
394                                            &wiphy_features));
395 }
396
397 }  // namespace wificond
398 }  // namespace android