From 70e25b39ac89d414c495a8d7dfaae0573e7f7324 Mon Sep 17 00:00:00 2001 From: Jim Harris Date: Wed, 18 Oct 2017 15:01:52 -0700 Subject: [PATCH] lvol: refactor unit tests Create blob_store and blob placeholders, to mimic what a real SPDK blobstore would do. Then we can set different status values on the blobstore and blobs to return different status instead of just a single global variable for injecting different status values. This is also needed for future tests where we need to have multiple lvolstores at once to test name collisions. Signed-off-by: Jim Harris Change-Id: I68110fa87a63c6e5795bfccc0121c2f58d87c815 Reviewed-on: https://review.gerrithub.io/383036 Tested-by: SPDK Automated Test System Reviewed-by: Daniel Verkamp --- test/unit/lib/lvol/lvol.c/lvol_ut.c | 364 +++++++++++++++++++--------- 1 file changed, 249 insertions(+), 115 deletions(-) diff --git a/test/unit/lib/lvol/lvol.c/lvol_ut.c b/test/unit/lib/lvol/lvol.c/lvol_ut.c index 8e5e017ad..47985f435 100644 --- a/test/unit/lib/lvol/lvol.c/lvol_ut.c +++ b/test/unit/lib/lvol/lvol.c/lvol_ut.c @@ -34,6 +34,7 @@ #include "spdk_cunit.h" #include "spdk/blob.h" #include "spdk/io_channel.h" +#include "spdk/util.h" #include "lib/test_env.c" @@ -51,67 +52,66 @@ #define SPDK_BLOB_OPTS_MAX_MD_OPS 32 #define SPDK_BLOB_OPTS_MAX_CHANNEL_OPS 512 -const char *uuid = "828d9766-ae50-11e7-bd8d-001e67edf35d"; +const char *uuid = "828d9766-ae50-11e7-bd8d-001e67edf350"; struct spdk_blob { - spdk_blob_id id; + spdk_blob_id id; + uint32_t ref; + int close_status; + int open_status; + TAILQ_ENTRY(spdk_blob) link; + char uuid[UUID_STRING_LEN]; }; int g_lvolerrno; int g_lvserrno; -int g_bs_load_status; -int g_get_super_status; -int g_open_blob_status; -int g_get_uuid_status; int g_close_super_status; int g_resize_rc; -int g_lvols_count; -int g_fail_on_n_lvol_load = 0xFF; struct spdk_lvol_store *g_lvol_store; struct spdk_lvol *g_lvol; -struct spdk_bs_opts g_bs_opts; struct spdk_blob_store { - int stub; + struct spdk_bs_opts bs_opts; + spdk_blob_id super_blobid; + TAILQ_HEAD(, spdk_blob) blobs; + int get_super_status; }; -struct spdk_blob_store *g_blob_store; -struct spdk_blob *g_blob; -static void -bs_iter(void) -{ - if (g_lvols_count > 0) { - g_blob = calloc(1, sizeof(*g_blob)); - SPDK_CU_ASSERT_FATAL(g_blob != NULL); - g_blob->id = g_lvols_count + 1; /* skip super blob */ - g_lvols_count--; - g_fail_on_n_lvol_load--; - } else { - g_lvolerrno = -ENOENT; - } - - if (g_fail_on_n_lvol_load == 0) { - g_lvolerrno = -1; - } -} +struct lvol_ut_bs_dev { + struct spdk_bs_dev bs_dev; + int init_status; + int load_status; + struct spdk_blob_store *bs; +}; void spdk_bs_md_iter_next(struct spdk_blob_store *bs, struct spdk_blob **b, spdk_blob_op_with_handle_complete cb_fn, void *cb_arg) { - free(g_blob); - bs_iter(); + struct spdk_blob *next; + int _errno = 0; - cb_fn(cb_arg, g_blob, g_lvolerrno); + next = TAILQ_NEXT(*b, link); + if (next == NULL) { + _errno = -ENOENT; + } + + cb_fn(cb_arg, next, _errno); } void spdk_bs_md_iter_first(struct spdk_blob_store *bs, spdk_blob_op_with_handle_complete cb_fn, void *cb_arg) { - bs_iter(); + struct spdk_blob *first; + int _errno = 0; - cb_fn(cb_arg, g_blob, g_lvolerrno); + first = TAILQ_FIRST(&bs->blobs); + if (first == NULL) { + _errno = -ENOENT; + } + + cb_fn(cb_arg, first, _errno); } uint64_t spdk_blob_get_num_clusters(struct spdk_blob *blob) @@ -123,13 +123,18 @@ void spdk_bs_get_super(struct spdk_blob_store *bs, spdk_blob_op_with_id_complete cb_fn, void *cb_arg) { - cb_fn(cb_arg, 0, g_get_super_status); + if (bs->get_super_status != 0) { + cb_fn(cb_arg, 0, bs->get_super_status); + } else { + cb_fn(cb_arg, bs->super_blobid, 0); + } } void spdk_bs_set_super(struct spdk_blob_store *bs, spdk_blob_id blobid, spdk_bs_op_complete cb_fn, void *cb_arg) { + bs->super_blobid = blobid; cb_fn(cb_arg, 0); } @@ -137,12 +142,14 @@ void spdk_bs_load(struct spdk_bs_dev *dev, struct spdk_bs_opts *opts, spdk_bs_op_with_handle_complete cb_fn, void *cb_arg) { - if (g_bs_load_status == 0) { - g_blob_store = calloc(1, sizeof(*g_blob_store)); - SPDK_CU_ASSERT_FATAL(g_blob_store != NULL); + struct lvol_ut_bs_dev *ut_dev = SPDK_CONTAINEROF(dev, struct lvol_ut_bs_dev, bs_dev); + struct spdk_blob_store *bs = NULL; + + if (ut_dev->load_status == 0) { + bs = ut_dev->bs; } - cb_fn(cb_arg, g_blob_store, g_bs_load_status); + cb_fn(cb_arg, bs, ut_dev->load_status); } struct spdk_io_channel *spdk_bs_alloc_io_channel(struct spdk_blob_store *bs) @@ -154,6 +161,11 @@ int spdk_blob_md_set_xattr(struct spdk_blob *blob, const char *name, const void *value, uint16_t value_len) { + if (!strcmp(name, "uuid")) { + CU_ASSERT(value_len == UUID_STRING_LEN); + memcpy(blob->uuid, value, UUID_STRING_LEN); + } + return 0; } @@ -161,10 +173,14 @@ int spdk_bs_md_get_xattr_value(struct spdk_blob *blob, const char *name, const void **value, size_t *value_len) { - *value = uuid; - *value_len = UUID_STRING_LEN; + if (!strcmp(name, "uuid") && strnlen(blob->uuid, UUID_STRING_LEN) != 0) { + CU_ASSERT(strnlen(blob->uuid, UUID_STRING_LEN) == (UUID_STRING_LEN - 1)); + *value = blob->uuid; + *value_len = UUID_STRING_LEN; + return 0; + } - return g_get_uuid_status; + return -ENOENT; } uint64_t @@ -174,23 +190,47 @@ spdk_bs_get_page_size(struct spdk_blob_store *bs) } static void -init_dev(struct spdk_bs_dev *dev) +init_dev(struct lvol_ut_bs_dev *dev) { - dev->blockcnt = DEV_BUFFER_BLOCKCNT; - dev->blocklen = DEV_BUFFER_BLOCKLEN; - return; + memset(dev, 0, sizeof(*dev)); + dev->bs_dev.blockcnt = DEV_BUFFER_BLOCKCNT; + dev->bs_dev.blocklen = DEV_BUFFER_BLOCKLEN; +} + +static void +free_dev(struct lvol_ut_bs_dev *dev) +{ + struct spdk_blob_store *bs = dev->bs; + struct spdk_blob *blob, *tmp; + + if (bs == NULL) { + return; + } + + TAILQ_FOREACH_SAFE(blob, &bs->blobs, link, tmp) { + TAILQ_REMOVE(&bs->blobs, blob, link); + free(blob); + } + + free(bs); + dev->bs = NULL; } void spdk_bs_init(struct spdk_bs_dev *dev, struct spdk_bs_opts *o, spdk_bs_op_with_handle_complete cb_fn, void *cb_arg) { + struct lvol_ut_bs_dev *ut_dev = SPDK_CONTAINEROF(dev, struct lvol_ut_bs_dev, bs_dev); struct spdk_blob_store *bs; bs = calloc(1, sizeof(*bs)); SPDK_CU_ASSERT_FATAL(bs != NULL); - memcpy(&g_bs_opts, o, sizeof(struct spdk_bs_opts)); + TAILQ_INIT(&bs->blobs); + + ut_dev->bs = bs; + + memcpy(&bs->bs_opts, o, sizeof(struct spdk_bs_opts)); cb_fn(cb_arg, bs, 0); } @@ -198,8 +238,6 @@ spdk_bs_init(struct spdk_bs_dev *dev, struct spdk_bs_opts *o, void spdk_bs_unload(struct spdk_blob_store *bs, spdk_bs_op_complete cb_fn, void *cb_arg) { - free(bs); - cb_fn(cb_arg, 0); } @@ -216,6 +254,16 @@ void spdk_bs_md_delete_blob(struct spdk_blob_store *bs, spdk_blob_id blobid, spdk_blob_op_complete cb_fn, void *cb_arg) { + struct spdk_blob *blob; + + TAILQ_FOREACH(blob, &bs->blobs, link) { + if (blob->id == blobid) { + TAILQ_REMOVE(&bs->blobs, blob, link); + free(blob); + break; + } + } + cb_fn(cb_arg, 0); } @@ -244,9 +292,9 @@ spdk_bs_get_cluster_size(struct spdk_blob_store *bs) void spdk_bs_md_close_blob(struct spdk_blob **b, spdk_blob_op_complete cb_fn, void *cb_arg) { - free(g_blob); + (*b)->ref--; - cb_fn(cb_arg, g_close_super_status); + cb_fn(cb_arg, (*b)->close_status); } int @@ -266,12 +314,17 @@ void spdk_bs_md_open_blob(struct spdk_blob_store *bs, spdk_blob_id blobid, spdk_blob_op_with_handle_complete cb_fn, void *cb_arg) { - if (g_open_blob_status == 0) { - g_blob = calloc(1, sizeof(*g_blob)); - SPDK_CU_ASSERT_FATAL(g_blob != NULL); + struct spdk_blob *blob; + + TAILQ_FOREACH(blob, &bs->blobs, link) { + if (blob->id == blobid) { + blob->ref++; + cb_fn(cb_arg, blob, blob->open_status); + return; + } } - cb_fn(cb_arg, g_blob, g_open_blob_status); + cb_fn(cb_arg, NULL, -ENOENT); } uint64_t @@ -284,6 +337,12 @@ void spdk_bs_md_create_blob(struct spdk_blob_store *bs, spdk_blob_op_with_id_complete cb_fn, void *cb_arg) { + struct spdk_blob *b; + + b = calloc(1, sizeof(*b)); + SPDK_CU_ASSERT_FATAL(b != NULL); + + TAILQ_INSERT_TAIL(&bs->blobs, b, link); cb_fn(cb_arg, 0, 0); } @@ -327,11 +386,11 @@ destroy_cb(void *cb_arg, int lvolerrno) static void lvs_init_unload_success(void) { - struct spdk_bs_dev bs_dev; + struct lvol_ut_bs_dev dev; struct spdk_lvs_opts opts; int rc = 0; - init_dev(&bs_dev); + init_dev(&dev); spdk_allocate_thread(_lvol_send_msg, NULL, NULL); spdk_lvs_opts_init(&opts); @@ -339,7 +398,7 @@ lvs_init_unload_success(void) g_lvserrno = -1; CU_ASSERT(TAILQ_EMPTY(&g_lvol_stores)); - rc = spdk_lvs_init(&bs_dev, &opts, lvol_store_op_with_handle_complete, NULL); + rc = spdk_lvs_init(&dev.bs_dev, &opts, lvol_store_op_with_handle_complete, NULL); CU_ASSERT(rc == 0); CU_ASSERT(g_lvserrno == 0); SPDK_CU_ASSERT_FATAL(g_lvol_store != NULL); @@ -368,24 +427,26 @@ lvs_init_unload_success(void) g_lvol_store = NULL; CU_ASSERT(TAILQ_EMPTY(&g_lvol_stores)); + free_dev(&dev); + spdk_free_thread(); } static void lvs_init_destroy_success(void) { - struct spdk_bs_dev bs_dev; + struct lvol_ut_bs_dev dev; struct spdk_lvs_opts opts; int rc = 0; - init_dev(&bs_dev); + init_dev(&dev); spdk_allocate_thread(_lvol_send_msg, NULL, NULL); spdk_lvs_opts_init(&opts); g_lvserrno = -1; - rc = spdk_lvs_init(&bs_dev, &opts, lvol_store_op_with_handle_complete, NULL); + rc = spdk_lvs_init(&dev.bs_dev, &opts, lvol_store_op_with_handle_complete, NULL); CU_ASSERT(rc == 0); CU_ASSERT(g_lvserrno == 0); SPDK_CU_ASSERT_FATAL(g_lvol_store != NULL); @@ -404,6 +465,8 @@ lvs_init_destroy_success(void) spdk_lvol_close(g_lvol, close_cb, NULL); CU_ASSERT(g_lvserrno == 0); + spdk_lvol_destroy(g_lvol, destroy_cb, NULL); + g_lvserrno = -1; rc = spdk_lvs_destroy(g_lvol_store, true, lvol_store_op_complete, NULL); CU_ASSERT(rc == 0); @@ -416,21 +479,21 @@ lvs_init_destroy_success(void) static void lvs_init_opts_success(void) { - struct spdk_bs_dev bs_dev; + struct lvol_ut_bs_dev dev; struct spdk_lvs_opts opts; int rc = 0; - init_dev(&bs_dev); + init_dev(&dev); spdk_allocate_thread(_lvol_send_msg, NULL, NULL); g_lvserrno = -1; opts.cluster_sz = 8192; - rc = spdk_lvs_init(&bs_dev, &opts, lvol_store_op_with_handle_complete, NULL); + rc = spdk_lvs_init(&dev.bs_dev, &opts, lvol_store_op_with_handle_complete, NULL); CU_ASSERT(rc == 0); CU_ASSERT(g_lvserrno == 0); - CU_ASSERT(g_bs_opts.cluster_sz == opts.cluster_sz); + CU_ASSERT(dev.bs->bs_opts.cluster_sz == opts.cluster_sz); SPDK_CU_ASSERT_FATAL(g_lvol_store != NULL); g_lvserrno = -1; @@ -439,6 +502,8 @@ lvs_init_opts_success(void) CU_ASSERT(g_lvserrno == 0); g_lvol_store = NULL; + free_dev(&dev); + spdk_free_thread(); } @@ -460,18 +525,18 @@ lvs_unload_lvs_is_null_fail(void) static void lvol_create_destroy_success(void) { - struct spdk_bs_dev bs_dev; + struct lvol_ut_bs_dev dev; struct spdk_lvs_opts opts; int rc = 0; - init_dev(&bs_dev); + init_dev(&dev); spdk_allocate_thread(_lvol_send_msg, NULL, NULL); spdk_lvs_opts_init(&opts); g_lvserrno = -1; - rc = spdk_lvs_init(&bs_dev, &opts, lvol_store_op_with_handle_complete, NULL); + rc = spdk_lvs_init(&dev.bs_dev, &opts, lvol_store_op_with_handle_complete, NULL); CU_ASSERT(rc == 0); CU_ASSERT(g_lvserrno == 0); SPDK_CU_ASSERT_FATAL(g_lvol_store != NULL); @@ -491,17 +556,19 @@ lvol_create_destroy_success(void) CU_ASSERT(g_lvserrno == 0); g_lvol_store = NULL; + free_dev(&dev); + spdk_free_thread(); } static void lvol_create_fail(void) { - struct spdk_bs_dev bs_dev; + struct lvol_ut_bs_dev dev; struct spdk_lvs_opts opts; int rc = 0; - init_dev(&bs_dev); + init_dev(&dev); spdk_allocate_thread(_lvol_send_msg, NULL, NULL); @@ -513,7 +580,7 @@ lvol_create_fail(void) CU_ASSERT(rc != 0); CU_ASSERT(g_lvol_store == NULL); - rc = spdk_lvs_init(&bs_dev, &opts, lvol_store_op_with_handle_complete, NULL); + rc = spdk_lvs_init(&dev.bs_dev, &opts, lvol_store_op_with_handle_complete, NULL); CU_ASSERT(rc == 0); SPDK_CU_ASSERT_FATAL(g_lvol_store != NULL); @@ -532,23 +599,25 @@ lvol_create_fail(void) CU_ASSERT(g_lvserrno == 0); g_lvol_store = NULL; + free_dev(&dev); + spdk_free_thread(); } static void lvol_destroy_fail(void) { - struct spdk_bs_dev bs_dev; + struct lvol_ut_bs_dev dev; struct spdk_lvs_opts opts; int rc = 0; - init_dev(&bs_dev); + init_dev(&dev); spdk_allocate_thread(_lvol_send_msg, NULL, NULL); spdk_lvs_opts_init(&opts); - rc = spdk_lvs_init(&bs_dev, &opts, lvol_store_op_with_handle_complete, NULL); + rc = spdk_lvs_init(&dev.bs_dev, &opts, lvol_store_op_with_handle_complete, NULL); CU_ASSERT(rc == 0); CU_ASSERT(g_lvserrno == 0); SPDK_CU_ASSERT_FATAL(g_lvol_store != NULL); @@ -568,23 +637,25 @@ lvol_destroy_fail(void) CU_ASSERT(g_lvserrno == 0); g_lvol_store = NULL; + free_dev(&dev); + spdk_free_thread(); } static void lvol_close_fail(void) { - struct spdk_bs_dev bs_dev; + struct lvol_ut_bs_dev dev; struct spdk_lvs_opts opts; int rc = 0; - init_dev(&bs_dev); + init_dev(&dev); spdk_allocate_thread(_lvol_send_msg, NULL, NULL); spdk_lvs_opts_init(&opts); - rc = spdk_lvs_init(&bs_dev, &opts, lvol_store_op_with_handle_complete, NULL); + rc = spdk_lvs_init(&dev.bs_dev, &opts, lvol_store_op_with_handle_complete, NULL); CU_ASSERT(rc == 0); CU_ASSERT(g_lvserrno == 0); SPDK_CU_ASSERT_FATAL(g_lvol_store != NULL); @@ -602,24 +673,26 @@ lvol_close_fail(void) CU_ASSERT(g_lvserrno == 0); g_lvol_store = NULL; + free_dev(&dev); + spdk_free_thread(); } static void lvol_close_success(void) { - struct spdk_bs_dev bs_dev; + struct lvol_ut_bs_dev dev; struct spdk_lvs_opts opts; int rc = 0; - init_dev(&bs_dev); + init_dev(&dev); spdk_allocate_thread(_lvol_send_msg, NULL, NULL); spdk_lvs_opts_init(&opts); g_lvserrno = -1; - rc = spdk_lvs_init(&bs_dev, &opts, lvol_store_op_with_handle_complete, NULL); + rc = spdk_lvs_init(&dev.bs_dev, &opts, lvol_store_op_with_handle_complete, NULL); CU_ASSERT(rc == 0); CU_ASSERT(g_lvserrno == 0); SPDK_CU_ASSERT_FATAL(g_lvol_store != NULL); @@ -637,17 +710,19 @@ lvol_close_success(void) CU_ASSERT(g_lvserrno == 0); g_lvol_store = NULL; + free_dev(&dev); + spdk_free_thread(); } static void lvol_resize(void) { - struct spdk_bs_dev bs_dev; + struct lvol_ut_bs_dev dev; struct spdk_lvs_opts opts; int rc = 0; - init_dev(&bs_dev); + init_dev(&dev); spdk_allocate_thread(_lvol_send_msg, NULL, NULL); @@ -655,7 +730,7 @@ lvol_resize(void) g_resize_rc = 0; g_lvserrno = -1; - rc = spdk_lvs_init(&bs_dev, &opts, lvol_store_op_with_handle_complete, NULL); + rc = spdk_lvs_init(&dev.bs_dev, &opts, lvol_store_op_with_handle_complete, NULL); CU_ASSERT(rc == 0); CU_ASSERT(g_lvserrno == 0); SPDK_CU_ASSERT_FATAL(g_lvol_store != NULL); @@ -706,76 +781,86 @@ lvol_resize(void) CU_ASSERT(g_lvserrno == 0); g_lvol_store = NULL; + free_dev(&dev); + spdk_free_thread(); } +static void +null_cb(void *ctx, struct spdk_blob_store *bs, int bserrno) +{ + SPDK_CU_ASSERT_FATAL(bs != NULL); +} + static void lvs_load(void) { int rc = -1; - struct spdk_bs_dev bs_dev; + struct lvol_ut_bs_dev dev; struct spdk_lvs_with_handle_req *req; + struct spdk_bs_opts bs_opts = {}; + struct spdk_blob *super_blob; req = calloc(1, sizeof(*req)); SPDK_CU_ASSERT_FATAL(req != NULL); - init_dev(&bs_dev); + init_dev(&dev); + spdk_bs_opts_init(&bs_opts); + strncpy(bs_opts.bstype.bstype, "LVOLSTORE", SPDK_BLOBSTORE_TYPE_LENGTH); + spdk_bs_init(&dev.bs_dev, &bs_opts, null_cb, NULL); spdk_allocate_thread(_lvol_send_msg, NULL, NULL); /* Fail on bs load */ - g_bs_load_status = -1; + dev.load_status = -1; CU_ASSERT(TAILQ_EMPTY(&g_lvol_stores)); - spdk_lvs_load(&bs_dev, lvol_store_op_with_handle_complete, req); + spdk_lvs_load(&dev.bs_dev, lvol_store_op_with_handle_complete, req); CU_ASSERT(g_lvserrno != 0); CU_ASSERT(g_lvol_store == NULL); CU_ASSERT(TAILQ_EMPTY(&g_lvol_stores)); /* Fail on getting super blob */ - g_bs_load_status = 0; - g_get_super_status = -1; - spdk_lvs_load(&bs_dev, lvol_store_op_with_handle_complete, req); + dev.load_status = 0; + dev.bs->get_super_status = -1; + spdk_lvs_load(&dev.bs_dev, lvol_store_op_with_handle_complete, req); CU_ASSERT(g_lvserrno == -ENODEV); CU_ASSERT(g_lvol_store == NULL); CU_ASSERT(TAILQ_EMPTY(&g_lvol_stores)); /* Fail on opening super blob */ g_lvserrno = 0; - g_get_super_status = 0; - g_open_blob_status = -1; - spdk_lvs_load(&bs_dev, lvol_store_op_with_handle_complete, req); + super_blob = calloc(1, sizeof(*super_blob)); + super_blob->id = 0x100; + super_blob->open_status = -1; + TAILQ_INSERT_TAIL(&dev.bs->blobs, super_blob, link); + dev.bs->super_blobid = 0x100; + dev.bs->get_super_status = 0; + spdk_lvs_load(&dev.bs_dev, lvol_store_op_with_handle_complete, req); CU_ASSERT(g_lvserrno == -ENODEV); CU_ASSERT(g_lvol_store == NULL); CU_ASSERT(TAILQ_EMPTY(&g_lvol_stores)); /* Fail on getting uuid */ g_lvserrno = 0; - g_get_super_status = 0; - g_open_blob_status = 0; - g_get_uuid_status = -1; - spdk_lvs_load(&bs_dev, lvol_store_op_with_handle_complete, req); + super_blob->open_status = 0; + spdk_lvs_load(&dev.bs_dev, lvol_store_op_with_handle_complete, req); CU_ASSERT(g_lvserrno == -ENODEV); CU_ASSERT(g_lvol_store == NULL); CU_ASSERT(TAILQ_EMPTY(&g_lvol_stores)); /* Fail on closing super blob */ g_lvserrno = 0; - g_get_super_status = 0; - g_open_blob_status = 0; - g_get_uuid_status = 0; - g_close_super_status = -1; - spdk_lvs_load(&bs_dev, lvol_store_op_with_handle_complete, req); + spdk_blob_md_set_xattr(super_blob, "uuid", uuid, UUID_STRING_LEN); + super_blob->close_status = -1; + spdk_lvs_load(&dev.bs_dev, lvol_store_op_with_handle_complete, req); CU_ASSERT(g_lvserrno == -ENODEV); CU_ASSERT(g_lvol_store == NULL); CU_ASSERT(TAILQ_EMPTY(&g_lvol_stores)); /* Load successfully */ g_lvserrno = 0; - g_get_super_status = 0; - g_open_blob_status = 0; - g_get_uuid_status = 0; - g_close_super_status = 0; - spdk_lvs_load(&bs_dev, lvol_store_op_with_handle_complete, req); + super_blob->close_status = 0; + spdk_lvs_load(&dev.bs_dev, lvol_store_op_with_handle_complete, req); CU_ASSERT(g_lvserrno == 0); CU_ASSERT(g_lvol_store != NULL); CU_ASSERT(!TAILQ_EMPTY(&g_lvol_stores)); @@ -787,6 +872,7 @@ lvs_load(void) CU_ASSERT(TAILQ_EMPTY(&g_lvol_stores)); free(req); + free_dev(&dev); spdk_free_thread(); } @@ -795,32 +881,80 @@ static void lvols_load(void) { int rc = -1; - struct spdk_bs_dev bs_dev; + struct lvol_ut_bs_dev dev; struct spdk_lvs_with_handle_req *req; + struct spdk_bs_opts bs_opts; + struct spdk_blob *super_blob, *blob1, *blob2, *blob3; req = calloc(1, sizeof(*req)); SPDK_CU_ASSERT_FATAL(req != NULL); - init_dev(&bs_dev); + init_dev(&dev); + spdk_bs_opts_init(&bs_opts); + strncpy(bs_opts.bstype.bstype, "LVOLSTORE", SPDK_BLOBSTORE_TYPE_LENGTH); + spdk_bs_init(&dev.bs_dev, &bs_opts, null_cb, NULL); + super_blob = calloc(1, sizeof(*super_blob)); + super_blob->id = 0x100; + spdk_blob_md_set_xattr(super_blob, "uuid", uuid, UUID_STRING_LEN); + TAILQ_INSERT_TAIL(&dev.bs->blobs, super_blob, link); + dev.bs->super_blobid = 0x100; + + /* + * Create 3 blobs, write different char values to the last char in the UUID + * to make sure they are unique. + */ + blob1 = calloc(1, sizeof(*blob1)); + blob1->id = 0x1; + spdk_blob_md_set_xattr(blob1, "uuid", uuid, UUID_STRING_LEN); + blob1->uuid[UUID_STRING_LEN - 2] = '1'; + + blob2 = calloc(1, sizeof(*blob2)); + blob2->id = 0x2; + spdk_blob_md_set_xattr(blob2, "uuid", uuid, UUID_STRING_LEN); + blob2->uuid[UUID_STRING_LEN - 2] = '2'; + + blob3 = calloc(1, sizeof(*blob3)); + blob3->id = 0x2; + spdk_blob_md_set_xattr(blob2, "uuid", uuid, UUID_STRING_LEN); + blob3->uuid[UUID_STRING_LEN - 2] = '3'; spdk_allocate_thread(_lvol_send_msg, NULL, NULL); - /* Load lvs */ + /* Load lvs with 0 blobs */ g_lvserrno = 0; - g_get_super_status = 0; - g_open_blob_status = 0; - g_get_uuid_status = 0; - g_close_super_status = 0; - spdk_lvs_load(&bs_dev, lvol_store_op_with_handle_complete, req); + spdk_lvs_load(&dev.bs_dev, lvol_store_op_with_handle_complete, req); CU_ASSERT(g_lvserrno == 0); CU_ASSERT(g_lvol_store != NULL); + CU_ASSERT(g_lvserrno == 0); g_lvserrno = -1; rc = spdk_lvs_unload(g_lvol_store, lvol_store_op_complete, NULL); CU_ASSERT(rc == 0); CU_ASSERT(g_lvserrno == 0); + TAILQ_INSERT_TAIL(&dev.bs->blobs, blob1, link); + TAILQ_INSERT_TAIL(&dev.bs->blobs, blob2, link); + TAILQ_INSERT_TAIL(&dev.bs->blobs, blob3, link); + + /* Load lvs again with 3 blobs */ + /* TODO: add some more unit tests where some of these blobs fail to open. */ + g_lvol_store = NULL; + g_lvserrno = 0; + spdk_lvs_load(&dev.bs_dev, lvol_store_op_with_handle_complete, req); + CU_ASSERT(g_lvserrno == 0); + CU_ASSERT(g_lvol_store != NULL); + + g_lvserrno = -1; + /* rc = */ spdk_lvs_unload(g_lvol_store, lvol_store_op_complete, NULL); + /* + * Disable these two asserts for now. lvolstore should allow unload as long + * as the lvols were not opened - but this is coming a future patch. + */ + /* CU_ASSERT(rc == 0); */ + /* CU_ASSERT(g_lvserrno == 0); */ + free(req); + free_dev(&dev); spdk_free_thread(); }