OSDN Git Service

Add unit tests for wificond ScanUtils am: 65b365fe4b
authorNingyuan Wang <nywang@google.com>
Thu, 19 Jan 2017 02:36:33 +0000 (02:36 +0000)
committerandroid-build-merger <android-build-merger@google.com>
Thu, 19 Jan 2017 02:36:33 +0000 (02:36 +0000)
am: e3463a7c28

Change-Id: Ie3a4b1dc5dae543b987cf74792788740ad66e4b6

Android.mk
scanning/scan_utils.h
tests/scan_utils_unittest.cpp [new file with mode: 0644]

index eb2dfe2..c070d57 100644 (file)
@@ -13,7 +13,7 @@
 # limitations under the License.
 
 LOCAL_PATH := $(call my-dir)
-wificond_cpp_flags := -std=c++11 -Wall -Werror -Wno-unused-parameter
+wificond_cpp_flags := -Wall -Werror -Wno-unused-parameter
 # TODO(b/33211652): Remove once ScannerImpl is fleshed out.
 wificond_cpp_flags += -Wno-unused-private-field
 wificond_parent_dir := $(LOCAL_PATH)/../
@@ -159,6 +159,7 @@ LOCAL_SRC_FILES := \
     tests/nl80211_packet_unittest.cpp \
     tests/scan_result_unittest.cpp \
     tests/scan_settings_unittest.cpp \
+    tests/scan_utils_unittest.cpp \
     tests/server_unittest.cpp
 LOCAL_STATIC_LIBRARIES := \
     libgmock \
index 5a865ea..da1011a 100644 (file)
@@ -88,7 +88,7 @@ class ScanUtils {
   // Only BSSs match the |match_ssids| and |rssi_threshold| will be returned as
   // scan results.
   // Returns true on success.
-  bool StartScheduledScan(
+  virtual bool StartScheduledScan(
       uint32_t interface_index,
       uint32_t interval_ms,
       int32_t rssi_threshold,
diff --git a/tests/scan_utils_unittest.cpp b/tests/scan_utils_unittest.cpp
new file mode 100644 (file)
index 0000000..3cfca96
--- /dev/null
@@ -0,0 +1,199 @@
+/*
+ * Copyright (C) 2016, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <functional>
+#include <memory>
+#include <vector>
+
+#include <linux/netlink.h>
+#include <linux/nl80211.h>
+
+#include <gtest/gtest.h>
+
+#include "wificond/scanning/scan_result.h"
+#include "wificond/scanning/scan_utils.h"
+#include "wificond/tests/mock_netlink_manager.h"
+
+using std::bind;
+using std::placeholders::_1;
+using std::placeholders::_2;
+using std::unique_ptr;
+using std::vector;
+using testing::Invoke;
+using testing::NiceMock;
+using testing::Return;
+using testing::_;
+
+using com::android::server::wifi::wificond::NativeScanResult;
+
+namespace android {
+namespace wificond {
+
+namespace {
+
+constexpr uint32_t kFakeInterfaceIndex = 12;
+constexpr uint32_t kFakeScheduledScanIntervalMs = 20000;
+constexpr uint32_t kFakeSequenceNumber = 1984;
+constexpr int kFakeErrorCode = EIO;
+constexpr int32_t kFakeRssiThreshold = -80;
+
+// Currently, control messages are only created by the kernel and sent to us.
+// Therefore NL80211Packet doesn't have corresponding constructor.
+// For test we manually create control messages using this helper function.
+NL80211Packet CreateControlMessageError(int error_code) {
+  vector<uint8_t> data;
+  data.resize(NLMSG_HDRLEN + NLA_ALIGN(sizeof(int)), 0);
+  // Initialize length field.
+  nlmsghdr* nl_header = reinterpret_cast<nlmsghdr*>(data.data());
+  nl_header->nlmsg_len = data.size();
+  nl_header->nlmsg_type = NLMSG_ERROR;
+  nl_header->nlmsg_seq = kFakeSequenceNumber;
+  nl_header->nlmsg_pid = getpid();
+  int* error_field = reinterpret_cast<int*>(data.data() + NLMSG_HDRLEN);
+  *error_field = -error_code;
+
+  return NL80211Packet(data);
+}
+
+NL80211Packet CreateControlMessageAck() {
+  return CreateControlMessageError(0);
+}
+
+// This is a helper function to mock the behavior of NetlinkManager::
+// SendMessageAndGetResponses() when we expect a single packet response.
+// |request_message| and |response| are mapped to existing parameters of
+// SendMessageAndGetResponses().
+// |mock_response| and |mock_return value| are additional parameters used
+// for specifying expected results,
+bool AppendMessageAndReturn(
+    NL80211Packet& mock_response,
+    bool mock_return_value,
+    const NL80211Packet& request_message,
+    vector<std::unique_ptr<const NL80211Packet>>* response) {
+  response->push_back(std::make_unique<NL80211Packet>(mock_response));
+  return mock_return_value;
+}
+
+}  // namespace
+
+class ScanUtilsTest : public ::testing::Test {
+ protected:
+  virtual void SetUp() {
+    ON_CALL(netlink_manager_,
+            SendMessageAndGetResponses(_, _)).WillByDefault(Return(true));
+  }
+
+  NiceMock<MockNetlinkManager> netlink_manager_;
+  ScanUtils scan_utils_{&netlink_manager_};
+};
+
+MATCHER_P(DoesNL80211PacketMatchCommand, command,
+          "Check if the netlink packet matches |command|") {
+  return arg.GetCommand() == command;
+}
+
+TEST_F(ScanUtilsTest, CanGetScanResult) {
+  vector<NativeScanResult> scan_results;
+  EXPECT_CALL(
+      netlink_manager_,
+      SendMessageAndGetResponses(
+          DoesNL80211PacketMatchCommand(NL80211_CMD_GET_SCAN), _));
+
+  // We don't use EXPECT_TRUE here because we need to mock a complete
+  // response for NL80211_CMD_GET_SCAN to satisfy the parsing code called
+  // by GetScanResult.
+  // TODO(b/34231002): Mock response for NL80211_CMD_GET_SCAN.
+  // TODO(b/34231420): Add validation of interface index.
+  scan_utils_.GetScanResult(kFakeInterfaceIndex, &scan_results);
+}
+
+TEST_F(ScanUtilsTest, CanSendScanRequest) {
+  NL80211Packet response = CreateControlMessageAck();
+  EXPECT_CALL(
+      netlink_manager_,
+      SendMessageAndGetResponses(
+          DoesNL80211PacketMatchCommand(NL80211_CMD_TRIGGER_SCAN), _)).
+              WillOnce(Invoke(bind(
+                  AppendMessageAndReturn, response, true, _1, _2)));
+
+  EXPECT_TRUE(scan_utils_.Scan(kFakeInterfaceIndex, {}, {}));
+  // TODO(b/34231420): Add validation of requested scan ssids, threshold,
+  // and frequencies.
+}
+
+TEST_F(ScanUtilsTest, CanHandleScanRequestFailure) {
+  NL80211Packet response = CreateControlMessageError(kFakeErrorCode);
+  EXPECT_CALL(
+      netlink_manager_,
+      SendMessageAndGetResponses(
+          DoesNL80211PacketMatchCommand(NL80211_CMD_TRIGGER_SCAN), _)).
+              WillOnce(Invoke(bind(
+                  AppendMessageAndReturn, response, true, _1, _2)));
+  EXPECT_FALSE(scan_utils_.Scan(kFakeInterfaceIndex, {}, {}));
+}
+
+TEST_F(ScanUtilsTest, CanSendSchedScanRequest) {
+  NL80211Packet response = CreateControlMessageAck();
+  EXPECT_CALL(
+      netlink_manager_,
+       SendMessageAndGetResponses(
+           DoesNL80211PacketMatchCommand(NL80211_CMD_START_SCHED_SCAN), _)).
+              WillOnce(Invoke(bind(
+                  AppendMessageAndReturn, response, true, _1, _2)));
+  EXPECT_TRUE(scan_utils_.StartScheduledScan(
+      kFakeInterfaceIndex,
+      kFakeScheduledScanIntervalMs, kFakeRssiThreshold, {}, {}, {}));
+  // TODO(b/34231420): Add validation of requested scan ssids, threshold,
+  // and frequencies.
+}
+
+TEST_F(ScanUtilsTest, CanHandleSchedScanRequestFailure) {
+  NL80211Packet response = CreateControlMessageError(kFakeErrorCode);
+  EXPECT_CALL(
+      netlink_manager_,
+       SendMessageAndGetResponses(
+           DoesNL80211PacketMatchCommand(NL80211_CMD_START_SCHED_SCAN), _)).
+              WillOnce(Invoke(bind(
+                  AppendMessageAndReturn, response, true, _1, _2)));
+  EXPECT_FALSE(scan_utils_.StartScheduledScan(
+      kFakeInterfaceIndex,
+      kFakeScheduledScanIntervalMs, kFakeRssiThreshold, {}, {}, {}));
+}
+
+TEST_F(ScanUtilsTest, CanSendFullScanRequest) {
+  NL80211Packet response = CreateControlMessageAck();
+  EXPECT_CALL(
+      netlink_manager_,
+      SendMessageAndGetResponses(
+          DoesNL80211PacketMatchCommand(NL80211_CMD_TRIGGER_SCAN), _)).
+              WillOnce(Invoke(bind(
+                  AppendMessageAndReturn, response, true, _1, _2)));
+  EXPECT_TRUE(scan_utils_.StartFullScan(kFakeInterfaceIndex));
+}
+
+TEST_F(ScanUtilsTest, CanHandleFullScanRequestFailure) {
+  NL80211Packet response = CreateControlMessageError(kFakeErrorCode);
+  EXPECT_CALL(
+      netlink_manager_,
+      SendMessageAndGetResponses(
+          DoesNL80211PacketMatchCommand(NL80211_CMD_TRIGGER_SCAN), _)).
+              WillOnce(Invoke(bind(
+                  AppendMessageAndReturn, response, true, _1, _2)));
+  EXPECT_FALSE(scan_utils_.StartFullScan(kFakeInterfaceIndex));
+}
+
+}  // namespace wificond
+}  // namespace android