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 2025 Oxide Computer Company 14 */ 15 16 /* 17 * Namespace Management unit tests. 18 */ 19 20 #include <stdlib.h> 21 #include <sys/sysmacros.h> 22 #include <err.h> 23 24 #include "nvme_unit.h" 25 26 static const nvme_unit_field_test_t ns_attach_field_tests[] = { { 27 .nu_desc = "invalid selector (1)", 28 .nu_fields = nvme_ns_attach_fields, 29 .nu_index = NVME_NS_ATTACH_REQ_FIELD_SEL, 30 .nu_data = &nvme_ctrl_ns_1v2, 31 .nu_value = 0x7777, 32 .nu_ret = NVME_FIELD_ERR_BAD_VALUE 33 }, { 34 .nu_desc = "invalid selector (2)", 35 .nu_fields = nvme_ns_attach_fields, 36 .nu_index = NVME_NS_ATTACH_REQ_FIELD_SEL, 37 .nu_data = &nvme_ctrl_ns_1v2, 38 .nu_value = NVME_NS_ATTACH_CTRL_DETACH + 1, 39 .nu_ret = NVME_FIELD_ERR_BAD_VALUE 40 }, { 41 .nu_desc = "valid selector (1)", 42 .nu_fields = nvme_ns_attach_fields, 43 .nu_index = NVME_NS_ATTACH_REQ_FIELD_SEL, 44 .nu_data = &nvme_ctrl_ns_1v2, 45 .nu_value = NVME_NS_ATTACH_CTRL_DETACH, 46 .nu_ret = NVME_FIELD_ERR_OK 47 }, { 48 .nu_desc = "valid selector (2)", 49 .nu_fields = nvme_ns_attach_fields, 50 .nu_index = NVME_NS_ATTACH_REQ_FIELD_SEL, 51 .nu_data = &nvme_ctrl_ns_1v2, 52 .nu_value = NVME_NS_ATTACH_CTRL_ATTACH, 53 .nu_ret = NVME_FIELD_ERR_OK 54 }, { 55 .nu_desc = "invalid NSID (1)", 56 .nu_fields = nvme_ns_attach_fields, 57 .nu_index = NVME_NS_ATTACH_REQ_FIELD_NSID, 58 .nu_data = &nvme_ctrl_ns_1v2, 59 .nu_value = 0x0, 60 .nu_ret = NVME_FIELD_ERR_BAD_VALUE 61 }, { 62 .nu_desc = "invalid NSID (2)", 63 .nu_fields = nvme_ns_attach_fields, 64 .nu_index = NVME_NS_ATTACH_REQ_FIELD_NSID, 65 .nu_data = &nvme_ctrl_ns_1v2, 66 .nu_value = 0x7777, 67 .nu_ret = NVME_FIELD_ERR_BAD_VALUE 68 }, { 69 .nu_desc = "valid NSID (1)", 70 .nu_fields = nvme_ns_attach_fields, 71 .nu_index = NVME_NS_ATTACH_REQ_FIELD_NSID, 72 .nu_data = &nvme_ctrl_ns_1v2, 73 .nu_value = 0x1, 74 .nu_ret = NVME_FIELD_ERR_OK 75 }, { 76 .nu_desc = "valid NSID (2)", 77 .nu_fields = nvme_ns_attach_fields, 78 .nu_index = NVME_NS_ATTACH_REQ_FIELD_NSID, 79 .nu_data = &nvme_ctrl_ns_1v2, 80 .nu_value = NVME_NSID_BCAST, 81 .nu_ret = NVME_FIELD_ERR_OK 82 } }; 83 84 static const nvme_unit_field_test_t ns_delete_field_tests[] = { { 85 .nu_desc = "invalid NSID (1)", 86 .nu_fields = nvme_ns_delete_fields, 87 .nu_index = NVME_NS_DELETE_REQ_FIELD_NSID, 88 .nu_data = &nvme_ctrl_ns_1v4, 89 .nu_value = 0x0, 90 .nu_ret = NVME_FIELD_ERR_BAD_VALUE 91 }, { 92 .nu_desc = "invalid NSID (2)", 93 .nu_fields = nvme_ns_delete_fields, 94 .nu_index = NVME_NS_DELETE_REQ_FIELD_NSID, 95 .nu_data = &nvme_ctrl_ns_1v4, 96 .nu_value = 0x7777, 97 .nu_ret = NVME_FIELD_ERR_BAD_VALUE 98 }, { 99 .nu_desc = "valid NSID (1)", 100 .nu_fields = nvme_ns_delete_fields, 101 .nu_index = NVME_NS_DELETE_REQ_FIELD_NSID, 102 .nu_data = &nvme_ctrl_ns_1v4, 103 .nu_value = 0x1, 104 .nu_ret = NVME_FIELD_ERR_OK 105 }, { 106 .nu_desc = "valid NSID (2)", 107 .nu_fields = nvme_ns_delete_fields, 108 .nu_index = NVME_NS_DELETE_REQ_FIELD_NSID, 109 .nu_data = &nvme_ctrl_ns_1v4, 110 .nu_value = NVME_NSID_BCAST, 111 .nu_ret = NVME_FIELD_ERR_OK 112 } }; 113 114 static const nvme_unit_field_test_t ns_create_field_tests[] = { { 115 .nu_desc = "valid CSI (1)", 116 .nu_fields = nvme_ns_create_fields, 117 .nu_index = NVME_NS_CREATE_REQ_FIELD_CSI, 118 .nu_data = &nvme_ctrl_ns_2v0, 119 .nu_value = NVME_CSI_NVM, 120 .nu_ret = NVME_FIELD_ERR_OK 121 }, { 122 .nu_desc = "valid CSI (2)", 123 .nu_fields = nvme_ns_create_fields, 124 .nu_index = NVME_NS_CREATE_REQ_FIELD_CSI, 125 .nu_data = &nvme_ctrl_ns_2v0, 126 .nu_value = NVME_CSI_ZNS, 127 .nu_ret = NVME_FIELD_ERR_OK 128 }, { 129 .nu_desc = "invalid CSI (1)", 130 .nu_fields = nvme_ns_create_fields, 131 .nu_index = NVME_NS_CREATE_REQ_FIELD_CSI, 132 .nu_data = &nvme_ctrl_ns_2v0, 133 .nu_value = 0x7777, 134 .nu_ret = NVME_FIELD_ERR_BAD_VALUE 135 }, { 136 .nu_desc = "invalid CSI (2)", 137 .nu_fields = nvme_ns_create_fields, 138 .nu_index = NVME_NS_CREATE_REQ_FIELD_CSI, 139 .nu_data = &nvme_ctrl_ns_1v2, 140 .nu_value = NVME_CSI_ZNS, 141 .nu_ret = NVME_FIELD_ERR_UNSUP_VERSION 142 }, { 143 .nu_desc = "invalid CSI (3)", 144 .nu_fields = nvme_ns_create_fields, 145 .nu_index = NVME_NS_CREATE_REQ_FIELD_CSI, 146 .nu_data = &nvme_ctrl_ns_1v4, 147 .nu_value = NVME_CSI_NVM, 148 .nu_ret = NVME_FIELD_ERR_UNSUP_VERSION 149 }, { 150 .nu_desc = "invalid NSZE (1)", 151 .nu_fields = nvme_ns_create_fields, 152 .nu_index = NVME_NS_CREATE_REQ_FIELD_NSZE, 153 .nu_data = &nvme_ctrl_ns_2v0, 154 .nu_value = 0, 155 .nu_ret = NVME_FIELD_ERR_BAD_VALUE 156 }, { 157 .nu_desc = "valid NSZE (1)", 158 .nu_fields = nvme_ns_create_fields, 159 .nu_index = NVME_NS_CREATE_REQ_FIELD_NSZE, 160 .nu_data = &nvme_ctrl_ns_2v0, 161 .nu_value = 1, 162 .nu_ret = NVME_FIELD_ERR_OK 163 }, { 164 .nu_desc = "valid NSZE (2)", 165 .nu_fields = nvme_ns_create_fields, 166 .nu_index = NVME_NS_CREATE_REQ_FIELD_NSZE, 167 .nu_data = &nvme_ctrl_ns_2v0, 168 .nu_value = UINT64_MAX, 169 .nu_ret = NVME_FIELD_ERR_OK 170 }, { 171 .nu_desc = "valid NSZE (3)", 172 .nu_fields = nvme_ns_create_fields, 173 .nu_index = NVME_NS_CREATE_REQ_FIELD_NSZE, 174 .nu_data = &nvme_ctrl_ns_2v0, 175 .nu_value = 0xaabbccddeeff, 176 .nu_ret = NVME_FIELD_ERR_OK 177 }, { 178 .nu_desc = "valid NSZE (4)", 179 .nu_fields = nvme_ns_create_fields, 180 .nu_index = NVME_NS_CREATE_REQ_FIELD_NSZE, 181 .nu_data = &nvme_ctrl_ns_2v0, 182 .nu_value = 0x7777, 183 .nu_ret = NVME_FIELD_ERR_OK 184 }, { 185 .nu_desc = "invalid NCAP (1)", 186 .nu_fields = nvme_ns_create_fields, 187 .nu_index = NVME_NS_CREATE_REQ_FIELD_NCAP, 188 .nu_data = &nvme_ctrl_ns_2v0, 189 .nu_value = 0, 190 .nu_ret = NVME_FIELD_ERR_BAD_VALUE 191 }, { 192 .nu_desc = "valid NCAP (1)", 193 .nu_fields = nvme_ns_create_fields, 194 .nu_index = NVME_NS_CREATE_REQ_FIELD_NCAP, 195 .nu_data = &nvme_ctrl_ns_2v0, 196 .nu_value = 1, 197 .nu_ret = NVME_FIELD_ERR_OK 198 }, { 199 .nu_desc = "valid NCAP (2)", 200 .nu_fields = nvme_ns_create_fields, 201 .nu_index = NVME_NS_CREATE_REQ_FIELD_NCAP, 202 .nu_data = &nvme_ctrl_ns_2v0, 203 .nu_value = UINT64_MAX, 204 .nu_ret = NVME_FIELD_ERR_OK 205 }, { 206 .nu_desc = "valid NCAP (3)", 207 .nu_fields = nvme_ns_create_fields, 208 .nu_index = NVME_NS_CREATE_REQ_FIELD_NCAP, 209 .nu_data = &nvme_ctrl_ns_2v0, 210 .nu_value = 0xaabbccddeeff, 211 .nu_ret = NVME_FIELD_ERR_OK 212 }, { 213 .nu_desc = "valid NCAP (4)", 214 .nu_fields = nvme_ns_create_fields, 215 .nu_index = NVME_NS_CREATE_REQ_FIELD_NCAP, 216 .nu_data = &nvme_ctrl_ns_2v0, 217 .nu_value = 0x7777, 218 .nu_ret = NVME_FIELD_ERR_OK 219 }, { 220 .nu_desc = "invalid FLBAS (1)", 221 .nu_fields = nvme_ns_create_fields, 222 .nu_index = NVME_NS_CREATE_REQ_FIELD_FLBAS, 223 .nu_data = &nvme_ctrl_ns_2v0, 224 .nu_value = 0x2bb2, 225 .nu_ret = NVME_FIELD_ERR_BAD_VALUE 226 }, { 227 .nu_desc = "invalid FLBAS (2)", 228 .nu_fields = nvme_ns_create_fields, 229 .nu_index = NVME_NS_CREATE_REQ_FIELD_FLBAS, 230 .nu_data = &nvme_ctrl_ns_2v0, 231 .nu_value = UINT32_MAX, 232 .nu_ret = NVME_FIELD_ERR_BAD_VALUE 233 }, { 234 .nu_desc = "valid FLBAS (1)", 235 .nu_fields = nvme_ns_create_fields, 236 .nu_index = NVME_NS_CREATE_REQ_FIELD_FLBAS, 237 .nu_data = &nvme_ctrl_ns_2v0, 238 .nu_value = 0, 239 .nu_ret = NVME_FIELD_ERR_OK 240 }, { 241 .nu_desc = "valid FLBAS (2)", 242 .nu_fields = nvme_ns_create_fields, 243 .nu_index = NVME_NS_CREATE_REQ_FIELD_FLBAS, 244 .nu_data = &nvme_ctrl_ns_2v0, 245 .nu_value = 0xf, 246 .nu_ret = NVME_FIELD_ERR_OK 247 }, { 248 .nu_desc = "valid FLBAS (3)", 249 .nu_fields = nvme_ns_create_fields, 250 .nu_index = NVME_NS_CREATE_REQ_FIELD_FLBAS, 251 .nu_data = &nvme_ctrl_ns_2v0, 252 .nu_value = 0x7, 253 .nu_ret = NVME_FIELD_ERR_OK 254 }, { 255 .nu_desc = "valid NMIC (1)", 256 .nu_fields = nvme_ns_create_fields, 257 .nu_index = NVME_NS_CREATE_REQ_FIELD_NMIC, 258 .nu_data = &nvme_ctrl_ns_1v2, 259 .nu_value = 0x0, 260 .nu_ret = NVME_FIELD_ERR_OK 261 }, { 262 .nu_desc = "valid NMIC (1)", 263 .nu_fields = nvme_ns_create_fields, 264 .nu_index = NVME_NS_CREATE_REQ_FIELD_NMIC, 265 .nu_data = &nvme_ctrl_ns_1v2, 266 .nu_value = 0x1, 267 .nu_ret = NVME_FIELD_ERR_OK 268 }, { 269 .nu_desc = "valid NMIC (2)", 270 .nu_fields = nvme_ns_create_fields, 271 .nu_index = NVME_NS_CREATE_REQ_FIELD_NMIC, 272 .nu_data = &nvme_ctrl_ns_1v2, 273 .nu_value = 0x1, 274 .nu_ret = NVME_FIELD_ERR_OK 275 }, { 276 .nu_desc = "invalid NMIC (1)", 277 .nu_fields = nvme_ns_create_fields, 278 .nu_index = NVME_NS_CREATE_REQ_FIELD_NMIC, 279 .nu_data = &nvme_ctrl_ns_1v2, 280 .nu_value = 0x23, 281 .nu_ret = NVME_FIELD_ERR_BAD_VALUE 282 }, { 283 .nu_desc = "invalid NMIC (2)", 284 .nu_fields = nvme_ns_create_fields, 285 .nu_index = NVME_NS_CREATE_REQ_FIELD_NMIC, 286 .nu_data = &nvme_ctrl_ns_1v2, 287 .nu_value = 0x400, 288 .nu_ret = NVME_FIELD_ERR_BAD_VALUE 289 }, { 290 .nu_desc = "invalid NMIC (3)", 291 .nu_fields = nvme_ns_create_fields, 292 .nu_index = NVME_NS_CREATE_REQ_FIELD_NMIC, 293 .nu_data = &nvme_ctrl_ns_1v2, 294 .nu_value = UINT32_MAX, 295 .nu_ret = NVME_FIELD_ERR_BAD_VALUE 296 }, { 297 .nu_desc = "invalid NMIC (4)", 298 .nu_fields = nvme_ns_create_fields, 299 .nu_index = NVME_NS_CREATE_REQ_FIELD_NMIC, 300 .nu_data = &nvme_ctrl_ns_1v2, 301 .nu_value = 0x2, 302 .nu_ret = NVME_FIELD_ERR_BAD_VALUE 303 } }; 304 305 typedef struct { 306 const char *nii_desc; 307 const nvme_valid_ctrl_data_t *nii_data; 308 bool nii_impl; 309 } nsmgmt_impl_test_t; 310 311 static const nsmgmt_impl_test_t nsmgmt_impl_tests[] = { { 312 .nii_desc = "Basic 1.0 controller unsupported", 313 .nii_data = &nvme_ctrl_base_1v0, 314 .nii_impl = false 315 }, { 316 .nii_desc = "Basic 1.1 controller unsupported", 317 .nii_data = &nvme_ctrl_base_1v1, 318 .nii_impl = false 319 }, { 320 .nii_desc = "Basic 1.2 controller unsupported", 321 .nii_data = &nvme_ctrl_base_1v2, 322 .nii_impl = false 323 }, { 324 .nii_desc = "Basic 2.0 controller unsupported", 325 .nii_data = &nvme_ctrl_base_2v0, 326 .nii_impl = false 327 }, { 328 .nii_desc = "Fancy 1.2 controller supported", 329 .nii_data = &nvme_ctrl_ns_1v2, 330 .nii_impl = true 331 }, { 332 .nii_desc = "Fancy 1.3 controller supported", 333 .nii_data = &nvme_ctrl_ns_1v3, 334 .nii_impl = true 335 }, { 336 .nii_desc = "Fancy 1.4 controller supported", 337 .nii_data = &nvme_ctrl_ns_1v4, 338 .nii_impl = true 339 }, { 340 .nii_desc = "Fancy 2.0 controller supported", 341 .nii_data = &nvme_ctrl_ns_1v4, 342 .nii_impl = true 343 }, { 344 .nii_desc = "Fancy 1.4 w/o nsmgmt unsupported", 345 .nii_data = &nvme_ctrl_nons_1v4, 346 .nii_impl = false 347 } }; 348 349 static bool 350 nsmgmt_impl_test_one(const nsmgmt_impl_test_t *test) 351 { 352 bool impl = nvme_nsmgmt_cmds_supported(test->nii_data); 353 354 if (impl != test->nii_impl) { 355 warnx("TEST FAILED: %s: expected impl %u, found %u", 356 test->nii_desc, test->nii_impl, impl); 357 return (false); 358 } 359 360 (void) printf("TEST PASSED: %s: got correct impl\n", test->nii_desc); 361 return (true); 362 } 363 364 int 365 main(void) 366 { 367 int ret = EXIT_SUCCESS; 368 369 if (!nvme_unit_field_test(ns_attach_field_tests, 370 ARRAY_SIZE(ns_attach_field_tests))) { 371 ret = EXIT_FAILURE; 372 } 373 374 if (!nvme_unit_field_test(ns_delete_field_tests, 375 ARRAY_SIZE(ns_delete_field_tests))) { 376 ret = EXIT_FAILURE; 377 } 378 379 if (!nvme_unit_field_test(ns_create_field_tests, 380 ARRAY_SIZE(ns_create_field_tests))) { 381 ret = EXIT_FAILURE; 382 } 383 384 for (size_t i = 0; i < ARRAY_SIZE(nsmgmt_impl_tests); i++) { 385 if (!nsmgmt_impl_test_one(&nsmgmt_impl_tests[i])) { 386 ret = EXIT_FAILURE; 387 } 388 } 389 390 if (ret == EXIT_SUCCESS) { 391 (void) printf("All tests passed successfully!\n"); 392 } 393 394 return (ret); 395 } 396