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.
39 #include "spdk_cunit.h"
45 SPDK_LOG_REGISTER_TRACE_FLAG("scsi", SPDK_TRACE_SCSI
)
47 struct spdk_scsi_globals g_spdk_scsi
;
49 static bool g_lun_execute_fail
= false;
50 static int g_lun_execute_status
= SPDK_SCSI_TASK_PENDING
;
51 static uint32_t g_task_count
= 0;
54 spdk_poller_register(struct spdk_poller
**ppoller
, spdk_poller_fn fn
, void *arg
,
55 uint32_t lcore
, uint64_t period_microseconds
)
60 spdk_poller_unregister(struct spdk_poller
**ppoller
,
61 struct spdk_event
*complete
)
66 spdk_env_get_current_core(void)
71 void spdk_trace_record(uint16_t tpoint_id
, uint16_t poller_id
, uint32_t size
,
72 uint64_t object_id
, uint64_t arg1
)
77 spdk_lun_ut_free_task(struct spdk_scsi_task
*task
)
82 static struct spdk_scsi_task
*
83 spdk_get_task(uint32_t *owner_task_ctr
)
85 struct spdk_scsi_task
*task
;
87 task
= calloc(1, sizeof(*task
));
92 spdk_scsi_task_construct(task
, &g_task_count
, NULL
);
93 task
->free_fn
= spdk_lun_ut_free_task
;
99 spdk_malloc(size_t size
, size_t align
, uint64_t *phys_addr
)
101 void *buf
= malloc(size
);
103 *phys_addr
= (uint64_t)buf
;
108 spdk_zmalloc(size_t size
, size_t align
, uint64_t *phys_addr
)
110 void *buf
= calloc(size
, 1);
112 *phys_addr
= (uint64_t)buf
;
123 spdk_bdev_free_io(struct spdk_bdev_io
*bdev_io
)
130 spdk_bdev_claim(struct spdk_bdev
*bdev
, spdk_bdev_remove_cb_t remove_cb
,
137 spdk_bdev_unclaim(struct spdk_bdev
*bdev
)
141 void spdk_scsi_dev_queue_mgmt_task(struct spdk_scsi_dev
*dev
,
142 struct spdk_scsi_task
*task
)
146 void spdk_scsi_dev_delete_lun(struct spdk_scsi_dev
*dev
,
147 struct spdk_scsi_lun
*lun
)
153 spdk_bdev_scsi_reset(struct spdk_bdev
*bdev
, struct spdk_scsi_task
*task
)
159 spdk_bdev_scsi_execute(struct spdk_bdev
*bdev
, struct spdk_scsi_task
*task
)
161 if (g_lun_execute_fail
)
164 task
->status
= SPDK_SCSI_STATUS_GOOD
;
166 if (g_lun_execute_status
== SPDK_SCSI_TASK_PENDING
)
167 return g_lun_execute_status
;
168 else if (g_lun_execute_status
== SPDK_SCSI_TASK_COMPLETE
)
169 return g_lun_execute_status
;
175 void spdk_bdev_unregister(struct spdk_bdev
*bdev
)
179 struct spdk_io_channel
*
180 spdk_bdev_get_io_channel(struct spdk_bdev
*bdev
, uint32_t priority
)
186 spdk_put_io_channel(struct spdk_io_channel
*ch
)
190 void spdk_event_call(struct spdk_event
*event
)
194 static _spdk_scsi_lun
*
197 struct spdk_scsi_lun
*lun
;
198 struct spdk_bdev bdev
;
200 lun
= spdk_scsi_lun_construct("lun0", &bdev
);
202 SPDK_CU_ASSERT_FATAL(lun
!= NULL
);
204 SPDK_CU_ASSERT_FATAL(TAILQ_EMPTY(&lun
->pending_tasks
));
211 lun_destruct(struct spdk_scsi_lun
*lun
)
213 spdk_scsi_lun_destruct(lun
);
217 lun_task_mgmt_execute_null_task(void)
221 rc
= spdk_scsi_lun_task_mgmt_execute(NULL
);
223 /* returns -1 since we passed NULL for the task */
224 CU_ASSERT_TRUE(rc
< 0);
225 CU_ASSERT_EQUAL(g_task_count
, 0);
229 lun_task_mgmt_execute_abort_task_null_lun_failure(void)
231 struct spdk_scsi_task
*mgmt_task
;
232 struct spdk_scsi_port initiator_port
= { 0 };
235 mgmt_task
= spdk_get_task(NULL
);
236 mgmt_task
->function
= SPDK_SCSI_TASK_FUNC_ABORT_TASK
;
237 mgmt_task
->lun
= NULL
;
238 mgmt_task
->initiator_port
= &initiator_port
;
240 rc
= spdk_scsi_lun_task_mgmt_execute(mgmt_task
);
242 spdk_scsi_task_put(mgmt_task
);
244 /* returns -1 since we passed NULL for LUN */
245 CU_ASSERT_TRUE(rc
< 0);
246 CU_ASSERT_EQUAL(g_task_count
, 0);
250 lun_task_mgmt_execute_abort_task_not_supported(void)
252 struct spdk_scsi_lun
*lun
;
253 struct spdk_scsi_task
*task
;
254 struct spdk_scsi_task
*mgmt_task
;
255 struct spdk_scsi_port initiator_port
= { 0 };
256 struct spdk_scsi_dev dev
= { 0 };
257 uint8_t cdb
[6] = { 0 };
260 lun
= lun_construct();
263 mgmt_task
= spdk_get_task(NULL
);
264 mgmt_task
->type
= SPDK_SCSI_TASK_TYPE_MANAGE
;
265 mgmt_task
->function
= SPDK_SCSI_TASK_FUNC_ABORT_TASK
;
266 mgmt_task
->lun
= lun
;
267 mgmt_task
->initiator_port
= &initiator_port
;
269 /* Params to add regular task to the lun->tasks */
270 task
= spdk_get_task(NULL
);
274 /* Set the task's id and abort_id to the same value */
275 mgmt_task
->abort_id
= task
->id
;
277 spdk_scsi_lun_append_task(lun
, task
);
279 /* task should now be on the pending_task list */
280 CU_ASSERT(!TAILQ_EMPTY(&lun
->pending_tasks
));
282 spdk_scsi_lun_execute_tasks(lun
);
284 /*task should now be on the tasks list */
285 CU_ASSERT(!TAILQ_EMPTY(&lun
->tasks
));
287 rc
= spdk_scsi_lun_task_mgmt_execute(mgmt_task
);
289 /* returns -1 since task abort is not supported */
290 CU_ASSERT_TRUE(rc
< 0);
291 CU_ASSERT(mgmt_task
->response
== SPDK_SCSI_TASK_MGMT_RESP_REJECT_FUNC_NOT_SUPPORTED
);
293 spdk_scsi_task_put(mgmt_task
);
294 spdk_scsi_task_put(task
);
298 CU_ASSERT_EQUAL(g_task_count
, 0);
302 lun_task_mgmt_execute_abort_task_all_null_lun_failure(void)
304 struct spdk_scsi_task
*mgmt_task
;
305 struct spdk_scsi_port initiator_port
= { 0 };
308 mgmt_task
= spdk_get_task(NULL
);
309 mgmt_task
->function
= SPDK_SCSI_TASK_FUNC_ABORT_TASK_SET
;
310 mgmt_task
->lun
= NULL
;
311 mgmt_task
->initiator_port
= &initiator_port
;
313 rc
= spdk_scsi_lun_task_mgmt_execute(mgmt_task
);
315 /* Returns -1 since we passed NULL for lun */
316 CU_ASSERT_TRUE(rc
< 0);
318 spdk_scsi_task_put(mgmt_task
);
320 CU_ASSERT_EQUAL(g_task_count
, 0);
324 lun_task_mgmt_execute_abort_task_all_not_supported(void)
326 struct spdk_scsi_lun
*lun
;
327 struct spdk_scsi_task
*task
;
328 struct spdk_scsi_task
*mgmt_task
;
329 struct spdk_scsi_port initiator_port
= { 0 };
330 struct spdk_scsi_dev dev
= { 0 };
332 uint8_t cdb
[6] = { 0 };
334 lun
= lun_construct();
337 mgmt_task
= spdk_get_task(NULL
);
338 mgmt_task
->type
= SPDK_SCSI_TASK_TYPE_MANAGE
;
339 mgmt_task
->function
= SPDK_SCSI_TASK_FUNC_ABORT_TASK_SET
;
340 mgmt_task
->lun
= lun
;
341 mgmt_task
->initiator_port
= &initiator_port
;
343 /* Params to add regular task to the lun->tasks */
344 task
= spdk_get_task(NULL
);
345 task
->initiator_port
= &initiator_port
;
349 spdk_scsi_lun_append_task(lun
, task
);
351 /* task should now be on the pending_task list */
352 CU_ASSERT(!TAILQ_EMPTY(&lun
->pending_tasks
));
354 spdk_scsi_lun_execute_tasks(lun
);
356 /*task should now be on the tasks list */
357 CU_ASSERT(!TAILQ_EMPTY(&lun
->tasks
));
359 rc
= spdk_scsi_lun_task_mgmt_execute(mgmt_task
);
361 /* returns -1 since task abort is not supported */
362 CU_ASSERT_TRUE(rc
< 0);
363 CU_ASSERT(mgmt_task
->response
== SPDK_SCSI_TASK_MGMT_RESP_REJECT_FUNC_NOT_SUPPORTED
);
365 spdk_scsi_task_put(mgmt_task
);
366 spdk_scsi_task_put(task
);
370 CU_ASSERT_EQUAL(g_task_count
, 0);
374 lun_task_mgmt_execute_lun_reset_failure(void)
376 struct spdk_scsi_task
*mgmt_task
;
379 mgmt_task
= spdk_get_task(NULL
);
380 mgmt_task
->type
= SPDK_SCSI_TASK_TYPE_MANAGE
;
381 mgmt_task
->lun
= NULL
;
382 mgmt_task
->function
= SPDK_SCSI_TASK_FUNC_LUN_RESET
;
384 rc
= spdk_scsi_lun_task_mgmt_execute(mgmt_task
);
386 /* Returns -1 since we passed NULL for lun */
387 CU_ASSERT_TRUE(rc
< 0);
389 spdk_scsi_task_put(mgmt_task
);
391 CU_ASSERT_EQUAL(g_task_count
, 0);
395 lun_task_mgmt_execute_lun_reset(void)
397 struct spdk_scsi_lun
*lun
;
398 struct spdk_scsi_task
*mgmt_task
;
399 struct spdk_scsi_dev dev
= { 0 };
402 lun
= lun_construct();
405 mgmt_task
= spdk_get_task(NULL
);
406 mgmt_task
->type
= SPDK_SCSI_TASK_TYPE_MANAGE
;
407 mgmt_task
->lun
= lun
;
408 mgmt_task
->function
= SPDK_SCSI_TASK_FUNC_LUN_RESET
;
410 rc
= spdk_scsi_lun_task_mgmt_execute(mgmt_task
);
412 /* Returns success */
413 CU_ASSERT_EQUAL(rc
, 0);
415 spdk_scsi_task_put(mgmt_task
);
419 CU_ASSERT_EQUAL(g_task_count
, 0);
423 lun_task_mgmt_execute_invalid_case(void)
425 struct spdk_scsi_lun
*lun
;
426 struct spdk_scsi_task
*mgmt_task
;
427 struct spdk_scsi_dev dev
= { 0 };
430 lun
= lun_construct();
433 mgmt_task
= spdk_get_task(NULL
);
434 mgmt_task
->type
= SPDK_SCSI_TASK_TYPE_MANAGE
;
435 /* Pass an invalid value to the switch statement */
436 mgmt_task
->function
= 5;
438 rc
= spdk_scsi_lun_task_mgmt_execute(mgmt_task
);
440 /* Returns -1 on passing an invalid value to the switch case */
441 CU_ASSERT_TRUE(rc
< 0);
443 spdk_scsi_task_put(mgmt_task
);
447 CU_ASSERT_EQUAL(g_task_count
, 0);
451 lun_append_task_null_lun_task_cdb_spc_inquiry(void)
453 struct spdk_scsi_task
*task
;
454 uint8_t cdb
[6] = { 0 };
456 task
= spdk_get_task(NULL
);
458 task
->cdb
[0] = SPDK_SPC_INQUIRY
;
459 /* alloc_len >= 4096 */
464 spdk_scsi_task_process_null_lun(task
);
466 CU_ASSERT_EQUAL(task
->status
, SPDK_SCSI_STATUS_GOOD
);
468 spdk_scsi_task_put(task
);
470 CU_ASSERT_EQUAL(g_task_count
, 0);
474 lun_append_task_null_lun_alloc_len_lt_4096(void)
476 struct spdk_scsi_task
*task
;
477 uint8_t cdb
[6] = { 0 };
479 task
= spdk_get_task(NULL
);
481 task
->cdb
[0] = SPDK_SPC_INQUIRY
;
482 /* alloc_len < 4096 */
485 /* alloc_len is set to a minimal value of 4096
486 * Hence, rbuf of size 4096 is allocated*/
487 spdk_scsi_task_process_null_lun(task
);
489 CU_ASSERT_EQUAL(task
->status
, SPDK_SCSI_STATUS_GOOD
);
491 spdk_scsi_task_put(task
);
493 CU_ASSERT_EQUAL(g_task_count
, 0);
497 lun_append_task_null_lun_not_supported(void)
499 struct spdk_scsi_task
*task
;
500 uint8_t cdb
[6] = { 0 };
502 task
= spdk_get_task(NULL
);
506 spdk_scsi_task_process_null_lun(task
);
508 CU_ASSERT_EQUAL(task
->status
, SPDK_SCSI_STATUS_CHECK_CONDITION
);
509 /* LUN not supported; task's data transferred should be 0 */
510 CU_ASSERT_EQUAL(task
->data_transferred
, 0);
512 spdk_scsi_task_put(task
);
514 CU_ASSERT_EQUAL(g_task_count
, 0);
518 lun_execute_scsi_task_pending(void)
520 struct spdk_scsi_lun
*lun
;
521 struct spdk_scsi_task
*task
;
522 struct spdk_scsi_dev dev
= { 0 };
524 lun
= lun_construct();
526 task
= spdk_get_task(NULL
);
530 g_lun_execute_fail
= false;
531 g_lun_execute_status
= SPDK_SCSI_TASK_PENDING
;
533 spdk_scsi_lun_append_task(lun
, task
);
535 /* task should now be on the pending_task list */
536 CU_ASSERT(!TAILQ_EMPTY(&lun
->pending_tasks
));
538 /* but the tasks list should still be empty since it has not been
541 CU_ASSERT(TAILQ_EMPTY(&lun
->tasks
));
543 spdk_scsi_lun_execute_tasks(lun
);
545 /* Assert the task has been successfully added to the tasks queue */
546 CU_ASSERT(!TAILQ_EMPTY(&lun
->tasks
));
548 spdk_scsi_task_put(task
);
552 CU_ASSERT_EQUAL(g_task_count
, 0);
556 lun_execute_scsi_task_complete(void)
558 struct spdk_scsi_lun
*lun
;
559 struct spdk_scsi_task
*task
;
560 struct spdk_scsi_dev dev
= { 0 };
562 lun
= lun_construct();
564 task
= spdk_get_task(NULL
);
568 g_lun_execute_fail
= false;
569 g_lun_execute_status
= SPDK_SCSI_TASK_COMPLETE
;
571 spdk_scsi_lun_append_task(lun
, task
);
573 /* task should now be on the pending_task list */
574 CU_ASSERT(!TAILQ_EMPTY(&lun
->pending_tasks
));
576 /* but the tasks list should still be empty since it has not been
579 CU_ASSERT(TAILQ_EMPTY(&lun
->tasks
));
581 spdk_scsi_lun_execute_tasks(lun
);
583 /* Assert the task has not been added to the tasks queue */
584 CU_ASSERT(TAILQ_EMPTY(&lun
->tasks
));
586 spdk_scsi_task_put(task
);
590 CU_ASSERT_EQUAL(g_task_count
, 0);
594 lun_destruct_success(void)
596 struct spdk_scsi_lun
*lun
;
599 lun
= lun_construct();
601 rc
= spdk_scsi_lun_destruct(lun
);
603 CU_ASSERT_EQUAL(rc
, 0);
604 CU_ASSERT_EQUAL(g_task_count
, 0);
608 lun_construct_null_ctx(void)
610 struct spdk_scsi_lun
*lun
;
612 lun
= spdk_scsi_lun_construct("lun0", NULL
);
614 /* lun should be NULL since we passed NULL for the ctx pointer. */
615 CU_ASSERT(lun
== NULL
);
616 CU_ASSERT_EQUAL(g_task_count
, 0);
620 lun_construct_success(void)
622 struct spdk_scsi_lun
*lun
= lun_construct();
626 CU_ASSERT_EQUAL(g_task_count
, 0);
630 lun_construct_same_same_twice(void)
632 struct spdk_scsi_lun
*lun
, *lun2
;
633 struct spdk_bdev bdev
, bdev2
;
635 lun
= spdk_scsi_lun_construct("lun0", &bdev
);
637 /* Successfully constructs and returns lun */
638 SPDK_CU_ASSERT_FATAL(lun
!= NULL
);
640 lun2
= spdk_scsi_lun_construct("lun0", &bdev2
);
642 /* Fails to construct the same lun on another bdev and returns NULL */
643 CU_ASSERT(lun2
== NULL
);
647 CU_ASSERT_EQUAL(g_task_count
, 0);
653 struct spdk_scsi_lun
*lun
;
656 lun
= lun_construct();
658 rc
= spdk_scsi_lun_delete(lun
->name
);
659 CU_ASSERT_EQUAL(rc
, 0);
661 lun
= lun_construct();
663 rc
= spdk_scsi_lun_claim(lun
);
664 CU_ASSERT_EQUAL(rc
, 0);
666 rc
= spdk_scsi_lun_delete(lun
->name
);
667 CU_ASSERT_EQUAL(rc
, 0);
669 rc
= spdk_scsi_lun_delete("test");
670 CU_ASSERT_EQUAL(rc
, -1);
674 main(int argc
, char **argv
)
676 CU_pSuite suite
= NULL
;
677 unsigned int num_failures
;
680 if (CU_initialize_registry() != CUE_SUCCESS
) {
681 return CU_get_error();
684 suite
= CU_add_suite("lun_suite", NULL
, NULL
);
686 CU_cleanup_registry();
687 return CU_get_error();
691 CU_add_test(suite
, "task management - null task failure",
692 lun_task_mgmt_execute_null_task
) == NULL
693 || CU_add_test(suite
, "task management abort task - null lun failure",
694 lun_task_mgmt_execute_abort_task_null_lun_failure
) == NULL
695 || CU_add_test(suite
, "task management abort task - not supported",
696 lun_task_mgmt_execute_abort_task_not_supported
) == NULL
697 || CU_add_test(suite
, "task management abort task set - null lun failure",
698 lun_task_mgmt_execute_abort_task_all_null_lun_failure
) == NULL
699 || CU_add_test(suite
, "task management abort task set - success",
700 lun_task_mgmt_execute_abort_task_all_not_supported
) == NULL
701 || CU_add_test(suite
, "task management - lun reset failure",
702 lun_task_mgmt_execute_lun_reset_failure
) == NULL
703 || CU_add_test(suite
, "task management - lun reset success",
704 lun_task_mgmt_execute_lun_reset
) == NULL
705 || CU_add_test(suite
, "task management - invalid option",
706 lun_task_mgmt_execute_invalid_case
) == NULL
707 || CU_add_test(suite
, "append task - null lun SPDK_SPC_INQUIRY",
708 lun_append_task_null_lun_task_cdb_spc_inquiry
) == NULL
709 || CU_add_test(suite
, "append task - allocated length less than 4096",
710 lun_append_task_null_lun_alloc_len_lt_4096
) == NULL
711 || CU_add_test(suite
, "append task - unsupported lun",
712 lun_append_task_null_lun_not_supported
) == NULL
713 || CU_add_test(suite
, "execute task - scsi task pending",
714 lun_execute_scsi_task_pending
) == NULL
715 || CU_add_test(suite
, "execute task - scsi task complete",
716 lun_execute_scsi_task_complete
) == NULL
717 || CU_add_test(suite
, "destruct task - success", lun_destruct_success
) == NULL
718 || CU_add_test(suite
, "construct - null ctx", lun_construct_null_ctx
) == NULL
719 || CU_add_test(suite
, "construct - success", lun_construct_success
) == NULL
720 || CU_add_test(suite
, "construct - same lun twice", lun_construct_same_same_twice
) == NULL
721 || CU_add_test(suite
, "lun_delete", lun_delete
) == NULL
723 CU_cleanup_registry();
724 return CU_get_error();
727 CU_basic_set_mode(CU_BRM_VERBOSE
);
728 CU_basic_run_tests();
729 num_failures
= CU_get_number_of_failures();
732 rc
= spdk_cunit_print_results(argv
[1]);
734 CU_cleanup_registry();
739 CU_cleanup_registry();