1 | /* SPDX-License-Identifier: GPL-2.0 */ |
2 | #ifndef __TEST_PROGS_H |
3 | #define __TEST_PROGS_H |
4 | |
5 | #include <stdio.h> |
6 | #include <unistd.h> |
7 | #include <errno.h> |
8 | #include <string.h> |
9 | #include <assert.h> |
10 | #include <stdlib.h> |
11 | #include <stdarg.h> |
12 | #include <time.h> |
13 | #include <signal.h> |
14 | |
15 | #include <linux/types.h> |
16 | typedef __u16 __sum16; |
17 | #include <arpa/inet.h> |
18 | #include <linux/if_ether.h> |
19 | #include <linux/if_packet.h> |
20 | #include <linux/ip.h> |
21 | #include <linux/ipv6.h> |
22 | #include <linux/filter.h> |
23 | #include <linux/perf_event.h> |
24 | #include <linux/socket.h> |
25 | #include <linux/unistd.h> |
26 | |
27 | #include <sys/ioctl.h> |
28 | #include <sys/wait.h> |
29 | #include <sys/types.h> |
30 | #include <sys/time.h> |
31 | #include <sys/param.h> |
32 | #include <fcntl.h> |
33 | #include <pthread.h> |
34 | #include <linux/bpf.h> |
35 | #include <linux/err.h> |
36 | #include <bpf/bpf.h> |
37 | #include <bpf/libbpf.h> |
38 | |
39 | #include "test_iptunnel_common.h" |
40 | #include "bpf_util.h" |
41 | #include <bpf/bpf_endian.h> |
42 | #include "trace_helpers.h" |
43 | #include "testing_helpers.h" |
44 | |
45 | enum verbosity { |
46 | VERBOSE_NONE, |
47 | VERBOSE_NORMAL, |
48 | VERBOSE_VERY, |
49 | VERBOSE_SUPER, |
50 | }; |
51 | |
52 | struct test_filter { |
53 | char *name; |
54 | char **subtests; |
55 | int subtest_cnt; |
56 | }; |
57 | |
58 | struct test_filter_set { |
59 | struct test_filter *tests; |
60 | int cnt; |
61 | }; |
62 | |
63 | struct test_selector { |
64 | struct test_filter_set whitelist; |
65 | struct test_filter_set blacklist; |
66 | bool *num_set; |
67 | int num_set_len; |
68 | }; |
69 | |
70 | struct subtest_state { |
71 | char *name; |
72 | size_t log_cnt; |
73 | char *log_buf; |
74 | int error_cnt; |
75 | bool skipped; |
76 | bool filtered; |
77 | |
78 | FILE *stdout; |
79 | }; |
80 | |
81 | struct test_state { |
82 | bool tested; |
83 | bool force_log; |
84 | |
85 | int error_cnt; |
86 | int skip_cnt; |
87 | int sub_succ_cnt; |
88 | |
89 | struct subtest_state *subtest_states; |
90 | int subtest_num; |
91 | |
92 | size_t log_cnt; |
93 | char *log_buf; |
94 | |
95 | FILE *stdout; |
96 | }; |
97 | |
98 | struct test_env { |
99 | struct test_selector test_selector; |
100 | struct test_selector subtest_selector; |
101 | bool verifier_stats; |
102 | bool debug; |
103 | enum verbosity verbosity; |
104 | |
105 | bool jit_enabled; |
106 | bool has_testmod; |
107 | bool get_test_cnt; |
108 | bool list_test_names; |
109 | |
110 | struct prog_test_def *test; /* current running test */ |
111 | struct test_state *test_state; /* current running test state */ |
112 | struct subtest_state *subtest_state; /* current running subtest state */ |
113 | |
114 | FILE *stdout; |
115 | FILE *stderr; |
116 | int nr_cpus; |
117 | FILE *json; |
118 | |
119 | int succ_cnt; /* successful tests */ |
120 | int sub_succ_cnt; /* successful sub-tests */ |
121 | int fail_cnt; /* total failed tests + sub-tests */ |
122 | int skip_cnt; /* skipped tests */ |
123 | |
124 | int saved_netns_fd; |
125 | int workers; /* number of worker process */ |
126 | int worker_id; /* id number of current worker, main process is -1 */ |
127 | pid_t *worker_pids; /* array of worker pids */ |
128 | int *worker_socks; /* array of worker socks */ |
129 | int *worker_current_test; /* array of current running test for each worker */ |
130 | }; |
131 | |
132 | #define MAX_LOG_TRUNK_SIZE 8192 |
133 | #define MAX_SUBTEST_NAME 1024 |
134 | enum msg_type { |
135 | MSG_DO_TEST = 0, |
136 | MSG_TEST_DONE = 1, |
137 | MSG_TEST_LOG = 2, |
138 | MSG_SUBTEST_DONE = 3, |
139 | MSG_EXIT = 255, |
140 | }; |
141 | struct msg { |
142 | enum msg_type type; |
143 | union { |
144 | struct { |
145 | int num; |
146 | } do_test; |
147 | struct { |
148 | int num; |
149 | int sub_succ_cnt; |
150 | int error_cnt; |
151 | int skip_cnt; |
152 | bool have_log; |
153 | int subtest_num; |
154 | } test_done; |
155 | struct { |
156 | char log_buf[MAX_LOG_TRUNK_SIZE + 1]; |
157 | bool is_last; |
158 | } test_log; |
159 | struct { |
160 | int num; |
161 | char name[MAX_SUBTEST_NAME + 1]; |
162 | int error_cnt; |
163 | bool skipped; |
164 | bool filtered; |
165 | bool have_log; |
166 | } subtest_done; |
167 | }; |
168 | }; |
169 | |
170 | extern struct test_env env; |
171 | |
172 | void test__force_log(void); |
173 | bool test__start_subtest(const char *name); |
174 | void test__end_subtest(void); |
175 | void test__skip(void); |
176 | void test__fail(void); |
177 | int test__join_cgroup(const char *path); |
178 | |
179 | #define PRINT_FAIL(format...) \ |
180 | ({ \ |
181 | test__fail(); \ |
182 | fprintf(stdout, "%s:FAIL:%d ", __func__, __LINE__); \ |
183 | fprintf(stdout, ##format); \ |
184 | }) |
185 | |
186 | #define _CHECK(condition, tag, duration, format...) ({ \ |
187 | int __ret = !!(condition); \ |
188 | int __save_errno = errno; \ |
189 | if (__ret) { \ |
190 | test__fail(); \ |
191 | fprintf(stdout, "%s:FAIL:%s ", __func__, tag); \ |
192 | fprintf(stdout, ##format); \ |
193 | } else { \ |
194 | fprintf(stdout, "%s:PASS:%s %d nsec\n", \ |
195 | __func__, tag, duration); \ |
196 | } \ |
197 | errno = __save_errno; \ |
198 | __ret; \ |
199 | }) |
200 | |
201 | #define CHECK_FAIL(condition) ({ \ |
202 | int __ret = !!(condition); \ |
203 | int __save_errno = errno; \ |
204 | if (__ret) { \ |
205 | test__fail(); \ |
206 | fprintf(stdout, "%s:FAIL:%d\n", __func__, __LINE__); \ |
207 | } \ |
208 | errno = __save_errno; \ |
209 | __ret; \ |
210 | }) |
211 | |
212 | #define CHECK(condition, tag, format...) \ |
213 | _CHECK(condition, tag, duration, format) |
214 | #define CHECK_ATTR(condition, tag, format...) \ |
215 | _CHECK(condition, tag, tattr.duration, format) |
216 | |
217 | #define ASSERT_FAIL(fmt, args...) ({ \ |
218 | static int duration = 0; \ |
219 | CHECK(false, "", fmt"\n", ##args); \ |
220 | false; \ |
221 | }) |
222 | |
223 | #define ASSERT_TRUE(actual, name) ({ \ |
224 | static int duration = 0; \ |
225 | bool ___ok = (actual); \ |
226 | CHECK(!___ok, (name), "unexpected %s: got FALSE\n", (name)); \ |
227 | ___ok; \ |
228 | }) |
229 | |
230 | #define ASSERT_FALSE(actual, name) ({ \ |
231 | static int duration = 0; \ |
232 | bool ___ok = !(actual); \ |
233 | CHECK(!___ok, (name), "unexpected %s: got TRUE\n", (name)); \ |
234 | ___ok; \ |
235 | }) |
236 | |
237 | #define ASSERT_EQ(actual, expected, name) ({ \ |
238 | static int duration = 0; \ |
239 | typeof(actual) ___act = (actual); \ |
240 | typeof(expected) ___exp = (expected); \ |
241 | bool ___ok = ___act == ___exp; \ |
242 | CHECK(!___ok, (name), \ |
243 | "unexpected %s: actual %lld != expected %lld\n", \ |
244 | (name), (long long)(___act), (long long)(___exp)); \ |
245 | ___ok; \ |
246 | }) |
247 | |
248 | #define ASSERT_NEQ(actual, expected, name) ({ \ |
249 | static int duration = 0; \ |
250 | typeof(actual) ___act = (actual); \ |
251 | typeof(expected) ___exp = (expected); \ |
252 | bool ___ok = ___act != ___exp; \ |
253 | CHECK(!___ok, (name), \ |
254 | "unexpected %s: actual %lld == expected %lld\n", \ |
255 | (name), (long long)(___act), (long long)(___exp)); \ |
256 | ___ok; \ |
257 | }) |
258 | |
259 | #define ASSERT_LT(actual, expected, name) ({ \ |
260 | static int duration = 0; \ |
261 | typeof(actual) ___act = (actual); \ |
262 | typeof(expected) ___exp = (expected); \ |
263 | bool ___ok = ___act < ___exp; \ |
264 | CHECK(!___ok, (name), \ |
265 | "unexpected %s: actual %lld >= expected %lld\n", \ |
266 | (name), (long long)(___act), (long long)(___exp)); \ |
267 | ___ok; \ |
268 | }) |
269 | |
270 | #define ASSERT_LE(actual, expected, name) ({ \ |
271 | static int duration = 0; \ |
272 | typeof(actual) ___act = (actual); \ |
273 | typeof(expected) ___exp = (expected); \ |
274 | bool ___ok = ___act <= ___exp; \ |
275 | CHECK(!___ok, (name), \ |
276 | "unexpected %s: actual %lld > expected %lld\n", \ |
277 | (name), (long long)(___act), (long long)(___exp)); \ |
278 | ___ok; \ |
279 | }) |
280 | |
281 | #define ASSERT_GT(actual, expected, name) ({ \ |
282 | static int duration = 0; \ |
283 | typeof(actual) ___act = (actual); \ |
284 | typeof(expected) ___exp = (expected); \ |
285 | bool ___ok = ___act > ___exp; \ |
286 | CHECK(!___ok, (name), \ |
287 | "unexpected %s: actual %lld <= expected %lld\n", \ |
288 | (name), (long long)(___act), (long long)(___exp)); \ |
289 | ___ok; \ |
290 | }) |
291 | |
292 | #define ASSERT_GE(actual, expected, name) ({ \ |
293 | static int duration = 0; \ |
294 | typeof(actual) ___act = (actual); \ |
295 | typeof(expected) ___exp = (expected); \ |
296 | bool ___ok = ___act >= ___exp; \ |
297 | CHECK(!___ok, (name), \ |
298 | "unexpected %s: actual %lld < expected %lld\n", \ |
299 | (name), (long long)(___act), (long long)(___exp)); \ |
300 | ___ok; \ |
301 | }) |
302 | |
303 | #define ASSERT_STREQ(actual, expected, name) ({ \ |
304 | static int duration = 0; \ |
305 | const char *___act = actual; \ |
306 | const char *___exp = expected; \ |
307 | bool ___ok = strcmp(___act, ___exp) == 0; \ |
308 | CHECK(!___ok, (name), \ |
309 | "unexpected %s: actual '%s' != expected '%s'\n", \ |
310 | (name), ___act, ___exp); \ |
311 | ___ok; \ |
312 | }) |
313 | |
314 | #define ASSERT_STRNEQ(actual, expected, len, name) ({ \ |
315 | static int duration = 0; \ |
316 | const char *___act = actual; \ |
317 | const char *___exp = expected; \ |
318 | int ___len = len; \ |
319 | bool ___ok = strncmp(___act, ___exp, ___len) == 0; \ |
320 | CHECK(!___ok, (name), \ |
321 | "unexpected %s: actual '%.*s' != expected '%.*s'\n", \ |
322 | (name), ___len, ___act, ___len, ___exp); \ |
323 | ___ok; \ |
324 | }) |
325 | |
326 | #define ASSERT_HAS_SUBSTR(str, substr, name) ({ \ |
327 | static int duration = 0; \ |
328 | const char *___str = str; \ |
329 | const char *___substr = substr; \ |
330 | bool ___ok = strstr(___str, ___substr) != NULL; \ |
331 | CHECK(!___ok, (name), \ |
332 | "unexpected %s: '%s' is not a substring of '%s'\n", \ |
333 | (name), ___substr, ___str); \ |
334 | ___ok; \ |
335 | }) |
336 | |
337 | #define ASSERT_OK(res, name) ({ \ |
338 | static int duration = 0; \ |
339 | long long ___res = (res); \ |
340 | bool ___ok = ___res == 0; \ |
341 | CHECK(!___ok, (name), "unexpected error: %lld (errno %d)\n", \ |
342 | ___res, errno); \ |
343 | ___ok; \ |
344 | }) |
345 | |
346 | #define ASSERT_ERR(res, name) ({ \ |
347 | static int duration = 0; \ |
348 | long long ___res = (res); \ |
349 | bool ___ok = ___res < 0; \ |
350 | CHECK(!___ok, (name), "unexpected success: %lld\n", ___res); \ |
351 | ___ok; \ |
352 | }) |
353 | |
354 | #define ASSERT_NULL(ptr, name) ({ \ |
355 | static int duration = 0; \ |
356 | const void *___res = (ptr); \ |
357 | bool ___ok = !___res; \ |
358 | CHECK(!___ok, (name), "unexpected pointer: %p\n", ___res); \ |
359 | ___ok; \ |
360 | }) |
361 | |
362 | #define ASSERT_OK_PTR(ptr, name) ({ \ |
363 | static int duration = 0; \ |
364 | const void *___res = (ptr); \ |
365 | int ___err = libbpf_get_error(___res); \ |
366 | bool ___ok = ___err == 0; \ |
367 | CHECK(!___ok, (name), "unexpected error: %d\n", ___err); \ |
368 | ___ok; \ |
369 | }) |
370 | |
371 | #define ASSERT_ERR_PTR(ptr, name) ({ \ |
372 | static int duration = 0; \ |
373 | const void *___res = (ptr); \ |
374 | int ___err = libbpf_get_error(___res); \ |
375 | bool ___ok = ___err != 0; \ |
376 | CHECK(!___ok, (name), "unexpected pointer: %p\n", ___res); \ |
377 | ___ok; \ |
378 | }) |
379 | |
380 | #define SYS(goto_label, fmt, ...) \ |
381 | ({ \ |
382 | char cmd[1024]; \ |
383 | snprintf(cmd, sizeof(cmd), fmt, ##__VA_ARGS__); \ |
384 | if (!ASSERT_OK(system(cmd), cmd)) \ |
385 | goto goto_label; \ |
386 | }) |
387 | |
388 | #define ALL_TO_DEV_NULL " >/dev/null 2>&1" |
389 | |
390 | #define SYS_NOFAIL(fmt, ...) \ |
391 | ({ \ |
392 | char cmd[1024]; \ |
393 | int n; \ |
394 | n = snprintf(cmd, sizeof(cmd), fmt, ##__VA_ARGS__); \ |
395 | if (n < sizeof(cmd) && sizeof(cmd) - n >= sizeof(ALL_TO_DEV_NULL)) \ |
396 | strcat(cmd, ALL_TO_DEV_NULL); \ |
397 | system(cmd); \ |
398 | }) |
399 | |
400 | int start_libbpf_log_capture(void); |
401 | char *stop_libbpf_log_capture(void); |
402 | |
403 | static inline __u64 ptr_to_u64(const void *ptr) |
404 | { |
405 | return (__u64) (unsigned long) ptr; |
406 | } |
407 | |
408 | static inline void *u64_to_ptr(__u64 ptr) |
409 | { |
410 | return (void *) (unsigned long) ptr; |
411 | } |
412 | |
413 | int bpf_find_map(const char *test, struct bpf_object *obj, const char *name); |
414 | int compare_map_keys(int map1_fd, int map2_fd); |
415 | int compare_stack_ips(int smap_fd, int amap_fd, int stack_trace_len); |
416 | int trigger_module_test_read(int read_sz); |
417 | int trigger_module_test_write(int write_sz); |
418 | int write_sysctl(const char *sysctl, const char *value); |
419 | int get_bpf_max_tramp_links_from(struct btf *btf); |
420 | int get_bpf_max_tramp_links(void); |
421 | |
422 | #ifdef __x86_64__ |
423 | #define SYS_NANOSLEEP_KPROBE_NAME "__x64_sys_nanosleep" |
424 | #elif defined(__s390x__) |
425 | #define SYS_NANOSLEEP_KPROBE_NAME "__s390x_sys_nanosleep" |
426 | #elif defined(__aarch64__) |
427 | #define SYS_NANOSLEEP_KPROBE_NAME "__arm64_sys_nanosleep" |
428 | #elif defined(__riscv) |
429 | #define SYS_NANOSLEEP_KPROBE_NAME "__riscv_sys_nanosleep" |
430 | #else |
431 | #define SYS_NANOSLEEP_KPROBE_NAME "sys_nanosleep" |
432 | #endif |
433 | |
434 | #define BPF_TESTMOD_TEST_FILE "/sys/kernel/bpf_testmod" |
435 | |
436 | typedef int (*pre_execution_cb)(struct bpf_object *obj); |
437 | |
438 | struct test_loader { |
439 | char *log_buf; |
440 | size_t log_buf_sz; |
441 | size_t next_match_pos; |
442 | pre_execution_cb pre_execution_cb; |
443 | |
444 | struct bpf_object *obj; |
445 | }; |
446 | |
447 | static inline void test_loader__set_pre_execution_cb(struct test_loader *tester, |
448 | pre_execution_cb cb) |
449 | { |
450 | tester->pre_execution_cb = cb; |
451 | } |
452 | |
453 | typedef const void *(*skel_elf_bytes_fn)(size_t *sz); |
454 | |
455 | extern void test_loader__run_subtests(struct test_loader *tester, |
456 | const char *skel_name, |
457 | skel_elf_bytes_fn elf_bytes_factory); |
458 | |
459 | extern void test_loader_fini(struct test_loader *tester); |
460 | |
461 | #define RUN_TESTS(skel) ({ \ |
462 | struct test_loader tester = {}; \ |
463 | \ |
464 | test_loader__run_subtests(&tester, #skel, skel##__elf_bytes); \ |
465 | test_loader_fini(&tester); \ |
466 | }) |
467 | |
468 | #endif /* __TEST_PROGS_H */ |
469 | |