scan_utils_unittest.cpp revision 8f62fdd7479506aa865560941d74dc4e4c77e1b3
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 <functional> 18#include <memory> 19#include <vector> 20 21#include <linux/netlink.h> 22#include <linux/nl80211.h> 23 24#include <gtest/gtest.h> 25 26#include "wificond/scanning/scan_result.h" 27#include "wificond/scanning/scan_utils.h" 28#include "wificond/tests/mock_netlink_manager.h" 29 30using std::bind; 31using std::placeholders::_1; 32using std::placeholders::_2; 33using std::unique_ptr; 34using std::vector; 35using testing::Invoke; 36using testing::NiceMock; 37using testing::Return; 38using testing::_; 39 40using com::android::server::wifi::wificond::NativeScanResult; 41 42namespace android { 43namespace wificond { 44 45namespace { 46 47constexpr uint32_t kFakeInterfaceIndex = 12; 48constexpr uint32_t kFakeScheduledScanIntervalMs = 20000; 49constexpr uint32_t kFakeSequenceNumber = 1984; 50constexpr int kFakeErrorCode = EIO; 51constexpr int32_t kFakeRssiThreshold = -80; 52constexpr bool kFakeUseRandomMAC = true; 53 54// Currently, control messages are only created by the kernel and sent to us. 55// Therefore NL80211Packet doesn't have corresponding constructor. 56// For test we manually create control messages using this helper function. 57NL80211Packet CreateControlMessageError(int error_code) { 58 vector<uint8_t> data; 59 data.resize(NLMSG_HDRLEN + NLA_ALIGN(sizeof(int)), 0); 60 // Initialize length field. 61 nlmsghdr* nl_header = reinterpret_cast<nlmsghdr*>(data.data()); 62 nl_header->nlmsg_len = data.size(); 63 nl_header->nlmsg_type = NLMSG_ERROR; 64 nl_header->nlmsg_seq = kFakeSequenceNumber; 65 nl_header->nlmsg_pid = getpid(); 66 int* error_field = reinterpret_cast<int*>(data.data() + NLMSG_HDRLEN); 67 *error_field = -error_code; 68 69 return NL80211Packet(data); 70} 71 72NL80211Packet CreateControlMessageAck() { 73 return CreateControlMessageError(0); 74} 75 76// This is a helper function to mock the behavior of NetlinkManager:: 77// SendMessageAndGetResponses() when we expect a single packet response. 78// |request_message| and |response| are mapped to existing parameters of 79// SendMessageAndGetResponses(). 80// |mock_response| and |mock_return value| are additional parameters used 81// for specifying expected results, 82bool AppendMessageAndReturn( 83 NL80211Packet& mock_response, 84 bool mock_return_value, 85 const NL80211Packet& request_message, 86 vector<std::unique_ptr<const NL80211Packet>>* response) { 87 response->push_back(std::make_unique<NL80211Packet>(mock_response)); 88 return mock_return_value; 89} 90 91} // namespace 92 93class ScanUtilsTest : public ::testing::Test { 94 protected: 95 virtual void SetUp() { 96 ON_CALL(netlink_manager_, 97 SendMessageAndGetResponses(_, _)).WillByDefault(Return(true)); 98 } 99 100 NiceMock<MockNetlinkManager> netlink_manager_; 101 ScanUtils scan_utils_{&netlink_manager_}; 102}; 103 104MATCHER_P(DoesNL80211PacketMatchCommand, command, 105 "Check if the netlink packet matches |command|") { 106 return arg.GetCommand() == command; 107} 108 109TEST_F(ScanUtilsTest, CanGetScanResult) { 110 vector<NativeScanResult> scan_results; 111 EXPECT_CALL( 112 netlink_manager_, 113 SendMessageAndGetResponses( 114 DoesNL80211PacketMatchCommand(NL80211_CMD_GET_SCAN), _)); 115 116 // We don't use EXPECT_TRUE here because we need to mock a complete 117 // response for NL80211_CMD_GET_SCAN to satisfy the parsing code called 118 // by GetScanResult. 119 // TODO(b/34231002): Mock response for NL80211_CMD_GET_SCAN. 120 // TODO(b/34231420): Add validation of interface index. 121 scan_utils_.GetScanResult(kFakeInterfaceIndex, &scan_results); 122} 123 124TEST_F(ScanUtilsTest, CanSendScanRequest) { 125 NL80211Packet response = CreateControlMessageAck(); 126 EXPECT_CALL( 127 netlink_manager_, 128 SendMessageAndGetResponses( 129 DoesNL80211PacketMatchCommand(NL80211_CMD_TRIGGER_SCAN), _)). 130 WillOnce(Invoke(bind( 131 AppendMessageAndReturn, response, true, _1, _2))); 132 133 EXPECT_TRUE(scan_utils_.Scan(kFakeInterfaceIndex, kFakeUseRandomMAC, {}, {})); 134 // TODO(b/34231420): Add validation of requested scan ssids, threshold, 135 // and frequencies. 136} 137 138TEST_F(ScanUtilsTest, CanHandleScanRequestFailure) { 139 NL80211Packet response = CreateControlMessageError(kFakeErrorCode); 140 EXPECT_CALL( 141 netlink_manager_, 142 SendMessageAndGetResponses( 143 DoesNL80211PacketMatchCommand(NL80211_CMD_TRIGGER_SCAN), _)). 144 WillOnce(Invoke(bind( 145 AppendMessageAndReturn, response, true, _1, _2))); 146 EXPECT_FALSE(scan_utils_.Scan(kFakeInterfaceIndex, kFakeUseRandomMAC, {}, {})); 147} 148 149TEST_F(ScanUtilsTest, CanSendSchedScanRequest) { 150 NL80211Packet response = CreateControlMessageAck(); 151 EXPECT_CALL( 152 netlink_manager_, 153 SendMessageAndGetResponses( 154 DoesNL80211PacketMatchCommand(NL80211_CMD_START_SCHED_SCAN), _)). 155 WillOnce(Invoke(bind( 156 AppendMessageAndReturn, response, true, _1, _2))); 157 EXPECT_TRUE(scan_utils_.StartScheduledScan( 158 kFakeInterfaceIndex, 159 kFakeScheduledScanIntervalMs, 160 kFakeRssiThreshold, kFakeUseRandomMAC, {}, {}, {})); 161 // TODO(b/34231420): Add validation of requested scan ssids, threshold, 162 // and frequencies. 163} 164 165TEST_F(ScanUtilsTest, CanHandleSchedScanRequestFailure) { 166 NL80211Packet response = CreateControlMessageError(kFakeErrorCode); 167 EXPECT_CALL( 168 netlink_manager_, 169 SendMessageAndGetResponses( 170 DoesNL80211PacketMatchCommand(NL80211_CMD_START_SCHED_SCAN), _)). 171 WillOnce(Invoke(bind( 172 AppendMessageAndReturn, response, true, _1, _2))); 173 EXPECT_FALSE(scan_utils_.StartScheduledScan( 174 kFakeInterfaceIndex, 175 kFakeScheduledScanIntervalMs, 176 kFakeRssiThreshold, kFakeUseRandomMAC, {}, {}, {})); 177} 178 179} // namespace wificond 180} // namespace android 181