scanner_unittest.cpp revision c6ecdf8ea59f7de47edfd6161f059b8ab45d1f8f
1/*
2 * Copyright (C) 2017, 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 <vector>
18
19#include <gmock/gmock.h>
20#include <gtest/gtest.h>
21#include <wifi_system_test/mock_interface_tool.h>
22#include <wifi_system_test/mock_supplicant_manager.h>
23
24#include "wificond/scanning/offload/offload_scan_utils.h"
25#include "wificond/scanning/scanner_impl.h"
26#include "wificond/tests/mock_client_interface_impl.h"
27#include "wificond/tests/mock_netlink_manager.h"
28#include "wificond/tests/mock_netlink_utils.h"
29#include "wificond/tests/mock_offload_scan_callback_interface_impl.h"
30#include "wificond/tests/mock_offload_scan_manager.h"
31#include "wificond/tests/mock_offload_service_utils.h"
32#include "wificond/tests/mock_scan_utils.h"
33#include "wificond/tests/offload_test_utils.h"
34
35using ::android::binder::Status;
36using ::android::wifi_system::MockInterfaceTool;
37using ::com::android::server::wifi::wificond::SingleScanSettings;
38using ::com::android::server::wifi::wificond::PnoSettings;
39using ::com::android::server::wifi::wificond::NativeScanResult;
40using android::hardware::wifi::offload::V1_0::ScanResult;
41using ::testing::Invoke;
42using ::testing::NiceMock;
43using ::testing::Return;
44using ::testing::_;
45using std::shared_ptr;
46using std::unique_ptr;
47using std::vector;
48
49using namespace std::placeholders;
50
51namespace android {
52namespace wificond {
53
54namespace {
55
56constexpr uint32_t kFakeInterfaceIndex = 12;
57constexpr uint32_t kFakeScanIntervalMs = 10000;
58
59// This is a helper function to mock the behavior of ScanUtils::Scan()
60// when we expect a error code.
61// |interface_index_ignored|, |request_random_mac_ignored|, |ssids_ignored|,
62// |freqs_ignored|, |error_code| are mapped to existing parameters of ScanUtils::Scan().
63// |mock_error_code| is a additional parameter used for specifying expected error code.
64bool ReturnErrorCodeForScanRequest(
65    int mock_error_code,
66    uint32_t interface_index_ignored,
67    bool request_random_mac_ignored,
68    const std::vector<std::vector<uint8_t>>& ssids_ignored,
69    const std::vector<uint32_t>& freqs_ignored,
70    int* error_code) {
71  *error_code = mock_error_code;
72  // Returing false because this helper function is used for failure case.
73  return false;
74}
75
76bool CaptureSchedScanIntervalSetting(
77    uint32_t /* interface_index */,
78    const SchedScanIntervalSetting&  interval_setting,
79    int32_t /* rssi_threshold_2g */,
80    int32_t /* rssi_threshold_5g */,
81    bool /* request_random_mac */,
82    const  std::vector<std::vector<uint8_t>>& /* scan_ssids */,
83    const std::vector<std::vector<uint8_t>>& /* match_ssids */,
84    const  std::vector<uint32_t>& /* freqs */,
85    int* /* error_code */,
86    SchedScanIntervalSetting* out_interval_setting) {
87  *out_interval_setting = interval_setting;
88  return true;
89}
90
91bool ReturnOffloadScanResults(
92    std::vector<NativeScanResult>* native_scan_results_,
93    const std::vector<ScanResult>& offload_scan_results) {
94  return OffloadScanUtils::convertToNativeScanResults(offload_scan_results,
95                                                      native_scan_results_);
96}
97
98bool ReturnNetlinkScanResults(
99    uint32_t interface_index,
100    std::vector<NativeScanResult>* native_scan_results_,
101    const std::vector<ScanResult>& offload_scan_results) {
102  return OffloadScanUtils::convertToNativeScanResults(offload_scan_results,
103                                                      native_scan_results_);
104}
105
106}  // namespace
107
108class ScannerTest : public ::testing::Test {
109 protected:
110  void SetUp() override {
111    ON_CALL(*offload_service_utils_, GetOffloadScanManager(_, _))
112        .WillByDefault(Return(offload_scan_manager_));
113    ON_CALL(*offload_service_utils_, GetOffloadScanCallbackInterface(_))
114        .WillByDefault(Return(offload_scan_callback_interface_));
115    dummy_scan_results_ = OffloadTestUtils::createOffloadScanResults();
116  }
117
118  void TearDown() override { dummy_scan_results_.clear(); }
119
120  unique_ptr<ScannerImpl> scanner_impl_;
121  NiceMock<MockNetlinkManager> netlink_manager_;
122  NiceMock<MockNetlinkUtils> netlink_utils_{&netlink_manager_};
123  NiceMock<MockScanUtils> scan_utils_{&netlink_manager_};
124  NiceMock<MockInterfaceTool> if_tool_;
125  NiceMock<MockClientInterfaceImpl> client_interface_impl_{
126      &if_tool_, &netlink_utils_, &scan_utils_};
127  shared_ptr<NiceMock<MockOffloadServiceUtils>> offload_service_utils_{
128      new NiceMock<MockOffloadServiceUtils>()};
129  shared_ptr<NiceMock<MockOffloadScanCallbackInterfaceImpl>>
130      offload_scan_callback_interface_{
131          new NiceMock<MockOffloadScanCallbackInterfaceImpl>(
132              scanner_impl_.get())};
133  std::shared_ptr<NiceMock<MockOffloadScanManager>> offload_scan_manager_{
134      new NiceMock<MockOffloadScanManager>(offload_service_utils_,
135                                           offload_scan_callback_interface_)};
136  ScanCapabilities scan_capabilities_;
137  WiphyFeatures wiphy_features_;
138  std::vector<ScanResult> dummy_scan_results_;
139};
140
141TEST_F(ScannerTest, TestSingleScan) {
142  EXPECT_CALL(scan_utils_, Scan(_, _, _, _, _)).WillOnce(Return(true));
143  bool success = false;
144  scanner_impl_.reset(new ScannerImpl(kFakeInterfaceIndex,
145                                      scan_capabilities_, wiphy_features_,
146                                      &client_interface_impl_,
147                                      &scan_utils_, offload_service_utils_));
148  EXPECT_TRUE(scanner_impl_->scan(SingleScanSettings(), &success).isOk());
149  EXPECT_TRUE(success);
150}
151
152TEST_F(ScannerTest, TestSingleScanFailure) {
153  scanner_impl_.reset(new ScannerImpl(kFakeInterfaceIndex,
154                                      scan_capabilities_, wiphy_features_,
155                                      &client_interface_impl_,
156                                      &scan_utils_, offload_service_utils_));
157  EXPECT_CALL(
158      scan_utils_,
159      Scan(_, _, _, _, _)).
160          WillOnce(Invoke(bind(
161              ReturnErrorCodeForScanRequest, EBUSY, _1, _2, _3, _4, _5)));
162
163  bool success = false;
164  EXPECT_TRUE(scanner_impl_->scan(SingleScanSettings(), &success).isOk());
165  EXPECT_FALSE(success);
166}
167
168TEST_F(ScannerTest, TestProcessAbortsOnScanReturningNoDeviceError) {
169  scanner_impl_.reset(new ScannerImpl(kFakeInterfaceIndex,
170                                      scan_capabilities_, wiphy_features_,
171                                      &client_interface_impl_,
172                                      &scan_utils_, offload_service_utils_));
173  ON_CALL(
174      scan_utils_,
175      Scan(_, _, _, _, _)).
176          WillByDefault(Invoke(bind(
177              ReturnErrorCodeForScanRequest, ENODEV, _1, _2, _3, _4, _5)));
178
179  bool success_ignored;
180  EXPECT_DEATH(scanner_impl_->scan(SingleScanSettings(), &success_ignored),
181               "Driver is in a bad state*");
182}
183
184TEST_F(ScannerTest, TestAbortScan) {
185  bool single_scan_success = false;
186  scanner_impl_.reset(new ScannerImpl(kFakeInterfaceIndex,
187                                      scan_capabilities_, wiphy_features_,
188                                      &client_interface_impl_,
189                                      &scan_utils_, offload_service_utils_));
190  EXPECT_CALL(scan_utils_, Scan(_, _, _, _, _)).WillOnce(Return(true));
191  EXPECT_TRUE(
192      scanner_impl_->scan(SingleScanSettings(), &single_scan_success).isOk());
193  EXPECT_TRUE(single_scan_success);
194
195  EXPECT_CALL(scan_utils_, AbortScan(_));
196  EXPECT_TRUE(scanner_impl_->abortScan().isOk());
197}
198
199TEST_F(ScannerTest, TestAbortScanNotIssuedIfNoOngoingScan) {
200  scanner_impl_.reset(new ScannerImpl(kFakeInterfaceIndex,
201                                      scan_capabilities_, wiphy_features_,
202                                      &client_interface_impl_,
203                                      &scan_utils_, offload_service_utils_));
204  EXPECT_CALL(scan_utils_, AbortScan(_)).Times(0);
205  EXPECT_TRUE(scanner_impl_->abortScan().isOk());
206}
207
208TEST_F(ScannerTest, TestGetScanResults) {
209  vector<NativeScanResult> scan_results;
210  scanner_impl_.reset(new ScannerImpl(kFakeInterfaceIndex,
211                                      scan_capabilities_, wiphy_features_,
212                                      &client_interface_impl_,
213                                      &scan_utils_, offload_service_utils_));
214  EXPECT_CALL(scan_utils_, GetScanResult(_, _)).WillOnce(Return(true));
215  EXPECT_TRUE(scanner_impl_->getScanResults(&scan_results).isOk());
216}
217
218TEST_F(ScannerTest, TestStartPnoScanViaNetlink) {
219  bool success = false;
220  EXPECT_CALL(*offload_service_utils_, IsOffloadScanSupported())
221      .Times(1)
222      .WillRepeatedly(Return(false));
223  scanner_impl_.reset(new ScannerImpl(kFakeInterfaceIndex,
224                                      scan_capabilities_, wiphy_features_,
225                                      &client_interface_impl_,
226                                      &scan_utils_, offload_service_utils_));
227  EXPECT_CALL(scan_utils_, StartScheduledScan(_, _, _, _, _, _, _, _, _))
228              .WillOnce(Return(true));
229  EXPECT_TRUE(scanner_impl_->startPnoScan(PnoSettings(), &success).isOk());
230  EXPECT_TRUE(success);
231}
232
233TEST_F(ScannerTest, TestStopPnoScanViaNetlink) {
234  bool success = false;
235  EXPECT_CALL(*offload_service_utils_, IsOffloadScanSupported())
236      .Times(1)
237      .WillRepeatedly(Return(false));
238  scanner_impl_.reset(new ScannerImpl(kFakeInterfaceIndex,
239                                      scan_capabilities_, wiphy_features_,
240                                      &client_interface_impl_,
241                                      &scan_utils_, offload_service_utils_));
242  // StopScheduledScan() will be called no matter if there is an ongoing
243  // scheduled scan or not. This is for making the system more robust.
244  EXPECT_CALL(scan_utils_, StopScheduledScan(_)).WillOnce(Return(true));
245  EXPECT_TRUE(scanner_impl_->stopPnoScan(&success).isOk());
246  EXPECT_TRUE(success);
247}
248
249TEST_F(ScannerTest, TestStartScanOverOffload) {
250  bool success = false;
251  EXPECT_CALL(*offload_service_utils_, IsOffloadScanSupported())
252      .Times(1)
253      .WillRepeatedly(Return(true));
254  EXPECT_CALL(*offload_scan_manager_, startScan(_, _, _, _, _, _, _))
255      .Times(1)
256      .WillRepeatedly(Return(true));
257  EXPECT_CALL(*offload_scan_manager_, stopScan(_))
258      .Times(1)
259      .WillRepeatedly(Return(true));
260  scanner_impl_.reset(new ScannerImpl(kFakeInterfaceIndex,
261                                      scan_capabilities_, wiphy_features_,
262                                      &client_interface_impl_,
263                                      &scan_utils_, offload_service_utils_));
264  scanner_impl_->startPnoScan(PnoSettings(), &success);
265  EXPECT_TRUE(success);
266  scanner_impl_->stopPnoScan(&success);
267  EXPECT_TRUE(success);
268}
269
270TEST_F(ScannerTest, TestStartScanOverNetlinkFallback) {
271  bool success = false;
272  ON_CALL(*offload_service_utils_, IsOffloadScanSupported())
273      .WillByDefault(Return(true));
274  scanner_impl_.reset(new ScannerImpl(kFakeInterfaceIndex,
275                                      scan_capabilities_, wiphy_features_,
276                                      &client_interface_impl_,
277                                      &scan_utils_, offload_service_utils_));
278  EXPECT_CALL(*offload_scan_manager_, startScan(_, _, _, _, _, _, _))
279      .WillOnce(Return(false));
280  EXPECT_CALL(*offload_scan_manager_, stopScan(_)).Times(0);
281  EXPECT_CALL(scan_utils_, StartScheduledScan(_, _, _, _, _, _, _, _, _))
282      .WillOnce(Return(true));
283  EXPECT_CALL(scan_utils_, StopScheduledScan(_)).WillOnce(Return(true));
284  EXPECT_TRUE(scanner_impl_->startPnoScan(PnoSettings(), &success).isOk());
285  EXPECT_TRUE(success == true);
286  scanner_impl_->stopPnoScan(&success);
287  EXPECT_TRUE(success);
288}
289
290TEST_F(ScannerTest, TestAsyncErrorOverOffload) {
291  bool success = false;
292  EXPECT_CALL(*offload_service_utils_, IsOffloadScanSupported())
293      .Times(1)
294      .WillRepeatedly(Return(true));
295  EXPECT_CALL(*offload_scan_manager_, startScan(_, _, _, _, _, _, _))
296      .Times(1)
297      .WillRepeatedly(Return(true));
298  EXPECT_CALL(*offload_scan_manager_, stopScan(_))
299      .Times(1)
300      .WillRepeatedly(Return(true));
301  scanner_impl_.reset(new ScannerImpl(kFakeInterfaceIndex,
302                                      scan_capabilities_, wiphy_features_,
303                                      &client_interface_impl_,
304                                      &scan_utils_, offload_service_utils_));
305  EXPECT_CALL(scan_utils_, StartScheduledScan(_, _, _, _, _, _, _, _, _))
306      .WillOnce(Return(true));
307  EXPECT_CALL(scan_utils_, StopScheduledScan(_)).WillOnce(Return(true));
308  scanner_impl_->startPnoScan(PnoSettings(), &success);
309  EXPECT_TRUE(success);
310  scanner_impl_->OnOffloadError(
311      OffloadScanCallbackInterface::AsyncErrorReason::REMOTE_FAILURE);
312  scanner_impl_->stopPnoScan(&success);
313  EXPECT_TRUE(success);
314}
315
316TEST_F(ScannerTest, TestGetScanResultsFromOffload) {
317  bool success = false;
318  EXPECT_CALL(*offload_service_utils_, IsOffloadScanSupported())
319      .Times(1)
320      .WillRepeatedly(Return(true));
321  EXPECT_CALL(*offload_scan_manager_, startScan(_, _, _, _, _, _, _))
322      .Times(1)
323      .WillRepeatedly(Return(true));
324  EXPECT_CALL(*offload_scan_manager_, getScanResults(_))
325      .Times(1)
326      .WillOnce(
327          Invoke(bind(ReturnOffloadScanResults, _1, dummy_scan_results_)));
328  EXPECT_CALL(*offload_scan_manager_, stopScan(_))
329      .Times(1)
330      .WillRepeatedly(Return(true));
331  scanner_impl_.reset(new ScannerImpl(kFakeInterfaceIndex,
332                                      scan_capabilities_, wiphy_features_,
333                                      &client_interface_impl_,
334                                      &scan_utils_, offload_service_utils_));
335  scanner_impl_->startPnoScan(PnoSettings(), &success);
336  EXPECT_TRUE(success);
337  scanner_impl_->OnOffloadScanResult();
338  std::vector<NativeScanResult> scan_results;
339  EXPECT_TRUE(scanner_impl_->getPnoScanResults(&scan_results).isOk());
340  EXPECT_FALSE(scan_results.empty());
341  scanner_impl_->stopPnoScan(&success);
342  EXPECT_TRUE(success);
343}
344
345TEST_F(ScannerTest, TestGetScanResultsWhenOffloadFails) {
346  bool success = false;
347  EXPECT_CALL(*offload_service_utils_, IsOffloadScanSupported())
348      .Times(1)
349      .WillRepeatedly(Return(true));
350  EXPECT_CALL(*offload_scan_manager_, startScan(_, _, _, _, _, _, _))
351      .Times(1)
352      .WillRepeatedly(Return(true));
353  EXPECT_CALL(*offload_scan_manager_, stopScan(_))
354      .Times(1)
355      .WillRepeatedly(Return(true));
356  EXPECT_CALL(*offload_scan_manager_, getScanResults(_)).Times(0);
357  EXPECT_CALL(scan_utils_, GetScanResult(_, _))
358      .Times(1)
359      .WillOnce(
360          Invoke(bind(ReturnNetlinkScanResults, _1, _2, dummy_scan_results_)));
361  scanner_impl_.reset(new ScannerImpl(kFakeInterfaceIndex,
362                                      scan_capabilities_, wiphy_features_,
363                                      &client_interface_impl_,
364                                      &scan_utils_, offload_service_utils_));
365  EXPECT_CALL(scan_utils_, StartScheduledScan(_, _, _, _, _, _, _, _, _))
366      .WillOnce(Return(true));
367  EXPECT_CALL(scan_utils_, StopScheduledScan(_)).WillOnce(Return(true));
368  EXPECT_TRUE(scanner_impl_->startPnoScan(PnoSettings(), &success).isOk());
369  EXPECT_TRUE(success);
370  scanner_impl_->OnOffloadError(
371      OffloadScanCallbackInterface::AsyncErrorReason::REMOTE_FAILURE);
372  std::vector<NativeScanResult> scan_results;
373  EXPECT_TRUE(scanner_impl_->getPnoScanResults(&scan_results).isOk());
374  EXPECT_FALSE(scan_results.empty());
375  scanner_impl_->stopPnoScan(&success);
376  EXPECT_TRUE(success);
377}
378
379TEST_F(ScannerTest, TestGenerateScanPlansIfDeviceSupports) {
380  ScanCapabilities scan_capabilities_scan_plan_supported(
381      0 /* max_num_scan_ssids */,
382      0 /* max_num_sched_scan_ssids */,
383      0 /* max_match_sets */,
384      // Parameters above are not related to this test.
385      2 /* 1 plan for finite repeated scan and 1 plan for ininfite scan loop */,
386      kFakeScanIntervalMs * PnoSettings::kSlowScanIntervalMultiplier / 1000,
387      PnoSettings::kFastScanIterations);
388  ScannerImpl scanner(
389      kFakeInterfaceIndex,
390      scan_capabilities_scan_plan_supported, wiphy_features_,
391      &client_interface_impl_,
392      &scan_utils_, offload_service_utils_);
393
394  PnoSettings pno_settings;
395  pno_settings.interval_ms_ = kFakeScanIntervalMs;
396
397  SchedScanIntervalSetting interval_setting;
398  EXPECT_CALL(
399      scan_utils_,
400      StartScheduledScan(_, _, _, _, _, _, _, _, _)).
401              WillOnce(Invoke(bind(
402                  CaptureSchedScanIntervalSetting,
403                  _1, _2, _3, _4, _5, _6, _7, _8, _9, &interval_setting)));
404
405  bool success_ignored = 0;
406  EXPECT_TRUE(scanner.startPnoScan(pno_settings, &success_ignored).isOk());
407  /* 1 plan for finite repeated scan */
408  EXPECT_EQ(1U, interval_setting.plans.size());
409  EXPECT_EQ(kFakeScanIntervalMs * PnoSettings::kSlowScanIntervalMultiplier,
410            interval_setting.final_interval_ms);
411}
412
413TEST_F(ScannerTest, TestGenerateSingleIntervalIfDeviceDoesNotSupportScanPlan) {
414  ScanCapabilities scan_capabilities_no_scan_plan_support(
415      0 /* max_num_scan_ssids */,
416      0 /* max_num_sched_scan_ssids */,
417      0 /* max_match_sets */,
418      // Parameters above are not related to this test.
419      0 /* max_num_scan_plans */,
420      0 /* max_scan_plan_interval */,
421      0 /* max_scan_plan_iterations */);
422  ScannerImpl scanner(
423      kFakeInterfaceIndex,
424      scan_capabilities_no_scan_plan_support, wiphy_features_,
425      &client_interface_impl_,
426      &scan_utils_, offload_service_utils_);
427  PnoSettings pno_settings;
428  pno_settings.interval_ms_ = kFakeScanIntervalMs;
429
430  SchedScanIntervalSetting interval_setting;
431  EXPECT_CALL(
432      scan_utils_,
433      StartScheduledScan(_, _, _, _, _, _, _, _, _)).
434              WillOnce(Invoke(bind(
435                  CaptureSchedScanIntervalSetting,
436                  _1, _2, _3, _4, _5, _6, _7, _8, _9, &interval_setting)));
437
438  bool success_ignored = 0;
439  EXPECT_TRUE(scanner.startPnoScan(pno_settings, &success_ignored).isOk());
440
441  EXPECT_EQ(0U, interval_setting.plans.size());
442  EXPECT_EQ(kFakeScanIntervalMs, interval_setting.final_interval_ms);
443}
444
445}  // namespace wificond
446}  // namespace android
447