xref: /freebsd/sys/tests/ktest.h (revision e0c4386e7e71d93b0edc0c8fa156263fc4a8b0b6)
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 struct ktest_module_info {
61 	const char			*name;
62 	const struct ktest_test_info	*tests;
63 	int				num_tests;
64 	void				*module_ptr;
65 };
66 
67 int ktest_default_modevent(module_t mod, int type, void *arg);
68 
69 bool ktest_start_msg(struct ktest_test_context *ctx);
70 void ktest_add_msg_meta(struct ktest_test_context *ctx, const char *func,
71     const char *fname, int line);
72 void ktest_add_msg_text(struct ktest_test_context *ctx, int msg_level,
73     const char *fmt, ...);
74 void ktest_end_msg(struct ktest_test_context *ctx);
75 
76 #define	KTEST_LOG_LEVEL(_ctx, _l, _fmt, ...) {				\
77 	if (ktest_start_msg(_ctx)) {					\
78 		ktest_add_msg_meta(_ctx, __func__, __FILE__, __LINE__);	\
79 		ktest_add_msg_text(_ctx, _l, _fmt, ## __VA_ARGS__);	\
80 		ktest_end_msg(_ctx);					\
81 	}								\
82 }
83 
84 #define	KTEST_LOG(_ctx, _fmt, ...)					\
85 	KTEST_LOG_LEVEL(_ctx, LOG_DEBUG, _fmt, ## __VA_ARGS__)
86 
87 #define KTEST_MAX_BUF	512
88 
89 #define	KTEST_MODULE_DECLARE(_n, _t) 					\
90 static struct ktest_module_info _module_info = {			\
91 	.name = #_n,							\
92 	.tests = _t,							\
93 	.num_tests = nitems(_t),					\
94 };									\
95 									\
96 static moduledata_t _module_data = {					\
97         #_n,								\
98         ktest_default_modevent,						\
99         &_module_info,							\
100 };									\
101 									\
102 DECLARE_MODULE(ktest_##_n, _module_data, SI_SUB_PSEUDO, SI_ORDER_ANY);	\
103 MODULE_VERSION(ktest_##_n, 1);						\
104 MODULE_DEPEND(ktest_##_n, ktestmod, 1, 1, 1);				\
105 MODULE_DEPEND(ktest_##_n, netlink, 1, 1, 1);				\
106 
107 #endif /* _KERNEL */
108 
109 /* genetlink definitions */
110 #define KTEST_FAMILY_NAME	"ktest"
111 
112 /* commands */
113 enum {
114 	KTEST_CMD_UNSPEC	= 0,
115 	KTEST_CMD_LIST		= 1,
116 	KTEST_CMD_RUN		= 2,
117 	KTEST_CMD_NEWTEST	= 3,
118 	KTEST_CMD_NEWMESSAGE	= 4,
119 	__KTEST_CMD_MAX,
120 };
121 #define	KTEST_CMD_MAX	(__KTEST_CMD_MAX - 1)
122 
123 enum ktest_attr_type_t {
124 	KTEST_ATTR_UNSPEC,
125 	KTEST_ATTR_MOD_NAME	= 1,	/* string: test module name */
126 	KTEST_ATTR_TEST_NAME	= 2,	/* string: test name */
127 	KTEST_ATTR_TEST_DESCR	= 3,	/* string: test description */
128 	KTEST_ATTR_TEST_META	= 4,	/* nested: container with test-specific metadata */
129 };
130 
131 enum ktest_msg_attr_type_t {
132 	KTEST_MSG_ATTR_UNSPEC,
133 	KTEST_MSG_ATTR_TS	= 1,	/* struct timespec */
134 	KTEST_MSG_ATTR_FUNC	= 2,	/* string: function name */
135 	KTEST_MSG_ATTR_FILE	= 3,	/* string: file name */
136 	KTEST_MSG_ATTR_LINE	= 4,	/* u32: line in the file */
137 	KTEST_MSG_ATTR_TEXT	= 5,	/* string: actual message data */
138 	KTEST_MSG_ATTR_LEVEL	= 6,	/* u8: syslog loglevel */
139 	KTEST_MSG_ATTR_META	= 7,	/* nested: message metadata */
140 };
141 
142 #endif
143