xref: /freebsd/sys/tests/ktest.h (revision bfdd5b643d23171c53920accc2f15f78e984dfae)
1 /*-
2  * SPDX-License-Identifier: BSD-2-Clause
3  *
4  * Copyright (c) 2023 Alexander V. Chernikov
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  * 1. Redistributions of source code must retain the above copyright
10  *    notice, this list of conditions and the following disclaimer.
11  * 2. Redistributions in binary form must reproduce the above copyright
12  *    notice, this list of conditions and the following disclaimer in the
13  *    documentation and/or other materials provided with the distribution.
14  *
15  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18  * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25  * SUCH DAMAGE.
26  */
27 
28 #ifndef	SYS_TESTS_KTEST_H_
29 #define SYS_TESTS_KTEST_H_
30 
31 #ifdef _KERNEL
32 
33 #include <sys/param.h>
34 #include <sys/kernel.h>
35 #include <sys/module.h>
36 #include <sys/syslog.h>
37 
38 struct nlattr;
39 struct nl_pstate;
40 struct nlmsghdr;
41 
42 struct ktest_test_context {
43 	void			*arg;
44 	struct nl_pstate	*npt;
45 	struct nlmsghdr		*hdr;
46 	char			*buf;
47 	size_t			bufsize;
48 };
49 
50 typedef int (*ktest_run_t)(struct ktest_test_context *ctx);
51 typedef int (*ktest_parse_t)(struct ktest_test_context *ctx, struct nlattr *container);
52 
53 struct ktest_test_info {
54 	const char	*name;
55 	const char	*desc;
56 	ktest_run_t	func;
57 	ktest_parse_t	parse;
58 };
59 
60 #define KTEST_FUNC(X) static int __ktest_##X(struct ktest_test_context *ctx)
61 
62 struct ktest_module_info {
63 	const char			*name;
64 	const struct ktest_test_info	*tests;
65 	int				num_tests;
66 	void				*module_ptr;
67 };
68 
69 #define KTEST_INFO(X) { "test_" #X, "Test " #X, __ktest_##X, NULL }
70 
71 int ktest_default_modevent(module_t mod, int type, void *arg);
72 
73 bool ktest_start_msg(struct ktest_test_context *ctx);
74 void ktest_add_msg_meta(struct ktest_test_context *ctx, const char *func,
75     const char *fname, int line);
76 void ktest_add_msg_text(struct ktest_test_context *ctx, int msg_level,
77     const char *fmt, ...);
78 void ktest_end_msg(struct ktest_test_context *ctx);
79 
80 #define	KTEST_LOG_LEVEL(_ctx, _l, _fmt, ...) {				\
81 	if (ktest_start_msg(_ctx)) {					\
82 		ktest_add_msg_meta(_ctx, __func__, __FILE__, __LINE__);	\
83 		ktest_add_msg_text(_ctx, _l, _fmt, ## __VA_ARGS__);	\
84 		ktest_end_msg(_ctx);					\
85 	}								\
86 }
87 
88 #define	KTEST_LOG(_ctx, _fmt, ...)					\
89 	KTEST_LOG_LEVEL(_ctx, LOG_DEBUG, _fmt, ## __VA_ARGS__)
90 
91 #define	KTEST_ERR(_ctx, _fmt, ...)	\
92 	KTEST_LOG_LEVEL(_ctx, LOG_ERR, _fmt, ## __VA_ARGS__)
93 
94 #define KTEST_MAX_BUF	512
95 
96 #define	KTEST_MODULE_DECLARE(_n, _t) 					\
97 static struct ktest_module_info _module_info = {			\
98 	.name = #_n,							\
99 	.tests = _t,							\
100 	.num_tests = nitems(_t),					\
101 };									\
102 									\
103 static moduledata_t _module_data = {					\
104         #_n,								\
105         ktest_default_modevent,						\
106         &_module_info,							\
107 };									\
108 									\
109 DECLARE_MODULE(ktest_##_n, _module_data, SI_SUB_PSEUDO, SI_ORDER_ANY);	\
110 MODULE_VERSION(ktest_##_n, 1);						\
111 MODULE_DEPEND(ktest_##_n, ktestmod, 1, 1, 1);				\
112 MODULE_DEPEND(ktest_##_n, netlink, 1, 1, 1);				\
113 
114 #define	KTEST_MODULE_DEPEND(_n, _d)		\
115 MODULE_DEPEND(ktest_##_n, _d, 1, 1, 1);	\
116 
117 #endif /* _KERNEL */
118 
119 /* genetlink definitions */
120 #define KTEST_FAMILY_NAME	"ktest"
121 
122 /* commands */
123 enum {
124 	KTEST_CMD_UNSPEC	= 0,
125 	KTEST_CMD_LIST		= 1,
126 	KTEST_CMD_RUN		= 2,
127 	KTEST_CMD_NEWTEST	= 3,
128 	KTEST_CMD_NEWMESSAGE	= 4,
129 	__KTEST_CMD_MAX,
130 };
131 #define	KTEST_CMD_MAX	(__KTEST_CMD_MAX - 1)
132 
133 enum ktest_attr_type_t {
134 	KTEST_ATTR_UNSPEC,
135 	KTEST_ATTR_MOD_NAME	= 1,	/* string: test module name */
136 	KTEST_ATTR_TEST_NAME	= 2,	/* string: test name */
137 	KTEST_ATTR_TEST_DESCR	= 3,	/* string: test description */
138 	KTEST_ATTR_TEST_META	= 4,	/* nested: container with test-specific metadata */
139 };
140 
141 enum ktest_msg_attr_type_t {
142 	KTEST_MSG_ATTR_UNSPEC,
143 	KTEST_MSG_ATTR_TS	= 1,	/* struct timespec */
144 	KTEST_MSG_ATTR_FUNC	= 2,	/* string: function name */
145 	KTEST_MSG_ATTR_FILE	= 3,	/* string: file name */
146 	KTEST_MSG_ATTR_LINE	= 4,	/* u32: line in the file */
147 	KTEST_MSG_ATTR_TEXT	= 5,	/* string: actual message data */
148 	KTEST_MSG_ATTR_LEVEL	= 6,	/* u8: syslog loglevel */
149 	KTEST_MSG_ATTR_META	= 7,	/* nested: message metadata */
150 };
151 
152 #endif
153