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

Commit c37306ea authored by Patrik Fimml's avatar Patrik Fimml
Browse files

Wifi VTS: use VTS-native feature detection

Previously, VTS would run VtsHalWifiV1_0HostTest, a python script on the
host that tries identify whether SoftAP and NAN should be supported by
the device. This is complex, prevents migration to pure gtests without
custom runners, and duplicates logic that has become available in VTS.

This switches to equivalent methods natively available in VTS:
- NAN: We can use "precondition-feature" to check for the
"android.hardware.wifi.aware" feature.
- SoftAP: We can use "precondition-lshal" to check whether the
"android.hardware.wifi.hostapd" HAL is declared in the device manifest
(should have the same semantics as the previous python check).

This splits out NAN- and SoftAP-dependent parts of IWifiChip tests so
that they can use this method, so some tests moved between these targets:
- VtsHalWifiV1_0TargetTest
- VtsHalWifiApV1_0TargetTest
- VtsHalWifiNanV1_0TargetTest

Bug: 142304083
Test: vts-tradefed run vts --primary-abi-only --skip-device-info -l DEBUG --include-filter VtsHalWifiV1_0Target --include-filter VtsHalWifiApV1_0Target --include-filter VtsHalWifiNanV1_0Target --include-filter VtsHalWifiV1_1Target --include-filter VtsHalWifiV1_2Target --include-filter VtsHalWifiV1_3Target --include-filter VtsHalWifiApV1_4Target
Change-Id: Ica0b58811a0aa152c1a6c3c9a35d577d6ae70160
parent 03d81e7b
Loading
Loading
Loading
Loading
+23 −2
Original line number Diff line number Diff line
@@ -28,7 +28,9 @@ cc_library_static {
    shared_libs: [
        "libnativehelper",
    ],
    static_libs: ["android.hardware.wifi@1.0"],
    static_libs: [
        "android.hardware.wifi@1.0",
    ],
}

cc_test {
@@ -36,7 +38,6 @@ cc_test {
    defaults: ["VtsHalTargetTestDefaults"],
    srcs: [
        "VtsHalWifiV1_0TargetTest.cpp",
        "wifi_ap_iface_hidl_test.cpp",
        "wifi_chip_hidl_test.cpp",
        "wifi_p2p_iface_hidl_test.cpp",
        "wifi_rtt_controller_hidl_test.cpp",
@@ -52,11 +53,14 @@ cc_test {
    test_suites: ["general-tests"],
}

// These tests are split out so that they can be conditioned on presence of the
// "android.hardware.wifi.aware" feature.
cc_test {
    name: "VtsHalWifiNanV1_0TargetTest",
    defaults: ["VtsHalTargetTestDefaults"],
    srcs: [
        "VtsHalWifiV1_0TargetTest.cpp",
        "wifi_chip_hidl_nan_test.cpp",
        "wifi_nan_iface_hidl_test.cpp",
    ],
    static_libs: [
@@ -65,3 +69,20 @@ cc_test {
    ],
    test_suites: ["general-tests"],
}

// These tests are split out so that they can be conditioned on presence of
// the hostapd HAL, which indicates SoftAP support.
cc_test {
    name: "VtsHalWifiApV1_0TargetTest",
    defaults: ["VtsHalTargetTestDefaults"],
    srcs: [
        "VtsHalWifiV1_0TargetTest.cpp",
        "wifi_ap_iface_hidl_test.cpp",
        "wifi_chip_hidl_ap_test.cpp",
    ],
    static_libs: [
        "VtsHalWifiV1_0TargetTestUtil",
        "android.hardware.wifi@1.0",
    ],
    test_suites: ["general-tests"],
}
+2 −5
Original line number Diff line number Diff line
@@ -41,10 +41,7 @@ int main(int argc, char** argv) {
    ::testing::AddGlobalTestEnvironment(gEnv);
    ::testing::InitGoogleTest(&argc, argv);
    gEnv->init(&argc, argv);
    int status = gEnv->initFromOptions(argc, argv);
    if (status == 0) {
        status = RUN_ALL_TESTS();
    int status = RUN_ALL_TESTS();
    LOG(INFO) << "Test result = " << status;
    }
    return status;
}
+0 −8
Original line number Diff line number Diff line
@@ -29,21 +29,17 @@ using ::android::hardware::wifi::V1_0::WifiBand;
using ::android::hardware::wifi::V1_0::WifiStatusCode;
using ::android::sp;

extern WifiHidlEnvironment* gEnv;

/**
 * Fixture to use for all AP Iface HIDL interface tests.
 */
class WifiApIfaceHidlTest : public ::testing::VtsHalHidlTargetTestBase {
   public:
    virtual void SetUp() override {
        if (!gEnv->isSoftApOn) return;
        wifi_ap_iface_ = getWifiApIface();
        ASSERT_NE(nullptr, wifi_ap_iface_.get());
    }

    virtual void TearDown() override {
        if (!gEnv->isSoftApOn) return;
        stopWifi();
    }

@@ -57,7 +53,6 @@ class WifiApIfaceHidlTest : public ::testing::VtsHalHidlTargetTestBase {
 * successfully created.
 */
TEST(WifiApIfaceHidlTestNoFixture, Create) {
    if (!gEnv->isSoftApOn) return;
    EXPECT_NE(nullptr, getWifiApIface().get());
    stopWifi();
}
@@ -67,7 +62,6 @@ TEST(WifiApIfaceHidlTestNoFixture, Create) {
 * Ensures that the correct interface type is returned for AP interface.
 */
TEST_F(WifiApIfaceHidlTest, GetType) {
    if (!gEnv->isSoftApOn) return;
    const auto& status_and_type = HIDL_INVOKE(wifi_ap_iface_, getType);
    EXPECT_EQ(WifiStatusCode::SUCCESS, status_and_type.first.code);
    EXPECT_EQ(IfaceType::AP, status_and_type.second);
@@ -79,7 +73,6 @@ TEST_F(WifiApIfaceHidlTest, GetType) {
 * status code.
 */
TEST_F(WifiApIfaceHidlTest, SetCountryCode) {
    if (!gEnv->isSoftApOn) return;
    const android::hardware::hidl_array<int8_t, 2> kCountryCode{
        std::array<int8_t, 2>{{0x55, 0x53}}};
    EXPECT_EQ(WifiStatusCode::SUCCESS,
@@ -91,7 +84,6 @@ TEST_F(WifiApIfaceHidlTest, SetCountryCode) {
 * Ensures that we can retrieve valid frequencies for 2.4 GHz band.
 */
TEST_F(WifiApIfaceHidlTest, GetValidFrequenciesForBand) {
    if (!gEnv->isSoftApOn) return;
    const auto& status_and_freqs = HIDL_INVOKE(
        wifi_ap_iface_, getValidFrequenciesForBand, WifiBand::BAND_24GHZ);
    EXPECT_EQ(WifiStatusCode::SUCCESS, status_and_freqs.first.code);
+168 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2019 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 <android/hardware/wifi/1.0/IWifiChip.h>

#include <VtsHalHidlTargetTestBase.h>

#include "wifi_hidl_call_util.h"
#include "wifi_hidl_test_utils.h"

using ::android::sp;
using ::android::hardware::wifi::V1_0::ChipModeId;
using ::android::hardware::wifi::V1_0::IfaceType;
using ::android::hardware::wifi::V1_0::IWifiApIface;
using ::android::hardware::wifi::V1_0::IWifiChip;
using ::android::hardware::wifi::V1_0::IWifiIface;
using ::android::hardware::wifi::V1_0::WifiStatus;
using ::android::hardware::wifi::V1_0::WifiStatusCode;

/**
 * Fixture for IWifiChip tests that are conditioned on SoftAP support.
 */
class WifiChipHidlApTest : public ::testing::VtsHalHidlTargetTestBase {
   public:
    virtual void SetUp() override {
        wifi_chip_ = getWifiChip();
        ASSERT_NE(nullptr, wifi_chip_.get());
    }

    virtual void TearDown() override { stopWifi(); }

   protected:
    // Helper function to configure the Chip in one of the supported modes.
    // Most of the non-mode-configuration-related methods require chip
    // to be first configured.
    ChipModeId configureChipForIfaceType(IfaceType type, bool expectSuccess) {
        ChipModeId mode_id;
        EXPECT_EQ(expectSuccess,
                  configureChipToSupportIfaceType(wifi_chip_, type, &mode_id));
        return mode_id;
    }

    std::string getIfaceName(const sp<IWifiIface>& iface) {
        const auto& status_and_name = HIDL_INVOKE(iface, getName);
        EXPECT_EQ(WifiStatusCode::SUCCESS, status_and_name.first.code);
        return status_and_name.second;
    }

    WifiStatusCode createApIface(sp<IWifiApIface>* ap_iface) {
        const auto& status_and_iface = HIDL_INVOKE(wifi_chip_, createApIface);
        *ap_iface = status_and_iface.second;
        return status_and_iface.first.code;
    }

    WifiStatusCode removeApIface(const std::string& name) {
        return HIDL_INVOKE(wifi_chip_, removeApIface, name).code;
    }

    sp<IWifiChip> wifi_chip_;
};

/*
 * CreateApIface
 * Configures the chip in AP mode and ensures that at least 1 iface creation
 * succeeds.
 */
TEST_F(WifiChipHidlApTest, CreateApIface) {
    configureChipForIfaceType(IfaceType::AP, true);

    sp<IWifiApIface> iface;
    EXPECT_EQ(WifiStatusCode::SUCCESS, createApIface(&iface));
    EXPECT_NE(nullptr, iface.get());
}

/*
 * GetApIfaceNames
 * Configures the chip in AP mode and ensures that the iface list is empty
 * before creating the iface. Then, create the iface and ensure that
 * iface name is returned via the list.
 */
TEST_F(WifiChipHidlApTest, GetApIfaceNames) {
    configureChipForIfaceType(IfaceType::AP, true);

    const auto& status_and_iface_names1 =
        HIDL_INVOKE(wifi_chip_, getApIfaceNames);
    EXPECT_EQ(WifiStatusCode::SUCCESS, status_and_iface_names1.first.code);
    EXPECT_EQ(0u, status_and_iface_names1.second.size());

    sp<IWifiApIface> iface;
    EXPECT_EQ(WifiStatusCode::SUCCESS, createApIface(&iface));
    EXPECT_NE(nullptr, iface.get());

    std::string iface_name = getIfaceName(iface);
    const auto& status_and_iface_names2 =
        HIDL_INVOKE(wifi_chip_, getApIfaceNames);
    EXPECT_EQ(WifiStatusCode::SUCCESS, status_and_iface_names2.first.code);
    EXPECT_EQ(1u, status_and_iface_names2.second.size());
    EXPECT_EQ(iface_name, status_and_iface_names2.second[0]);

    EXPECT_EQ(WifiStatusCode::SUCCESS, removeApIface(iface_name));
    const auto& status_and_iface_names3 =
        HIDL_INVOKE(wifi_chip_, getApIfaceNames);
    EXPECT_EQ(WifiStatusCode::SUCCESS, status_and_iface_names3.first.code);
    EXPECT_EQ(0u, status_and_iface_names3.second.size());
}

/*
 * GetApIface
 * Configures the chip in AP mode and create an iface. Then, retrieve
 * the iface object using the correct name and ensure any other name
 * doesn't retrieve an iface object.
 */
TEST_F(WifiChipHidlApTest, GetApIface) {
    configureChipForIfaceType(IfaceType::AP, true);

    sp<IWifiApIface> ap_iface;
    EXPECT_EQ(WifiStatusCode::SUCCESS, createApIface(&ap_iface));
    EXPECT_NE(nullptr, ap_iface.get());

    std::string iface_name = getIfaceName(ap_iface);
    const auto& status_and_iface1 =
        HIDL_INVOKE(wifi_chip_, getApIface, iface_name);
    EXPECT_EQ(WifiStatusCode::SUCCESS, status_and_iface1.first.code);
    EXPECT_NE(nullptr, status_and_iface1.second.get());

    std::string invalid_name = iface_name + "0";
    const auto& status_and_iface2 =
        HIDL_INVOKE(wifi_chip_, getApIface, invalid_name);
    EXPECT_EQ(WifiStatusCode::ERROR_INVALID_ARGS, status_and_iface2.first.code);
    EXPECT_EQ(nullptr, status_and_iface2.second.get());
}

/*
 * RemoveApIface
 * Configures the chip in AP mode and create an iface. Then, remove
 * the iface object using the correct name and ensure any other name
 * doesn't remove the iface.
 */
TEST_F(WifiChipHidlApTest, RemoveApIface) {
    configureChipForIfaceType(IfaceType::AP, true);

    sp<IWifiApIface> ap_iface;
    EXPECT_EQ(WifiStatusCode::SUCCESS, createApIface(&ap_iface));
    EXPECT_NE(nullptr, ap_iface.get());

    std::string iface_name = getIfaceName(ap_iface);
    std::string invalid_name = iface_name + "0";
    EXPECT_EQ(WifiStatusCode::ERROR_INVALID_ARGS, removeApIface(invalid_name));
    EXPECT_EQ(WifiStatusCode::SUCCESS, removeApIface(iface_name));

    // No such iface exists now. So, this should return failure.
    EXPECT_EQ(WifiStatusCode::ERROR_INVALID_ARGS, removeApIface(iface_name));
}
+169 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2019 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 <android/hardware/wifi/1.0/IWifiChip.h>

#include <VtsHalHidlTargetTestBase.h>

#include "wifi_hidl_call_util.h"
#include "wifi_hidl_test_utils.h"

using ::android::sp;
using ::android::hardware::wifi::V1_0::ChipModeId;
using ::android::hardware::wifi::V1_0::IfaceType;
using ::android::hardware::wifi::V1_0::IWifiChip;
using ::android::hardware::wifi::V1_0::IWifiIface;
using ::android::hardware::wifi::V1_0::IWifiNanIface;
using ::android::hardware::wifi::V1_0::WifiStatus;
using ::android::hardware::wifi::V1_0::WifiStatusCode;

/**
 * Fixture for IWifiChip tests that are conditioned on NAN support.
 */
class WifiChipHidlNanTest : public ::testing::VtsHalHidlTargetTestBase {
   public:
    virtual void SetUp() override {
        wifi_chip_ = getWifiChip();
        ASSERT_NE(nullptr, wifi_chip_.get());
    }

    virtual void TearDown() override { stopWifi(); }

   protected:
    // Helper function to configure the Chip in one of the supported modes.
    // Most of the non-mode-configuration-related methods require chip
    // to be first configured.
    ChipModeId configureChipForIfaceType(IfaceType type, bool expectSuccess) {
        ChipModeId mode_id;
        EXPECT_EQ(expectSuccess,
                  configureChipToSupportIfaceType(wifi_chip_, type, &mode_id));
        return mode_id;
    }

    std::string getIfaceName(const sp<IWifiIface>& iface) {
        const auto& status_and_name = HIDL_INVOKE(iface, getName);
        EXPECT_EQ(WifiStatusCode::SUCCESS, status_and_name.first.code);
        return status_and_name.second;
    }

    WifiStatusCode createNanIface(sp<IWifiNanIface>* nan_iface) {
        const auto& status_and_iface = HIDL_INVOKE(wifi_chip_, createNanIface);
        *nan_iface = status_and_iface.second;
        return status_and_iface.first.code;
    }

    WifiStatusCode removeNanIface(const std::string& name) {
        return HIDL_INVOKE(wifi_chip_, removeNanIface, name).code;
    }

    sp<IWifiChip> wifi_chip_;
};

/*
 * CreateNanIface
 * Configures the chip in NAN mode and ensures that at least 1 iface creation
 * succeeds.
 */
TEST_F(WifiChipHidlNanTest, CreateNanIface) {
    configureChipForIfaceType(IfaceType::NAN, true);

    sp<IWifiNanIface> iface;
    ASSERT_EQ(WifiStatusCode::SUCCESS, createNanIface(&iface));
    EXPECT_NE(nullptr, iface.get());
}

/*
 * GetNanIfaceNames
 * Configures the chip in NAN mode and ensures that the iface list is empty
 * before creating the iface. Then, create the iface and ensure that
 * iface name is returned via the list.
 */
TEST_F(WifiChipHidlNanTest, GetNanIfaceNames) {
    configureChipForIfaceType(IfaceType::NAN, true);

    const auto& status_and_iface_names1 =
        HIDL_INVOKE(wifi_chip_, getNanIfaceNames);
    ASSERT_EQ(WifiStatusCode::SUCCESS, status_and_iface_names1.first.code);
    EXPECT_EQ(0u, status_and_iface_names1.second.size());

    sp<IWifiNanIface> iface;
    EXPECT_EQ(WifiStatusCode::SUCCESS, createNanIface(&iface));
    EXPECT_NE(nullptr, iface.get());

    std::string iface_name = getIfaceName(iface);
    const auto& status_and_iface_names2 =
        HIDL_INVOKE(wifi_chip_, getNanIfaceNames);
    EXPECT_EQ(WifiStatusCode::SUCCESS, status_and_iface_names2.first.code);
    EXPECT_EQ(1u, status_and_iface_names2.second.size());
    EXPECT_EQ(iface_name, status_and_iface_names2.second[0]);

    EXPECT_EQ(WifiStatusCode::SUCCESS, removeNanIface(iface_name));
    const auto& status_and_iface_names3 =
        HIDL_INVOKE(wifi_chip_, getNanIfaceNames);
    EXPECT_EQ(WifiStatusCode::SUCCESS, status_and_iface_names3.first.code);
    EXPECT_EQ(0u, status_and_iface_names3.second.size());
}

/*
 * GetNanIface
 * Configures the chip in NAN mode and create an iface. Then, retrieve
 * the iface object using the correct name and ensure any other name
 * doesn't retrieve an iface object.
 */
TEST_F(WifiChipHidlNanTest, GetNanIface) {
    configureChipForIfaceType(IfaceType::NAN, true);

    sp<IWifiNanIface> nan_iface;
    EXPECT_EQ(WifiStatusCode::SUCCESS, createNanIface(&nan_iface));
    EXPECT_NE(nullptr, nan_iface.get());

    std::string iface_name = getIfaceName(nan_iface);
    const auto& status_and_iface1 =
        HIDL_INVOKE(wifi_chip_, getNanIface, iface_name);
    EXPECT_EQ(WifiStatusCode::SUCCESS, status_and_iface1.first.code);
    EXPECT_NE(nullptr, status_and_iface1.second.get());

    std::string invalid_name = iface_name + "0";
    const auto& status_and_iface2 =
        HIDL_INVOKE(wifi_chip_, getNanIface, invalid_name);
    EXPECT_EQ(WifiStatusCode::ERROR_INVALID_ARGS, status_and_iface2.first.code);
    EXPECT_EQ(nullptr, status_and_iface2.second.get());
}

/*
 * RemoveNanIface
 * Configures the chip in NAN mode and create an iface. Then, remove
 * the iface object using the correct name and ensure any other name
 * doesn't remove the iface.
 */
TEST_F(WifiChipHidlNanTest, RemoveNanIface) {
    configureChipForIfaceType(IfaceType::NAN, true);

    sp<IWifiNanIface> nan_iface;
    EXPECT_EQ(WifiStatusCode::SUCCESS, createNanIface(&nan_iface));
    EXPECT_NE(nullptr, nan_iface.get());

    std::string iface_name = getIfaceName(nan_iface);
    std::string invalid_name = iface_name + "0";
    EXPECT_EQ(WifiStatusCode::ERROR_INVALID_ARGS, removeNanIface(invalid_name));

    EXPECT_EQ(WifiStatusCode::SUCCESS, removeNanIface(iface_name));

    // No such iface exists now. So, this should return failure.
    EXPECT_EQ(WifiStatusCode::ERROR_INVALID_ARGS, removeNanIface(iface_name));
}
Loading