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