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