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