1 // SPDX-License-Identifier: GPL-2.0-only
2 /* Copyright (c) 2017 Facebook
5 #include "test_progs.h"
6 #include "cgroup_helpers.h"
7 #include "bpf_rlimit.h"
13 #include <execinfo.h> /* backtrace */
15 #define EXIT_NO_TEST 2
16 #define EXIT_ERR_SETUP_INFRA 3
18 /* defined in test_progs.h */
19 struct test_env env
= {};
21 struct prog_test_def
{
22 const char *test_name
;
24 void (*run_test
)(void);
29 bool need_cgroup_cleanup
;
34 /* store counts before subtest started */
38 /* Override C runtime library's usleep() implementation to ensure nanosleep()
39 * is always called. Usleep is frequently used in selftests as a way to
40 * trigger kprobe and tracepoints.
42 int usleep(useconds_t usec
)
44 struct timespec ts
= {
45 .tv_sec
= usec
/ 1000000,
46 .tv_nsec
= (usec
% 1000000) * 1000,
49 return syscall(__NR_nanosleep
, &ts
, NULL
);
52 static bool should_run(struct test_selector
*sel
, int num
, const char *name
)
56 for (i
= 0; i
< sel
->blacklist
.cnt
; i
++) {
57 if (strstr(name
, sel
->blacklist
.strs
[i
]))
61 for (i
= 0; i
< sel
->whitelist
.cnt
; i
++) {
62 if (strstr(name
, sel
->whitelist
.strs
[i
]))
66 if (!sel
->whitelist
.cnt
&& !sel
->num_set
)
69 return num
< sel
->num_set_len
&& sel
->num_set
[num
];
72 static void dump_test_log(const struct prog_test_def
*test
, bool failed
)
74 if (stdout
== env
.stdout
)
77 fflush(stdout
); /* exports env.log_buf & env.log_cnt */
79 if (env
.verbosity
> VERBOSE_NONE
|| test
->force_log
|| failed
) {
81 env
.log_buf
[env
.log_cnt
] = '\0';
82 fprintf(env
.stdout
, "%s", env
.log_buf
);
83 if (env
.log_buf
[env
.log_cnt
- 1] != '\n')
84 fprintf(env
.stdout
, "\n");
88 fseeko(stdout
, 0, SEEK_SET
); /* rewind */
91 static void skip_account(void)
93 if (env
.test
->skip_cnt
) {
95 env
.test
->skip_cnt
= 0;
99 static void stdio_restore(void);
101 /* A bunch of tests set custom affinity per-thread and/or per-process. Reset
102 * it after each test/sub-test.
104 static void reset_affinity() {
110 for (i
= 0; i
< env
.nr_cpus
; i
++)
113 err
= sched_setaffinity(0, sizeof(cpuset
), &cpuset
);
116 fprintf(stderr
, "Failed to reset process affinity: %d!\n", err
);
117 exit(EXIT_ERR_SETUP_INFRA
);
119 err
= pthread_setaffinity_np(pthread_self(), sizeof(cpuset
), &cpuset
);
122 fprintf(stderr
, "Failed to reset thread affinity: %d!\n", err
);
123 exit(EXIT_ERR_SETUP_INFRA
);
127 static void save_netns(void)
129 env
.saved_netns_fd
= open("/proc/self/ns/net", O_RDONLY
);
130 if (env
.saved_netns_fd
== -1) {
131 perror("open(/proc/self/ns/net)");
132 exit(EXIT_ERR_SETUP_INFRA
);
136 static void restore_netns(void)
138 if (setns(env
.saved_netns_fd
, CLONE_NEWNET
) == -1) {
140 perror("setns(CLONE_NEWNS)");
141 exit(EXIT_ERR_SETUP_INFRA
);
145 void test__end_subtest()
147 struct prog_test_def
*test
= env
.test
;
148 int sub_error_cnt
= test
->error_cnt
- test
->old_error_cnt
;
152 else if (test
->skip_cnt
== 0)
156 dump_test_log(test
, sub_error_cnt
);
158 fprintf(env
.stdout
, "#%d/%d %s:%s\n",
159 test
->test_num
, test
->subtest_num
, test
->subtest_name
,
160 sub_error_cnt
? "FAIL" : (test
->skip_cnt
? "SKIP" : "OK"));
162 free(test
->subtest_name
);
163 test
->subtest_name
= NULL
;
166 bool test__start_subtest(const char *name
)
168 struct prog_test_def
*test
= env
.test
;
170 if (test
->subtest_name
)
175 if (!name
|| !name
[0]) {
177 "Subtest #%d didn't provide sub-test name!\n",
182 if (!should_run(&env
.subtest_selector
, test
->subtest_num
, name
))
185 test
->subtest_name
= strdup(name
);
186 if (!test
->subtest_name
) {
188 "Subtest #%d: failed to copy subtest name!\n",
192 env
.test
->old_error_cnt
= env
.test
->error_cnt
;
197 void test__force_log() {
198 env
.test
->force_log
= true;
201 void test__skip(void)
203 env
.test
->skip_cnt
++;
206 void test__fail(void)
208 env
.test
->error_cnt
++;
211 int test__join_cgroup(const char *path
)
215 if (!env
.test
->need_cgroup_cleanup
) {
216 if (setup_cgroup_environment()) {
218 "#%d %s: Failed to setup cgroup environment\n",
219 env
.test
->test_num
, env
.test
->test_name
);
223 env
.test
->need_cgroup_cleanup
= true;
226 fd
= create_and_get_cgroup(path
);
229 "#%d %s: Failed to create cgroup '%s' (errno=%d)\n",
230 env
.test
->test_num
, env
.test
->test_name
, path
, errno
);
234 if (join_cgroup(path
)) {
236 "#%d %s: Failed to join cgroup '%s' (errno=%d)\n",
237 env
.test
->test_num
, env
.test
->test_name
, path
, errno
);
244 int bpf_find_map(const char *test
, struct bpf_object
*obj
, const char *name
)
248 map
= bpf_object__find_map_by_name(obj
, name
);
250 fprintf(stdout
, "%s:FAIL:map '%s' not found\n", test
, name
);
254 return bpf_map__fd(map
);
257 static bool is_jit_enabled(void)
259 const char *jit_sysctl
= "/proc/sys/net/core/bpf_jit_enable";
260 bool enabled
= false;
263 sysctl_fd
= open(jit_sysctl
, 0, O_RDONLY
);
264 if (sysctl_fd
!= -1) {
267 if (read(sysctl_fd
, &tmpc
, sizeof(tmpc
)) == 1)
268 enabled
= (tmpc
!= '0');
275 int compare_map_keys(int map1_fd
, int map2_fd
)
278 char val_buf
[PERF_MAX_STACK_DEPTH
*
279 sizeof(struct bpf_stack_build_id
)];
282 err
= bpf_map_get_next_key(map1_fd
, NULL
, &key
);
285 err
= bpf_map_lookup_elem(map2_fd
, &key
, val_buf
);
289 while (bpf_map_get_next_key(map1_fd
, &key
, &next_key
) == 0) {
290 err
= bpf_map_lookup_elem(map2_fd
, &next_key
, val_buf
);
302 int compare_stack_ips(int smap_fd
, int amap_fd
, int stack_trace_len
)
304 __u32 key
, next_key
, *cur_key_p
, *next_key_p
;
305 char *val_buf1
, *val_buf2
;
308 val_buf1
= malloc(stack_trace_len
);
309 val_buf2
= malloc(stack_trace_len
);
312 while (bpf_map_get_next_key(smap_fd
, cur_key_p
, next_key_p
) == 0) {
313 err
= bpf_map_lookup_elem(smap_fd
, next_key_p
, val_buf1
);
316 err
= bpf_map_lookup_elem(amap_fd
, next_key_p
, val_buf2
);
319 for (i
= 0; i
< stack_trace_len
; i
++) {
320 if (val_buf1
[i
] != val_buf2
[i
]) {
327 next_key_p
= &next_key
;
338 int extract_build_id(char *build_id
, size_t size
)
344 fp
= popen("readelf -n ./urandom_read | grep 'Build ID'", "r");
348 if (getline(&line
, &len
, fp
) == -1)
354 memcpy(build_id
, line
, len
);
355 build_id
[len
] = '\0';
363 static int finit_module(int fd
, const char *param_values
, int flags
)
365 return syscall(__NR_finit_module
, fd
, param_values
, flags
);
368 static int delete_module(const char *name
, int flags
)
370 return syscall(__NR_delete_module
, name
, flags
);
373 static void unload_bpf_testmod(void)
375 if (delete_module("bpf_testmod", 0)) {
376 if (errno
== ENOENT
) {
377 if (env
.verbosity
> VERBOSE_NONE
)
378 fprintf(stdout
, "bpf_testmod.ko is already unloaded.\n");
381 fprintf(env
.stderr
, "Failed to unload bpf_testmod.ko from kernel: %d\n", -errno
);
384 if (env
.verbosity
> VERBOSE_NONE
)
385 fprintf(stdout
, "Successfully unloaded bpf_testmod.ko.\n");
388 static int load_bpf_testmod(void)
392 /* ensure previous instance of the module is unloaded */
393 unload_bpf_testmod();
395 if (env
.verbosity
> VERBOSE_NONE
)
396 fprintf(stdout
, "Loading bpf_testmod.ko...\n");
398 fd
= open("bpf_testmod.ko", O_RDONLY
);
400 fprintf(env
.stderr
, "Can't find bpf_testmod.ko kernel module: %d\n", -errno
);
403 if (finit_module(fd
, "", 0)) {
404 fprintf(env
.stderr
, "Failed to load bpf_testmod.ko into the kernel: %d\n", -errno
);
410 if (env
.verbosity
> VERBOSE_NONE
)
411 fprintf(stdout
, "Successfully loaded bpf_testmod.ko.\n");
415 /* extern declarations for test funcs */
416 #define DEFINE_TEST(name) extern void test_##name(void);
417 #include <prog_tests/tests.h>
420 static struct prog_test_def prog_test_defs
[] = {
421 #define DEFINE_TEST(name) { \
422 .test_name = #name, \
423 .run_test = &test_##name, \
425 #include <prog_tests/tests.h>
428 const int prog_test_cnt
= ARRAY_SIZE(prog_test_defs
);
430 const char *argp_program_version
= "test_progs 0.1";
431 const char *argp_program_bug_address
= "<bpf@vger.kernel.org>";
432 const char argp_program_doc
[] = "BPF selftests test runner";
437 ARG_TEST_NAME_BLACKLIST
= 'b',
438 ARG_VERIFIER_STATS
= 's',
440 ARG_GET_TEST_CNT
= 'c',
441 ARG_LIST_TEST_NAMES
= 'l',
444 static const struct argp_option opts
[] = {
445 { "num", ARG_TEST_NUM
, "NUM", 0,
446 "Run test number NUM only " },
447 { "name", ARG_TEST_NAME
, "NAMES", 0,
448 "Run tests with names containing any string from NAMES list" },
449 { "name-blacklist", ARG_TEST_NAME_BLACKLIST
, "NAMES", 0,
450 "Don't run tests with names containing any string from NAMES list" },
451 { "verifier-stats", ARG_VERIFIER_STATS
, NULL
, 0,
452 "Output verifier statistics", },
453 { "verbose", ARG_VERBOSE
, "LEVEL", OPTION_ARG_OPTIONAL
,
454 "Verbose output (use -vv or -vvv for progressively verbose output)" },
455 { "count", ARG_GET_TEST_CNT
, NULL
, 0,
456 "Get number of selected top-level tests " },
457 { "list", ARG_LIST_TEST_NAMES
, NULL
, 0,
458 "List test names that would run (without running them) " },
462 static int libbpf_print_fn(enum libbpf_print_level level
,
463 const char *format
, va_list args
)
465 if (env
.verbosity
< VERBOSE_VERY
&& level
== LIBBPF_DEBUG
)
467 vfprintf(stdout
, format
, args
);
471 static void free_str_set(const struct str_set
*set
)
478 for (i
= 0; i
< set
->cnt
; i
++)
479 free((void *)set
->strs
[i
]);
483 static int parse_str_list(const char *s
, struct str_set
*set
)
485 char *input
, *state
= NULL
, *next
, **tmp
, **strs
= NULL
;
495 while ((next
= strtok_r(state
? NULL
: input
, ",", &state
))) {
496 tmp
= realloc(strs
, sizeof(*strs
) * (cnt
+ 1));
501 strs
[cnt
] = strdup(next
);
509 set
->strs
= (const char **)strs
;
518 extern int extra_prog_load_log_flags
;
520 static error_t
parse_arg(int key
, char *arg
, struct argp_state
*state
)
522 struct test_env
*env
= state
->input
;
526 char *subtest_str
= strchr(arg
, '/');
530 if (parse_num_list(subtest_str
+ 1,
531 &env
->subtest_selector
.num_set
,
532 &env
->subtest_selector
.num_set_len
)) {
534 "Failed to parse subtest numbers.\n");
538 if (parse_num_list(arg
, &env
->test_selector
.num_set
,
539 &env
->test_selector
.num_set_len
)) {
540 fprintf(stderr
, "Failed to parse test numbers.\n");
545 case ARG_TEST_NAME
: {
546 char *subtest_str
= strchr(arg
, '/');
550 if (parse_str_list(subtest_str
+ 1,
551 &env
->subtest_selector
.whitelist
))
554 if (parse_str_list(arg
, &env
->test_selector
.whitelist
))
558 case ARG_TEST_NAME_BLACKLIST
: {
559 char *subtest_str
= strchr(arg
, '/');
563 if (parse_str_list(subtest_str
+ 1,
564 &env
->subtest_selector
.blacklist
))
567 if (parse_str_list(arg
, &env
->test_selector
.blacklist
))
571 case ARG_VERIFIER_STATS
:
572 env
->verifier_stats
= true;
575 env
->verbosity
= VERBOSE_NORMAL
;
577 if (strcmp(arg
, "v") == 0) {
578 env
->verbosity
= VERBOSE_VERY
;
579 extra_prog_load_log_flags
= 1;
580 } else if (strcmp(arg
, "vv") == 0) {
581 env
->verbosity
= VERBOSE_SUPER
;
582 extra_prog_load_log_flags
= 2;
585 "Unrecognized verbosity setting ('%s'), only -v and -vv are supported\n",
591 if (env
->verbosity
> VERBOSE_NONE
) {
592 if (setenv("SELFTESTS_VERBOSE", "1", 1) == -1) {
594 "Unable to setenv SELFTESTS_VERBOSE=1 (errno=%d)",
601 case ARG_GET_TEST_CNT
:
602 env
->get_test_cnt
= true;
604 case ARG_LIST_TEST_NAMES
:
605 env
->list_test_names
= true;
613 return ARGP_ERR_UNKNOWN
;
618 static void stdio_hijack(void)
624 if (env
.verbosity
> VERBOSE_NONE
) {
625 /* nothing to do, output to stdout by default */
629 /* stdout and stderr -> buffer */
632 stdout
= open_memstream(&env
.log_buf
, &env
.log_cnt
);
635 perror("open_memstream");
643 static void stdio_restore(void)
646 if (stdout
== env
.stdout
)
661 * Determine if test_progs is running as a "flavored" test runner and switch
662 * into corresponding sub-directory to load correct BPF objects.
664 * This is done by looking at executable name. If it contains "-flavor"
665 * suffix, then we are running as a flavored test runner.
667 int cd_flavor_subdir(const char *exec_name
)
669 /* General form of argv[0] passed here is:
670 * some/path/to/test_progs[-flavor], where -flavor part is optional.
671 * First cut out "test_progs[-flavor]" part, then extract "flavor"
672 * part, if it's there.
674 const char *flavor
= strrchr(exec_name
, '/');
679 flavor
= strrchr(flavor
, '-');
683 if (env
.verbosity
> VERBOSE_NONE
)
684 fprintf(stdout
, "Switching to flavor '%s' subdirectory...\n", flavor
);
686 return chdir(flavor
);
689 #define MAX_BACKTRACE_SZ 128
690 void crash_handler(int signum
)
692 void *bt
[MAX_BACKTRACE_SZ
];
695 sz
= backtrace(bt
, ARRAY_SIZE(bt
));
698 dump_test_log(env
.test
, true);
702 fprintf(stderr
, "Caught signal #%d!\nStack trace:\n", signum
);
703 backtrace_symbols_fd(bt
, sz
, STDERR_FILENO
);
706 int main(int argc
, char **argv
)
708 static const struct argp argp
= {
711 .doc
= argp_program_doc
,
713 struct sigaction sigact
= {
714 .sa_handler
= crash_handler
,
715 .sa_flags
= SA_RESETHAND
,
719 sigaction(SIGSEGV
, &sigact
, NULL
);
721 err
= argp_parse(&argp
, argc
, argv
, 0, NULL
, &env
);
725 err
= cd_flavor_subdir(argv
[0]);
729 libbpf_set_print(libbpf_print_fn
);
733 env
.jit_enabled
= is_jit_enabled();
734 env
.nr_cpus
= libbpf_num_possible_cpus();
735 if (env
.nr_cpus
< 0) {
736 fprintf(stderr
, "Failed to get number of CPUs: %d!\n",
743 env
.has_testmod
= true;
744 if (load_bpf_testmod()) {
745 fprintf(env
.stderr
, "WARNING! Selftests relying on bpf_testmod.ko will be skipped.\n");
746 env
.has_testmod
= false;
748 for (i
= 0; i
< prog_test_cnt
; i
++) {
749 struct prog_test_def
*test
= &prog_test_defs
[i
];
752 test
->test_num
= i
+ 1;
754 if (!should_run(&env
.test_selector
,
755 test
->test_num
, test
->test_name
))
758 if (env
.get_test_cnt
) {
763 if (env
.list_test_names
) {
764 fprintf(env
.stdout
, "%s\n", test
->test_name
);
770 /* ensure last sub-test is finalized properly */
771 if (test
->subtest_name
)
781 dump_test_log(test
, test
->error_cnt
);
783 fprintf(env
.stdout
, "#%d %s:%s\n",
784 test
->test_num
, test
->test_name
,
785 test
->error_cnt
? "FAIL" : "OK");
789 if (test
->need_cgroup_cleanup
)
790 cleanup_cgroup_environment();
793 unload_bpf_testmod();
796 if (env
.get_test_cnt
) {
797 printf("%d\n", env
.succ_cnt
);
801 if (env
.list_test_names
)
804 fprintf(stdout
, "Summary: %d/%d PASSED, %d SKIPPED, %d FAILED\n",
805 env
.succ_cnt
, env
.sub_succ_cnt
, env
.skip_cnt
, env
.fail_cnt
);
808 free_str_set(&env
.test_selector
.blacklist
);
809 free_str_set(&env
.test_selector
.whitelist
);
810 free(env
.test_selector
.num_set
);
811 free_str_set(&env
.subtest_selector
.blacklist
);
812 free_str_set(&env
.subtest_selector
.whitelist
);
813 free(env
.subtest_selector
.num_set
);
814 close(env
.saved_netns_fd
);
816 if (env
.succ_cnt
+ env
.fail_cnt
+ env
.skip_cnt
== 0)
819 return env
.fail_cnt
? EXIT_FAILURE
: EXIT_SUCCESS
;