xref: /illumos-gate/usr/src/uts/common/io/ktest/ktest_selftest.c (revision 08855964b9970604433f7b19dcd71cf5af5e5f14)
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