c2cce8a4b3235e3111d48d7311a3e995ffbdabd1
[platform/core/api/sound-pool.git] / test / sound_pool_test.c
1 /*
2  * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
3  *
4  * Licensed under the Apache License, Version 2.0 (the License);
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an AS IS BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 #include "logger.h"
18 #include "proxy.h"
19
20 #include <string.h>
21 #include <stdio.h>
22 #include <termios.h>
23 #include <unistd.h>
24 #include <getopt.h>
25
26 #define KEY_CODE_ESCAPE      27
27 #define KEY_CODE_BACKSPACE   127
28 #define KEY_CODE_TAB         9
29 #define KEY_CODE_ARROW_UP    65
30 #define KEY_CODE_ARROW_DOWN  66
31 #define KEY_CODE_ARROW_RIGHT 67
32 #define KEY_CODE_ARROW_LEFT  68
33
34 /* The list data structure to keep history of the test suite commands */
35 typedef struct __cmd_history_s {
36         struct __cmd_history_s *prev;
37         struct __cmd_history_s *next;
38         char cmd[MAX_COMMAND_LINE_LEN];
39 } _cmd_history_t;
40
41 static _cmd_history_t *_cmd_history_tail = NULL;
42 static _cmd_history_t *_cmd_history_curp = NULL;
43 static char OUTPUT_LOG_FILE[MAX_PATH_LEN] = "out.log";
44
45 void print_usage() {
46         printf( "Usage: sound_pool_test [options]                              \n");
47         printf( "Test Suite for testing Tizen SoundPool module                 \n");
48         printf( "-h, --help             - shows this help;                     \n");
49         printf( "-s, --script=SCRIPT    - executes commands from the text file \n"
50                         "                         directly after start;                \n");
51         printf( "-t, --target=TARGET(S) - selects the target or targets to     \n"
52                         "                         output logs. Possible targets are:   \n"
53                         "                         stderr, dlog, file. You can also     \n"
54                         "                         select multiple targets using coma.  \n"
55                         "                         for example,                         \n"
56                         "                         > sound_pool_test -t stderr,file     \n"
57                         "                         will output both in standard         \n"
58                         "                         error and file;                      \n");
59         printf( "-f, --file=FILEPATH    - selects file for file output logging.\n"
60                         "                         Works only in -t argument value      \n"
61                         "                         includes 'file' target;              \n");
62 }
63
64 _cmd_history_t *add_cmd_to_history(const char *cmd)
65 {
66         if (!cmd)
67                 return NULL;
68
69         if (!_cmd_history_tail) {
70                 _cmd_history_tail = malloc(sizeof(_cmd_history_t));
71                 if (!_cmd_history_tail)
72                         return NULL;
73                 _cmd_history_tail->prev = NULL;
74                 _cmd_history_tail->next = NULL;
75         } else {
76                 _cmd_history_tail->next = malloc(sizeof(_cmd_history_t));
77                 if (!_cmd_history_tail->next)
78                         return NULL;
79                 _cmd_history_tail->next->prev = _cmd_history_tail;
80                 _cmd_history_tail->next->next = NULL;
81                 _cmd_history_tail = _cmd_history_tail->next;
82         }
83
84         strncpy(_cmd_history_tail->cmd, cmd, MAX_COMMAND_LINE_LEN - 1);
85         _cmd_history_tail->cmd[MAX_COMMAND_LINE_LEN - 1] = '\0';
86         _cmd_history_curp = _cmd_history_tail;
87         return _cmd_history_tail;
88 }
89
90 const char *pop_up_curp_from_cmd_history()
91 {
92         if (!_cmd_history_curp)
93                 return NULL;
94
95         const char *curp_cmd = _cmd_history_curp->cmd;
96         if (_cmd_history_curp->prev)
97                 _cmd_history_curp = _cmd_history_curp->prev;
98         return curp_cmd;
99 }
100
101 const char *pop_down_curp_from_cmd_history()
102 {
103         if (!_cmd_history_curp)
104                 return NULL;
105
106         const char *curp_cmd = _cmd_history_curp->cmd;
107         if (_cmd_history_curp->next)
108                 _cmd_history_curp = _cmd_history_curp->next;
109         return curp_cmd;
110 }
111
112 /* Searches the same part of two strings from the start and returns the length
113    of this part. For example, for the strings "Big Troll" and "Big troll" value
114    4 will be returned (the same part is "Big "). */
115 size_t get_identical_start_len(const char *str1, const char *str2)
116 {
117         size_t len1 = strnlen(str1, MAX_COMMAND_LINE_LEN);
118         size_t len2 = strnlen(str2, MAX_COMMAND_LINE_LEN);
119         size_t idx = 0;
120         while(idx < len1 && idx < len2) {
121                 if (str1[idx] != str2[idx])
122                         break;
123                 ++idx;
124         }
125         return idx;
126 }
127
128 size_t auto_fill(const char *cmd_start, char fill_hint[MAX_COMMAND_LINE_LEN])
129 {
130         size_t idx = 0;
131         size_t cmd_start_len = strnlen(cmd_start, MAX_COMMAND_LINE_LEN);
132
133         char auto_fill[MAX_COMMAND_LINE_LEN] = { '\0' };
134         size_t fill_found = 0;
135
136         for (; idx < CMD_COUNT; ++idx) {
137                 if (strncmp(cmd_start, cmd_list[idx], cmd_start_len) == 0) {
138                         if (!fill_found) {
139                                 strncpy(auto_fill, cmd_list[idx], MAX_COMMAND_LINE_LEN);
140                                 fill_found = strnlen(auto_fill, MAX_COMMAND_LINE_LEN);
141                         } else {
142                                 fill_found = get_identical_start_len(auto_fill, cmd_list[idx]);
143                                 auto_fill[fill_found] = '\0';
144                         }
145                 }
146         }
147
148         if (!fill_found)
149                 strncpy(fill_hint, cmd_start, MAX_COMMAND_LINE_LEN);
150         else
151                 strncpy(fill_hint, auto_fill, MAX_COMMAND_LINE_LEN);
152
153         return fill_found;
154 }
155
156 size_t print_cmd_prompt()
157 {
158         const char *prompt = "sound-pool-ts-cmd > ";
159         printf("%s", prompt);
160         /* Return the length of comand prompt c-string */
161         return strnlen(prompt, MAX_COMMAND_LINE_LEN);
162 }
163
164 int getch(void)
165 {
166     struct termios oldattr, newattr;
167     int ch;
168     tcgetattr(STDIN_FILENO, &oldattr);
169     newattr = oldattr;
170     newattr.c_lflag &= ~(ICANON | ECHO);
171     tcsetattr(STDIN_FILENO, TCSANOW, &newattr);
172     ch = getchar();
173     tcsetattr(STDIN_FILENO, TCSANOW, &oldattr);
174     return ch;
175 }
176
177 size_t ts_getline(char *cmd_line)
178 {
179         if (!cmd_line)
180                 return 0;
181
182         print_cmd_prompt();
183
184         /* Read whole line */
185         int ci = 0;
186         char cc = '\0';
187         int c = 0;
188         while ((c = getch()) != EOF && (cc = (char)c) != '\n' &&
189                         ci < MAX_COMMAND_LINE_LEN - 1) {
190                 if (cc == KEY_CODE_ESCAPE) { /* Arrow keys */
191                         getch();
192                         c = getch();
193                         if (c == EOF)
194                                 continue;
195                         cc = (char)c; /* Here is particular arrow code */
196                         const char *curp_cmd = NULL;
197                         if (cc == KEY_CODE_ARROW_UP) {
198                                 if ((curp_cmd = pop_up_curp_from_cmd_history())) {
199                                         while (ci-- != 0)
200                                                 printf("\b \b");
201                                         printf("%s", curp_cmd);
202                                         strncpy(cmd_line, curp_cmd, MAX_COMMAND_LINE_LEN);
203                                         ci = strnlen(curp_cmd, MAX_COMMAND_LINE_LEN);
204                                 }
205                         } else if (cc == KEY_CODE_ARROW_DOWN) {
206                                 if ((curp_cmd = pop_down_curp_from_cmd_history())) {
207                                         while (ci-- != 0)
208                                                 printf("\b \b");
209                                         printf("%s", curp_cmd);
210                                         strncpy(cmd_line, curp_cmd, MAX_COMMAND_LINE_LEN);
211                                         ci = strnlen(curp_cmd, MAX_COMMAND_LINE_LEN);
212                                 }
213                         }
214                         continue;
215                 }
216                 if (cc == KEY_CODE_BACKSPACE) { /* Backspace key */
217                         if (ci != 0) {
218                                 printf("\b \b");
219                                 cmd_line[ci--] = '\0';
220                         }
221                         continue;
222                 }
223                 if (cc == KEY_CODE_TAB) { /* Tab key */
224                         size_t hint_len = auto_fill(cmd_line, cmd_line);
225                         while (ci < hint_len)
226                                 printf("%c", cmd_line[ci++]);
227                         cmd_line[ci] = '\0';
228                         continue;
229                 }
230                 cmd_line[ci++] = cc;
231                 cmd_line[ci] = '\0';
232                 printf("%c", cc);
233         }
234
235         printf("\n");
236
237         return ci + 1;
238 }
239
240 int main(int argc, char* argv[])
241 {
242         _logger_set_log_tag("TIZEN_SOUND_POOL_TEST_SUITE");
243         _logger_set_logging_mode(LOG_MODE_STDERR | LOG_MODE_DLOG);
244
245 #   define OPTIONS "s:f:t:h"
246         struct option options[] = {
247                 { "script",  required_argument, NULL, 's' },
248                 { "logfile", required_argument, NULL, 'f' },
249                 { "target",  required_argument, NULL, 't' },
250                 { "help",    no_argument,       NULL, 'h' },
251                 { NULL, 0, NULL, 0 }
252         };
253
254         char commands[MAX_COMMAND_LINE_LEN] = { '\0' };
255         size_t last_cmd_end = 0;
256
257         int opt = 0;
258         int do_print_usage = 0;
259         int do_set_file = 0;
260         while ((opt = getopt_long(argc, argv, OPTIONS, options, NULL)) != -1) {
261                 switch (opt) {
262                 case 's': {
263                         snprintf(commands + last_cmd_end, MAX_COMMAND_LINE_LEN,
264                                         "%s %s\n", CMD_EXECUTE_SCRIPT, optarg);
265                         last_cmd_end +=
266                                         strnlen(commands + last_cmd_end, MAX_COMMAND_LINE_LEN) + 1;
267                         break;
268                 }
269                 case 'f': {
270                         _logger_set_file(optarg);
271                         do_set_file--;
272                         break;
273                 }
274                 case 't': {
275                         int log_mode = LOG_MODE_NONE;
276                         char *token = strtok(optarg, ",");
277
278                         while (token != NULL) {
279                                 if (strncmp(token, "stderr", MAX_MSG_LEN) == 0) {
280                                         log_mode |= LOG_MODE_STDERR;
281                                 } else if (strncmp(token, "file", MAX_MSG_LEN) == 0) {
282                                         log_mode |= LOG_MODE_FILE;
283                                         do_set_file++;
284                                 } else if (strncmp(token, "dlog", MAX_MSG_LEN) == 0) {
285                                         log_mode |= LOG_MODE_DLOG;
286                                 } else {
287                                         _printf(CMD_COLOR_RED, "%s target is not supported! "
288                                                         "Use one (or combination separated by coma) "
289                                                         "from the list: dlog, stderr, and dlog.\n", token);
290                                 }
291                                 token = strtok(NULL, ", ");
292                         }
293
294                         if (log_mode != LOG_MODE_NONE)
295                                 _logger_set_logging_mode(log_mode);
296                         break;
297                 }
298                 case 'h':
299                 case '?': {
300                         do_print_usage = 1;
301                         break;
302                 }
303                 default:
304                         break;
305                 }
306         }
307
308         if (do_print_usage != 0)
309                 print_usage();
310
311         if (do_set_file > 0)
312                 _logger_set_file(OUTPUT_LOG_FILE);
313
314         char *ccmd = commands;
315
316         while (ccmd[0] != '\0') {
317                 if (_exec_cmd(ccmd) == UCMD) {
318                         _printf(CMD_COLOR_RED,
319                                         "Unknown command! Type 'help' for command help!\n");
320                 }
321                 ccmd += strnlen(ccmd, MAX_COMMAND_LINE_LEN) + 1;
322         }
323
324         char cmd_line[MAX_COMMAND_LINE_LEN];
325         size_t cmd_line_len = 0;
326
327         while ((cmd_line_len = ts_getline(cmd_line))) {
328                 if (cmd_line_len == 1)
329                         continue;
330
331                 /* Try to execute commands parsed from the line: */
332                 int res = _exec_cmd(cmd_line);
333                 if (res == EXIT)
334                         break;
335
336                 if (res == UCMD)
337                         _printf(CMD_COLOR_RED,
338                                         "Unknown command! Type 'help' for command help!\n");
339
340                 add_cmd_to_history(cmd_line);
341         }
342
343         return 0;
344 }