1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * builtin-test.c 4 * 5 * Builtin regression testing command: ever growing number of sanity tests 6 */ 7 #include <ctype.h> 8 #include <fcntl.h> 9 #include <errno.h> 10 #ifdef HAVE_BACKTRACE_SUPPORT 11 #include <execinfo.h> 12 #endif 13 #include <setjmp.h> 14 #include <stdlib.h> 15 #include <string.h> 16 17 #include <dirent.h> 18 #include <linux/kernel.h> 19 #include <linux/string.h> 20 #include <linux/zalloc.h> 21 #include <poll.h> 22 #include <sys/ioctl.h> 23 #include <sys/stat.h> 24 #include <sys/time.h> 25 #include <sys/types.h> 26 #include <sys/wait.h> 27 #include <unistd.h> 28 29 #include <subcmd/exec-cmd.h> 30 #include <subcmd/parse-options.h> 31 #include <subcmd/run-command.h> 32 33 #include "builtin.h" 34 #include "color.h" 35 #include "config.h" 36 #include "debug.h" 37 #include "hist.h" 38 #include "intlist.h" 39 #include "string2.h" 40 #include "symbol.h" 41 #include "tests-scripts.h" 42 #include "tests.h" 43 #include "util/rlimit.h" 44 #include "util/strbuf.h" 45 #include "util/term.h" 46 47 static const char *junit_filename; 48 static struct strbuf junit_xml_buf = STRBUF_INIT; 49 50 /* 51 * Command line option to not fork the test running in the same process and 52 * making them easier to debug. 53 */ 54 static bool dont_fork; 55 /* Fork the tests in parallel and wait for their completion. */ 56 static bool sequential; 57 /* Number of times each test is run. */ 58 static unsigned int runs_per_test = 1; 59 /* Number of lines to include in failure snippet. */ 60 static unsigned int failure_snippet_lines = 10; 61 const char *dso_to_test; 62 const char *test_objdump_path = "objdump"; 63 static const char *workload_control; 64 65 /* 66 * List of architecture specific tests. Not a weak symbol as the array length is 67 * dependent on the initialization, as such GCC with LTO complains of 68 * conflicting definitions with a weak symbol. 69 */ 70 #if defined(__i386__) || defined(__x86_64__) || defined(__aarch64__) || defined(__powerpc64__) 71 extern struct test_suite *arch_tests[]; 72 #else 73 static struct test_suite *arch_tests[] = { 74 NULL, 75 }; 76 #endif 77 78 static struct test_suite *generic_tests[] = { 79 &suite__vmlinux_matches_kallsyms, 80 &suite__openat_syscall_event, 81 &suite__openat_syscall_event_on_all_cpus, 82 &suite__basic_mmap, 83 &suite__mem, 84 &suite__parse_events, 85 &suite__uncore_event_sorting, 86 &suite__expr, 87 &suite__PERF_RECORD, 88 &suite__pmu, 89 &suite__pmu_events, 90 &suite__hwmon_pmu, 91 &suite__tool_pmu, 92 &suite__dso_data, 93 &suite__perf_evsel__roundtrip_name_test, 94 #ifdef HAVE_LIBTRACEEVENT 95 &suite__perf_evsel__tp_sched_test, 96 &suite__syscall_openat_tp_fields, 97 #endif 98 &suite__hists_link, 99 &suite__bp_signal, 100 &suite__bp_signal_overflow, 101 &suite__bp_accounting, 102 &suite__wp, 103 &suite__task_exit, 104 &suite__sw_clock_freq, 105 &suite__code_reading, 106 &suite__sample_parsing, 107 &suite__keep_tracking, 108 &suite__parse_no_sample_id_all, 109 &suite__hists_filter, 110 &suite__mmap_thread_lookup, 111 &suite__thread_maps_share, 112 &suite__hists_output, 113 &suite__hists_cumulate, 114 #ifdef HAVE_LIBTRACEEVENT 115 &suite__switch_tracking, 116 #endif 117 &suite__fdarray__filter, 118 &suite__fdarray__add, 119 &suite__kmod_path__parse, 120 &suite__thread_map, 121 &suite__session_topology, 122 &suite__thread_map_synthesize, 123 &suite__thread_map_remove, 124 &suite__cpu_map, 125 &suite__synthesize_stat_config, 126 &suite__synthesize_stat, 127 &suite__synthesize_stat_round, 128 &suite__event_update, 129 &suite__event_times, 130 &suite__backward_ring_buffer, 131 &suite__sdt_event, 132 &suite__is_printable_array, 133 &suite__bitmap_print, 134 &suite__perf_hooks, 135 &suite__unit_number__scnprint, 136 &suite__mem2node, 137 &suite__time_utils, 138 &suite__jit_write_elf, 139 &suite__pfm, 140 &suite__api_io, 141 &suite__maps, 142 &suite__demangle_java, 143 &suite__demangle_ocaml, 144 &suite__demangle_rust, 145 &suite__parse_metric, 146 &suite__pe_file_parsing, 147 &suite__expand_cgroup_events, 148 &suite__perf_time_to_tsc, 149 &suite__dlfilter, 150 &suite__sigtrap, 151 &suite__event_groups, 152 &suite__symbols, 153 &suite__util, 154 &suite__subcmd_help, 155 &suite__kallsyms_split, 156 NULL, 157 }; 158 159 static struct test_workload *workloads[] = { 160 &workload__noploop, 161 &workload__thloop, 162 &workload__named_threads, 163 &workload__leafloop, 164 &workload__sqrtloop, 165 &workload__brstack, 166 &workload__datasym, 167 &workload__landlock, 168 &workload__traploop, 169 &workload__inlineloop, 170 &workload__jitdump, 171 &workload__context_switch_loop, 172 &workload__deterministic, 173 &workload__callchain, 174 175 #ifdef HAVE_RUST_SUPPORT 176 &workload__code_with_type, 177 #endif 178 }; 179 180 struct workload_control { 181 int ctl_fd; 182 int ack_fd; 183 }; 184 185 #define workloads__for_each(workload) \ 186 for (unsigned i = 0; i < ARRAY_SIZE(workloads) && ({ workload = workloads[i]; 1; }); i++) 187 188 #define test_suite__for_each_test_case(suite, idx) \ 189 for (idx = 0; (suite)->test_cases && (suite)->test_cases[idx].name != NULL; idx++) 190 191 static void close_parent_fds(void) 192 { 193 DIR *dir = opendir("/proc/self/fd"); 194 struct dirent *ent; 195 196 while ((ent = readdir(dir))) { 197 char *end; 198 long fd; 199 200 if (ent->d_type != DT_LNK) 201 continue; 202 203 if (!isdigit(ent->d_name[0])) 204 continue; 205 206 fd = strtol(ent->d_name, &end, 10); 207 if (*end) 208 continue; 209 210 if (fd <= 3 || fd == dirfd(dir)) 211 continue; 212 213 close(fd); 214 } 215 closedir(dir); 216 } 217 218 static void check_leaks(void) 219 { 220 DIR *dir = opendir("/proc/self/fd"); 221 struct dirent *ent; 222 int leaks = 0; 223 224 while ((ent = readdir(dir))) { 225 char path[PATH_MAX]; 226 char *end; 227 long fd; 228 ssize_t len; 229 230 if (ent->d_type != DT_LNK) 231 continue; 232 233 if (!isdigit(ent->d_name[0])) 234 continue; 235 236 fd = strtol(ent->d_name, &end, 10); 237 if (*end) 238 continue; 239 240 if (fd <= 3 || fd == dirfd(dir)) 241 continue; 242 243 leaks++; 244 len = readlinkat(dirfd(dir), ent->d_name, path, sizeof(path)); 245 if (len > 0 && (size_t)len < sizeof(path)) 246 path[len] = '\0'; 247 else 248 strncpy(path, ent->d_name, sizeof(path)); 249 pr_err("Leak of file descriptor %s that opened: '%s'\n", ent->d_name, path); 250 } 251 closedir(dir); 252 if (leaks) 253 abort(); 254 } 255 256 static int test_suite__num_test_cases(const struct test_suite *t) 257 { 258 int num; 259 260 test_suite__for_each_test_case(t, num); 261 262 return num; 263 } 264 265 static const char *skip_reason(const struct test_suite *t, int test_case) 266 { 267 if (!t->test_cases) 268 return NULL; 269 270 return t->test_cases[test_case >= 0 ? test_case : 0].skip_reason; 271 } 272 273 static const char *test_description(const struct test_suite *t, int test_case) 274 { 275 if (t->test_cases && test_case >= 0) 276 return t->test_cases[test_case].desc; 277 278 return t->desc; 279 } 280 281 static test_fnptr test_function(const struct test_suite *t, int test_case) 282 { 283 if (test_case <= 0) 284 return t->test_cases[0].run_case; 285 286 return t->test_cases[test_case].run_case; 287 } 288 289 static bool test_exclusive(const struct test_suite *t, int test_case) 290 { 291 if (test_case <= 0) 292 return t->test_cases[0].exclusive; 293 294 return t->test_cases[test_case].exclusive; 295 } 296 297 static bool perf_test__matches(const char *desc, int suite_num, int argc, const char *argv[]) 298 { 299 int i; 300 301 if (argc == 0) 302 return true; 303 304 for (i = 0; i < argc; ++i) { 305 char *end; 306 long nr = strtoul(argv[i], &end, 10); 307 308 if (*end == '\0') { 309 if (nr == suite_num + 1) 310 return true; 311 continue; 312 } 313 314 if (strcasestr(desc, argv[i])) 315 return true; 316 } 317 318 return false; 319 } 320 321 struct child_test { 322 struct child_process process; 323 struct test_suite *test; 324 int suite_num; 325 int test_case_num; 326 struct strbuf err_output; 327 int result; 328 bool done; 329 struct timespec start_time; 330 struct timespec end_time; 331 }; 332 333 static jmp_buf run_test_jmp_buf; 334 335 static void child_test_sig_handler(int sig) 336 { 337 #ifdef HAVE_BACKTRACE_SUPPORT 338 void *stackdump[32]; 339 size_t stackdump_size; 340 #endif 341 342 fprintf(stderr, "\n---- unexpected signal (%d) ----\n", sig); 343 #ifdef HAVE_BACKTRACE_SUPPORT 344 stackdump_size = backtrace(stackdump, ARRAY_SIZE(stackdump)); 345 __dump_stack(stderr, stackdump, stackdump_size); 346 #endif 347 siglongjmp(run_test_jmp_buf, sig); 348 } 349 350 static int run_test_child(struct child_process *process) 351 { 352 const int signals[] = { 353 SIGABRT, SIGBUS, SIGFPE, SIGILL, SIGINT, SIGPIPE, SIGQUIT, SIGSEGV, SIGTERM, 354 }; 355 struct child_test *child = container_of(process, struct child_test, process); 356 int err; 357 358 close_parent_fds(); 359 360 err = sigsetjmp(run_test_jmp_buf, 1); 361 if (err) { 362 /* Received signal. */ 363 err = err > 0 ? -err : -1; 364 goto err_out; 365 } 366 367 for (size_t i = 0; i < ARRAY_SIZE(signals); i++) 368 signal(signals[i], child_test_sig_handler); 369 370 pr_debug("---- start ----\n"); 371 pr_debug("test child forked, pid %d\n", getpid()); 372 err = test_function(child->test, child->test_case_num)(child->test, child->test_case_num); 373 pr_debug("---- end(%d) ----\n", err); 374 375 check_leaks(); 376 err_out: 377 fflush(NULL); 378 for (size_t i = 0; i < ARRAY_SIZE(signals); i++) 379 signal(signals[i], SIG_DFL); 380 return -err; 381 } 382 383 #define TEST_RUNNING -3 384 385 static struct pollfd *global_pfds; 386 static size_t *global_pfd_indices; 387 static unsigned int summary_tests_passed; 388 static unsigned int summary_subtests_passed; 389 static unsigned int summary_tests_skipped; 390 static unsigned int summary_tests_failed; 391 static struct strbuf summary_failed_tests_buf = STRBUF_INIT; 392 393 static int strbuf_addstr_safe(struct strbuf *sb, const char *s); 394 static int __printf(2, 3) strbuf_addf_safe(struct strbuf *sb, const char *fmt, ...); 395 396 static char *xml_escape(const char *str) 397 { 398 struct strbuf buf = STRBUF_INIT; 399 const char *p; 400 char *res; 401 402 if (!str) 403 return strdup(""); 404 405 for (p = str; *p; p++) { 406 if (*p == '&') 407 strbuf_addstr(&buf, "&"); 408 else if (*p == '<') 409 strbuf_addstr(&buf, "<"); 410 else if (*p == '>') 411 strbuf_addstr(&buf, ">"); 412 else if (*p == '"') 413 strbuf_addstr(&buf, """); 414 else if ((unsigned char)*p >= 32 || *p == '\n' || *p == '\t') 415 strbuf_addch(&buf, *p); 416 } 417 res = strbuf_detach(&buf, NULL); 418 return res ? res : strdup(""); 419 } 420 421 static int get_term_width(void) 422 { 423 struct winsize ws; 424 int cols = 80; 425 int term_width; 426 427 /* 428 * If output is redirected to a file or piped, we don't need to wrap 429 * or truncate at all. Use a massive virtually infinite terminal width 430 * so descriptions are printed in full. 431 */ 432 if (!isatty(fileno(debug_file()))) 433 return 10000; 434 435 get_term_dimensions(&ws); 436 if (ws.ws_col > 0) 437 cols = ws.ws_col; 438 439 /* 440 * Limit description width to fit on a single line. We subtract 35 441 * columns of headroom to allocate space for: 442 * - The suite index prefix: e.g. " 10.100:" (8 characters) plus 1 space separator. 443 * - The trailing colon (1 character) and space before status (1 character). 444 * - The longest status results: e.g. "Skip (some metrics failed)" (26 characters) 445 * or "Running (XX active)" (20 characters). 446 * 447 * A minimum description width of 10 is enforced to ensure names are 448 * legible even on very narrow consoles. 449 */ 450 term_width = cols - 35; 451 if (term_width < 10) 452 term_width = 10; 453 454 return term_width; 455 } 456 457 static int get_max_desc_width(int width) 458 { 459 int term_width = get_term_width(); 460 461 return width > term_width ? term_width : width; 462 } 463 464 static int print_test_result(struct test_suite *t, int curr_suite, int curr_test_case, 465 int result, int width, int running, 466 const char *err_output, double elapsed) 467 { 468 int pad_width = get_max_desc_width(width); 469 int term_width = get_term_width(); 470 471 if (test_suite__num_test_cases(t) > 1) { 472 char prefix[32]; 473 int len = snprintf(prefix, sizeof(prefix), "%3d.%1d:", 474 curr_suite + 1, curr_test_case + 1); 475 int pad = len >= 4 ? pad_width + 4 - len : pad_width; 476 int trunc = len >= 4 ? term_width + 4 - len : term_width; 477 478 pr_info("%s %-*.*s:", prefix, pad, trunc, 479 test_description(t, curr_test_case)); 480 } else { 481 pr_info("%3d: %-*.*s:", curr_suite + 1, pad_width, term_width, 482 test_description(t, curr_test_case)); 483 } 484 485 switch (result) { 486 case TEST_RUNNING: 487 color_fprintf(debug_file(), PERF_COLOR_YELLOW, " Running (%d active)\n", running); 488 break; 489 case TEST_OK: 490 if (test_suite__num_test_cases(t) > 1) 491 summary_subtests_passed++; 492 else 493 summary_tests_passed++; 494 pr_info(" Ok\n"); 495 break; 496 case TEST_SKIP: { 497 const char *reason = skip_reason(t, curr_test_case); 498 499 summary_tests_skipped++; 500 if (reason) 501 color_fprintf(debug_file(), PERF_COLOR_YELLOW, " Skip (%s)\n", reason); 502 else 503 color_fprintf(debug_file(), PERF_COLOR_YELLOW, " Skip\n"); 504 } 505 break; 506 case TEST_FAIL: 507 default: 508 summary_tests_failed++; 509 if (test_suite__num_test_cases(t) > 1) 510 strbuf_addf_safe(&summary_failed_tests_buf, " %3d.%1d: %s\n", 511 curr_suite + 1, curr_test_case + 1, 512 test_description(t, curr_test_case)); 513 else 514 strbuf_addf_safe(&summary_failed_tests_buf, " %3d: %s\n", 515 curr_suite + 1, 516 test_description(t, curr_test_case)); 517 color_fprintf(debug_file(), PERF_COLOR_RED, " FAILED!\n"); 518 break; 519 } 520 521 if (junit_filename && result != TEST_RUNNING) { 522 const char *classname = t->desc; 523 const char *testname = test_description(t, curr_test_case); 524 char *escaped_err = xml_escape(err_output); 525 char *escaped_class = xml_escape(classname); 526 char *escaped_test = xml_escape(testname); 527 528 strbuf_addf(&junit_xml_buf, 529 " <testcase classname=\"%s\" name=\"%s\" time=\"%.2f\">\n", 530 escaped_class, escaped_test, elapsed); 531 if (result != TEST_OK && result != TEST_SKIP) { 532 strbuf_addf(&junit_xml_buf, 533 " <failure message=\"FAILED\">\n%s\n </failure>\n", 534 escaped_err); 535 } else if (result == TEST_SKIP) { 536 const char *reason = skip_reason(t, curr_test_case); 537 char *escaped_reason = xml_escape(reason ? reason : "Skip"); 538 539 if (err_output && *err_output) { 540 strbuf_addf(&junit_xml_buf, 541 " <skipped message=\"%s\">\n%s\n </skipped>\n", 542 escaped_reason, escaped_err); 543 } else { 544 strbuf_addf(&junit_xml_buf, " <skipped message=\"%s\"/>\n", 545 escaped_reason); 546 } 547 free(escaped_reason); 548 } 549 strbuf_addstr(&junit_xml_buf, " </testcase>\n"); 550 free(escaped_err); 551 free(escaped_class); 552 free(escaped_test); 553 } 554 555 return 0; 556 } 557 558 static const char * const fail_keywords[] = { 559 "error", "fail", "segv", "abort", 560 "signal", "fatal", "panic", "corrupt", NULL 561 }; 562 563 static const char *find_next_keyword(const char *str, size_t max_len, size_t *kw_len) 564 { 565 const char *best = NULL; 566 size_t best_len = 0; 567 int k; 568 569 for (k = 0; fail_keywords[k]; k++) { 570 const char *s = str; 571 size_t len = strlen(fail_keywords[k]); 572 573 while ((size_t)(s - str) + len <= max_len) { 574 size_t i; 575 576 if (best && s >= best) 577 break; 578 579 for (i = 0; i < len; i++) { 580 if (tolower(s[i]) != fail_keywords[k][i]) 581 break; 582 } 583 if (i == len) { 584 if (!best || s < best) { 585 best = s; 586 best_len = len; 587 } 588 break; 589 } 590 s++; 591 } 592 } 593 if (best) { 594 *kw_len = best_len; 595 return best; 596 } 597 return NULL; 598 } 599 600 static void print_line_highlighted(FILE *fp, const char *line, size_t len) 601 { 602 const char *s = line; 603 604 while (len > 0) { 605 size_t kw_len = 0; 606 const char *match = find_next_keyword(s, len, &kw_len); 607 608 if (!match) { 609 fwrite(s, 1, len, fp); 610 break; 611 } 612 if (match > s) 613 fwrite(s, 1, match - s, fp); 614 if (perf_use_color_default) 615 fprintf(fp, "%s", PERF_COLOR_RED); 616 fwrite(match, 1, kw_len, fp); 617 if (perf_use_color_default) 618 fprintf(fp, "%s", PERF_COLOR_RESET); 619 620 len -= (match + kw_len) - s; 621 s = match + kw_len; 622 } 623 } 624 625 626 static void print_test_failure_snippet(FILE *fp, const char *buf) 627 { 628 size_t num_lines = 0; 629 size_t max_lines = 128; 630 const char **lines = calloc(max_lines, sizeof(const char *)); 631 size_t *line_lens = calloc(max_lines, sizeof(size_t)); 632 const char *s = buf; 633 size_t i; 634 unsigned int picked_count = 0; 635 bool *pick; 636 int last_printed = -1; 637 638 if (!lines || !line_lens) { 639 free(lines); free(line_lens); 640 fprintf(fp, "%s", buf); 641 return; 642 } 643 644 while (*s) { 645 const char *eol = strchr(s, '\n'); 646 size_t len; 647 648 if (eol) 649 len = eol - s + 1; 650 else 651 len = strlen(s); 652 653 if (num_lines == max_lines) { 654 const char **new_lines; 655 size_t *new_lens; 656 657 max_lines *= 2; 658 new_lines = realloc(lines, max_lines * sizeof(const char *)); 659 if (!new_lines) { 660 free(lines); free(line_lens); 661 fprintf(fp, "%s", buf); 662 return; 663 } 664 lines = new_lines; 665 666 new_lens = realloc(line_lens, max_lines * sizeof(size_t)); 667 if (!new_lens) { 668 free(lines); free(line_lens); 669 fprintf(fp, "%s", buf); 670 return; 671 } 672 line_lens = new_lens; 673 } 674 lines[num_lines] = s; 675 line_lens[num_lines] = len; 676 num_lines++; 677 s += len; 678 } 679 680 if (num_lines <= failure_snippet_lines) { 681 for (i = 0; i < num_lines; i++) 682 print_line_highlighted(fp, lines[i], line_lens[i]); 683 free(lines); free(line_lens); 684 return; 685 } 686 687 pick = calloc(num_lines, sizeof(bool)); 688 if (!pick) { 689 for (i = 0; i < num_lines; i++) 690 print_line_highlighted(fp, lines[i], line_lens[i]); 691 free(lines); free(line_lens); 692 return; 693 } 694 695 /* Pass 0: Always pick the very first line */ 696 if (num_lines > 0 && picked_count < failure_snippet_lines) { 697 pick[0] = true; 698 picked_count++; 699 } 700 701 /* Pass 1: Pick lines with failure keywords from start (Highest Priority) */ 702 for (i = 0; i < num_lines && picked_count < failure_snippet_lines; i++) { 703 size_t dummy; 704 705 if (find_next_keyword(lines[i], line_lens[i], &dummy)) { 706 if (!pick[i]) { 707 pick[i] = true; 708 picked_count++; 709 } 710 /* Prioritize getting the immediate next line for context */ 711 if (i + 1 < num_lines && !pick[i + 1] && 712 picked_count < failure_snippet_lines) { 713 pick[i + 1] = true; 714 picked_count++; 715 } 716 } 717 } 718 719 /* Pass 2: Fill remaining quota from the end backwards */ 720 i = num_lines; 721 while (i > 0 && picked_count < failure_snippet_lines) { 722 i--; 723 if (!pick[i]) { 724 pick[i] = true; 725 picked_count++; 726 } 727 } 728 729 for (i = 0; i < num_lines; i++) { 730 if (!pick[i]) 731 continue; 732 if (last_printed != -1 && (int)i > last_printed + 1) { 733 if (perf_use_color_default) 734 fprintf(fp, "%s...%s\n", PERF_COLOR_BLUE, PERF_COLOR_RESET); 735 else 736 fprintf(fp, "...\n"); 737 } 738 print_line_highlighted(fp, lines[i], line_lens[i]); 739 last_printed = i; 740 } 741 742 free(pick); 743 free(lines); 744 free(line_lens); 745 } 746 747 static void finish_test(struct child_test **child_tests, int running_test, int child_test_num, 748 int width) 749 { 750 struct child_test *child_test = child_tests[running_test]; 751 struct test_suite *t; 752 int curr_suite, curr_test_case, err; 753 bool err_done = false; 754 struct strbuf err_output = STRBUF_INIT; 755 int last_running = -1; 756 int ret; 757 struct timespec end_time; 758 double elapsed; 759 width = get_max_desc_width(width); 760 761 if (child_test == NULL) { 762 /* Test wasn't started. */ 763 return; 764 } 765 t = child_test->test; 766 curr_suite = child_test->suite_num; 767 curr_test_case = child_test->test_case_num; 768 err = child_test->process.err; 769 /* 770 * For test suites with subtests, display the suite name ahead of the 771 * sub test names. 772 */ 773 if (test_suite__num_test_cases(t) > 1 && curr_test_case == 0) 774 pr_info("%3d: %-*.*s:\n", curr_suite + 1, width, width, 775 test_description(t, -1)); 776 777 /* 778 * Busy loop reading from the child's stdout/stderr that are set to be 779 * non-blocking until EOF. 780 */ 781 if (err >= 0) 782 fcntl(err, F_SETFL, O_NONBLOCK); 783 if (verbose > 1) { 784 if (test_suite__num_test_cases(t) > 1) 785 pr_info("%3d.%1d: %s:\n", curr_suite + 1, curr_test_case + 1, 786 test_description(t, curr_test_case)); 787 else 788 pr_info("%3d: %s:\n", curr_suite + 1, test_description(t, -1)); 789 } 790 while (!err_done) { 791 struct pollfd pfds[1] = { 792 { .fd = err, 793 .events = POLLIN | POLLERR | POLLHUP | POLLNVAL, 794 }, 795 }; 796 if (perf_use_color_default) { 797 int running = 0; 798 799 for (int y = running_test; y < child_test_num; y++) { 800 if (child_tests[y] == NULL) 801 continue; 802 if (check_if_command_finished(&child_tests[y]->process) == 0) 803 running++; 804 } 805 if (running != last_running) { 806 if (last_running != -1) { 807 /* 808 * Erase "Running (.. active)" line 809 * printed before poll/sleep. 810 */ 811 fprintf(debug_file(), PERF_COLOR_DELETE_LINE); 812 } 813 print_test_result(t, curr_suite, curr_test_case, TEST_RUNNING, 814 width, running, NULL, 0.0); 815 last_running = running; 816 } 817 } 818 819 err_done = true; 820 if (err <= 0) { 821 /* No child stderr to poll, sleep for 10ms for child to complete. */ 822 usleep(10 * 1000); 823 } else { 824 /* Poll to avoid excessive spinning, timeout set for 100ms. */ 825 poll(pfds, ARRAY_SIZE(pfds), /*timeout=*/100); 826 if (pfds[0].revents) { 827 char buf[512]; 828 ssize_t len; 829 830 len = read(err, buf, sizeof(buf) - 1); 831 832 if (len > 0) { 833 err_done = false; 834 buf[len] = '\0'; 835 strbuf_addstr_safe(&err_output, buf); 836 } 837 } 838 } 839 if (err_done) 840 err_done = check_if_command_finished(&child_test->process); 841 } 842 /* Drain any remaining data from the pipe. */ 843 if (err >= 0) { 844 char buf[512]; 845 ssize_t len; 846 847 while ((len = read(err, buf, sizeof(buf) - 1)) > 0) { 848 buf[len] = '\0'; 849 strbuf_addstr_safe(&err_output, buf); 850 } 851 } 852 if (perf_use_color_default && last_running != -1) { 853 /* Erase "Running (.. active)" line printed before poll/sleep. */ 854 fprintf(debug_file(), PERF_COLOR_DELETE_LINE); 855 } 856 /* Clean up child process. */ 857 ret = finish_command(&child_test->process); 858 child_test->process.pid = 0; 859 if (child_test->err_output.len > 0) { 860 struct strbuf merged = STRBUF_INIT; 861 862 if (child_test->err_output.buf) 863 strbuf_addstr_safe(&merged, child_test->err_output.buf); 864 if (err_output.buf) 865 strbuf_addstr_safe(&merged, err_output.buf); 866 strbuf_release(&err_output); 867 err_output = merged; 868 } 869 if (verbose > 1) 870 fprintf(stderr, "%s", err_output.buf); 871 else if (verbose == 1 && ret == TEST_FAIL) 872 print_test_failure_snippet(stderr, err_output.buf); 873 874 clock_gettime(CLOCK_MONOTONIC, &end_time); 875 elapsed = (end_time.tv_sec - child_test->start_time.tv_sec) + 876 (end_time.tv_nsec - child_test->start_time.tv_nsec) / 1000000000.0; 877 878 print_test_result(t, curr_suite, curr_test_case, ret, width, /*running=*/0, 879 err_output.buf, elapsed); 880 strbuf_release(&err_output); 881 strbuf_release(&child_test->err_output); 882 if (err > 0) 883 close(err); 884 zfree(&child_tests[running_test]); 885 } 886 887 static int strbuf_addstr_safe(struct strbuf *sb, const char *s) 888 { 889 sigset_t set, oldset; 890 int ret; 891 892 sigemptyset(&set); 893 sigaddset(&set, SIGINT); 894 sigaddset(&set, SIGTERM); 895 pthread_sigmask(SIG_BLOCK, &set, &oldset); 896 ret = strbuf_addstr(sb, s); 897 pthread_sigmask(SIG_SETMASK, &oldset, NULL); 898 return ret; 899 } 900 901 static int __printf(2, 3) strbuf_addf_safe(struct strbuf *sb, const char *fmt, ...) 902 { 903 char buf[1024]; 904 va_list ap; 905 int len; 906 sigset_t set, oldset; 907 int ret; 908 909 sigemptyset(&set); 910 sigaddset(&set, SIGINT); 911 sigaddset(&set, SIGTERM); 912 sigprocmask(SIG_BLOCK, &set, &oldset); 913 914 va_start(ap, fmt); 915 len = vsnprintf(buf, sizeof(buf), fmt, ap); 916 va_end(ap); 917 918 if (len < 0) { 919 sigprocmask(SIG_SETMASK, &oldset, NULL); 920 return len; 921 } 922 if ((size_t)len >= sizeof(buf)) { 923 char *dynamic_buf = malloc(len + 1); 924 925 if (!dynamic_buf) { 926 sigprocmask(SIG_SETMASK, &oldset, NULL); 927 return -ENOMEM; 928 } 929 va_start(ap, fmt); 930 vsnprintf(dynamic_buf, len + 1, fmt, ap); 931 va_end(ap); 932 ret = strbuf_addstr(sb, dynamic_buf); 933 free(dynamic_buf); 934 } else { 935 ret = strbuf_addstr(sb, buf); 936 } 937 938 sigprocmask(SIG_SETMASK, &oldset, NULL); 939 return ret; 940 } 941 942 static void drain_child_process_err(struct child_test *child) 943 { 944 char buf[512]; 945 ssize_t len; 946 947 while ((len = read(child->process.err, buf, sizeof(buf) - 1)) > 0) { 948 buf[len] = '\0'; 949 strbuf_addstr_safe(&child->err_output, buf); 950 } 951 } 952 953 static void handle_child_pipe_activity(struct child_test *child, short revents) 954 { 955 if (!revents) 956 return; 957 958 drain_child_process_err(child); 959 /* 960 * If the child closed its end of the pipe (EOF) or encountered 961 * an error, close the file descriptor immediately and set it 962 * to -1. This removes it from the pfds array for subsequent 963 * iterations, preventing a tight CPU busy-loop while waiting 964 * for the process itself to exit. 965 */ 966 if (revents & (POLLHUP | POLLERR | POLLNVAL)) { 967 close(child->process.err); 968 child->process.err = -1; 969 } 970 } 971 972 static int finish_tests_parallel(struct child_test **child_tests, size_t num_tests, int width) 973 { 974 size_t next_to_print = 0; 975 struct pollfd *pfds; 976 size_t *pfd_indices; 977 size_t num_pfds = 0; 978 int last_running = -1; 979 size_t i; 980 int last_suite_printed = -1; 981 sigset_t set, oldset; 982 983 width = get_max_desc_width(width); 984 985 sigemptyset(&set); 986 sigaddset(&set, SIGINT); 987 sigaddset(&set, SIGTERM); 988 989 pthread_sigmask(SIG_BLOCK, &set, &oldset); 990 global_pfds = calloc(num_tests, sizeof(*pfds)); 991 global_pfd_indices = calloc(num_tests, sizeof(*pfd_indices)); 992 pfds = global_pfds; 993 pfd_indices = global_pfd_indices; 994 if (!pfds || !pfd_indices) { 995 free(pfds); 996 free(pfd_indices); 997 global_pfds = NULL; 998 global_pfd_indices = NULL; 999 pthread_sigmask(SIG_SETMASK, &oldset, NULL); 1000 return -ENOMEM; 1001 } 1002 pthread_sigmask(SIG_SETMASK, &oldset, NULL); 1003 1004 for (i = 0; i < num_tests; i++) { 1005 struct child_test *child = child_tests[i]; 1006 1007 if (!child) 1008 continue; 1009 strbuf_init(&child->err_output, 0); 1010 if (child->process.err >= 0) 1011 fcntl(child->process.err, F_SETFL, O_NONBLOCK); 1012 } 1013 1014 while (next_to_print < num_tests) { 1015 size_t running_count = 0; 1016 size_t p; 1017 1018 while (next_to_print < num_tests && 1019 (!child_tests[next_to_print] || child_tests[next_to_print]->done)) 1020 next_to_print++; 1021 1022 if (next_to_print >= num_tests) 1023 break; 1024 1025 num_pfds = 0; 1026 1027 for (i = next_to_print; i < num_tests; i++) { 1028 struct child_test *child = child_tests[i]; 1029 1030 if (!child || child->done) 1031 continue; 1032 1033 if (!check_if_command_finished(&child->process)) 1034 running_count++; 1035 1036 if (child->process.err >= 0) { 1037 pfds[num_pfds].fd = child->process.err; 1038 pfds[num_pfds].events = POLLIN | POLLERR | POLLHUP | POLLNVAL; 1039 pfd_indices[num_pfds] = i; 1040 num_pfds++; 1041 } 1042 } 1043 1044 if (perf_use_color_default && running_count != (size_t)last_running) { 1045 struct child_test *next_child = child_tests[next_to_print]; 1046 1047 if (last_running != -1) 1048 fprintf(debug_file(), PERF_COLOR_DELETE_LINE); 1049 1050 if (next_child) { 1051 if (test_suite__num_test_cases(next_child->test) > 1 && 1052 last_suite_printed != next_child->suite_num) { 1053 pr_info("%3d: %-*.*s:\n", 1054 next_child->suite_num + 1, 1055 width, width, 1056 test_description( 1057 next_child->test, -1)); 1058 last_suite_printed = next_child->suite_num; 1059 } 1060 print_test_result(next_child->test, next_child->suite_num, 1061 next_child->test_case_num, TEST_RUNNING, width, 1062 running_count, NULL, 0.0); 1063 } 1064 last_running = running_count; 1065 } 1066 1067 if (num_pfds == 0) { 1068 if (running_count > 0) 1069 usleep(10 * 1000); 1070 } else { 1071 int pret = poll(pfds, num_pfds, 100); 1072 1073 if (pret > 0) { 1074 for (p = 0; p < num_pfds; p++) { 1075 size_t idx = pfd_indices[p]; 1076 1077 handle_child_pipe_activity(child_tests[idx], 1078 pfds[p].revents); 1079 } 1080 } 1081 } 1082 1083 for (i = next_to_print; i < num_tests; i++) { 1084 struct child_test *child = child_tests[i]; 1085 1086 if (!child || child->done) 1087 continue; 1088 1089 if (check_if_command_finished(&child->process)) { 1090 if (child->process.err >= 0) { 1091 drain_child_process_err(child); 1092 close(child->process.err); 1093 child->process.err = -1; 1094 } 1095 child->result = finish_command(&child->process); 1096 child->process.pid = 0; 1097 clock_gettime(CLOCK_MONOTONIC, &child->end_time); 1098 child->done = true; 1099 } 1100 } 1101 1102 while (next_to_print < num_tests) { 1103 struct child_test *child = child_tests[next_to_print]; 1104 double elapsed; 1105 1106 if (!child) { 1107 next_to_print++; 1108 continue; 1109 } 1110 if (!child->done) 1111 break; 1112 1113 if (perf_use_color_default && last_running != -1) { 1114 fprintf(debug_file(), PERF_COLOR_DELETE_LINE); 1115 last_running = -1; 1116 } 1117 1118 if (test_suite__num_test_cases(child->test) > 1 && 1119 last_suite_printed != child->suite_num) { 1120 pr_info("%3d: %-*.*s:\n", child->suite_num + 1, 1121 width, width, 1122 test_description(child->test, -1)); 1123 last_suite_printed = child->suite_num; 1124 } 1125 1126 if (verbose > 1) { 1127 if (test_suite__num_test_cases(child->test) > 1) { 1128 pr_info("%3d.%1d: %s:\n", child->suite_num + 1, 1129 child->test_case_num + 1, 1130 test_description(child->test, 1131 child->test_case_num)); 1132 } else { 1133 pr_info("%3d: %s:\n", child->suite_num + 1, 1134 test_description(child->test, -1)); 1135 } 1136 } 1137 1138 if (verbose > 1) 1139 fprintf(stderr, "%s", child->err_output.buf); 1140 else if (verbose == 1 && child->result == TEST_FAIL) 1141 print_test_failure_snippet(stderr, child->err_output.buf); 1142 1143 elapsed = (child->end_time.tv_sec - child->start_time.tv_sec) + 1144 (child->end_time.tv_nsec - 1145 child->start_time.tv_nsec) / 1000000000.0; 1146 1147 print_test_result(child->test, child->suite_num, child->test_case_num, 1148 child->result, width, 0, child->err_output.buf, elapsed); 1149 pthread_sigmask(SIG_BLOCK, &set, &oldset); 1150 strbuf_release(&child->err_output); 1151 child_tests[next_to_print] = NULL; 1152 zfree(&child); 1153 pthread_sigmask(SIG_SETMASK, &oldset, NULL); 1154 next_to_print++; 1155 } 1156 } 1157 1158 pthread_sigmask(SIG_BLOCK, &set, &oldset); 1159 free(global_pfds); 1160 free(global_pfd_indices); 1161 global_pfds = NULL; 1162 global_pfd_indices = NULL; 1163 pthread_sigmask(SIG_SETMASK, &oldset, NULL); 1164 return 0; 1165 } 1166 1167 static int start_test(struct test_suite *test, int curr_suite, int curr_test_case, 1168 struct child_test **child, int width, int pass) 1169 { 1170 int err; 1171 1172 *child = NULL; 1173 if (dont_fork) { 1174 if (pass == 1) { 1175 struct timespec start_time, end_time; 1176 double elapsed; 1177 1178 clock_gettime(CLOCK_MONOTONIC, &start_time); 1179 pr_debug("--- start ---\n"); 1180 err = test_function(test, curr_test_case)(test, curr_test_case); 1181 pr_debug("---- end ----\n"); 1182 clock_gettime(CLOCK_MONOTONIC, &end_time); 1183 elapsed = (end_time.tv_sec - start_time.tv_sec) + 1184 (end_time.tv_nsec - start_time.tv_nsec) / 1000000000.0; 1185 print_test_result(test, curr_suite, curr_test_case, err, width, 1186 /*running=*/0, NULL, elapsed); 1187 } 1188 return 0; 1189 } 1190 if (pass == 1 && !sequential && test_exclusive(test, curr_test_case)) { 1191 /* When parallel, skip exclusive tests on the first pass. */ 1192 return 0; 1193 } 1194 if (pass != 1 && (sequential || !test_exclusive(test, curr_test_case))) { 1195 /* Sequential and non-exclusive tests were run on the first pass. */ 1196 return 0; 1197 } 1198 *child = zalloc(sizeof(**child)); 1199 if (!*child) 1200 return -ENOMEM; 1201 1202 (*child)->test = test; 1203 (*child)->suite_num = curr_suite; 1204 (*child)->test_case_num = curr_test_case; 1205 (*child)->process.pid = -1; 1206 (*child)->process.no_stdin = 1; 1207 (*child)->process.in = -1; 1208 (*child)->process.out = -1; 1209 (*child)->process.err = -1; 1210 if (verbose <= 0) { 1211 (*child)->process.no_stdout = 1; 1212 (*child)->process.no_stderr = 1; 1213 } else { 1214 (*child)->process.stdout_to_stderr = 1; 1215 } 1216 (*child)->process.no_exec_cmd = run_test_child; 1217 if (sequential || pass == 2) { 1218 err = start_command(&(*child)->process); 1219 if (err) 1220 return err; 1221 finish_test(child, /*running_test=*/0, /*child_test_num=*/1, width); 1222 return 0; 1223 } 1224 return start_command(&(*child)->process); 1225 } 1226 1227 /* State outside of __cmd_test for the sake of the signal handler. */ 1228 1229 static size_t num_tests; 1230 static struct child_test **child_tests; 1231 static jmp_buf cmd_test_jmp_buf; 1232 1233 static void cmd_test_sig_handler(int sig) 1234 { 1235 siglongjmp(cmd_test_jmp_buf, sig); 1236 } 1237 1238 static void print_tests_summary(void) 1239 { 1240 pr_info("\n=== Test Summary ===\n"); 1241 pr_info("Passed main tests : %u\n", summary_tests_passed); 1242 pr_info("Passed subtests : %u\n", summary_subtests_passed); 1243 pr_info("Skipped tests : %u\n", summary_tests_skipped); 1244 if (summary_tests_failed > 0) { 1245 color_fprintf(debug_file(), PERF_COLOR_RED, "Failed tests : %u\n", 1246 summary_tests_failed); 1247 pr_info("List of failed tests:\n"); 1248 pr_info("%s", summary_failed_tests_buf.buf); 1249 } else { 1250 color_fprintf(debug_file(), PERF_COLOR_GREEN, "Failed tests : 0\n"); 1251 } 1252 1253 if (junit_filename) { 1254 int fd; 1255 FILE *fp; 1256 1257 fd = open(junit_filename, O_CREAT | O_TRUNC | O_WRONLY | O_NOFOLLOW, 0644); 1258 if (fd >= 0) { 1259 fp = fdopen(fd, "w"); 1260 if (fp) { 1261 unsigned int total = summary_tests_passed + 1262 summary_subtests_passed + 1263 summary_tests_skipped + 1264 summary_tests_failed; 1265 fprintf(fp, "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n"); 1266 fprintf(fp, "<testsuites>\n"); 1267 fprintf(fp, 1268 " <testsuite name=\"perf-tests\" tests=\"%u\" failures=\"%u\" skipped=\"%u\">\n", 1269 total, summary_tests_failed, 1270 summary_tests_skipped); 1271 fprintf(fp, "%s", junit_xml_buf.buf); 1272 fprintf(fp, " </testsuite>\n"); 1273 fprintf(fp, "</testsuites>\n"); 1274 fclose(fp); 1275 pr_info("Wrote junit XML output to %s\n", junit_filename); 1276 } else { 1277 close(fd); 1278 pr_err("Failed to associate stream with fd for %s: %s\n", 1279 junit_filename, strerror(errno)); 1280 } 1281 } else { 1282 pr_err("Failed to open %s for writing junit XML output: %s\n", 1283 junit_filename, strerror(errno)); 1284 } 1285 } 1286 strbuf_release(&junit_xml_buf); 1287 strbuf_release(&summary_failed_tests_buf); 1288 } 1289 1290 static int __cmd_test(struct test_suite **suites, int argc, const char *argv[], 1291 struct intlist *skiplist) 1292 { 1293 static int width = 0; 1294 int err = 0; 1295 1296 for (struct test_suite **t = suites; *t; t++) { 1297 int i, len = strlen(test_description(*t, -1)); 1298 1299 if (width < len) 1300 width = len; 1301 1302 test_suite__for_each_test_case(*t, i) { 1303 len = strlen(test_description(*t, i)); 1304 if (width < len) 1305 width = len; 1306 num_tests += runs_per_test; 1307 } 1308 } 1309 child_tests = calloc(num_tests, sizeof(*child_tests)); 1310 if (!child_tests) 1311 return -ENOMEM; 1312 1313 err = sigsetjmp(cmd_test_jmp_buf, 1); 1314 if (err) { 1315 pr_err("\nSignal (%d) while running tests.\nTerminating tests with the same signal\n", 1316 err); 1317 for (size_t x = 0; x < num_tests; x++) { 1318 struct child_test *child_test = child_tests[x]; 1319 1320 if (!child_test || child_test->process.pid <= 0) 1321 continue; 1322 1323 pr_debug3("Killing %d pid %d\n", 1324 child_test->suite_num + 1, 1325 child_test->process.pid); 1326 kill(child_test->process.pid, err); 1327 } 1328 goto err_out; 1329 } 1330 signal(SIGINT, cmd_test_sig_handler); 1331 signal(SIGTERM, cmd_test_sig_handler); 1332 1333 /* 1334 * In parallel mode pass 1 runs non-exclusive tests in parallel, pass 2 1335 * runs the exclusive tests sequentially. In other modes all tests are 1336 * run in pass 1. 1337 */ 1338 for (int pass = 1; pass <= 2; pass++) { 1339 int child_test_num = 0; 1340 int curr_suite = 0; 1341 1342 for (struct test_suite **t = suites; *t; t++, curr_suite++) { 1343 int curr_test_case; 1344 bool suite_matched = false; 1345 1346 if (!perf_test__matches(test_description(*t, -1), curr_suite, argc, argv)) { 1347 /* 1348 * Test suite shouldn't be run based on 1349 * description. See if any test case should. 1350 */ 1351 bool skip = true; 1352 1353 test_suite__for_each_test_case(*t, curr_test_case) { 1354 if (perf_test__matches(test_description(*t, curr_test_case), 1355 curr_suite, argc, argv)) { 1356 skip = false; 1357 break; 1358 } 1359 } 1360 if (skip) 1361 continue; 1362 } else { 1363 suite_matched = true; 1364 } 1365 1366 if (intlist__find(skiplist, curr_suite + 1)) { 1367 if (pass == 1) { 1368 int pad_width = get_max_desc_width(width); 1369 int term_width = get_term_width(); 1370 1371 pr_info("%3d: %-*.*s:", curr_suite + 1, 1372 pad_width, term_width, 1373 test_description(*t, -1)); 1374 color_fprintf(debug_file(), PERF_COLOR_YELLOW, 1375 " Skip (user override)\n"); 1376 summary_tests_skipped++; 1377 if (junit_filename) { 1378 char *escaped_class = 1379 xml_escape((const char *) 1380 test_description(*t, -1)); 1381 char *escaped_test = xml_escape("override"); 1382 char *escaped_reason = 1383 xml_escape("user override"); 1384 1385 strbuf_addf(&junit_xml_buf, 1386 " <testcase classname=\"%s\" name=\"%s\" time=\"0.000\">\n", 1387 escaped_class, escaped_test); 1388 strbuf_addf(&junit_xml_buf, 1389 " <skipped message=\"%s\"/>\n", 1390 escaped_reason); 1391 strbuf_addstr(&junit_xml_buf, " </testcase>\n"); 1392 free(escaped_reason); 1393 free(escaped_test); 1394 free(escaped_class); 1395 } 1396 } 1397 continue; 1398 } 1399 1400 for (unsigned int run = 0; run < runs_per_test; run++) { 1401 test_suite__for_each_test_case(*t, curr_test_case) { 1402 if (!suite_matched && 1403 !perf_test__matches(test_description(*t, curr_test_case), 1404 curr_suite, argc, argv)) 1405 continue; 1406 err = start_test(*t, curr_suite, curr_test_case, 1407 &child_tests[child_test_num++], 1408 width, pass); 1409 if (err) 1410 goto err_out; 1411 } 1412 } 1413 } 1414 if (!sequential) { 1415 /* Parallel mode starts tests but doesn't finish them. Do that now. */ 1416 err = finish_tests_parallel(child_tests, num_tests, width); 1417 if (err) 1418 goto err_out; 1419 } 1420 } 1421 err_out: 1422 signal(SIGINT, SIG_DFL); 1423 signal(SIGTERM, SIG_DFL); 1424 if (err) { 1425 pr_err("Internal test harness failure. Completing any started tests:\n:"); 1426 for (size_t x = 0; x < num_tests; x++) 1427 finish_test(child_tests, x, num_tests, width); 1428 } 1429 print_tests_summary(); 1430 free(global_pfds); 1431 free(global_pfd_indices); 1432 global_pfds = NULL; 1433 global_pfd_indices = NULL; 1434 free(child_tests); 1435 return err; 1436 } 1437 1438 static int perf_test__list(FILE *fp, struct test_suite **suites, int argc, const char **argv) 1439 { 1440 int curr_suite = 0; 1441 1442 for (struct test_suite **t = suites; *t; t++, curr_suite++) { 1443 int curr_test_case; 1444 1445 if (!perf_test__matches(test_description(*t, -1), curr_suite, argc, argv)) 1446 continue; 1447 1448 fprintf(fp, "%3d: %s\n", curr_suite + 1, test_description(*t, -1)); 1449 1450 if (test_suite__num_test_cases(*t) <= 1) 1451 continue; 1452 1453 test_suite__for_each_test_case(*t, curr_test_case) { 1454 fprintf(fp, "%3d.%1d: %s\n", curr_suite + 1, curr_test_case + 1, 1455 test_description(*t, curr_test_case)); 1456 } 1457 } 1458 return 0; 1459 } 1460 1461 static int workloads__fprintf_list(FILE *fp) 1462 { 1463 struct test_workload *twl; 1464 int printed = 0; 1465 1466 workloads__for_each(twl) 1467 printed += fprintf(fp, "%s\n", twl->name); 1468 1469 return printed; 1470 } 1471 1472 static int perf_control_open_fifo(struct workload_control *ctl, const char *str) 1473 { 1474 char *s, *p; 1475 int ret; 1476 1477 if (strncmp(str, "fifo:", 5)) 1478 return -EINVAL; 1479 1480 str += 5; 1481 if (!*str || *str == ',') 1482 return -EINVAL; 1483 1484 s = strdup(str); 1485 if (!s) 1486 return -ENOMEM; 1487 1488 p = strchr(s, ','); 1489 if (p) 1490 *p = '\0'; 1491 1492 ctl->ctl_fd = open(s, O_WRONLY | O_CLOEXEC); 1493 if (ctl->ctl_fd < 0) { 1494 ret = -errno; 1495 pr_err("Failed to open workload control FIFO '%s': %m\n", s); 1496 free(s); 1497 return ret; 1498 } 1499 1500 if (p && *++p) { 1501 ctl->ack_fd = open(p, O_RDONLY | O_CLOEXEC); 1502 if (ctl->ack_fd < 0) { 1503 ret = -errno; 1504 pr_err("Failed to open workload control ack FIFO '%s': %m\n", p); 1505 close(ctl->ctl_fd); 1506 ctl->ctl_fd = -1; 1507 free(s); 1508 return ret; 1509 } 1510 } 1511 1512 free(s); 1513 return 0; 1514 } 1515 1516 static int perf_control_open(struct workload_control *ctl) 1517 { 1518 int ret; 1519 1520 if (!workload_control) 1521 return 0; 1522 1523 ret = perf_control_open_fifo(ctl, workload_control); 1524 1525 if (ret == -EINVAL) { 1526 pr_err("Unsupported workload control spec '%s', expected fifo:ctl-fifo[,ack-fifo]\n", 1527 workload_control); 1528 } 1529 1530 return ret; 1531 } 1532 1533 static void perf_control_close(struct workload_control *ctl) 1534 { 1535 if (ctl->ctl_fd >= 0) { 1536 close(ctl->ctl_fd); 1537 ctl->ctl_fd = -1; 1538 } 1539 if (ctl->ack_fd >= 0) { 1540 close(ctl->ack_fd); 1541 ctl->ack_fd = -1; 1542 } 1543 } 1544 1545 static int perf_control_write_cmd(int fd, const char *cmd) 1546 { 1547 size_t len = strlen(cmd); 1548 ssize_t ret; 1549 1550 while (len) { 1551 ret = write(fd, cmd, len); 1552 if (ret < 0) { 1553 if (errno == EINTR) 1554 continue; 1555 pr_err("Failed to write perf control command: %m\n"); 1556 return -1; 1557 } 1558 1559 if (!ret) { 1560 pr_err("Failed to write perf control command: short write\n"); 1561 return -1; 1562 } 1563 1564 cmd += ret; 1565 len -= ret; 1566 } 1567 1568 return 0; 1569 } 1570 1571 static int perf_control_read_ack(int fd) 1572 { 1573 char buf[16]; 1574 ssize_t ret; 1575 1576 do { 1577 ret = read(fd, buf, sizeof(buf) - 1); 1578 } while (ret < 0 && errno == EINTR); 1579 1580 if (ret < 0) { 1581 pr_err("Failed to read perf control ack: %m\n"); 1582 return -1; 1583 } 1584 1585 if (!ret) { 1586 pr_err("Unexpected EOF while reading perf control ack\n"); 1587 return -1; 1588 } 1589 1590 buf[ret] = '\0'; 1591 for (ssize_t i = 0; i < ret; i++) { 1592 if (buf[i] == '\n' || buf[i] == '\0') { 1593 buf[i] = '\0'; 1594 break; 1595 } 1596 } 1597 1598 if (strcmp(buf, "ack")) { 1599 pr_err("Unexpected perf control ack: %s\n", buf); 1600 return -1; 1601 } 1602 1603 return 0; 1604 } 1605 1606 static int perf_control_send(struct workload_control *ctl, const char *cmd) 1607 { 1608 if (ctl->ctl_fd < 0) 1609 return 0; 1610 1611 if (perf_control_write_cmd(ctl->ctl_fd, cmd)) 1612 return -1; 1613 1614 if (ctl->ack_fd >= 0 && perf_control_read_ack(ctl->ack_fd)) 1615 return -1; 1616 1617 return 0; 1618 } 1619 1620 static int run_workload(const char *work, int argc, const char **argv) 1621 { 1622 struct test_workload *twl; 1623 1624 workloads__for_each(twl) { 1625 struct workload_control ctl = { 1626 .ctl_fd = -1, 1627 .ack_fd = -1, 1628 }; 1629 int control_ret, ret; 1630 1631 if (strcmp(twl->name, work)) 1632 continue; 1633 1634 ret = perf_control_open(&ctl); 1635 if (ret) 1636 return ret; 1637 1638 if (perf_control_send(&ctl, "enable\n")) { 1639 perf_control_close(&ctl); 1640 return -1; 1641 } 1642 1643 ret = twl->func(argc, argv); 1644 1645 control_ret = perf_control_send(&ctl, "disable\n"); 1646 perf_control_close(&ctl); 1647 if (control_ret) 1648 return -1; 1649 1650 return ret; 1651 } 1652 1653 pr_info("No workload found: %s\n", work); 1654 return -1; 1655 } 1656 1657 static int perf_test__config(const char *var, const char *value, 1658 void *data __maybe_unused) 1659 { 1660 if (!strcmp(var, "annotate.objdump")) 1661 test_objdump_path = value; 1662 1663 return 0; 1664 } 1665 1666 static struct test_suite **build_suites(void) 1667 { 1668 /* 1669 * TODO: suites is static to avoid needing to clean up the scripts tests 1670 * for leak sanitizer. 1671 */ 1672 static struct test_suite **suites[] = { 1673 generic_tests, 1674 arch_tests, 1675 NULL, 1676 }; 1677 struct test_suite **result; 1678 struct test_suite *t; 1679 size_t n = 0, num_suites = 0; 1680 1681 if (suites[2] == NULL) 1682 suites[2] = create_script_test_suites(); 1683 1684 #define for_each_suite(suite) \ 1685 for (size_t i = 0, j = 0; i < ARRAY_SIZE(suites); i++, j = 0) \ 1686 while ((suite = suites[i][j++]) != NULL) 1687 1688 for_each_suite(t) { 1689 if (t->setup) { 1690 int ret = t->setup(t); 1691 1692 if (ret < 0) { 1693 errno = -ret; 1694 return NULL; 1695 } 1696 } 1697 num_suites++; 1698 } 1699 1700 result = calloc(num_suites + 1, sizeof(struct test_suite *)); 1701 if (!result) 1702 return NULL; 1703 1704 for (int pass = 1; pass <= 2; pass++) { 1705 for_each_suite(t) { 1706 bool exclusive = false; 1707 int curr_test_case; 1708 1709 test_suite__for_each_test_case(t, curr_test_case) { 1710 if (test_exclusive(t, curr_test_case)) { 1711 exclusive = true; 1712 break; 1713 } 1714 } 1715 if ((!exclusive && pass == 1) || (exclusive && pass == 2)) 1716 result[n++] = t; 1717 } 1718 } 1719 return result; 1720 #undef for_each_suite 1721 } 1722 1723 int cmd_test(int argc, const char **argv) 1724 { 1725 const char *test_usage[] = { 1726 "perf test [<options>] [{list <test-name-fragment>|[<test-name-fragments>|<test-numbers>]}]", 1727 NULL, 1728 }; 1729 const char *skip = NULL; 1730 const char *workload = NULL; 1731 bool list_workloads = false; 1732 const struct option test_options[] = { 1733 OPT_STRING('s', "skip", &skip, "tests", "tests to skip"), 1734 OPT_INCR('v', "verbose", &verbose, 1735 "be more verbose (show symbol address, etc)"), 1736 OPT_BOOLEAN('F', "dont-fork", &dont_fork, 1737 "Do not fork for testcase"), 1738 OPT_BOOLEAN('S', "sequential", &sequential, 1739 "Run the tests one after another rather than in parallel"), 1740 OPT_UINTEGER('r', "runs-per-test", &runs_per_test, 1741 "Run each test the given number of times, default 1"), 1742 OPT_STRING('w', "workload", &workload, "work", "workload to run for testing, use '--list-workloads' to list the available ones."), 1743 OPT_STRING(0, "record-ctl", &workload_control, "fifo:ctl-fifo[,ack-fifo]", 1744 "Write enable to the fifo just before running the workload and disable after, with optional ack from ack-fifo"), 1745 OPT_BOOLEAN(0, "list-workloads", &list_workloads, "List the available builtin workloads to use with -w/--workload"), 1746 OPT_STRING(0, "dso", &dso_to_test, "dso", "dso to test"), 1747 OPT_STRING(0, "objdump", &test_objdump_path, "path", 1748 "objdump binary to use for disassembly and annotations"), 1749 OPT_UINTEGER(0, "failure-snippet-lines", &failure_snippet_lines, 1750 "Number of lines to include in failure snippet, default 10"), 1751 OPT_STRING_OPTARG('j', "junit", &junit_filename, "file", 1752 "Generate junit XML output, default test.xml", "test.xml"), 1753 OPT_END() 1754 }; 1755 const char * const test_subcommands[] = { "list", NULL }; 1756 struct intlist *skiplist = NULL; 1757 int ret = hists__init(); 1758 struct test_suite **suites; 1759 1760 if (ret < 0) 1761 return ret; 1762 1763 perf_config(perf_test__config, NULL); 1764 1765 /* Unbuffered output */ 1766 setvbuf(stdout, NULL, _IONBF, 0); 1767 1768 argc = parse_options_subcommand(argc, argv, test_options, test_subcommands, test_usage, 0); 1769 if (argc >= 1 && !strcmp(argv[0], "list")) { 1770 suites = build_suites(); 1771 if (!suites) 1772 return errno ? -errno : -ENOMEM; 1773 ret = perf_test__list(stdout, suites, argc - 1, argv + 1); 1774 free(suites); 1775 return ret; 1776 } 1777 1778 if (workload) 1779 return run_workload(workload, argc, argv); 1780 1781 if (list_workloads) { 1782 workloads__fprintf_list(stdout); 1783 return 0; 1784 } 1785 1786 if (dont_fork) 1787 sequential = true; 1788 1789 symbol_conf.priv_size = sizeof(int); 1790 symbol_conf.try_vmlinux_path = true; 1791 1792 1793 if (symbol__init(NULL) < 0) 1794 return -1; 1795 1796 if (skip != NULL) 1797 skiplist = intlist__new(skip); 1798 /* 1799 * Tests that create BPF maps, for instance, need more than the 64K 1800 * default: 1801 */ 1802 rlimit__bump_memlock(); 1803 1804 suites = build_suites(); 1805 if (!suites) { 1806 int err = errno; 1807 1808 intlist__delete(skiplist); 1809 return err ? -err : -ENOMEM; 1810 } 1811 ret = __cmd_test(suites, argc, argv, skiplist); 1812 free(suites); 1813 intlist__delete(skiplist); 1814 return ret; 1815 } 1816