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