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

Commit 3312801a authored by Roshan Pius's avatar Roshan Pius
Browse files

wifi(implementation): Unit tests for V1 & V2 iface combos

Unit tests for all the iface combos supported in V1 (2016 devices) & V2
(2017 devices).

Bug: 68775880
Test: ./hardware/interfaces/wifi/1.2/default/tests/runtests.sh
Change-Id: I1049176aabdf936d442d022b5915129010ce7387
parent 200a17db
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -88,6 +88,7 @@ include $(BUILD_EXECUTABLE)
###
include $(CLEAR_VARS)
LOCAL_MODULE := android.hardware.wifi@1.0-service-tests
LOCAL_PROPRIETARY_MODULE := true
LOCAL_SRC_FILES := \
    tests/main.cpp \
    tests/mock_wifi_feature_flags.cpp \
+1 −1
Original line number Diff line number Diff line
@@ -47,4 +47,4 @@ fi

adb sync

adb shell /data/nativetest64/android.hardware.wifi@1.0-service-tests/android.hardware.wifi@1.0-service-tests
adb shell /data/nativetest/vendor/android.hardware.wifi@1.0-service-tests/android.hardware.wifi@1.0-service-tests
+285 −5
Original line number Diff line number Diff line
@@ -29,7 +29,11 @@ using testing::NiceMock;
using testing::Return;
using testing::Test;

namespace {}  // namespace
namespace {
using android::hardware::wifi::V1_0::ChipId;

constexpr ChipId kFakeChipId = 5;
}  // namespace

namespace android {
namespace hardware {
@@ -42,30 +46,306 @@ class WifiChipTest : public Test {
    void setupV1IfaceCombination() {
        EXPECT_CALL(*feature_flags_, isAwareSupported())
            .WillRepeatedly(testing::Return(false));
        chip_->getAvailableModes(
            [](const WifiStatus& status,
               const std::vector<WifiChip::ChipMode>& modes) {
                ASSERT_EQ(WifiStatusCode::SUCCESS, status.code);
                // V1 has 2 modes of operation.
                ASSERT_EQ(2u, modes.size());
            });
    }

    void setupV2IfaceCombination() {
        EXPECT_CALL(*feature_flags_, isAwareSupported())
            .WillRepeatedly(testing::Return(true));
        chip_->getAvailableModes(
            [](const WifiStatus& status,
               const std::vector<WifiChip::ChipMode>& modes) {
                ASSERT_EQ(WifiStatusCode::SUCCESS, status.code);
                // V2 has 2 modes of operation.
                ASSERT_EQ(2u, modes.size());
            });
    }

    sp<WifiChip> chip_;
    void findModeAndConfigureForIfaceType(const IfaceType& type) {
        // This should be aligned with kInvalidModeId in wifi_chip.cpp.
        ChipModeId mode_id = UINT32_MAX;
        chip_->getAvailableModes(
            [&mode_id, &type](const WifiStatus& status,
                              const std::vector<WifiChip::ChipMode>& modes) {
                ASSERT_EQ(WifiStatusCode::SUCCESS, status.code);
                for (const auto& mode : modes) {
                    for (const auto& combination : mode.availableCombinations) {
                        for (const auto& limit : combination.limits) {
                            if (limit.types.end() !=
                                std::find(limit.types.begin(),
                                          limit.types.end(), type)) {
                                mode_id = mode.id;
                            }
                        }
                    }
                }
            });
        ASSERT_NE(UINT32_MAX, mode_id);

    ChipId chip_id_ = 5;
        chip_->configureChip(mode_id, [](const WifiStatus& status) {
            ASSERT_EQ(WifiStatusCode::SUCCESS, status.code);
        });
    }

    // Returns an empty string on error.
    std::string createIface(const IfaceType& type) {
        std::string iface_name;
        if (type == IfaceType::AP) {
            chip_->createApIface([&iface_name](const WifiStatus& status,
                                               const sp<IWifiApIface>& iface) {
                if (WifiStatusCode::SUCCESS == status.code) {
                    ASSERT_NE(iface.get(), nullptr);
                    iface->getName([&iface_name](const WifiStatus& status,
                                                 const hidl_string& name) {
                        ASSERT_EQ(WifiStatusCode::SUCCESS, status.code);
                        iface_name = name.c_str();
                    });
                }
            });
        } else if (type == IfaceType::NAN) {
            chip_->createNanIface(
                [&iface_name](const WifiStatus& status,
                              const sp<IWifiNanIface>& iface) {
                    if (WifiStatusCode::SUCCESS == status.code) {
                        ASSERT_NE(iface.get(), nullptr);
                        iface->getName([&iface_name](const WifiStatus& status,
                                                     const hidl_string& name) {
                            ASSERT_EQ(WifiStatusCode::SUCCESS, status.code);
                            iface_name = name.c_str();
                        });
                    }
                });
        } else if (type == IfaceType::P2P) {
            chip_->createP2pIface(
                [&iface_name](const WifiStatus& status,
                              const sp<IWifiP2pIface>& iface) {
                    if (WifiStatusCode::SUCCESS == status.code) {
                        ASSERT_NE(iface.get(), nullptr);
                        iface->getName([&iface_name](const WifiStatus& status,
                                                     const hidl_string& name) {
                            ASSERT_EQ(WifiStatusCode::SUCCESS, status.code);
                            iface_name = name.c_str();
                        });
                    }
                });
        } else if (type == IfaceType::STA) {
            chip_->createStaIface(
                [&iface_name](const WifiStatus& status,
                              const sp<IWifiStaIface>& iface) {
                    if (WifiStatusCode::SUCCESS == status.code) {
                        ASSERT_NE(iface.get(), nullptr);
                        iface->getName([&iface_name](const WifiStatus& status,
                                                     const hidl_string& name) {
                            ASSERT_EQ(WifiStatusCode::SUCCESS, status.code);
                            iface_name = name.c_str();
                        });
                    }
                });
        }
        return iface_name;
    }

    void removeIface(const IfaceType& type, const std::string& iface_name) {
        if (type == IfaceType::AP) {
            chip_->removeApIface(iface_name, [](const WifiStatus& status) {
                ASSERT_EQ(WifiStatusCode::SUCCESS, status.code);
            });
        } else if (type == IfaceType::NAN) {
            chip_->removeNanIface(iface_name, [](const WifiStatus& status) {
                ASSERT_EQ(WifiStatusCode::SUCCESS, status.code);
            });
        } else if (type == IfaceType::P2P) {
            chip_->removeP2pIface(iface_name, [](const WifiStatus& status) {
                ASSERT_EQ(WifiStatusCode::SUCCESS, status.code);
            });
        } else if (type == IfaceType::STA) {
            chip_->removeStaIface(iface_name, [](const WifiStatus& status) {
                ASSERT_EQ(WifiStatusCode::SUCCESS, status.code);
            });
        }
    }

   public:
    void SetUp() override {
        chip_ = new WifiChip(chip_id_, legacy_hal_, mode_controller_,
                             feature_flags_);

        EXPECT_CALL(*mode_controller_, changeFirmwareMode(testing::_))
            .WillRepeatedly(testing::Return(true));
        EXPECT_CALL(*legacy_hal_, start())
            .WillRepeatedly(testing::Return(legacy_hal::WIFI_SUCCESS));
    }

   private:
    sp<WifiChip> chip_;
    ChipId chip_id_ = kFakeChipId;
    std::shared_ptr<NiceMock<legacy_hal::MockWifiLegacyHal>> legacy_hal_{
        new NiceMock<legacy_hal::MockWifiLegacyHal>};
    std::shared_ptr<NiceMock<mode_controller::MockWifiModeController>>
        mode_controller_{new NiceMock<mode_controller::MockWifiModeController>};
    std::shared_ptr<NiceMock<feature_flags::MockWifiFeatureFlags>>
        feature_flags_{new NiceMock<feature_flags::MockWifiFeatureFlags>};
};

////////// V1 Iface Combinations ////////////
// Mode 1 - STA + P2P
// Mode 2 - AP
class WifiChipV1IfaceCombinationTest : public WifiChipTest {
   public:
    void SetUp() override {
        chip_ = new WifiChip(chip_id_, legacy_hal_, mode_controller_,
                             feature_flags_);
        WifiChipTest::SetUp();
        setupV1IfaceCombination();
    }
};

TEST_F(WifiChipV1IfaceCombinationTest, StaMode_CreateSta_ShouldSucceed) {
    findModeAndConfigureForIfaceType(IfaceType::STA);
    ASSERT_FALSE(createIface(IfaceType::STA).empty());
}

TEST_F(WifiChipV1IfaceCombinationTest, StaMode_CreateP2p_ShouldSucceed) {
    findModeAndConfigureForIfaceType(IfaceType::STA);
    ASSERT_FALSE(createIface(IfaceType::P2P).empty());
}

TEST_F(WifiChipV1IfaceCombinationTest, StaMode_CreateNan_ShouldFail) {
    findModeAndConfigureForIfaceType(IfaceType::STA);
    ASSERT_TRUE(createIface(IfaceType::NAN).empty());
}

TEST_F(WifiChipV1IfaceCombinationTest, StaMode_CreateAp_ShouldFail) {
    findModeAndConfigureForIfaceType(IfaceType::STA);
    ASSERT_TRUE(createIface(IfaceType::AP).empty());
}

TEST_F(WifiChipV1IfaceCombinationTest, StaMode_CreateStaP2p_ShouldSucceed) {
    findModeAndConfigureForIfaceType(IfaceType::STA);
    ASSERT_FALSE(createIface(IfaceType::STA).empty());
    ASSERT_FALSE(createIface(IfaceType::P2P).empty());
}

TEST_F(WifiChipV1IfaceCombinationTest, ApMode_CreateAp_ShouldSucceed) {
    findModeAndConfigureForIfaceType(IfaceType::AP);
    ASSERT_FALSE(createIface(IfaceType::AP).empty());
}

TEST_F(WifiChipV1IfaceCombinationTest, ApMode_CreateSta_ShouldFail) {
    findModeAndConfigureForIfaceType(IfaceType::AP);
    ASSERT_TRUE(createIface(IfaceType::STA).empty());
}

TEST_F(WifiChipV1IfaceCombinationTest, ApMode_CreateP2p_ShouldFail) {
    findModeAndConfigureForIfaceType(IfaceType::AP);
    ASSERT_TRUE(createIface(IfaceType::STA).empty());
}

TEST_F(WifiChipV1IfaceCombinationTest, ApMode_CreateNan_ShouldFail) {
    findModeAndConfigureForIfaceType(IfaceType::AP);
    ASSERT_TRUE(createIface(IfaceType::NAN).empty());
}

////////// V2 Iface Combinations ////////////
// Mode 1 - STA + P2P/NAN
// Mode 2 - AP
class WifiChipV2IfaceCombinationTest : public WifiChipTest {
   public:
    void SetUp() override {
        WifiChipTest::SetUp();
        setupV2IfaceCombination();
    }
};

TEST_F(WifiChipV2IfaceCombinationTest, StaMode_CreateSta_ShouldSucceed) {
    findModeAndConfigureForIfaceType(IfaceType::STA);
    ASSERT_FALSE(createIface(IfaceType::STA).empty());
}

TEST_F(WifiChipV2IfaceCombinationTest, StaMode_CreateP2p_ShouldSucceed) {
    findModeAndConfigureForIfaceType(IfaceType::STA);
    ASSERT_FALSE(createIface(IfaceType::P2P).empty());
}

TEST_F(WifiChipV2IfaceCombinationTest, StaMode_CreateNan_ShouldSucceed) {
    findModeAndConfigureForIfaceType(IfaceType::STA);
    ASSERT_FALSE(createIface(IfaceType::NAN).empty());
}

TEST_F(WifiChipV2IfaceCombinationTest, StaMode_CreateAp_ShouldFail) {
    findModeAndConfigureForIfaceType(IfaceType::STA);
    ASSERT_TRUE(createIface(IfaceType::AP).empty());
}

TEST_F(WifiChipV2IfaceCombinationTest, StaMode_CreateStaP2p_ShouldSucceed) {
    findModeAndConfigureForIfaceType(IfaceType::STA);
    ASSERT_FALSE(createIface(IfaceType::STA).empty());
    ASSERT_FALSE(createIface(IfaceType::P2P).empty());
}

TEST_F(WifiChipV2IfaceCombinationTest, StaMode_CreateStaNan_ShouldSucceed) {
    findModeAndConfigureForIfaceType(IfaceType::STA);
    ASSERT_FALSE(createIface(IfaceType::STA).empty());
    ASSERT_FALSE(createIface(IfaceType::NAN).empty());
}

TEST_F(WifiChipV2IfaceCombinationTest, StaMode_CreateStaP2PNan_ShouldFail) {
    findModeAndConfigureForIfaceType(IfaceType::STA);
    ASSERT_FALSE(createIface(IfaceType::STA).empty());
    ASSERT_FALSE(createIface(IfaceType::P2P).empty());
    ASSERT_TRUE(createIface(IfaceType::NAN).empty());
}

TEST_F(WifiChipV2IfaceCombinationTest,
       StaMode_CreateStaNan_AfterP2pRemove_ShouldSucceed) {
    findModeAndConfigureForIfaceType(IfaceType::STA);
    ASSERT_FALSE(createIface(IfaceType::STA).empty());
    const auto p2p_iface_name = createIface(IfaceType::P2P);
    ASSERT_FALSE(p2p_iface_name.empty());
    ASSERT_TRUE(createIface(IfaceType::NAN).empty());

    // After removing P2P iface, NAN iface creation should succeed.
    removeIface(IfaceType::P2P, p2p_iface_name);
    ASSERT_FALSE(createIface(IfaceType::NAN).empty());
}

TEST_F(WifiChipV2IfaceCombinationTest,
       StaMode_CreateStaP2p_AfterNanRemove_ShouldSucceed) {
    findModeAndConfigureForIfaceType(IfaceType::STA);
    ASSERT_FALSE(createIface(IfaceType::STA).empty());
    const auto nan_iface_name = createIface(IfaceType::NAN);
    ASSERT_FALSE(nan_iface_name.empty());
    ASSERT_TRUE(createIface(IfaceType::P2P).empty());

    // After removing NAN iface, P2P iface creation should succeed.
    removeIface(IfaceType::NAN, nan_iface_name);
    ASSERT_FALSE(createIface(IfaceType::P2P).empty());
}

TEST_F(WifiChipV2IfaceCombinationTest, ApMode_CreateAp_ShouldSucceed) {
    findModeAndConfigureForIfaceType(IfaceType::AP);
    ASSERT_FALSE(createIface(IfaceType::AP).empty());
}

TEST_F(WifiChipV2IfaceCombinationTest, ApMode_CreateSta_ShouldFail) {
    findModeAndConfigureForIfaceType(IfaceType::AP);
    ASSERT_TRUE(createIface(IfaceType::STA).empty());
}

TEST_F(WifiChipV2IfaceCombinationTest, ApMode_CreateP2p_ShouldFail) {
    findModeAndConfigureForIfaceType(IfaceType::AP);
    ASSERT_TRUE(createIface(IfaceType::STA).empty());
}

TEST_F(WifiChipV2IfaceCombinationTest, ApMode_CreateNan_ShouldFail) {
    findModeAndConfigureForIfaceType(IfaceType::AP);
    ASSERT_TRUE(createIface(IfaceType::NAN).empty());
}

}  // namespace implementation
}  // namespace V1_2
}  // namespace wifi