Upgrade bluez5_37 :Merge the code from private
[platform/upstream/bluez.git] / src / shared / tester.c
1 /*
2  *
3  *  BlueZ - Bluetooth protocol stack for Linux
4  *
5  *  Copyright (C) 2012-2014  Intel Corporation. All rights reserved.
6  *
7  *
8  *  This library is free software; you can redistribute it and/or
9  *  modify it under the terms of the GNU Lesser General Public
10  *  License as published by the Free Software Foundation; either
11  *  version 2.1 of the License, or (at your option) any later version.
12  *
13  *  This library is distributed in the hope that it will be useful,
14  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
15  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16  *  Lesser General Public License for more details.
17  *
18  *  You should have received a copy of the GNU Lesser General Public
19  *  License along with this library; if not, write to the Free Software
20  *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
21  *
22  */
23
24 #ifdef HAVE_CONFIG_H
25 #include <config.h>
26 #endif
27
28 #include <stdio.h>
29 #include <errno.h>
30 #include <unistd.h>
31 #include <stdlib.h>
32 #include <string.h>
33 #include <signal.h>
34 #include <sys/signalfd.h>
35
36 #include <glib.h>
37
38 #ifdef HAVE_VALGRIND_MEMCHECK_H
39 #include <valgrind/memcheck.h>
40 #endif
41
42 #include "src/shared/util.h"
43 #include "src/shared/tester.h"
44
45 #define COLOR_OFF       "\x1B[0m"
46 #define COLOR_BLACK     "\x1B[0;30m"
47 #define COLOR_RED       "\x1B[0;31m"
48 #define COLOR_GREEN     "\x1B[0;32m"
49 #define COLOR_YELLOW    "\x1B[0;33m"
50 #define COLOR_BLUE      "\x1B[0;34m"
51 #define COLOR_MAGENTA   "\x1B[0;35m"
52 #define COLOR_CYAN      "\x1B[0;36m"
53 #define COLOR_WHITE     "\x1B[0;37m"
54 #define COLOR_HIGHLIGHT "\x1B[1;39m"
55
56 #define print_text(color, fmt, args...) \
57                 printf(color fmt COLOR_OFF "\n", ## args)
58
59 #define print_summary(label, color, value, fmt, args...) \
60                         printf("%-52s " color "%-10s" COLOR_OFF fmt "\n", \
61                                                         label, value, ## args)
62
63 #define print_progress(name, color, fmt, args...) \
64                 printf(COLOR_HIGHLIGHT "%s" COLOR_OFF " - " \
65                                 color fmt COLOR_OFF "\n", name, ## args)
66
67 enum test_result {
68         TEST_RESULT_NOT_RUN,
69         TEST_RESULT_PASSED,
70         TEST_RESULT_FAILED,
71         TEST_RESULT_TIMED_OUT,
72 };
73
74 enum test_stage {
75         TEST_STAGE_INVALID,
76         TEST_STAGE_PRE_SETUP,
77         TEST_STAGE_SETUP,
78         TEST_STAGE_RUN,
79         TEST_STAGE_TEARDOWN,
80         TEST_STAGE_POST_TEARDOWN,
81 };
82
83 struct test_case {
84         char *name;
85         enum test_result result;
86         enum test_stage stage;
87         const void *test_data;
88         tester_data_func_t pre_setup_func;
89         tester_data_func_t setup_func;
90         tester_data_func_t test_func;
91         tester_data_func_t teardown_func;
92         tester_data_func_t post_teardown_func;
93         gdouble start_time;
94         gdouble end_time;
95         unsigned int timeout;
96         unsigned int timeout_id;
97         unsigned int teardown_id;
98         tester_destroy_func_t destroy;
99         void *user_data;
100 };
101
102 static GMainLoop *main_loop;
103
104 static GList *test_list;
105 static GList *test_current;
106 static GTimer *test_timer;
107
108 static gboolean option_version = FALSE;
109 static gboolean option_quiet = FALSE;
110 static gboolean option_debug = FALSE;
111 static gboolean option_list = FALSE;
112 static const char *option_prefix = NULL;
113
114 static void test_destroy(gpointer data)
115 {
116         struct test_case *test = data;
117
118         if (test->timeout_id > 0)
119                 g_source_remove(test->timeout_id);
120
121         if (test->teardown_id > 0)
122                 g_source_remove(test->teardown_id);
123
124         if (test->destroy)
125                 test->destroy(test->user_data);
126
127         free(test->name);
128         free(test);
129 }
130
131 void tester_print(const char *format, ...)
132 {
133         va_list ap;
134
135         if (tester_use_quiet())
136                 return;
137
138         printf("  %s", COLOR_WHITE);
139         va_start(ap, format);
140         vprintf(format, ap);
141         va_end(ap);
142         printf("%s\n", COLOR_OFF);
143 }
144
145 void tester_debug(const char *format, ...)
146 {
147         va_list ap;
148
149         if (!tester_use_debug())
150                 return;
151
152         printf("  %s", COLOR_WHITE);
153         va_start(ap, format);
154         vprintf(format, ap);
155         va_end(ap);
156         printf("%s\n", COLOR_OFF);
157 }
158
159 void tester_warn(const char *format, ...)
160 {
161         va_list ap;
162
163         printf("  %s", COLOR_WHITE);
164         va_start(ap, format);
165         vprintf(format, ap);
166         va_end(ap);
167         printf("%s\n", COLOR_OFF);
168 }
169
170 static void default_pre_setup(const void *test_data)
171 {
172         tester_pre_setup_complete();
173 }
174
175 static void default_setup(const void *test_data)
176 {
177         tester_setup_complete();
178 }
179
180 static void default_teardown(const void *test_data)
181 {
182         tester_teardown_complete();
183 }
184
185 static void default_post_teardown(const void *test_data)
186 {
187         tester_post_teardown_complete();
188 }
189
190 void tester_add_full(const char *name, const void *test_data,
191                                 tester_data_func_t pre_setup_func,
192                                 tester_data_func_t setup_func,
193                                 tester_data_func_t test_func,
194                                 tester_data_func_t teardown_func,
195                                 tester_data_func_t post_teardown_func,
196                                 unsigned int timeout,
197                                 void *user_data, tester_destroy_func_t destroy)
198 {
199         struct test_case *test;
200
201         if (!test_func)
202                 return;
203
204         if (option_prefix && !g_str_has_prefix(name, option_prefix)) {
205                 if (destroy)
206                         destroy(user_data);
207                 return;
208         }
209
210         if (option_list) {
211                 printf("%s\n", name);
212                 if (destroy)
213                         destroy(user_data);
214                 return;
215         }
216
217         test = new0(struct test_case, 1);
218         test->name = strdup(name);
219         test->result = TEST_RESULT_NOT_RUN;
220         test->stage = TEST_STAGE_INVALID;
221
222         test->test_data = test_data;
223
224         if (pre_setup_func)
225                 test->pre_setup_func = pre_setup_func;
226         else
227                 test->pre_setup_func = default_pre_setup;
228
229         if (setup_func)
230                 test->setup_func = setup_func;
231         else
232                 test->setup_func = default_setup;
233
234         test->test_func = test_func;
235
236         if (teardown_func)
237                 test->teardown_func = teardown_func;
238         else
239                 test->teardown_func = default_teardown;
240
241         if (post_teardown_func)
242                 test->post_teardown_func = post_teardown_func;
243         else
244                 test->post_teardown_func = default_post_teardown;
245
246         test->timeout = timeout;
247
248         test->destroy = destroy;
249         test->user_data = user_data;
250
251         test_list = g_list_append(test_list, test);
252 }
253
254 void tester_add(const char *name, const void *test_data,
255                                         tester_data_func_t setup_func,
256                                         tester_data_func_t test_func,
257                                         tester_data_func_t teardown_func)
258 {
259         tester_add_full(name, test_data, NULL, setup_func, test_func,
260                                         teardown_func, NULL, 0, NULL, NULL);
261 }
262
263 void *tester_get_data(void)
264 {
265         struct test_case *test;
266
267         if (!test_current)
268                 return NULL;
269
270         test = test_current->data;
271
272         return test->user_data;
273 }
274
275 static int tester_summarize(void)
276 {
277         unsigned int not_run = 0, passed = 0, failed = 0;
278         gdouble execution_time;
279         GList *list;
280
281         printf("\n");
282         print_text(COLOR_HIGHLIGHT, "");
283         print_text(COLOR_HIGHLIGHT, "Test Summary");
284         print_text(COLOR_HIGHLIGHT, "------------");
285
286         for (list = g_list_first(test_list); list; list = g_list_next(list)) {
287                 struct test_case *test = list->data;
288                 gdouble exec_time;
289
290                 exec_time = test->end_time - test->start_time;
291
292                 switch (test->result) {
293                 case TEST_RESULT_NOT_RUN:
294                         print_summary(test->name, COLOR_YELLOW, "Not Run", "");
295                         not_run++;
296                         break;
297                 case TEST_RESULT_PASSED:
298                         print_summary(test->name, COLOR_GREEN, "Passed",
299                                                 "%8.3f seconds", exec_time);
300                         passed++;
301                         break;
302                 case TEST_RESULT_FAILED:
303                         print_summary(test->name, COLOR_RED, "Failed",
304                                                 "%8.3f seconds", exec_time);
305                         failed++;
306                         break;
307                 case TEST_RESULT_TIMED_OUT:
308                         print_summary(test->name, COLOR_RED, "Timed out",
309                                                 "%8.3f seconds", exec_time);
310                         failed++;
311                         break;
312                 }
313         }
314
315         printf("\nTotal: %d, "
316                 COLOR_GREEN "Passed: %d (%.1f%%)" COLOR_OFF ", "
317                 COLOR_RED "Failed: %d" COLOR_OFF ", "
318                 COLOR_YELLOW "Not Run: %d" COLOR_OFF "\n",
319                         not_run + passed + failed, passed,
320                         (not_run + passed + failed) ?
321                         (float) passed * 100 / (not_run + passed + failed) : 0,
322                         failed, not_run);
323
324         execution_time = g_timer_elapsed(test_timer, NULL);
325         printf("Overall execution time: %.3g seconds\n", execution_time);
326
327         return failed;
328 }
329
330 static gboolean teardown_callback(gpointer user_data)
331 {
332         struct test_case *test = user_data;
333
334         test->teardown_id = 0;
335         test->stage = TEST_STAGE_TEARDOWN;
336
337         print_progress(test->name, COLOR_MAGENTA, "teardown");
338         test->teardown_func(test->test_data);
339
340 #ifdef HAVE_VALGRIND_MEMCHECK_H
341         VALGRIND_DO_ADDED_LEAK_CHECK;
342 #endif
343
344         return FALSE;
345 }
346
347 static gboolean test_timeout(gpointer user_data)
348 {
349         struct test_case *test = user_data;
350
351         test->timeout_id = 0;
352
353         if (!test_current)
354                 return FALSE;
355
356         test->result = TEST_RESULT_TIMED_OUT;
357         print_progress(test->name, COLOR_RED, "test timed out");
358
359         g_idle_add(teardown_callback, test);
360
361         return FALSE;
362 }
363
364 static void next_test_case(void)
365 {
366         struct test_case *test;
367
368         if (test_current)
369                 test_current = g_list_next(test_current);
370         else
371                 test_current = test_list;
372
373         if (!test_current) {
374                 g_timer_stop(test_timer);
375
376                 g_main_loop_quit(main_loop);
377                 return;
378         }
379
380         test = test_current->data;
381
382         printf("\n");
383         print_progress(test->name, COLOR_BLACK, "init");
384
385         test->start_time = g_timer_elapsed(test_timer, NULL);
386
387         if (test->timeout > 0)
388                 test->timeout_id = g_timeout_add_seconds(test->timeout,
389                                                         test_timeout, test);
390
391         test->stage = TEST_STAGE_PRE_SETUP;
392
393         test->pre_setup_func(test->test_data);
394 }
395
396 static gboolean setup_callback(gpointer user_data)
397 {
398         struct test_case *test = user_data;
399
400         test->stage = TEST_STAGE_SETUP;
401
402         print_progress(test->name, COLOR_BLUE, "setup");
403         test->setup_func(test->test_data);
404
405         return FALSE;
406 }
407
408 static gboolean run_callback(gpointer user_data)
409 {
410         struct test_case *test = user_data;
411
412         test->stage = TEST_STAGE_RUN;
413
414         print_progress(test->name, COLOR_BLACK, "run");
415         test->test_func(test->test_data);
416
417         return FALSE;
418 }
419
420 static gboolean done_callback(gpointer user_data)
421 {
422         struct test_case *test = user_data;
423
424         test->end_time = g_timer_elapsed(test_timer, NULL);
425
426         print_progress(test->name, COLOR_BLACK, "done");
427         next_test_case();
428
429         return FALSE;
430 }
431
432 void tester_pre_setup_complete(void)
433 {
434         struct test_case *test;
435
436         if (!test_current)
437                 return;
438
439         test = test_current->data;
440
441         if (test->stage != TEST_STAGE_PRE_SETUP)
442                 return;
443
444         g_idle_add(setup_callback, test);
445 }
446
447 void tester_pre_setup_failed(void)
448 {
449         struct test_case *test;
450
451         if (!test_current)
452                 return;
453
454         test = test_current->data;
455
456         if (test->stage != TEST_STAGE_PRE_SETUP)
457                 return;
458
459         print_progress(test->name, COLOR_RED, "pre setup failed");
460
461         g_idle_add(done_callback, test);
462 }
463
464 void tester_setup_complete(void)
465 {
466         struct test_case *test;
467
468         if (!test_current)
469                 return;
470
471         test = test_current->data;
472
473         if (test->stage != TEST_STAGE_SETUP)
474                 return;
475
476         print_progress(test->name, COLOR_BLUE, "setup complete");
477
478         g_idle_add(run_callback, test);
479 }
480
481 void tester_setup_failed(void)
482 {
483         struct test_case *test;
484
485         if (!test_current)
486                 return;
487
488         test = test_current->data;
489
490         if (test->stage != TEST_STAGE_SETUP)
491                 return;
492
493         test->stage = TEST_STAGE_POST_TEARDOWN;
494
495         if (test->timeout_id > 0) {
496                 g_source_remove(test->timeout_id);
497                 test->timeout_id = 0;
498         }
499
500         print_progress(test->name, COLOR_RED, "setup failed");
501         print_progress(test->name, COLOR_MAGENTA, "teardown");
502
503         test->post_teardown_func(test->test_data);
504 }
505
506 static void test_result(enum test_result result)
507 {
508         struct test_case *test;
509
510         if (!test_current)
511                 return;
512
513         test = test_current->data;
514
515         if (test->stage != TEST_STAGE_RUN)
516                 return;
517
518         if (test->timeout_id > 0) {
519                 g_source_remove(test->timeout_id);
520                 test->timeout_id = 0;
521         }
522
523         test->result = result;
524         switch (result) {
525         case TEST_RESULT_PASSED:
526                 print_progress(test->name, COLOR_GREEN, "test passed");
527                 break;
528         case TEST_RESULT_FAILED:
529                 print_progress(test->name, COLOR_RED, "test failed");
530                 break;
531         case TEST_RESULT_NOT_RUN:
532                 print_progress(test->name, COLOR_YELLOW, "test not run");
533                 break;
534         case TEST_RESULT_TIMED_OUT:
535                 print_progress(test->name, COLOR_RED, "test timed out");
536                 break;
537         }
538
539         if (test->teardown_id > 0)
540                 return;
541
542         test->teardown_id = g_idle_add(teardown_callback, test);
543 }
544
545 void tester_test_passed(void)
546 {
547         test_result(TEST_RESULT_PASSED);
548 }
549
550 void tester_test_failed(void)
551 {
552         test_result(TEST_RESULT_FAILED);
553 }
554
555 void tester_test_abort(void)
556 {
557         test_result(TEST_RESULT_NOT_RUN);
558 }
559
560 void tester_teardown_complete(void)
561 {
562         struct test_case *test;
563
564         if (!test_current)
565                 return;
566
567         test = test_current->data;
568
569         if (test->stage != TEST_STAGE_TEARDOWN)
570                 return;
571
572         test->stage = TEST_STAGE_POST_TEARDOWN;
573
574         test->post_teardown_func(test->test_data);
575 }
576
577 void tester_teardown_failed(void)
578 {
579         struct test_case *test;
580
581         if (!test_current)
582                 return;
583
584         test = test_current->data;
585
586         if (test->stage != TEST_STAGE_TEARDOWN)
587                 return;
588
589         test->stage = TEST_STAGE_POST_TEARDOWN;
590
591         tester_post_teardown_failed();
592 }
593
594 void tester_post_teardown_complete(void)
595 {
596         struct test_case *test;
597
598         if (!test_current)
599                 return;
600
601         test = test_current->data;
602
603         if (test->stage != TEST_STAGE_POST_TEARDOWN)
604                 return;
605
606         print_progress(test->name, COLOR_MAGENTA, "teardown complete");
607
608         g_idle_add(done_callback, test);
609 }
610
611 void tester_post_teardown_failed(void)
612 {
613         struct test_case *test;
614
615         if (!test_current)
616                 return;
617
618         test = test_current->data;
619
620         if (test->stage != TEST_STAGE_POST_TEARDOWN)
621                 return;
622
623         print_progress(test->name, COLOR_RED, "teardown failed");
624
625         g_idle_add(done_callback, test);
626 }
627
628 static gboolean start_tester(gpointer user_data)
629 {
630         test_timer = g_timer_new();
631
632         next_test_case();
633
634         return FALSE;
635 }
636
637 struct wait_data {
638         unsigned int seconds;
639         struct test_case *test;
640         tester_wait_func_t func;
641         void *user_data;
642 };
643
644 static gboolean wait_callback(gpointer user_data)
645 {
646         struct wait_data *wait = user_data;
647         struct test_case *test = wait->test;
648
649         wait->seconds--;
650
651         if (wait->seconds > 0) {
652                 print_progress(test->name, COLOR_BLACK, "%u seconds left",
653                                                                 wait->seconds);
654                 return TRUE;
655         }
656
657         print_progress(test->name, COLOR_BLACK, "waiting done");
658
659         wait->func(wait->user_data);
660
661         free(wait);
662
663         return FALSE;
664 }
665
666 void tester_wait(unsigned int seconds, tester_wait_func_t func,
667                                                         void *user_data)
668 {
669         struct test_case *test;
670         struct wait_data *wait;
671
672         if (!func || seconds < 1)
673                 return;
674
675         if (!test_current)
676                 return;
677
678         test = test_current->data;
679
680         wait = new0(struct wait_data, 1);
681         wait->seconds = seconds;
682         wait->test = test;
683         wait->func = func;
684         wait->user_data = user_data;
685
686         g_timeout_add(1000, wait_callback, wait);
687
688         print_progress(test->name, COLOR_BLACK, "waiting %u seconds", seconds);
689 }
690
691 static gboolean signal_handler(GIOChannel *channel, GIOCondition condition,
692                                                         gpointer user_data)
693 {
694         static bool terminated = false;
695         struct signalfd_siginfo si;
696         ssize_t result;
697         int fd;
698
699         if (condition & (G_IO_NVAL | G_IO_ERR | G_IO_HUP)) {
700                 g_main_loop_quit(main_loop);
701                 return FALSE;
702         }
703
704         fd = g_io_channel_unix_get_fd(channel);
705
706         result = read(fd, &si, sizeof(si));
707         if (result != sizeof(si))
708                 return FALSE;
709
710         switch (si.ssi_signo) {
711         case SIGINT:
712         case SIGTERM:
713                 if (!terminated)
714                         g_main_loop_quit(main_loop);
715
716                 terminated = true;
717                 break;
718         }
719
720         return TRUE;
721 }
722
723 static guint setup_signalfd(void)
724 {
725         GIOChannel *channel;
726         guint source;
727         sigset_t mask;
728         int fd;
729
730         sigemptyset(&mask);
731         sigaddset(&mask, SIGINT);
732         sigaddset(&mask, SIGTERM);
733
734         if (sigprocmask(SIG_BLOCK, &mask, NULL) < 0) {
735                 perror("Failed to set signal mask");
736                 return 0;
737         }
738
739         fd = signalfd(-1, &mask, 0);
740         if (fd < 0) {
741                 perror("Failed to create signal descriptor");
742                 return 0;
743         }
744
745         channel = g_io_channel_unix_new(fd);
746
747         g_io_channel_set_close_on_unref(channel, TRUE);
748         g_io_channel_set_encoding(channel, NULL, NULL);
749         g_io_channel_set_buffered(channel, FALSE);
750
751         source = g_io_add_watch(channel,
752                                 G_IO_IN | G_IO_HUP | G_IO_ERR | G_IO_NVAL,
753                                 signal_handler, NULL);
754
755         g_io_channel_unref(channel);
756
757         return source;
758 }
759
760 bool tester_use_quiet(void)
761 {
762         return option_quiet == TRUE ? true : false;
763 }
764
765 bool tester_use_debug(void)
766 {
767         return option_debug == TRUE ? true : false;
768 }
769
770 static GOptionEntry options[] = {
771         { "version", 'v', 0, G_OPTION_ARG_NONE, &option_version,
772                                 "Show version information and exit" },
773         { "quiet", 'q', 0, G_OPTION_ARG_NONE, &option_quiet,
774                                 "Run tests without logging" },
775         { "debug", 'd', 0, G_OPTION_ARG_NONE, &option_debug,
776                                 "Run tests with debug output" },
777         { "list", 'l', 0, G_OPTION_ARG_NONE, &option_list,
778                                 "Only list the tests to be run" },
779         { "prefix", 'p', 0, G_OPTION_ARG_STRING, &option_prefix,
780                                 "Run tests matching provided prefix" },
781         { NULL },
782 };
783
784 void tester_init(int *argc, char ***argv)
785 {
786         GOptionContext *context;
787         GError *error = NULL;
788
789         context = g_option_context_new(NULL);
790         g_option_context_add_main_entries(context, options, NULL);
791
792         if (g_option_context_parse(context, argc, argv, &error) == FALSE) {
793                 if (error != NULL) {
794                         g_printerr("%s\n", error->message);
795                         g_error_free(error);
796                 } else
797                         g_printerr("An unknown error occurred\n");
798                 exit(1);
799         }
800
801         g_option_context_free(context);
802
803         if (option_version == TRUE) {
804                 g_print("%s\n", VERSION);
805                 exit(EXIT_SUCCESS);
806         }
807
808         main_loop = g_main_loop_new(NULL, FALSE);
809
810         test_list = NULL;
811         test_current = NULL;
812 }
813
814 int tester_run(void)
815 {
816         guint signal;
817         int ret;
818
819         if (!main_loop)
820                 return EXIT_FAILURE;
821
822         if (option_list) {
823                 g_main_loop_unref(main_loop);
824                 return EXIT_SUCCESS;
825         }
826
827         signal = setup_signalfd();
828
829         g_idle_add(start_tester, NULL);
830         g_main_loop_run(main_loop);
831
832         g_source_remove(signal);
833
834         g_main_loop_unref(main_loop);
835
836         ret = tester_summarize();
837
838         g_list_free_full(test_list, test_destroy);
839
840         return ret == 0 ? EXIT_SUCCESS : EXIT_FAILURE;
841 }