xref: /spdk/test/unit/lib/nvme/nvme_ns.c/nvme_ns_ut.c (revision 8dd1cd2104ea4001e4a0da2a4851ccd62c82f8e8)
1 /*   SPDX-License-Identifier: BSD-3-Clause
2  *   Copyright (c) Intel Corporation. All rights reserved.
3  *   Copyright (c) 2021 Mellanox Technologies LTD. All rights reserved.
4  */
5 
6 #include "spdk_cunit.h"
7 
8 #include "spdk/env.h"
9 
10 #include "nvme/nvme_ns.c"
11 
12 #include "common/lib/test_env.c"
13 
14 SPDK_LOG_REGISTER_COMPONENT(nvme)
15 
16 DEFINE_STUB(nvme_wait_for_completion_robust_lock, int,
17 	    (struct spdk_nvme_qpair *qpair,
18 	     struct nvme_completion_poll_status *status,
19 	     pthread_mutex_t *robust_mutex), 0);
20 DEFINE_STUB(nvme_ctrlr_multi_iocs_enabled, bool, (struct spdk_nvme_ctrlr *ctrlr), true);
21 
22 static struct spdk_nvme_cpl fake_cpl = {};
23 static enum spdk_nvme_generic_command_status_code set_status_code = SPDK_NVME_SC_SUCCESS;
24 
25 static void
26 fake_cpl_sc(spdk_nvme_cmd_cb cb_fn, void *cb_arg)
27 {
28 	fake_cpl.status.sc = set_status_code;
29 	cb_fn(cb_arg, &fake_cpl);
30 }
31 
32 static struct spdk_nvme_ns_data *fake_nsdata;
33 static struct spdk_nvme_zns_ns_data nsdata_zns = {
34 	.mar = 1024,
35 	.mor = 1024,
36 };
37 
38 struct spdk_nvme_cmd g_ut_cmd = {};
39 
40 int
41 nvme_ctrlr_cmd_identify(struct spdk_nvme_ctrlr *ctrlr, uint8_t cns, uint16_t cntid, uint32_t nsid,
42 			uint8_t csi, void *payload, size_t payload_size,
43 			spdk_nvme_cmd_cb cb_fn, void *cb_arg)
44 {
45 	memset(&g_ut_cmd, 0, sizeof(g_ut_cmd));
46 
47 	if (cns == SPDK_NVME_IDENTIFY_NS) {
48 		assert(payload_size == sizeof(struct spdk_nvme_ns_data));
49 		if (fake_nsdata) {
50 			memcpy(payload, fake_nsdata, sizeof(*fake_nsdata));
51 		} else {
52 			memset(payload, 0, payload_size);
53 		}
54 		fake_cpl_sc(cb_fn, cb_arg);
55 		return 0;
56 	} else if (cns == SPDK_NVME_IDENTIFY_NS_IOCS) {
57 		assert(payload_size == sizeof(struct spdk_nvme_zns_ns_data));
58 		memcpy(payload, &nsdata_zns, sizeof(struct spdk_nvme_zns_ns_data));
59 		return 0;
60 	} else if (cns == SPDK_NVME_IDENTIFY_NS_ID_DESCRIPTOR_LIST) {
61 		g_ut_cmd.cdw10_bits.identify.cns = cns;
62 		g_ut_cmd.cdw10_bits.identify.cntid = cntid;
63 		g_ut_cmd.cdw11_bits.identify.csi = csi;
64 		g_ut_cmd.nsid = nsid;
65 		return 0;
66 	}
67 	return -1;
68 }
69 
70 void
71 nvme_completion_poll_cb(void *arg, const struct spdk_nvme_cpl *cpl)
72 {
73 }
74 
75 int32_t
76 spdk_nvme_qpair_process_completions(struct spdk_nvme_qpair *qpair, uint32_t max_completions)
77 {
78 	return -1;
79 }
80 
81 static void
82 test_nvme_ns_construct(void)
83 {
84 	struct spdk_nvme_ns ns = {};
85 	uint32_t id = 1;
86 	struct spdk_nvme_ctrlr ctrlr = { };
87 
88 	nvme_ns_construct(&ns, id, &ctrlr);
89 	CU_ASSERT(ns.id == 1);
90 }
91 
92 static void
93 test_nvme_ns_uuid(void)
94 {
95 	struct spdk_nvme_ns ns = {};
96 	uint32_t id = 1;
97 	struct spdk_nvme_ctrlr ctrlr = {};
98 	const struct spdk_uuid *uuid;
99 	struct spdk_uuid expected_uuid;
100 
101 	memset(&expected_uuid, 0xA5, sizeof(expected_uuid));
102 
103 	/* Empty list - no UUID should be found */
104 	nvme_ns_construct(&ns, id, &ctrlr);
105 	uuid = spdk_nvme_ns_get_uuid(&ns);
106 	CU_ASSERT(uuid == NULL);
107 	nvme_ns_destruct(&ns);
108 
109 	/* NGUID only (no UUID in list) */
110 	nvme_ns_construct(&ns, id, &ctrlr);
111 	ns.id_desc_list[0] = 0x02; /* NIDT == NGUID */
112 	ns.id_desc_list[1] = 0x10; /* NIDL */
113 	memset(&ns.id_desc_list[4], 0xCC, 0x10);
114 	uuid = spdk_nvme_ns_get_uuid(&ns);
115 	CU_ASSERT(uuid == NULL);
116 	nvme_ns_destruct(&ns);
117 
118 	/* Just UUID in the list */
119 	nvme_ns_construct(&ns, id, &ctrlr);
120 	ns.id_desc_list[0] = 0x03; /* NIDT == UUID */
121 	ns.id_desc_list[1] = 0x10; /* NIDL */
122 	memcpy(&ns.id_desc_list[4], &expected_uuid, sizeof(expected_uuid));
123 	uuid = spdk_nvme_ns_get_uuid(&ns);
124 	SPDK_CU_ASSERT_FATAL(uuid != NULL);
125 	CU_ASSERT(memcmp(uuid, &expected_uuid, sizeof(*uuid)) == 0);
126 	nvme_ns_destruct(&ns);
127 
128 	/* UUID followed by NGUID */
129 	nvme_ns_construct(&ns, id, &ctrlr);
130 	ns.id_desc_list[0] = 0x03; /* NIDT == UUID */
131 	ns.id_desc_list[1] = 0x10; /* NIDL */
132 	memcpy(&ns.id_desc_list[4], &expected_uuid, sizeof(expected_uuid));
133 	ns.id_desc_list[20] = 0x02; /* NIDT == NGUID */
134 	ns.id_desc_list[21] = 0x10; /* NIDL */
135 	memset(&ns.id_desc_list[24], 0xCC, 0x10);
136 	uuid = spdk_nvme_ns_get_uuid(&ns);
137 	SPDK_CU_ASSERT_FATAL(uuid != NULL);
138 	CU_ASSERT(memcmp(uuid, &expected_uuid, sizeof(*uuid)) == 0);
139 	nvme_ns_destruct(&ns);
140 
141 	/* NGUID followed by UUID */
142 	nvme_ns_construct(&ns, id, &ctrlr);
143 	ns.id_desc_list[0] = 0x02; /* NIDT == NGUID */
144 	ns.id_desc_list[1] = 0x10; /* NIDL */
145 	memset(&ns.id_desc_list[4], 0xCC, 0x10);
146 	ns.id_desc_list[20] = 0x03; /* NIDT = UUID */
147 	ns.id_desc_list[21] = 0x10; /* NIDL */
148 	memcpy(&ns.id_desc_list[24], &expected_uuid, sizeof(expected_uuid));
149 	uuid = spdk_nvme_ns_get_uuid(&ns);
150 	SPDK_CU_ASSERT_FATAL(uuid != NULL);
151 	CU_ASSERT(memcmp(uuid, &expected_uuid, sizeof(*uuid)) == 0);
152 	nvme_ns_destruct(&ns);
153 }
154 
155 static void
156 test_nvme_ns_csi(void)
157 {
158 	struct spdk_nvme_ns ns = {};
159 	uint32_t id = 1;
160 	struct spdk_nvme_ctrlr ctrlr = {};
161 	enum spdk_nvme_csi csi;
162 
163 	/* Empty list - SPDK_NVME_CSI_NVM should be returned */
164 	nvme_ns_construct(&ns, id, &ctrlr);
165 	csi = nvme_ns_get_csi(&ns);
166 	CU_ASSERT(csi == SPDK_NVME_CSI_NVM);
167 	nvme_ns_destruct(&ns);
168 
169 	/* NVM CSI - SPDK_NVME_CSI_NVM should be returned */
170 	nvme_ns_construct(&ns, id, &ctrlr);
171 	ns.id_desc_list[0] = 0x4; /* NIDT == CSI */
172 	ns.id_desc_list[1] = 0x1; /* NIDL */
173 	ns.id_desc_list[4] = 0x0; /* SPDK_NVME_CSI_NVM */
174 	csi = nvme_ns_get_csi(&ns);
175 	CU_ASSERT(csi == SPDK_NVME_CSI_NVM);
176 	nvme_ns_destruct(&ns);
177 
178 	/* NGUID followed by ZNS CSI - SPDK_NVME_CSI_ZNS should be returned */
179 	nvme_ns_construct(&ns, id, &ctrlr);
180 	ns.id_desc_list[0] = 0x02; /* NIDT == NGUID */
181 	ns.id_desc_list[1] = 0x10; /* NIDL */
182 	memset(&ns.id_desc_list[4], 0xCC, 0x10);
183 	ns.id_desc_list[20] = 0x4; /* NIDT == CSI */
184 	ns.id_desc_list[21] = 0x1; /* NIDL */
185 	ns.id_desc_list[24] = 0x2; /* SPDK_NVME_CSI_ZNS */
186 	csi = nvme_ns_get_csi(&ns);
187 	CU_ASSERT(csi == SPDK_NVME_CSI_ZNS);
188 	nvme_ns_destruct(&ns);
189 
190 	/* KV CSI followed by NGUID - SPDK_NVME_CSI_KV should be returned */
191 	nvme_ns_construct(&ns, id, &ctrlr);
192 	ns.id_desc_list[0] = 0x4; /* NIDT == CSI */
193 	ns.id_desc_list[1] = 0x1; /* NIDL */
194 	ns.id_desc_list[4] = 0x1; /* SPDK_NVME_CSI_KV */
195 	ns.id_desc_list[5] = 0x02; /* NIDT == NGUID */
196 	ns.id_desc_list[6] = 0x10; /* NIDL */
197 	memset(&ns.id_desc_list[9], 0xCC, 0x10);
198 	csi = nvme_ns_get_csi(&ns);
199 	CU_ASSERT(csi == SPDK_NVME_CSI_KV);
200 	nvme_ns_destruct(&ns);
201 }
202 
203 static void
204 test_nvme_ns_data(void)
205 {
206 	struct spdk_nvme_ns ns = {};
207 	struct spdk_nvme_ctrlr ctrlr = { };
208 	struct spdk_nvme_ns_data expected_nsdata = {
209 		.nsze = 1000,
210 		.ncap = 1000,
211 	};
212 	const struct spdk_nvme_ns_data *nsdata;
213 
214 	fake_nsdata = &expected_nsdata;
215 	SPDK_CU_ASSERT_FATAL(nvme_ns_construct(&ns, 1, &ctrlr) == 0);
216 	fake_nsdata = NULL;
217 	CU_ASSERT(spdk_nvme_ns_is_active(&ns));
218 	CU_ASSERT(spdk_nvme_ns_get_id(&ns) == 1);
219 	CU_ASSERT(spdk_nvme_ns_get_num_sectors(&ns) == 1000);
220 
221 	nsdata = spdk_nvme_ns_get_data(&ns);
222 	CU_ASSERT(nsdata != NULL);
223 	CU_ASSERT(nsdata->ncap == 1000);
224 
225 	nvme_ns_destruct(&ns);
226 
227 	/* Cached NS data is still accessible after destruction. But is cleared. */
228 	CU_ASSERT(!spdk_nvme_ns_is_active(&ns));
229 	CU_ASSERT(spdk_nvme_ns_get_id(&ns) == 1);
230 	CU_ASSERT(spdk_nvme_ns_get_num_sectors(&ns) == 0);
231 	CU_ASSERT(nsdata->ncap == 0);
232 	CU_ASSERT(nsdata == spdk_nvme_ns_get_data(&ns));
233 }
234 
235 static void
236 test_nvme_ns_set_identify_data(void)
237 {
238 	struct spdk_nvme_ns ns = {};
239 	struct spdk_nvme_ctrlr ctrlr = {};
240 
241 	ns.id = 1;
242 	ns.ctrlr = &ctrlr;
243 
244 	ns.ctrlr->cdata.oncs.dsm = 1;
245 	ns.ctrlr->cdata.oncs.compare = 1;
246 	ns.ctrlr->cdata.vwc.present = 1;
247 	ns.ctrlr->cdata.oncs.write_zeroes = 1;
248 	ns.ctrlr->cdata.oncs.write_unc = 1;
249 	ns.ctrlr->min_page_size = 4096;
250 	ns.ctrlr->max_xfer_size = 131072;
251 
252 	ns.nsdata.flbas.extended = 1;
253 	ns.nsdata.nsrescap.raw = 1;
254 	ns.nsdata.dps.pit = SPDK_NVME_FMT_NVM_PROTECTION_TYPE1;
255 	ns.nsdata.flbas.format = 0;
256 	ns.nsdata.lbaf[0].lbads = 9;
257 	ns.nsdata.lbaf[0].ms = 8;
258 
259 	/* case 1:  nsdata->noiob > 0 */
260 	ns.nsdata.noiob = 1;
261 	nvme_ns_set_identify_data(&ns);
262 	CU_ASSERT(spdk_nvme_ns_get_optimal_io_boundary(&ns) == 1)
263 
264 	CU_ASSERT(spdk_nvme_ns_get_sector_size(&ns) == 512);
265 	CU_ASSERT(spdk_nvme_ns_get_extended_sector_size(&ns) == 520);
266 	CU_ASSERT(spdk_nvme_ns_get_md_size(&ns) == 8);
267 	CU_ASSERT(spdk_nvme_ns_get_max_io_xfer_size(&ns) == 131072);
268 	CU_ASSERT(ns.sectors_per_max_io == 252);
269 	CU_ASSERT(ns.sectors_per_max_io_no_md == 256);
270 	CU_ASSERT(spdk_nvme_ns_get_pi_type(&ns) == SPDK_NVME_FMT_NVM_PROTECTION_TYPE1);
271 
272 	CU_ASSERT(spdk_nvme_ns_get_flags(&ns) & SPDK_NVME_NS_EXTENDED_LBA_SUPPORTED);
273 	CU_ASSERT(spdk_nvme_ns_get_flags(&ns) & SPDK_NVME_NS_RESERVATION_SUPPORTED);
274 	CU_ASSERT(spdk_nvme_ns_get_flags(&ns) & SPDK_NVME_NS_COMPARE_SUPPORTED);
275 	CU_ASSERT(spdk_nvme_ns_get_flags(&ns) & SPDK_NVME_NS_FLUSH_SUPPORTED);
276 	CU_ASSERT(spdk_nvme_ns_get_flags(&ns) & SPDK_NVME_NS_WRITE_ZEROES_SUPPORTED);
277 	CU_ASSERT(spdk_nvme_ns_get_flags(&ns) & SPDK_NVME_NS_WRITE_UNCORRECTABLE_SUPPORTED);
278 	CU_ASSERT(spdk_nvme_ns_get_flags(&ns) & SPDK_NVME_NS_RESERVATION_SUPPORTED);
279 	CU_ASSERT(spdk_nvme_ns_get_flags(&ns) & SPDK_NVME_NS_DPS_PI_SUPPORTED);
280 
281 	/* case 2: quirks for NVME_QUIRK_MDTS_EXCLUDE_MD */
282 	ns.ctrlr->quirks = NVME_QUIRK_MDTS_EXCLUDE_MD;
283 	nvme_ns_set_identify_data(&ns);
284 	CU_ASSERT(ns.sectors_per_max_io == 256);
285 	CU_ASSERT(ns.sectors_per_max_io_no_md == 256);
286 }
287 
288 static void
289 test_spdk_nvme_ns_get_values(void)
290 {
291 	struct spdk_nvme_ns ns = {};
292 	struct spdk_nvme_ctrlr nsctrlr = {};
293 
294 	ns.ctrlr = &nsctrlr;
295 
296 	/* case1: spdk_nvme_ns_get_id */
297 	ns.id = 1;
298 	CU_ASSERT(spdk_nvme_ns_get_id(&ns) == 1);
299 
300 	/* case2: spdk_nvme_ns_get_ctrlr */
301 	CU_ASSERT(spdk_nvme_ns_get_ctrlr(&ns) == &nsctrlr);
302 
303 	/* case3: spdk_nvme_ns_get_max_io_xfer_size */
304 	ns.ctrlr->max_xfer_size = 65536;
305 	CU_ASSERT(spdk_nvme_ns_get_max_io_xfer_size(&ns) == 65536);
306 
307 	/* case4: spdk_nvme_ns_get_sector_size */
308 	ns.sector_size = 512;
309 	CU_ASSERT(spdk_nvme_ns_get_sector_size(&ns) == 512);
310 
311 	/* case5: spdk_nvme_ns_get_extended_sector_size */
312 	ns.extended_lba_size = 512;
313 	CU_ASSERT(spdk_nvme_ns_get_extended_sector_size(&ns) == 512);
314 
315 	/* case6: spdk_nvme_ns_get_num_sectors */
316 	ns.nsdata.nsze = 1024;
317 	CU_ASSERT(spdk_nvme_ns_get_num_sectors(&ns) == 1024);
318 
319 	/* case7: spdk_nvme_ns_get_size */
320 	CU_ASSERT(spdk_nvme_ns_get_size(&ns) == 524288);
321 
322 	/* case8: spdk_nvme_ns_get_flags */
323 	ns.flags = 255;
324 	CU_ASSERT(spdk_nvme_ns_get_flags(&ns) == 255);
325 
326 	/* case9: spdk_nvme_ns_get_pi_type */
327 	ns.pi_type = SPDK_NVME_FMT_NVM_PROTECTION_DISABLE;
328 	CU_ASSERT(spdk_nvme_ns_get_pi_type(&ns) == SPDK_NVME_FMT_NVM_PROTECTION_DISABLE);
329 
330 	/* case10: spdk_nvme_ns_get_md_size */
331 	ns.md_size = 512;
332 	CU_ASSERT(spdk_nvme_ns_get_md_size(&ns) == 512);
333 
334 	/* case11: spdk_nvme_ns_get_data */
335 	CU_ASSERT(spdk_nvme_ns_get_data(&ns) != NULL);
336 
337 	/* case12: spdk_nvme_ns_get_optimal_io_boundary */
338 	ns.sectors_per_stripe = 1;
339 	CU_ASSERT(spdk_nvme_ns_get_optimal_io_boundary(&ns) == 1);
340 
341 	/* case13: spdk_nvme_ns_get_dealloc_logical_block_read_value */
342 	ns.ctrlr->quirks = NVME_QUIRK_READ_ZERO_AFTER_DEALLOCATE | NVME_INTEL_QUIRK_WRITE_LATENCY;
343 	ns.nsdata.dlfeat.bits.read_value = SPDK_NVME_DEALLOC_NOT_REPORTED;
344 	CU_ASSERT(spdk_nvme_ns_get_dealloc_logical_block_read_value(&ns) == SPDK_NVME_DEALLOC_READ_00);
345 
346 	ns.ctrlr->quirks = NVME_INTEL_QUIRK_READ_LATENCY;
347 	CU_ASSERT(spdk_nvme_ns_get_dealloc_logical_block_read_value(&ns) == SPDK_NVME_DEALLOC_NOT_REPORTED);
348 
349 	/* case14: spdk_nvme_ns_get_csi */
350 	ns.csi = SPDK_NVME_CSI_NVM;
351 	CU_ASSERT(spdk_nvme_ns_get_csi(&ns) == SPDK_NVME_CSI_NVM);
352 
353 	/* case15: spdk_nvme_ns_get_ana_group_id */
354 	ns.ana_group_id = 15;
355 	CU_ASSERT(spdk_nvme_ns_get_ana_group_id(&ns) == 15);
356 
357 	/* case16: spdk_nvme_ns_get_ana_state */
358 	ns.ana_state = SPDK_NVME_ANA_OPTIMIZED_STATE;
359 	CU_ASSERT(spdk_nvme_ns_get_ana_state(&ns) == SPDK_NVME_ANA_OPTIMIZED_STATE);
360 }
361 
362 static void
363 test_spdk_nvme_ns_is_active(void)
364 {
365 	struct spdk_nvme_ns ns = {};
366 
367 	/* case1: nsdata->id == 0 return false */
368 	ns.id = 0;
369 	CU_ASSERT(spdk_nvme_ns_is_active(&ns) == false);
370 
371 	/* case2: nsdata->ncap == 0 return false */
372 	ns.id = 1;
373 	ns.nsdata.ncap = 0;
374 	CU_ASSERT(spdk_nvme_ns_is_active(&ns) == false);
375 
376 	/* case3: ns->ncap != 0 return true */
377 	ns.nsdata.ncap = 1;
378 	CU_ASSERT(spdk_nvme_ns_is_active(&ns) == true);
379 }
380 
381 static void
382 spdk_nvme_ns_supports(void)
383 {
384 	struct spdk_nvme_ns ns = {};
385 
386 	/* case1: spdk_nvme_ns_supports_extended_lba */
387 	ns.flags = SPDK_NVME_NS_DEALLOCATE_SUPPORTED;
388 	CU_ASSERT(spdk_nvme_ns_supports_extended_lba(&ns) == false);
389 	ns.flags = SPDK_NVME_NS_EXTENDED_LBA_SUPPORTED | SPDK_NVME_NS_DEALLOCATE_SUPPORTED;
390 	CU_ASSERT(spdk_nvme_ns_supports_extended_lba(&ns) == true);
391 
392 	/* case2: spdk_nvme_ns_supports_compare */
393 	ns.flags = SPDK_NVME_NS_DEALLOCATE_SUPPORTED;
394 	CU_ASSERT(spdk_nvme_ns_supports_compare(&ns) == false);
395 	ns.flags = SPDK_NVME_NS_COMPARE_SUPPORTED | SPDK_NVME_NS_DEALLOCATE_SUPPORTED;
396 	CU_ASSERT(spdk_nvme_ns_supports_compare(&ns) == true);
397 }
398 
399 static void
400 test_nvme_ns_has_supported_iocs_specific_data(void)
401 {
402 	struct spdk_nvme_ns ns = {};
403 
404 	/* case 1: ns.csi == SPDK_NVME_CSI_NVM. Expect: false */
405 	ns.csi = SPDK_NVME_CSI_NVM;
406 	CU_ASSERT(nvme_ns_has_supported_iocs_specific_data(&ns) == false);
407 	/* case 2: ns.csi == SPDK_NVME_CSI_ZNS. Expect: true */
408 	ns.csi = SPDK_NVME_CSI_ZNS;
409 	CU_ASSERT(nvme_ns_has_supported_iocs_specific_data(&ns) == true);
410 	/* case 3: default ns.csi == SPDK_NVME_CSI_KV. Expect: false */
411 	ns.csi = SPDK_NVME_CSI_KV;
412 	CU_ASSERT(nvme_ns_has_supported_iocs_specific_data(&ns) == false);
413 }
414 
415 static void
416 test_nvme_ctrlr_identify_ns_iocs_specific(void)
417 {
418 	struct spdk_nvme_ns ns = {};
419 	struct spdk_nvme_ctrlr ctrlr = {};
420 	int rc = 0;
421 
422 	ns.ctrlr = &ctrlr;
423 
424 	ns.csi = SPDK_NVME_CSI_ZNS;
425 	ns.id = 1;
426 
427 	/* case 1: Test nvme_ctrlr_identify_ns_iocs_specific. Expect: PASS. */
428 	rc = nvme_ctrlr_identify_ns_iocs_specific(&ns);
429 	CU_ASSERT(rc == 0);
430 	CU_ASSERT(ns.nsdata_zns->mar == 1024);
431 	CU_ASSERT(ns.nsdata_zns->mor == 1024);
432 
433 	/* case 2: Test nvme_ns_free_zns_specific_data. Expect: PASS. */
434 	nvme_ns_free_zns_specific_data(&ns);
435 	CU_ASSERT(ns.nsdata_zns == NULL);
436 }
437 
438 static void
439 test_nvme_ctrlr_identify_id_desc(void)
440 {
441 	struct spdk_nvme_ns ns = {};
442 	struct spdk_nvme_ctrlr ctrlr = {};
443 	int rc;
444 
445 	ns.ctrlr = &ctrlr;
446 	ns.ctrlr->vs.raw = SPDK_NVME_VERSION(1, 3, 0);
447 	ns.ctrlr->cap.bits.css |= SPDK_NVME_CAP_CSS_IOCS;
448 	ns.id = 1;
449 
450 	rc = nvme_ctrlr_identify_id_desc(&ns);
451 	CU_ASSERT(rc == 0);
452 	CU_ASSERT(g_ut_cmd.cdw10_bits.identify.cns == SPDK_NVME_IDENTIFY_NS_ID_DESCRIPTOR_LIST);
453 	CU_ASSERT(g_ut_cmd.cdw10_bits.identify.cntid == 0);
454 	CU_ASSERT(g_ut_cmd.cdw11_bits.identify.csi == spdk_nvme_ns_get_csi(&ns));
455 	CU_ASSERT(g_ut_cmd.nsid == 1);
456 
457 	/* NVME version and css unsupported */
458 	ns.ctrlr->vs.raw = SPDK_NVME_VERSION(1, 2, 0);
459 	ns.ctrlr->cap.bits.css &= ~SPDK_NVME_CAP_CSS_IOCS;
460 
461 	rc = nvme_ctrlr_identify_id_desc(&ns);
462 	CU_ASSERT(rc == 0);
463 }
464 
465 static void
466 test_nvme_ns_find_id_desc(void)
467 {
468 	struct spdk_nvme_ns ns = {};
469 	struct spdk_nvme_ns_id_desc *desc = NULL;
470 	const uint8_t *csi = NULL;
471 	size_t length = 0;
472 
473 	desc = (void *)ns.id_desc_list;
474 	desc->nidl = 4;
475 	desc->nidt = SPDK_NVME_NIDT_CSI;
476 
477 	/* Case 1: get id descriptor successfully */
478 	csi = nvme_ns_find_id_desc(&ns, SPDK_NVME_NIDT_CSI, &length);
479 	CU_ASSERT(csi == desc->nid);
480 	CU_ASSERT(length == 4);
481 
482 	/* Case 2: ns_id length invalid, expect fail */
483 	desc->nidl = 0;
484 
485 	csi = nvme_ns_find_id_desc(&ns, SPDK_NVME_NIDT_CSI, &length);
486 	CU_ASSERT(csi == NULL);
487 
488 	/* Case 3: No correct id descriptor type entry, expect fail */
489 	desc->nidl = 4;
490 	desc->nidt = SPDK_NVME_NIDT_CSI;
491 
492 	csi = nvme_ns_find_id_desc(&ns, SPDK_NVME_NIDT_UUID, &length);
493 	CU_ASSERT(csi == NULL);
494 }
495 
496 int
497 main(int argc, char **argv)
498 {
499 	CU_pSuite	suite = NULL;
500 	unsigned int	num_failures;
501 
502 	CU_set_error_action(CUEA_ABORT);
503 	CU_initialize_registry();
504 
505 	suite = CU_add_suite("nvme", NULL, NULL);
506 
507 	CU_ADD_TEST(suite, test_nvme_ns_construct);
508 	CU_ADD_TEST(suite, test_nvme_ns_uuid);
509 	CU_ADD_TEST(suite, test_nvme_ns_csi);
510 	CU_ADD_TEST(suite, test_nvme_ns_data);
511 	CU_ADD_TEST(suite, test_nvme_ns_set_identify_data);
512 	CU_ADD_TEST(suite, test_spdk_nvme_ns_get_values);
513 	CU_ADD_TEST(suite, test_spdk_nvme_ns_is_active);
514 	CU_ADD_TEST(suite, spdk_nvme_ns_supports);
515 	CU_ADD_TEST(suite, test_nvme_ns_has_supported_iocs_specific_data);
516 	CU_ADD_TEST(suite, test_nvme_ctrlr_identify_ns_iocs_specific);
517 	CU_ADD_TEST(suite, test_nvme_ctrlr_identify_id_desc);
518 	CU_ADD_TEST(suite, test_nvme_ns_find_id_desc);
519 
520 	CU_basic_set_mode(CU_BRM_VERBOSE);
521 	CU_basic_run_tests();
522 	num_failures = CU_get_number_of_failures();
523 	CU_cleanup_registry();
524 	return num_failures;
525 }
526