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> 16typedef __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 45enum verbosity { 46 VERBOSE_NONE, 47 VERBOSE_NORMAL, 48 VERBOSE_VERY, 49 VERBOSE_SUPER, 50}; 51 52struct test_filter { 53 char *name; 54 char **subtests; 55 int subtest_cnt; 56}; 57 58struct test_filter_set { 59 struct test_filter *tests; 60 int cnt; 61}; 62 63struct 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 70struct 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 81struct 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 98struct 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 134enum 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}; 141struct 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 170extern struct test_env env; 171 172void test__force_log(void); 173bool test__start_subtest(const char *name); 174void test__end_subtest(void); 175void test__skip(void); 176void test__fail(void); 177int 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 400int start_libbpf_log_capture(void); 401char *stop_libbpf_log_capture(void); 402 403static inline __u64 ptr_to_u64(const void *ptr) 404{ 405 return (__u64) (unsigned long) ptr; 406} 407 408static inline void *u64_to_ptr(__u64 ptr) 409{ 410 return (void *) (unsigned long) ptr; 411} 412 413int bpf_find_map(const char *test, struct bpf_object *obj, const char *name); 414int compare_map_keys(int map1_fd, int map2_fd); 415int compare_stack_ips(int smap_fd, int amap_fd, int stack_trace_len); 416int trigger_module_test_read(int read_sz); 417int trigger_module_test_write(int write_sz); 418int write_sysctl(const char *sysctl, const char *value); 419int get_bpf_max_tramp_links_from(struct btf *btf); 420int 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 436typedef int (*pre_execution_cb)(struct bpf_object *obj); 437 438struct 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 447static 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 453typedef const void *(*skel_elf_bytes_fn)(size_t *sz); 454 455extern void test_loader__run_subtests(struct test_loader *tester, 456 const char *skel_name, 457 skel_elf_bytes_fn elf_bytes_factory); 458 459extern 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