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