4 * Copyright (c) Intel Corporation.
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
11 * * Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * * Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in
15 * the documentation and/or other materials provided with the
17 * * Neither the name of Intel Corporation nor the names of its
18 * contributors may be used to endorse or promote products derived
19 * from this software without specific prior written permission.
21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
24 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
25 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
26 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
27 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
31 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34 #include "spdk_cunit.h"
38 #include "nvme/nvme.c"
40 #include "spdk_internal/mock.h"
42 #include "common/lib/test_env.c"
44 DEFINE_STUB_V(nvme_ctrlr_proc_get_ref
, (struct spdk_nvme_ctrlr
*ctrlr
));
45 DEFINE_STUB_V(nvme_ctrlr_proc_put_ref
, (struct spdk_nvme_ctrlr
*ctrlr
));
46 DEFINE_STUB(spdk_nvme_transport_available
, bool,
47 (enum spdk_nvme_transport_type trtype
), true);
48 /* return anything non-NULL, this won't be deferenced anywhere in this test */
49 DEFINE_STUB(spdk_nvme_ctrlr_get_current_process
, struct spdk_nvme_ctrlr_process
*,
50 (struct spdk_nvme_ctrlr
*ctrlr
), (struct spdk_nvme_ctrlr_process
*)(uintptr_t)0x1);
51 DEFINE_STUB(nvme_ctrlr_process_init
, int,
52 (struct spdk_nvme_ctrlr
*ctrlr
), 0);
53 DEFINE_STUB(nvme_ctrlr_get_ref_count
, int,
54 (struct spdk_nvme_ctrlr
*ctrlr
), 0);
55 DEFINE_STUB(dummy_probe_cb
, bool,
56 (void *cb_ctx
, const struct spdk_nvme_transport_id
*trid
,
57 struct spdk_nvme_ctrlr_opts
*opts
), false);
58 DEFINE_STUB(nvme_transport_ctrlr_construct
, struct spdk_nvme_ctrlr
*,
59 (const struct spdk_nvme_transport_id
*trid
,
60 const struct spdk_nvme_ctrlr_opts
*opts
,
61 void *devhandle
), NULL
);
63 static bool ut_destruct_called
= false;
65 nvme_ctrlr_destruct(struct spdk_nvme_ctrlr
*ctrlr
)
67 ut_destruct_called
= true;
71 spdk_nvme_ctrlr_get_default_ctrlr_opts(struct spdk_nvme_ctrlr_opts
*opts
, size_t opts_size
)
73 memset(opts
, 0, sizeof(*opts
));
77 memset_trid(struct spdk_nvme_transport_id
*trid1
, struct spdk_nvme_transport_id
*trid2
)
79 memset(trid1
, 0, sizeof(struct spdk_nvme_transport_id
));
80 memset(trid2
, 0, sizeof(struct spdk_nvme_transport_id
));
83 static bool ut_check_trtype
= false;
85 nvme_transport_ctrlr_scan(struct spdk_nvme_probe_ctx
*probe_ctx
,
88 struct spdk_nvme_ctrlr
*ctrlr
= NULL
;
90 if (ut_check_trtype
== true) {
91 CU_ASSERT(probe_ctx
->trid
.trtype
== SPDK_NVME_TRANSPORT_PCIE
);
94 if (direct_connect
== true && probe_ctx
->probe_cb
) {
95 nvme_robust_mutex_unlock(&g_spdk_nvme_driver
->lock
);
96 ctrlr
= spdk_nvme_get_ctrlr_by_trid(&probe_ctx
->trid
);
97 nvme_robust_mutex_lock(&g_spdk_nvme_driver
->lock
);
98 probe_ctx
->probe_cb(probe_ctx
->cb_ctx
, &probe_ctx
->trid
, &ctrlr
->opts
);
103 static bool ut_attach_cb_called
= false;
105 dummy_attach_cb(void *cb_ctx
, const struct spdk_nvme_transport_id
*trid
,
106 struct spdk_nvme_ctrlr
*ctrlr
, const struct spdk_nvme_ctrlr_opts
*opts
)
108 ut_attach_cb_called
= true;
112 test_spdk_nvme_probe(void)
115 const struct spdk_nvme_transport_id
*trid
= NULL
;
117 spdk_nvme_probe_cb probe_cb
= NULL
;
118 spdk_nvme_attach_cb attach_cb
= dummy_attach_cb
;
119 spdk_nvme_remove_cb remove_cb
= NULL
;
120 struct spdk_nvme_ctrlr ctrlr
;
121 pthread_mutexattr_t attr
;
122 struct nvme_driver dummy
;
123 g_spdk_nvme_driver
= &dummy
;
125 /* driver init fails */
126 MOCK_SET(spdk_process_is_primary
, false);
127 MOCK_SET(spdk_memzone_lookup
, NULL
);
128 rc
= spdk_nvme_probe(trid
, cb_ctx
, probe_cb
, attach_cb
, remove_cb
);
132 * For secondary processes, the attach_cb should automatically get
133 * called for any controllers already initialized by the primary
136 MOCK_SET(spdk_nvme_transport_available
, false);
137 MOCK_SET(spdk_process_is_primary
, true);
138 dummy
.initialized
= true;
139 g_spdk_nvme_driver
= &dummy
;
140 rc
= spdk_nvme_probe(trid
, cb_ctx
, probe_cb
, attach_cb
, remove_cb
);
143 /* driver init passes, transport available, secondary call attach_cb */
144 MOCK_SET(spdk_nvme_transport_available
, true);
145 MOCK_SET(spdk_process_is_primary
, false);
146 MOCK_SET(spdk_memzone_lookup
, g_spdk_nvme_driver
);
147 dummy
.initialized
= true;
148 memset(&ctrlr
, 0, sizeof(struct spdk_nvme_ctrlr
));
149 CU_ASSERT(pthread_mutexattr_init(&attr
) == 0);
150 CU_ASSERT(pthread_mutex_init(&dummy
.lock
, &attr
) == 0);
151 TAILQ_INIT(&dummy
.shared_attached_ctrlrs
);
152 TAILQ_INSERT_TAIL(&dummy
.shared_attached_ctrlrs
, &ctrlr
, tailq
);
153 ut_attach_cb_called
= false;
154 /* setup nvme_transport_ctrlr_scan() stub to also check the trype */
155 ut_check_trtype
= true;
156 rc
= spdk_nvme_probe(trid
, cb_ctx
, probe_cb
, attach_cb
, remove_cb
);
158 CU_ASSERT(ut_attach_cb_called
== true);
160 /* driver init passes, transport available, we are primary */
161 MOCK_SET(spdk_process_is_primary
, true);
162 rc
= spdk_nvme_probe(trid
, cb_ctx
, probe_cb
, attach_cb
, remove_cb
);
165 g_spdk_nvme_driver
= NULL
;
166 /* reset to pre-test values */
167 MOCK_CLEAR(spdk_memzone_lookup
);
168 ut_check_trtype
= false;
170 pthread_mutex_destroy(&dummy
.lock
);
171 pthread_mutexattr_destroy(&attr
);
175 test_spdk_nvme_connect(void)
177 struct spdk_nvme_ctrlr
*ret_ctrlr
= NULL
;
178 struct spdk_nvme_transport_id trid
= {};
179 struct spdk_nvme_ctrlr_opts opts
= {};
180 struct spdk_nvme_ctrlr ctrlr
;
181 pthread_mutexattr_t attr
;
182 struct nvme_driver dummy
;
184 /* initialize the variable to prepare the test */
185 dummy
.initialized
= true;
186 TAILQ_INIT(&dummy
.shared_attached_ctrlrs
);
187 g_spdk_nvme_driver
= &dummy
;
188 CU_ASSERT(pthread_mutexattr_init(&attr
) == 0);
189 CU_ASSERT(pthread_mutex_init(&g_spdk_nvme_driver
->lock
, &attr
) == 0);
191 /* set NULL trid pointer to test immediate return */
192 ret_ctrlr
= spdk_nvme_connect(NULL
, NULL
, 0);
193 CU_ASSERT(ret_ctrlr
== NULL
);
195 /* driver init passes, transport available, secondary process connects ctrlr */
196 MOCK_SET(spdk_process_is_primary
, false);
197 MOCK_SET(spdk_memzone_lookup
, g_spdk_nvme_driver
);
198 MOCK_SET(spdk_nvme_transport_available
, true);
199 memset(&trid
, 0, sizeof(trid
));
200 trid
.trtype
= SPDK_NVME_TRANSPORT_PCIE
;
201 ret_ctrlr
= spdk_nvme_connect(&trid
, NULL
, 0);
202 CU_ASSERT(ret_ctrlr
== NULL
);
204 /* driver init passes, setup one ctrlr on the attached_list */
205 memset(&ctrlr
, 0, sizeof(struct spdk_nvme_ctrlr
));
206 snprintf(ctrlr
.trid
.traddr
, sizeof(ctrlr
.trid
.traddr
), "0000:01:00.0");
207 ctrlr
.trid
.trtype
= SPDK_NVME_TRANSPORT_PCIE
;
208 TAILQ_INSERT_TAIL(&g_spdk_nvme_driver
->shared_attached_ctrlrs
, &ctrlr
, tailq
);
209 /* get the ctrlr from the attached list */
210 snprintf(trid
.traddr
, sizeof(trid
.traddr
), "0000:01:00.0");
211 ret_ctrlr
= spdk_nvme_connect(&trid
, NULL
, 0);
212 CU_ASSERT(ret_ctrlr
== &ctrlr
);
213 /* get the ctrlr from the attached list with default ctrlr opts */
214 ctrlr
.opts
.num_io_queues
= DEFAULT_MAX_IO_QUEUES
;
215 ret_ctrlr
= spdk_nvme_connect(&trid
, NULL
, 0);
216 CU_ASSERT(ret_ctrlr
== &ctrlr
);
217 CU_ASSERT_EQUAL(ret_ctrlr
->opts
.num_io_queues
, DEFAULT_MAX_IO_QUEUES
);
218 /* get the ctrlr from the attached list with default ctrlr opts and consistent opts_size */
219 opts
.num_io_queues
= 1;
220 ret_ctrlr
= spdk_nvme_connect(&trid
, &opts
, sizeof(opts
));
221 CU_ASSERT(ret_ctrlr
== &ctrlr
);
222 CU_ASSERT_EQUAL(ret_ctrlr
->opts
.num_io_queues
, 1);
223 /* opts_size must be sizeof(*opts) if opts != NULL */
224 ret_ctrlr
= spdk_nvme_connect(&trid
, &opts
, sizeof(opts
) + 1);
225 CU_ASSERT(ret_ctrlr
== NULL
);
226 /* remove the attached ctrlr on the attached_list */
227 CU_ASSERT(spdk_nvme_detach(&ctrlr
) == 0);
228 CU_ASSERT(TAILQ_EMPTY(&g_spdk_nvme_driver
->shared_attached_ctrlrs
));
230 /* driver init passes, transport available, primary process connects ctrlr */
231 MOCK_SET(spdk_process_is_primary
, true);
232 /* setup one ctrlr on the attached_list */
233 memset(&ctrlr
, 0, sizeof(struct spdk_nvme_ctrlr
));
234 snprintf(ctrlr
.trid
.traddr
, sizeof(ctrlr
.trid
.traddr
), "0000:02:00.0");
235 ctrlr
.trid
.trtype
= SPDK_NVME_TRANSPORT_PCIE
;
236 TAILQ_INSERT_TAIL(&g_spdk_nvme_driver
->shared_attached_ctrlrs
, &ctrlr
, tailq
);
237 /* get the ctrlr from the attached list */
238 snprintf(trid
.traddr
, sizeof(trid
.traddr
), "0000:02:00.0");
239 ret_ctrlr
= spdk_nvme_connect(&trid
, NULL
, 0);
240 CU_ASSERT(ret_ctrlr
== &ctrlr
);
241 /* get the ctrlr from the attached list with default ctrlr opts */
242 ctrlr
.opts
.num_io_queues
= DEFAULT_MAX_IO_QUEUES
;
243 ret_ctrlr
= spdk_nvme_connect(&trid
, NULL
, 0);
244 CU_ASSERT(ret_ctrlr
== &ctrlr
);
245 CU_ASSERT_EQUAL(ret_ctrlr
->opts
.num_io_queues
, DEFAULT_MAX_IO_QUEUES
);
246 /* get the ctrlr from the attached list with default ctrlr opts and consistent opts_size */
247 opts
.num_io_queues
= 2;
248 ret_ctrlr
= spdk_nvme_connect(&trid
, &opts
, sizeof(opts
));
249 CU_ASSERT(ret_ctrlr
== &ctrlr
);
250 CU_ASSERT_EQUAL(ret_ctrlr
->opts
.num_io_queues
, 2);
251 /* remove the attached ctrlr on the attached_list */
252 CU_ASSERT(spdk_nvme_detach(ret_ctrlr
) == 0);
253 CU_ASSERT(TAILQ_EMPTY(&g_spdk_nvme_driver
->shared_attached_ctrlrs
));
255 /* test driver init failure return */
256 MOCK_SET(spdk_process_is_primary
, false);
257 MOCK_SET(spdk_memzone_lookup
, NULL
);
258 ret_ctrlr
= spdk_nvme_connect(&trid
, NULL
, 0);
259 CU_ASSERT(ret_ctrlr
== NULL
);
262 static struct spdk_nvme_probe_ctx
*
263 test_nvme_init_get_probe_ctx(void)
265 struct spdk_nvme_probe_ctx
*probe_ctx
;
267 probe_ctx
= calloc(1, sizeof(*probe_ctx
));
268 SPDK_CU_ASSERT_FATAL(probe_ctx
!= NULL
);
269 TAILQ_INIT(&probe_ctx
->init_ctrlrs
);
275 test_nvme_init_controllers(void)
278 struct nvme_driver test_driver
;
280 spdk_nvme_attach_cb attach_cb
= dummy_attach_cb
;
281 struct spdk_nvme_probe_ctx
*probe_ctx
;
282 struct spdk_nvme_ctrlr
*ctrlr
;
283 pthread_mutexattr_t attr
;
285 g_spdk_nvme_driver
= &test_driver
;
286 ctrlr
= calloc(1, sizeof(*ctrlr
));
287 SPDK_CU_ASSERT_FATAL(ctrlr
!= NULL
);
288 ctrlr
->trid
.trtype
= SPDK_NVME_TRANSPORT_PCIE
;
289 CU_ASSERT(pthread_mutexattr_init(&attr
) == 0);
290 CU_ASSERT(pthread_mutex_init(&test_driver
.lock
, &attr
) == 0);
291 TAILQ_INIT(&test_driver
.shared_attached_ctrlrs
);
294 * Try to initialize, but nvme_ctrlr_process_init will fail.
295 * Verify correct behavior when it does.
297 MOCK_SET(nvme_ctrlr_process_init
, 1);
298 MOCK_SET(spdk_process_is_primary
, 1);
299 g_spdk_nvme_driver
->initialized
= false;
300 ut_destruct_called
= false;
301 probe_ctx
= test_nvme_init_get_probe_ctx();
302 TAILQ_INSERT_TAIL(&probe_ctx
->init_ctrlrs
, ctrlr
, tailq
);
303 probe_ctx
->cb_ctx
= cb_ctx
;
304 probe_ctx
->attach_cb
= attach_cb
;
305 probe_ctx
->trid
.trtype
= SPDK_NVME_TRANSPORT_PCIE
;
306 rc
= nvme_init_controllers(probe_ctx
);
308 CU_ASSERT(g_spdk_nvme_driver
->initialized
== true);
309 CU_ASSERT(ut_destruct_called
== true);
312 * Controller init OK, need to move the controller state machine
313 * forward by setting the ctrl state so that it can be moved
314 * the shared_attached_ctrlrs list.
316 probe_ctx
= test_nvme_init_get_probe_ctx();
317 TAILQ_INSERT_TAIL(&probe_ctx
->init_ctrlrs
, ctrlr
, tailq
);
318 ctrlr
->state
= NVME_CTRLR_STATE_READY
;
319 MOCK_SET(nvme_ctrlr_process_init
, 0);
320 rc
= nvme_init_controllers(probe_ctx
);
322 CU_ASSERT(ut_attach_cb_called
== true);
323 CU_ASSERT(TAILQ_EMPTY(&g_nvme_attached_ctrlrs
));
324 CU_ASSERT(TAILQ_FIRST(&g_spdk_nvme_driver
->shared_attached_ctrlrs
) == ctrlr
);
325 TAILQ_REMOVE(&g_spdk_nvme_driver
->shared_attached_ctrlrs
, ctrlr
, tailq
);
328 * Non-PCIe controllers should be added to the per-process list, not the shared list.
330 memset(ctrlr
, 0, sizeof(struct spdk_nvme_ctrlr
));
331 ctrlr
->trid
.trtype
= SPDK_NVME_TRANSPORT_RDMA
;
332 probe_ctx
= test_nvme_init_get_probe_ctx();
333 TAILQ_INSERT_TAIL(&probe_ctx
->init_ctrlrs
, ctrlr
, tailq
);
334 ctrlr
->state
= NVME_CTRLR_STATE_READY
;
335 MOCK_SET(nvme_ctrlr_process_init
, 0);
336 rc
= nvme_init_controllers(probe_ctx
);
338 CU_ASSERT(ut_attach_cb_called
== true);
339 CU_ASSERT(TAILQ_EMPTY(&g_spdk_nvme_driver
->shared_attached_ctrlrs
));
340 CU_ASSERT(TAILQ_FIRST(&g_nvme_attached_ctrlrs
) == ctrlr
);
341 TAILQ_REMOVE(&g_nvme_attached_ctrlrs
, ctrlr
, tailq
);
343 CU_ASSERT(TAILQ_EMPTY(&g_nvme_attached_ctrlrs
));
345 g_spdk_nvme_driver
= NULL
;
346 pthread_mutexattr_destroy(&attr
);
347 pthread_mutex_destroy(&test_driver
.lock
);
351 test_nvme_driver_init(void)
354 struct nvme_driver dummy
;
355 g_spdk_nvme_driver
= &dummy
;
357 /* adjust this so testing doesn't take so long */
358 g_nvme_driver_timeout_ms
= 100;
360 /* process is primary and mem already reserved */
361 MOCK_SET(spdk_process_is_primary
, true);
362 dummy
.initialized
= true;
363 rc
= nvme_driver_init();
367 * Process is primary and mem not yet reserved but the call
368 * to spdk_memzone_reserve() returns NULL.
370 g_spdk_nvme_driver
= NULL
;
371 MOCK_SET(spdk_process_is_primary
, true);
372 MOCK_SET(spdk_memzone_reserve
, NULL
);
373 rc
= nvme_driver_init();
376 /* process is not primary, no mem already reserved */
377 MOCK_SET(spdk_process_is_primary
, false);
378 MOCK_SET(spdk_memzone_lookup
, NULL
);
379 g_spdk_nvme_driver
= NULL
;
380 rc
= nvme_driver_init();
383 /* process is not primary, mem is already reserved & init'd */
384 MOCK_SET(spdk_process_is_primary
, false);
385 MOCK_SET(spdk_memzone_lookup
, (void *)&dummy
);
386 dummy
.initialized
= true;
387 rc
= nvme_driver_init();
390 /* process is not primary, mem is reserved but not initialized */
392 MOCK_SET(spdk_process_is_primary
, false);
393 MOCK_SET(spdk_memzone_reserve
, (void *)&dummy
);
394 dummy
.initialized
= false;
395 rc
= nvme_driver_init();
398 /* process is primary, got mem but mutex won't init */
399 MOCK_SET(spdk_process_is_primary
, true);
400 MOCK_SET(spdk_memzone_reserve
, (void *)&dummy
);
401 MOCK_SET(pthread_mutexattr_init
, -1);
402 g_spdk_nvme_driver
= NULL
;
403 dummy
.initialized
= true;
404 rc
= nvme_driver_init();
405 /* for FreeBSD we can't can't effectively mock this path */
412 /* process is primary, got mem, mutex OK */
413 MOCK_SET(spdk_process_is_primary
, true);
414 MOCK_CLEAR(pthread_mutexattr_init
);
415 g_spdk_nvme_driver
= NULL
;
416 rc
= nvme_driver_init();
417 CU_ASSERT(g_spdk_nvme_driver
->initialized
== false);
418 CU_ASSERT(TAILQ_EMPTY(&g_spdk_nvme_driver
->shared_attached_ctrlrs
));
421 g_spdk_nvme_driver
= NULL
;
422 MOCK_CLEAR(spdk_memzone_reserve
);
423 MOCK_CLEAR(spdk_memzone_lookup
);
427 test_spdk_nvme_detach(void)
430 struct spdk_nvme_ctrlr ctrlr
;
431 struct spdk_nvme_ctrlr
*ret_ctrlr
;
432 struct nvme_driver test_driver
;
434 memset(&ctrlr
, 0, sizeof(ctrlr
));
435 ctrlr
.trid
.trtype
= SPDK_NVME_TRANSPORT_PCIE
;
437 g_spdk_nvme_driver
= &test_driver
;
438 TAILQ_INIT(&test_driver
.shared_attached_ctrlrs
);
439 TAILQ_INSERT_TAIL(&test_driver
.shared_attached_ctrlrs
, &ctrlr
, tailq
);
440 CU_ASSERT(pthread_mutex_init(&test_driver
.lock
, NULL
) == 0);
443 * Controllers are ref counted so mock the function that returns
444 * the ref count so that detach will actually call the destruct
445 * function which we've mocked simply to verify that it gets
446 * called (we aren't testing what the real destruct function does
449 MOCK_SET(nvme_ctrlr_get_ref_count
, 0);
450 rc
= spdk_nvme_detach(&ctrlr
);
451 ret_ctrlr
= TAILQ_FIRST(&test_driver
.shared_attached_ctrlrs
);
452 CU_ASSERT(ret_ctrlr
== NULL
);
453 CU_ASSERT(ut_destruct_called
== true);
457 * Mock the ref count to 1 so we confirm that the destruct
458 * function is not called and that attached ctrl list is
461 MOCK_SET(nvme_ctrlr_get_ref_count
, 1);
462 TAILQ_INSERT_TAIL(&test_driver
.shared_attached_ctrlrs
, &ctrlr
, tailq
);
463 ut_destruct_called
= false;
464 rc
= spdk_nvme_detach(&ctrlr
);
465 ret_ctrlr
= TAILQ_FIRST(&test_driver
.shared_attached_ctrlrs
);
466 CU_ASSERT(ret_ctrlr
!= NULL
);
467 CU_ASSERT(ut_destruct_called
== false);
471 * Non-PCIe controllers should be on the per-process attached_ctrlrs list, not the
472 * shared_attached_ctrlrs list. Test an RDMA controller and ensure it is removed
473 * from the correct list.
475 memset(&ctrlr
, 0, sizeof(ctrlr
));
476 ctrlr
.trid
.trtype
= SPDK_NVME_TRANSPORT_RDMA
;
477 TAILQ_INIT(&g_nvme_attached_ctrlrs
);
478 TAILQ_INSERT_TAIL(&g_nvme_attached_ctrlrs
, &ctrlr
, tailq
);
479 MOCK_SET(nvme_ctrlr_get_ref_count
, 0);
480 rc
= spdk_nvme_detach(&ctrlr
);
481 CU_ASSERT(TAILQ_EMPTY(&g_nvme_attached_ctrlrs
));
482 CU_ASSERT(ut_destruct_called
== true);
485 g_spdk_nvme_driver
= NULL
;
486 pthread_mutex_destroy(&test_driver
.lock
);
490 test_nvme_completion_poll_cb(void)
492 struct nvme_completion_poll_status status
;
493 struct spdk_nvme_cpl cpl
;
495 memset(&status
, 0x0, sizeof(status
));
496 memset(&cpl
, 0xff, sizeof(cpl
));
498 nvme_completion_poll_cb(&status
, &cpl
);
499 CU_ASSERT(status
.done
== true);
500 CU_ASSERT(memcmp(&cpl
, &status
.cpl
,
501 sizeof(struct spdk_nvme_cpl
)) == 0);
504 /* stub callback used by test_nvme_user_copy_cmd_complete() */
505 static struct spdk_nvme_cpl ut_spdk_nvme_cpl
= {0};
507 dummy_cb(void *user_cb_arg
, struct spdk_nvme_cpl
*cpl
)
509 ut_spdk_nvme_cpl
= *cpl
;
513 test_nvme_user_copy_cmd_complete(void)
515 struct nvme_request req
;
516 int test_data
= 0xdeadbeef;
517 int buff_size
= sizeof(int);
519 static struct spdk_nvme_cpl cpl
;
521 memset(&req
, 0, sizeof(req
));
522 memset(&cpl
, 0x5a, sizeof(cpl
));
524 /* test without a user buffer provided */
525 req
.user_cb_fn
= (void *)dummy_cb
;
526 nvme_user_copy_cmd_complete(&req
, &cpl
);
527 CU_ASSERT(memcmp(&ut_spdk_nvme_cpl
, &cpl
, sizeof(cpl
)) == 0);
529 /* test with a user buffer provided */
530 req
.user_buffer
= malloc(buff_size
);
531 SPDK_CU_ASSERT_FATAL(req
.user_buffer
!= NULL
);
532 memset(req
.user_buffer
, 0, buff_size
);
533 req
.payload_size
= buff_size
;
534 buff
= spdk_dma_zmalloc(buff_size
, 0x100, NULL
);
535 SPDK_CU_ASSERT_FATAL(buff
!= NULL
);
536 req
.payload
= NVME_PAYLOAD_CONTIG(buff
, NULL
);
537 memcpy(buff
, &test_data
, buff_size
);
538 req
.cmd
.opc
= SPDK_NVME_OPC_GET_LOG_PAGE
;
541 /* zero out the test value set in the callback */
542 memset(&ut_spdk_nvme_cpl
, 0, sizeof(ut_spdk_nvme_cpl
));
544 nvme_user_copy_cmd_complete(&req
, &cpl
);
545 CU_ASSERT(memcmp(req
.user_buffer
, &test_data
, buff_size
) == 0);
546 CU_ASSERT(memcmp(&ut_spdk_nvme_cpl
, &cpl
, sizeof(cpl
)) == 0);
549 * Now test the same path as above but this time choose an opc
550 * that results in a different data transfer type.
552 memset(&ut_spdk_nvme_cpl
, 0, sizeof(ut_spdk_nvme_cpl
));
553 memset(req
.user_buffer
, 0, buff_size
);
554 buff
= spdk_dma_zmalloc(buff_size
, 0x100, NULL
);
555 SPDK_CU_ASSERT_FATAL(buff
!= NULL
);
556 req
.payload
= NVME_PAYLOAD_CONTIG(buff
, NULL
);
557 memcpy(buff
, &test_data
, buff_size
);
558 req
.cmd
.opc
= SPDK_NVME_OPC_SET_FEATURES
;
559 nvme_user_copy_cmd_complete(&req
, &cpl
);
560 CU_ASSERT(memcmp(req
.user_buffer
, &test_data
, buff_size
) != 0);
561 CU_ASSERT(memcmp(&ut_spdk_nvme_cpl
, &cpl
, sizeof(cpl
)) == 0);
564 free(req
.user_buffer
);
568 test_nvme_allocate_request_null(void)
570 struct spdk_nvme_qpair qpair
;
571 spdk_nvme_cmd_cb cb_fn
= (spdk_nvme_cmd_cb
)0x1234;
572 void *cb_arg
= (void *)0x5678;
573 struct nvme_request
*req
= NULL
;
574 struct nvme_request dummy_req
;
576 STAILQ_INIT(&qpair
.free_req
);
577 STAILQ_INIT(&qpair
.queued_req
);
580 * Put a dummy on the queue so we can make a request
581 * and confirm that what comes back is what we expect.
583 STAILQ_INSERT_HEAD(&qpair
.free_req
, &dummy_req
, stailq
);
585 req
= nvme_allocate_request_null(&qpair
, cb_fn
, cb_arg
);
588 * Compare the req with the parmaters that we passed in
589 * as well as what the function is supposed to update.
591 SPDK_CU_ASSERT_FATAL(req
!= NULL
);
592 CU_ASSERT(req
->cb_fn
== cb_fn
);
593 CU_ASSERT(req
->cb_arg
== cb_arg
);
594 CU_ASSERT(req
->pid
== getpid());
595 CU_ASSERT(nvme_payload_type(&req
->payload
) == NVME_PAYLOAD_TYPE_CONTIG
);
596 CU_ASSERT(req
->payload
.md
== NULL
);
597 CU_ASSERT(req
->payload
.contig_or_cb_arg
== NULL
);
601 test_nvme_allocate_request(void)
603 struct spdk_nvme_qpair qpair
;
604 struct nvme_payload payload
;
605 uint32_t payload_struct_size
= sizeof(payload
);
606 spdk_nvme_cmd_cb cb_fn
= (spdk_nvme_cmd_cb
)0x1234;
607 void *cb_arg
= (void *)0x6789;
608 struct nvme_request
*req
= NULL
;
609 struct nvme_request dummy_req
;
611 /* Fill the whole payload struct with a known pattern */
612 memset(&payload
, 0x5a, payload_struct_size
);
613 STAILQ_INIT(&qpair
.free_req
);
614 STAILQ_INIT(&qpair
.queued_req
);
616 /* Test trying to allocate a request when no requests are available */
617 req
= nvme_allocate_request(&qpair
, &payload
, payload_struct_size
,
619 CU_ASSERT(req
== NULL
);
621 /* put a dummy on the queue, and then allocate one */
622 STAILQ_INSERT_HEAD(&qpair
.free_req
, &dummy_req
, stailq
);
623 req
= nvme_allocate_request(&qpair
, &payload
, payload_struct_size
,
626 /* all the req elements should now match the passed in parameters */
627 SPDK_CU_ASSERT_FATAL(req
!= NULL
);
628 CU_ASSERT(req
->cb_fn
== cb_fn
);
629 CU_ASSERT(req
->cb_arg
== cb_arg
);
630 CU_ASSERT(memcmp(&req
->payload
, &payload
, payload_struct_size
) == 0);
631 CU_ASSERT(req
->payload_size
== payload_struct_size
);
632 CU_ASSERT(req
->pid
== getpid());
636 test_nvme_free_request(void)
638 struct nvme_request match_req
;
639 struct spdk_nvme_qpair qpair
;
640 struct nvme_request
*req
;
642 /* put a req on the Q, take it off and compare */
643 memset(&match_req
.cmd
, 0x5a, sizeof(struct spdk_nvme_cmd
));
644 match_req
.qpair
= &qpair
;
645 /* the code under tests asserts this condition */
646 match_req
.num_children
= 0;
647 STAILQ_INIT(&qpair
.free_req
);
649 nvme_free_request(&match_req
);
650 req
= STAILQ_FIRST(&match_req
.qpair
->free_req
);
651 CU_ASSERT(req
== &match_req
);
655 test_nvme_allocate_request_user_copy(void)
657 struct spdk_nvme_qpair qpair
;
658 spdk_nvme_cmd_cb cb_fn
= (spdk_nvme_cmd_cb
)0x12345;
659 void *cb_arg
= (void *)0x12345;
660 bool host_to_controller
= true;
661 struct nvme_request
*req
;
662 struct nvme_request dummy_req
;
663 int test_data
= 0xdeadbeef;
665 uint32_t payload_size
= sizeof(int);
667 STAILQ_INIT(&qpair
.free_req
);
668 STAILQ_INIT(&qpair
.queued_req
);
670 /* no buffer or valid payload size, early NULL return */
671 req
= nvme_allocate_request_user_copy(&qpair
, buffer
, payload_size
, cb_fn
,
672 cb_arg
, host_to_controller
);
673 CU_ASSERT(req
== NULL
);
675 /* good buffer and valid payload size */
676 buffer
= malloc(payload_size
);
677 SPDK_CU_ASSERT_FATAL(buffer
!= NULL
);
678 memcpy(buffer
, &test_data
, payload_size
);
680 /* put a dummy on the queue */
681 STAILQ_INSERT_HEAD(&qpair
.free_req
, &dummy_req
, stailq
);
683 MOCK_CLEAR(spdk_malloc
);
684 MOCK_CLEAR(spdk_zmalloc
);
685 req
= nvme_allocate_request_user_copy(&qpair
, buffer
, payload_size
, cb_fn
,
686 cb_arg
, host_to_controller
);
687 SPDK_CU_ASSERT_FATAL(req
!= NULL
);
688 CU_ASSERT(req
->user_cb_fn
== cb_fn
);
689 CU_ASSERT(req
->user_cb_arg
== cb_arg
);
690 CU_ASSERT(req
->user_buffer
== buffer
);
691 CU_ASSERT(req
->cb_arg
== req
);
692 CU_ASSERT(memcmp(req
->payload
.contig_or_cb_arg
, buffer
, payload_size
) == 0);
693 spdk_dma_free(req
->payload
.contig_or_cb_arg
);
695 /* same thing but additional path coverage, no copy */
696 host_to_controller
= false;
697 STAILQ_INSERT_HEAD(&qpair
.free_req
, &dummy_req
, stailq
);
699 req
= nvme_allocate_request_user_copy(&qpair
, buffer
, payload_size
, cb_fn
,
700 cb_arg
, host_to_controller
);
701 SPDK_CU_ASSERT_FATAL(req
!= NULL
);
702 CU_ASSERT(req
->user_cb_fn
== cb_fn
);
703 CU_ASSERT(req
->user_cb_arg
== cb_arg
);
704 CU_ASSERT(req
->user_buffer
== buffer
);
705 CU_ASSERT(req
->cb_arg
== req
);
706 CU_ASSERT(memcmp(req
->payload
.contig_or_cb_arg
, buffer
, payload_size
) != 0);
707 spdk_dma_free(req
->payload
.contig_or_cb_arg
);
709 /* good buffer and valid payload size but make spdk_dma_zmalloc fail */
710 /* set the mock pointer to NULL for spdk_dma_zmalloc */
711 MOCK_SET(spdk_dma_zmalloc
, NULL
);
712 req
= nvme_allocate_request_user_copy(&qpair
, buffer
, payload_size
, cb_fn
,
713 cb_arg
, host_to_controller
);
714 CU_ASSERT(req
== NULL
);
716 MOCK_CLEAR(spdk_dma_zmalloc
);
720 test_nvme_ctrlr_probe(void)
723 struct spdk_nvme_ctrlr ctrlr
= {};
724 const struct spdk_nvme_transport_id trid
= {};
725 struct spdk_nvme_probe_ctx probe_ctx
= {};
726 void *devhandle
= NULL
;
728 struct spdk_nvme_ctrlr
*dummy
= NULL
;
732 /* test when probe_cb returns false */
734 MOCK_SET(dummy_probe_cb
, false);
735 spdk_nvme_probe_ctx_init(&probe_ctx
, &trid
, cb_ctx
, dummy_probe_cb
, NULL
, NULL
);
736 rc
= nvme_ctrlr_probe(&trid
, &probe_ctx
, devhandle
);
739 /* probe_cb returns true but we can't construct a ctrl */
740 MOCK_SET(dummy_probe_cb
, true);
741 MOCK_SET(nvme_transport_ctrlr_construct
, NULL
);
742 spdk_nvme_probe_ctx_init(&probe_ctx
, &trid
, cb_ctx
, dummy_probe_cb
, NULL
, NULL
);
743 rc
= nvme_ctrlr_probe(&trid
, &probe_ctx
, devhandle
);
747 MOCK_SET(dummy_probe_cb
, true);
748 MOCK_SET(nvme_transport_ctrlr_construct
, &ctrlr
);
749 spdk_nvme_probe_ctx_init(&probe_ctx
, &trid
, cb_ctx
, dummy_probe_cb
, NULL
, NULL
);
750 rc
= nvme_ctrlr_probe(&trid
, &probe_ctx
, devhandle
);
752 dummy
= TAILQ_FIRST(&probe_ctx
.init_ctrlrs
);
753 CU_ASSERT(dummy
== ut_nvme_transport_ctrlr_construct
);
754 TAILQ_REMOVE(&probe_ctx
.init_ctrlrs
, dummy
, tailq
);
755 MOCK_CLEAR_P(nvme_transport_ctrlr_construct
);
757 free(g_spdk_nvme_driver
);
761 test_nvme_robust_mutex_init_shared(void)
766 /* test where both pthread calls succeed */
767 MOCK_SET(pthread_mutexattr_init
, 0);
768 MOCK_SET(pthread_mutex_init
, 0);
769 rc
= nvme_robust_mutex_init_shared(&mtx
);
772 /* test where we can't init attr's but init mutex works */
773 MOCK_SET(pthread_mutexattr_init
, -1);
774 MOCK_SET(pthread_mutex_init
, 0);
775 rc
= nvme_robust_mutex_init_shared(&mtx
);
776 /* for FreeBSD the only possible return value is 0 */
783 /* test where we can init attr's but the mutex init fails */
784 MOCK_SET(pthread_mutexattr_init
, 0);
785 MOCK_SET(pthread_mutex_init
, -1);
786 rc
= nvme_robust_mutex_init_shared(&mtx
);
787 /* for FreeBSD the only possible return value is 0 */
796 test_opc_data_transfer(void)
798 enum spdk_nvme_data_transfer xfer
;
800 xfer
= spdk_nvme_opc_get_data_transfer(SPDK_NVME_OPC_FLUSH
);
801 CU_ASSERT(xfer
== SPDK_NVME_DATA_NONE
);
803 xfer
= spdk_nvme_opc_get_data_transfer(SPDK_NVME_OPC_WRITE
);
804 CU_ASSERT(xfer
== SPDK_NVME_DATA_HOST_TO_CONTROLLER
);
806 xfer
= spdk_nvme_opc_get_data_transfer(SPDK_NVME_OPC_READ
);
807 CU_ASSERT(xfer
== SPDK_NVME_DATA_CONTROLLER_TO_HOST
);
809 xfer
= spdk_nvme_opc_get_data_transfer(SPDK_NVME_OPC_GET_LOG_PAGE
);
810 CU_ASSERT(xfer
== SPDK_NVME_DATA_CONTROLLER_TO_HOST
);
814 test_trid_parse_and_compare(void)
816 struct spdk_nvme_transport_id trid1
, trid2
;
819 /* set trid1 trid2 value to id parse */
820 ret
= spdk_nvme_transport_id_parse(NULL
, "trtype:PCIe traddr:0000:04:00.0");
821 CU_ASSERT(ret
== -EINVAL
);
822 memset(&trid1
, 0, sizeof(trid1
));
823 ret
= spdk_nvme_transport_id_parse(&trid1
, NULL
);
824 CU_ASSERT(ret
== -EINVAL
);
825 ret
= spdk_nvme_transport_id_parse(NULL
, NULL
);
826 CU_ASSERT(ret
== -EINVAL
);
827 memset(&trid1
, 0, sizeof(trid1
));
828 ret
= spdk_nvme_transport_id_parse(&trid1
, "trtype-PCIe traddr-0000-04-00.0");
829 CU_ASSERT(ret
== -EINVAL
);
830 memset(&trid1
, 0, sizeof(trid1
));
831 ret
= spdk_nvme_transport_id_parse(&trid1
, "trtype-PCIe traddr-0000-04-00.0-:");
832 CU_ASSERT(ret
== -EINVAL
);
833 memset(&trid1
, 0, sizeof(trid1
));
834 ret
= spdk_nvme_transport_id_parse(&trid1
, " \t\n:");
835 CU_ASSERT(ret
== -EINVAL
);
836 memset(&trid1
, 0, sizeof(trid1
));
837 CU_ASSERT(spdk_nvme_transport_id_parse(&trid1
,
840 "traddr:192.168.100.8\n"
842 "subnqn:nqn.2014-08.org.nvmexpress.discovery") == 0);
843 CU_ASSERT(trid1
.trtype
== SPDK_NVME_TRANSPORT_RDMA
);
844 CU_ASSERT(trid1
.adrfam
== SPDK_NVMF_ADRFAM_IPV4
);
845 CU_ASSERT(strcmp(trid1
.traddr
, "192.168.100.8") == 0);
846 CU_ASSERT(strcmp(trid1
.trsvcid
, "4420") == 0);
847 CU_ASSERT(strcmp(trid1
.subnqn
, "nqn.2014-08.org.nvmexpress.discovery") == 0);
849 memset(&trid2
, 0, sizeof(trid2
));
850 CU_ASSERT(spdk_nvme_transport_id_parse(&trid2
, "trtype:PCIe traddr:0000:04:00.0") == 0);
851 CU_ASSERT(trid2
.trtype
== SPDK_NVME_TRANSPORT_PCIE
);
852 CU_ASSERT(strcmp(trid2
.traddr
, "0000:04:00.0") == 0);
854 CU_ASSERT(spdk_nvme_transport_id_compare(&trid1
, &trid2
) != 0);
856 /* set trid1 trid2 and test id_compare */
857 memset_trid(&trid1
, &trid2
);
858 trid1
.adrfam
= SPDK_NVMF_ADRFAM_IPV6
;
859 trid2
.adrfam
= SPDK_NVMF_ADRFAM_IPV4
;
860 ret
= spdk_nvme_transport_id_compare(&trid1
, &trid2
);
863 memset_trid(&trid1
, &trid2
);
864 snprintf(trid1
.traddr
, sizeof(trid1
.traddr
), "192.168.100.8");
865 snprintf(trid2
.traddr
, sizeof(trid2
.traddr
), "192.168.100.9");
866 ret
= spdk_nvme_transport_id_compare(&trid1
, &trid2
);
869 memset_trid(&trid1
, &trid2
);
870 snprintf(trid1
.trsvcid
, sizeof(trid1
.trsvcid
), "4420");
871 snprintf(trid2
.trsvcid
, sizeof(trid2
.trsvcid
), "4421");
872 ret
= spdk_nvme_transport_id_compare(&trid1
, &trid2
);
875 memset_trid(&trid1
, &trid2
);
876 snprintf(trid1
.subnqn
, sizeof(trid1
.subnqn
), "subnqn:nqn.2016-08.org.nvmexpress.discovery");
877 snprintf(trid2
.subnqn
, sizeof(trid2
.subnqn
), "subnqn:nqn.2017-08.org.nvmexpress.discovery");
878 ret
= spdk_nvme_transport_id_compare(&trid1
, &trid2
);
881 memset_trid(&trid1
, &trid2
);
882 snprintf(trid1
.subnqn
, sizeof(trid1
.subnqn
), "subnqn:nqn.2016-08.org.nvmexpress.discovery");
883 snprintf(trid2
.subnqn
, sizeof(trid2
.subnqn
), "subnqn:nqn.2016-08.org.nvmexpress.discovery");
884 ret
= spdk_nvme_transport_id_compare(&trid1
, &trid2
);
887 memset_trid(&trid1
, &trid2
);
888 snprintf(trid1
.subnqn
, sizeof(trid1
.subnqn
), "subnqn:nqn.2016-08.org.nvmexpress.discovery");
889 snprintf(trid2
.subnqn
, sizeof(trid2
.subnqn
), "subnqn:nqn.2016-08.org.Nvmexpress.discovery");
890 ret
= spdk_nvme_transport_id_compare(&trid1
, &trid2
);
893 memset_trid(&trid1
, &trid2
);
894 ret
= spdk_nvme_transport_id_compare(&trid1
, &trid2
);
897 /* Compare PCI addresses via spdk_pci_addr_compare (rather than as strings) */
898 memset_trid(&trid1
, &trid2
);
899 CU_ASSERT(spdk_nvme_transport_id_parse(&trid1
, "trtype:PCIe traddr:0000:04:00.0") == 0);
900 CU_ASSERT(spdk_nvme_transport_id_parse(&trid2
, "trtype:PCIe traddr:04:00.0") == 0);
901 CU_ASSERT(spdk_nvme_transport_id_compare(&trid1
, &trid2
) == 0);
903 memset_trid(&trid1
, &trid2
);
904 CU_ASSERT(spdk_nvme_transport_id_parse(&trid1
, "trtype:PCIe traddr:0000:05:00.0") == 0);
905 CU_ASSERT(spdk_nvme_transport_id_parse(&trid2
, "trtype:PCIe traddr:04:00.0") == 0);
906 CU_ASSERT(spdk_nvme_transport_id_compare(&trid1
, &trid2
) > 0);
908 memset_trid(&trid1
, &trid2
);
909 CU_ASSERT(spdk_nvme_transport_id_parse(&trid1
, "trtype:PCIe traddr:0000:04:00.0") == 0);
910 CU_ASSERT(spdk_nvme_transport_id_parse(&trid2
, "trtype:PCIe traddr:05:00.0") == 0);
911 CU_ASSERT(spdk_nvme_transport_id_compare(&trid1
, &trid2
) < 0);
913 memset_trid(&trid1
, &trid2
);
914 CU_ASSERT(spdk_nvme_transport_id_parse(&trid1
, "trtype=PCIe traddr=0000:04:00.0") == 0);
915 CU_ASSERT(spdk_nvme_transport_id_parse(&trid2
, "trtype=PCIe traddr=05:00.0") == 0);
916 CU_ASSERT(spdk_nvme_transport_id_compare(&trid1
, &trid2
) < 0);
920 test_spdk_nvme_transport_id_parse_trtype(void)
923 enum spdk_nvme_transport_type
*trtype
;
924 enum spdk_nvme_transport_type sct
;
930 /* test function returned value when trtype is NULL but str not NULL */
931 CU_ASSERT(spdk_nvme_transport_id_parse_trtype(trtype
, str
) == (-EINVAL
));
933 /* test function returned value when str is NULL but trtype not NULL */
936 CU_ASSERT(spdk_nvme_transport_id_parse_trtype(trtype
, str
) == (-EINVAL
));
938 /* test function returned value when str and strtype not NULL, but str value
939 * not "PCIe" or "RDMA" */
941 CU_ASSERT(spdk_nvme_transport_id_parse_trtype(trtype
, str
) == (-ENOENT
));
943 /* test trtype value when use function "strcasecmp" to compare str and "PCIe",not case-sensitive */
945 spdk_nvme_transport_id_parse_trtype(trtype
, str
);
946 CU_ASSERT((*trtype
) == SPDK_NVME_TRANSPORT_PCIE
);
949 spdk_nvme_transport_id_parse_trtype(trtype
, str
);
950 CU_ASSERT((*trtype
) == SPDK_NVME_TRANSPORT_PCIE
);
952 /* test trtype value when use function "strcasecmp" to compare str and "RDMA",not case-sensitive */
954 spdk_nvme_transport_id_parse_trtype(trtype
, str
);
955 CU_ASSERT((*trtype
) == SPDK_NVME_TRANSPORT_RDMA
);
958 spdk_nvme_transport_id_parse_trtype(trtype
, str
);
959 CU_ASSERT((*trtype
) == SPDK_NVME_TRANSPORT_RDMA
);
961 /* test trtype value when use function "strcasecmp" to compare str and "FC",not case-sensitive */
963 spdk_nvme_transport_id_parse_trtype(trtype
, str
);
964 CU_ASSERT((*trtype
) == SPDK_NVME_TRANSPORT_FC
);
967 spdk_nvme_transport_id_parse_trtype(trtype
, str
);
968 CU_ASSERT((*trtype
) == SPDK_NVME_TRANSPORT_FC
);
970 /* test trtype value when use function "strcasecmp" to compare str and "TCP",not case-sensitive */
972 spdk_nvme_transport_id_parse_trtype(trtype
, str
);
973 CU_ASSERT((*trtype
) == SPDK_NVME_TRANSPORT_TCP
);
976 spdk_nvme_transport_id_parse_trtype(trtype
, str
);
977 CU_ASSERT((*trtype
) == SPDK_NVME_TRANSPORT_TCP
);
981 test_spdk_nvme_transport_id_parse_adrfam(void)
984 enum spdk_nvmf_adrfam
*adrfam
;
985 enum spdk_nvmf_adrfam sct
;
991 /* test function returned value when adrfam is NULL but str not NULL */
992 CU_ASSERT(spdk_nvme_transport_id_parse_adrfam(adrfam
, str
) == (-EINVAL
));
994 /* test function returned value when str is NULL but adrfam not NULL */
997 CU_ASSERT(spdk_nvme_transport_id_parse_adrfam(adrfam
, str
) == (-EINVAL
));
999 /* test function returned value when str and adrfam not NULL, but str value
1000 * not "IPv4" or "IPv6" or "IB" or "FC" */
1002 CU_ASSERT(spdk_nvme_transport_id_parse_adrfam(adrfam
, str
) == (-ENOENT
));
1004 /* test adrfam value when use function "strcasecmp" to compare str and "IPv4",not case-sensitive */
1006 spdk_nvme_transport_id_parse_adrfam(adrfam
, str
);
1007 CU_ASSERT((*adrfam
) == SPDK_NVMF_ADRFAM_IPV4
);
1010 spdk_nvme_transport_id_parse_adrfam(adrfam
, str
);
1011 CU_ASSERT((*adrfam
) == SPDK_NVMF_ADRFAM_IPV4
);
1013 /* test adrfam value when use function "strcasecmp" to compare str and "IPv6",not case-sensitive */
1015 spdk_nvme_transport_id_parse_adrfam(adrfam
, str
);
1016 CU_ASSERT((*adrfam
) == SPDK_NVMF_ADRFAM_IPV6
);
1019 spdk_nvme_transport_id_parse_adrfam(adrfam
, str
);
1020 CU_ASSERT((*adrfam
) == SPDK_NVMF_ADRFAM_IPV6
);
1022 /* test adrfam value when use function "strcasecmp" to compare str and "IB",not case-sensitive */
1024 spdk_nvme_transport_id_parse_adrfam(adrfam
, str
);
1025 CU_ASSERT((*adrfam
) == SPDK_NVMF_ADRFAM_IB
);
1028 spdk_nvme_transport_id_parse_adrfam(adrfam
, str
);
1029 CU_ASSERT((*adrfam
) == SPDK_NVMF_ADRFAM_IB
);
1031 /* test adrfam value when use function "strcasecmp" to compare str and "FC",not case-sensitive */
1033 spdk_nvme_transport_id_parse_adrfam(adrfam
, str
);
1034 CU_ASSERT((*adrfam
) == SPDK_NVMF_ADRFAM_FC
);
1037 spdk_nvme_transport_id_parse_adrfam(adrfam
, str
);
1038 CU_ASSERT((*adrfam
) == SPDK_NVMF_ADRFAM_FC
);
1043 test_trid_trtype_str(void)
1047 s
= spdk_nvme_transport_id_trtype_str(-5);
1048 CU_ASSERT(s
== NULL
);
1050 s
= spdk_nvme_transport_id_trtype_str(SPDK_NVME_TRANSPORT_PCIE
);
1051 SPDK_CU_ASSERT_FATAL(s
!= NULL
);
1052 CU_ASSERT(strcmp(s
, "PCIe") == 0);
1054 s
= spdk_nvme_transport_id_trtype_str(SPDK_NVME_TRANSPORT_RDMA
);
1055 SPDK_CU_ASSERT_FATAL(s
!= NULL
);
1056 CU_ASSERT(strcmp(s
, "RDMA") == 0);
1058 s
= spdk_nvme_transport_id_trtype_str(SPDK_NVME_TRANSPORT_FC
);
1059 SPDK_CU_ASSERT_FATAL(s
!= NULL
);
1060 CU_ASSERT(strcmp(s
, "FC") == 0);
1062 s
= spdk_nvme_transport_id_trtype_str(SPDK_NVME_TRANSPORT_TCP
);
1063 SPDK_CU_ASSERT_FATAL(s
!= NULL
);
1064 CU_ASSERT(strcmp(s
, "TCP") == 0);
1068 test_trid_adrfam_str(void)
1072 s
= spdk_nvme_transport_id_adrfam_str(-5);
1073 CU_ASSERT(s
== NULL
);
1075 s
= spdk_nvme_transport_id_adrfam_str(SPDK_NVMF_ADRFAM_IPV4
);
1076 SPDK_CU_ASSERT_FATAL(s
!= NULL
);
1077 CU_ASSERT(strcmp(s
, "IPv4") == 0);
1079 s
= spdk_nvme_transport_id_adrfam_str(SPDK_NVMF_ADRFAM_IPV6
);
1080 SPDK_CU_ASSERT_FATAL(s
!= NULL
);
1081 CU_ASSERT(strcmp(s
, "IPv6") == 0);
1083 s
= spdk_nvme_transport_id_adrfam_str(SPDK_NVMF_ADRFAM_IB
);
1084 SPDK_CU_ASSERT_FATAL(s
!= NULL
);
1085 CU_ASSERT(strcmp(s
, "IB") == 0);
1087 s
= spdk_nvme_transport_id_adrfam_str(SPDK_NVMF_ADRFAM_FC
);
1088 SPDK_CU_ASSERT_FATAL(s
!= NULL
);
1089 CU_ASSERT(strcmp(s
, "FC") == 0);
1092 /* stub callback used by the test_nvme_request_check_timeout */
1093 static bool ut_timeout_cb_call
= false;
1095 dummy_timeout_cb(void *cb_arg
, struct spdk_nvme_ctrlr
*ctrlr
,
1096 struct spdk_nvme_qpair
*qpair
, uint16_t cid
)
1098 ut_timeout_cb_call
= true;
1102 test_nvme_request_check_timeout(void)
1105 struct spdk_nvme_qpair qpair
;
1106 struct nvme_request req
;
1107 struct spdk_nvme_ctrlr_process active_proc
;
1109 uint64_t now_tick
= 0;
1111 memset(&qpair
, 0x0, sizeof(qpair
));
1112 memset(&req
, 0x0, sizeof(req
));
1113 memset(&active_proc
, 0x0, sizeof(active_proc
));
1115 active_proc
.timeout_cb_fn
= dummy_timeout_cb
;
1117 /* if have called timeout_cb_fn then return directly */
1118 req
.timed_out
= true;
1119 rc
= nvme_request_check_timeout(&req
, cid
, &active_proc
, now_tick
);
1121 CU_ASSERT(ut_timeout_cb_call
== false);
1123 /* if timeout isn't enabled then return directly */
1124 req
.timed_out
= false;
1125 req
.submit_tick
= 0;
1126 rc
= nvme_request_check_timeout(&req
, cid
, &active_proc
, now_tick
);
1128 CU_ASSERT(ut_timeout_cb_call
== false);
1130 /* req->pid isn't right then return directly */
1131 req
.submit_tick
= 1;
1132 req
.pid
= g_spdk_nvme_pid
+ 1;
1133 rc
= nvme_request_check_timeout(&req
, cid
, &active_proc
, now_tick
);
1135 CU_ASSERT(ut_timeout_cb_call
== false);
1137 /* AER command has no timeout */
1138 req
.pid
= g_spdk_nvme_pid
;
1139 req
.cmd
.opc
= SPDK_NVME_OPC_ASYNC_EVENT_REQUEST
;
1140 rc
= nvme_request_check_timeout(&req
, cid
, &active_proc
, now_tick
);
1142 CU_ASSERT(ut_timeout_cb_call
== false);
1144 /* time isn't out */
1146 rc
= nvme_request_check_timeout(&req
, cid
, &active_proc
, now_tick
);
1148 CU_ASSERT(ut_timeout_cb_call
== false);
1151 rc
= nvme_request_check_timeout(&req
, cid
, &active_proc
, now_tick
);
1152 CU_ASSERT(req
.timed_out
== true);
1153 CU_ASSERT(ut_timeout_cb_call
== true);
1157 struct nvme_completion_poll_status g_status
;
1158 uint64_t completion_delay
, timeout_in_secs
;
1160 spdk_nvme_qpair_process_completions(struct spdk_nvme_qpair
*qpair
, uint32_t max_completions
)
1162 spdk_delay_us(completion_delay
* spdk_get_ticks_hz());
1164 g_status
.done
= completion_delay
< timeout_in_secs
? true : false;
1170 test_nvme_wait_for_completion(void)
1172 struct spdk_nvme_qpair qpair
;
1175 memset(&qpair
, 0, sizeof(qpair
));
1176 memset(&g_status
, 0, sizeof(g_status
));
1178 /* completion timeout */
1179 completion_delay
= 2;
1180 timeout_in_secs
= 1;
1181 g_status
.done
= true;
1182 rc
= spdk_nvme_wait_for_completion_timeout(&qpair
, &g_status
, timeout_in_secs
);
1183 CU_ASSERT(g_status
.done
== false);
1184 CU_ASSERT(rc
== -EIO
);
1186 /* complete in time */
1187 completion_delay
= 1;
1188 timeout_in_secs
= 2;
1189 rc
= spdk_nvme_wait_for_completion_timeout(&qpair
, &g_status
, timeout_in_secs
);
1190 CU_ASSERT(g_status
.done
== true);
1194 int main(int argc
, char **argv
)
1196 CU_pSuite suite
= NULL
;
1197 unsigned int num_failures
;
1199 if (CU_initialize_registry() != CUE_SUCCESS
) {
1200 return CU_get_error();
1203 suite
= CU_add_suite("nvme", NULL
, NULL
);
1204 if (suite
== NULL
) {
1205 CU_cleanup_registry();
1206 return CU_get_error();
1210 CU_add_test(suite
, "test_opc_data_transfer",
1211 test_opc_data_transfer
) == NULL
||
1212 CU_add_test(suite
, "test_spdk_nvme_transport_id_parse_trtype",
1213 test_spdk_nvme_transport_id_parse_trtype
) == NULL
||
1214 CU_add_test(suite
, "test_spdk_nvme_transport_id_parse_adrfam",
1215 test_spdk_nvme_transport_id_parse_adrfam
) == NULL
||
1216 CU_add_test(suite
, "test_trid_parse_and_compare",
1217 test_trid_parse_and_compare
) == NULL
||
1218 CU_add_test(suite
, "test_trid_trtype_str",
1219 test_trid_trtype_str
) == NULL
||
1220 CU_add_test(suite
, "test_trid_adrfam_str",
1221 test_trid_adrfam_str
) == NULL
||
1222 CU_add_test(suite
, "test_nvme_ctrlr_probe",
1223 test_nvme_ctrlr_probe
) == NULL
||
1224 CU_add_test(suite
, "test_spdk_nvme_probe",
1225 test_spdk_nvme_probe
) == NULL
||
1226 CU_add_test(suite
, "test_spdk_nvme_connect",
1227 test_spdk_nvme_connect
) == NULL
||
1228 CU_add_test(suite
, "test_nvme_init_controllers",
1229 test_nvme_init_controllers
) == NULL
||
1230 CU_add_test(suite
, "test_nvme_driver_init",
1231 test_nvme_driver_init
) == NULL
||
1232 CU_add_test(suite
, "test_spdk_nvme_detach",
1233 test_spdk_nvme_detach
) == NULL
||
1234 CU_add_test(suite
, "test_nvme_completion_poll_cb",
1235 test_nvme_completion_poll_cb
) == NULL
||
1236 CU_add_test(suite
, "test_nvme_user_copy_cmd_complete",
1237 test_nvme_user_copy_cmd_complete
) == NULL
||
1238 CU_add_test(suite
, "test_nvme_allocate_request_null",
1239 test_nvme_allocate_request_null
) == NULL
||
1240 CU_add_test(suite
, "test_nvme_allocate_request",
1241 test_nvme_allocate_request
) == NULL
||
1242 CU_add_test(suite
, "test_nvme_free_request",
1243 test_nvme_free_request
) == NULL
||
1244 CU_add_test(suite
, "test_nvme_allocate_request_user_copy",
1245 test_nvme_allocate_request_user_copy
) == NULL
||
1246 CU_add_test(suite
, "test_nvme_robust_mutex_init_shared",
1247 test_nvme_robust_mutex_init_shared
) == NULL
||
1248 CU_add_test(suite
, "test_nvme_request_check_timeout",
1249 test_nvme_request_check_timeout
) == NULL
||
1250 CU_add_test(suite
, "test_nvme_wait_for_completion",
1251 test_nvme_wait_for_completion
) == NULL
1253 CU_cleanup_registry();
1254 return CU_get_error();
1257 CU_basic_set_mode(CU_BRM_VERBOSE
);
1258 CU_basic_run_tests();
1259 num_failures
= CU_get_number_of_failures();
1260 CU_cleanup_registry();
1261 return num_failures
;