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