]> git.proxmox.com Git - ceph.git/blame - ceph/src/spdk/test/lib/scsi/dev/dev_ut.c
add subtree-ish sources for 12.0.3
[ceph.git] / ceph / src / spdk / test / lib / scsi / dev / dev_ut.c
CommitLineData
7c673cae
FG
1/*-
2 * BSD LICENSE
3 *
4 * Copyright (c) Intel Corporation.
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 *
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
16 * distribution.
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.
20 *
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.
32 */
33
34#include <stdint.h>
35#include <stdlib.h>
36#include <string.h>
37
38#include "CUnit/Basic.h"
39#include "spdk_cunit.h"
40
41#include "dev.c"
42#include "port.c"
43
44static uint32_t g_task_count = 0;
45static struct spdk_bdev g_bdev = {};
46
47struct lun_entry {
48 TAILQ_ENTRY(lun_entry) lun_entries;
49 struct spdk_scsi_lun *lun;
50};
51TAILQ_HEAD(, lun_entry) g_lun_head;
52
53static int
54test_setup(void)
55{
56 TAILQ_INIT(&g_lun_head);
57 return 0;
58}
59
60void
61spdk_bdev_unregister(struct spdk_bdev *bdev)
62{
63}
64
65static struct spdk_scsi_task *
66spdk_get_task(uint32_t *owner_task_ctr)
67{
68 struct spdk_scsi_task *task;
69
70 task = calloc(1, sizeof(*task));
71 if (!task) {
72 return NULL;
73 }
74
75 task->id = g_task_count;
76
77 g_task_count++;
78
79 return task;
80}
81
82void
83spdk_scsi_task_put(struct spdk_scsi_task *task)
84{
85 g_task_count--;
86
87 free(task);
88}
89
90_spdk_scsi_lun *
91spdk_scsi_lun_construct(const char *name, struct spdk_bdev *bdev)
92{
93 struct spdk_scsi_lun *lun;
94
95 lun = calloc(1, sizeof(struct spdk_scsi_lun));
96 SPDK_CU_ASSERT_FATAL(lun != NULL);
97
98 snprintf(lun->name, sizeof(lun->name), "%s", name);
99 lun->bdev = bdev;
100 return lun;
101}
102
103int
104spdk_scsi_lun_destruct(struct spdk_scsi_lun *lun)
105{
106 free(lun);
107 return 0;
108}
109
110struct spdk_bdev *
111spdk_bdev_get_by_name(const char *bdev_name)
112{
113 snprintf(g_bdev.name, sizeof(g_bdev.name), "%s", bdev_name);
114 return &g_bdev;
115}
116
117int
118spdk_scsi_lun_claim(struct spdk_scsi_lun *lun)
119{
120 struct lun_entry *p;
121
122 TAILQ_FOREACH(p, &g_lun_head, lun_entries) {
123 CU_ASSERT_FATAL(p->lun != NULL);
124 if (strncmp(p->lun->name, lun->name, sizeof(lun->name)) == 0)
125 return -1;
126 }
127
128 p = calloc(1, sizeof(struct lun_entry));
129 SPDK_CU_ASSERT_FATAL(p != NULL);
130
131 p->lun = lun;
132
133 TAILQ_INSERT_TAIL(&g_lun_head, p, lun_entries);
134 return 0;
135}
136
137int
138spdk_scsi_lun_unclaim(struct spdk_scsi_lun *lun)
139{
140 struct lun_entry *p, *tmp;
141
142 TAILQ_FOREACH_SAFE(p, &g_lun_head, lun_entries, tmp) {
143 CU_ASSERT_FATAL(p->lun != NULL);
144 if (strncmp(p->lun->name, lun->name, sizeof(lun->name)) == 0) {
145 TAILQ_REMOVE(&g_lun_head, p, lun_entries);
146 free(p);
147 return 0;
148 }
149 }
150 return 0;
151}
152
153int
154spdk_scsi_lun_task_mgmt_execute(struct spdk_scsi_task *task)
155{
156 return 0;
157}
158
159int
160spdk_scsi_lun_append_task(struct spdk_scsi_lun *lun, struct spdk_scsi_task *task)
161{
162 return 0;
163}
164
165void
166spdk_scsi_lun_execute_tasks(struct spdk_scsi_lun *lun)
167{
168}
169
170int
171spdk_scsi_lun_allocate_io_channel(struct spdk_scsi_lun *lun)
172{
173 return 0;
174}
175
176void
177spdk_scsi_lun_free_io_channel(struct spdk_scsi_lun *lun)
178{
179}
180
181
182static void
183dev_destruct_null_dev(void)
184{
185 /* pass null for the dev */
186 spdk_scsi_dev_destruct(NULL);
187}
188
189static void
190dev_destruct_zero_luns(void)
191{
192 struct spdk_scsi_dev dev = { 0 };
193
194 /* pass maxlun as 0.
195 * No luns attached to the dev */
196 dev.maxlun = 0;
197
198 /* free the dev */
199 spdk_scsi_dev_destruct(&dev);
200}
201
202static void
203dev_destruct_null_lun(void)
204{
205 struct spdk_scsi_dev dev = { 0 };
206
207 dev.maxlun = 1;
208 /* pass null for the lun */
209 dev.lun[0] = NULL;
210
211 /* free the dev */
212 spdk_scsi_dev_destruct(&dev);
213}
214
215static void
216dev_destruct_success(void)
217{
218 struct spdk_scsi_dev dev = { 0 };
219 struct spdk_scsi_lun *lun;
220
221 lun = calloc(1, sizeof(struct spdk_scsi_lun));
222
223 /* dev with a single lun */
224 dev.maxlun = 1;
225 dev.lun[0] = lun;
226
227 /* free the dev */
228 spdk_scsi_dev_destruct(&dev);
229
230}
231
232static void
233dev_construct_num_luns_zero(void)
234{
235 struct spdk_scsi_dev *dev;
236 char *lun_name_list[1] = {};
237 int lun_id_list[1] = { 0 };
238
239 dev = spdk_scsi_dev_construct("Name", lun_name_list, lun_id_list, 0);
240
241 /* dev should be null since we passed num_luns = 0 */
242 CU_ASSERT_TRUE(dev == NULL);
243}
244
245static void
246dev_construct_no_lun_zero(void)
247{
248 struct spdk_scsi_dev *dev;
249 char *lun_name_list[1] = {};
250 int lun_id_list[1] = { 0 };
251
252 lun_id_list[0] = 1;
253
254 dev = spdk_scsi_dev_construct("Name", lun_name_list, lun_id_list, 1);
255
256 /* dev should be null since no LUN0 was specified (lun_id_list[0] = 1) */
257 CU_ASSERT_TRUE(dev == NULL);
258}
259
260static void
261dev_construct_null_lun(void)
262{
263 struct spdk_scsi_dev *dev;
264 char *lun_name_list[1] = {};
265 int lun_id_list[1] = { 0 };
266
267 dev = spdk_scsi_dev_construct("Name", lun_name_list, lun_id_list, 1);
268
269 /* dev should be null since no LUN0 was specified (lun_list[0] = NULL) */
270 CU_ASSERT_TRUE(dev == NULL);
271}
272
273static void
274dev_construct_success(void)
275{
276 struct spdk_scsi_dev *dev;
277 char *lun_name_list[1] = {"malloc0"};
278 int lun_id_list[1] = { 0 };
279
280 dev = spdk_scsi_dev_construct("Name", lun_name_list, lun_id_list, 1);
281
282 /* Successfully constructs and returns a dev */
283 CU_ASSERT_TRUE(dev != NULL);
284
285 /* free the dev */
286 spdk_scsi_dev_destruct(dev);
287
288 CU_ASSERT(TAILQ_EMPTY(&g_lun_head));
289}
290
291static void
292dev_construct_same_lun_two_devices(void)
293{
294 struct spdk_scsi_dev *dev, *dev2;
295 char *lun_name_list[1] = {"malloc0"};
296 int lun_id_list[1] = { 0 };
297
298 dev = spdk_scsi_dev_construct("Name", lun_name_list, lun_id_list, 1);
299
300 /* Successfully constructs and returns a dev */
301 CU_ASSERT_TRUE(dev != NULL);
302
303 dev2 = spdk_scsi_dev_construct("Name2", lun_name_list, lun_id_list, 1);
304
305 /* Fails to construct dev and returns NULL */
306 CU_ASSERT_TRUE(dev2 == NULL);
307
308 /* free the dev */
309 spdk_scsi_dev_destruct(dev);
310
311 CU_ASSERT(TAILQ_EMPTY(&g_lun_head));
312}
313
314static void
315dev_construct_same_lun_one_device(void)
316{
317 struct spdk_scsi_dev *dev;
318 char *lun_name_list[2] = {"malloc0", "malloc0"};
319 int lun_id_list[2] = { 0, 1 };
320
321 dev = spdk_scsi_dev_construct("Name", lun_name_list, lun_id_list, 2);
322
323 /* Fails to construct dev and returns NULL */
324 CU_ASSERT_TRUE(dev == NULL);
325
326 CU_ASSERT(TAILQ_EMPTY(&g_lun_head));
327}
328
329static void
330dev_queue_mgmt_task_success(void)
331{
332 struct spdk_scsi_dev *dev;
333 char *lun_name_list[1] = {"malloc0"};
334 int lun_id_list[1] = { 0 };
335 struct spdk_scsi_task *task;
336
337 dev = spdk_scsi_dev_construct("Name", lun_name_list, lun_id_list, 1);
338
339 /* Successfully constructs and returns a dev */
340 CU_ASSERT_TRUE(dev != NULL);
341
342 task = spdk_get_task(NULL);
343
344 spdk_scsi_dev_queue_mgmt_task(dev, task);
345
346 spdk_scsi_task_put(task);
347
348 spdk_scsi_dev_destruct(dev);
349}
350
351static void
352dev_queue_task_success(void)
353{
354 struct spdk_scsi_dev *dev;
355 char *lun_name_list[1] = {"malloc0"};
356 int lun_id_list[1] = { 0 };
357 struct spdk_scsi_task *task;
358
359 dev = spdk_scsi_dev_construct("Name", lun_name_list, lun_id_list, 1);
360
361 /* Successfully constructs and returns a dev */
362 CU_ASSERT_TRUE(dev != NULL);
363
364 task = spdk_get_task(NULL);
365
366 spdk_scsi_dev_queue_task(dev, task);
367
368 spdk_scsi_task_put(task);
369
370 spdk_scsi_dev_destruct(dev);
371}
372
373static void
374dev_stop_success(void)
375{
376 struct spdk_scsi_dev dev = { 0 };
377 struct spdk_scsi_task *task;
378 struct spdk_scsi_task *task_mgmt;
379
380 task = spdk_get_task(NULL);
381
382 spdk_scsi_dev_queue_task(&dev, task);
383
384 task_mgmt = spdk_get_task(NULL);
385
386 /* Enqueue the tasks into dev->task_mgmt_submit_queue*/
387 spdk_scsi_dev_queue_mgmt_task(&dev, task_mgmt);
388
389 spdk_scsi_task_put(task);
390 spdk_scsi_task_put(task_mgmt);
391}
392
393static void
394dev_add_port_max_ports(void)
395{
396 struct spdk_scsi_dev dev = { 0 };
397 const char *name;
398 int id, rc;
399
400 /* dev is set to SPDK_SCSI_DEV_MAX_PORTS */
401 dev.num_ports = SPDK_SCSI_DEV_MAX_PORTS;
402 name = "Name of Port";
403 id = 1;
404
405 rc = spdk_scsi_dev_add_port(&dev, id, name);
406
407 /* returns -1; since the dev already has maximum
408 * number of ports (SPDK_SCSI_DEV_MAX_PORTS) */
409 CU_ASSERT_TRUE(rc < 0);
410}
411
412static void
413dev_add_port_construct_failure(void)
414{
415 struct spdk_scsi_dev dev = { 0 };
416 const int port_name_length = SPDK_SCSI_PORT_MAX_NAME_LENGTH + 2;
417 char name[port_name_length];
418 int id, rc;
419
420 dev.num_ports = 1;
421 /* Set the name such that the length exceeds SPDK_SCSI_PORT_MAX_NAME_LENGTH
422 * SPDK_SCSI_PORT_MAX_NAME_LENGTH = 256 */
423 memset(name, 'a', port_name_length - 1);
424 name[port_name_length - 1] = '\0';
425 id = 1;
426
427 rc = spdk_scsi_dev_add_port(&dev, id, name);
428
429 /* returns -1; since the length of the name exceeds
430 * SPDK_SCSI_PORT_MAX_NAME_LENGTH */
431 CU_ASSERT_TRUE(rc < 0);
432}
433
434static void
435dev_add_port_success(void)
436{
437 struct spdk_scsi_dev dev = { 0 };
438 const char *name;
439 int id, rc;
440
441 dev.num_ports = 1;
442 name = "Name of Port";
443 id = 1;
444
445 rc = spdk_scsi_dev_add_port(&dev, id, name);
446
447 /* successfully adds a port */
448 CU_ASSERT_EQUAL(rc, 0);
449 /* Assert num_ports has been incremented to 2 */
450 CU_ASSERT_EQUAL(dev.num_ports, 2);
451}
452
453static void
454dev_find_port_by_id_num_ports_zero(void)
455{
456 struct spdk_scsi_dev dev = { 0 };
457 struct spdk_scsi_port *rp_port;
458 uint64_t id;
459
460 dev.num_ports = 0;
461 id = 1;
462
463 rp_port = spdk_scsi_dev_find_port_by_id(&dev, id);
464
465 /* returns null; since dev's num_ports is 0 */
466 CU_ASSERT_TRUE(rp_port == NULL);
467}
468
469static void
470dev_find_port_by_id_id_not_found_failure(void)
471{
472 struct spdk_scsi_dev dev = { 0 };
473 struct spdk_scsi_port *rp_port;
474 const char *name;
475 int rc;
476 uint64_t id, find_id;
477
478 id = 1;
479 dev.num_ports = 1;
480 name = "Name of Port";
481 find_id = 2;
482
483 /* Add a port with id = 1 */
484 rc = spdk_scsi_dev_add_port(&dev, id, name);
485
486 CU_ASSERT_EQUAL(rc, 0);
487
488 /* Find port with id = 2 */
489 rp_port = spdk_scsi_dev_find_port_by_id(&dev, find_id);
490
491 /* returns null; failed to find port specified by id = 2 */
492 CU_ASSERT_TRUE(rp_port == NULL);
493}
494
495static void
496dev_find_port_by_id_success(void)
497{
498 struct spdk_scsi_dev dev = { 0 };
499 struct spdk_scsi_port *rp_port;
500 const char *name;
501 int rc;
502 uint64_t id;
503
504 id = 1;
505 dev.num_ports = 1;
506 name = "Name of Port";
507
508 /* Add a port */
509 rc = spdk_scsi_dev_add_port(&dev, id, name);
510
511 CU_ASSERT_EQUAL(rc, 0);
512
513 /* Find port by the same id as the one added above */
514 rp_port = spdk_scsi_dev_find_port_by_id(&dev, id);
515
516 /* Successfully found port specified by id */
517 CU_ASSERT_TRUE(rp_port != NULL);
518 if (rp_port != NULL) {
519 /* Assert the found port's id and name are same as
520 * the port added. */
521 CU_ASSERT_EQUAL(rp_port->id, 1);
522 CU_ASSERT_STRING_EQUAL(rp_port->name, "Name of Port");
523 }
524}
525
526static void
527dev_print_success(void)
528{
529 struct spdk_scsi_dev dev = { 0 };
530 struct spdk_scsi_lun lun = { 0 };
531
532 dev.maxlun = 1;
533 dev.lun[0] = &lun;
534
535 /* Prints the dev and a list of the LUNs associated with
536 * the dev */
537 spdk_scsi_dev_print(&dev);
538}
539
540int
541main(int argc, char **argv)
542{
543 CU_pSuite suite = NULL;
544 unsigned int num_failures;
545
546 if (CU_initialize_registry() != CUE_SUCCESS) {
547 return CU_get_error();
548 }
549
550 suite = CU_add_suite("dev_suite", test_setup, NULL);
551 if (suite == NULL) {
552 CU_cleanup_registry();
553 return CU_get_error();
554 }
555
556 if (
557 CU_add_test(suite, "destruct - null dev",
558 dev_destruct_null_dev) == NULL
559 || CU_add_test(suite, "destruct - zero luns", dev_destruct_zero_luns) == NULL
560 || CU_add_test(suite, "destruct - null lun", dev_destruct_null_lun) == NULL
561 || CU_add_test(suite, "destruct - success", dev_destruct_success) == NULL
562 || CU_add_test(suite, "construct - queue depth gt max depth",
563 dev_construct_num_luns_zero) == NULL
564 || CU_add_test(suite, "construct - no lun0",
565 dev_construct_no_lun_zero) == NULL
566 || CU_add_test(suite, "construct - null lun",
567 dev_construct_null_lun) == NULL
568 || CU_add_test(suite, "construct - success", dev_construct_success) == NULL
569 || CU_add_test(suite, "construct - same lun on two devices",
570 dev_construct_same_lun_two_devices) == NULL
571 || CU_add_test(suite, "construct - same lun on once device",
572 dev_construct_same_lun_one_device) == NULL
573 || CU_add_test(suite, "dev queue task mgmt - success",
574 dev_queue_mgmt_task_success) == NULL
575 || CU_add_test(suite, "dev queue task - success",
576 dev_queue_task_success) == NULL
577 || CU_add_test(suite, "dev stop - success", dev_stop_success) == NULL
578 || CU_add_test(suite, "dev add port - max ports",
579 dev_add_port_max_ports) == NULL
580 || CU_add_test(suite, "dev add port - construct port failure",
581 dev_add_port_construct_failure) == NULL
582 || CU_add_test(suite, "dev add port - success",
583 dev_add_port_success) == NULL
584 || CU_add_test(suite, "dev find port by id - num ports zero",
585 dev_find_port_by_id_num_ports_zero) == NULL
586 || CU_add_test(suite, "dev find port by id - different port id failure",
587 dev_find_port_by_id_id_not_found_failure) == NULL
588 || CU_add_test(suite, "dev find port by id - success",
589 dev_find_port_by_id_success) == NULL
590 || CU_add_test(suite, "dev print - success", dev_print_success) == NULL
591 ) {
592 CU_cleanup_registry();
593 return CU_get_error();
594 }
595
596 CU_basic_set_mode(CU_BRM_VERBOSE);
597 CU_basic_run_tests();
598 num_failures = CU_get_number_of_failures();
599 CU_cleanup_registry();
600
601 return num_failures;
602}