OSDN Git Service

Add wpa binder integration tests
authorRoshan Pius <rpius@google.com>
Thu, 7 Jul 2016 16:37:25 +0000 (09:37 -0700)
committerRoshan Pius <rpius@google.com>
Fri, 15 Jul 2016 17:51:57 +0000 (10:51 -0700)
Moving the wpa_supplicant binder interface integration tests to wificond.

These tests uses |gtests| and need to hardcode some strings for basic
verification of the binder interface. So, we probably don't want to put this in
wpa_supplicant's open source codebase.

BUG: 29877893
Change-Id: I778fceab418354e106ab36fb15fb9746a88c6947
TEST: Ran existings test on device: /data/wpa_binder_test

Android.mk
tests/integration/wpa_supplicant_binder/tests.cpp [new file with mode: 0644]

index bbe7dfd..7d71446 100644 (file)
@@ -148,3 +148,27 @@ LOCAL_STATIC_LIBRARIES := \
     libwificond_ipc \
     libwificond_test_utils
 include $(BUILD_NATIVE_TEST)
+
+###
+### wpa_supplicant binder integration tests.
+### (Compiled only when wpa_supplicant's binder interface is enabled)
+###
+ifeq ($(WPA_SUPPLICANT_USE_BINDER), y)
+include $(CLEAR_VARS)
+LOCAL_MODULE := wpa_supplicant_binder_test
+LOCAL_CPPFLAGS := $(wificond_cpp_flags)
+LOCAL_SRC_FILES := \
+    tests/main.cpp \
+    tests/integration/wpa_supplicant_binder/tests.cpp
+LOCAL_SHARED_LIBRARIES := \
+    libbase \
+    libbinder \
+    libcutils \
+    libutils \
+    libwifi-hal \
+    libwifi-system
+LOCAL_STATIC_LIBRARIES := \
+    libwificond_test_utils \
+    libwpa_binder_interface
+include $(BUILD_NATIVE_TEST)
+endif # WPA_SUPPLICANT_USE_BINDER == y
diff --git a/tests/integration/wpa_supplicant_binder/tests.cpp b/tests/integration/wpa_supplicant_binder/tests.cpp
new file mode 100644 (file)
index 0000000..4910cb9
--- /dev/null
@@ -0,0 +1,234 @@
+/*
+ * 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 <android-base/logging.h>
+#include <binder/IBinder.h>
+#include <binder/IServiceManager.h>
+#include <binder/PersistableBundle.h>
+#include <gtest/gtest.h>
+#include <utils/Errors.h>
+#include <utils/String16.h>
+#include <utils/StrongPointer.h>
+#include <wifi_hal/driver_tool.h>
+#include <wifi_system/interface_tool.h>
+#include <wifi_system/wifi.h>
+#include <wpa_supplicant_binder/binder_constants.h>
+
+#include <fi/w1/wpa_supplicant/IIface.h>
+#include <fi/w1/wpa_supplicant/ISupplicant.h>
+
+#include "tests/shell_utils.h"
+
+using android::wifi_hal::DriverTool;
+using android::wifi_system::InterfaceTool;
+using android::wificond::tests::integration::RunShellCommand;
+
+using fi::w1::wpa_supplicant::IIface;
+using fi::w1::wpa_supplicant::ISupplicant;
+
+namespace wpa_supplicant_binder {
+namespace {
+
+// Hardcoded values for test.
+const char kWlan0IfaceName[] = "wlan0";
+const char kP2p0IfaceName[] = "p2p0";
+const char kIfaceDriver[] = "nl80211";
+const char kIfaceConfigFile[] = "/data/misc/wifi/wpa_supplicant.conf";
+
+/**
+ * Base class for all wpa_supplicant binder interface testing.
+ * All the test classes should inherit from this class and invoke this base
+ * class |Setup| & |TearDown|.
+ *
+ * The |SetUp| method prepares the device for wpa_supplicant binder testing by
+ * stopping framework, reloading driver, restarting wpa_supplicant, etc.
+ */
+class WpaSupplicantBinderTest : public ::testing::Test {
+ protected:
+  WpaSupplicantBinderTest()
+      : ::testing::Test(),
+        iface_tool_(new InterfaceTool()),
+        driver_tool_(new DriverTool()) {}
+
+  /**
+   * Steps performed before each test:
+   * 1. Stop android framework.
+   * 2. Stop |wificond|.
+   * 3. Stop |wpa_supplicant|.
+   * 4. Unload the driver.
+   * 5. Load the driver.
+   * 6. Set the firmware in Sta mode. (TODO: Ap mode for some tests).
+   * 7. Set the wlan0 interface up.
+   * 8. Start wpa_supplicant.
+   * 9. Wait for wpa_supplicant binder service to be registered.
+   * 10. Remove the |wlan0| & |p2p0| interface from wpa_supplicant.
+   *
+   * TODO: We can't fully nuke the existing wpa_supplicant.conf file because
+   * there are some device specific parameters stored there needed for
+   * wpa_supplicant to work properly.
+   */
+  void SetUp() override {
+    RunShellCommand("stop");
+    RunShellCommand("stop wificond");
+    EXPECT_TRUE(android::wifi_system::wifi_stop_supplicant(false) == 0);
+    EXPECT_TRUE(driver_tool_->UnloadDriver());
+    EXPECT_TRUE(driver_tool_->LoadDriver());
+    EXPECT_TRUE(driver_tool_->ChangeFirmwareMode(DriverTool::kFirmwareModeSta));
+    EXPECT_TRUE(iface_tool_->SetWifiUpState(true));
+    EXPECT_TRUE(android::wifi_system::wifi_start_supplicant(false) == 0);
+    waitForBinderServiceRegistration();
+    removeAllInterfaces();
+  }
+
+  /**
+   * Steps performed after each test:
+   * 1. Stop |wpa_supplicant|.
+   * 2. Unload the driver.
+   * 3. Start |wificond|.
+   * 4. Start android framework.
+   *
+   * Assuming that android framework will perform the necessary steps after
+   * this to put the device in working state.
+   */
+  void TearDown() override {
+    EXPECT_TRUE(android::wifi_system::wifi_stop_supplicant(false) == 0);
+    EXPECT_TRUE(driver_tool_->UnloadDriver());
+    RunShellCommand("start wificond");
+    RunShellCommand("start");
+  }
+
+  /**
+   * Retrieve reference to wpa_supplicant's binder service.
+   */
+  android::sp<ISupplicant> getBinderService() {
+    android::sp<android::IBinder> service =
+        android::defaultServiceManager()->checkService(
+            android::String16(binder_constants::kServiceName));
+    return android::interface_cast<ISupplicant>(service);
+  }
+
+  /**
+   * Checks if wpa_supplicant's binder service is registered and visible.
+   */
+  bool IsBinderServiceRegistered() {
+    return getBinderService().get() != nullptr;
+  }
+
+  /**
+   * Creates a network interface for test using the hardcoded params:
+   * |kWlan0IfaceName|, |kIfaceDriver|, |kIfaceConfigFile|.
+   */
+  android::sp<IIface> CreateInterfaceForTest() {
+    android::os::PersistableBundle params;
+    params.putString(android::String16("Ifname"),
+                     android::String16(kWlan0IfaceName));
+    params.putString(android::String16("Driver"),
+                     android::String16(kIfaceDriver));
+    params.putString(android::String16("ConfigFile"),
+                     android::String16(kIfaceConfigFile));
+
+    android::sp<IIface> iface;
+    android::binder::Status status = service_->CreateInterface(params, &iface);
+    EXPECT_TRUE((status.isOk()) && (iface.get() != nullptr));
+    return iface;
+  }
+
+  /**
+   * Removes the network interface created using |CreateInterfaceForTest|.
+   */
+  void RemoveInterfaceForTest() {
+    android::binder::Status status = service_->RemoveInterface(kWlan0IfaceName);
+    EXPECT_TRUE(status.isOk());
+  }
+
+  android::sp<ISupplicant> service_;
+
+ private:
+  /**
+   * Waits in a loop for a maximum of 10 milliseconds for the binder service to
+   * be registered.
+   */
+  void waitForBinderServiceRegistration() {
+    for (int tries = 0; tries < 10; tries++) {
+      if (IsBinderServiceRegistered()) {
+        break;
+      }
+      usleep(1000);
+    }
+    service_ = getBinderService();
+    // Ensure that the service is available. This is needed for all tests.
+    EXPECT_TRUE(service_.get() != nullptr);
+  }
+
+  /**
+   * Removes all the interfaces (|wlan0| & |p2p0|) controlled by
+   * |wpa_supplicant|.
+   * wpa_supplicant is started with |wlan0| and |p2p0| assigned in init.rc.
+   */
+  void removeAllInterfaces() {
+    android::sp<IIface> iface;
+    // TODO: Add a service->ListInterfaces() to retrieve all the available
+    // interfaces.
+    android::binder::Status status =
+        service_->GetInterface(kWlan0IfaceName, &iface);
+    if (status.isOk() && iface.get() != nullptr) {
+      status = service_->RemoveInterface(kWlan0IfaceName);
+      EXPECT_TRUE(status.isOk());
+    }
+    status = service_->GetInterface(kP2p0IfaceName, &iface);
+    if (status.isOk() && iface.get() != nullptr) {
+      status = service_->RemoveInterface(kP2p0IfaceName);
+      EXPECT_TRUE(status.isOk());
+    }
+  }
+
+  std::unique_ptr<InterfaceTool> iface_tool_;
+  std::unique_ptr<DriverTool> driver_tool_;
+
+};  // class WpaSupplicantBinderTest
+}  // namespace
+
+/**
+ * Verifies the |ISupplicant.CreateInterface| binder call.
+ */
+TEST_F(WpaSupplicantBinderTest, CreateInterface) {
+  // Create the interface.
+  CreateInterfaceForTest();
+
+  android::sp<IIface> iface;
+  android::binder::Status status =
+      service_->GetInterface(kWlan0IfaceName, &iface);
+  EXPECT_TRUE((status.isOk()) && (iface.get() != nullptr));
+}
+
+/**
+ * Verifies the |ISupplicant.RemoveInterface| binder call.
+ */
+TEST_F(WpaSupplicantBinderTest, RemoveInterface) {
+  // Create the interface first.
+  CreateInterfaceForTest();
+
+  // Now remove the interface.
+  RemoveInterfaceForTest();
+
+  // The interface should no longer be present now.
+  android::sp<IIface> iface;
+  android::binder::Status status =
+      service_->GetInterface(kWlan0IfaceName, &iface);
+  EXPECT_TRUE(status.serviceSpecificErrorCode() ==
+              ISupplicant::ERROR_IFACE_UNKNOWN);
+}
+}  // namespace wpa_supplicant_binder