From c6dbe6e3166a42752fc0fd9e133dfdd892f669ab Mon Sep 17 00:00:00 2001 From: Suyeon Hwang Date: Fri, 2 Jun 2023 11:44:57 +0900 Subject: [PATCH] Add test cases for audio streaming functions - Requirements: The test cases for testing new functions are neccessary. - Contents: This patch adds new test cases for audio streaming functions. With this patch, the developer can validate new functions. Change-Id: Ie07218cca3ba169967400f58a0b0f4bf8c5531c8 Signed-off-by: Suyeon Hwang --- packaging/stt.spec | 1 + tests/CMakeLists.txt | 2 + tests/res/test_pcm.dat | Bin 0 -> 71680 bytes tests/src/stt_unittests.cpp | 494 ++++++++++++++++++++++++++++++++++++++++---- 4 files changed, 461 insertions(+), 36 deletions(-) create mode 100644 tests/res/test_pcm.dat diff --git a/packaging/stt.spec b/packaging/stt.spec index 939a80f..06e909d 100644 --- a/packaging/stt.spec +++ b/packaging/stt.spec @@ -248,5 +248,6 @@ mkdir -p %{TZ_SYS_RO_SHARE}/voice/test %manifest tests/org.tizen.stt-unittests.manifest %defattr(-,root,root,-) %{TZ_SYS_RO_PACKAGES}/org.tizen.stt-unittests.xml +%{TZ_SYS_RO_APP}/org.tizen.stt-unittests/res/test_pcm.dat %{TZ_SYS_RO_APP}/org.tizen.stt-unittests/bin/stt-unittests %{_bindir}/tizen-unittests/%{name}/run-unittest.sh diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 1dffba8..ecb866d 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -2,6 +2,7 @@ CMAKE_MINIMUM_REQUIRED(VERSION 2.6) PROJECT(gtest-stt CXX) SET(PKGNAME "org.tizen.stt-unittests") +SET(RESDIR "${TZ_SYS_RO_APP}/${PKGNAME}/res") SET(BINDIR "${TZ_SYS_RO_APP}/${PKGNAME}/bin") FOREACH(flag ${pkgs_CFLAGS}) @@ -43,4 +44,5 @@ SET_TARGET_PROPERTIES(${UNITTEST_STT} PROPERTIES --wrap=calloc") INSTALL(FILES ${CMAKE_SOURCE_DIR}/tests/${PKGNAME}.xml DESTINATION ${TZ_SYS_RO_PACKAGES}) +INSTALL(FILES ${CMAKE_SOURCE_DIR}/tests/res/test_pcm.dat DESTINATION ${RESDIR}) INSTALL(TARGETS ${UNITTEST_STT} DESTINATION ${BINDIR}) diff --git a/tests/res/test_pcm.dat b/tests/res/test_pcm.dat new file mode 100644 index 0000000000000000000000000000000000000000..edde2e64375931c66788c85a9676753774dde2c3 GIT binary patch literal 71680 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 K2>gFX;C}%;kGsAA literal 0 HcmV?d00001 diff --git a/tests/src/stt_unittests.cpp b/tests/src/stt_unittests.cpp index d9d2a92..3c9283e 100644 --- a/tests/src/stt_unittests.cpp +++ b/tests/src/stt_unittests.cpp @@ -16,9 +16,10 @@ #include #include +#include #include +#include #include -#include "../../client/stt_client.h" #include "cynara_mock.h" #include "system_info_mock.h" @@ -34,6 +35,9 @@ static stt_state_e g_temp_current_state; static bool g_stt_supported = false; static stt_error_e g_error = STT_ERROR_NONE; +static char* g_pcm_data = nullptr; +static long g_pcm_size = 0; + static bool __stt_supported_engine_cb(stt_h stt, const char* engine_id, const char* engine_name, void* user_data) { return true; @@ -83,6 +87,39 @@ static void __stt_speech_status_cb(stt_h stt, stt_speech_status_e status, void * { } +static void read_test_pcm() +{ + 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 = (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; + } + + g_pcm_size = size; + g_pcm_data = data; +} + static bool is_feature_enabled() { bool stt_feature = false; @@ -99,44 +136,120 @@ static bool is_feature_enabled() } class STTTest : public testing::Test { - public: - virtual void SetUp() { - ecore_init(); - - cynara_check_set_result(CYNARA_API_ACCESS_ALLOWED); - - /* start of TC */ - int ret = -1; - g_stt_supported = is_feature_enabled(); - g_current_state = STT_STATE_CREATED; - g_error = STT_ERROR_NONE; - - if (g_stt_supported) { - g_stt = NULL; - ret = stt_create(&g_stt); - EXPECT_EQ(ret, STT_ERROR_NONE); - - ret = stt_set_state_changed_cb(g_stt, __stt_state_changed_cb, nullptr); - EXPECT_EQ(ret, STT_ERROR_NONE); - ret = stt_set_error_cb(g_stt, __stt_error_cb, nullptr); - EXPECT_EQ(ret, STT_ERROR_NONE); - } +public: + virtual void SetUp() + { + ecore_init(); + + /* start of TC */ + g_stt_supported = is_feature_enabled(); + g_current_state = STT_STATE_CREATED; + g_error = STT_ERROR_NONE; + mIsStreaming = false; + + if (g_stt_supported) { + g_stt = nullptr; + EXPECT_EQ(stt_create(&g_stt), STT_ERROR_NONE); + EXPECT_EQ(stt_set_state_changed_cb(g_stt, __stt_state_changed_cb, nullptr), STT_ERROR_NONE); + EXPECT_EQ(stt_set_error_cb(g_stt, __stt_error_cb, nullptr), STT_ERROR_NONE); } + } - virtual void TearDown() { - /* end of TC */ - int ret = -1; - if (true == g_stt_supported) { - ret = stt_unset_state_changed_cb(g_stt); - EXPECT_EQ(ret, STT_ERROR_NONE); - ret = stt_unset_error_cb(g_stt); - EXPECT_EQ(ret, STT_ERROR_NONE); - ret = stt_destroy(g_stt); - EXPECT_EQ(ret, STT_ERROR_NONE); - } - g_stt = NULL; - ecore_shutdown(); + virtual void TearDown() + { + /* end of TC */ + CancelSttRecording(); + UnprepareStt(); + SetTestMode(false); + + if (true == g_stt_supported) { + EXPECT_EQ(stt_unset_state_changed_cb(g_stt), STT_ERROR_NONE); + EXPECT_EQ(stt_unset_error_cb(g_stt), STT_ERROR_NONE); + EXPECT_EQ(stt_destroy(g_stt), STT_ERROR_NONE); + g_stt = nullptr; + } + + ecore_shutdown(); + } + + bool CancelSttRecording() + { + stt_state_e state = STT_STATE_CREATED; + stt_get_state(g_stt, &state); + if (STT_STATE_READY == state || STT_STATE_CREATED == state) { + return false; } + + stt_cancel(g_stt); + return IsStateChanged(STT_STATE_READY, 5); + } + + bool UnprepareStt() + { + stt_state_e state = STT_STATE_CREATED; + stt_get_state(g_stt, &state); + if (STT_STATE_READY != state) { + return false; + } + + stt_unprepare(g_stt); + return IsStateChanged(STT_STATE_CREATED, 5); + } + + bool PrepareStt() + { + stt_state_e state = STT_STATE_CREATED; + stt_get_state(g_stt, &state); + if (STT_STATE_CREATED != state) { + return false; + } + + stt_prepare(g_stt); + return IsStateChanged(STT_STATE_READY, 5); + } + + void SetTestMode(bool isTestMode) + { + stt_state_e state = STT_STATE_CREATED; + stt_get_state(g_stt, &state); + if (STT_STATE_READY != state) { + return; + } + + stt_set_private_data(g_stt, "stt_verification", isTestMode ? "true" : "false"); + } + + bool IsStateChanged(stt_state_e state, int wait_delay) + { + mTargetState = state; + auto mainLoopQuitTimer = ecore_timer_add(static_cast(wait_delay), [](void *data) -> Eina_Bool { + ecore_main_loop_quit(); + return EINA_FALSE; + }, nullptr); + + auto stateCheckerTimer = ecore_timer_add(0.0, [](void *data) -> Eina_Bool { + auto instance = reinterpret_cast(data); + if (instance->mTargetState != g_current_state) { + return EINA_TRUE; + } + + ecore_main_loop_quit(); + return EINA_FALSE; + }, this); + + ecore_main_loop_begin(); + + ecore_timer_del(mainLoopQuitTimer); + mainLoopQuitTimer = nullptr; + + ecore_timer_del(stateCheckerTimer); + stateCheckerTimer = nullptr; + + return state == g_current_state; + } + + bool mIsStreaming = false; + stt_state_e mTargetState = STT_STATE_CREATED; }; TEST_F(STTTest, utc_stt_create_p) @@ -432,6 +545,8 @@ TEST_F(STTTest, utc_stt_unprepare_n1) ret = stt_unprepare(stt); EXPECT_EQ(ret, STT_ERROR_INVALID_STATE); + + EXPECT_EQ(stt_destroy(stt), STT_ERROR_NONE); } } @@ -2181,4 +2296,311 @@ TEST_F(STTTest, utc_stt_unset_speech_status_cb_n) } } +TEST_F(STTTest, utc_stt_get_audio_format_p) +{ + ASSERT_NE(g_stt, nullptr); + + stt_audio_type_e type = STT_AUDIO_TYPE_RAW_S16; + int rate = -1; + int num_of_channels = -1; + if (false == g_stt_supported) { + EXPECT_EQ(stt_get_audio_format(g_stt, &type, &rate, &num_of_channels), STT_ERROR_NOT_SUPPORTED); + return; + } + + ASSERT_EQ(PrepareStt(), true); + EXPECT_EQ(stt_get_audio_format(g_stt, &type, &rate, &num_of_channels), STT_ERROR_NONE); +} + +TEST_F(STTTest, utc_stt_get_audio_format_n1) +{ + ASSERT_NE(g_stt, nullptr); + + stt_audio_type_e type = STT_AUDIO_TYPE_RAW_S16; + int rate = -1; + int num_of_channels = -1; + if (false == g_stt_supported) { + EXPECT_EQ(stt_get_audio_format(g_stt, &type, &rate, &num_of_channels), STT_ERROR_NOT_SUPPORTED); + return; + } + + EXPECT_EQ(stt_get_audio_format(g_stt, &type, &rate, &num_of_channels), STT_ERROR_INVALID_STATE); +} + +TEST_F(STTTest, utc_stt_get_audio_format_n2) +{ + ASSERT_NE(g_stt, nullptr); + + stt_audio_type_e type = STT_AUDIO_TYPE_RAW_S16; + int rate = -1; + int num_of_channels = -1; + if (false == g_stt_supported) { + EXPECT_EQ(stt_get_audio_format(g_stt, &type, &rate, &num_of_channels), STT_ERROR_NOT_SUPPORTED); + return; + } + + ASSERT_EQ(PrepareStt(), true); + EXPECT_EQ(stt_get_audio_format(nullptr, &type, &rate, &num_of_channels), STT_ERROR_INVALID_PARAMETER); + EXPECT_EQ(stt_get_audio_format(g_stt, nullptr, &rate, &num_of_channels), STT_ERROR_INVALID_PARAMETER); + EXPECT_EQ(stt_get_audio_format(g_stt, &type, nullptr, &num_of_channels), STT_ERROR_INVALID_PARAMETER); + EXPECT_EQ(stt_get_audio_format(g_stt, &type, &rate, nullptr), STT_ERROR_INVALID_PARAMETER); +} + +TEST_F(STTTest, utc_stt_start_audio_streaming_p) +{ + ASSERT_NE(g_stt, nullptr); + mIsStreaming = true; + + const char *language = "en_US"; + const char *type = STT_RECOGNITION_TYPE_FREE_PARTIAL; + + if (false == g_stt_supported) { + EXPECT_EQ(stt_start_audio_streaming(g_stt, language, type), STT_ERROR_NOT_SUPPORTED); + return; + } + + ASSERT_EQ(PrepareStt(), true); + SetTestMode(true); + + EXPECT_EQ(stt_start_audio_streaming(g_stt, language, type), STT_ERROR_NONE); + EXPECT_EQ(IsStateChanged(STT_STATE_RECORDING, 5), true); +} + +TEST_F(STTTest, utc_stt_start_audio_streaming_n1) +{ + ASSERT_NE(g_stt, nullptr); + mIsStreaming = true; + + const char *language = "en_US"; + const char *type = STT_RECOGNITION_TYPE_FREE_PARTIAL; + + if (false == g_stt_supported) { + EXPECT_EQ(stt_start_audio_streaming(g_stt, language, type), STT_ERROR_NOT_SUPPORTED); + return; + } + + ASSERT_EQ(PrepareStt(), true); + SetTestMode(true); + + EXPECT_EQ(stt_start_audio_streaming(nullptr, language, type), STT_ERROR_INVALID_PARAMETER); + EXPECT_EQ(stt_start_audio_streaming(g_stt, language, nullptr), STT_ERROR_INVALID_PARAMETER); +} + +TEST_F(STTTest, utc_stt_start_audio_streaming_n2) +{ + ASSERT_NE(g_stt, nullptr); + mIsStreaming = true; + + const char *language = "en_US"; + const char *type = STT_RECOGNITION_TYPE_FREE_PARTIAL; + + if (false == g_stt_supported) { + EXPECT_EQ(stt_start_audio_streaming(g_stt, language, type), STT_ERROR_NOT_SUPPORTED); + return; + } + + EXPECT_EQ(stt_start_audio_streaming(g_stt, language, type), STT_ERROR_INVALID_STATE); + + ASSERT_EQ(PrepareStt(), true); + SetTestMode(true); + + ASSERT_EQ(stt_start_audio_streaming(g_stt, language, type), STT_ERROR_NONE); + ASSERT_EQ(IsStateChanged(STT_STATE_RECORDING, 5), true); + + EXPECT_EQ(stt_start_audio_streaming(g_stt, language, type), STT_ERROR_INVALID_STATE); +} + +TEST_F(STTTest, utc_stt_send_audio_streaming_p) +{ + ASSERT_NE(g_stt, nullptr); + mIsStreaming = true; + + read_test_pcm(); + ASSERT_NE(g_pcm_data, nullptr); + ASSERT_GT(g_pcm_size, 0); + + if (false == g_stt_supported) { + EXPECT_EQ(stt_send_audio_streaming(g_stt, g_pcm_data, g_pcm_size), STT_ERROR_NOT_SUPPORTED); + return; + } + + const char *language = "en_US"; + const char *type = STT_RECOGNITION_TYPE_FREE_PARTIAL; + + ASSERT_EQ(PrepareStt(), true); + SetTestMode(true); + + ASSERT_EQ(stt_start_audio_streaming(g_stt, language, type), STT_ERROR_NONE); + ASSERT_EQ(IsStateChanged(STT_STATE_RECORDING, 5), true); + + EXPECT_EQ(stt_send_audio_streaming(g_stt, g_pcm_data, g_pcm_size), STT_ERROR_NONE); +} + +TEST_F(STTTest, utc_stt_send_audio_streaming_n1) +{ + ASSERT_NE(g_stt, nullptr); + mIsStreaming = true; + + read_test_pcm(); + ASSERT_NE(g_pcm_data, nullptr); + ASSERT_GT(g_pcm_size, 0); + + if (false == g_stt_supported) { + EXPECT_EQ(stt_send_audio_streaming(g_stt, g_pcm_data, g_pcm_size), STT_ERROR_NOT_SUPPORTED); + return; + } + + const char *language = "en_US"; + const char *type = STT_RECOGNITION_TYPE_FREE_PARTIAL; + + ASSERT_EQ(PrepareStt(), true); + SetTestMode(true); + + ASSERT_EQ(stt_start_audio_streaming(g_stt, language, type), STT_ERROR_NONE); + ASSERT_EQ(IsStateChanged(STT_STATE_RECORDING, 5), true); + + EXPECT_EQ(stt_send_audio_streaming(nullptr, g_pcm_data, g_pcm_size), STT_ERROR_INVALID_PARAMETER); + EXPECT_EQ(stt_send_audio_streaming(g_stt, nullptr, g_pcm_size), STT_ERROR_INVALID_PARAMETER); + EXPECT_EQ(stt_send_audio_streaming(g_stt, g_pcm_data, 0), STT_ERROR_INVALID_PARAMETER); +} + +TEST_F(STTTest, utc_stt_send_audio_streaming_n2) +{ + ASSERT_NE(g_stt, nullptr); + mIsStreaming = true; + + read_test_pcm(); + ASSERT_NE(g_pcm_data, nullptr); + ASSERT_GT(g_pcm_size, 0); + + if (false == g_stt_supported) { + EXPECT_EQ(stt_send_audio_streaming(g_stt, g_pcm_data, g_pcm_size), STT_ERROR_NOT_SUPPORTED); + return; + } + + EXPECT_EQ(stt_send_audio_streaming(g_stt, g_pcm_data, g_pcm_size), STT_ERROR_INVALID_STATE); + + ASSERT_EQ(PrepareStt(), true); + SetTestMode(true); + EXPECT_EQ(stt_send_audio_streaming(g_stt, g_pcm_data, g_pcm_size), STT_ERROR_INVALID_STATE); +} + +TEST_F(STTTest, utc_stt_send_audio_streaming_n3) +{ + ASSERT_NE(g_stt, nullptr); + mIsStreaming = true; + + read_test_pcm(); + ASSERT_NE(g_pcm_data, nullptr); + ASSERT_GT(g_pcm_size, 0); + + if (false == g_stt_supported) { + EXPECT_EQ(stt_send_audio_streaming(g_stt, g_pcm_data, g_pcm_size), STT_ERROR_NOT_SUPPORTED); + return; + } + + const char *language = "en_US"; + const char *type = STT_RECOGNITION_TYPE_FREE_PARTIAL; + + ASSERT_EQ(PrepareStt(), true); + SetTestMode(true); + + ASSERT_EQ(stt_start(g_stt, language, type), STT_ERROR_NONE); + ASSERT_EQ(IsStateChanged(STT_STATE_RECORDING, 5), true); + + EXPECT_EQ(stt_send_audio_streaming(g_stt, g_pcm_data, g_pcm_size), STT_ERROR_OPERATION_FAILED); +} + +TEST_F(STTTest, utc_stt_stop_audio_streaming_p) +{ + ASSERT_NE(g_stt, nullptr); + mIsStreaming = true; + + if (false == g_stt_supported) { + EXPECT_EQ(stt_stop_audio_streaming(g_stt), STT_ERROR_NOT_SUPPORTED); + return; + } + + ASSERT_EQ(PrepareStt(), true); + SetTestMode(true); + + const char *language = "en_US"; + const char *type = STT_RECOGNITION_TYPE_FREE_PARTIAL; + EXPECT_EQ(stt_start_audio_streaming(g_stt, language, type), STT_ERROR_NONE); + EXPECT_EQ(IsStateChanged(STT_STATE_RECORDING, 5), true); + + EXPECT_EQ(stt_stop_audio_streaming(g_stt), STT_ERROR_NONE); + EXPECT_EQ(IsStateChanged(STT_STATE_PROCESSING, 5), true); + EXPECT_EQ(IsStateChanged(STT_STATE_READY, 5), true); +} + +TEST_F(STTTest, utc_stt_stop_audio_streaming_n1) +{ + ASSERT_NE(g_stt, nullptr); + mIsStreaming = true; + + if (false == g_stt_supported) { + EXPECT_EQ(stt_stop_audio_streaming(g_stt), STT_ERROR_NOT_SUPPORTED); + return; + } + + ASSERT_EQ(PrepareStt(), true); + SetTestMode(true); + + const char *language = "en_US"; + const char *type = STT_RECOGNITION_TYPE_FREE_PARTIAL; + EXPECT_EQ(stt_start_audio_streaming(g_stt, language, type), STT_ERROR_NONE); + EXPECT_EQ(IsStateChanged(STT_STATE_RECORDING, 5), true); + + EXPECT_EQ(stt_stop_audio_streaming(nullptr), STT_ERROR_INVALID_PARAMETER); +} + +TEST_F(STTTest, utc_stt_stop_audio_streaming_n2) +{ + ASSERT_NE(g_stt, nullptr); + mIsStreaming = true; + + if (false == g_stt_supported) { + EXPECT_EQ(stt_stop_audio_streaming(g_stt), STT_ERROR_NOT_SUPPORTED); + return; + } + + EXPECT_EQ(stt_stop_audio_streaming(g_stt), STT_ERROR_INVALID_STATE); + + ASSERT_EQ(PrepareStt(), true); + SetTestMode(true); + EXPECT_EQ(stt_stop_audio_streaming(g_stt), STT_ERROR_INVALID_STATE); + + const char *language = "en_US"; + const char *type = STT_RECOGNITION_TYPE_FREE_PARTIAL; + EXPECT_EQ(stt_start_audio_streaming(g_stt, language, type), STT_ERROR_NONE); + EXPECT_EQ(IsStateChanged(STT_STATE_RECORDING, 5), true); + + EXPECT_EQ(stt_stop_audio_streaming(g_stt), STT_ERROR_NONE); + EXPECT_EQ(IsStateChanged(STT_STATE_PROCESSING, 5), true); + + EXPECT_EQ(stt_stop_audio_streaming(g_stt), STT_ERROR_INVALID_STATE); +} + +TEST_F(STTTest, utc_stt_stop_audio_streaming_n3) +{ + ASSERT_NE(g_stt, nullptr); + mIsStreaming = true; + + if (false == g_stt_supported) { + EXPECT_EQ(stt_stop_audio_streaming(g_stt), STT_ERROR_NOT_SUPPORTED); + return; + } + + ASSERT_EQ(PrepareStt(), true); + SetTestMode(true); + + const char *language = "en_US"; + const char *type = STT_RECOGNITION_TYPE_FREE_PARTIAL; + EXPECT_EQ(stt_start(g_stt, language, type), STT_ERROR_NONE); + EXPECT_EQ(IsStateChanged(STT_STATE_RECORDING, 5), true); + + EXPECT_EQ(stt_stop_audio_streaming(g_stt), STT_ERROR_OPERATION_FAILED); +} + } // namespace -- 2.7.4