1*08855964SRyan Zezeski /*
2*08855964SRyan Zezeski * This file and its contents are supplied under the terms of the
3*08855964SRyan Zezeski * Common Development and Distribution License ("CDDL"), version 1.0.
4*08855964SRyan Zezeski * You may only use this file in accordance with the terms of version
5*08855964SRyan Zezeski * 1.0 of the CDDL.
6*08855964SRyan Zezeski *
7*08855964SRyan Zezeski * A full copy of the text of the CDDL should have accompanied this
8*08855964SRyan Zezeski * source. A copy of the CDDL is also available via the Internet at
9*08855964SRyan Zezeski * http://www.illumos.org/license/CDDL.
10*08855964SRyan Zezeski */
11*08855964SRyan Zezeski
12*08855964SRyan Zezeski /*
13*08855964SRyan Zezeski * Copyright 2023 Oxide Computer Company
14*08855964SRyan Zezeski * Copyright 2024 Ryan Zezeski
15*08855964SRyan Zezeski */
16*08855964SRyan Zezeski
17*08855964SRyan Zezeski /*
18*08855964SRyan Zezeski * The ktest self test. Make sure the basics work.
19*08855964SRyan Zezeski */
20*08855964SRyan Zezeski #include <sys/ktest.h>
21*08855964SRyan Zezeski
22*08855964SRyan Zezeski void
ktest_st_pass_test(ktest_ctx_hdl_t * ctx)23*08855964SRyan Zezeski ktest_st_pass_test(ktest_ctx_hdl_t *ctx)
24*08855964SRyan Zezeski {
25*08855964SRyan Zezeski KT_PASS(ctx);
26*08855964SRyan Zezeski }
27*08855964SRyan Zezeski
28*08855964SRyan Zezeski static boolean_t
ktest_st_is_even(int x)29*08855964SRyan Zezeski ktest_st_is_even(int x)
30*08855964SRyan Zezeski {
31*08855964SRyan Zezeski return ((x % 2) == 0);
32*08855964SRyan Zezeski }
33*08855964SRyan Zezeski
34*08855964SRyan Zezeski void
ktest_st_fail_test(ktest_ctx_hdl_t * ctx)35*08855964SRyan Zezeski ktest_st_fail_test(ktest_ctx_hdl_t *ctx)
36*08855964SRyan Zezeski {
37*08855964SRyan Zezeski KT_ASSERT(ktest_st_is_even(5), ctx);
38*08855964SRyan Zezeski KT_PASS(ctx);
39*08855964SRyan Zezeski }
40*08855964SRyan Zezeski
41*08855964SRyan Zezeski static int
ktest_st_pretend_func(int input)42*08855964SRyan Zezeski ktest_st_pretend_func(int input)
43*08855964SRyan Zezeski {
44*08855964SRyan Zezeski if (input == 42) {
45*08855964SRyan Zezeski return (0);
46*08855964SRyan Zezeski }
47*08855964SRyan Zezeski
48*08855964SRyan Zezeski return (-1);
49*08855964SRyan Zezeski }
50*08855964SRyan Zezeski
51*08855964SRyan Zezeski /*
52*08855964SRyan Zezeski * This test should report a NONE result as it never touches the
53*08855964SRyan Zezeski * context.
54*08855964SRyan Zezeski */
55*08855964SRyan Zezeski void
ktest_st_none_test(ktest_ctx_hdl_t * ctx)56*08855964SRyan Zezeski ktest_st_none_test(ktest_ctx_hdl_t *ctx)
57*08855964SRyan Zezeski {
58*08855964SRyan Zezeski (void) ktest_st_pretend_func(7);
59*08855964SRyan Zezeski }
60*08855964SRyan Zezeski
61*08855964SRyan Zezeski /*
62*08855964SRyan Zezeski * This test should report an ERROR result.
63*08855964SRyan Zezeski */
64*08855964SRyan Zezeski void
ktest_st_err_test(ktest_ctx_hdl_t * ctx)65*08855964SRyan Zezeski ktest_st_err_test(ktest_ctx_hdl_t *ctx)
66*08855964SRyan Zezeski {
67*08855964SRyan Zezeski KT_EASSERT0(ktest_st_pretend_func(7), ctx);
68*08855964SRyan Zezeski }
69*08855964SRyan Zezeski
70*08855964SRyan Zezeski /*
71*08855964SRyan Zezeski * This test should report a SKIP result.
72*08855964SRyan Zezeski */
73*08855964SRyan Zezeski void
ktest_st_skip_test(ktest_ctx_hdl_t * ctx)74*08855964SRyan Zezeski ktest_st_skip_test(ktest_ctx_hdl_t *ctx)
75*08855964SRyan Zezeski {
76*08855964SRyan Zezeski KT_SKIP(ctx, "This test should be skipped.");
77*08855964SRyan Zezeski }
78*08855964SRyan Zezeski
79*08855964SRyan Zezeski /*
80*08855964SRyan Zezeski * This test should only run when given an input stream.
81*08855964SRyan Zezeski */
82*08855964SRyan Zezeski void
ktest_st_input_test(ktest_ctx_hdl_t * ctx)83*08855964SRyan Zezeski ktest_st_input_test(ktest_ctx_hdl_t *ctx)
84*08855964SRyan Zezeski {
85*08855964SRyan Zezeski uchar_t *bytes;
86*08855964SRyan Zezeski size_t num_bytes = 0;
87*08855964SRyan Zezeski
88*08855964SRyan Zezeski ktest_get_input(ctx, &bytes, &num_bytes);
89*08855964SRyan Zezeski
90*08855964SRyan Zezeski if (num_bytes < 4) {
91*08855964SRyan Zezeski KT_ERROR(ctx, "expected 4 or more bytes, got %u", num_bytes);
92*08855964SRyan Zezeski return;
93*08855964SRyan Zezeski }
94*08855964SRyan Zezeski
95*08855964SRyan Zezeski cmn_err(CE_WARN, "bytes (%lu): 0x%x 0x%x 0x%x 0x%x",
96*08855964SRyan Zezeski num_bytes, bytes[0], bytes[1], bytes[2],
97*08855964SRyan Zezeski bytes[3]);
98*08855964SRyan Zezeski
99*08855964SRyan Zezeski KT_PASS(ctx);
100*08855964SRyan Zezeski }
101*08855964SRyan Zezeski
102*08855964SRyan Zezeski /*
103*08855964SRyan Zezeski * Verify that ktest catches multiple results and returns an error to
104*08855964SRyan Zezeski * alert the user.
105*08855964SRyan Zezeski */
106*08855964SRyan Zezeski void
ktest_st_mult_result_test(ktest_ctx_hdl_t * ctx)107*08855964SRyan Zezeski ktest_st_mult_result_test(ktest_ctx_hdl_t *ctx)
108*08855964SRyan Zezeski {
109*08855964SRyan Zezeski KT_FAIL(ctx, "this is a fail result");
110*08855964SRyan Zezeski KT_PASS(ctx);
111*08855964SRyan Zezeski }
112*08855964SRyan Zezeski
113*08855964SRyan Zezeski /*
114*08855964SRyan Zezeski * Verify the suite and test name uniqueness is enforced. Module name
115*08855964SRyan Zezeski * uniqueness is tested in _init().
116*08855964SRyan Zezeski */
117*08855964SRyan Zezeski void
ktest_st_unique_test(ktest_ctx_hdl_t * ctx)118*08855964SRyan Zezeski ktest_st_unique_test(ktest_ctx_hdl_t *ctx)
119*08855964SRyan Zezeski {
120*08855964SRyan Zezeski ktest_module_hdl_t *km = NULL;
121*08855964SRyan Zezeski ktest_suite_hdl_t *ks = NULL;
122*08855964SRyan Zezeski
123*08855964SRyan Zezeski KT_ASSERT0(ktest_create_module("ktest", &km), ctx);
124*08855964SRyan Zezeski KT_ASSERT0G(ktest_add_suite(km, "selftest", &ks), ctx, cleanup);
125*08855964SRyan Zezeski KT_ASSERT3SG(ktest_add_suite(km, "selftest", &ks), ==, EEXIST, ctx,
126*08855964SRyan Zezeski cleanup);
127*08855964SRyan Zezeski KT_ASSERT0G(ktest_add_test(ks, "ktest_st_pass_test", ktest_st_pass_test,
128*08855964SRyan Zezeski KTEST_FLAG_NONE), ctx, cleanup);
129*08855964SRyan Zezeski KT_ASSERTG(ktest_add_test(ks, "ktest_st_pass_test", ktest_st_pass_test,
130*08855964SRyan Zezeski KTEST_FLAG_NONE) == EEXIST, ctx, cleanup);
131*08855964SRyan Zezeski
132*08855964SRyan Zezeski KT_PASS(ctx);
133*08855964SRyan Zezeski
134*08855964SRyan Zezeski cleanup:
135*08855964SRyan Zezeski ktest_free_module(km);
136*08855964SRyan Zezeski }
137*08855964SRyan Zezeski
138*08855964SRyan Zezeski void
ktest_st_name_test(ktest_ctx_hdl_t * ctx)139*08855964SRyan Zezeski ktest_st_name_test(ktest_ctx_hdl_t *ctx)
140*08855964SRyan Zezeski {
141*08855964SRyan Zezeski ktest_module_hdl_t *km = NULL;
142*08855964SRyan Zezeski
143*08855964SRyan Zezeski KT_ASSERT3SG(ktest_create_module("bad:name", &km), ==, EINVAL, ctx,
144*08855964SRyan Zezeski cleanup);
145*08855964SRyan Zezeski KT_ASSERT3SG(ktest_create_module("bad/name", &km), ==, EINVAL, ctx,
146*08855964SRyan Zezeski cleanup);
147*08855964SRyan Zezeski KT_ASSERT3SG(ktest_create_module("bad?name", &km), ==, EINVAL, ctx,
148*08855964SRyan Zezeski cleanup);
149*08855964SRyan Zezeski KT_ASSERT3SG(ktest_create_module("bad name", &km), ==, EINVAL, ctx,
150*08855964SRyan Zezeski cleanup);
151*08855964SRyan Zezeski KT_ASSERT3SG(ktest_create_module("bad>name", &km), ==, EINVAL, ctx,
152*08855964SRyan Zezeski cleanup);
153*08855964SRyan Zezeski KT_ASSERT3SG(ktest_create_module("bad<name", &km), ==, EINVAL, ctx,
154*08855964SRyan Zezeski cleanup);
155*08855964SRyan Zezeski KT_ASSERT3SG(ktest_create_module("bad&name", &km), ==, EINVAL, ctx,
156*08855964SRyan Zezeski cleanup);
157*08855964SRyan Zezeski KT_ASSERT3SG(ktest_create_module("bad*name", &km), ==, EINVAL, ctx,
158*08855964SRyan Zezeski cleanup);
159*08855964SRyan Zezeski
160*08855964SRyan Zezeski KT_ASSERT0G(ktest_create_module("good_name", &km), ctx, cleanup);
161*08855964SRyan Zezeski ktest_free_module(km);
162*08855964SRyan Zezeski KT_ASSERT0G(ktest_create_module("good_name02", &km), ctx, cleanup);
163*08855964SRyan Zezeski ktest_free_module(km);
164*08855964SRyan Zezeski KT_ASSERT0G(ktest_create_module("good.name02", &km), ctx, cleanup);
165*08855964SRyan Zezeski ktest_free_module(km);
166*08855964SRyan Zezeski KT_ASSERT0G(ktest_create_module("_l33t.n4m3", &km), ctx, cleanup);
167*08855964SRyan Zezeski
168*08855964SRyan Zezeski KT_PASS(ctx);
169*08855964SRyan Zezeski
170*08855964SRyan Zezeski cleanup:
171*08855964SRyan Zezeski ktest_free_module(km);
172*08855964SRyan Zezeski }
173*08855964SRyan Zezeski
174*08855964SRyan Zezeski static struct modlmisc ktest_selftest_modlmisc = {
175*08855964SRyan Zezeski .misc_modops = &mod_miscops,
176*08855964SRyan Zezeski .misc_linkinfo = "ktest selftest module"
177*08855964SRyan Zezeski };
178*08855964SRyan Zezeski
179*08855964SRyan Zezeski static struct modlinkage ktest_selftest_modlinkage = {
180*08855964SRyan Zezeski .ml_rev = MODREV_1,
181*08855964SRyan Zezeski .ml_linkage = { &ktest_selftest_modlmisc, NULL }
182*08855964SRyan Zezeski };
183*08855964SRyan Zezeski
184*08855964SRyan Zezeski int
_init()185*08855964SRyan Zezeski _init()
186*08855964SRyan Zezeski {
187*08855964SRyan Zezeski int ret;
188*08855964SRyan Zezeski ktest_module_hdl_t *km = NULL;
189*08855964SRyan Zezeski ktest_suite_hdl_t *ks = NULL;
190*08855964SRyan Zezeski
191*08855964SRyan Zezeski VERIFY0(ktest_create_module("ktest", &km));
192*08855964SRyan Zezeski VERIFY0(ktest_add_suite(km, "selftest", &ks));
193*08855964SRyan Zezeski VERIFY0(ktest_add_test(ks, "ktest_st_none_test", ktest_st_none_test,
194*08855964SRyan Zezeski KTEST_FLAG_NONE));
195*08855964SRyan Zezeski VERIFY0(ktest_add_test(ks, "ktest_st_pass_test", ktest_st_pass_test,
196*08855964SRyan Zezeski KTEST_FLAG_NONE));
197*08855964SRyan Zezeski VERIFY0(ktest_add_test(ks, "ktest_st_fail_test", ktest_st_fail_test,
198*08855964SRyan Zezeski KTEST_FLAG_NONE));
199*08855964SRyan Zezeski VERIFY0(ktest_add_test(ks, "ktest_st_err_test", ktest_st_err_test,
200*08855964SRyan Zezeski KTEST_FLAG_NONE));
201*08855964SRyan Zezeski VERIFY0(ktest_add_test(ks, "ktest_st_skip_test", ktest_st_skip_test,
202*08855964SRyan Zezeski KTEST_FLAG_NONE));
203*08855964SRyan Zezeski VERIFY0(ktest_add_test(ks, "ktest_st_input_test", ktest_st_input_test,
204*08855964SRyan Zezeski KTEST_FLAG_INPUT));
205*08855964SRyan Zezeski VERIFY0(ktest_add_test(ks, "ktest_st_mult_result_test",
206*08855964SRyan Zezeski ktest_st_mult_result_test, KTEST_FLAG_NONE));
207*08855964SRyan Zezeski VERIFY0(ktest_add_test(ks, "ktest_st_unique_test",
208*08855964SRyan Zezeski ktest_st_unique_test, KTEST_FLAG_NONE));
209*08855964SRyan Zezeski VERIFY0(ktest_add_test(ks, "ktest_st_name_test",
210*08855964SRyan Zezeski ktest_st_name_test, KTEST_FLAG_NONE));
211*08855964SRyan Zezeski
212*08855964SRyan Zezeski if ((ret = ktest_register_module(km)) != 0) {
213*08855964SRyan Zezeski ktest_free_module(km);
214*08855964SRyan Zezeski return (ret);
215*08855964SRyan Zezeski }
216*08855964SRyan Zezeski
217*08855964SRyan Zezeski /*
218*08855964SRyan Zezeski * It would be nice to test this in ktest_st_test_unique(),
219*08855964SRyan Zezeski * but we can't because this call grabs the ktest_lock, and
220*08855964SRyan Zezeski * the lock is already held while a test is running. If you
221*08855964SRyan Zezeski * see a panic here, check ktest_register_module() to make
222*08855964SRyan Zezeski * sure it's enforcing module name uniqueness.
223*08855964SRyan Zezeski */
224*08855964SRyan Zezeski VERIFY(ktest_register_module(km) == EEXIST);
225*08855964SRyan Zezeski
226*08855964SRyan Zezeski if ((ret = mod_install(&ktest_selftest_modlinkage)) != 0) {
227*08855964SRyan Zezeski ktest_unregister_module("ktest");
228*08855964SRyan Zezeski return (ret);
229*08855964SRyan Zezeski }
230*08855964SRyan Zezeski
231*08855964SRyan Zezeski return (0);
232*08855964SRyan Zezeski }
233*08855964SRyan Zezeski
234*08855964SRyan Zezeski int
_fini(void)235*08855964SRyan Zezeski _fini(void)
236*08855964SRyan Zezeski {
237*08855964SRyan Zezeski ktest_unregister_module("ktest");
238*08855964SRyan Zezeski return (mod_remove(&ktest_selftest_modlinkage));
239*08855964SRyan Zezeski }
240*08855964SRyan Zezeski
241*08855964SRyan Zezeski int
_info(struct modinfo * modinfop)242*08855964SRyan Zezeski _info(struct modinfo *modinfop)
243*08855964SRyan Zezeski {
244*08855964SRyan Zezeski return (mod_info(&ktest_selftest_modlinkage, modinfop));
245*08855964SRyan Zezeski }
246