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
38struct nlattr;
39struct nl_pstate;
40struct nlmsghdr;
41
42struct ktest_test_context {
43	void			*arg;
44	struct nl_pstate	*npt;
45	struct nlmsghdr		*hdr;
46	char			*buf;
47	size_t			bufsize;
48};
49
50typedef int (*ktest_run_t)(struct ktest_test_context *ctx);
51typedef int (*ktest_parse_t)(struct ktest_test_context *ctx, struct nlattr *container);
52
53struct ktest_test_info {
54	const char	*name;
55	const char	*desc;
56	ktest_run_t	func;
57	ktest_parse_t	parse;
58};
59
60struct ktest_module_info {
61	const char			*name;
62	const struct ktest_test_info	*tests;
63	int				num_tests;
64	void				*module_ptr;
65};
66
67int ktest_default_modevent(module_t mod, int type, void *arg);
68
69bool ktest_start_msg(struct ktest_test_context *ctx);
70void ktest_add_msg_meta(struct ktest_test_context *ctx, const char *func,
71    const char *fname, int line);
72void ktest_add_msg_text(struct ktest_test_context *ctx, int msg_level,
73    const char *fmt, ...);
74void 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) 					\
90static struct ktest_module_info _module_info = {			\
91	.name = #_n,							\
92	.tests = _t,							\
93	.num_tests = nitems(_t),					\
94};									\
95									\
96static moduledata_t _module_data = {					\
97        #_n,								\
98        ktest_default_modevent,						\
99        &_module_info,							\
100};									\
101									\
102DECLARE_MODULE(ktest_##_n, _module_data, SI_SUB_PSEUDO, SI_ORDER_ANY);	\
103MODULE_VERSION(ktest_##_n, 1);						\
104MODULE_DEPEND(ktest_##_n, ktestmod, 1, 1, 1);				\
105MODULE_DEPEND(ktest_##_n, netlink, 1, 1, 1);				\
106
107#endif /* _KERNEL */
108
109/* genetlink definitions */
110#define KTEST_FAMILY_NAME	"ktest"
111
112/* commands */
113enum {
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
123enum 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
131enum 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