Add test utility classes 59/296659/1
authorSuyeon Hwang <stom.hwang@samsung.com>
Thu, 13 Jul 2023 07:58:01 +0000 (16:58 +0900)
committerTizen AI <ai.tzn.sec@samsung.com>
Thu, 3 Aug 2023 01:46:05 +0000 (10:46 +0900)
- Contents:
This patch introduces new utility classes for test case. Through these
classes, developers can easily make the test cases. These new classes
provide many useful utility methods and frequently used code blocks.

Change-Id: I955ac4f97fc790baa7bbfa796b2fc63e570ea3c2
Signed-off-by: Suyeon Hwang <stom.hwang@samsung.com>
tests/src/vc_common_test_util.cpp [new file with mode: 0644]
tests/src/vc_common_test_util.h [new file with mode: 0644]
tests/src/vc_mgr_test_util.cpp [new file with mode: 0644]
tests/src/vc_mgr_test_util.h [new file with mode: 0644]
tests/src/vc_test_util.cpp [new file with mode: 0644]
tests/src/vc_test_util.h [new file with mode: 0644]

diff --git a/tests/src/vc_common_test_util.cpp b/tests/src/vc_common_test_util.cpp
new file mode 100644 (file)
index 0000000..a230eba
--- /dev/null
@@ -0,0 +1,190 @@
+/*
+ * Copyright (c) 2023 Samsung Electronics Co., Ltd.
+ *
+ * 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 <gtest/gtest.h>
+#include <app_manager_extension.h>
+#include <system_info.h>
+#include <tzplatform_config.h>
+#include <vconf.h>
+#include <Ecore.h>
+
+#include <voice_control_manager.h>
+#include <voice_control_setting.h>
+#include <voice_control_common.h>
+#include <voice_control_command.h>
+#include <voice_control_command_expand.h>
+
+#include "vc_common_test_util.h"
+
+
+static const char *TEST_COMMAND_JSON_PATH = tzplatform_mkpath(tzplatform_getid("TZ_SYS_RO_APP"), "/org.tizen.vc-unittests/res/test_command.json");
+static const char *TEST_EMPTY_FILE_PATH = tzplatform_mkpath(tzplatform_getid("TZ_SYS_RO_APP"), "/org.tizen.vc-unittests/res/empty_file");
+
+
+vc_cmd_h VcCommonTestUtility::CreateTestCommand(const char *commandText)
+{
+       vc_cmd_h command = nullptr;
+
+       EXPECT_EQ(vc_cmd_create(&command), VC_ERROR_NONE);
+       EXPECT_EQ(vc_cmd_set_command(command, commandText), VC_ERROR_NONE);
+       EXPECT_EQ(vc_cmd_set_unfixed_command(command, commandText), VC_ERROR_NONE);
+
+       return command;
+}
+
+vc_cmd_list_h VcCommonTestUtility::CreateTestCommandList()
+{
+       vc_cmd_h command1 = CreateTestCommand("test");
+       EXPECT_EQ(vc_cmd_set_type(command1, VC_COMMAND_TYPE_FOREGROUND), VC_ERROR_NONE);
+
+       vc_cmd_h command2 = CreateTestCommand("background");
+       EXPECT_EQ(vc_cmd_set_type(command2, VC_COMMAND_TYPE_BACKGROUND), VC_ERROR_NONE);
+
+       vc_cmd_list_h commands = nullptr;
+       EXPECT_EQ(vc_cmd_list_create(&commands), VC_ERROR_NONE);
+       EXPECT_EQ(vc_cmd_list_add(commands, command1), VC_ERROR_NONE);
+       EXPECT_EQ(vc_cmd_list_add(commands, command2), VC_ERROR_NONE);
+
+       return commands;
+}
+
+vc_cmd_list_h VcCommonTestUtility::CreateSystemCommandList()
+{
+       vc_cmd_h command1 = CreateTestCommand("test");
+       EXPECT_EQ(vc_cmd_set_type(command1, VC_COMMAND_TYPE_SYSTEM), VC_ERROR_NONE);
+
+       vc_cmd_h command2 = CreateTestCommand("background");
+       EXPECT_EQ(vc_cmd_set_type(command2, VC_COMMAND_TYPE_SYSTEM_BACKGROUND), VC_ERROR_NONE);
+
+       vc_cmd_list_h commands = nullptr;
+       EXPECT_EQ(vc_cmd_list_create(&commands), VC_ERROR_NONE);
+       EXPECT_EQ(vc_cmd_list_add(commands, command1), VC_ERROR_NONE);
+       EXPECT_EQ(vc_cmd_list_add(commands, command2), VC_ERROR_NONE);
+
+       return commands;
+}
+
+void VcCommonTestUtility::TerminateCurrentEngine()
+{
+       char* engineId = vconf_get_str(VCONFKEY_VC_ENGINE_DEFAULT);
+
+       app_context_h context = nullptr;
+       app_manager_get_app_context(engineId, &context);
+       free(engineId);
+
+       ASSERT_NE(context, nullptr);
+
+       EXPECT_EQ(app_manager_terminate_app(context), APP_MANAGER_ERROR_NONE);
+       EXPECT_EQ(app_context_destroy(context), APP_MANAGER_ERROR_NONE);
+}
+
+void VcCommonTestUtility::WaitUntilEngineTerminated(int duration)
+{
+       auto engineChcker = [](void) {
+               bool is_running = false;
+
+               char* engineId = vconf_get_str(VCONFKEY_VC_ENGINE_DEFAULT);
+               app_manager_is_running(engineId, &is_running);
+               free(engineId);
+
+               return !is_running;
+       };
+
+       WaitCondtion(engineChcker, duration);
+}
+
+bool VcCommonTestUtility::IsVcFeatureSupported()
+{
+       bool isVcSupported = false;
+       if (SYSTEM_INFO_ERROR_NONE != system_info_get_platform_bool("http://tizen.org/feature/speech.control", &isVcSupported)) {
+               return false;
+       }
+
+       bool isMicSupported = false;
+       if (SYSTEM_INFO_ERROR_NONE != system_info_get_platform_bool("http://tizen.org/feature/microphone", &isMicSupported)) {
+               return false;
+       }
+
+       return isVcSupported && isMicSupported;
+}
+
+bool VcCommonTestUtility::IsVcMgrFeatureSupported()
+{
+       bool isVcSupported = false;
+       if (SYSTEM_INFO_ERROR_NONE != system_info_get_platform_bool("http://tizen.org/feature/speech.control_manager", &isVcSupported)) {
+               return false;
+       }
+
+       bool isMicSupported = false;
+       if (SYSTEM_INFO_ERROR_NONE != system_info_get_platform_bool("http://tizen.org/feature/microphone", &isMicSupported)) {
+               return false;
+       }
+
+       return isVcSupported && isMicSupported;
+}
+
+const char *VcCommonTestUtility::GetCommandJsonFilePath()
+{
+       return TEST_COMMAND_JSON_PATH;
+}
+
+const char *VcCommonTestUtility::GetCommandEmptyFilePath()
+{
+       return TEST_EMPTY_FILE_PATH;
+}
+
+void VcCommonTestUtility::SetCurrentLanguage(const char *language)
+{
+       vc_setting_initialize();
+       vc_setting_set_language("en_US");
+       vc_setting_deinitialize();
+}
+
+void VcCommonTestUtility::EnableAutoLanguageSelection()
+{
+       vc_setting_initialize();
+       vc_setting_set_auto_language(true);
+       vc_setting_deinitialize();
+}
+
+bool VcCommonTestUtility::WaitCondtion(std::function<bool(void)> checker, int duration)
+{
+       auto mainLoopQuitTimer = ecore_timer_add(static_cast<double>(duration), [](void *data) -> Eina_Bool {
+               ecore_main_loop_quit();
+               return EINA_FALSE;
+       }, nullptr);
+
+       auto checkerTimer = ecore_timer_add(0.0, [](void *data) -> Eina_Bool {
+               auto &checker = *reinterpret_cast<std::function<bool()> *>(data);
+               if (false == checker()) {
+                       return EINA_TRUE;
+               }
+
+               ecore_main_loop_quit();
+               return EINA_FALSE;
+       }, &checker);
+
+       ecore_main_loop_begin();
+
+       ecore_timer_del(mainLoopQuitTimer);
+       mainLoopQuitTimer = nullptr;
+
+       ecore_timer_del(checkerTimer);
+       checkerTimer = nullptr;
+
+       return checker();
+}
diff --git a/tests/src/vc_common_test_util.h b/tests/src/vc_common_test_util.h
new file mode 100644 (file)
index 0000000..c37c1ac
--- /dev/null
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2023 Samsung Electronics Co., Ltd.
+ *
+ * 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 __VC_COMMON_TEST_UTIL_H__
+#define __VC_COMMON_TEST_UTIL_H__
+
+
+#include <functional>
+#include <voice_control_command.h>
+
+
+class VcCommonTestUtility {
+public:
+       static vc_cmd_h CreateTestCommand(const char *commandText);
+       static vc_cmd_list_h CreateTestCommandList();
+       static vc_cmd_list_h CreateSystemCommandList();
+
+       static void TerminateCurrentEngine();
+       static void WaitUntilEngineTerminated(int duration);
+       static bool IsVcFeatureSupported();
+       static bool IsVcMgrFeatureSupported();
+       static const char *GetCommandJsonFilePath();
+       static const char *GetCommandEmptyFilePath();
+
+       static void SetCurrentLanguage(const char *language);
+       static void EnableAutoLanguageSelection();
+
+       static bool WaitCondtion(std::function<bool(void)> checker, int duration);
+};
+
+
+#endif  /* __VC_COMMON_TEST_UTIL_H__ */
diff --git a/tests/src/vc_mgr_test_util.cpp b/tests/src/vc_mgr_test_util.cpp
new file mode 100644 (file)
index 0000000..699526f
--- /dev/null
@@ -0,0 +1,280 @@
+/*
+ * Copyright (c) 2023 Samsung Electronics Co., Ltd.
+ *
+ * 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 <gtest/gtest.h>
+#include <tzplatform_config.h>
+
+#include "vc_common_test_util.h"
+#include "vc_mgr_test_util.h"
+
+
+VcMgrTestUtility::VcMgrTestUtility()
+{
+       mCurrentState = VC_STATE_NONE;
+       mCurrentServiceState = VC_SERVICE_STATE_NONE;
+       mDefaultCommandList = nullptr;
+
+       mErrorOccured = false;
+       mGetErrorMessageReturn = VC_ERROR_OPERATION_FAILED;
+       mAllResultReceived = false;
+       mSetSelectedResultReturn = VC_ERROR_OPERATION_FAILED;
+       mResultReceived = false;
+       mSpeechDetected = false;
+
+       mErrorMessage = nullptr;
+
+       mPCMData = nullptr;
+       mPCMSize = 0;
+}
+
+VcMgrTestUtility::~VcMgrTestUtility()
+{
+       vc_cmd_list_destroy(mDefaultCommandList, true);
+       mDefaultCommandList = nullptr;
+
+       free(mErrorMessage);
+       mErrorMessage = nullptr;
+
+       free(mPCMData);
+       mPCMData = nullptr;
+       mPCMSize = 0;
+
+       Deinitialize();
+}
+
+void VcMgrTestUtility::StateChangedCallback(vc_state_e previous, vc_state_e current, void *user_data)
+{
+       auto instance = reinterpret_cast<VcMgrTestUtility *>(user_data);
+       instance->mCurrentState = current;
+}
+
+void VcMgrTestUtility::ServiceStateChangedCallback(vc_service_state_e previous, vc_service_state_e current, void* user_data)
+{
+       auto instance = reinterpret_cast<VcMgrTestUtility *>(user_data);
+       instance->mCurrentServiceState = current;
+}
+
+void VcMgrTestUtility::ErrorCallback(vc_error_e reason, void *user_data)
+{
+       auto instance = reinterpret_cast<VcMgrTestUtility *>(user_data);
+       instance->mErrorOccured = true;
+
+       char *error = nullptr;
+       instance->mGetErrorMessageReturn = vc_mgr_get_error_message(&error);
+       free(error);
+}
+
+bool VcMgrTestUtility::AllResultCallback(vc_result_event_e event, vc_cmd_list_h vc_cmd_list, const char *result, const char *msg, void *user_data)
+{
+       auto instance = reinterpret_cast<VcMgrTestUtility *>(user_data);
+
+       instance->mAllResultReceived = true;
+       instance->mSetSelectedResultReturn = vc_mgr_set_selected_results(instance->mDefaultCommandList);
+       return false;
+}
+
+void VcMgrTestUtility::ResultCallback(vc_result_event_e event, vc_cmd_list_h vc_cmd_list, const char* result, void *user_data)
+{
+       auto instance = reinterpret_cast<VcMgrTestUtility *>(user_data);
+       instance->mResultReceived = true;
+}
+
+void VcMgrTestUtility::SpeechDetectedCallback(void *user_data)
+{
+       auto instance = reinterpret_cast<VcMgrTestUtility *>(user_data);
+       instance->mSpeechDetected = true;
+}
+
+void VcMgrTestUtility::GetTestPCMData()
+{
+       const char* pcm_path = tzplatform_mkpath(tzplatform_getid("TZ_SYS_RO_APP"), "/org.tizen.vc-unittests/res/test_pcm.dat");
+       FILE* fp_in = fopen(pcm_path, "rb");
+       if (fp_in == nullptr) {
+               return;
+       }
+
+       fseek(fp_in, 0, SEEK_END);
+       long size = ftell(fp_in);
+       fseek(fp_in, 0, SEEK_SET);
+       if (size <= 0) {
+               fclose(fp_in);
+               return;
+       }
+
+       unsigned char* data = reinterpret_cast<unsigned char *>(calloc(sizeof(unsigned char), size));
+       if (nullptr == data) {
+               fclose(fp_in);
+               return;
+       }
+
+       size_t read_size = fread(data, sizeof(char), size, fp_in);
+       fclose(fp_in);
+
+       if (read_size <= 0) {
+               free(data);
+               return;
+       }
+
+       mPCMSize = size;
+       mPCMData = data;
+}
+
+void VcMgrTestUtility::Initialize()
+{
+       if (VcCommonTestUtility::IsVcFeatureSupported() == false) {
+               return;
+       }
+
+       vc_mgr_initialize();
+
+       vc_mgr_set_state_changed_cb(StateChangedCallback, this);
+       vc_mgr_set_service_state_changed_cb(ServiceStateChangedCallback, this);
+       vc_mgr_set_error_cb(ErrorCallback, this);
+       vc_mgr_set_all_result_cb(AllResultCallback, this);
+}
+
+void VcMgrTestUtility::Deinitialize()
+{
+       vc_mgr_deinitialize();
+}
+
+bool VcMgrTestUtility::IsStateChanged(vc_state_e targetState, int duration)
+{
+       auto stateChecker = std::bind([](VcMgrTestUtility *instance, vc_state_e target) {
+               return target == instance->mCurrentState;
+       }, this, targetState);
+
+       return VcCommonTestUtility::WaitCondtion(stateChecker, duration);
+}
+
+bool VcMgrTestUtility::IsServiceStateChanged(vc_service_state_e targetState, int duration)
+{
+       auto serviceStateChecker = std::bind([](VcMgrTestUtility *instance, vc_service_state_e target) {
+               return target == instance->mCurrentServiceState;
+       }, this, targetState);
+
+       return VcCommonTestUtility::WaitCondtion(serviceStateChecker, duration);
+}
+
+bool VcMgrTestUtility::IsErrorOccurring(int duration)
+{
+       auto errorChecker = std::bind([](VcMgrTestUtility *instance) {
+               return instance->mErrorOccured;
+       }, this);
+
+       return VcCommonTestUtility::WaitCondtion(errorChecker, duration);
+}
+
+bool VcMgrTestUtility::IsAllResultReceived(int duration)
+{
+       auto resultChecker = std::bind([](VcMgrTestUtility *instance) {
+               return instance->mAllResultReceived;
+       }, this);
+
+       return VcCommonTestUtility::WaitCondtion(resultChecker, duration);
+}
+
+bool VcMgrTestUtility::IsResultReceived(int duration)
+{
+       auto resultChecker = std::bind([](VcMgrTestUtility *instance) {
+               return instance->mResultReceived;
+       }, this);
+
+       return VcCommonTestUtility::WaitCondtion(resultChecker, duration);
+}
+
+bool VcMgrTestUtility::IsSpeechDetected(int duration)
+{
+       auto resultChecker = std::bind([](VcMgrTestUtility *instance) {
+               return instance->mSpeechDetected;
+       }, this);
+
+       return VcCommonTestUtility::WaitCondtion(resultChecker, duration);
+}
+
+bool VcMgrTestUtility::Prepare()
+{
+       vc_state_e state = VC_STATE_INITIALIZED;
+       vc_mgr_get_state(&state);
+       if (VC_STATE_INITIALIZED != state) {
+               return false;
+       }
+
+       vc_mgr_prepare();
+       return IsStateChanged(VC_STATE_READY, 5);
+}
+
+bool VcMgrTestUtility::Unprepare()
+{
+       vc_state_e state = VC_STATE_INITIALIZED;
+       vc_mgr_get_state(&state);
+       if (VC_STATE_READY != state) {
+               return false;
+       }
+
+       vc_mgr_unprepare();
+       return IsStateChanged(VC_STATE_INITIALIZED, 5);
+}
+
+void VcMgrTestUtility::SetDefaultCommands()
+{
+       mDefaultCommandList = VcCommonTestUtility::CreateSystemCommandList();
+       vc_mgr_set_command_list(mDefaultCommandList);
+}
+
+bool VcMgrTestUtility::Start(bool isExclusive)
+{
+       EXPECT_EQ(vc_mgr_start(isExclusive), VC_ERROR_NONE);
+       return IsServiceStateChanged(VC_SERVICE_STATE_RECORDING, 5);
+}
+
+bool VcMgrTestUtility::Stop()
+{
+       EXPECT_EQ(vc_mgr_stop(), VC_ERROR_NONE);
+       return IsServiceStateChanged(VC_SERVICE_STATE_PROCESSING, 5);
+}
+
+bool VcMgrTestUtility::Cancel()
+{
+       EXPECT_EQ(vc_mgr_cancel(), VC_ERROR_NONE);
+       return IsServiceStateChanged(VC_SERVICE_STATE_READY, 5);
+}
+
+void VcMgrTestUtility::SimulateVoiceRecording()
+{
+       EXPECT_EQ(vc_mgr_set_recognition_mode(VC_RECOGNITION_MODE_MANUAL), VC_ERROR_NONE);
+       EXPECT_EQ(vc_mgr_set_audio_streaming_mode(VC_AUDIO_STREAMING_MODE_OUTSIDE), VC_ERROR_NONE);
+
+       SetDefaultCommands();
+       ASSERT_EQ(Start(false), true);
+
+       GetTestPCMData();
+
+       const size_t shift_size = 12000;
+       int data_num = mPCMSize / shift_size;
+       for (int i = 0; i <= data_num; i++ ) {
+               if (0 == i) {
+                       EXPECT_EQ(vc_mgr_send_audio_streaming(VC_AUDIO_STREAMING_EVENT_START, &mPCMData[i*shift_size], shift_size), VC_ERROR_NONE);
+               } else if (data_num == i) {
+                       EXPECT_EQ(vc_mgr_send_audio_streaming(VC_AUDIO_STREAMING_EVENT_FINISH, &mPCMData[i*shift_size], mPCMSize % shift_size), VC_ERROR_NONE);
+               } else {
+                       EXPECT_EQ(vc_mgr_send_audio_streaming(VC_AUDIO_STREAMING_EVENT_CONTINUE, &mPCMData[i*shift_size], shift_size), VC_ERROR_NONE);
+               }
+       }
+
+       ASSERT_EQ(Stop(), true);
+}
diff --git a/tests/src/vc_mgr_test_util.h b/tests/src/vc_mgr_test_util.h
new file mode 100644 (file)
index 0000000..2d8dd92
--- /dev/null
@@ -0,0 +1,81 @@
+/*
+ * Copyright (c) 2023 Samsung Electronics Co., Ltd.
+ *
+ * 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 __VC_MGR_TEST_UTIL_H__
+#define __VC_MGR_TEST_UTIL_H__
+
+
+#include <voice_control_manager.h>
+#include <voice_control_manager_internal.h>
+
+
+class VcMgrTestUtility {
+public:
+       static void StateChangedCallback(vc_state_e previous, vc_state_e current, void *user_data);
+       static void ServiceStateChangedCallback(vc_service_state_e previous, vc_service_state_e current, void* user_data);
+       static void ErrorCallback(vc_error_e reason, void *user_data);
+       static bool AllResultCallback(vc_result_event_e event, vc_cmd_list_h vc_cmd_list, const char *result, const char *msg, void *user_data);
+       static void ResultCallback(vc_result_event_e event, vc_cmd_list_h vc_cmd_list, const char* result, void *user_data);
+       static void SpeechDetectedCallback(void *user_data);
+
+public:
+       VcMgrTestUtility();
+       ~VcMgrTestUtility();
+
+       void GetTestPCMData();
+
+       void Initialize();
+       void Deinitialize();
+
+       bool Prepare();
+       bool Unprepare();
+
+       void SetDefaultCommands();
+
+       bool Start(bool isExclusive);
+       bool Stop();
+       bool Cancel();
+
+       void SimulateVoiceRecording();
+
+       bool IsStateChanged(vc_state_e targetState, int duration);
+       bool IsServiceStateChanged(vc_service_state_e targetState, int duration);
+       bool IsErrorOccurring(int duration);
+       bool IsAllResultReceived(int duration);
+       bool IsResultReceived(int duration);
+       bool IsSpeechDetected(int duration);
+
+public:
+       vc_state_e mCurrentState;
+       vc_service_state_e mCurrentServiceState;
+       vc_cmd_list_h mDefaultCommandList;
+
+       bool mErrorOccured;
+       int mGetErrorMessageReturn;
+       bool mAllResultReceived;
+       int mSetSelectedResultReturn;
+       bool mResultReceived;
+       bool mSpeechDetected;
+
+       char *mErrorMessage;
+
+       unsigned char* mPCMData;
+       size_t mPCMSize;
+};
+
+
+#endif  /* __VC_MGR_TEST_UTIL_H__ */
diff --git a/tests/src/vc_test_util.cpp b/tests/src/vc_test_util.cpp
new file mode 100644 (file)
index 0000000..3788465
--- /dev/null
@@ -0,0 +1,148 @@
+/*
+ * Copyright (c) 2023 Samsung Electronics Co., Ltd.
+ *
+ * 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 <gtest/gtest.h>
+
+#include "vc_common_test_util.h"
+#include "vc_test_util.h"
+
+
+VcTestUtility::VcTestUtility()
+{
+       mCurrentState = VC_STATE_NONE;
+       mCurrentServiceState = VC_SERVICE_STATE_NONE;
+       mErrorOccured = false;
+       mResultReceived = false;
+
+       mErrorMessage = nullptr;
+
+       mTestCommands = VcCommonTestUtility::CreateTestCommandList();
+}
+
+VcTestUtility::~VcTestUtility()
+{
+       free(mErrorMessage);
+       mErrorMessage = nullptr;
+
+       vc_cmd_list_destroy(mTestCommands, true);
+       mTestCommands = nullptr;
+
+       Deinitialize();
+}
+
+void VcTestUtility::StateChangedCallback(vc_state_e previous, vc_state_e current, void *user_data)
+{
+       auto instance = reinterpret_cast<VcTestUtility *>(user_data);
+       instance->mCurrentState = current;
+}
+
+void VcTestUtility::ServiceStateChangedCallback(vc_service_state_e previous, vc_service_state_e current, void* user_data)
+{
+       auto instance = reinterpret_cast<VcTestUtility *>(user_data);
+       instance->mCurrentServiceState = current;
+}
+
+void VcTestUtility::ErrorCallback(vc_error_e reason, void *user_data)
+{
+       auto instance = reinterpret_cast<VcTestUtility *>(user_data);
+       instance->mErrorOccured = true;
+}
+
+void VcTestUtility::ResultCallback(vc_result_event_e event, vc_cmd_list_h vc_cmd_list, const char* result, void *user_data)
+{
+       auto instance = reinterpret_cast<VcTestUtility *>(user_data);
+       instance->mResultReceived = true;
+}
+
+void VcTestUtility::Initialize()
+{
+       if (VcCommonTestUtility::IsVcFeatureSupported() == false) {
+               return;
+       }
+
+       EXPECT_EQ(vc_initialize(), VC_ERROR_NONE);
+
+       EXPECT_EQ(vc_set_state_changed_cb(StateChangedCallback, this), VC_ERROR_NONE);
+       EXPECT_EQ(vc_set_service_state_changed_cb(ServiceStateChangedCallback, this), VC_ERROR_NONE);
+       EXPECT_EQ(vc_set_error_cb(ErrorCallback, this), VC_ERROR_NONE);
+}
+
+void VcTestUtility::Deinitialize()
+{
+       vc_deinitialize();
+}
+
+bool VcTestUtility::IsStateChanged(vc_state_e targetState, int duration)
+{
+       auto stateChecker = std::bind([](VcTestUtility *instance, vc_state_e target) {
+               return target == instance->mCurrentState;
+       }, this, targetState);
+
+       return VcCommonTestUtility::WaitCondtion(stateChecker, duration);
+}
+
+bool VcTestUtility::IsServiceStateChanged(vc_service_state_e targetState, int duration)
+{
+       auto serviceStateChecker = std::bind([](VcTestUtility *instance, vc_service_state_e target) {
+               return target == instance->mCurrentServiceState;
+       }, this, targetState);
+
+       return VcCommonTestUtility::WaitCondtion(serviceStateChecker, duration);
+}
+
+bool VcTestUtility::IsErrorOccurring(int duration)
+{
+       auto errorChecker = std::bind([](VcTestUtility *instance) {
+               return instance->mErrorOccured;
+       }, this);
+
+       return VcCommonTestUtility::WaitCondtion(errorChecker, duration);
+}
+
+bool VcTestUtility::IsResultReceived(int duration)
+{
+       auto resultChecker = std::bind([](VcTestUtility *instance) {
+               return instance->mResultReceived;
+       }, this);
+
+       return VcCommonTestUtility::WaitCondtion(resultChecker, duration);
+}
+
+bool VcTestUtility::Prepare()
+{
+       vc_state_e state = VC_STATE_INITIALIZED;
+       vc_get_state(&state);
+       if (VC_STATE_INITIALIZED != state) {
+               return false;
+       }
+
+       vc_prepare();
+       return IsStateChanged(VC_STATE_READY, 5);
+}
+
+bool VcTestUtility::Unprepare()
+{
+       vc_state_e state = VC_STATE_INITIALIZED;
+       vc_get_state(&state);
+       if (VC_STATE_READY != state) {
+               return false;
+       }
+
+       vc_unprepare();
+       return IsStateChanged(VC_STATE_INITIALIZED, 5);
+}
+
diff --git a/tests/src/vc_test_util.h b/tests/src/vc_test_util.h
new file mode 100644 (file)
index 0000000..51e94d3
--- /dev/null
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 2023 Samsung Electronics Co., Ltd.
+ *
+ * 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 __VC_TEST_UTIL_H__
+#define __VC_TEST_UTIL_H__
+
+
+#include <voice_control.h>
+#include <voice_control_internal.h>
+
+
+class VcTestUtility {
+public:
+       static void StateChangedCallback(vc_state_e previous, vc_state_e current, void *user_data);
+       static void ServiceStateChangedCallback(vc_service_state_e previous, vc_service_state_e current, void* user_data);
+       static void ErrorCallback(vc_error_e reason, void *user_data);
+       static void ResultCallback(vc_result_event_e event, vc_cmd_list_h vc_cmd_list, const char* result, void *user_data);
+
+public:
+       VcTestUtility();
+       ~VcTestUtility();
+
+       void Initialize();
+       void Deinitialize();
+
+       bool Prepare();
+       bool Unprepare();
+
+       bool IsStateChanged(vc_state_e targetState, int duration);
+       bool IsServiceStateChanged(vc_service_state_e targetState, int duration);
+       bool IsErrorOccurring(int duration);
+       bool IsResultReceived(int duration);
+
+public:
+       vc_state_e mCurrentState;
+       vc_service_state_e mCurrentServiceState;
+
+       bool mErrorOccured;
+       bool mResultReceived;
+
+       char *mErrorMessage;
+       vc_cmd_list_h mTestCommands;
+};
+
+
+#endif  /* __VC_TEST_UTIL_H__ */