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 23 ktest_st_pass_test(ktest_ctx_hdl_t *ctx) 24 { 25 KT_PASS(ctx); 26 } 27 28 static boolean_t 29 ktest_st_is_even(int x) 30 { 31 return ((x % 2) == 0); 32 } 33 34 void 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 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 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 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 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 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 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 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 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 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 235 _fini(void) 236 { 237 ktest_unregister_module("ktest"); 238 return (mod_remove(&ktest_selftest_modlinkage)); 239 } 240 241 int 242 _info(struct modinfo *modinfop) 243 { 244 return (mod_info(&ktest_selftest_modlinkage, modinfop)); 245 } 246