brintos

brintos / linux-shallow public Read only

0
0
Text · 12.5 KiB · 7767d9a Raw
485 lines · c
1/* SPDX-License-Identifier: GPL-2.0 */2#ifndef __TEST_PROGS_H3#define __TEST_PROGS_H4 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	bool should_tmon;78 79	FILE *stdout_saved;80};81 82struct test_state {83	bool tested;84	bool force_log;85 86	int error_cnt;87	int skip_cnt;88	int sub_succ_cnt;89 90	struct subtest_state *subtest_states;91	int subtest_num;92 93	size_t log_cnt;94	char *log_buf;95 96	FILE *stdout_saved;97};98 99extern int env_verbosity;100 101struct test_env {102	struct test_selector test_selector;103	struct test_selector subtest_selector;104	struct test_selector tmon_selector;105	bool verifier_stats;106	bool debug;107	enum verbosity verbosity;108 109	bool jit_enabled;110	bool has_testmod;111	bool get_test_cnt;112	bool list_test_names;113 114	struct prog_test_def *test; /* current running test */115	struct test_state *test_state; /* current running test state */116	struct subtest_state *subtest_state; /* current running subtest state */117 118	FILE *stdout_saved;119	FILE *stderr_saved;120	int nr_cpus;121	FILE *json;122 123	int succ_cnt; /* successful tests */124	int sub_succ_cnt; /* successful sub-tests */125	int fail_cnt; /* total failed tests + sub-tests */126	int skip_cnt; /* skipped tests */127 128	int saved_netns_fd;129	int workers; /* number of worker process */130	int worker_id; /* id number of current worker, main process is -1 */131	pid_t *worker_pids; /* array of worker pids */132	int *worker_socks; /* array of worker socks */133	int *worker_current_test; /* array of current running test for each worker */134};135 136#define MAX_LOG_TRUNK_SIZE 8192137#define MAX_SUBTEST_NAME 1024138enum msg_type {139	MSG_DO_TEST = 0,140	MSG_TEST_DONE = 1,141	MSG_TEST_LOG = 2,142	MSG_SUBTEST_DONE = 3,143	MSG_EXIT = 255,144};145struct msg {146	enum msg_type type;147	union {148		struct {149			int num;150		} do_test;151		struct {152			int num;153			int sub_succ_cnt;154			int error_cnt;155			int skip_cnt;156			bool have_log;157			int subtest_num;158		} test_done;159		struct {160			char log_buf[MAX_LOG_TRUNK_SIZE + 1];161			bool is_last;162		} test_log;163		struct {164			int num;165			char name[MAX_SUBTEST_NAME + 1];166			int error_cnt;167			bool skipped;168			bool filtered;169			bool have_log;170		} subtest_done;171	};172};173 174extern struct test_env env;175 176void test__force_log(void);177bool test__start_subtest(const char *name);178void test__end_subtest(void);179void test__skip(void);180void test__fail(void);181int test__join_cgroup(const char *path);182 183#define PRINT_FAIL(format...)                                                  \184	({                                                                     \185		test__fail();                                                  \186		fprintf(stdout, "%s:FAIL:%d ", __func__, __LINE__);            \187		fprintf(stdout, ##format);                                     \188	})189 190#define _CHECK(condition, tag, duration, format...) ({			\191	int __ret = !!(condition);					\192	int __save_errno = errno;					\193	if (__ret) {							\194		test__fail();						\195		fprintf(stdout, "%s:FAIL:%s ", __func__, tag);		\196		fprintf(stdout, ##format);				\197	} else {							\198		fprintf(stdout, "%s:PASS:%s %d nsec\n",			\199		       __func__, tag, duration);			\200	}								\201	errno = __save_errno;						\202	__ret;								\203})204 205#define CHECK_FAIL(condition) ({					\206	int __ret = !!(condition);					\207	int __save_errno = errno;					\208	if (__ret) {							\209		test__fail();						\210		fprintf(stdout, "%s:FAIL:%d\n", __func__, __LINE__);	\211	}								\212	errno = __save_errno;						\213	__ret;								\214})215 216#define CHECK(condition, tag, format...) \217	_CHECK(condition, tag, duration, format)218#define CHECK_ATTR(condition, tag, format...) \219	_CHECK(condition, tag, tattr.duration, format)220 221#define ASSERT_FAIL(fmt, args...) ({					\222	static int duration = 0;					\223	CHECK(false, "", fmt"\n", ##args);				\224	false;								\225})226 227#define ASSERT_TRUE(actual, name) ({					\228	static int duration = 0;					\229	bool ___ok = (actual);						\230	CHECK(!___ok, (name), "unexpected %s: got FALSE\n", (name));	\231	___ok;								\232})233 234#define ASSERT_FALSE(actual, name) ({					\235	static int duration = 0;					\236	bool ___ok = !(actual);						\237	CHECK(!___ok, (name), "unexpected %s: got TRUE\n", (name));	\238	___ok;								\239})240 241#define ASSERT_EQ(actual, expected, name) ({				\242	static int duration = 0;					\243	typeof(actual) ___act = (actual);				\244	typeof(expected) ___exp = (expected);				\245	bool ___ok = ___act == ___exp;					\246	CHECK(!___ok, (name),						\247	      "unexpected %s: actual %lld != expected %lld\n",		\248	      (name), (long long)(___act), (long long)(___exp));	\249	___ok;								\250})251 252#define ASSERT_NEQ(actual, expected, name) ({				\253	static int duration = 0;					\254	typeof(actual) ___act = (actual);				\255	typeof(expected) ___exp = (expected);				\256	bool ___ok = ___act != ___exp;					\257	CHECK(!___ok, (name),						\258	      "unexpected %s: actual %lld == expected %lld\n",		\259	      (name), (long long)(___act), (long long)(___exp));	\260	___ok;								\261})262 263#define ASSERT_LT(actual, expected, name) ({				\264	static int duration = 0;					\265	typeof(actual) ___act = (actual);				\266	typeof(expected) ___exp = (expected);				\267	bool ___ok = ___act < ___exp;					\268	CHECK(!___ok, (name),						\269	      "unexpected %s: actual %lld >= expected %lld\n",		\270	      (name), (long long)(___act), (long long)(___exp));	\271	___ok;								\272})273 274#define ASSERT_LE(actual, expected, name) ({				\275	static int duration = 0;					\276	typeof(actual) ___act = (actual);				\277	typeof(expected) ___exp = (expected);				\278	bool ___ok = ___act <= ___exp;					\279	CHECK(!___ok, (name),						\280	      "unexpected %s: actual %lld > expected %lld\n",		\281	      (name), (long long)(___act), (long long)(___exp));	\282	___ok;								\283})284 285#define ASSERT_GT(actual, expected, name) ({				\286	static int duration = 0;					\287	typeof(actual) ___act = (actual);				\288	typeof(expected) ___exp = (expected);				\289	bool ___ok = ___act > ___exp;					\290	CHECK(!___ok, (name),						\291	      "unexpected %s: actual %lld <= expected %lld\n",		\292	      (name), (long long)(___act), (long long)(___exp));	\293	___ok;								\294})295 296#define ASSERT_GE(actual, expected, name) ({				\297	static int duration = 0;					\298	typeof(actual) ___act = (actual);				\299	typeof(expected) ___exp = (expected);				\300	bool ___ok = ___act >= ___exp;					\301	CHECK(!___ok, (name),						\302	      "unexpected %s: actual %lld < expected %lld\n",		\303	      (name), (long long)(___act), (long long)(___exp));	\304	___ok;								\305})306 307#define ASSERT_STREQ(actual, expected, name) ({				\308	static int duration = 0;					\309	const char *___act = actual;					\310	const char *___exp = expected;					\311	bool ___ok = strcmp(___act, ___exp) == 0;			\312	CHECK(!___ok, (name),						\313	      "unexpected %s: actual '%s' != expected '%s'\n",		\314	      (name), ___act, ___exp);					\315	___ok;								\316})317 318#define ASSERT_STRNEQ(actual, expected, len, name) ({			\319	static int duration = 0;					\320	const char *___act = actual;					\321	const char *___exp = expected;					\322	int ___len = len;						\323	bool ___ok = strncmp(___act, ___exp, ___len) == 0;		\324	CHECK(!___ok, (name),						\325	      "unexpected %s: actual '%.*s' != expected '%.*s'\n",	\326	      (name), ___len, ___act, ___len, ___exp);			\327	___ok;								\328})329 330#define ASSERT_HAS_SUBSTR(str, substr, name) ({				\331	static int duration = 0;					\332	const char *___str = str;					\333	const char *___substr = substr;					\334	bool ___ok = strstr(___str, ___substr) != NULL;			\335	CHECK(!___ok, (name),						\336	      "unexpected %s: '%s' is not a substring of '%s'\n",	\337	      (name), ___substr, ___str);				\338	___ok;								\339})340 341#define ASSERT_OK(res, name) ({						\342	static int duration = 0;					\343	long long ___res = (res);					\344	bool ___ok = ___res == 0;					\345	CHECK(!___ok, (name), "unexpected error: %lld (errno %d)\n",	\346	      ___res, errno);						\347	___ok;								\348})349 350#define ASSERT_ERR(res, name) ({					\351	static int duration = 0;					\352	long long ___res = (res);					\353	bool ___ok = ___res < 0;					\354	CHECK(!___ok, (name), "unexpected success: %lld\n", ___res);	\355	___ok;								\356})357 358#define ASSERT_NULL(ptr, name) ({					\359	static int duration = 0;					\360	const void *___res = (ptr);					\361	bool ___ok = !___res;						\362	CHECK(!___ok, (name), "unexpected pointer: %p\n", ___res);	\363	___ok;								\364})365 366#define ASSERT_OK_PTR(ptr, name) ({					\367	static int duration = 0;					\368	const void *___res = (ptr);					\369	int ___err = libbpf_get_error(___res);				\370	bool ___ok = ___err == 0;					\371	CHECK(!___ok, (name), "unexpected error: %d\n", ___err);	\372	___ok;								\373})374 375#define ASSERT_ERR_PTR(ptr, name) ({					\376	static int duration = 0;					\377	const void *___res = (ptr);					\378	int ___err = libbpf_get_error(___res);				\379	bool ___ok = ___err != 0;					\380	CHECK(!___ok, (name), "unexpected pointer: %p\n", ___res);	\381	___ok;								\382})383 384#define ASSERT_OK_FD(fd, name) ({					\385	static int duration = 0;					\386	int ___fd = (fd);						\387	bool ___ok = ___fd >= 0;					\388	CHECK(!___ok, (name), "unexpected fd: %d (errno %d)\n",		\389	      ___fd, errno);						\390	___ok;								\391})392 393#define SYS(goto_label, fmt, ...)					\394	({								\395		char cmd[1024];						\396		snprintf(cmd, sizeof(cmd), fmt, ##__VA_ARGS__);		\397		if (!ASSERT_OK(system(cmd), cmd))			\398			goto goto_label;				\399	})400 401#define ALL_TO_DEV_NULL " >/dev/null 2>&1"402 403#define SYS_NOFAIL(fmt, ...)						\404	({								\405		char cmd[1024];						\406		int n;							\407		n = snprintf(cmd, sizeof(cmd), fmt, ##__VA_ARGS__);	\408		if (n < sizeof(cmd) && sizeof(cmd) - n >= sizeof(ALL_TO_DEV_NULL)) \409			strcat(cmd, ALL_TO_DEV_NULL);			\410		system(cmd);						\411	})412 413int start_libbpf_log_capture(void);414char *stop_libbpf_log_capture(void);415 416static inline __u64 ptr_to_u64(const void *ptr)417{418	return (__u64) (unsigned long) ptr;419}420 421static inline void *u64_to_ptr(__u64 ptr)422{423	return (void *) (unsigned long) ptr;424}425 426int bpf_find_map(const char *test, struct bpf_object *obj, const char *name);427int compare_map_keys(int map1_fd, int map2_fd);428int compare_stack_ips(int smap_fd, int amap_fd, int stack_trace_len);429int trigger_module_test_read(int read_sz);430int trigger_module_test_write(int write_sz);431int write_sysctl(const char *sysctl, const char *value);432int get_bpf_max_tramp_links_from(struct btf *btf);433int get_bpf_max_tramp_links(void);434 435struct netns_obj;436struct netns_obj *netns_new(const char *name, bool open);437void netns_free(struct netns_obj *netns);438 439#ifdef __x86_64__440#define SYS_NANOSLEEP_KPROBE_NAME "__x64_sys_nanosleep"441#elif defined(__s390x__)442#define SYS_NANOSLEEP_KPROBE_NAME "__s390x_sys_nanosleep"443#elif defined(__aarch64__)444#define SYS_NANOSLEEP_KPROBE_NAME "__arm64_sys_nanosleep"445#elif defined(__riscv)446#define SYS_NANOSLEEP_KPROBE_NAME "__riscv_sys_nanosleep"447#else448#define SYS_NANOSLEEP_KPROBE_NAME "sys_nanosleep"449#endif450 451#define BPF_TESTMOD_TEST_FILE "/sys/kernel/bpf_testmod"452 453typedef int (*pre_execution_cb)(struct bpf_object *obj);454 455struct test_loader {456	char *log_buf;457	size_t log_buf_sz;458	pre_execution_cb pre_execution_cb;459 460	struct bpf_object *obj;461};462 463static inline void test_loader__set_pre_execution_cb(struct test_loader *tester,464						     pre_execution_cb cb)465{466	tester->pre_execution_cb = cb;467}468 469typedef const void *(*skel_elf_bytes_fn)(size_t *sz);470 471extern void test_loader__run_subtests(struct test_loader *tester,472				      const char *skel_name,473				      skel_elf_bytes_fn elf_bytes_factory);474 475extern void test_loader_fini(struct test_loader *tester);476 477#define RUN_TESTS(skel) ({						       \478	struct test_loader tester = {};					       \479									       \480	test_loader__run_subtests(&tester, #skel, skel##__elf_bytes);	       \481	test_loader_fini(&tester);					       \482})483 484#endif /* __TEST_PROGS_H */485