xref: /freebsd/sys/tests/ktest.h (revision 0eb0d2333546cc2af4027e43a5a254a0e2790dce)
13e5d0784SAlexander V. Chernikov /*-
23e5d0784SAlexander V. Chernikov  * SPDX-License-Identifier: BSD-2-Clause
33e5d0784SAlexander V. Chernikov  *
43e5d0784SAlexander V. Chernikov  * Copyright (c) 2023 Alexander V. Chernikov
53e5d0784SAlexander V. Chernikov  *
63e5d0784SAlexander V. Chernikov  * Redistribution and use in source and binary forms, with or without
73e5d0784SAlexander V. Chernikov  * modification, are permitted provided that the following conditions
83e5d0784SAlexander V. Chernikov  * are met:
93e5d0784SAlexander V. Chernikov  * 1. Redistributions of source code must retain the above copyright
103e5d0784SAlexander V. Chernikov  *    notice, this list of conditions and the following disclaimer.
113e5d0784SAlexander V. Chernikov  * 2. Redistributions in binary form must reproduce the above copyright
123e5d0784SAlexander V. Chernikov  *    notice, this list of conditions and the following disclaimer in the
133e5d0784SAlexander V. Chernikov  *    documentation and/or other materials provided with the distribution.
143e5d0784SAlexander V. Chernikov  *
153e5d0784SAlexander V. Chernikov  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
163e5d0784SAlexander V. Chernikov  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
173e5d0784SAlexander V. Chernikov  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
183e5d0784SAlexander V. Chernikov  * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
193e5d0784SAlexander V. Chernikov  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
203e5d0784SAlexander V. Chernikov  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
213e5d0784SAlexander V. Chernikov  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
223e5d0784SAlexander V. Chernikov  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
233e5d0784SAlexander V. Chernikov  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
243e5d0784SAlexander V. Chernikov  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
253e5d0784SAlexander V. Chernikov  * SUCH DAMAGE.
263e5d0784SAlexander V. Chernikov  */
273e5d0784SAlexander V. Chernikov 
283e5d0784SAlexander V. Chernikov #ifndef	SYS_TESTS_KTEST_H_
293e5d0784SAlexander V. Chernikov #define SYS_TESTS_KTEST_H_
303e5d0784SAlexander V. Chernikov 
313e5d0784SAlexander V. Chernikov #ifdef _KERNEL
323e5d0784SAlexander V. Chernikov 
333e5d0784SAlexander V. Chernikov #include <sys/param.h>
343e5d0784SAlexander V. Chernikov #include <sys/kernel.h>
353e5d0784SAlexander V. Chernikov #include <sys/module.h>
363e5d0784SAlexander V. Chernikov #include <sys/syslog.h>
373e5d0784SAlexander V. Chernikov 
383e5d0784SAlexander V. Chernikov struct nlattr;
393e5d0784SAlexander V. Chernikov struct nl_pstate;
403e5d0784SAlexander V. Chernikov struct nlmsghdr;
413e5d0784SAlexander V. Chernikov 
423e5d0784SAlexander V. Chernikov struct ktest_test_context {
433e5d0784SAlexander V. Chernikov 	void			*arg;
443e5d0784SAlexander V. Chernikov 	struct nl_pstate	*npt;
453e5d0784SAlexander V. Chernikov 	struct nlmsghdr		*hdr;
463e5d0784SAlexander V. Chernikov 	char			*buf;
473e5d0784SAlexander V. Chernikov 	size_t			bufsize;
483e5d0784SAlexander V. Chernikov };
493e5d0784SAlexander V. Chernikov 
503e5d0784SAlexander V. Chernikov typedef int (*ktest_run_t)(struct ktest_test_context *ctx);
513e5d0784SAlexander V. Chernikov typedef int (*ktest_parse_t)(struct ktest_test_context *ctx, struct nlattr *container);
523e5d0784SAlexander V. Chernikov 
533e5d0784SAlexander V. Chernikov struct ktest_test_info {
543e5d0784SAlexander V. Chernikov 	const char	*name;
553e5d0784SAlexander V. Chernikov 	const char	*desc;
563e5d0784SAlexander V. Chernikov 	ktest_run_t	func;
573e5d0784SAlexander V. Chernikov 	ktest_parse_t	parse;
583e5d0784SAlexander V. Chernikov };
593e5d0784SAlexander V. Chernikov 
603e5d0784SAlexander V. Chernikov struct ktest_module_info {
613e5d0784SAlexander V. Chernikov 	const char			*name;
623e5d0784SAlexander V. Chernikov 	const struct ktest_test_info	*tests;
633e5d0784SAlexander V. Chernikov 	int				num_tests;
643e5d0784SAlexander V. Chernikov 	void				*module_ptr;
653e5d0784SAlexander V. Chernikov };
663e5d0784SAlexander V. Chernikov 
673e5d0784SAlexander V. Chernikov int ktest_default_modevent(module_t mod, int type, void *arg);
683e5d0784SAlexander V. Chernikov 
693e5d0784SAlexander V. Chernikov bool ktest_start_msg(struct ktest_test_context *ctx);
703e5d0784SAlexander V. Chernikov void ktest_add_msg_meta(struct ktest_test_context *ctx, const char *func,
713e5d0784SAlexander V. Chernikov     const char *fname, int line);
723e5d0784SAlexander V. Chernikov void ktest_add_msg_text(struct ktest_test_context *ctx, int msg_level,
733e5d0784SAlexander V. Chernikov     const char *fmt, ...);
743e5d0784SAlexander V. Chernikov void ktest_end_msg(struct ktest_test_context *ctx);
753e5d0784SAlexander V. Chernikov 
763e5d0784SAlexander V. Chernikov #define	KTEST_LOG_LEVEL(_ctx, _l, _fmt, ...) {				\
773e5d0784SAlexander V. Chernikov 	if (ktest_start_msg(_ctx)) {					\
783e5d0784SAlexander V. Chernikov 		ktest_add_msg_meta(_ctx, __func__, __FILE__, __LINE__);	\
793e5d0784SAlexander V. Chernikov 		ktest_add_msg_text(_ctx, _l, _fmt, ## __VA_ARGS__);	\
803e5d0784SAlexander V. Chernikov 		ktest_end_msg(_ctx);					\
813e5d0784SAlexander V. Chernikov 	}								\
823e5d0784SAlexander V. Chernikov }
833e5d0784SAlexander V. Chernikov 
843e5d0784SAlexander V. Chernikov #define	KTEST_LOG(_ctx, _fmt, ...)					\
853e5d0784SAlexander V. Chernikov 	KTEST_LOG_LEVEL(_ctx, LOG_DEBUG, _fmt, ## __VA_ARGS__)
863e5d0784SAlexander V. Chernikov 
873e5d0784SAlexander V. Chernikov #define KTEST_MAX_BUF	512
883e5d0784SAlexander V. Chernikov 
893e5d0784SAlexander V. Chernikov #define	KTEST_MODULE_DECLARE(_n, _t) 					\
903e5d0784SAlexander V. Chernikov static struct ktest_module_info _module_info = {			\
913e5d0784SAlexander V. Chernikov 	.name = #_n,							\
923e5d0784SAlexander V. Chernikov 	.tests = _t,							\
933e5d0784SAlexander V. Chernikov 	.num_tests = nitems(_t),					\
943e5d0784SAlexander V. Chernikov };									\
953e5d0784SAlexander V. Chernikov 									\
963e5d0784SAlexander V. Chernikov static moduledata_t _module_data = {					\
97*0eb0d233SAlexander V. Chernikov         #_n,								\
983e5d0784SAlexander V. Chernikov         ktest_default_modevent,						\
993e5d0784SAlexander V. Chernikov         &_module_info,							\
1003e5d0784SAlexander V. Chernikov };									\
1013e5d0784SAlexander V. Chernikov 									\
1023e5d0784SAlexander V. Chernikov DECLARE_MODULE(ktest_##_n, _module_data, SI_SUB_PSEUDO, SI_ORDER_ANY);	\
1033e5d0784SAlexander V. Chernikov MODULE_VERSION(ktest_##_n, 1);						\
1043e5d0784SAlexander V. Chernikov MODULE_DEPEND(ktest_##_n, ktestmod, 1, 1, 1);				\
105*0eb0d233SAlexander V. Chernikov MODULE_DEPEND(ktest_##_n, netlink, 1, 1, 1);				\
1063e5d0784SAlexander V. Chernikov 
1073e5d0784SAlexander V. Chernikov #endif /* _KERNEL */
1083e5d0784SAlexander V. Chernikov 
1093e5d0784SAlexander V. Chernikov /* genetlink definitions */
1103e5d0784SAlexander V. Chernikov #define KTEST_FAMILY_NAME	"ktest"
1113e5d0784SAlexander V. Chernikov 
1123e5d0784SAlexander V. Chernikov /* commands */
1133e5d0784SAlexander V. Chernikov enum {
1143e5d0784SAlexander V. Chernikov 	KTEST_CMD_UNSPEC	= 0,
1153e5d0784SAlexander V. Chernikov 	KTEST_CMD_LIST		= 1,
1163e5d0784SAlexander V. Chernikov 	KTEST_CMD_RUN		= 2,
1173e5d0784SAlexander V. Chernikov 	KTEST_CMD_NEWTEST	= 3,
1183e5d0784SAlexander V. Chernikov 	KTEST_CMD_NEWMESSAGE	= 4,
1193e5d0784SAlexander V. Chernikov 	__KTEST_CMD_MAX,
1203e5d0784SAlexander V. Chernikov };
1213e5d0784SAlexander V. Chernikov #define	KTEST_CMD_MAX	(__KTEST_CMD_MAX - 1)
1223e5d0784SAlexander V. Chernikov 
1233e5d0784SAlexander V. Chernikov enum ktest_attr_type_t {
1243e5d0784SAlexander V. Chernikov 	KTEST_ATTR_UNSPEC,
1253e5d0784SAlexander V. Chernikov 	KTEST_ATTR_MOD_NAME	= 1,	/* string: test module name */
1263e5d0784SAlexander V. Chernikov 	KTEST_ATTR_TEST_NAME	= 2,	/* string: test name */
1273e5d0784SAlexander V. Chernikov 	KTEST_ATTR_TEST_DESCR	= 3,	/* string: test description */
1283e5d0784SAlexander V. Chernikov 	KTEST_ATTR_TEST_META	= 4,	/* nested: container with test-specific metadata */
1293e5d0784SAlexander V. Chernikov };
1303e5d0784SAlexander V. Chernikov 
1313e5d0784SAlexander V. Chernikov enum ktest_msg_attr_type_t {
1323e5d0784SAlexander V. Chernikov 	KTEST_MSG_ATTR_UNSPEC,
1333e5d0784SAlexander V. Chernikov 	KTEST_MSG_ATTR_TS	= 1,	/* struct timespec */
1343e5d0784SAlexander V. Chernikov 	KTEST_MSG_ATTR_FUNC	= 2,	/* string: function name */
1353e5d0784SAlexander V. Chernikov 	KTEST_MSG_ATTR_FILE	= 3,	/* string: file name */
1363e5d0784SAlexander V. Chernikov 	KTEST_MSG_ATTR_LINE	= 4,	/* u32: line in the file */
1373e5d0784SAlexander V. Chernikov 	KTEST_MSG_ATTR_TEXT	= 5,	/* string: actual message data */
1383e5d0784SAlexander V. Chernikov 	KTEST_MSG_ATTR_LEVEL	= 6,	/* u8: syslog loglevel */
1393e5d0784SAlexander V. Chernikov 	KTEST_MSG_ATTR_META	= 7,	/* nested: message metadata */
1403e5d0784SAlexander V. Chernikov };
1413e5d0784SAlexander V. Chernikov 
1423e5d0784SAlexander V. Chernikov #endif
143