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