aboutsummaryrefslogtreecommitdiffstats
path: root/src/plugins/voiceagents/test
diff options
context:
space:
mode:
authorNaveen Bobbili <nbobbili@amazon.com>2018-11-12 16:12:38 -0800
committerNaveen Bobbili <nbobbili@amazon.com>2018-11-13 15:05:41 -0800
commitb6abca2edcb36c0c0848d1cd8dc291f23293aa80 (patch)
treea838812e0b66f0695cb6cf0f8bebfa38315ce8b8 /src/plugins/voiceagents/test
parentbe70712f89eacd20dca413bcce46e4aa26b5709e (diff)
SPEC-1924: AGL Speech Framework's Voice Service High Level 1.0 Release.
Details: 1) Control plugin implementation for VSHL 1.0 2) Exposed APIs that are documented in the confluence page https://confluence.automotivelinux.org/display/SPE/Speech+EG+Architecture 3) Implemented 39 unit tests based on GTest framework to test all the low level components of VSHL binding. 4) Implemented a HTML5 based VSHL API tester application to test VSHL APIs. API specification: https://confluence.automotivelinux.org/display/SPE/Speech+EG+Architecture#SpeechEGArchitecture-HighLevelVoiceService Test performed: 1) Tested AGL service running Alexa Auto SDK https://github.com/alexa/aac-sdk on Ubuntu 16.04 and Renesas R-Car M3 board. License: Apache 2.0 Developers/Owners: Naveen Bobbili (nbobbili@amazon.com) Prakash Buddhiraja (buddhip@amazon.com) Shotaro Uchida (shotaru@amazon.co.jp) Change-Id: I3370f4ad65aff030f24f4ad571fb02d525bbfbca Signed-off-by: Naveen Bobbili <nbobbili@amazon.com>
Diffstat (limited to 'src/plugins/voiceagents/test')
-rw-r--r--src/plugins/voiceagents/test/VoiceAgentTest.cpp94
-rw-r--r--src/plugins/voiceagents/test/VoiceAgentsDataManagerTest.cpp294
-rw-r--r--src/plugins/voiceagents/test/VoiceAgentsTestData.h67
3 files changed, 455 insertions, 0 deletions
diff --git a/src/plugins/voiceagents/test/VoiceAgentTest.cpp b/src/plugins/voiceagents/test/VoiceAgentTest.cpp
new file mode 100644
index 0000000..e5ad15e
--- /dev/null
+++ b/src/plugins/voiceagents/test/VoiceAgentTest.cpp
@@ -0,0 +1,94 @@
+/*
+ * Copyright 2018-2019 Amazon.com, Inc. or its affiliates. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License").
+ * You may not use this file except in compliance with the License.
+ * A copy of the License is located at
+ *
+ * http://aws.amazon.com/apache2.0/
+ *
+ * or in the "license" file accompanying this file. This file 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 <gtest/gtest.h>
+
+#include "voiceagents/include/VoiceAgent.h"
+
+#include "voiceagents/test/VoiceAgentsTestData.h"
+#include "test/common/ConsoleLogger.h"
+
+using namespace vshl::voiceagents;
+using namespace vshl::test::common;
+
+namespace vshl {
+namespace test {
+
+class VoiceAgentTest : public ::testing::Test {
+protected:
+ void SetUp() override {
+ mConsoleLogger = std::make_shared<ConsoleLogger>();
+
+ mVoiceAgentData = *(getVoiceAgentsTestData().begin());
+ mVoiceAgent = VoiceAgent::create(
+ mConsoleLogger,
+ mVoiceAgentData.id,
+ mVoiceAgentData.name,
+ mVoiceAgentData.description,
+ mVoiceAgentData.api,
+ mVoiceAgentData.vendor,
+ mVoiceAgentData.activeWakeword,
+ mVoiceAgentData.isActive,
+ mVoiceAgentData.wakewords);
+ }
+
+ std::shared_ptr<ConsoleLogger> mConsoleLogger;
+ std::shared_ptr<VoiceAgent> mVoiceAgent;
+ VoiceAgentTestData mVoiceAgentData;
+};
+
+TEST_F(VoiceAgentTest, InitializesCorrectly) {
+ ASSERT_NE(mVoiceAgent, nullptr);
+ ASSERT_EQ(mVoiceAgent->getId(), mVoiceAgentData.id);
+ ASSERT_EQ(mVoiceAgent->getName(), mVoiceAgentData.name);
+ ASSERT_EQ(mVoiceAgent->getDescription(), mVoiceAgentData.description);
+ ASSERT_EQ(mVoiceAgent->getApi(), mVoiceAgentData.api);
+ ASSERT_EQ(mVoiceAgent->getVendor(), mVoiceAgentData.vendor);
+ ASSERT_EQ(mVoiceAgent->getActiveWakeword(), mVoiceAgentData.activeWakeword);
+ ASSERT_EQ(mVoiceAgent->isActive(), mVoiceAgentData.isActive);
+
+ std::unordered_set<std::string> wakeWords = *mVoiceAgentData.wakewords;
+ ASSERT_EQ(*(mVoiceAgent->getWakeWords()), wakeWords);
+}
+
+TEST_F(VoiceAgentTest, FailsCreationOnNonExistentWakeword) {
+ std::string nonExistentWW = "non-existent";
+ auto voiceAgent = VoiceAgent::create(
+ mConsoleLogger,
+ mVoiceAgentData.id,
+ mVoiceAgentData.name,
+ mVoiceAgentData.description,
+ mVoiceAgentData.api,
+ mVoiceAgentData.vendor,
+ nonExistentWW,
+ mVoiceAgentData.isActive,
+ mVoiceAgentData.wakewords);
+ ASSERT_EQ(voiceAgent, nullptr);
+}
+
+TEST_F(VoiceAgentTest, SetsWakewordCorrectly) {
+ std::string wakeword = *(mVoiceAgentData.wakewords->begin());
+ ASSERT_TRUE(mVoiceAgent->setActiveWakeWord(wakeword));
+ ASSERT_EQ(mVoiceAgent->getActiveWakeword(), wakeword);
+}
+
+TEST_F(VoiceAgentTest, FailsToSetNonExistentWakeword) {
+ std::string nonExistentWW = "non-existent";
+ ASSERT_FALSE(mVoiceAgent->setActiveWakeWord(nonExistentWW));
+ ASSERT_EQ(mVoiceAgent->getActiveWakeword(), mVoiceAgentData.activeWakeword);
+}
+
+} // namespace test
+} // namespace vshl \ No newline at end of file
diff --git a/src/plugins/voiceagents/test/VoiceAgentsDataManagerTest.cpp b/src/plugins/voiceagents/test/VoiceAgentsDataManagerTest.cpp
new file mode 100644
index 0000000..58c62ed
--- /dev/null
+++ b/src/plugins/voiceagents/test/VoiceAgentsDataManagerTest.cpp
@@ -0,0 +1,294 @@
+/*
+ * Copyright 2018-2019 Amazon.com, Inc. or its affiliates. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License").
+ * You may not use this file except in compliance with the License.
+ * A copy of the License is located at
+ *
+ * http://aws.amazon.com/apache2.0/
+ *
+ * or in the "license" file accompanying this file. This file 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 <gtest/gtest.h>
+
+#include "voiceagents/VoiceAgentsDataManager.h"
+
+#include "test/common/ConsoleLogger.h"
+#include "test/mocks/AFBApiMock.h"
+#include "test/mocks/VoiceAgentsChangeObserverMock.h"
+#include "voiceagents/test/VoiceAgentsTestData.h"
+
+using namespace vshl::common::interfaces;
+using namespace vshl::voiceagents;
+
+using namespace vshl::test::common;
+
+namespace vshl {
+namespace test {
+
+class VoiceAgentDataManagerTest : public ::testing::Test {
+protected:
+ void SetUp() override {
+ mConsoleLogger = std::make_shared<ConsoleLogger>();
+ mAfbApi = std::make_shared<::testing::NiceMock<AFBApiMock>>();
+ mVADataManager = VoiceAgentsDataManager::create(mConsoleLogger, mAfbApi);
+
+ mAgentsChangeObserver = std::make_shared<
+ ::testing::StrictMock<VoiceAgentsChangeObserverMock>>();
+ mVADataManager->addVoiceAgentsChangeObserver(mAgentsChangeObserver);
+
+ mVoiceAgentsData = getVoiceAgentsTestData();
+ }
+
+ void TearDown() override {
+ mVADataManager->removeVoiceAgentsChangeObserver(mAgentsChangeObserver);
+ }
+
+ static bool addVoiceAgent(VoiceAgentsDataManager &mgr,
+ VoiceAgentTestData &data) {
+ return mgr.addNewVoiceAgent(data.id, data.name, data.description, data.api,
+ data.vendor, data.activeWakeword, data.isActive,
+ data.wakewords);
+ }
+
+ static bool isEqual(const VoiceAgentTestData &lhs, const IVoiceAgent &rhs) {
+ return lhs.id == rhs.getId() && lhs.name == rhs.getName() &&
+ lhs.description == rhs.getDescription() && lhs.api == rhs.getApi() &&
+ lhs.vendor == rhs.getVendor() &&
+ lhs.activeWakeword == rhs.getActiveWakeword() &&
+ lhs.isActive == rhs.isActive() &&
+ *lhs.wakewords == *rhs.getWakeWords();
+ }
+
+ static std::shared_ptr<IVoiceAgent>
+ findVoiceAgent(std::set<std::shared_ptr<IVoiceAgent>> &voiceAgents,
+ std::string &vaId) {
+ for (auto va : voiceAgents) {
+ if (va->getId() == vaId)
+ return va;
+ }
+
+ return nullptr;
+ }
+
+ std::shared_ptr<ConsoleLogger> mConsoleLogger;
+
+ // It is a NiceMock because we don't want gtest to produce warnings about non
+ // interesting calls.
+ // The non interesting calls like createEvent is internal implementation
+ // detail for many of the
+ // tests in this class, and hence suppression of these warnings with NiceMock.
+ std::shared_ptr<::testing::NiceMock<AFBApiMock>> mAfbApi;
+
+ // It is a StrictMock because we want to fail the test for all non interesting
+ // calls.
+ std::shared_ptr<::testing::StrictMock<VoiceAgentsChangeObserverMock>>
+ mAgentsChangeObserver;
+
+ std::vector<VoiceAgentTestData> mVoiceAgentsData;
+ std::unique_ptr<VoiceAgentsDataManager> mVADataManager;
+};
+
+TEST_F(VoiceAgentDataManagerTest, InitializesCorrectly) {
+ ASSERT_NE(mVADataManager, nullptr);
+ ASSERT_EQ(mVADataManager->getAllVoiceAgents().size(), 0);
+ ASSERT_EQ(mVADataManager->getDefaultVoiceAgent(), std::string());
+}
+
+TEST_F(VoiceAgentDataManagerTest, addingVoiceAgentWithSameIdFails) {
+ EXPECT_CALL(*mAgentsChangeObserver, OnVoiceAgentAdded(::testing::_)).Times(1);
+
+ ASSERT_TRUE(addVoiceAgent(*mVADataManager, mVoiceAgentsData[0]));
+ ASSERT_FALSE(addVoiceAgent(*mVADataManager, mVoiceAgentsData[0]));
+
+ auto allVoiceAgents = mVADataManager->getAllVoiceAgents();
+ ASSERT_EQ(allVoiceAgents.size(), 1);
+}
+
+TEST_F(VoiceAgentDataManagerTest,
+ addingVoiceAgentWithNonExistentActiveWakewordFails) {
+ auto voiceAgetData = mVoiceAgentsData[0];
+ voiceAgetData.activeWakeword = "non-existent";
+ ASSERT_FALSE(addVoiceAgent(*mVADataManager, voiceAgetData));
+
+ auto allVoiceAgents = mVADataManager->getAllVoiceAgents();
+ ASSERT_EQ(allVoiceAgents.size(), 0);
+}
+
+TEST_F(VoiceAgentDataManagerTest, canAddNewVoiceAgents) {
+ EXPECT_CALL(*mAgentsChangeObserver, OnVoiceAgentAdded(::testing::_)).Times(2);
+
+ ASSERT_TRUE(addVoiceAgent(*mVADataManager, mVoiceAgentsData[0]));
+
+ auto allVoiceAgents = mVADataManager->getAllVoiceAgents();
+ ASSERT_EQ(allVoiceAgents.size(), 1);
+
+ ASSERT_TRUE(addVoiceAgent(*mVADataManager, mVoiceAgentsData[1]));
+
+ allVoiceAgents = mVADataManager->getAllVoiceAgents();
+ ASSERT_EQ(allVoiceAgents.size(), 2);
+
+ for (auto va : allVoiceAgents) {
+ bool voiceAgentFound = false;
+ for (auto vaData : mVoiceAgentsData) {
+ if (isEqual(vaData, *va)) {
+ voiceAgentFound = true;
+ break;
+ }
+ }
+ ASSERT_TRUE(voiceAgentFound);
+ }
+}
+
+TEST_F(VoiceAgentDataManagerTest, removingUnknonwVoiceAgentFails) {
+ EXPECT_CALL(*mAgentsChangeObserver, OnVoiceAgentAdded(::testing::_)).Times(1);
+
+ ASSERT_FALSE(mVADataManager->removeVoiceAgent("non-existent-vaid"));
+
+ ASSERT_TRUE(addVoiceAgent(*mVADataManager, mVoiceAgentsData[0]));
+ ASSERT_FALSE(mVADataManager->removeVoiceAgent("non-existent-vaid"));
+}
+
+TEST_F(VoiceAgentDataManagerTest, canRemoveVoiceAgents) {
+ EXPECT_CALL(*mAgentsChangeObserver, OnVoiceAgentAdded(::testing::_)).Times(2);
+ EXPECT_CALL(*mAgentsChangeObserver, OnVoiceAgentRemoved(::testing::_))
+ .Times(2);
+
+ ASSERT_TRUE(addVoiceAgent(*mVADataManager, mVoiceAgentsData[0]));
+ ASSERT_TRUE(addVoiceAgent(*mVADataManager, mVoiceAgentsData[1]));
+
+ auto allVoiceAgents = mVADataManager->getAllVoiceAgents();
+ ASSERT_EQ(allVoiceAgents.size(), 2);
+
+ ASSERT_TRUE(mVADataManager->removeVoiceAgent(mVoiceAgentsData[0].id));
+
+ allVoiceAgents = mVADataManager->getAllVoiceAgents();
+ ASSERT_EQ(allVoiceAgents.size(), 1);
+
+ ASSERT_TRUE(mVADataManager->removeVoiceAgent(mVoiceAgentsData[1].id));
+
+ allVoiceAgents = mVADataManager->getAllVoiceAgents();
+ ASSERT_EQ(allVoiceAgents.size(), 0);
+}
+
+TEST_F(VoiceAgentDataManagerTest, activatingNonExistentVoiceAgentsFails) {
+ uint32_t result = mVADataManager->activateVoiceAgents({"non", "existent"});
+ ASSERT_EQ(result, 0);
+
+ EXPECT_CALL(*mAgentsChangeObserver, OnVoiceAgentAdded(::testing::_)).Times(2);
+
+ ASSERT_TRUE(addVoiceAgent(*mVADataManager, mVoiceAgentsData[0]));
+ ASSERT_TRUE(addVoiceAgent(*mVADataManager, mVoiceAgentsData[1]));
+
+ result = mVADataManager->activateVoiceAgents({"non", "existent"});
+ ASSERT_EQ(result, 0);
+}
+
+TEST_F(VoiceAgentDataManagerTest, deactivatingNonExistentVoiceAgentsFails) {
+ uint32_t result = mVADataManager->deactivateVoiceAgents({"non", "existent"});
+ ASSERT_EQ(result, 0);
+
+ EXPECT_CALL(*mAgentsChangeObserver, OnVoiceAgentAdded(::testing::_)).Times(2);
+
+ ASSERT_TRUE(addVoiceAgent(*mVADataManager, mVoiceAgentsData[0]));
+ ASSERT_TRUE(addVoiceAgent(*mVADataManager, mVoiceAgentsData[1]));
+
+ result = mVADataManager->deactivateVoiceAgents({"non", "existent"});
+ ASSERT_EQ(result, 0);
+}
+
+TEST_F(VoiceAgentDataManagerTest, canActivateDeactivateVoiceAgents) {
+ {
+ ::testing::InSequence dummy;
+
+ EXPECT_CALL(*mAgentsChangeObserver, OnVoiceAgentAdded(::testing::_))
+ .Times(2);
+ EXPECT_CALL(*mAgentsChangeObserver, OnVoiceAgentDeactivated(::testing::_))
+ .Times(1);
+ EXPECT_CALL(*mAgentsChangeObserver, OnVoiceAgentActivated(::testing::_))
+ .Times(1);
+ }
+
+ ASSERT_TRUE(addVoiceAgent(*mVADataManager, mVoiceAgentsData[0]));
+ ASSERT_TRUE(addVoiceAgent(*mVADataManager, mVoiceAgentsData[1]));
+
+ std::string vaId = mVoiceAgentsData[0].id;
+
+ auto allVA = mVADataManager->getAllVoiceAgents();
+ auto voiceAgent = findVoiceAgent(allVA, vaId);
+ ASSERT_NE(voiceAgent, nullptr);
+ ASSERT_TRUE(voiceAgent->isActive());
+
+ uint32_t result =
+ mVADataManager->deactivateVoiceAgents({"non-existent", vaId});
+ ASSERT_EQ(result, 1);
+ ASSERT_FALSE(voiceAgent->isActive());
+
+ // Try de-activating already de-activated agent
+ result = mVADataManager->deactivateVoiceAgents({vaId});
+ ASSERT_EQ(result, 1);
+ ASSERT_FALSE(voiceAgent->isActive());
+
+ result = mVADataManager->activateVoiceAgents({"non-existent", vaId});
+ ASSERT_EQ(result, 1);
+ ASSERT_TRUE(voiceAgent->isActive());
+
+ // Try activating already activated agent
+ result = mVADataManager->activateVoiceAgents({vaId});
+ ASSERT_EQ(result, 1);
+ ASSERT_TRUE(voiceAgent->isActive());
+}
+
+TEST_F(VoiceAgentDataManagerTest,
+ NoDefaultAgentIsReturnedWhenNoDefaultAgentIsSet) {
+ EXPECT_CALL(*mAgentsChangeObserver, OnVoiceAgentAdded(::testing::_)).Times(2);
+
+ ASSERT_TRUE(addVoiceAgent(*mVADataManager, mVoiceAgentsData[0]));
+ ASSERT_TRUE(addVoiceAgent(*mVADataManager, mVoiceAgentsData[1]));
+
+ std::string defaultAgentId = mVADataManager->getDefaultVoiceAgent();
+ ASSERT_EQ(defaultAgentId, "");
+}
+
+TEST_F(VoiceAgentDataManagerTest, DefaultAgentCanBeSet) {
+ EXPECT_CALL(*mAgentsChangeObserver, OnVoiceAgentAdded(::testing::_)).Times(2);
+
+ ASSERT_TRUE(addVoiceAgent(*mVADataManager, mVoiceAgentsData[0]));
+ ASSERT_TRUE(addVoiceAgent(*mVADataManager, mVoiceAgentsData[1]));
+
+ auto allAgents = mVADataManager->getAllVoiceAgents();
+ std::string vaId1 = mVoiceAgentsData[1].id;
+ std::string vaId2 = mVoiceAgentsData[0].id;
+ auto va1 = findVoiceAgent(allAgents, vaId1);
+ auto va2 = findVoiceAgent(allAgents, vaId2);
+
+ {
+ ::testing::InSequence dummy;
+
+ EXPECT_CALL(*mAgentsChangeObserver, OnDefaultVoiceAgentChanged(va1))
+ .Times(1);
+ EXPECT_CALL(*mAgentsChangeObserver, OnDefaultVoiceAgentChanged(va2))
+ .Times(1);
+ }
+
+ ASSERT_TRUE(mVADataManager->setDefaultVoiceAgent(vaId1));
+ ASSERT_EQ(mVADataManager->getDefaultVoiceAgent(), vaId1);
+
+ ASSERT_TRUE(mVADataManager->setDefaultVoiceAgent(vaId2));
+ ASSERT_EQ(mVADataManager->getDefaultVoiceAgent(), vaId2);
+
+ ASSERT_FALSE(mVADataManager->setDefaultVoiceAgent("non-existent"));
+ ASSERT_EQ(mVADataManager->getDefaultVoiceAgent(), vaId2);
+
+ // Setting default agent to already default agent shouldn't result in extra
+ // callback to OnDefaultVoiceAgentChanged
+ ASSERT_TRUE(mVADataManager->setDefaultVoiceAgent(vaId2));
+ ASSERT_EQ(mVADataManager->getDefaultVoiceAgent(), vaId2);
+}
+
+} // namespace test
+} // namespace vshl \ No newline at end of file
diff --git a/src/plugins/voiceagents/test/VoiceAgentsTestData.h b/src/plugins/voiceagents/test/VoiceAgentsTestData.h
new file mode 100644
index 0000000..ced068f
--- /dev/null
+++ b/src/plugins/voiceagents/test/VoiceAgentsTestData.h
@@ -0,0 +1,67 @@
+/*
+ * Copyright 2018-2019 Amazon.com, Inc. or its affiliates. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License").
+ * You may not use this file except in compliance with the License.
+ * A copy of the License is located at
+ *
+ * http://aws.amazon.com/apache2.0/
+ *
+ * or in the "license" file accompanying this file. This file 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 <memory>
+#include <string>
+#include <unordered_set>
+#include <vector>
+
+namespace vshl {
+namespace test {
+
+typedef std::shared_ptr<std::unordered_set<std::string>> WakeWords;
+
+struct VoiceAgentTestData {
+ std::string id;
+ std::string name;
+ std::string description;
+ std::string api;
+ std::string vendor;
+ std::string activeWakeword;
+ bool isActive;
+ WakeWords wakewords;
+};
+
+static std::vector<VoiceAgentTestData> getVoiceAgentsTestData() {
+ std::vector<VoiceAgentTestData> voiceAgentsTestData{
+ {
+ "VA-001", // Id
+ "Foundation", // Name
+ "Voice Agent For Galactic Empire", // Description
+ "api-1", // API
+ "Asimov", // Vendor
+ "Hari Seldon", // Active Wakeword
+ true, // Is Active
+ std::shared_ptr<std::unordered_set<std::string>>(
+ new std::unordered_set<std::string>{"Hari Seldon", "Cleon I ", "Eto Demerzel"}) // Wake Words
+ },
+ {
+ "VA-002", // Id
+ "Betelgeuse", // Name
+ "Voice Agent For Galaxy hopper", // Description
+ "api-2", // API
+ "Douglas Adams", // Vendor
+ "Ford Prefect", // Active Wakeword
+ true, // Is Active
+ std::shared_ptr<std::unordered_set<std::string>>(
+ new std::unordered_set<std::string>{"Ford Prefect", "Zaphod Beeblebrox"}) // Wake Words
+ },
+ };
+
+ return voiceAgentsTestData;
+}
+
+} // namespace test
+} // namespace vshl