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
nsmgmt_impl_test_one(const nsmgmt_impl_test_t * test)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
main(void)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