From 330535f5bad307e543c529f4dcd865ffd61a0ca2 Mon Sep 17 00:00:00 2001 From: Suyeon Hwang Date: Thu, 29 Jun 2023 10:56:39 +0900 Subject: [PATCH] Add test utility class - 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: Ife285e7e7bd065423197727bcaeb72219a3ecc8e Signed-off-by: Suyeon Hwang --- tests/src/test_util.cpp | 318 ++++++++++++++++++++++++++++++++++++++++++++++++ tests/src/test_util.h | 83 +++++++++++++ 2 files changed, 401 insertions(+) create mode 100644 tests/src/test_util.cpp create mode 100644 tests/src/test_util.h diff --git a/tests/src/test_util.cpp b/tests/src/test_util.cpp new file mode 100644 index 0000000..08d46cd --- /dev/null +++ b/tests/src/test_util.cpp @@ -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 +#include +#include +#include +#include +#include + +#include "test_util.h" + + +TtsTestUtility::TtsTestUtility() +{ + mHandle = nullptr; + mCurrentState = TTS_STATE_CREATED; + mCurrentServiceState = TTS_SERVICE_STATE_NONE; + + mLanguage = nullptr; + mVoiceType = TTS_VOICE_TYPE_AUTO; + mScreenReaderOn = false; + mUtteranceStarted = false; + mUtteranceCompleted = false; + mErrorOccured = false; + mUttId = -1; + + mPCMData = nullptr; + mPCMSize = 0; + + CreateHandle(); +} + +TtsTestUtility::~TtsTestUtility() +{ + DestroyHandle(); + + free(mLanguage); + mLanguage = nullptr; + + free(mPCMData); + mPCMData = nullptr; + mPCMSize = 0; +} + +void TtsTestUtility::StateChangedCallback(tts_h tts, tts_state_e previous, tts_state_e current, void *user_data) +{ + auto instance = reinterpret_cast(user_data); + instance->mCurrentState = current; +} + +void TtsTestUtility::ServiceStateChangedCallback(tts_h tts, tts_service_state_e previous, tts_service_state_e current, void* user_data) +{ + auto instance = reinterpret_cast(user_data); + instance->mCurrentServiceState = current; +} + +void TtsTestUtility::ScreenReaderChangedCallback(tts_h tts, bool is_on, void* user_data) +{ + auto instance = reinterpret_cast(user_data); + instance->mScreenReaderOn = is_on; +} + +void TtsTestUtility::UtteranceStartedCallback(tts_h tts, int utt_id, void* user_data) +{ + auto instance = reinterpret_cast(user_data); + instance->mUtteranceStarted = true; +} + +void TtsTestUtility::UtteranceCompletedCallback(tts_h tts, int utt_id, void *user_data) +{ + auto instance = reinterpret_cast(user_data); + instance->mUtteranceCompleted = true; + instance->mUttId = utt_id; +} + +void TtsTestUtility::ErrorCallback(tts_h tts, int utt_id, tts_error_e reason, void* user_data) +{ + auto instance = reinterpret_cast(user_data); + instance->mErrorOccured = true; +} + +void TtsTestUtility::TerminateCurrentEngine() +{ + char* engineId = vconf_get_str(VCONFKEY_TTS_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 TtsTestUtility::WaitUntilEngineTerminated(int duration) +{ + auto engineChcker = [](void) { + bool is_running = false; + + char* engineId = vconf_get_str(VCONFKEY_TTS_ENGINE_DEFAULT); + app_manager_is_running(engineId, &is_running); + free(engineId); + + return !is_running; + }; + + WaitCondtion(engineChcker, duration); +} + +bool TtsTestUtility::IsFeatureSupported() +{ + bool isSupported = false; + system_info_get_platform_bool("http://tizen.org/feature/speech.synthesis", &isSupported); + return isSupported; +} + +void TtsTestUtility::GetTestPCMData() +{ + static const char* PCM_PATH = tzplatform_mkpath(tzplatform_getid("TZ_SYS_RO_APP"), "/org.tizen.tts-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(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 TtsTestUtility::CreateHandle() +{ + if (IsFeatureSupported() == false) { + mHandle = nullptr; + return; + } + + tts_create(&mHandle); + ASSERT_NE(mHandle, nullptr); + + EXPECT_EQ(tts_set_state_changed_cb(mHandle, StateChangedCallback, this), TTS_ERROR_NONE); + EXPECT_EQ(tts_set_service_state_changed_cb(mHandle, ServiceStateChangedCallback, this), TTS_ERROR_NONE); + EXPECT_EQ(tts_set_error_cb(mHandle, ErrorCallback, this), TTS_ERROR_NONE); + EXPECT_EQ(tts_get_default_voice(mHandle, &mLanguage, &mVoiceType), TTS_ERROR_NONE); +} + +void TtsTestUtility::DestroyHandle() +{ + if (nullptr != mHandle) { + EXPECT_EQ(tts_destroy(mHandle), TTS_ERROR_NONE); + mHandle = nullptr; + } +} + +bool TtsTestUtility::IsStateChanged(tts_state_e targetState, int duration) +{ + auto stateChecker = std::bind([](TtsTestUtility *instance, tts_state_e target) { + return target == instance->mCurrentState; + }, this, targetState); + + return WaitCondtion(stateChecker, duration); +} + +bool TtsTestUtility::IsServiceStateChanged(tts_service_state_e targetState, int duration) +{ + auto stateChecker = std::bind([](TtsTestUtility *instance, tts_service_state_e target) { + return target == instance->mCurrentServiceState; + }, this, targetState); + + return WaitCondtion(stateChecker, duration); +} + +bool TtsTestUtility::IsScreenReaderOn(int duration) +{ + auto screenReaderChecker = std::bind([](TtsTestUtility *instance) { + return instance->mScreenReaderOn; + }, this); + + return WaitCondtion(screenReaderChecker, duration); +} + +bool TtsTestUtility::IsUtteranceStarted(int duration) +{ + auto utteranceChecker = std::bind([](TtsTestUtility *instance) { + return instance->mUtteranceStarted; + }, this); + + return WaitCondtion(utteranceChecker, duration); +} + +bool TtsTestUtility::IsUtteranceCompleted(int duration) +{ + auto utteranceChecker = std::bind([](TtsTestUtility *instance) { + return instance->mUtteranceCompleted; + }, this); + + return WaitCondtion(utteranceChecker, duration); +} + +bool TtsTestUtility::IsErrorOccurring(int duration) +{ + auto errorChecker = std::bind([](TtsTestUtility *instance) { + return instance->mErrorOccured; + }, this); + + return WaitCondtion(errorChecker, duration); +} + +bool TtsTestUtility::Prepare() +{ + tts_state_e state = TTS_STATE_CREATED; + tts_get_state(mHandle, &state); + if (TTS_STATE_CREATED != state) { + return false; + } + + tts_prepare(mHandle); + return IsStateChanged(TTS_STATE_READY, 5); +} + +bool TtsTestUtility::Unprepare() +{ + tts_state_e state = TTS_STATE_CREATED; + tts_get_state(mHandle, &state); + if (TTS_STATE_READY != state) { + return false; + } + + tts_unprepare(mHandle); + return IsStateChanged(TTS_STATE_CREATED, 5); +} + +bool TtsTestUtility::Play() +{ + EXPECT_EQ(tts_play(mHandle), TTS_ERROR_NONE); + return IsStateChanged(TTS_STATE_PLAYING, 5); +} + +bool TtsTestUtility::Pause() +{ + EXPECT_EQ(tts_pause(mHandle), TTS_ERROR_NONE); + return IsStateChanged(TTS_STATE_PAUSED, 5); +} + +bool TtsTestUtility::Stop() +{ + EXPECT_EQ(tts_stop(mHandle), TTS_ERROR_NONE); + return IsStateChanged(TTS_STATE_READY, 5); +} + +bool TtsTestUtility::WaitCondtion(std::function checker, int duration) +{ + auto mainLoopQuitTimer = ecore_timer_add(static_cast(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 *>(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 index 0000000..41a5d91 --- /dev/null +++ b/tests/src/test_util.h @@ -0,0 +1,83 @@ +/* + * 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 __TTS_TEST_UTIL_H__ +#define __TTS_TEST_UTIL_H__ + + +#include +#include + + +class TtsTestUtility { +public: + static void StateChangedCallback(tts_h tts, tts_state_e previous, tts_state_e current, void *user_data); + static void ServiceStateChangedCallback(tts_h tts, tts_service_state_e previous, tts_service_state_e current, void* user_data); + static void ScreenReaderChangedCallback(tts_h tts, bool is_on, void* user_data); + static void UtteranceStartedCallback(tts_h tts, int utt_id, void* user_data); + static void UtteranceCompletedCallback(tts_h tts, int utt_id, void *user_data); + static void ErrorCallback(tts_h tts, int utt_id, tts_error_e reason, void* user_data); + + static void TerminateCurrentEngine(); + static void WaitUntilEngineTerminated(int duration); + static bool IsFeatureSupported(); + +public: + TtsTestUtility(); + ~TtsTestUtility(); + + void GetTestPCMData(); + + void CreateHandle(); + void DestroyHandle(); + + bool Prepare(); + bool Unprepare(); + + bool Play(); + bool Pause(); + bool Stop(); + + bool IsStateChanged(tts_state_e targetState, int duration); + bool IsServiceStateChanged(tts_service_state_e targetState, int duration); + bool IsScreenReaderOn(int duration); + bool IsUtteranceStarted(int duration); + bool IsUtteranceCompleted(int duration); + bool IsErrorOccurring(int duration); + +public: + tts_h mHandle; + tts_state_e mCurrentState; + tts_service_state_e mCurrentServiceState; + + char *mLanguage; + int mVoiceType; + bool mScreenReaderOn; + bool mUtteranceStarted; + bool mUtteranceCompleted; + bool mErrorOccured; + int mUttId; + + char* mPCMData; + size_t mPCMSize; + +private: + static bool WaitCondtion(std::function checker, int duration); +}; + + +#endif /* __TTS_TEST_UTIL_H__ */ -- 2.7.4