Add test utility class 84/295384/3
authorSuyeon Hwang <stom.hwang@samsung.com>
Wed, 5 Jul 2023 12:11:53 +0000 (21:11 +0900)
committerSuyeon Hwang <stom.hwang@samsung.com>
Thu, 13 Jul 2023 06:25:35 +0000 (15:25 +0900)
- Contents:
This patch introduces new utility class for test case. Through this
class, developers can easily make the test cases. This new class
provides many useful utility methods and frequently used code blocks.

Change-Id: Ia76c9eed7345f98421a89da7c302c59794b311d3
Signed-off-by: Suyeon Hwang <stom.hwang@samsung.com>
CMakeLists.txt
tests/src/test_util.cpp [new file with mode: 0644]
tests/src/test_util.h [new file with mode: 0644]

index 86519ac..aa317cc 100644 (file)
@@ -40,12 +40,12 @@ INCLUDE(FindPkgConfig)
 IF("${_TV_PRODUCT}" STREQUAL "TRUE")
 pkg_check_modules(pkgs REQUIRED
        aul capi-media-audio-io capi-media-wav-player capi-network-bluetooth capi-network-bluetooth-tv capi-system-info cynara-client cynara-session
-       dbus-1 dlog ecore glib-2.0 libgum libtzplatform-config libxml-2.0 vconf vconf-internal-keys buxton2 gmock farfield-voice-api
+       dbus-1 dlog ecore glib-2.0 libgum libtzplatform-config libxml-2.0 vconf vconf-internal-keys buxton2 gmock farfield-voice-api capi-appfw-app-manager
 )
 ELSE()
 pkg_check_modules(pkgs REQUIRED
        aul capi-media-audio-io capi-media-wav-player capi-system-info cynara-client cynara-session
-       dbus-1 dlog ecore glib-2.0 libgum libtzplatform-config libxml-2.0 vconf vconf-internal-keys buxton2 gmock
+       dbus-1 dlog ecore glib-2.0 libgum libtzplatform-config libxml-2.0 vconf vconf-internal-keys buxton2 gmock capi-appfw-app-manager
 )
 ENDIF()
 
diff --git a/tests/src/test_util.cpp b/tests/src/test_util.cpp
new file mode 100644 (file)
index 0000000..f52b074
--- /dev/null
@@ -0,0 +1,318 @@
+/*
+ * 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 <app_manager_extension.h>
+#include <tzplatform_config.h>
+#include <system_info.h>
+#include <vconf.h>
+#include <gtest/gtest.h>
+#include <Ecore.h>
+
+#include "test_util.h"
+
+
+SttTestUtility::SttTestUtility()
+{
+       mHandle = nullptr;
+       mCurrentState = STT_STATE_CREATED;
+       mErrorOccured = false;
+       mResultReceived = false;
+       mErrorMessage = nullptr;
+
+       mPCMData = nullptr;
+       mPCMSize = 0;
+
+       CreateHandle();
+}
+
+SttTestUtility::~SttTestUtility()
+{
+       UnsetTestMode();
+       DestroyHandle();
+
+       free(mErrorMessage);
+       mErrorMessage = nullptr;
+
+       free(mPCMData);
+       mPCMData = nullptr;
+       mPCMSize = 0;
+}
+
+void SttTestUtility::StateChangedCallback(stt_h tts, stt_state_e previous, stt_state_e current, void *user_data)
+{
+       auto instance = reinterpret_cast<SttTestUtility *>(user_data);
+       instance->mCurrentState = current;
+}
+
+void SttTestUtility::ErrorCallback(stt_h stt, stt_error_e reason, void *user_data)
+{
+       auto instance = reinterpret_cast<SttTestUtility *>(user_data);
+       instance->mErrorOccured = true;
+
+       char *errorMessage = nullptr;
+       ASSERT_EQ(stt_get_error_message(instance->mHandle, &errorMessage), STT_ERROR_NONE);
+
+       free(instance->mErrorMessage);
+       instance->mErrorMessage = errorMessage;
+}
+
+void SttTestUtility::RecognitionResultCallback(stt_h stt, stt_result_event_e event, const char** data, int data_count, const char* msg, void *user_data)
+{
+       auto instance = reinterpret_cast<SttTestUtility *>(user_data);
+       instance->mResultReceived = true;
+}
+
+
+void SttTestUtility::TerminateCurrentEngine()
+{
+       char* engineId = vconf_get_str(VCONFKEY_STT_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 SttTestUtility::WaitUntilEngineTerminated(int duration)
+{
+       auto engineChcker = [](void) {
+               bool is_running = false;
+
+               char* engineId = vconf_get_str(VCONFKEY_STT_ENGINE_DEFAULT);
+               app_manager_is_running(engineId, &is_running);
+               free(engineId);
+
+               return !is_running;
+       };
+
+       WaitCondtion(engineChcker, duration);
+}
+
+bool SttTestUtility::IsFeatureSupported()
+{
+       bool isSttSupported = false;
+       if (SYSTEM_INFO_ERROR_NONE != system_info_get_platform_bool("http://tizen.org/feature/speech.recognition", &isSttSupported)) {
+               return false;
+       }
+
+       bool isMicSupported = false;
+       if (SYSTEM_INFO_ERROR_NONE != system_info_get_platform_bool("http://tizen.org/feature/microphone", &isMicSupported)) {
+               return false;
+       }
+
+       return isSttSupported && isMicSupported;
+}
+
+void SttTestUtility::GetTestPCMData()
+{
+       static const char* PCM_PATH = tzplatform_mkpath(tzplatform_getid("TZ_SYS_RO_APP"), "/org.tizen.stt-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;
+       }
+
+       char* data = reinterpret_cast<char *>(calloc(sizeof(char), size));
+       if (NULL == 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 SttTestUtility::CreateHandle()
+{
+       if (IsFeatureSupported() == false) {
+               mHandle = nullptr;
+               return;
+       }
+
+       stt_create(&mHandle);
+       ASSERT_NE(mHandle, nullptr);
+
+       EXPECT_EQ(stt_set_state_changed_cb(mHandle, StateChangedCallback, this), STT_ERROR_NONE);
+       EXPECT_EQ(stt_set_error_cb(mHandle, ErrorCallback, this), STT_ERROR_NONE);
+}
+
+void SttTestUtility::DestroyHandle()
+{
+       if (nullptr != mHandle) {
+               EXPECT_EQ(stt_destroy(mHandle), STT_ERROR_NONE);
+               mHandle = nullptr;
+       }
+}
+
+void SttTestUtility::SetTestMode()
+{
+       stt_state_e state = STT_STATE_CREATED;
+       ASSERT_EQ(stt_get_state(mHandle, &state), STT_ERROR_NONE);
+       ASSERT_EQ(state, STT_STATE_READY);
+       EXPECT_EQ(stt_set_private_data(mHandle, "stt_verification", "true"), STT_ERROR_NONE);
+}
+
+void SttTestUtility::UnsetTestMode()
+{
+       stt_state_e state = STT_STATE_CREATED;
+       stt_get_state(mHandle, &state);
+       if (STT_STATE_READY != state) {
+               return;
+       }
+
+       stt_set_private_data(mHandle, "stt_verification", "false");
+}
+
+bool SttTestUtility::IsStateChanged(stt_state_e targetState, int duration)
+{
+       auto stateChecker = std::bind([](SttTestUtility *instance, stt_state_e target) {
+               return target == instance->mCurrentState;
+       }, this, targetState);
+
+       return WaitCondtion(stateChecker, duration);
+}
+
+bool SttTestUtility::IsErrorOccurring(int duration)
+{
+       auto errorChecker = std::bind([](SttTestUtility *instance) {
+               return instance->mErrorOccured;
+       }, this);
+
+       return WaitCondtion(errorChecker, duration);
+}
+
+bool SttTestUtility::IsResultReceived(int duration)
+{
+       auto resultChecker = std::bind([](SttTestUtility *instance) {
+               return instance->mResultReceived;
+       }, this);
+
+       return WaitCondtion(resultChecker, duration);
+}
+
+bool SttTestUtility::Prepare()
+{
+       stt_state_e state = STT_STATE_CREATED;
+       stt_get_state(mHandle, &state);
+       if (STT_STATE_CREATED != state) {
+               return false;
+       }
+
+       stt_prepare(mHandle);
+       return IsStateChanged(STT_STATE_READY, 5);
+}
+
+bool SttTestUtility::Unprepare()
+{
+       stt_state_e state = STT_STATE_CREATED;
+       stt_get_state(mHandle, &state);
+       if (STT_STATE_READY != state) {
+               return false;
+       }
+
+       stt_unprepare(mHandle);
+       return IsStateChanged(STT_STATE_CREATED, 5);
+}
+
+bool SttTestUtility::Start(const char* language, const char* type)
+{
+       EXPECT_EQ(stt_start(mHandle, language, type), STT_ERROR_NONE);
+       return IsStateChanged(STT_STATE_RECORDING, 5);
+}
+
+bool SttTestUtility::Stop()
+{
+       EXPECT_EQ(stt_stop(mHandle), STT_ERROR_NONE);
+       return IsStateChanged(STT_STATE_PROCESSING, 5);
+}
+
+bool SttTestUtility::StartAudioStreaming(const char* language, const char* type)
+{
+       EXPECT_EQ(stt_start_audio_streaming(mHandle, language, type), STT_ERROR_NONE);
+       return IsStateChanged(STT_STATE_RECORDING, 5);
+}
+
+bool SttTestUtility::StopAudioStreaming()
+{
+       EXPECT_EQ(stt_stop_audio_streaming(mHandle), STT_ERROR_NONE);
+       return IsStateChanged(STT_STATE_PROCESSING, 5);
+}
+
+bool SttTestUtility::Cancel()
+{
+       stt_state_e state = STT_STATE_CREATED;
+       stt_get_state(mHandle, &state);
+       if (STT_STATE_READY == state || STT_STATE_CREATED == state) {
+               return false;
+       }
+
+       EXPECT_EQ(stt_cancel(mHandle), STT_ERROR_NONE);
+       return IsStateChanged(STT_STATE_READY, 5);
+}
+
+
+bool SttTestUtility::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);
+
+       if (nullptr == mainLoopQuitTimer || nullptr == checkerTimer) {
+               return false;
+       }
+
+       ecore_main_loop_begin();
+
+       ecore_timer_del(mainLoopQuitTimer);
+       mainLoopQuitTimer = nullptr;
+
+       ecore_timer_del(checkerTimer);
+       checkerTimer = nullptr;
+
+       return checker();
+}
diff --git a/tests/src/test_util.h b/tests/src/test_util.h
new file mode 100644 (file)
index 0000000..dc9d185
--- /dev/null
@@ -0,0 +1,78 @@
+/*
+ * 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 __STT_TEST_UTIL_H__
+#define __STT_TEST_UTIL_H__
+
+
+#include <functional>
+
+#include <stt.h>
+#include <stt_internal.h>
+
+
+class SttTestUtility {
+public:
+       static void StateChangedCallback(stt_h stt, stt_state_e previous, stt_state_e current, void *user_data);
+       static void ErrorCallback(stt_h stt, stt_error_e reason, void *user_data);
+       static void RecognitionResultCallback(stt_h stt, stt_result_event_e event, const char** data, int data_count, const char* msg, void *user_data);
+
+       static void TerminateCurrentEngine();
+       static void WaitUntilEngineTerminated(int duration);
+       static bool IsFeatureSupported();
+
+public:
+       SttTestUtility();
+       ~SttTestUtility();
+
+       void GetTestPCMData();
+
+       void CreateHandle();
+       void DestroyHandle();
+       void SetTestMode();
+       void UnsetTestMode();
+
+       bool Prepare();
+       bool Unprepare();
+
+       bool Start(const char* language, const char* type);
+       bool Stop();
+       bool StartAudioStreaming(const char* language, const char* type);
+       bool StopAudioStreaming();
+       bool Cancel();
+
+       bool IsStateChanged(stt_state_e targetState, int duration);
+       bool IsErrorOccurring(int duration);
+       bool IsResultReceived(int duration);
+
+public:
+       stt_h mHandle;
+       stt_state_e mCurrentState;
+
+       bool mErrorOccured;
+       bool mResultReceived;
+       char *mErrorMessage;
+
+       char* mPCMData;
+       size_t mPCMSize;
+
+private:
+       static bool WaitCondtion(std::function<bool(void)> checker, int duration);
+};
+
+
+#endif  /* __STT_TEST_UTIL_H__ */