From bbcf938a09448569647fa640e34f68c9fff86a58 Mon Sep 17 00:00:00 2001 From: Roshan Pius Date: Thu, 7 Jul 2016 09:37:25 -0700 Subject: [PATCH] Add wpa binder integration tests 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 | 24 +++ tests/integration/wpa_supplicant_binder/tests.cpp | 234 ++++++++++++++++++++++ 2 files changed, 258 insertions(+) create mode 100644 tests/integration/wpa_supplicant_binder/tests.cpp diff --git a/Android.mk b/Android.mk index bbe7dfd..7d71446 100644 --- a/Android.mk +++ b/Android.mk @@ -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 index 0000000..4910cb9 --- /dev/null +++ b/tests/integration/wpa_supplicant_binder/tests.cpp @@ -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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#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 getBinderService() { + android::sp service = + android::defaultServiceManager()->checkService( + android::String16(binder_constants::kServiceName)); + return android::interface_cast(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 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 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 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 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 iface_tool_; + std::unique_ptr driver_tool_; + +}; // class WpaSupplicantBinderTest +} // namespace + +/** + * Verifies the |ISupplicant.CreateInterface| binder call. + */ +TEST_F(WpaSupplicantBinderTest, CreateInterface) { + // Create the interface. + CreateInterfaceForTest(); + + android::sp 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 iface; + android::binder::Status status = + service_->GetInterface(kWlan0IfaceName, &iface); + EXPECT_TRUE(status.serviceSpecificErrorCode() == + ISupplicant::ERROR_IFACE_UNKNOWN); +} +} // namespace wpa_supplicant_binder -- 2.11.0