1 // SPDX-License-Identifier: GPL-2.0-only 2 /* Copyright (c) 2017 Facebook 3 */ 4 #define _GNU_SOURCE 5 #include "test_progs.h" 6 #include "cgroup_helpers.h" 7 #include <argp.h> 8 #include <pthread.h> 9 #include <sched.h> 10 #include <signal.h> 11 #include <string.h> 12 #include <execinfo.h> /* backtrace */ 13 #include <linux/membarrier.h> 14 #include <sys/sysinfo.h> /* get_nprocs */ 15 #include <netinet/in.h> 16 #include <sys/select.h> 17 #include <sys/socket.h> 18 #include <sys/un.h> 19 20 /* Adapted from perf/util/string.c */ 21 static bool glob_match(const char *str, const char *pat) 22 { 23 while (*str && *pat && *pat != '*') { 24 if (*str != *pat) 25 return false; 26 str++; 27 pat++; 28 } 29 /* Check wild card */ 30 if (*pat == '*') { 31 while (*pat == '*') 32 pat++; 33 if (!*pat) /* Tail wild card matches all */ 34 return true; 35 while (*str) 36 if (glob_match(str++, pat)) 37 return true; 38 } 39 return !*str && !*pat; 40 } 41 42 #define EXIT_NO_TEST 2 43 #define EXIT_ERR_SETUP_INFRA 3 44 45 /* defined in test_progs.h */ 46 struct test_env env = {}; 47 48 struct prog_test_def { 49 const char *test_name; 50 int test_num; 51 void (*run_test)(void); 52 void (*run_serial_test)(void); 53 bool force_log; 54 int error_cnt; 55 int skip_cnt; 56 int sub_succ_cnt; 57 bool should_run; 58 bool tested; 59 bool need_cgroup_cleanup; 60 61 char *subtest_name; 62 int subtest_num; 63 64 /* store counts before subtest started */ 65 int old_error_cnt; 66 }; 67 68 /* Override C runtime library's usleep() implementation to ensure nanosleep() 69 * is always called. Usleep is frequently used in selftests as a way to 70 * trigger kprobe and tracepoints. 71 */ 72 int usleep(useconds_t usec) 73 { 74 struct timespec ts = { 75 .tv_sec = usec / 1000000, 76 .tv_nsec = (usec % 1000000) * 1000, 77 }; 78 79 return syscall(__NR_nanosleep, &ts, NULL); 80 } 81 82 static bool should_run(struct test_selector *sel, int num, const char *name) 83 { 84 int i; 85 86 for (i = 0; i < sel->blacklist.cnt; i++) { 87 if (glob_match(name, sel->blacklist.strs[i])) 88 return false; 89 } 90 91 for (i = 0; i < sel->whitelist.cnt; i++) { 92 if (glob_match(name, sel->whitelist.strs[i])) 93 return true; 94 } 95 96 if (!sel->whitelist.cnt && !sel->num_set) 97 return true; 98 99 return num < sel->num_set_len && sel->num_set[num]; 100 } 101 102 static void dump_test_log(const struct prog_test_def *test, bool failed) 103 { 104 if (stdout == env.stdout) 105 return; 106 107 /* worker always holds log */ 108 if (env.worker_id != -1) 109 return; 110 111 fflush(stdout); /* exports env.log_buf & env.log_cnt */ 112 113 if (env.verbosity > VERBOSE_NONE || test->force_log || failed) { 114 if (env.log_cnt) { 115 env.log_buf[env.log_cnt] = '\0'; 116 fprintf(env.stdout, "%s", env.log_buf); 117 if (env.log_buf[env.log_cnt - 1] != '\n') 118 fprintf(env.stdout, "\n"); 119 } 120 } 121 } 122 123 static void skip_account(void) 124 { 125 if (env.test->skip_cnt) { 126 env.skip_cnt++; 127 env.test->skip_cnt = 0; 128 } 129 } 130 131 static void stdio_restore(void); 132 133 /* A bunch of tests set custom affinity per-thread and/or per-process. Reset 134 * it after each test/sub-test. 135 */ 136 static void reset_affinity(void) 137 { 138 139 cpu_set_t cpuset; 140 int i, err; 141 142 CPU_ZERO(&cpuset); 143 for (i = 0; i < env.nr_cpus; i++) 144 CPU_SET(i, &cpuset); 145 146 err = sched_setaffinity(0, sizeof(cpuset), &cpuset); 147 if (err < 0) { 148 stdio_restore(); 149 fprintf(stderr, "Failed to reset process affinity: %d!\n", err); 150 exit(EXIT_ERR_SETUP_INFRA); 151 } 152 err = pthread_setaffinity_np(pthread_self(), sizeof(cpuset), &cpuset); 153 if (err < 0) { 154 stdio_restore(); 155 fprintf(stderr, "Failed to reset thread affinity: %d!\n", err); 156 exit(EXIT_ERR_SETUP_INFRA); 157 } 158 } 159 160 static void save_netns(void) 161 { 162 env.saved_netns_fd = open("/proc/self/ns/net", O_RDONLY); 163 if (env.saved_netns_fd == -1) { 164 perror("open(/proc/self/ns/net)"); 165 exit(EXIT_ERR_SETUP_INFRA); 166 } 167 } 168 169 static void restore_netns(void) 170 { 171 if (setns(env.saved_netns_fd, CLONE_NEWNET) == -1) { 172 stdio_restore(); 173 perror("setns(CLONE_NEWNS)"); 174 exit(EXIT_ERR_SETUP_INFRA); 175 } 176 } 177 178 void test__end_subtest(void) 179 { 180 struct prog_test_def *test = env.test; 181 int sub_error_cnt = test->error_cnt - test->old_error_cnt; 182 183 dump_test_log(test, sub_error_cnt); 184 185 fprintf(stdout, "#%d/%d %s/%s:%s\n", 186 test->test_num, test->subtest_num, test->test_name, test->subtest_name, 187 sub_error_cnt ? "FAIL" : (test->skip_cnt ? "SKIP" : "OK")); 188 189 if (sub_error_cnt) 190 test->error_cnt++; 191 else if (test->skip_cnt == 0) 192 test->sub_succ_cnt++; 193 skip_account(); 194 195 free(test->subtest_name); 196 test->subtest_name = NULL; 197 } 198 199 bool test__start_subtest(const char *name) 200 { 201 struct prog_test_def *test = env.test; 202 203 if (test->subtest_name) 204 test__end_subtest(); 205 206 test->subtest_num++; 207 208 if (!name || !name[0]) { 209 fprintf(env.stderr, 210 "Subtest #%d didn't provide sub-test name!\n", 211 test->subtest_num); 212 return false; 213 } 214 215 if (!should_run(&env.subtest_selector, test->subtest_num, name)) 216 return false; 217 218 test->subtest_name = strdup(name); 219 if (!test->subtest_name) { 220 fprintf(env.stderr, 221 "Subtest #%d: failed to copy subtest name!\n", 222 test->subtest_num); 223 return false; 224 } 225 env.test->old_error_cnt = env.test->error_cnt; 226 227 return true; 228 } 229 230 void test__force_log(void) 231 { 232 env.test->force_log = true; 233 } 234 235 void test__skip(void) 236 { 237 env.test->skip_cnt++; 238 } 239 240 void test__fail(void) 241 { 242 env.test->error_cnt++; 243 } 244 245 int test__join_cgroup(const char *path) 246 { 247 int fd; 248 249 if (!env.test->need_cgroup_cleanup) { 250 if (setup_cgroup_environment()) { 251 fprintf(stderr, 252 "#%d %s: Failed to setup cgroup environment\n", 253 env.test->test_num, env.test->test_name); 254 return -1; 255 } 256 257 env.test->need_cgroup_cleanup = true; 258 } 259 260 fd = create_and_get_cgroup(path); 261 if (fd < 0) { 262 fprintf(stderr, 263 "#%d %s: Failed to create cgroup '%s' (errno=%d)\n", 264 env.test->test_num, env.test->test_name, path, errno); 265 return fd; 266 } 267 268 if (join_cgroup(path)) { 269 fprintf(stderr, 270 "#%d %s: Failed to join cgroup '%s' (errno=%d)\n", 271 env.test->test_num, env.test->test_name, path, errno); 272 return -1; 273 } 274 275 return fd; 276 } 277 278 int bpf_find_map(const char *test, struct bpf_object *obj, const char *name) 279 { 280 struct bpf_map *map; 281 282 map = bpf_object__find_map_by_name(obj, name); 283 if (!map) { 284 fprintf(stdout, "%s:FAIL:map '%s' not found\n", test, name); 285 test__fail(); 286 return -1; 287 } 288 return bpf_map__fd(map); 289 } 290 291 static bool is_jit_enabled(void) 292 { 293 const char *jit_sysctl = "/proc/sys/net/core/bpf_jit_enable"; 294 bool enabled = false; 295 int sysctl_fd; 296 297 sysctl_fd = open(jit_sysctl, 0, O_RDONLY); 298 if (sysctl_fd != -1) { 299 char tmpc; 300 301 if (read(sysctl_fd, &tmpc, sizeof(tmpc)) == 1) 302 enabled = (tmpc != '0'); 303 close(sysctl_fd); 304 } 305 306 return enabled; 307 } 308 309 int compare_map_keys(int map1_fd, int map2_fd) 310 { 311 __u32 key, next_key; 312 char val_buf[PERF_MAX_STACK_DEPTH * 313 sizeof(struct bpf_stack_build_id)]; 314 int err; 315 316 err = bpf_map_get_next_key(map1_fd, NULL, &key); 317 if (err) 318 return err; 319 err = bpf_map_lookup_elem(map2_fd, &key, val_buf); 320 if (err) 321 return err; 322 323 while (bpf_map_get_next_key(map1_fd, &key, &next_key) == 0) { 324 err = bpf_map_lookup_elem(map2_fd, &next_key, val_buf); 325 if (err) 326 return err; 327 328 key = next_key; 329 } 330 if (errno != ENOENT) 331 return -1; 332 333 return 0; 334 } 335 336 int compare_stack_ips(int smap_fd, int amap_fd, int stack_trace_len) 337 { 338 __u32 key, next_key, *cur_key_p, *next_key_p; 339 char *val_buf1, *val_buf2; 340 int i, err = 0; 341 342 val_buf1 = malloc(stack_trace_len); 343 val_buf2 = malloc(stack_trace_len); 344 cur_key_p = NULL; 345 next_key_p = &key; 346 while (bpf_map_get_next_key(smap_fd, cur_key_p, next_key_p) == 0) { 347 err = bpf_map_lookup_elem(smap_fd, next_key_p, val_buf1); 348 if (err) 349 goto out; 350 err = bpf_map_lookup_elem(amap_fd, next_key_p, val_buf2); 351 if (err) 352 goto out; 353 for (i = 0; i < stack_trace_len; i++) { 354 if (val_buf1[i] != val_buf2[i]) { 355 err = -1; 356 goto out; 357 } 358 } 359 key = *next_key_p; 360 cur_key_p = &key; 361 next_key_p = &next_key; 362 } 363 if (errno != ENOENT) 364 err = -1; 365 366 out: 367 free(val_buf1); 368 free(val_buf2); 369 return err; 370 } 371 372 int extract_build_id(char *build_id, size_t size) 373 { 374 FILE *fp; 375 char *line = NULL; 376 size_t len = 0; 377 378 fp = popen("readelf -n ./urandom_read | grep 'Build ID'", "r"); 379 if (fp == NULL) 380 return -1; 381 382 if (getline(&line, &len, fp) == -1) 383 goto err; 384 pclose(fp); 385 386 if (len > size) 387 len = size; 388 memcpy(build_id, line, len); 389 build_id[len] = '\0'; 390 free(line); 391 return 0; 392 err: 393 pclose(fp); 394 return -1; 395 } 396 397 static int finit_module(int fd, const char *param_values, int flags) 398 { 399 return syscall(__NR_finit_module, fd, param_values, flags); 400 } 401 402 static int delete_module(const char *name, int flags) 403 { 404 return syscall(__NR_delete_module, name, flags); 405 } 406 407 /* 408 * Trigger synchronize_rcu() in kernel. 409 */ 410 int kern_sync_rcu(void) 411 { 412 return syscall(__NR_membarrier, MEMBARRIER_CMD_SHARED, 0, 0); 413 } 414 415 static void unload_bpf_testmod(void) 416 { 417 if (kern_sync_rcu()) 418 fprintf(env.stderr, "Failed to trigger kernel-side RCU sync!\n"); 419 if (delete_module("bpf_testmod", 0)) { 420 if (errno == ENOENT) { 421 if (env.verbosity > VERBOSE_NONE) 422 fprintf(stdout, "bpf_testmod.ko is already unloaded.\n"); 423 return; 424 } 425 fprintf(env.stderr, "Failed to unload bpf_testmod.ko from kernel: %d\n", -errno); 426 return; 427 } 428 if (env.verbosity > VERBOSE_NONE) 429 fprintf(stdout, "Successfully unloaded bpf_testmod.ko.\n"); 430 } 431 432 static int load_bpf_testmod(void) 433 { 434 int fd; 435 436 /* ensure previous instance of the module is unloaded */ 437 unload_bpf_testmod(); 438 439 if (env.verbosity > VERBOSE_NONE) 440 fprintf(stdout, "Loading bpf_testmod.ko...\n"); 441 442 fd = open("bpf_testmod.ko", O_RDONLY); 443 if (fd < 0) { 444 fprintf(env.stderr, "Can't find bpf_testmod.ko kernel module: %d\n", -errno); 445 return -ENOENT; 446 } 447 if (finit_module(fd, "", 0)) { 448 fprintf(env.stderr, "Failed to load bpf_testmod.ko into the kernel: %d\n", -errno); 449 close(fd); 450 return -EINVAL; 451 } 452 close(fd); 453 454 if (env.verbosity > VERBOSE_NONE) 455 fprintf(stdout, "Successfully loaded bpf_testmod.ko.\n"); 456 return 0; 457 } 458 459 /* extern declarations for test funcs */ 460 #define DEFINE_TEST(name) \ 461 extern void test_##name(void) __weak; \ 462 extern void serial_test_##name(void) __weak; 463 #include <prog_tests/tests.h> 464 #undef DEFINE_TEST 465 466 static struct prog_test_def prog_test_defs[] = { 467 #define DEFINE_TEST(name) { \ 468 .test_name = #name, \ 469 .run_test = &test_##name, \ 470 .run_serial_test = &serial_test_##name, \ 471 }, 472 #include <prog_tests/tests.h> 473 #undef DEFINE_TEST 474 }; 475 static const int prog_test_cnt = ARRAY_SIZE(prog_test_defs); 476 477 const char *argp_program_version = "test_progs 0.1"; 478 const char *argp_program_bug_address = "<bpf@vger.kernel.org>"; 479 static const char argp_program_doc[] = "BPF selftests test runner"; 480 481 enum ARG_KEYS { 482 ARG_TEST_NUM = 'n', 483 ARG_TEST_NAME = 't', 484 ARG_TEST_NAME_BLACKLIST = 'b', 485 ARG_VERIFIER_STATS = 's', 486 ARG_VERBOSE = 'v', 487 ARG_GET_TEST_CNT = 'c', 488 ARG_LIST_TEST_NAMES = 'l', 489 ARG_TEST_NAME_GLOB_ALLOWLIST = 'a', 490 ARG_TEST_NAME_GLOB_DENYLIST = 'd', 491 ARG_NUM_WORKERS = 'j', 492 ARG_DEBUG = -1, 493 }; 494 495 static const struct argp_option opts[] = { 496 { "num", ARG_TEST_NUM, "NUM", 0, 497 "Run test number NUM only " }, 498 { "name", ARG_TEST_NAME, "NAMES", 0, 499 "Run tests with names containing any string from NAMES list" }, 500 { "name-blacklist", ARG_TEST_NAME_BLACKLIST, "NAMES", 0, 501 "Don't run tests with names containing any string from NAMES list" }, 502 { "verifier-stats", ARG_VERIFIER_STATS, NULL, 0, 503 "Output verifier statistics", }, 504 { "verbose", ARG_VERBOSE, "LEVEL", OPTION_ARG_OPTIONAL, 505 "Verbose output (use -vv or -vvv for progressively verbose output)" }, 506 { "count", ARG_GET_TEST_CNT, NULL, 0, 507 "Get number of selected top-level tests " }, 508 { "list", ARG_LIST_TEST_NAMES, NULL, 0, 509 "List test names that would run (without running them) " }, 510 { "allow", ARG_TEST_NAME_GLOB_ALLOWLIST, "NAMES", 0, 511 "Run tests with name matching the pattern (supports '*' wildcard)." }, 512 { "deny", ARG_TEST_NAME_GLOB_DENYLIST, "NAMES", 0, 513 "Don't run tests with name matching the pattern (supports '*' wildcard)." }, 514 { "workers", ARG_NUM_WORKERS, "WORKERS", OPTION_ARG_OPTIONAL, 515 "Number of workers to run in parallel, default to number of cpus." }, 516 { "debug", ARG_DEBUG, NULL, 0, 517 "print extra debug information for test_progs." }, 518 {}, 519 }; 520 521 static int libbpf_print_fn(enum libbpf_print_level level, 522 const char *format, va_list args) 523 { 524 if (env.verbosity < VERBOSE_VERY && level == LIBBPF_DEBUG) 525 return 0; 526 vfprintf(stdout, format, args); 527 return 0; 528 } 529 530 static void free_str_set(const struct str_set *set) 531 { 532 int i; 533 534 if (!set) 535 return; 536 537 for (i = 0; i < set->cnt; i++) 538 free((void *)set->strs[i]); 539 free(set->strs); 540 } 541 542 static int parse_str_list(const char *s, struct str_set *set, bool is_glob_pattern) 543 { 544 char *input, *state = NULL, *next, **tmp, **strs = NULL; 545 int i, cnt = 0; 546 547 input = strdup(s); 548 if (!input) 549 return -ENOMEM; 550 551 while ((next = strtok_r(state ? NULL : input, ",", &state))) { 552 tmp = realloc(strs, sizeof(*strs) * (cnt + 1)); 553 if (!tmp) 554 goto err; 555 strs = tmp; 556 557 if (is_glob_pattern) { 558 strs[cnt] = strdup(next); 559 if (!strs[cnt]) 560 goto err; 561 } else { 562 strs[cnt] = malloc(strlen(next) + 2 + 1); 563 if (!strs[cnt]) 564 goto err; 565 sprintf(strs[cnt], "*%s*", next); 566 } 567 568 cnt++; 569 } 570 571 tmp = realloc(set->strs, sizeof(*strs) * (cnt + set->cnt)); 572 if (!tmp) 573 goto err; 574 memcpy(tmp + set->cnt, strs, sizeof(*strs) * cnt); 575 set->strs = (const char **)tmp; 576 set->cnt += cnt; 577 578 free(input); 579 free(strs); 580 return 0; 581 err: 582 for (i = 0; i < cnt; i++) 583 free(strs[i]); 584 free(strs); 585 free(input); 586 return -ENOMEM; 587 } 588 589 extern int extra_prog_load_log_flags; 590 591 static error_t parse_arg(int key, char *arg, struct argp_state *state) 592 { 593 struct test_env *env = state->input; 594 595 switch (key) { 596 case ARG_TEST_NUM: { 597 char *subtest_str = strchr(arg, '/'); 598 599 if (subtest_str) { 600 *subtest_str = '\0'; 601 if (parse_num_list(subtest_str + 1, 602 &env->subtest_selector.num_set, 603 &env->subtest_selector.num_set_len)) { 604 fprintf(stderr, 605 "Failed to parse subtest numbers.\n"); 606 return -EINVAL; 607 } 608 } 609 if (parse_num_list(arg, &env->test_selector.num_set, 610 &env->test_selector.num_set_len)) { 611 fprintf(stderr, "Failed to parse test numbers.\n"); 612 return -EINVAL; 613 } 614 break; 615 } 616 case ARG_TEST_NAME_GLOB_ALLOWLIST: 617 case ARG_TEST_NAME: { 618 char *subtest_str = strchr(arg, '/'); 619 620 if (subtest_str) { 621 *subtest_str = '\0'; 622 if (parse_str_list(subtest_str + 1, 623 &env->subtest_selector.whitelist, 624 key == ARG_TEST_NAME_GLOB_ALLOWLIST)) 625 return -ENOMEM; 626 } 627 if (parse_str_list(arg, &env->test_selector.whitelist, 628 key == ARG_TEST_NAME_GLOB_ALLOWLIST)) 629 return -ENOMEM; 630 break; 631 } 632 case ARG_TEST_NAME_GLOB_DENYLIST: 633 case ARG_TEST_NAME_BLACKLIST: { 634 char *subtest_str = strchr(arg, '/'); 635 636 if (subtest_str) { 637 *subtest_str = '\0'; 638 if (parse_str_list(subtest_str + 1, 639 &env->subtest_selector.blacklist, 640 key == ARG_TEST_NAME_GLOB_DENYLIST)) 641 return -ENOMEM; 642 } 643 if (parse_str_list(arg, &env->test_selector.blacklist, 644 key == ARG_TEST_NAME_GLOB_DENYLIST)) 645 return -ENOMEM; 646 break; 647 } 648 case ARG_VERIFIER_STATS: 649 env->verifier_stats = true; 650 break; 651 case ARG_VERBOSE: 652 env->verbosity = VERBOSE_NORMAL; 653 if (arg) { 654 if (strcmp(arg, "v") == 0) { 655 env->verbosity = VERBOSE_VERY; 656 extra_prog_load_log_flags = 1; 657 } else if (strcmp(arg, "vv") == 0) { 658 env->verbosity = VERBOSE_SUPER; 659 extra_prog_load_log_flags = 2; 660 } else { 661 fprintf(stderr, 662 "Unrecognized verbosity setting ('%s'), only -v and -vv are supported\n", 663 arg); 664 return -EINVAL; 665 } 666 } 667 668 if (env->verbosity > VERBOSE_NONE) { 669 if (setenv("SELFTESTS_VERBOSE", "1", 1) == -1) { 670 fprintf(stderr, 671 "Unable to setenv SELFTESTS_VERBOSE=1 (errno=%d)", 672 errno); 673 return -EINVAL; 674 } 675 } 676 677 break; 678 case ARG_GET_TEST_CNT: 679 env->get_test_cnt = true; 680 break; 681 case ARG_LIST_TEST_NAMES: 682 env->list_test_names = true; 683 break; 684 case ARG_NUM_WORKERS: 685 if (arg) { 686 env->workers = atoi(arg); 687 if (!env->workers) { 688 fprintf(stderr, "Invalid number of worker: %s.", arg); 689 return -EINVAL; 690 } 691 } else { 692 env->workers = get_nprocs(); 693 } 694 break; 695 case ARG_DEBUG: 696 env->debug = true; 697 break; 698 case ARGP_KEY_ARG: 699 argp_usage(state); 700 break; 701 case ARGP_KEY_END: 702 break; 703 default: 704 return ARGP_ERR_UNKNOWN; 705 } 706 return 0; 707 } 708 709 static void stdio_hijack(void) 710 { 711 #ifdef __GLIBC__ 712 env.stdout = stdout; 713 env.stderr = stderr; 714 715 if (env.verbosity > VERBOSE_NONE && env.worker_id == -1) { 716 /* nothing to do, output to stdout by default */ 717 return; 718 } 719 720 /* stdout and stderr -> buffer */ 721 fflush(stdout); 722 723 stdout = open_memstream(&env.log_buf, &env.log_cnt); 724 if (!stdout) { 725 stdout = env.stdout; 726 perror("open_memstream"); 727 return; 728 } 729 730 stderr = stdout; 731 #endif 732 } 733 734 static void stdio_restore(void) 735 { 736 #ifdef __GLIBC__ 737 if (stdout == env.stdout) 738 return; 739 740 fclose(stdout); 741 742 stdout = env.stdout; 743 stderr = env.stderr; 744 #endif 745 } 746 747 /* 748 * Determine if test_progs is running as a "flavored" test runner and switch 749 * into corresponding sub-directory to load correct BPF objects. 750 * 751 * This is done by looking at executable name. If it contains "-flavor" 752 * suffix, then we are running as a flavored test runner. 753 */ 754 int cd_flavor_subdir(const char *exec_name) 755 { 756 /* General form of argv[0] passed here is: 757 * some/path/to/test_progs[-flavor], where -flavor part is optional. 758 * First cut out "test_progs[-flavor]" part, then extract "flavor" 759 * part, if it's there. 760 */ 761 const char *flavor = strrchr(exec_name, '/'); 762 763 if (!flavor) 764 flavor = exec_name; 765 else 766 flavor++; 767 768 flavor = strrchr(flavor, '-'); 769 if (!flavor) 770 return 0; 771 flavor++; 772 if (env.verbosity > VERBOSE_NONE) 773 fprintf(stdout, "Switching to flavor '%s' subdirectory...\n", flavor); 774 775 return chdir(flavor); 776 } 777 778 int trigger_module_test_read(int read_sz) 779 { 780 int fd, err; 781 782 fd = open(BPF_TESTMOD_TEST_FILE, O_RDONLY); 783 err = -errno; 784 if (!ASSERT_GE(fd, 0, "testmod_file_open")) 785 return err; 786 787 read(fd, NULL, read_sz); 788 close(fd); 789 790 return 0; 791 } 792 793 int trigger_module_test_write(int write_sz) 794 { 795 int fd, err; 796 char *buf = malloc(write_sz); 797 798 if (!buf) 799 return -ENOMEM; 800 801 memset(buf, 'a', write_sz); 802 buf[write_sz-1] = '\0'; 803 804 fd = open(BPF_TESTMOD_TEST_FILE, O_WRONLY); 805 err = -errno; 806 if (!ASSERT_GE(fd, 0, "testmod_file_open")) { 807 free(buf); 808 return err; 809 } 810 811 write(fd, buf, write_sz); 812 close(fd); 813 free(buf); 814 return 0; 815 } 816 817 #define MAX_BACKTRACE_SZ 128 818 void crash_handler(int signum) 819 { 820 void *bt[MAX_BACKTRACE_SZ]; 821 size_t sz; 822 823 sz = backtrace(bt, ARRAY_SIZE(bt)); 824 825 if (env.test) 826 dump_test_log(env.test, true); 827 if (env.stdout) 828 stdio_restore(); 829 if (env.worker_id != -1) 830 fprintf(stderr, "[%d]: ", env.worker_id); 831 fprintf(stderr, "Caught signal #%d!\nStack trace:\n", signum); 832 backtrace_symbols_fd(bt, sz, STDERR_FILENO); 833 } 834 835 static void sigint_handler(int signum) 836 { 837 int i; 838 839 for (i = 0; i < env.workers; i++) 840 if (env.worker_socks[i] > 0) 841 close(env.worker_socks[i]); 842 } 843 844 static int current_test_idx; 845 static pthread_mutex_t current_test_lock; 846 static pthread_mutex_t stdout_output_lock; 847 848 struct test_result { 849 int error_cnt; 850 int skip_cnt; 851 int sub_succ_cnt; 852 853 size_t log_cnt; 854 char *log_buf; 855 }; 856 857 static struct test_result test_results[ARRAY_SIZE(prog_test_defs)]; 858 859 static inline const char *str_msg(const struct msg *msg, char *buf) 860 { 861 switch (msg->type) { 862 case MSG_DO_TEST: 863 sprintf(buf, "MSG_DO_TEST %d", msg->do_test.test_num); 864 break; 865 case MSG_TEST_DONE: 866 sprintf(buf, "MSG_TEST_DONE %d (log: %d)", 867 msg->test_done.test_num, 868 msg->test_done.have_log); 869 break; 870 case MSG_TEST_LOG: 871 sprintf(buf, "MSG_TEST_LOG (cnt: %ld, last: %d)", 872 strlen(msg->test_log.log_buf), 873 msg->test_log.is_last); 874 break; 875 case MSG_EXIT: 876 sprintf(buf, "MSG_EXIT"); 877 break; 878 default: 879 sprintf(buf, "UNKNOWN"); 880 break; 881 } 882 883 return buf; 884 } 885 886 static int send_message(int sock, const struct msg *msg) 887 { 888 char buf[256]; 889 890 if (env.debug) 891 fprintf(stderr, "Sending msg: %s\n", str_msg(msg, buf)); 892 return send(sock, msg, sizeof(*msg), 0); 893 } 894 895 static int recv_message(int sock, struct msg *msg) 896 { 897 int ret; 898 char buf[256]; 899 900 memset(msg, 0, sizeof(*msg)); 901 ret = recv(sock, msg, sizeof(*msg), 0); 902 if (ret >= 0) { 903 if (env.debug) 904 fprintf(stderr, "Received msg: %s\n", str_msg(msg, buf)); 905 } 906 return ret; 907 } 908 909 static void run_one_test(int test_num) 910 { 911 struct prog_test_def *test = &prog_test_defs[test_num]; 912 913 env.test = test; 914 915 if (test->run_test) 916 test->run_test(); 917 else if (test->run_serial_test) 918 test->run_serial_test(); 919 920 /* ensure last sub-test is finalized properly */ 921 if (test->subtest_name) 922 test__end_subtest(); 923 924 test->tested = true; 925 926 dump_test_log(test, test->error_cnt); 927 928 reset_affinity(); 929 restore_netns(); 930 if (test->need_cgroup_cleanup) 931 cleanup_cgroup_environment(); 932 } 933 934 struct dispatch_data { 935 int worker_id; 936 int sock_fd; 937 }; 938 939 static void *dispatch_thread(void *ctx) 940 { 941 struct dispatch_data *data = ctx; 942 int sock_fd; 943 FILE *log_fp = NULL; 944 945 sock_fd = data->sock_fd; 946 947 while (true) { 948 int test_to_run = -1; 949 struct prog_test_def *test; 950 struct test_result *result; 951 952 /* grab a test */ 953 { 954 pthread_mutex_lock(¤t_test_lock); 955 956 if (current_test_idx >= prog_test_cnt) { 957 pthread_mutex_unlock(¤t_test_lock); 958 goto done; 959 } 960 961 test = &prog_test_defs[current_test_idx]; 962 test_to_run = current_test_idx; 963 current_test_idx++; 964 965 pthread_mutex_unlock(¤t_test_lock); 966 } 967 968 if (!test->should_run || test->run_serial_test) 969 continue; 970 971 /* run test through worker */ 972 { 973 struct msg msg_do_test; 974 975 msg_do_test.type = MSG_DO_TEST; 976 msg_do_test.do_test.test_num = test_to_run; 977 if (send_message(sock_fd, &msg_do_test) < 0) { 978 perror("Fail to send command"); 979 goto done; 980 } 981 env.worker_current_test[data->worker_id] = test_to_run; 982 } 983 984 /* wait for test done */ 985 { 986 int err; 987 struct msg msg_test_done; 988 989 err = recv_message(sock_fd, &msg_test_done); 990 if (err < 0) 991 goto error; 992 if (msg_test_done.type != MSG_TEST_DONE) 993 goto error; 994 if (test_to_run != msg_test_done.test_done.test_num) 995 goto error; 996 997 test->tested = true; 998 result = &test_results[test_to_run]; 999 1000 result->error_cnt = msg_test_done.test_done.error_cnt; 1001 result->skip_cnt = msg_test_done.test_done.skip_cnt; 1002 result->sub_succ_cnt = msg_test_done.test_done.sub_succ_cnt; 1003 1004 /* collect all logs */ 1005 if (msg_test_done.test_done.have_log) { 1006 log_fp = open_memstream(&result->log_buf, &result->log_cnt); 1007 if (!log_fp) 1008 goto error; 1009 1010 while (true) { 1011 struct msg msg_log; 1012 1013 if (recv_message(sock_fd, &msg_log) < 0) 1014 goto error; 1015 if (msg_log.type != MSG_TEST_LOG) 1016 goto error; 1017 1018 fprintf(log_fp, "%s", msg_log.test_log.log_buf); 1019 if (msg_log.test_log.is_last) 1020 break; 1021 } 1022 fclose(log_fp); 1023 log_fp = NULL; 1024 } 1025 /* output log */ 1026 { 1027 pthread_mutex_lock(&stdout_output_lock); 1028 1029 if (result->log_cnt) { 1030 result->log_buf[result->log_cnt] = '\0'; 1031 fprintf(stdout, "%s", result->log_buf); 1032 if (result->log_buf[result->log_cnt - 1] != '\n') 1033 fprintf(stdout, "\n"); 1034 } 1035 1036 fprintf(stdout, "#%d %s:%s\n", 1037 test->test_num, test->test_name, 1038 result->error_cnt ? "FAIL" : (result->skip_cnt ? "SKIP" : "OK")); 1039 1040 pthread_mutex_unlock(&stdout_output_lock); 1041 } 1042 1043 } /* wait for test done */ 1044 } /* while (true) */ 1045 error: 1046 if (env.debug) 1047 fprintf(stderr, "[%d]: Protocol/IO error: %s.\n", data->worker_id, strerror(errno)); 1048 1049 if (log_fp) 1050 fclose(log_fp); 1051 done: 1052 { 1053 struct msg msg_exit; 1054 1055 msg_exit.type = MSG_EXIT; 1056 if (send_message(sock_fd, &msg_exit) < 0) { 1057 if (env.debug) 1058 fprintf(stderr, "[%d]: send_message msg_exit: %s.\n", 1059 data->worker_id, strerror(errno)); 1060 } 1061 } 1062 return NULL; 1063 } 1064 1065 static void print_all_error_logs(void) 1066 { 1067 int i; 1068 1069 if (env.fail_cnt) 1070 fprintf(stdout, "\nAll error logs:\n"); 1071 1072 /* print error logs again */ 1073 for (i = 0; i < prog_test_cnt; i++) { 1074 struct prog_test_def *test; 1075 struct test_result *result; 1076 1077 test = &prog_test_defs[i]; 1078 result = &test_results[i]; 1079 1080 if (!test->tested || !result->error_cnt) 1081 continue; 1082 1083 fprintf(stdout, "\n#%d %s:%s\n", 1084 test->test_num, test->test_name, 1085 result->error_cnt ? "FAIL" : (result->skip_cnt ? "SKIP" : "OK")); 1086 1087 if (result->log_cnt) { 1088 result->log_buf[result->log_cnt] = '\0'; 1089 fprintf(stdout, "%s", result->log_buf); 1090 if (result->log_buf[result->log_cnt - 1] != '\n') 1091 fprintf(stdout, "\n"); 1092 } 1093 } 1094 } 1095 1096 static int server_main(void) 1097 { 1098 pthread_t *dispatcher_threads; 1099 struct dispatch_data *data; 1100 struct sigaction sigact_int = { 1101 .sa_handler = sigint_handler, 1102 .sa_flags = SA_RESETHAND, 1103 }; 1104 int i; 1105 1106 sigaction(SIGINT, &sigact_int, NULL); 1107 1108 dispatcher_threads = calloc(sizeof(pthread_t), env.workers); 1109 data = calloc(sizeof(struct dispatch_data), env.workers); 1110 1111 env.worker_current_test = calloc(sizeof(int), env.workers); 1112 for (i = 0; i < env.workers; i++) { 1113 int rc; 1114 1115 data[i].worker_id = i; 1116 data[i].sock_fd = env.worker_socks[i]; 1117 rc = pthread_create(&dispatcher_threads[i], NULL, dispatch_thread, &data[i]); 1118 if (rc < 0) { 1119 perror("Failed to launch dispatcher thread"); 1120 exit(EXIT_ERR_SETUP_INFRA); 1121 } 1122 } 1123 1124 /* wait for all dispatcher to finish */ 1125 for (i = 0; i < env.workers; i++) { 1126 while (true) { 1127 int ret = pthread_tryjoin_np(dispatcher_threads[i], NULL); 1128 1129 if (!ret) { 1130 break; 1131 } else if (ret == EBUSY) { 1132 if (env.debug) 1133 fprintf(stderr, "Still waiting for thread %d (test %d).\n", 1134 i, env.worker_current_test[i] + 1); 1135 usleep(1000 * 1000); 1136 continue; 1137 } else { 1138 fprintf(stderr, "Unexpected error joining dispatcher thread: %d", ret); 1139 break; 1140 } 1141 } 1142 } 1143 free(dispatcher_threads); 1144 free(env.worker_current_test); 1145 free(data); 1146 1147 /* run serial tests */ 1148 save_netns(); 1149 1150 for (int i = 0; i < prog_test_cnt; i++) { 1151 struct prog_test_def *test = &prog_test_defs[i]; 1152 struct test_result *result = &test_results[i]; 1153 1154 if (!test->should_run || !test->run_serial_test) 1155 continue; 1156 1157 stdio_hijack(); 1158 1159 run_one_test(i); 1160 1161 stdio_restore(); 1162 if (env.log_buf) { 1163 result->log_cnt = env.log_cnt; 1164 result->log_buf = strdup(env.log_buf); 1165 1166 free(env.log_buf); 1167 env.log_buf = NULL; 1168 env.log_cnt = 0; 1169 } 1170 restore_netns(); 1171 1172 fprintf(stdout, "#%d %s:%s\n", 1173 test->test_num, test->test_name, 1174 test->error_cnt ? "FAIL" : (test->skip_cnt ? "SKIP" : "OK")); 1175 1176 result->error_cnt = test->error_cnt; 1177 result->skip_cnt = test->skip_cnt; 1178 result->sub_succ_cnt = test->sub_succ_cnt; 1179 } 1180 1181 /* generate summary */ 1182 fflush(stderr); 1183 fflush(stdout); 1184 1185 for (i = 0; i < prog_test_cnt; i++) { 1186 struct prog_test_def *current_test; 1187 struct test_result *result; 1188 1189 current_test = &prog_test_defs[i]; 1190 result = &test_results[i]; 1191 1192 if (!current_test->tested) 1193 continue; 1194 1195 env.succ_cnt += result->error_cnt ? 0 : 1; 1196 env.skip_cnt += result->skip_cnt; 1197 if (result->error_cnt) 1198 env.fail_cnt++; 1199 env.sub_succ_cnt += result->sub_succ_cnt; 1200 } 1201 1202 print_all_error_logs(); 1203 1204 fprintf(stdout, "Summary: %d/%d PASSED, %d SKIPPED, %d FAILED\n", 1205 env.succ_cnt, env.sub_succ_cnt, env.skip_cnt, env.fail_cnt); 1206 1207 /* reap all workers */ 1208 for (i = 0; i < env.workers; i++) { 1209 int wstatus, pid; 1210 1211 pid = waitpid(env.worker_pids[i], &wstatus, 0); 1212 if (pid != env.worker_pids[i]) 1213 perror("Unable to reap worker"); 1214 } 1215 1216 return 0; 1217 } 1218 1219 static int worker_main(int sock) 1220 { 1221 save_netns(); 1222 1223 while (true) { 1224 /* receive command */ 1225 struct msg msg; 1226 1227 if (recv_message(sock, &msg) < 0) 1228 goto out; 1229 1230 switch (msg.type) { 1231 case MSG_EXIT: 1232 if (env.debug) 1233 fprintf(stderr, "[%d]: worker exit.\n", 1234 env.worker_id); 1235 goto out; 1236 case MSG_DO_TEST: { 1237 int test_to_run; 1238 struct prog_test_def *test; 1239 struct msg msg_done; 1240 1241 test_to_run = msg.do_test.test_num; 1242 test = &prog_test_defs[test_to_run]; 1243 1244 if (env.debug) 1245 fprintf(stderr, "[%d]: #%d:%s running.\n", 1246 env.worker_id, 1247 test_to_run + 1, 1248 test->test_name); 1249 1250 stdio_hijack(); 1251 1252 run_one_test(test_to_run); 1253 1254 stdio_restore(); 1255 1256 memset(&msg_done, 0, sizeof(msg_done)); 1257 msg_done.type = MSG_TEST_DONE; 1258 msg_done.test_done.test_num = test_to_run; 1259 msg_done.test_done.error_cnt = test->error_cnt; 1260 msg_done.test_done.skip_cnt = test->skip_cnt; 1261 msg_done.test_done.sub_succ_cnt = test->sub_succ_cnt; 1262 msg_done.test_done.have_log = false; 1263 1264 if (env.verbosity > VERBOSE_NONE || test->force_log || test->error_cnt) { 1265 if (env.log_cnt) 1266 msg_done.test_done.have_log = true; 1267 } 1268 if (send_message(sock, &msg_done) < 0) { 1269 perror("Fail to send message done"); 1270 goto out; 1271 } 1272 1273 /* send logs */ 1274 if (msg_done.test_done.have_log) { 1275 char *src; 1276 size_t slen; 1277 1278 src = env.log_buf; 1279 slen = env.log_cnt; 1280 while (slen) { 1281 struct msg msg_log; 1282 char *dest; 1283 size_t len; 1284 1285 memset(&msg_log, 0, sizeof(msg_log)); 1286 msg_log.type = MSG_TEST_LOG; 1287 dest = msg_log.test_log.log_buf; 1288 len = slen >= MAX_LOG_TRUNK_SIZE ? MAX_LOG_TRUNK_SIZE : slen; 1289 memcpy(dest, src, len); 1290 1291 src += len; 1292 slen -= len; 1293 if (!slen) 1294 msg_log.test_log.is_last = true; 1295 1296 assert(send_message(sock, &msg_log) >= 0); 1297 } 1298 } 1299 if (env.log_buf) { 1300 free(env.log_buf); 1301 env.log_buf = NULL; 1302 env.log_cnt = 0; 1303 } 1304 if (env.debug) 1305 fprintf(stderr, "[%d]: #%d:%s done.\n", 1306 env.worker_id, 1307 test_to_run + 1, 1308 test->test_name); 1309 break; 1310 } /* case MSG_DO_TEST */ 1311 default: 1312 if (env.debug) 1313 fprintf(stderr, "[%d]: unknown message.\n", env.worker_id); 1314 return -1; 1315 } 1316 } 1317 out: 1318 return 0; 1319 } 1320 1321 int main(int argc, char **argv) 1322 { 1323 static const struct argp argp = { 1324 .options = opts, 1325 .parser = parse_arg, 1326 .doc = argp_program_doc, 1327 }; 1328 struct sigaction sigact = { 1329 .sa_handler = crash_handler, 1330 .sa_flags = SA_RESETHAND, 1331 }; 1332 int err, i; 1333 1334 sigaction(SIGSEGV, &sigact, NULL); 1335 1336 err = argp_parse(&argp, argc, argv, 0, NULL, &env); 1337 if (err) 1338 return err; 1339 1340 err = cd_flavor_subdir(argv[0]); 1341 if (err) 1342 return err; 1343 1344 /* Use libbpf 1.0 API mode */ 1345 libbpf_set_strict_mode(LIBBPF_STRICT_ALL); 1346 libbpf_set_print(libbpf_print_fn); 1347 1348 srand(time(NULL)); 1349 1350 env.jit_enabled = is_jit_enabled(); 1351 env.nr_cpus = libbpf_num_possible_cpus(); 1352 if (env.nr_cpus < 0) { 1353 fprintf(stderr, "Failed to get number of CPUs: %d!\n", 1354 env.nr_cpus); 1355 return -1; 1356 } 1357 1358 env.stdout = stdout; 1359 env.stderr = stderr; 1360 1361 env.has_testmod = true; 1362 if (!env.list_test_names && load_bpf_testmod()) { 1363 fprintf(env.stderr, "WARNING! Selftests relying on bpf_testmod.ko will be skipped.\n"); 1364 env.has_testmod = false; 1365 } 1366 1367 /* initializing tests */ 1368 for (i = 0; i < prog_test_cnt; i++) { 1369 struct prog_test_def *test = &prog_test_defs[i]; 1370 1371 test->test_num = i + 1; 1372 if (should_run(&env.test_selector, 1373 test->test_num, test->test_name)) 1374 test->should_run = true; 1375 else 1376 test->should_run = false; 1377 1378 if ((test->run_test == NULL && test->run_serial_test == NULL) || 1379 (test->run_test != NULL && test->run_serial_test != NULL)) { 1380 fprintf(stderr, "Test %d:%s must have either test_%s() or serial_test_%sl() defined.\n", 1381 test->test_num, test->test_name, test->test_name, test->test_name); 1382 exit(EXIT_ERR_SETUP_INFRA); 1383 } 1384 } 1385 1386 /* ignore workers if we are just listing */ 1387 if (env.get_test_cnt || env.list_test_names) 1388 env.workers = 0; 1389 1390 /* launch workers if requested */ 1391 env.worker_id = -1; /* main process */ 1392 if (env.workers) { 1393 env.worker_pids = calloc(sizeof(__pid_t), env.workers); 1394 env.worker_socks = calloc(sizeof(int), env.workers); 1395 if (env.debug) 1396 fprintf(stdout, "Launching %d workers.\n", env.workers); 1397 for (i = 0; i < env.workers; i++) { 1398 int sv[2]; 1399 pid_t pid; 1400 1401 if (socketpair(AF_UNIX, SOCK_SEQPACKET | SOCK_CLOEXEC, 0, sv) < 0) { 1402 perror("Fail to create worker socket"); 1403 return -1; 1404 } 1405 pid = fork(); 1406 if (pid < 0) { 1407 perror("Failed to fork worker"); 1408 return -1; 1409 } else if (pid != 0) { /* main process */ 1410 close(sv[1]); 1411 env.worker_pids[i] = pid; 1412 env.worker_socks[i] = sv[0]; 1413 } else { /* inside each worker process */ 1414 close(sv[0]); 1415 env.worker_id = i; 1416 return worker_main(sv[1]); 1417 } 1418 } 1419 1420 if (env.worker_id == -1) { 1421 server_main(); 1422 goto out; 1423 } 1424 } 1425 1426 /* The rest of the main process */ 1427 1428 /* on single mode */ 1429 save_netns(); 1430 1431 for (i = 0; i < prog_test_cnt; i++) { 1432 struct prog_test_def *test = &prog_test_defs[i]; 1433 struct test_result *result; 1434 1435 if (!test->should_run) 1436 continue; 1437 1438 if (env.get_test_cnt) { 1439 env.succ_cnt++; 1440 continue; 1441 } 1442 1443 if (env.list_test_names) { 1444 fprintf(env.stdout, "%s\n", test->test_name); 1445 env.succ_cnt++; 1446 continue; 1447 } 1448 1449 stdio_hijack(); 1450 1451 run_one_test(i); 1452 1453 stdio_restore(); 1454 1455 fprintf(env.stdout, "#%d %s:%s\n", 1456 test->test_num, test->test_name, 1457 test->error_cnt ? "FAIL" : (test->skip_cnt ? "SKIP" : "OK")); 1458 1459 result = &test_results[i]; 1460 result->error_cnt = test->error_cnt; 1461 if (env.log_buf) { 1462 result->log_buf = strdup(env.log_buf); 1463 result->log_cnt = env.log_cnt; 1464 1465 free(env.log_buf); 1466 env.log_buf = NULL; 1467 env.log_cnt = 0; 1468 } 1469 1470 if (test->error_cnt) 1471 env.fail_cnt++; 1472 else 1473 env.succ_cnt++; 1474 1475 skip_account(); 1476 env.sub_succ_cnt += test->sub_succ_cnt; 1477 } 1478 1479 if (env.get_test_cnt) { 1480 printf("%d\n", env.succ_cnt); 1481 goto out; 1482 } 1483 1484 if (env.list_test_names) 1485 goto out; 1486 1487 print_all_error_logs(); 1488 1489 fprintf(stdout, "Summary: %d/%d PASSED, %d SKIPPED, %d FAILED\n", 1490 env.succ_cnt, env.sub_succ_cnt, env.skip_cnt, env.fail_cnt); 1491 1492 close(env.saved_netns_fd); 1493 out: 1494 if (!env.list_test_names && env.has_testmod) 1495 unload_bpf_testmod(); 1496 free_str_set(&env.test_selector.blacklist); 1497 free_str_set(&env.test_selector.whitelist); 1498 free(env.test_selector.num_set); 1499 free_str_set(&env.subtest_selector.blacklist); 1500 free_str_set(&env.subtest_selector.whitelist); 1501 free(env.subtest_selector.num_set); 1502 1503 if (env.succ_cnt + env.fail_cnt + env.skip_cnt == 0) 1504 return EXIT_NO_TEST; 1505 1506 return env.fail_cnt ? EXIT_FAILURE : EXIT_SUCCESS; 1507 } 1508