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 "bpf_rlimit.h" 8 #include <argp.h> 9 #include <pthread.h> 10 #include <sched.h> 11 #include <signal.h> 12 #include <string.h> 13 #include <execinfo.h> /* backtrace */ 14 #include <linux/membarrier.h> 15 16 /* Adapted from perf/util/string.c */ 17 static bool glob_match(const char *str, const char *pat) 18 { 19 while (*str && *pat && *pat != '*') { 20 if (*str != *pat) 21 return false; 22 str++; 23 pat++; 24 } 25 /* Check wild card */ 26 if (*pat == '*') { 27 while (*pat == '*') 28 pat++; 29 if (!*pat) /* Tail wild card matches all */ 30 return true; 31 while (*str) 32 if (glob_match(str++, pat)) 33 return true; 34 } 35 return !*str && !*pat; 36 } 37 38 #define EXIT_NO_TEST 2 39 #define EXIT_ERR_SETUP_INFRA 3 40 41 /* defined in test_progs.h */ 42 struct test_env env = {}; 43 44 struct prog_test_def { 45 const char *test_name; 46 int test_num; 47 void (*run_test)(void); 48 bool force_log; 49 int error_cnt; 50 int skip_cnt; 51 bool tested; 52 bool need_cgroup_cleanup; 53 54 char *subtest_name; 55 int subtest_num; 56 57 /* store counts before subtest started */ 58 int old_error_cnt; 59 }; 60 61 /* Override C runtime library's usleep() implementation to ensure nanosleep() 62 * is always called. Usleep is frequently used in selftests as a way to 63 * trigger kprobe and tracepoints. 64 */ 65 int usleep(useconds_t usec) 66 { 67 struct timespec ts = { 68 .tv_sec = usec / 1000000, 69 .tv_nsec = (usec % 1000000) * 1000, 70 }; 71 72 return syscall(__NR_nanosleep, &ts, NULL); 73 } 74 75 static bool should_run(struct test_selector *sel, int num, const char *name) 76 { 77 int i; 78 79 for (i = 0; i < sel->blacklist.cnt; i++) { 80 if (glob_match(name, sel->blacklist.strs[i])) 81 return false; 82 } 83 84 for (i = 0; i < sel->whitelist.cnt; i++) { 85 if (glob_match(name, sel->whitelist.strs[i])) 86 return true; 87 } 88 89 if (!sel->whitelist.cnt && !sel->num_set) 90 return true; 91 92 return num < sel->num_set_len && sel->num_set[num]; 93 } 94 95 static void dump_test_log(const struct prog_test_def *test, bool failed) 96 { 97 if (stdout == env.stdout) 98 return; 99 100 fflush(stdout); /* exports env.log_buf & env.log_cnt */ 101 102 if (env.verbosity > VERBOSE_NONE || test->force_log || failed) { 103 if (env.log_cnt) { 104 env.log_buf[env.log_cnt] = '\0'; 105 fprintf(env.stdout, "%s", env.log_buf); 106 if (env.log_buf[env.log_cnt - 1] != '\n') 107 fprintf(env.stdout, "\n"); 108 } 109 } 110 111 fseeko(stdout, 0, SEEK_SET); /* rewind */ 112 } 113 114 static void skip_account(void) 115 { 116 if (env.test->skip_cnt) { 117 env.skip_cnt++; 118 env.test->skip_cnt = 0; 119 } 120 } 121 122 static void stdio_restore(void); 123 124 /* A bunch of tests set custom affinity per-thread and/or per-process. Reset 125 * it after each test/sub-test. 126 */ 127 static void reset_affinity() { 128 129 cpu_set_t cpuset; 130 int i, err; 131 132 CPU_ZERO(&cpuset); 133 for (i = 0; i < env.nr_cpus; i++) 134 CPU_SET(i, &cpuset); 135 136 err = sched_setaffinity(0, sizeof(cpuset), &cpuset); 137 if (err < 0) { 138 stdio_restore(); 139 fprintf(stderr, "Failed to reset process affinity: %d!\n", err); 140 exit(EXIT_ERR_SETUP_INFRA); 141 } 142 err = pthread_setaffinity_np(pthread_self(), sizeof(cpuset), &cpuset); 143 if (err < 0) { 144 stdio_restore(); 145 fprintf(stderr, "Failed to reset thread affinity: %d!\n", err); 146 exit(EXIT_ERR_SETUP_INFRA); 147 } 148 } 149 150 static void save_netns(void) 151 { 152 env.saved_netns_fd = open("/proc/self/ns/net", O_RDONLY); 153 if (env.saved_netns_fd == -1) { 154 perror("open(/proc/self/ns/net)"); 155 exit(EXIT_ERR_SETUP_INFRA); 156 } 157 } 158 159 static void restore_netns(void) 160 { 161 if (setns(env.saved_netns_fd, CLONE_NEWNET) == -1) { 162 stdio_restore(); 163 perror("setns(CLONE_NEWNS)"); 164 exit(EXIT_ERR_SETUP_INFRA); 165 } 166 } 167 168 void test__end_subtest() 169 { 170 struct prog_test_def *test = env.test; 171 int sub_error_cnt = test->error_cnt - test->old_error_cnt; 172 173 dump_test_log(test, sub_error_cnt); 174 175 fprintf(env.stdout, "#%d/%d %s/%s:%s\n", 176 test->test_num, test->subtest_num, test->test_name, test->subtest_name, 177 sub_error_cnt ? "FAIL" : (test->skip_cnt ? "SKIP" : "OK")); 178 179 if (sub_error_cnt) 180 env.fail_cnt++; 181 else if (test->skip_cnt == 0) 182 env.sub_succ_cnt++; 183 skip_account(); 184 185 free(test->subtest_name); 186 test->subtest_name = NULL; 187 } 188 189 bool test__start_subtest(const char *name) 190 { 191 struct prog_test_def *test = env.test; 192 193 if (test->subtest_name) 194 test__end_subtest(); 195 196 test->subtest_num++; 197 198 if (!name || !name[0]) { 199 fprintf(env.stderr, 200 "Subtest #%d didn't provide sub-test name!\n", 201 test->subtest_num); 202 return false; 203 } 204 205 if (!should_run(&env.subtest_selector, test->subtest_num, name)) 206 return false; 207 208 test->subtest_name = strdup(name); 209 if (!test->subtest_name) { 210 fprintf(env.stderr, 211 "Subtest #%d: failed to copy subtest name!\n", 212 test->subtest_num); 213 return false; 214 } 215 env.test->old_error_cnt = env.test->error_cnt; 216 217 return true; 218 } 219 220 void test__force_log() { 221 env.test->force_log = true; 222 } 223 224 void test__skip(void) 225 { 226 env.test->skip_cnt++; 227 } 228 229 void test__fail(void) 230 { 231 env.test->error_cnt++; 232 } 233 234 int test__join_cgroup(const char *path) 235 { 236 int fd; 237 238 if (!env.test->need_cgroup_cleanup) { 239 if (setup_cgroup_environment()) { 240 fprintf(stderr, 241 "#%d %s: Failed to setup cgroup environment\n", 242 env.test->test_num, env.test->test_name); 243 return -1; 244 } 245 246 env.test->need_cgroup_cleanup = true; 247 } 248 249 fd = create_and_get_cgroup(path); 250 if (fd < 0) { 251 fprintf(stderr, 252 "#%d %s: Failed to create cgroup '%s' (errno=%d)\n", 253 env.test->test_num, env.test->test_name, path, errno); 254 return fd; 255 } 256 257 if (join_cgroup(path)) { 258 fprintf(stderr, 259 "#%d %s: Failed to join cgroup '%s' (errno=%d)\n", 260 env.test->test_num, env.test->test_name, path, errno); 261 return -1; 262 } 263 264 return fd; 265 } 266 267 int bpf_find_map(const char *test, struct bpf_object *obj, const char *name) 268 { 269 struct bpf_map *map; 270 271 map = bpf_object__find_map_by_name(obj, name); 272 if (!map) { 273 fprintf(stdout, "%s:FAIL:map '%s' not found\n", test, name); 274 test__fail(); 275 return -1; 276 } 277 return bpf_map__fd(map); 278 } 279 280 static bool is_jit_enabled(void) 281 { 282 const char *jit_sysctl = "/proc/sys/net/core/bpf_jit_enable"; 283 bool enabled = false; 284 int sysctl_fd; 285 286 sysctl_fd = open(jit_sysctl, 0, O_RDONLY); 287 if (sysctl_fd != -1) { 288 char tmpc; 289 290 if (read(sysctl_fd, &tmpc, sizeof(tmpc)) == 1) 291 enabled = (tmpc != '0'); 292 close(sysctl_fd); 293 } 294 295 return enabled; 296 } 297 298 int compare_map_keys(int map1_fd, int map2_fd) 299 { 300 __u32 key, next_key; 301 char val_buf[PERF_MAX_STACK_DEPTH * 302 sizeof(struct bpf_stack_build_id)]; 303 int err; 304 305 err = bpf_map_get_next_key(map1_fd, NULL, &key); 306 if (err) 307 return err; 308 err = bpf_map_lookup_elem(map2_fd, &key, val_buf); 309 if (err) 310 return err; 311 312 while (bpf_map_get_next_key(map1_fd, &key, &next_key) == 0) { 313 err = bpf_map_lookup_elem(map2_fd, &next_key, val_buf); 314 if (err) 315 return err; 316 317 key = next_key; 318 } 319 if (errno != ENOENT) 320 return -1; 321 322 return 0; 323 } 324 325 int compare_stack_ips(int smap_fd, int amap_fd, int stack_trace_len) 326 { 327 __u32 key, next_key, *cur_key_p, *next_key_p; 328 char *val_buf1, *val_buf2; 329 int i, err = 0; 330 331 val_buf1 = malloc(stack_trace_len); 332 val_buf2 = malloc(stack_trace_len); 333 cur_key_p = NULL; 334 next_key_p = &key; 335 while (bpf_map_get_next_key(smap_fd, cur_key_p, next_key_p) == 0) { 336 err = bpf_map_lookup_elem(smap_fd, next_key_p, val_buf1); 337 if (err) 338 goto out; 339 err = bpf_map_lookup_elem(amap_fd, next_key_p, val_buf2); 340 if (err) 341 goto out; 342 for (i = 0; i < stack_trace_len; i++) { 343 if (val_buf1[i] != val_buf2[i]) { 344 err = -1; 345 goto out; 346 } 347 } 348 key = *next_key_p; 349 cur_key_p = &key; 350 next_key_p = &next_key; 351 } 352 if (errno != ENOENT) 353 err = -1; 354 355 out: 356 free(val_buf1); 357 free(val_buf2); 358 return err; 359 } 360 361 int extract_build_id(char *build_id, size_t size) 362 { 363 FILE *fp; 364 char *line = NULL; 365 size_t len = 0; 366 367 fp = popen("readelf -n ./urandom_read | grep 'Build ID'", "r"); 368 if (fp == NULL) 369 return -1; 370 371 if (getline(&line, &len, fp) == -1) 372 goto err; 373 fclose(fp); 374 375 if (len > size) 376 len = size; 377 memcpy(build_id, line, len); 378 build_id[len] = '\0'; 379 free(line); 380 return 0; 381 err: 382 fclose(fp); 383 return -1; 384 } 385 386 static int finit_module(int fd, const char *param_values, int flags) 387 { 388 return syscall(__NR_finit_module, fd, param_values, flags); 389 } 390 391 static int delete_module(const char *name, int flags) 392 { 393 return syscall(__NR_delete_module, name, flags); 394 } 395 396 /* 397 * Trigger synchronize_rcu() in kernel. 398 */ 399 int kern_sync_rcu(void) 400 { 401 return syscall(__NR_membarrier, MEMBARRIER_CMD_SHARED, 0, 0); 402 } 403 404 static void unload_bpf_testmod(void) 405 { 406 if (kern_sync_rcu()) 407 fprintf(env.stderr, "Failed to trigger kernel-side RCU sync!\n"); 408 if (delete_module("bpf_testmod", 0)) { 409 if (errno == ENOENT) { 410 if (env.verbosity > VERBOSE_NONE) 411 fprintf(stdout, "bpf_testmod.ko is already unloaded.\n"); 412 return; 413 } 414 fprintf(env.stderr, "Failed to unload bpf_testmod.ko from kernel: %d\n", -errno); 415 return; 416 } 417 if (env.verbosity > VERBOSE_NONE) 418 fprintf(stdout, "Successfully unloaded bpf_testmod.ko.\n"); 419 } 420 421 static int load_bpf_testmod(void) 422 { 423 int fd; 424 425 /* ensure previous instance of the module is unloaded */ 426 unload_bpf_testmod(); 427 428 if (env.verbosity > VERBOSE_NONE) 429 fprintf(stdout, "Loading bpf_testmod.ko...\n"); 430 431 fd = open("bpf_testmod.ko", O_RDONLY); 432 if (fd < 0) { 433 fprintf(env.stderr, "Can't find bpf_testmod.ko kernel module: %d\n", -errno); 434 return -ENOENT; 435 } 436 if (finit_module(fd, "", 0)) { 437 fprintf(env.stderr, "Failed to load bpf_testmod.ko into the kernel: %d\n", -errno); 438 close(fd); 439 return -EINVAL; 440 } 441 close(fd); 442 443 if (env.verbosity > VERBOSE_NONE) 444 fprintf(stdout, "Successfully loaded bpf_testmod.ko.\n"); 445 return 0; 446 } 447 448 /* extern declarations for test funcs */ 449 #define DEFINE_TEST(name) extern void test_##name(void); 450 #include <prog_tests/tests.h> 451 #undef DEFINE_TEST 452 453 static struct prog_test_def prog_test_defs[] = { 454 #define DEFINE_TEST(name) { \ 455 .test_name = #name, \ 456 .run_test = &test_##name, \ 457 }, 458 #include <prog_tests/tests.h> 459 #undef DEFINE_TEST 460 }; 461 const int prog_test_cnt = ARRAY_SIZE(prog_test_defs); 462 463 const char *argp_program_version = "test_progs 0.1"; 464 const char *argp_program_bug_address = "<bpf@vger.kernel.org>"; 465 const char argp_program_doc[] = "BPF selftests test runner"; 466 467 enum ARG_KEYS { 468 ARG_TEST_NUM = 'n', 469 ARG_TEST_NAME = 't', 470 ARG_TEST_NAME_BLACKLIST = 'b', 471 ARG_VERIFIER_STATS = 's', 472 ARG_VERBOSE = 'v', 473 ARG_GET_TEST_CNT = 'c', 474 ARG_LIST_TEST_NAMES = 'l', 475 ARG_TEST_NAME_GLOB_ALLOWLIST = 'a', 476 ARG_TEST_NAME_GLOB_DENYLIST = 'd', 477 }; 478 479 static const struct argp_option opts[] = { 480 { "num", ARG_TEST_NUM, "NUM", 0, 481 "Run test number NUM only " }, 482 { "name", ARG_TEST_NAME, "NAMES", 0, 483 "Run tests with names containing any string from NAMES list" }, 484 { "name-blacklist", ARG_TEST_NAME_BLACKLIST, "NAMES", 0, 485 "Don't run tests with names containing any string from NAMES list" }, 486 { "verifier-stats", ARG_VERIFIER_STATS, NULL, 0, 487 "Output verifier statistics", }, 488 { "verbose", ARG_VERBOSE, "LEVEL", OPTION_ARG_OPTIONAL, 489 "Verbose output (use -vv or -vvv for progressively verbose output)" }, 490 { "count", ARG_GET_TEST_CNT, NULL, 0, 491 "Get number of selected top-level tests " }, 492 { "list", ARG_LIST_TEST_NAMES, NULL, 0, 493 "List test names that would run (without running them) " }, 494 { "allow", ARG_TEST_NAME_GLOB_ALLOWLIST, "NAMES", 0, 495 "Run tests with name matching the pattern (supports '*' wildcard)." }, 496 { "deny", ARG_TEST_NAME_GLOB_DENYLIST, "NAMES", 0, 497 "Don't run tests with name matching the pattern (supports '*' wildcard)." }, 498 {}, 499 }; 500 501 static int libbpf_print_fn(enum libbpf_print_level level, 502 const char *format, va_list args) 503 { 504 if (env.verbosity < VERBOSE_VERY && level == LIBBPF_DEBUG) 505 return 0; 506 vfprintf(stdout, format, args); 507 return 0; 508 } 509 510 static void free_str_set(const struct str_set *set) 511 { 512 int i; 513 514 if (!set) 515 return; 516 517 for (i = 0; i < set->cnt; i++) 518 free((void *)set->strs[i]); 519 free(set->strs); 520 } 521 522 static int parse_str_list(const char *s, struct str_set *set, bool is_glob_pattern) 523 { 524 char *input, *state = NULL, *next, **tmp, **strs = NULL; 525 int i, cnt = 0; 526 527 input = strdup(s); 528 if (!input) 529 return -ENOMEM; 530 531 while ((next = strtok_r(state ? NULL : input, ",", &state))) { 532 tmp = realloc(strs, sizeof(*strs) * (cnt + 1)); 533 if (!tmp) 534 goto err; 535 strs = tmp; 536 537 if (is_glob_pattern) { 538 strs[cnt] = strdup(next); 539 if (!strs[cnt]) 540 goto err; 541 } else { 542 strs[cnt] = malloc(strlen(next) + 2 + 1); 543 if (!strs[cnt]) 544 goto err; 545 sprintf(strs[cnt], "*%s*", next); 546 } 547 548 cnt++; 549 } 550 551 tmp = realloc(set->strs, sizeof(*strs) * (cnt + set->cnt)); 552 if (!tmp) 553 goto err; 554 memcpy(tmp + set->cnt, strs, sizeof(*strs) * cnt); 555 set->strs = (const char **)tmp; 556 set->cnt += cnt; 557 558 free(input); 559 free(strs); 560 return 0; 561 err: 562 for (i = 0; i < cnt; i++) 563 free(strs[i]); 564 free(strs); 565 free(input); 566 return -ENOMEM; 567 } 568 569 extern int extra_prog_load_log_flags; 570 571 static error_t parse_arg(int key, char *arg, struct argp_state *state) 572 { 573 struct test_env *env = state->input; 574 575 switch (key) { 576 case ARG_TEST_NUM: { 577 char *subtest_str = strchr(arg, '/'); 578 579 if (subtest_str) { 580 *subtest_str = '\0'; 581 if (parse_num_list(subtest_str + 1, 582 &env->subtest_selector.num_set, 583 &env->subtest_selector.num_set_len)) { 584 fprintf(stderr, 585 "Failed to parse subtest numbers.\n"); 586 return -EINVAL; 587 } 588 } 589 if (parse_num_list(arg, &env->test_selector.num_set, 590 &env->test_selector.num_set_len)) { 591 fprintf(stderr, "Failed to parse test numbers.\n"); 592 return -EINVAL; 593 } 594 break; 595 } 596 case ARG_TEST_NAME_GLOB_ALLOWLIST: 597 case ARG_TEST_NAME: { 598 char *subtest_str = strchr(arg, '/'); 599 600 if (subtest_str) { 601 *subtest_str = '\0'; 602 if (parse_str_list(subtest_str + 1, 603 &env->subtest_selector.whitelist, 604 key == ARG_TEST_NAME_GLOB_ALLOWLIST)) 605 return -ENOMEM; 606 } 607 if (parse_str_list(arg, &env->test_selector.whitelist, 608 key == ARG_TEST_NAME_GLOB_ALLOWLIST)) 609 return -ENOMEM; 610 break; 611 } 612 case ARG_TEST_NAME_GLOB_DENYLIST: 613 case ARG_TEST_NAME_BLACKLIST: { 614 char *subtest_str = strchr(arg, '/'); 615 616 if (subtest_str) { 617 *subtest_str = '\0'; 618 if (parse_str_list(subtest_str + 1, 619 &env->subtest_selector.blacklist, 620 key == ARG_TEST_NAME_GLOB_DENYLIST)) 621 return -ENOMEM; 622 } 623 if (parse_str_list(arg, &env->test_selector.blacklist, 624 key == ARG_TEST_NAME_GLOB_DENYLIST)) 625 return -ENOMEM; 626 break; 627 } 628 case ARG_VERIFIER_STATS: 629 env->verifier_stats = true; 630 break; 631 case ARG_VERBOSE: 632 env->verbosity = VERBOSE_NORMAL; 633 if (arg) { 634 if (strcmp(arg, "v") == 0) { 635 env->verbosity = VERBOSE_VERY; 636 extra_prog_load_log_flags = 1; 637 } else if (strcmp(arg, "vv") == 0) { 638 env->verbosity = VERBOSE_SUPER; 639 extra_prog_load_log_flags = 2; 640 } else { 641 fprintf(stderr, 642 "Unrecognized verbosity setting ('%s'), only -v and -vv are supported\n", 643 arg); 644 return -EINVAL; 645 } 646 } 647 648 if (env->verbosity > VERBOSE_NONE) { 649 if (setenv("SELFTESTS_VERBOSE", "1", 1) == -1) { 650 fprintf(stderr, 651 "Unable to setenv SELFTESTS_VERBOSE=1 (errno=%d)", 652 errno); 653 return -1; 654 } 655 } 656 657 break; 658 case ARG_GET_TEST_CNT: 659 env->get_test_cnt = true; 660 break; 661 case ARG_LIST_TEST_NAMES: 662 env->list_test_names = true; 663 break; 664 case ARGP_KEY_ARG: 665 argp_usage(state); 666 break; 667 case ARGP_KEY_END: 668 break; 669 default: 670 return ARGP_ERR_UNKNOWN; 671 } 672 return 0; 673 } 674 675 static void stdio_hijack(void) 676 { 677 #ifdef __GLIBC__ 678 env.stdout = stdout; 679 env.stderr = stderr; 680 681 if (env.verbosity > VERBOSE_NONE) { 682 /* nothing to do, output to stdout by default */ 683 return; 684 } 685 686 /* stdout and stderr -> buffer */ 687 fflush(stdout); 688 689 stdout = open_memstream(&env.log_buf, &env.log_cnt); 690 if (!stdout) { 691 stdout = env.stdout; 692 perror("open_memstream"); 693 return; 694 } 695 696 stderr = stdout; 697 #endif 698 } 699 700 static void stdio_restore(void) 701 { 702 #ifdef __GLIBC__ 703 if (stdout == env.stdout) 704 return; 705 706 fclose(stdout); 707 free(env.log_buf); 708 709 env.log_buf = NULL; 710 env.log_cnt = 0; 711 712 stdout = env.stdout; 713 stderr = env.stderr; 714 #endif 715 } 716 717 /* 718 * Determine if test_progs is running as a "flavored" test runner and switch 719 * into corresponding sub-directory to load correct BPF objects. 720 * 721 * This is done by looking at executable name. If it contains "-flavor" 722 * suffix, then we are running as a flavored test runner. 723 */ 724 int cd_flavor_subdir(const char *exec_name) 725 { 726 /* General form of argv[0] passed here is: 727 * some/path/to/test_progs[-flavor], where -flavor part is optional. 728 * First cut out "test_progs[-flavor]" part, then extract "flavor" 729 * part, if it's there. 730 */ 731 const char *flavor = strrchr(exec_name, '/'); 732 733 if (!flavor) 734 return 0; 735 flavor++; 736 flavor = strrchr(flavor, '-'); 737 if (!flavor) 738 return 0; 739 flavor++; 740 if (env.verbosity > VERBOSE_NONE) 741 fprintf(stdout, "Switching to flavor '%s' subdirectory...\n", flavor); 742 743 return chdir(flavor); 744 } 745 746 #define MAX_BACKTRACE_SZ 128 747 void crash_handler(int signum) 748 { 749 void *bt[MAX_BACKTRACE_SZ]; 750 size_t sz; 751 752 sz = backtrace(bt, ARRAY_SIZE(bt)); 753 754 if (env.test) 755 dump_test_log(env.test, true); 756 if (env.stdout) 757 stdio_restore(); 758 759 fprintf(stderr, "Caught signal #%d!\nStack trace:\n", signum); 760 backtrace_symbols_fd(bt, sz, STDERR_FILENO); 761 } 762 763 int main(int argc, char **argv) 764 { 765 static const struct argp argp = { 766 .options = opts, 767 .parser = parse_arg, 768 .doc = argp_program_doc, 769 }; 770 struct sigaction sigact = { 771 .sa_handler = crash_handler, 772 .sa_flags = SA_RESETHAND, 773 }; 774 int err, i; 775 776 sigaction(SIGSEGV, &sigact, NULL); 777 778 err = argp_parse(&argp, argc, argv, 0, NULL, &env); 779 if (err) 780 return err; 781 782 err = cd_flavor_subdir(argv[0]); 783 if (err) 784 return err; 785 786 /* Use libbpf 1.0 API mode */ 787 libbpf_set_strict_mode(LIBBPF_STRICT_ALL); 788 789 libbpf_set_print(libbpf_print_fn); 790 791 srand(time(NULL)); 792 793 env.jit_enabled = is_jit_enabled(); 794 env.nr_cpus = libbpf_num_possible_cpus(); 795 if (env.nr_cpus < 0) { 796 fprintf(stderr, "Failed to get number of CPUs: %d!\n", 797 env.nr_cpus); 798 return -1; 799 } 800 801 save_netns(); 802 stdio_hijack(); 803 env.has_testmod = true; 804 if (!env.list_test_names && load_bpf_testmod()) { 805 fprintf(env.stderr, "WARNING! Selftests relying on bpf_testmod.ko will be skipped.\n"); 806 env.has_testmod = false; 807 } 808 for (i = 0; i < prog_test_cnt; i++) { 809 struct prog_test_def *test = &prog_test_defs[i]; 810 811 env.test = test; 812 test->test_num = i + 1; 813 814 if (!should_run(&env.test_selector, 815 test->test_num, test->test_name)) 816 continue; 817 818 if (env.get_test_cnt) { 819 env.succ_cnt++; 820 continue; 821 } 822 823 if (env.list_test_names) { 824 fprintf(env.stdout, "%s\n", test->test_name); 825 env.succ_cnt++; 826 continue; 827 } 828 829 test->run_test(); 830 /* ensure last sub-test is finalized properly */ 831 if (test->subtest_name) 832 test__end_subtest(); 833 834 test->tested = true; 835 836 dump_test_log(test, test->error_cnt); 837 838 fprintf(env.stdout, "#%d %s:%s\n", 839 test->test_num, test->test_name, 840 test->error_cnt ? "FAIL" : (test->skip_cnt ? "SKIP" : "OK")); 841 842 if (test->error_cnt) 843 env.fail_cnt++; 844 else 845 env.succ_cnt++; 846 skip_account(); 847 848 reset_affinity(); 849 restore_netns(); 850 if (test->need_cgroup_cleanup) 851 cleanup_cgroup_environment(); 852 } 853 if (!env.list_test_names && env.has_testmod) 854 unload_bpf_testmod(); 855 stdio_restore(); 856 857 if (env.get_test_cnt) { 858 printf("%d\n", env.succ_cnt); 859 goto out; 860 } 861 862 if (env.list_test_names) 863 goto out; 864 865 fprintf(stdout, "Summary: %d/%d PASSED, %d SKIPPED, %d FAILED\n", 866 env.succ_cnt, env.sub_succ_cnt, env.skip_cnt, env.fail_cnt); 867 868 out: 869 free_str_set(&env.test_selector.blacklist); 870 free_str_set(&env.test_selector.whitelist); 871 free(env.test_selector.num_set); 872 free_str_set(&env.subtest_selector.blacklist); 873 free_str_set(&env.subtest_selector.whitelist); 874 free(env.subtest_selector.num_set); 875 close(env.saved_netns_fd); 876 877 if (env.succ_cnt + env.fail_cnt + env.skip_cnt == 0) 878 return EXIT_NO_TEST; 879 880 return env.fail_cnt ? EXIT_FAILURE : EXIT_SUCCESS; 881 } 882