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