From: Ievgen Vagin Date: Wed, 15 Jun 2016 11:53:54 +0000 (+0300) Subject: Implementation of the test suite for API testing X-Git-Tag: submit/tizen/20160824.052737~5 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=248f1ad9ac18d331e36db17ec37177e2bb7b012e;p=platform%2Fcore%2Fapi%2Fsound-pool.git Implementation of the test suite for API testing Change-Id: Ia9681a2cc28ef65fee2e491a3624614a0e5daf0f Signed-off-by: Ievgen Vagin --- diff --git a/CMakeLists.txt b/CMakeLists.txt index d34c3c1..ef95ddd 100755 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -68,7 +68,7 @@ CONFIGURE_FILE( ) INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/${fw_name}.pc DESTINATION ${LIB_INSTALL_DIR}/pkgconfig) -#ADD_SUBDIRECTORY(test) +ADD_SUBDIRECTORY(test) IF(UNIX) diff --git a/packaging/sound-pool.spec b/packaging/sound-pool.spec index 0f74e31..f4bece1 100644 --- a/packaging/sound-pool.spec +++ b/packaging/sound-pool.spec @@ -1,5 +1,5 @@ Name: sound-pool -Version: 0.0.1 +Version: 0.0.2 Summary: Tizen Sound Pool module Release: 0 Group: Multimedia/Framework @@ -40,7 +40,6 @@ make %{?jobs:-j%jobs} %install rm -rf %{buildroot} -mkdir -p %{buildroot}%{_bindir} %make_install @@ -51,6 +50,7 @@ mkdir -p %{buildroot}%{_bindir} %manifest %{name}.manifest %license LICENSE.APLv2 %{_libdir}/lib%{name}.so.* +%{_bindir}/* %files devel %manifest %{name}.manifest diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt new file mode 100644 index 0000000..a27573a --- /dev/null +++ b/test/CMakeLists.txt @@ -0,0 +1,34 @@ +CMAKE_MINIMUM_REQUIRED(VERSION 2.6) +SET(fw_test "${fw_name}-test") + +INCLUDE(FindPkgConfig) +pkg_check_modules(${fw_test} REQUIRED glib-2.0) +FOREACH(flag ${${fw_test}_CFLAGS}) + SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} ${flag}") +ENDFOREACH(flag) +SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${EXTRA_CFLAGS}") + +SET(modules "") +SET(srcs "") +FILE(GLOB children *) +FOREACH(child ${children}) + IF(IS_DIRECTORY ${child}) + aux_source_directory(${child}/src mod_srcs) + LIST(APPEND srcs ${mod_srcs}) + GET_FILENAME_COMPONENT(child_name ${child} NAME_WE) + LIST(APPEND modules ${child_name}) + ENDIF() +ENDFOREACH() + +INCLUDE_DIRECTORIES(../include) +INCLUDE_DIRECTORIES(${modules}) + +aux_source_directory(. sources) + +FOREACH(src ${sources}) + GET_FILENAME_COMPONENT(src_name ${src} NAME_WE) + SET(srcs ${src} ${mod_srcs}) + ADD_EXECUTABLE(${src_name} ${srcs}) + TARGET_LINK_LIBRARIES(${src_name} ${${fw_test}_LDFLAGS} ${fw_name}) + INSTALL(TARGETS ${src_name} DESTINATION bin) +ENDFOREACH() diff --git a/test/logger/logger.h b/test/logger/logger.h new file mode 100644 index 0000000..572459b --- /dev/null +++ b/test/logger/logger.h @@ -0,0 +1,62 @@ +/* + * Copyright (c) 2016 Samsung Electronics Co., Ltd 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. + * 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. + */ + +#define MAX_PATH_LEN 1024 +#define MAX_MSG_LEN 1024 + +#define _STRINGIFY(x) #x +#define STRINGIFY(x) _STRINGIFY(x) + +#define MAX_PATH_LEN_STR STRINGIFY(MAX_PATH_LEN) +#define MAX_MSG_LEN_STR STRINGIFY(MAX_MSG_LEN) + +#define LOG_MODE_NONE 0 +#define LOG_MODE_FILE 1 +#ifdef LOG_MODE_FILE +# define LOG_MODE_STDERR (LOG_MODE_FILE << 1) +# define LOG_MODE_DLOG (LOG_MODE_FILE << 2) +#endif + +/* Enumeration for terminal colors. Used in internal _printf() function */ +typedef enum { + CMD_COLOR_RED, + CMD_COLOR_YELLOW, + CMD_COLOR_GREEN +} _cmd_color_e; + +/* Sets globally the mode of logging. mode has to be specified as a single or + combination of the following defines: + LOG_MODE_NONE - no logging; + LOG_MODE_FILE - logging to the file; + LOG_MODE_STDERR - logging to the standart error stream; + LOG_MODE_DLOG - logging to the dlog. + For example, set_logging_mode(LOG_MODE_FILE | LOG_MODE_DLOG) call will + direct all following logging to both file and dlog daemon */ +void _logger_set_logging_mode(int mode); + +/* Sets globally the name of the file for LOG_MODE_FILE logging mode */ +int _logger_set_file(const char *fname); + +/* Sets globally the log tag will be used in logging journals like Tizen dlog */ +int _logger_set_log_tag(const char *tag); + +/* Functions for corresponding logging: */ +int _logger_log_info(const char *fmt, ...); +int _logger_log_warn(const char *fmt, ...); +int _logger_log_err(const char *fmt, ...); + +/* Function for using instead of standard printf() if coloring is needed */ +int _printf(_cmd_color_e color, const char *fmt, ...); diff --git a/test/logger/src/logger.c b/test/logger/src/logger.c new file mode 100644 index 0000000..d3932ab --- /dev/null +++ b/test/logger/src/logger.c @@ -0,0 +1,257 @@ +/* + * Copyright (c) 2016 Samsung Electronics Co., Ltd 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. + * 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 "logger.h" + +#include +#include +#include +#include +#include + +#define INFO_TAG "[ INFO ]" +#define WARNING_TAG "[ WARN ]" +#define ERROR_TAG "[ ERROR ]" + +#ifndef COLORED_LOG + #define COLORED_LOG +#endif +#ifdef COLORED_LOG +#define FONT_COLOR_RESET "\033[0m" +#define FONT_COLOR_RED "\033[31m" +#define FONT_COLOR_GREEN "\033[32m" +#define FONT_COLOR_YELLOW "\033[33m" +#else +#define FONT_COLOR_RESET +#define FONT_COLOR_RED +#define FONT_COLOR_GREEN +#define FONT_COLOR_YELLOW +#endif + +#ifdef LOG_TAG +#undef LOG_TAG +#endif + +#define MAX_LOG_TAG_LEN 32 +#define LOG_TAG "TIZEN_SOUND_POOL_TEST_SUITE" + +static struct { + int inited; + int mode; + char fname[MAX_PATH_LEN]; + pthread_mutex_t mutex; + time_t timer; +} __logger = { 0, LOG_MODE_NONE, {'\0'}, PTHREAD_MUTEX_INITIALIZER, 0 }; + +static char LOGGER_LOG_TAG[MAX_LOG_TAG_LEN] = LOG_TAG; + +#define MAX_DATETIME_STR_LEN 26 +static char str_time[MAX_DATETIME_STR_LEN]; + +void _logger_set_logging_mode(int mode) +{ + pthread_mutex_lock(&__logger.mutex); + __logger.mode = mode; + pthread_mutex_unlock(&__logger.mutex); +} + +int _logger_set_file(const char *fname) +{ + if (!fname) + return -1; + + FILE *fd = fopen(fname, "w+"); + if (!fd) + return -1; + + fclose(fd); + + pthread_mutex_lock(&__logger.mutex); + strncpy(__logger.fname, fname, MAX_PATH_LEN - 1); + __logger.fname[MAX_PATH_LEN - 1] = '\0'; + pthread_mutex_unlock(&__logger.mutex); + + return 0; +} + +int _logger_set_log_tag(const char *tag) +{ + if (!tag) + return -1; + + pthread_mutex_lock(&__logger.mutex); + strncpy(LOGGER_LOG_TAG, tag, MAX_LOG_TAG_LEN - 1); + LOGGER_LOG_TAG[MAX_LOG_TAG_LEN - 1] = '\0'; + pthread_mutex_unlock(&__logger.mutex); + return 0; +} + +# define __LOGGER_PREPARE() \ + do { \ + pthread_mutex_lock(&__logger.mutex); \ + time(&__logger.timer); \ + strftime(str_time, MAX_DATETIME_STR_LEN, "%Y:%m:%d %H:%M:%S", \ + localtime(&__logger.timer)); \ + } while (0) + +# define __LOGGER_UNPREPARE() \ + do { \ + pthread_mutex_unlock(&__logger.mutex); \ + } while (0) + +int _logger_log_info(const char *fmt, ...) +{ + int res = 0; + va_list args; + __LOGGER_PREPARE(); + + if ((__logger.mode & LOG_MODE_FILE) == LOG_MODE_FILE) { + FILE *fd = fopen(__logger.fname, "a"); + if (!fd) { + __LOGGER_UNPREPARE(); + return -1; + } + fprintf(fd, "[%s]", str_time); + fprintf(fd, INFO_TAG); + va_start(args, fmt); + res = vfprintf(fd, fmt, args); + fprintf(fd, "\n"); + fclose(fd); + } + if ((__logger.mode & LOG_MODE_STDERR) == LOG_MODE_STDERR) { + fprintf(stderr, "[%s]", str_time); + fprintf(stderr, FONT_COLOR_GREEN INFO_TAG); + va_start(args, fmt); + res = vfprintf(stderr, fmt, args); + fprintf(stderr, FONT_COLOR_RESET); + fprintf(stderr, "\n"); + } + if ((__logger.mode & LOG_MODE_DLOG) == LOG_MODE_DLOG) { + char msg[MAX_MSG_LEN] = { '\0' }; + snprintf(msg, MAX_MSG_LEN, "[%s]%s", str_time, fmt); + va_start(args, fmt); + dlog_vprint(DLOG_INFO, LOGGER_LOG_TAG, msg, args); + } + + va_end(args); + __LOGGER_UNPREPARE(); + return res; +} + +int _logger_log_warn(const char *fmt, ...) +{ + int res = 0; + va_list args; + __LOGGER_PREPARE(); + + if ((__logger.mode & LOG_MODE_FILE) == LOG_MODE_FILE) { + FILE *fd = fopen(__logger.fname, "a"); + if (!fd) { + __LOGGER_UNPREPARE(); + return -1; + } + fprintf(fd, "[%s]", str_time); + fprintf(fd, WARNING_TAG); + va_start(args, fmt); + res = vfprintf(fd, fmt, args); + fprintf(fd, "\n"); + fclose(fd); + } + if ((__logger.mode & LOG_MODE_STDERR) == LOG_MODE_STDERR) { + fprintf(stderr, "[%s]", str_time); + fprintf(stderr, FONT_COLOR_YELLOW WARNING_TAG); + va_start(args, fmt); + res = vfprintf(stderr, fmt, args); + fprintf(stderr, FONT_COLOR_RESET); + fprintf(stderr, "\n"); + } + if ((__logger.mode & LOG_MODE_DLOG) == LOG_MODE_DLOG) { + char msg[MAX_MSG_LEN] = { '\0' }; + snprintf(msg, MAX_MSG_LEN, "[%s]%s", str_time, fmt); + va_start(args, fmt); + dlog_vprint(DLOG_WARN, LOGGER_LOG_TAG, msg, args); + } + + va_end(args); + __LOGGER_UNPREPARE(); + return res; +} + +int _logger_log_err(const char *fmt, ...) +{ + int res = 0; + va_list args; + __LOGGER_PREPARE(); + + if ((__logger.mode & LOG_MODE_FILE) == LOG_MODE_FILE) { + FILE *fd = fopen(__logger.fname, "a"); + if (!fd) { + __LOGGER_UNPREPARE(); + return -1; + } + fprintf(fd, "[%s]", str_time); + fprintf(fd, ERROR_TAG); + va_start(args, fmt); + res = vfprintf(fd, fmt, args); + fprintf(fd, "\n"); + fclose(fd); + } + if ((__logger.mode & LOG_MODE_STDERR) == LOG_MODE_STDERR) { + fprintf(stderr, "[%s]", str_time); + fprintf(stderr, FONT_COLOR_RED ERROR_TAG); + va_start(args, fmt); + res = vfprintf(stderr, fmt, args); + fprintf(stderr, FONT_COLOR_RESET); + fprintf(stderr, "\n"); + } + if ((__logger.mode & LOG_MODE_DLOG) == LOG_MODE_DLOG) { + char msg[MAX_MSG_LEN] = { '\0' }; + snprintf(msg, MAX_MSG_LEN, "[%s]%s", str_time, fmt); + va_start(args, fmt); + dlog_vprint(DLOG_ERROR, LOGGER_LOG_TAG, msg, args); + } + + va_end(args); + __LOGGER_UNPREPARE(); + return res; +} + +int _printf(_cmd_color_e color, const char *fmt, ...) +{ + va_list args; + va_start(args, fmt); + + switch (color) { + case CMD_COLOR_RED: + vprintf(FONT_COLOR_RED, args); + break; + case CMD_COLOR_YELLOW: + vprintf(FONT_COLOR_YELLOW, args); + break; + case CMD_COLOR_GREEN: + vprintf(FONT_COLOR_GREEN, args); + break; + default: + break; + } + + int res = vprintf(fmt, args); + printf(FONT_COLOR_RESET); + + va_end(args); + + return res; +} diff --git a/test/proxy/proxy.h b/test/proxy/proxy.h new file mode 100644 index 0000000..3cdc86e --- /dev/null +++ b/test/proxy/proxy.h @@ -0,0 +1,79 @@ +/* + * Copyright (c) 2016 Samsung Electronics Co., Ltd 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. + * 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 "sound_pool.h" + +#define MAX_COMMAND_LINE_LEN 1024 + +/* Test suite command list */ +#define CMD_EXIT "exit" /* 0 */ +#define CMD_HELP "help" /* 1 */ +#define CMD_CREATE_POOL "pool create" /* 2 */ +#define CMD_DESTROY_POOL "pool destroy" /* 3 */ +#define CMD_ACTIVATE_POOL "pool activate" /* 4 */ +#define CMD_DEACTIVATE_POOL "pool deactivate" /* 5 */ +#define CMD_GET_POOL_STATE "pool get state" /* 6 */ +#define CMD_SET_POOL_VOLUME "pool set volume" /* 7 */ +#define CMD_GET_POOL_VOLUME "pool get volume" /* 8 */ +#define CMD_SET_POOL_CB_MSG "pool set callback message" /* 9 */ +#define CMD_SET_POOL_CB_SCRIPT "pool set callback script" /* 10 */ +#define CMD_UNSET_POOL_CB "pool unset callback" /* 11 */ +#define CMD_LIST_POOL "pool list" /* 12 */ +#define CMD_LOAD_SOURCE "source load" /* 13 */ +#define CMD_LOAD_MEDIA_PACKAGE "source load mic" /* 14 */ +#define CMD_UNLOAD_SOURCE "source unload" /* 15 */ +#define CMD_PLAY_STREAM "stream play" /* 16 */ +#define CMD_STOP_STREAM "stream stop" /* 17 */ +#define CMD_PAUSE_STREAM "stream pause" /* 18 */ +#define CMD_RESUME_STREAM "stream resume" /* 19 */ +#define CMD_SET_STREAM_VOLUME "stream set volume" /* 20 */ +#define CMD_GET_STREAM_VOLUME "stream get volume" /* 21 */ +#define CMD_SET_STREAM_LOOP "stream set loop" /* 22 */ +#define CMD_GET_STREAM_LOOP "stream get loop" /* 23 */ +#define CMD_SET_STREAM_PRIORITY "stream set priority" /* 24 */ +#define CMD_GET_STREAM_PRIORITY "stream get priority" /* 25 */ +#define CMD_GET_STREAM_STATE "stream get state" /* 26 */ +#define CMD_SET_STREAM_CB_MSG "stream set callback message" /* 27 */ +#define CMD_SET_STREAM_CB_SCRIPT "stream set callback script" /* 28 */ +#define CMD_UNSET_STREAM_CB "stream unset callback" /* 29 */ +#define CMD_EXECUTE_SCRIPT "script execute" /* 30 */ +#define CMD_SLEEP "sleep" /* 31 */ + +#define CMD_COUNT 32 + +/* Command execution results list */ +#define OK +1 +#define FAIL -1 +#define UCMD -2 +#define EXIT 0 + +static char *cmd_list[MAX_COMMAND_LINE_LEN] = { CMD_EXIT, CMD_HELP, + CMD_CREATE_POOL, CMD_DESTROY_POOL, CMD_ACTIVATE_POOL, + CMD_DEACTIVATE_POOL, CMD_GET_POOL_STATE, CMD_SET_POOL_VOLUME, + CMD_GET_POOL_VOLUME, CMD_SET_POOL_CB_MSG, CMD_SET_POOL_CB_SCRIPT, + CMD_UNSET_POOL_CB, CMD_LIST_POOL, CMD_LOAD_SOURCE, + CMD_LOAD_MEDIA_PACKAGE, CMD_UNLOAD_SOURCE, CMD_PLAY_STREAM, + CMD_STOP_STREAM, CMD_PAUSE_STREAM, CMD_RESUME_STREAM, + CMD_SET_STREAM_VOLUME, CMD_GET_STREAM_VOLUME, CMD_SET_STREAM_LOOP, + CMD_GET_STREAM_LOOP, CMD_SET_STREAM_PRIORITY, CMD_GET_STREAM_PRIORITY, + CMD_GET_STREAM_STATE, CMD_SET_STREAM_CB_MSG, CMD_SET_STREAM_CB_SCRIPT, + CMD_UNSET_STREAM_CB, CMD_EXECUTE_SCRIPT, CMD_SLEEP }; + +void print_cmd_help_msg(); + +void print_async_msg(); + +int _exec_cmd(const char *cmd_line); diff --git a/test/proxy/src/proxy.c b/test/proxy/src/proxy.c new file mode 100644 index 0000000..deaa36b --- /dev/null +++ b/test/proxy/src/proxy.c @@ -0,0 +1,1584 @@ +/* + * Copyright (c) 2016 Samsung Electronics Co., Ltd 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. + * 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 "proxy.h" +#include "logger.h" + +#include +#include +#include +#include + +#define DEFAULT_MAX_STREAMS_PER_POOL_CNT 25 +#define MICROSECS_PER_MILLISEC 1000 + +#define MAX_POOL_CNT 100 +static sound_pool_h pools[MAX_POOL_CNT] = { NULL }; + +/* Messages to be used for callbacks output (for pool state changing) */ +static char *messages[MAX_POOL_CNT] = { NULL }; +/* Scripts will be launched from callbacks (for stream state changing) */ +static char *scripts[MAX_POOL_CNT] = { NULL }; + +#define MAX_STREAM_CNT 1000 +/* Messages to be used for callbacks output (for pool state changing) */ +static char *stream_messages[MAX_POOL_CNT][MAX_STREAM_CNT] = { NULL }; +/* Messages to be used for callbacks output (for stream state changing) */ +static char *stream_scripts[MAX_POOL_CNT][MAX_STREAM_CNT] = { NULL }; + +static int __proxy_sound_pool_execute_script(const char *pars); + +const char *__stringify_sound_pool_error(sound_pool_error_e error) +{ + switch (error) { + case SOUND_POOL_ERROR_NONE: + return "SOUND_POOL_ERROR_NONE"; + break; + case SOUND_POOL_ERROR_NOT_SUPPORTED: + return "SOUND_POOL_ERROR_NOT_SUPPORTED"; + break; + case SOUND_POOL_ERROR_MSG_TOO_LONG: + return "SOUND_POOL_ERROR_MSG_TOO_LONG"; + break; + case SOUND_POOL_ERROR_NO_DATA: + return "SOUND_POOL_ERROR_NO_DATA"; + break; + case SOUND_POOL_ERROR_KEY_NOT_AVAILABLE: + return "SOUND_POOL_ERROR_KEY_NOT_AVAILABLE"; + break; + case SOUND_POOL_ERROR_OUT_OF_MEMORY: + return "SOUND_POOL_ERROR_OUT_OF_MEMORY"; + break; + case SOUND_POOL_ERROR_INVALID_PARAMETER: + return "SOUND_POOL_ERROR_INVALID_PARAMETER"; + break; + case SOUND_POOL_ERROR_INVALID_OPERATION: + return "SOUND_POOL_ERROR_INVALID_OPERATION"; + break; + case SOUND_POOL_ERROR_PERMISSION_DENIED: + return "SOUND_POOL_ERROR_PERMISSION_DENIED"; + break; + default: + return ""; + break; + } + + return NULL; +} + +const char *__stringify_stream_state(sound_pool_stream_state_e state) +{ + switch (state) { + case SOUND_POOL_STREAM_STATE_NONE: + return "SOUND_POOL_STREAM_STATE_NONE"; + break; + case SOUND_POOL_STREAM_STATE_PLAYING: + return "SOUND_POOL_STREAM_STATE_PLAYING"; + break; + case SOUND_POOL_STREAM_STATE_PAUSED: + return "SOUND_POOL_STREAM_STATE_PAUSED"; + break; + case SOUND_POOL_STREAM_STATE_SUSPENDED: + return "SOUND_POOL_STREAM_STATE_SUSPENDED"; + break; + case SOUND_POOL_STREAM_STATE_STOPPED: + return "SOUND_POOL_STREAM_STATE_STOPPED"; + break; + case SOUND_POOL_STREAM_STATE_FINISHED: + return "SOUND_POOL_STREAM_STATE_FINISHED"; + break; + default: + return ""; + break; + } + + return NULL; +} + +static void __sp_cb_msg(sound_pool_h pool, sound_pool_state_e prev_state, + sound_pool_state_e cur_state, void *data) +{ + const char *msg = (const char *)data; + _logger_log_info("Sound pool state was changing from %s to %s: %s", + prev_state == SOUND_POOL_STATE_ACTIVE ? + "SOUND_POOL_STATE_ACTIVE" : "SOUND_POOL_STATE_INACTIVE", + cur_state == SOUND_POOL_STATE_ACTIVE ? + "SOUND_POOL_STATE_ACTIVE" : "SOUND_POOL_STATE_INACTIVE", + msg ? msg : "No message"); +} + +static void __sp_cb_scr(sound_pool_h pool, sound_pool_state_e prev_state, + sound_pool_state_e cur_state, void *data) +{ + const char *scr = (const char *)data; + _logger_log_info("Sound pool state was changing from %s to %s; " + "Executing: %s...", + prev_state == SOUND_POOL_STATE_ACTIVE ? "SOUND_POOL_STATE_ACTIVE" : + "SOUND_POOL_STATE_INACTIVE", + cur_state == SOUND_POOL_STATE_ACTIVE ? "SOUND_POOL_STATE_ACTIVE" : + "SOUND_POOL_STATE_INACTIVE", + scr ? scr : "No script"); + __proxy_sound_pool_execute_script(scr); +} + +static void __s_cb_msg(sound_pool_h pool, const char *tag, unsigned id, + sound_pool_stream_state_e prev_state, + sound_pool_stream_state_e cur_state, void *data) +{ + const char *msg = (const char *)data; + _logger_log_info("Stream state was changing from %s to %s: %s", + __stringify_stream_state(prev_state), + __stringify_stream_state(cur_state), + msg ? msg : "No message"); +} + +static void __s_cb_scr(sound_pool_h pool, const char *tag, unsigned id, + sound_pool_stream_state_e prev_state, + sound_pool_stream_state_e cur_state, void *data) +{ + const char *scr = (const char *)data; + _logger_log_info("Sound pool state was changing from %s to %s; " + "Executing: %s...", __stringify_stream_state(prev_state), + __stringify_stream_state(cur_state), + scr ? scr : "No script"); + __proxy_sound_pool_execute_script(scr); +} + +/* CMD_EXIT */ +static int __exit() +{ + return EXIT; +} + +/* CMD_HELP */ +static int __print_cmd_help_msg() +{ + printf("\nTest suite usage help:\n"); + + printf(CMD_HELP "\n"); + printf("\t- Shows this help.\n"); + + printf(CMD_CREATE_POOL "\n"); + printf("\t- creates pool with specific identifier.\n"); + + printf(CMD_DESTROY_POOL "\n"); + printf("\t- destroys pool with specific identifier.\n"); + + printf(CMD_ACTIVATE_POOL "\n"); + printf("\t- activates pool with specific identifier.\n"); + + printf(CMD_DEACTIVATE_POOL "\n"); + printf("\t- deactivates pool with specific identifier.\n"); + + printf(CMD_GET_POOL_STATE "\n"); + printf("\t- shows state of the pool with specific identifier.\n"); + + printf(CMD_SET_POOL_VOLUME "\n"); + printf("\t- use this command to set volume for the specific sound pool.\n"); + + printf(CMD_GET_POOL_VOLUME "\n"); + printf("\t- shows volume of the sound pool with specific identifier.\n"); + + printf(CMD_SET_POOL_CB_MSG "\n"); + printf("\t- sets callback which will show the message when sound pool " + "state is changed.\n"); + + printf(CMD_SET_POOL_CB_SCRIPT "\n"); + printf("\t- sets callback which will execute the script when sound pool " + "state is changed.\n"); + + printf(CMD_UNSET_POOL_CB "\n"); + printf("\t- unsets the callback for the sound pool.\n"); + + printf(CMD_LIST_POOL "\n"); + printf("\t- shows ids of all pools had been created and their states.\n"); + + printf(CMD_LOAD_SOURCE "\n"); + printf("\t- loads the source with specific source tag.\n"); + + printf(CMD_UNLOAD_SOURCE "\n"); + printf("\t- unloads the source with specific source tag.\n"); + + printf(CMD_PLAY_STREAM "\n"); + printf("\t- creates the stream with unique identifier and starts playback.\n" + "\t Source tag to be used for stream creation should be specified.\n"); + + printf(CMD_STOP_STREAM "\n"); + printf("\t- stops the stream playback. Stream unique identifier should be\n" + "\t specified after command. After stopping the stream became invalid.\n"); + + printf(CMD_PAUSE_STREAM "\n"); + printf("\t- pauses the stream playback. Stream unique identifier should be\n" + "\t specified after command.\n"); + + printf(CMD_RESUME_STREAM "\n"); + printf("\t- resumes the stream was paused before. Stream unique identifier\n" + "\t should be specified after command.\n"); + + printf(CMD_SET_STREAM_VOLUME "\n"); + printf("\t- use this command to set volume parameter of the stream.\n"); + + printf(CMD_GET_STREAM_VOLUME "\n"); + printf("\t- shows volume of the stream in the pool with specified " + "identifiers.\n"); + + printf(CMD_SET_STREAM_LOOP "\n"); + printf("\t- use this command to set loop parameter of the stream.\n"); + + printf(CMD_GET_STREAM_LOOP "\n"); + printf("\t- shows loop count of the stream in the pool with specified " + "identifiers.\n"); + + printf(CMD_SET_STREAM_PRIORITY "\n"); + printf("\t- use this command to set priority parameter of the stream.\n"); + + printf(CMD_GET_STREAM_PRIORITY "\n"); + printf("\t- shows priority rank of the stream in the pool with specified " + "identifiers.\n"); + + printf(CMD_GET_STREAM_STATE "\n"); + printf("\t- shows state of the stream in the pool with specified " + "identifiers.\n"); + + printf(CMD_SET_STREAM_CB_MSG "\n"); + printf("\t- sets callback which will show the message when sound stream " + "state is changed.\n"); + + printf(CMD_SET_STREAM_CB_SCRIPT "\n"); + printf("\t- sets callback which will execute the script (from file) when " + "sound stream state is changed.\n"); + + printf(CMD_UNSET_STREAM_CB "\n"); + printf("\t- unsets the callback for the sound stream.\n"); + + printf(CMD_EXECUTE_SCRIPT "\n"); + printf("\t- executes the script from the file in filesystem. Script has to\n" + "\t be compiled with commands supported by testsuite, one command\n" + "\t per single line.\n"); + + printf(CMD_SLEEP "\n"); + printf("\t- suspends execution of the main thread for the specific amount " + "of milleseconds.\n"); + + printf(CMD_EXIT "\n"); + printf("\t- exits from the test suite.\n"); + + printf("\n"); + + return OK; +} + +/* CMD_CREATE_POOL */ +static int __proxy_sound_pool_create(const char *pars) +{ + _logger_log_info(CMD_CREATE_POOL " command was called"); + + unsigned int max_streams = DEFAULT_MAX_STREAMS_PER_POOL_CNT; + if (pars != NULL) + sscanf(pars, " %u", &max_streams); + + _logger_log_info("Creating the pool..."); + + sound_pool_h pool = NULL; + int ret = sound_pool_create(max_streams, &pool); + + if (ret == SOUND_POOL_ERROR_NONE) { + _logger_log_info("sound_pool_create(%u, pool) returned %s value", + max_streams, __stringify_sound_pool_error(ret)); + + size_t idx = 0; + while (idx < MAX_POOL_CNT) { + if (pools[idx++] == NULL) { + pools[--idx] = pool; + break; + } + } + + if (idx == MAX_POOL_CNT) { + _printf(CMD_COLOR_RED, "Limit of possible pools is exceeded. Destroy " + "some pools before creating of new ones.\n"); + + _logger_log_warn("Pool can't be created due to test suite " + "restrictions. Destroying the pool..."); + + ret = sound_pool_destroy(pool); + if (ret == SOUND_POOL_ERROR_NONE) + _logger_log_info("sound_pool_destroy(pool) returned %s value", + __stringify_sound_pool_error(ret)); + else + _logger_log_err("sound_pool_destroy(pool) returned %s value", + __stringify_sound_pool_error(ret)); + + return (ret == SOUND_POOL_ERROR_NONE ? OK : FAIL); + } + + if (!pool) + _logger_log_warn("Created pool is NULL"); + else + _logger_log_info("Identifier of the pool has been created is %zu", idx); + } else { + _logger_log_err("sound_pool_create(%u, pool) returned %s value", + max_streams, __stringify_sound_pool_error(ret)); + } + + return (ret == SOUND_POOL_ERROR_NONE ? OK : FAIL); +} + +/* CMD_DESTROY_POOL */ +static int __proxy_sound_pool_destroy(const char *pars) +{ + int ret = SOUND_POOL_ERROR_NONE; + size_t idx = 0; + if ((pars == NULL) || (sscanf(pars, " %zu", &idx) < 1)) { + _printf(CMD_COLOR_RED, "You have to specify identifier of the pool to be " + "destroyed after command! Format: " CMD_DESTROY_POOL " \n"); + return FAIL; + } + + if (idx > (MAX_POOL_CNT - 1)) { + _printf(CMD_COLOR_RED, "Pool identifier value can't be greater than %d\n", + MAX_POOL_CNT - 1); + return FAIL; + } + + _logger_log_info(CMD_DESTROY_POOL " command was called"); + _logger_log_info("Destroying the pool by %zu identifier...", idx); + + if (pools[idx] == NULL) + _logger_log_warn("Pool to be destroyed is NULL"); + + ret = sound_pool_destroy(pools[idx]); + + if (ret == SOUND_POOL_ERROR_NONE) + _logger_log_info("sound_pool_destroy(pool) returned %s value", + __stringify_sound_pool_error(ret)); + else + _logger_log_err("sound_pool_destroy(pool) returned %s value", + __stringify_sound_pool_error(ret)); + + pools[idx] = NULL; + + return (ret == SOUND_POOL_ERROR_NONE ? OK : FAIL); +} + +/* CMD_ACTIVATE_POOL */ +static int __proxy_sound_pool_activate(const char *pars) +{ + int ret = SOUND_POOL_ERROR_NONE; + size_t idx = 0; + if ((pars == NULL) || (sscanf(pars, " %zu", &idx) < 1)) { + _printf(CMD_COLOR_RED, "You have to specify identifier of the pool " + "to be activated after command name! Format: " + CMD_ACTIVATE_POOL " \n"); + return FAIL; + } + + if (idx > (MAX_POOL_CNT - 1)) { + _printf(CMD_COLOR_RED, "Pool identifier value can't be greater than %d\n", + MAX_POOL_CNT - 1); + return FAIL; + } + + _logger_log_info(CMD_ACTIVATE_POOL " command was called"); + _logger_log_info("Activating the pool by %zu identifier...", idx); + + if (pools[idx] == NULL) + _logger_log_warn("Pool to be activated is NULL"); + + ret = sound_pool_activate(pools[idx]); + + if (ret == SOUND_POOL_ERROR_NONE) + _logger_log_info("sound_pool_set_state(pool, " + "SOUND_POOL_STATE_ACTIVE) returned %s value", + __stringify_sound_pool_error(ret)); + else + _logger_log_err("sound_pool_set_state(pool, " + "SOUND_POOL_STATE_ACTIVE) returned %s value", + __stringify_sound_pool_error(ret)); + + return (ret == SOUND_POOL_ERROR_NONE ? OK : FAIL); +} + +/* CMD_DEACTIVATE_POOL */ +static int __proxy_sound_pool_deactivate(const char *pars) +{ + size_t idx = 0; + if ((pars == NULL) || (sscanf(pars, " %zu", &idx) < 1)) { + _printf(CMD_COLOR_RED, "You have to specify identifier of the pool " + "to be deactivated after command name! Format: " + CMD_DEACTIVATE_POOL " \n"); + return FAIL; + } + + if (idx > (MAX_POOL_CNT - 1)) { + _printf(CMD_COLOR_RED, "Pool identifier value can't be greater than %d\n", + MAX_POOL_CNT - 1); + return FAIL; + } + + _logger_log_info(CMD_DEACTIVATE_POOL " command was called"); + _logger_log_info("Deactivating the pool by %zu identifier...", idx); + + if (pools[idx] == NULL) + _logger_log_warn("Pool to be deactivated is NULL"); + + int ret = sound_pool_deactivate(pools[idx]); + + if (ret == SOUND_POOL_ERROR_NONE) + _logger_log_info("sound_pool_set_state(pool, " + "SOUND_POOL_STATE_INACTIVE) returned %s value", + __stringify_sound_pool_error(ret)); + else + _logger_log_err("sound_pool_set_state(pool, " + "SOUND_POOL_STATE_INACTIVE) returned %s value", + __stringify_sound_pool_error(ret)); + + return (ret == SOUND_POOL_ERROR_NONE ? OK : FAIL); +} + +/* CMD_GET_POOL_STATE */ +static int __proxy_sound_pool_get_state(const char *pars) +{ + size_t idx = 0; + if ((pars == NULL) || (sscanf(pars, " %zu", &idx) < 1)) { + _printf(CMD_COLOR_RED, "You have to specify identifier of the pool " + "to get state for, after command name! Format: " + CMD_GET_POOL_STATE " \n"); + return FAIL; + } + + if (idx > (MAX_POOL_CNT - 1)) { + _printf(CMD_COLOR_RED, "Pool identifier value can't be greater than %d\n", + MAX_POOL_CNT - 1); + return FAIL; + } + + _logger_log_info(CMD_GET_POOL_STATE " command was called"); + _logger_log_info("Getting the pool state by %zu identifier...", idx); + + if (pools[idx] == NULL) + _logger_log_warn("Pool to get state for is NULL"); + + sound_pool_state_e state = SOUND_POOL_STATE_INACTIVE; + int ret = sound_pool_get_state(pools[idx], &state); + + const char *str_state = (state == SOUND_POOL_STATE_ACTIVE ? + "SOUND_POOL_STATE_ACTIVE" : "SOUND_POOL_STATE_INACTIVE"); + + if (ret == SOUND_POOL_ERROR_NONE) + _logger_log_info("sound_pool_get_state(pool, state) returned %s value," + " state is %s", __stringify_sound_pool_error(ret), str_state); + else + _logger_log_err("sound_pool_get_state(pool, state) returned %s value," + " state is %s", __stringify_sound_pool_error(ret), str_state); + + return (ret == SOUND_POOL_ERROR_NONE ? OK : FAIL); +} + +/* CMD_SET_POOL_VOLUME */ +static int __proxy_sound_pool_set_volume(const char *pars) +{ + size_t idx = 0; + float volume = .0f; + if ((pars == NULL) || (sscanf(pars, " %zu %f", &idx, &volume) < 2)) { + _printf(CMD_COLOR_RED, "You have to specify both identifier of the " + "pool and new volume float value to set volume for whole pool! " + "Format: " CMD_SET_POOL_VOLUME " \n"); + return FAIL; + } + + if (idx > (MAX_POOL_CNT - 1)) { + _printf(CMD_COLOR_RED, "Pool identifier value can't be greater than %d\n", + MAX_POOL_CNT - 1); + return FAIL; + } + + _logger_log_info(CMD_SET_POOL_VOLUME " command was called"); + _logger_log_info("Set %f volume value for pool with %zu identifier...", + volume, idx); + + if (pools[idx] == NULL) + _logger_log_warn("Pool to get state for is NULL"); + + if (volume < .0f || volume > 1.0f) + _logger_log_warn("Volume is set as %f, not in [0, 1.0] range", volume); + + int ret = sound_pool_set_volume(pools[idx], volume); + + if (ret == SOUND_POOL_ERROR_NONE) + _logger_log_info("sound_pool_set_global_volume(pool, %f) " + "returned %s value", volume, __stringify_sound_pool_error(ret)); + else + _logger_log_err("sound_pool_set_global_volume(pool, %f) " + "returned %s value", volume, __stringify_sound_pool_error(ret)); + + return (ret == SOUND_POOL_ERROR_NONE ? OK : FAIL); +} + +/* CMD_GET_POOL_VOLUME */ +static int __proxy_sound_pool_get_volume(const char *pars) +{ + size_t idx = 0; + if ((pars == NULL) || (sscanf(pars, " %zu", &idx) < 1)) { + _printf(CMD_COLOR_RED, "You have to specify identifier of the pool " + "to get volume for, after command name! Format: " + CMD_GET_POOL_VOLUME " \n"); + return FAIL; + } + + if (idx > (MAX_POOL_CNT - 1)) { + _printf(CMD_COLOR_RED, "Pool identifier value can't be greater than %d\n", + MAX_POOL_CNT - 1); + return FAIL; + } + + _logger_log_info(CMD_GET_POOL_VOLUME " command was called"); + _logger_log_info("Getting the pool global volume for pool with %zu " + "identifier...", idx); + + if (pools[idx] == NULL) + _logger_log_warn("Pool to get state for is NULL"); + + float volume = .0f; + int ret = sound_pool_get_volume(pools[idx], &volume); + + if (ret == SOUND_POOL_ERROR_NONE) + _logger_log_info("sound_pool_get_global_volume(pool, volume) returned " + "%s value, volume is %f", __stringify_sound_pool_error(ret), + volume); + else + _logger_log_err("sound_pool_get_global_volume(pool, volume) returned " + "%s value, volume is %f", __stringify_sound_pool_error(ret), + volume); + + return (ret == SOUND_POOL_ERROR_NONE ? OK : FAIL); +} + +/* CMD_SET_POOL_CB_MSG */ +static int __proxy_sound_pool_set_state_change_callback_message(const char *pars) +{ + size_t idx = 0; + + char msg[MAX_MSG_LEN] = { '\0' }; + + if ((pars == NULL) || (sscanf(pars, " %zu %"MAX_MSG_LEN_STR"[^ ]", &idx, msg) < 2)) { + _printf(CMD_COLOR_RED, "You have to specify both identifier of the " + "pool and message to be shown each time when state of the pool " + " is changed! Message should be a single word. Format: " + CMD_SET_POOL_CB_MSG " \n"); + return FAIL; + } + + if (idx > (MAX_POOL_CNT - 1)) { + _printf(CMD_COLOR_RED, "Pool identifier value can't be greater than %d\n", + MAX_POOL_CNT - 1); + return FAIL; + } + + _logger_log_info(CMD_SET_POOL_CB_MSG " command was called"); + _logger_log_info("Set state changing callback (%s message) for pool with " + "%zu identifier...", msg, idx); + + if (pools[idx] == NULL) + _logger_log_warn("Pool to set callback for is NULL"); + + if (messages[idx]) + free(messages[idx]); + messages[idx] = strndup(msg, MAX_MSG_LEN); + + int ret = sound_pool_set_state_change_callback(pools[idx], __sp_cb_msg, + messages[idx]); + + if (ret == SOUND_POOL_ERROR_NONE) + _logger_log_info("sound_pool_set_state_change_callback(pool, cb, " + "\"%s\") returned %s value", msg, __stringify_sound_pool_error(ret)); + else + _logger_log_err("sound_pool_set_state_change_callback(pool, cb, " + "\"%s\") returned %s value", msg, __stringify_sound_pool_error(ret)); + + return (ret == SOUND_POOL_ERROR_NONE ? OK : FAIL); +} + +/* CMD_SET_POOL_CB_SCRIPT */ +static int __proxy_sound_pool_set_state_change_callback_script(const char *pars) +{ + size_t idx = 0; + + char scr[MAX_MSG_LEN] = { '\0' }; + + if ((pars == NULL) || (sscanf(pars, " %zu %"MAX_MSG_LEN_STR"[^ ]", &idx, scr) < 2)) { + _printf(CMD_COLOR_RED, "You have to specify both identifier of the " + "pool and script file name to be executed each time when state " + "of the pool will be changed! Format: " + CMD_SET_POOL_CB_SCRIPT "