From 80054133dc500ab0c460d9b4e146cf70db7a6f0a Mon Sep 17 00:00:00 2001 From: Etan Cohen Date: Mon, 13 Feb 2017 13:59:07 -0800 Subject: [PATCH] [AWARE] VTS baseline Modified Wi-Fi test setup/tear-down to shutdown and start the Android framework. The framework competes with the VTS to control the HAL and so must be disabled for the duration of the test. Added framework to support VTS testing with the Wi-Fi Aware (NAN) interface. Added all callback types (notifications, events) with ability to wait for such callbacks. Bug: 35276551 Test: gtest pass Change-Id: I50847fccad457c2b225ba7f2e1760b4dbb4d363f --- .../vts/functional/wifi_hidl_test_utils.cpp | 5 +- .../functional/wifi_nan_iface_hidl_test.cpp | 460 +++++++++++++++++- 2 files changed, 456 insertions(+), 9 deletions(-) diff --git a/wifi/1.0/vts/functional/wifi_hidl_test_utils.cpp b/wifi/1.0/vts/functional/wifi_hidl_test_utils.cpp index 9042075eb6..e0c92fe104 100644 --- a/wifi/1.0/vts/functional/wifi_hidl_test_utils.cpp +++ b/wifi/1.0/vts/functional/wifi_hidl_test_utils.cpp @@ -36,11 +36,12 @@ using ::android::hardware::hidl_string; using ::android::hardware::hidl_vec; void stopFramework() { - ASSERT_EQ(std::system("svc wifi disable"), 0); + ASSERT_EQ(std::system("stop"), 0); + stopWifi(); sleep(5); } -void startFramework() { ASSERT_EQ(std::system("svc wifi enable"), 0); } +void startFramework() { ASSERT_EQ(std::system("start"), 0); } sp getWifi() { sp wifi = ::testing::VtsHalHidlTargetBaseTest::getService(); diff --git a/wifi/1.0/vts/functional/wifi_nan_iface_hidl_test.cpp b/wifi/1.0/vts/functional/wifi_nan_iface_hidl_test.cpp index eb482c9f53..95c0e5daa5 100644 --- a/wifi/1.0/vts/functional/wifi_nan_iface_hidl_test.cpp +++ b/wifi/1.0/vts/functional/wifi_nan_iface_hidl_test.cpp @@ -17,24 +17,427 @@ #include #include +#include #include +#include +#include +#include +#include "wifi_hidl_call_util.h" #include "wifi_hidl_test_utils.h" -using ::android::hardware::wifi::V1_0::IWifiNanIface; +using namespace ::android::hardware::wifi::V1_0; + +using ::android::hardware::Return; +using ::android::hardware::Void; using ::android::sp; +#define TIMEOUT_PERIOD 10 + /** * Fixture to use for all NAN Iface HIDL interface tests. */ class WifiNanIfaceHidlTest : public ::testing::VtsHalHidlTargetBaseTest { - public: - virtual void SetUp() override {} + public: + virtual void SetUp() override { + iwifiNanIface = getWifiNanIface(); + ASSERT_NE(nullptr, iwifiNanIface.get()); + ASSERT_EQ(WifiStatusCode::SUCCESS, HIDL_INVOKE(iwifiNanIface, registerEventCallback, + new WifiNanIfaceEventCallback(*this)).code); + } - virtual void TearDown() override { stopWifi(); } + virtual void TearDown() override { + stopWifi(); + } - protected: + /* Used as a mechanism to inform the test about data/event callback */ + inline void notify() { + std::unique_lock lock(mtx_); + count_++; + cv_.notify_one(); + } + + enum CallbackType { + INVALID = -2, + ANY_CALLBACK = -1, + + NOTIFY_CAPABILITIES_RESPONSE = 0, + NOTIFY_ENABLE_RESPONSE, + NOTIFY_CONFIG_RESPONSE, + NOTIFY_DISABLE_RESPONSE, + NOTIFY_START_PUBLISH_RESPONSE, + NOTIFY_STOP_PUBLISH_RESPONSE, + NOTIFY_START_SUBSCRIBE_RESPONSE, + NOTIFY_STOP_SUBSCRIBE_RESPONSE, + NOTIFY_TRANSMIT_FOLLOWUP_RESPONSE, + NOTIFY_CREATE_DATA_INTERFACE_RESPONSE, + NOTIFY_DELETE_DATA_INTERFACE_RESPONSE, + NOTIFY_INITIATE_DATA_PATH_RESPONSE, + NOTIFY_RESPOND_TO_DATA_PATH_INDICATION_RESPONSE, + NOTIFY_TERMINATE_DATA_PATH_RESPONSE, + + EVENT_CLUSTER_EVENT, + EVENT_DISABLED, + EVENT_PUBLISH_TERMINATED, + EVENT_SUBSCRIBE_TERMINATED, + EVENT_MATCH, + EVENT_MATCH_EXPIRED, + EVENT_FOLLOWUP_RECEIVED, + EVENT_TRANSMIT_FOLLOWUP, + EVENT_DATA_PATH_REQUEST, + EVENT_DATA_PATH_CONFIRM, + EVENT_DATA_PATH_TERMINATED + }; + + /* Test code calls this function to wait for data/event callback */ + inline std::cv_status wait(CallbackType waitForCallbackType) { + std::unique_lock lock(mtx_); + + EXPECT_NE(INVALID, waitForCallbackType); // can't ASSERT in a non-void-returning method + + callbackType = INVALID; + std::cv_status status = std::cv_status::no_timeout; + auto now = std::chrono::system_clock::now(); + while (count_ == 0) { + status = cv_.wait_until(lock, now + std::chrono::seconds(TIMEOUT_PERIOD)); + if (status == std::cv_status::timeout) return status; + if (waitForCallbackType != ANY_CALLBACK && callbackType != INVALID + && callbackType != waitForCallbackType) { + count_--; + } + } + count_--; + return status; + } + + class WifiNanIfaceEventCallback: public IWifiNanIfaceEventCallback { + WifiNanIfaceHidlTest& parent_; + + public: + WifiNanIfaceEventCallback(WifiNanIfaceHidlTest& parent) : parent_(parent) {}; + + virtual ~WifiNanIfaceEventCallback() = default; + + Return notifyCapabilitiesResponse( + uint16_t id, + const WifiNanStatus& status, + const NanCapabilities& capabilities) override { + parent_.callbackType = NOTIFY_CAPABILITIES_RESPONSE; + + parent_.id = id; + parent_.status = status; + parent_.capabilities = capabilities; + + parent_.notify(); + return Void(); + } + + Return notifyEnableResponse( + uint16_t id, + const WifiNanStatus& status) override { + parent_.callbackType = NOTIFY_ENABLE_RESPONSE; + + parent_.id = id; + parent_.status = status; + + parent_.notify(); + return Void(); + } + + Return notifyConfigResponse( + uint16_t id, + const WifiNanStatus& status) override { + parent_.callbackType = NOTIFY_CONFIG_RESPONSE; + + parent_.id = id; + parent_.status = status; + + parent_.notify(); + return Void(); + } + + Return notifyDisableResponse( + uint16_t id, + const WifiNanStatus& status) override { + parent_.callbackType = NOTIFY_DISABLE_RESPONSE; + + parent_.id = id; + parent_.status = status; + + parent_.notify(); + return Void(); + } + + Return notifyStartPublishResponse( + uint16_t id, + const WifiNanStatus& status, + uint8_t sessionId) override { + parent_.callbackType = NOTIFY_START_PUBLISH_RESPONSE; + + parent_.id = id; + parent_.status = status; + parent_.sessionId = sessionId; + + parent_.notify(); + return Void(); + } + + Return notifyStopPublishResponse( + uint16_t id, + const WifiNanStatus& status) override { + parent_.callbackType = NOTIFY_STOP_PUBLISH_RESPONSE; + + parent_.id = id; + parent_.status = status; + + parent_.notify(); + return Void(); + } + + Return notifyStartSubscribeResponse( + uint16_t id, + const WifiNanStatus& status, + uint8_t sessionId) override { + parent_.callbackType = NOTIFY_START_SUBSCRIBE_RESPONSE; + + parent_.id = id; + parent_.status = status; + parent_.sessionId = sessionId; + + parent_.notify(); + return Void(); + } + + Return notifyStopSubscribeResponse( + uint16_t id, + const WifiNanStatus& status) override { + parent_.callbackType = NOTIFY_STOP_SUBSCRIBE_RESPONSE; + + parent_.id = id; + parent_.status = status; + + parent_.notify(); + return Void(); + } + + Return notifyTransmitFollowupResponse( + uint16_t id, + const WifiNanStatus& status) override { + parent_.callbackType = NOTIFY_TRANSMIT_FOLLOWUP_RESPONSE; + + parent_.id = id; + parent_.status = status; + + parent_.notify(); + return Void(); + } + + Return notifyCreateDataInterfaceResponse( + uint16_t id, + const WifiNanStatus& status) override { + parent_.callbackType = NOTIFY_CREATE_DATA_INTERFACE_RESPONSE; + + parent_.id = id; + parent_.status = status; + + parent_.notify(); + return Void(); + } + + Return notifyDeleteDataInterfaceResponse( + uint16_t id, + const WifiNanStatus& status) override { + parent_.callbackType = NOTIFY_DELETE_DATA_INTERFACE_RESPONSE; + + parent_.id = id; + parent_.status = status; + + parent_.notify(); + return Void(); + } + + Return notifyInitiateDataPathResponse( + uint16_t id, + const WifiNanStatus& status, + uint32_t ndpInstanceId) override { + parent_.callbackType = NOTIFY_INITIATE_DATA_PATH_RESPONSE; + + parent_.id = id; + parent_.status = status; + parent_.ndpInstanceId = ndpInstanceId; + + parent_.notify(); + return Void(); + } + + Return notifyRespondToDataPathIndicationResponse( + uint16_t id, + const WifiNanStatus& status) override { + parent_.callbackType = NOTIFY_RESPOND_TO_DATA_PATH_INDICATION_RESPONSE; + + parent_.id = id; + parent_.status = status; + + parent_.notify(); + return Void(); + } + + Return notifyTerminateDataPathResponse( + uint16_t id, + const WifiNanStatus& status) override { + parent_.callbackType = NOTIFY_TERMINATE_DATA_PATH_RESPONSE; + + parent_.id = id; + parent_.status = status; + + parent_.notify(); + return Void(); + } + + Return eventClusterEvent( + const NanClusterEventInd& event) override { + parent_.callbackType = EVENT_CLUSTER_EVENT; + + parent_.nanClusterEventInd = event; + + parent_.notify(); + return Void(); + } + + Return eventDisabled( + const WifiNanStatus& status) override { + parent_.callbackType = EVENT_DISABLED; + + parent_.status = status; + + parent_.notify(); + return Void(); + } + + Return eventPublishTerminated( + uint8_t sessionId, + const WifiNanStatus& status) override { + parent_.callbackType = EVENT_PUBLISH_TERMINATED; + + parent_.sessionId = sessionId; + parent_.status = status; + + parent_.notify(); + return Void(); + } + + Return eventSubscribeTerminated( + uint8_t sessionId, + const WifiNanStatus& status) override { + parent_.callbackType = EVENT_SUBSCRIBE_TERMINATED; + + parent_.sessionId = sessionId; + parent_.status = status; + + parent_.notify(); + return Void(); + } + + Return eventMatch( + const NanMatchInd& event) override { + parent_.callbackType = EVENT_MATCH; + + parent_.nanMatchInd = event; + + parent_.notify(); + return Void(); + } + + Return eventMatchExpired( + uint8_t discoverySessionId, + uint32_t peerId) override { + parent_.callbackType = EVENT_MATCH_EXPIRED; + + parent_.sessionId = discoverySessionId; + parent_.peerId = peerId; + + parent_.notify(); + return Void(); + } + + Return eventFollowupReceived( + const NanFollowupReceivedInd& event) override { + parent_.callbackType = EVENT_FOLLOWUP_RECEIVED; + + parent_.nanFollowupReceivedInd = event; + + parent_.notify(); + return Void(); + } + + Return eventTransmitFollowup( + uint16_t id, + const WifiNanStatus& status) override { + parent_.callbackType = EVENT_TRANSMIT_FOLLOWUP; + + parent_.id = id; + parent_.status = status; + + parent_.notify(); + return Void(); + } + + Return eventDataPathRequest( + const NanDataPathRequestInd& event) override { + parent_.callbackType = EVENT_DATA_PATH_REQUEST; + + parent_.nanDataPathRequestInd = event; + + parent_.notify(); + return Void(); + } + + Return eventDataPathConfirm( + const NanDataPathConfirmInd& event) override { + parent_.callbackType = EVENT_DATA_PATH_CONFIRM; + + parent_.nanDataPathConfirmInd = event; + + parent_.notify(); + return Void(); + } + + Return eventDataPathTerminated( + uint32_t ndpInstanceId) override { + parent_.callbackType = EVENT_DATA_PATH_TERMINATED; + + parent_.ndpInstanceId = ndpInstanceId; + + parent_.notify(); + return Void(); + } + }; + + private: + // synchronization objects + std::mutex mtx_; + std::condition_variable cv_; + int count_; + + protected: + android::sp iwifiNanIface; + + // Data from IWifiNanIfaceEventCallback callbacks: this is the collection of all + // arguments to all callbacks. They are set by the callback (notifications or + // events) and can be retrieved by tests. + CallbackType callbackType; + uint16_t id; + WifiNanStatus status; + NanCapabilities capabilities; + uint8_t sessionId; + uint32_t ndpInstanceId; + NanClusterEventInd nanClusterEventInd; + NanMatchInd nanMatchInd; + uint32_t peerId; + NanFollowupReceivedInd nanFollowupReceivedInd; + NanDataPathRequestInd nanDataPathRequestInd; + NanDataPathConfirmInd nanDataPathConfirmInd; }; /* @@ -43,6 +446,49 @@ class WifiNanIfaceHidlTest : public ::testing::VtsHalHidlTargetBaseTest { * successfully created. */ TEST(WifiNanIfaceHidlTestNoFixture, Create) { - EXPECT_NE(nullptr, getWifiNanIface().get()); - stopWifi(); + ASSERT_NE(nullptr, getWifiNanIface().get()); + stopWifi(); +} + +/* + * Fail: use past destruction + * Ensure that API calls fail with ERROR_WIFI_IFACE_INVALID when using an interface once wifi + * is disabled. + */ +TEST(WifiNanIfaceHidlTestNoFixture, FailOnIfaceInvalid) { + android::sp iwifiNanIface = getWifiNanIface(); + ASSERT_NE(nullptr, iwifiNanIface.get()); + stopWifi(); + sleep(5); // make sure that all chips/interfaces are invalidated + ASSERT_EQ(WifiStatusCode::ERROR_WIFI_IFACE_INVALID, + HIDL_INVOKE(iwifiNanIface, getCapabilitiesRequest, 0).code); +} + +/* + * getCapabilitiesRequest: validate that returns capabilities. + */ +TEST_F(WifiNanIfaceHidlTest, getCapabilitiesRequest) { + uint16_t inputCmdId = 10; + ASSERT_EQ(WifiStatusCode::SUCCESS, + HIDL_INVOKE(iwifiNanIface, getCapabilitiesRequest, inputCmdId).code); + // wait for a callback + ASSERT_EQ(std::cv_status::no_timeout, wait(NOTIFY_CAPABILITIES_RESPONSE)); + ASSERT_EQ(NOTIFY_CAPABILITIES_RESPONSE, callbackType); + ASSERT_EQ(id, inputCmdId); + + // check for reasonable capability values + EXPECT_GT(capabilities.maxConcurrentClusters, (unsigned int) 0); + EXPECT_GT(capabilities.maxPublishes, (unsigned int) 0); + EXPECT_GT(capabilities.maxSubscribes, (unsigned int) 0); + EXPECT_EQ(capabilities.maxServiceNameLen, (unsigned int) 255); + EXPECT_EQ(capabilities.maxMatchFilterLen, (unsigned int) 255); + EXPECT_GT(capabilities.maxTotalMatchFilterLen, (unsigned int) 255); + EXPECT_EQ(capabilities.maxServiceSpecificInfoLen, (unsigned int) 255); + EXPECT_GE(capabilities.maxExtendedServiceSpecificInfoLen, (unsigned int) 255); + EXPECT_GT(capabilities.maxNdiInterfaces, (unsigned int) 0); + EXPECT_GT(capabilities.maxNdpSessions, (unsigned int) 0); + EXPECT_GT(capabilities.maxAppInfoLen, (unsigned int) 0); + EXPECT_GT(capabilities.maxQueuedTransmitFollowupMsgs, (unsigned int) 0); + EXPECT_GT(capabilities.maxSubscribeInterfaceAddresses, (unsigned int) 0); + EXPECT_NE(capabilities.supportedCipherSuites, (unsigned int) 0); }