diff --git a/tools/perf/tests/builtin-test.c b/tools/perf/tests/builtin-test.c index 3401d79a1d24..8883d4744057 100644 --- a/tools/perf/tests/builtin-test.c +++ b/tools/perf/tests/builtin-test.c @@ -363,8 +363,14 @@ static int run_test_child(struct child_process *process) static struct pollfd *global_pfds; static size_t *global_pfd_indices; +static unsigned int summary_tests_passed; +static unsigned int summary_subtests_passed; +static unsigned int summary_tests_skipped; +static unsigned int summary_tests_failed; +static struct strbuf summary_failed_tests_buf = STRBUF_INIT; static int strbuf_addstr_safe(struct strbuf *sb, const char *s); +static int __printf(2, 3) strbuf_addf_safe(struct strbuf *sb, const char *fmt, ...); static int print_test_result(struct test_suite *t, int curr_suite, int curr_test_case, int result, int width, int running) @@ -382,11 +388,16 @@ static int print_test_result(struct test_suite *t, int curr_suite, int curr_test color_fprintf(stderr, PERF_COLOR_YELLOW, " Running (%d active)\n", running); break; case TEST_OK: + if (test_suite__num_test_cases(t) > 1) + summary_subtests_passed++; + else + summary_tests_passed++; pr_info(" Ok\n"); break; case TEST_SKIP: { const char *reason = skip_reason(t, curr_test_case); + summary_tests_skipped++; if (reason) color_fprintf(stderr, PERF_COLOR_YELLOW, " Skip (%s)\n", reason); else @@ -395,6 +406,15 @@ static int print_test_result(struct test_suite *t, int curr_suite, int curr_test break; case TEST_FAIL: default: + summary_tests_failed++; + if (test_suite__num_test_cases(t) > 1) + strbuf_addf_safe(&summary_failed_tests_buf, " %3d.%1d: %s\n", + curr_suite + 1, curr_test_case + 1, + test_description(t, curr_test_case)); + else + strbuf_addf_safe(&summary_failed_tests_buf, " %3d: %s\n", + curr_suite + 1, + test_description(t, curr_test_case)); color_fprintf(stderr, PERF_COLOR_RED, " FAILED!\n"); break; } @@ -736,6 +756,47 @@ static int strbuf_addstr_safe(struct strbuf *sb, const char *s) return ret; } +static int __printf(2, 3) strbuf_addf_safe(struct strbuf *sb, const char *fmt, ...) +{ + char buf[1024]; + va_list ap; + int len; + sigset_t set, oldset; + int ret; + + sigemptyset(&set); + sigaddset(&set, SIGINT); + sigaddset(&set, SIGTERM); + sigprocmask(SIG_BLOCK, &set, &oldset); + + va_start(ap, fmt); + len = vsnprintf(buf, sizeof(buf), fmt, ap); + va_end(ap); + + if (len < 0) { + sigprocmask(SIG_SETMASK, &oldset, NULL); + return len; + } + if ((size_t)len >= sizeof(buf)) { + char *dynamic_buf = malloc(len + 1); + + if (!dynamic_buf) { + sigprocmask(SIG_SETMASK, &oldset, NULL); + return -ENOMEM; + } + va_start(ap, fmt); + vsnprintf(dynamic_buf, len + 1, fmt, ap); + va_end(ap); + ret = strbuf_addstr(sb, dynamic_buf); + free(dynamic_buf); + } else { + ret = strbuf_addstr(sb, buf); + } + + sigprocmask(SIG_SETMASK, &oldset, NULL); + return ret; +} + static void drain_child_process_err(struct child_test *child) { char buf[512]; @@ -1013,6 +1074,23 @@ static void cmd_test_sig_handler(int sig) siglongjmp(cmd_test_jmp_buf, sig); } +static void print_tests_summary(void) +{ + pr_info("\n=== Test Summary ===\n"); + pr_info("Passed main tests : %u\n", summary_tests_passed); + pr_info("Passed subtests : %u\n", summary_subtests_passed); + pr_info("Skipped tests : %u\n", summary_tests_skipped); + if (summary_tests_failed > 0) { + color_fprintf(stderr, PERF_COLOR_RED, "Failed tests : %u\n", + summary_tests_failed); + pr_info("List of failed tests:\n"); + pr_info("%s", summary_failed_tests_buf.buf); + } else { + color_fprintf(stderr, PERF_COLOR_GREEN, "Failed tests : 0\n"); + } + strbuf_release(&summary_failed_tests_buf); +} + static int __cmd_test(struct test_suite **suites, int argc, const char *argv[], struct intlist *skiplist) { @@ -1090,9 +1168,13 @@ static int __cmd_test(struct test_suite **suites, int argc, const char *argv[], } if (intlist__find(skiplist, curr_suite + 1)) { - pr_info("%3d: %-*s:", curr_suite + 1, width, - test_description(*t, -1)); - color_fprintf(stderr, PERF_COLOR_YELLOW, " Skip (user override)\n"); + if (pass == 1) { + pr_info("%3d: %-*s:", curr_suite + 1, width, + test_description(*t, -1)); + color_fprintf(stderr, PERF_COLOR_YELLOW, + " Skip (user override)\n"); + summary_tests_skipped++; + } continue; } @@ -1125,6 +1207,7 @@ static int __cmd_test(struct test_suite **suites, int argc, const char *argv[], for (size_t x = 0; x < num_tests; x++) finish_test(child_tests, x, num_tests, width); } + print_tests_summary(); free(global_pfds); free(global_pfd_indices); global_pfds = NULL;