Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 522e62d5 authored by Roshan Pius's avatar Roshan Pius
Browse files

supplicant(vts): Add gtest framework

Bug: 33457575
Test: adb push
out/target/product/angler/data/nativetest/supplicant_hidl_test/supplicant_hidl_test
/data/ &&  adb shell /data/supplicant_hidl_test
Change-Id: I8b560483166822a33b8d81433178fdbc6077ec11
parent ab16b319
Loading
Loading
Loading
Loading
+43 −0
Original line number Diff line number Diff line
#
# 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.
#
LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)
LOCAL_MODULE := supplicant_hidl_test
LOCAL_CPPFLAGS := -Wall -Werror -Wextra
LOCAL_SRC_FILES := \
    main.cpp \
    supplicant_hidl_test.cpp \
    supplicant_hidl_test_utils.cpp \
    supplicant_p2p_iface_hidl_test.cpp \
    supplicant_sta_iface_hidl_test.cpp \
    supplicant_sta_network_hidl_test.cpp
LOCAL_SHARED_LIBRARIES := \
    android.hardware.wifi.supplicant@1.0 \
    libbase \
    libcutils \
    libhidlbase \
    libhidltransport \
    libhwbinder \
    liblog \
    libutils \
    libwifi-hal \
    libwifi-system
LOCAL_STATIC_LIBRARIES := \
    libgmock \
    libgtest
include $(BUILD_NATIVE_TEST)
+41 −0
Original line number Diff line number Diff line
/*
 * 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 <gtest/gtest.h>

#include "supplicant_hidl_test_utils.h"

class SupplicantHidlEnvironment : public ::testing::Environment {
   public:
    virtual void SetUp() override {
        stopWifiFramework();
        stopSupplicant();
    }
    virtual void TearDown() override {
        startWifiFramework();
        // Framework will start wpa_supplicant.
    }
};

int main(int argc, char** argv) {
    ::testing::AddGlobalTestEnvironment(new SupplicantHidlEnvironment);
    ::testing::InitGoogleTest(&argc, argv);
    int status = RUN_ALL_TESTS();
    LOG(INFO) << "Test result = " << status;
    return status;
}
+32 −0
Original line number Diff line number Diff line
/*
 * 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 <gtest/gtest.h>

#include "supplicant_hidl_test_utils.h"

/*
 * Create:
 * Ensures that an instance of the ISupplicant proxy object is
 * successfully created.
 */
TEST(SupplicantHidlTestNoFixture, Create) {
    startSupplicantAndWaitForHidlService();
    EXPECT_NE(nullptr, getSupplicant().get());
    stopSupplicant();
}
+267 −0
Original line number Diff line number Diff line
/*
 * 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 <gtest/gtest.h>

#include <hidl/HidlTransportSupport.h>
#include <android/hidl/manager/1.0/IServiceManager.h>
#include <android/hidl/manager/1.0/IServiceNotification.h>

#include <wifi_hal/driver_tool.h>
#include <wifi_system/interface_tool.h>
#include <wifi_system/supplicant_manager.h>

#include "supplicant_hidl_test_utils.h"

using ::android::sp;
using ::android::hardware::configureRpcThreadpool;
using ::android::hardware::joinRpcThreadpool;
using ::android::hardware::hidl_string;
using ::android::hardware::hidl_vec;
using ::android::hardware::Return;
using ::android::hardware::Void;
using ::android::hardware::wifi::supplicant::V1_0::ISupplicant;
using ::android::hardware::wifi::supplicant::V1_0::ISupplicantIface;
using ::android::hardware::wifi::supplicant::V1_0::ISupplicantNetwork;
using ::android::hardware::wifi::supplicant::V1_0::ISupplicantStaIface;
using ::android::hardware::wifi::supplicant::V1_0::ISupplicantStaNetwork;
using ::android::hardware::wifi::supplicant::V1_0::ISupplicantP2pIface;
using ::android::hardware::wifi::supplicant::V1_0::IfaceType;
using ::android::hardware::wifi::supplicant::V1_0::SupplicantStatus;
using ::android::hardware::wifi::supplicant::V1_0::SupplicantStatusCode;
using ::android::hidl::manager::V1_0::IServiceNotification;
using ::android::wifi_hal::DriverTool;
using ::android::wifi_system::InterfaceTool;
using ::android::wifi_system::SupplicantManager;

namespace {
const char kSupplicantServiceName[] = "wpa_supplicant";

// Helper function to initialize the driver and firmware to STA mode.
void initilializeDriverAndFirmware() {
    DriverTool driver_tool;
    InterfaceTool iface_tool;
    EXPECT_TRUE(driver_tool.LoadDriver());
    EXPECT_TRUE(driver_tool.ChangeFirmwareMode(DriverTool::kFirmwareModeSta));
    EXPECT_TRUE(iface_tool.SetWifiUpState(true));
}

// Helper function to find any iface of the desired type exposed.
bool findIfaceOfType(sp<ISupplicant> supplicant, IfaceType desired_type,
                     ISupplicant::IfaceInfo* out_info) {
    bool operation_failed = false;
    std::vector<ISupplicant::IfaceInfo> iface_infos;
    supplicant->listInterfaces([&](const SupplicantStatus& status,
                                   hidl_vec<ISupplicant::IfaceInfo> infos) {
        if (status.code != SupplicantStatusCode::SUCCESS) {
            operation_failed = true;
            return;
        }
        iface_infos = infos;
    });
    if (operation_failed) {
        return false;
    }
    for (const auto& info : iface_infos) {
        if (info.type == desired_type) {
            *out_info = info;
            return true;
        }
    }
    return false;
}
}  // namespace

// Utility class to wait for wpa_supplicant's HIDL service registration.
class ServiceNotificationListener : public IServiceNotification {
   public:
    Return<void> onRegistration(const hidl_string& fully_qualified_name,
                                const hidl_string& instance_name,
                                bool pre_existing) override {
        if (pre_existing) {
            return Void();
        }
        std::unique_lock<std::mutex> lock(mutex_);
        registered_.push_back(std::string(fully_qualified_name.c_str()) + "/" +
                              instance_name.c_str());
        lock.unlock();
        condition_.notify_one();
        return Void();
    }

    bool registerForHidlServiceNotifications(const std::string& instance_name) {
        if (!ISupplicant::registerForNotifications(instance_name, this)) {
            return false;
        }
        configureRpcThreadpool(2, false);
        return true;
    }

    bool waitForHidlService(uint32_t timeout_in_millis,
                            const std::string& instance_name) {
        std::unique_lock<std::mutex> lock(mutex_);
        condition_.wait_for(lock, std::chrono::milliseconds(timeout_in_millis),
                            [&]() { return registered_.size() >= 1; });
        if (registered_.size() != 1) {
            return false;
        }
        std::string exptected_registered =
            std::string(ISupplicant::descriptor) + "/" + instance_name;
        if (registered_[0] != exptected_registered) {
            LOG(ERROR) << "Expected: " << exptected_registered
                       << ", Got: " << registered_[0];
            return false;
        }
        return true;
    }

   private:
    std::vector<std::string> registered_{};
    std::mutex mutex_;
    std::condition_variable condition_;
};

void stopWifiFramework() {
    ASSERT_EQ(std::system("svc wifi disable"), 0);
    // TODO: Use some other mechanism to wait for the framework to
    // finish disabling.
    sleep(5);
}

void startWifiFramework() {
    ASSERT_EQ(std::system("svc wifi enable"), 0);
    // These tests don't care whether the framework
    // finished enabling or not.
}

void stopSupplicant() {
    DriverTool driver_tool;
    SupplicantManager supplicant_manager;

    ASSERT_TRUE(supplicant_manager.StopSupplicant());
    ASSERT_TRUE(driver_tool.UnloadDriver());
    ASSERT_FALSE(supplicant_manager.IsSupplicantRunning());
}

void startSupplicantAndWaitForHidlService() {
    initilializeDriverAndFirmware();

    android::sp<ServiceNotificationListener> notification_listener =
        new ServiceNotificationListener();
    ASSERT_TRUE(notification_listener->registerForHidlServiceNotifications(
        kSupplicantServiceName));

    SupplicantManager supplicant_manager;
    ASSERT_TRUE(supplicant_manager.StartSupplicant());
    ASSERT_TRUE(supplicant_manager.IsSupplicantRunning());

    ASSERT_TRUE(
        notification_listener->waitForHidlService(200, kSupplicantServiceName));
}

sp<ISupplicant> getSupplicant() {
    return ISupplicant::getService(kSupplicantServiceName);
}

sp<ISupplicantStaIface> getSupplicantStaIface() {
    sp<ISupplicant> supplicant = getSupplicant();
    if (!supplicant.get()) {
        return nullptr;
    }
    ISupplicant::IfaceInfo info;
    if (!findIfaceOfType(supplicant, IfaceType::STA, &info)) {
        return nullptr;
    }
    bool operation_failed = false;
    sp<ISupplicantStaIface> sta_iface;
    supplicant->getInterface(info, [&](const SupplicantStatus& status,
                                       const sp<ISupplicantIface>& iface) {
        if (status.code != SupplicantStatusCode::SUCCESS) {
            operation_failed = true;
            return;
        }
        sta_iface = ISupplicantStaIface::castFrom(iface);
    });
    if (operation_failed) {
        return nullptr;
    }
    return sta_iface;
}

sp<ISupplicantStaNetwork> createSupplicantStaNetwork() {
    sp<ISupplicantStaIface> sta_iface = getSupplicantStaIface();
    if (!sta_iface.get()) {
        return nullptr;
    }
    bool operation_failed = false;
    sp<ISupplicantStaNetwork> sta_network;
    sta_iface->addNetwork([&](const SupplicantStatus& status,
                              const sp<ISupplicantNetwork>& network) {
        if (status.code != SupplicantStatusCode::SUCCESS) {
            operation_failed = true;
            return;
        }
        sta_network = ISupplicantStaNetwork::castFrom(network);
    });
    if (operation_failed) {
        return nullptr;
    }
    return sta_network;
}

sp<ISupplicantP2pIface> getSupplicantP2pIface() {
    sp<ISupplicant> supplicant = getSupplicant();
    if (!supplicant.get()) {
        return nullptr;
    }
    ISupplicant::IfaceInfo info;
    if (!findIfaceOfType(supplicant, IfaceType::P2P, &info)) {
        return nullptr;
    }
    bool operation_failed = false;
    sp<ISupplicantP2pIface> p2p_iface;
    supplicant->getInterface(info, [&](const SupplicantStatus& status,
                                       const sp<ISupplicantIface>& iface) {
        if (status.code != SupplicantStatusCode::SUCCESS) {
            operation_failed = true;
            return;
        }
        p2p_iface = ISupplicantP2pIface::castFrom(iface);
    });
    if (operation_failed) {
        return nullptr;
    }
    return p2p_iface;
}

bool turnOnExcessiveLogging() {
    sp<ISupplicant> supplicant = getSupplicant();
    if (!supplicant.get()) {
        return false;
    }
    bool operation_failed = false;
    supplicant->setDebugParams(
        ISupplicant::DebugLevel::EXCESSIVE,
        true,  // show timestamps
        true,  // show keys
        [&](const SupplicantStatus& status) {
            if (status.code != SupplicantStatusCode::SUCCESS) {
                operation_failed = true;
            }
        });
    return !operation_failed;
}
+48 −0
Original line number Diff line number Diff line
/*
 * 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.
 */

#ifndef SUPPLICANT_HIDL_TEST_UTILS_H
#define SUPPLICANT_HIDL_TEST_UTILS_H

#include <android/hardware/wifi/supplicant/1.0/ISupplicant.h>
#include <android/hardware/wifi/supplicant/1.0/ISupplicantP2pIface.h>
#include <android/hardware/wifi/supplicant/1.0/ISupplicantStaIface.h>
#include <android/hardware/wifi/supplicant/1.0/ISupplicantStaNetwork.h>

// Used to stop the android wifi framework before every test.
void stopWifiFramework();
void startWifiFramework();
void stopSupplicant();
// Used to configure the chip, driver and start wpa_supplicant before every
// test.
void startSupplicantAndWaitForHidlService();

// Helper functions to obtain references to the various HIDL interface objects.
// Note: We only have a single instance of each of these objects currently.
// These helper functions should be modified to return vectors if we support
// multiple instances.
android::sp<android::hardware::wifi::supplicant::V1_0::ISupplicant>
getSupplicant();
android::sp<android::hardware::wifi::supplicant::V1_0::ISupplicantStaIface>
getSupplicantStaIface();
android::sp<android::hardware::wifi::supplicant::V1_0::ISupplicantStaNetwork>
createSupplicantStaNetwork();
android::sp<android::hardware::wifi::supplicant::V1_0::ISupplicantP2pIface>
getSupplicantP2pIface();

bool turnOnExcessiveLogging();

#endif /* SUPPLICANT_HIDL_TEST_UTILS_H */
Loading