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 <james.r.harris@intel.com>
Change-Id: I68110fa87a63c6e5795bfccc0121c2f58d87c815
Reviewed-on: https://review.gerrithub.io/383036
Tested-by: SPDK Automated Test System <sys_sgsw@intel.com>
Reviewed-by: Daniel Verkamp <daniel.verkamp@intel.com>
This commit is contained in:
Jim Harris 2017-10-18 15:01:52 -07:00 committed by Daniel Verkamp
parent 1efd9cfa2f
commit 70e25b39ac

View File

@ -34,6 +34,7 @@
#include "spdk_cunit.h" #include "spdk_cunit.h"
#include "spdk/blob.h" #include "spdk/blob.h"
#include "spdk/io_channel.h" #include "spdk/io_channel.h"
#include "spdk/util.h"
#include "lib/test_env.c" #include "lib/test_env.c"
@ -51,67 +52,66 @@
#define SPDK_BLOB_OPTS_MAX_MD_OPS 32 #define SPDK_BLOB_OPTS_MAX_MD_OPS 32
#define SPDK_BLOB_OPTS_MAX_CHANNEL_OPS 512 #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 { 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_lvolerrno;
int g_lvserrno; 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_close_super_status;
int g_resize_rc; 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_store *g_lvol_store;
struct spdk_lvol *g_lvol; struct spdk_lvol *g_lvol;
struct spdk_bs_opts g_bs_opts;
struct spdk_blob_store { 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 struct lvol_ut_bs_dev {
bs_iter(void) struct spdk_bs_dev bs_dev;
{ int init_status;
if (g_lvols_count > 0) { int load_status;
g_blob = calloc(1, sizeof(*g_blob)); struct spdk_blob_store *bs;
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;
}
}
void void
spdk_bs_md_iter_next(struct spdk_blob_store *bs, struct spdk_blob **b, 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) spdk_blob_op_with_handle_complete cb_fn, void *cb_arg)
{ {
free(g_blob); struct spdk_blob *next;
bs_iter(); 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 void
spdk_bs_md_iter_first(struct spdk_blob_store *bs, spdk_bs_md_iter_first(struct spdk_blob_store *bs,
spdk_blob_op_with_handle_complete cb_fn, void *cb_arg) 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) 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_bs_get_super(struct spdk_blob_store *bs,
spdk_blob_op_with_id_complete cb_fn, void *cb_arg) 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 void
spdk_bs_set_super(struct spdk_blob_store *bs, spdk_blob_id blobid, spdk_bs_set_super(struct spdk_blob_store *bs, spdk_blob_id blobid,
spdk_bs_op_complete cb_fn, void *cb_arg) spdk_bs_op_complete cb_fn, void *cb_arg)
{ {
bs->super_blobid = blobid;
cb_fn(cb_arg, 0); 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_load(struct spdk_bs_dev *dev, struct spdk_bs_opts *opts,
spdk_bs_op_with_handle_complete cb_fn, void *cb_arg) spdk_bs_op_with_handle_complete cb_fn, void *cb_arg)
{ {
if (g_bs_load_status == 0) { struct lvol_ut_bs_dev *ut_dev = SPDK_CONTAINEROF(dev, struct lvol_ut_bs_dev, bs_dev);
g_blob_store = calloc(1, sizeof(*g_blob_store)); struct spdk_blob_store *bs = NULL;
SPDK_CU_ASSERT_FATAL(g_blob_store != 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) 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, spdk_blob_md_set_xattr(struct spdk_blob *blob, const char *name, const void *value,
uint16_t value_len) uint16_t value_len)
{ {
if (!strcmp(name, "uuid")) {
CU_ASSERT(value_len == UUID_STRING_LEN);
memcpy(blob->uuid, value, UUID_STRING_LEN);
}
return 0; return 0;
} }
@ -161,10 +173,14 @@ int
spdk_bs_md_get_xattr_value(struct spdk_blob *blob, const char *name, spdk_bs_md_get_xattr_value(struct spdk_blob *blob, const char *name,
const void **value, size_t *value_len) const void **value, size_t *value_len)
{ {
*value = uuid; if (!strcmp(name, "uuid") && strnlen(blob->uuid, UUID_STRING_LEN) != 0) {
*value_len = UUID_STRING_LEN; 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 uint64_t
@ -174,23 +190,47 @@ spdk_bs_get_page_size(struct spdk_blob_store *bs)
} }
static void static void
init_dev(struct spdk_bs_dev *dev) init_dev(struct lvol_ut_bs_dev *dev)
{ {
dev->blockcnt = DEV_BUFFER_BLOCKCNT; memset(dev, 0, sizeof(*dev));
dev->blocklen = DEV_BUFFER_BLOCKLEN; dev->bs_dev.blockcnt = DEV_BUFFER_BLOCKCNT;
return; 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 void
spdk_bs_init(struct spdk_bs_dev *dev, struct spdk_bs_opts *o, spdk_bs_init(struct spdk_bs_dev *dev, struct spdk_bs_opts *o,
spdk_bs_op_with_handle_complete cb_fn, void *cb_arg) 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; struct spdk_blob_store *bs;
bs = calloc(1, sizeof(*bs)); bs = calloc(1, sizeof(*bs));
SPDK_CU_ASSERT_FATAL(bs != NULL); 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); cb_fn(cb_arg, bs, 0);
} }
@ -198,8 +238,6 @@ spdk_bs_init(struct spdk_bs_dev *dev, struct spdk_bs_opts *o,
void void
spdk_bs_unload(struct spdk_blob_store *bs, spdk_bs_op_complete cb_fn, void *cb_arg) spdk_bs_unload(struct spdk_blob_store *bs, spdk_bs_op_complete cb_fn, void *cb_arg)
{ {
free(bs);
cb_fn(cb_arg, 0); 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_bs_md_delete_blob(struct spdk_blob_store *bs, spdk_blob_id blobid,
spdk_blob_op_complete cb_fn, void *cb_arg) 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); 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, void spdk_bs_md_close_blob(struct spdk_blob **b,
spdk_blob_op_complete cb_fn, void *cb_arg) 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 int
@ -266,12 +314,17 @@ void
spdk_bs_md_open_blob(struct spdk_blob_store *bs, spdk_blob_id blobid, 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) spdk_blob_op_with_handle_complete cb_fn, void *cb_arg)
{ {
if (g_open_blob_status == 0) { struct spdk_blob *blob;
g_blob = calloc(1, sizeof(*g_blob));
SPDK_CU_ASSERT_FATAL(g_blob != NULL); 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 uint64_t
@ -284,6 +337,12 @@ void
spdk_bs_md_create_blob(struct spdk_blob_store *bs, spdk_bs_md_create_blob(struct spdk_blob_store *bs,
spdk_blob_op_with_id_complete cb_fn, void *cb_arg) 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); cb_fn(cb_arg, 0, 0);
} }
@ -327,11 +386,11 @@ destroy_cb(void *cb_arg, int lvolerrno)
static void static void
lvs_init_unload_success(void) lvs_init_unload_success(void)
{ {
struct spdk_bs_dev bs_dev; struct lvol_ut_bs_dev dev;
struct spdk_lvs_opts opts; struct spdk_lvs_opts opts;
int rc = 0; int rc = 0;
init_dev(&bs_dev); init_dev(&dev);
spdk_allocate_thread(_lvol_send_msg, NULL, NULL); spdk_allocate_thread(_lvol_send_msg, NULL, NULL);
spdk_lvs_opts_init(&opts); spdk_lvs_opts_init(&opts);
@ -339,7 +398,7 @@ lvs_init_unload_success(void)
g_lvserrno = -1; g_lvserrno = -1;
CU_ASSERT(TAILQ_EMPTY(&g_lvol_stores)); 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(rc == 0);
CU_ASSERT(g_lvserrno == 0); CU_ASSERT(g_lvserrno == 0);
SPDK_CU_ASSERT_FATAL(g_lvol_store != NULL); SPDK_CU_ASSERT_FATAL(g_lvol_store != NULL);
@ -368,24 +427,26 @@ lvs_init_unload_success(void)
g_lvol_store = NULL; g_lvol_store = NULL;
CU_ASSERT(TAILQ_EMPTY(&g_lvol_stores)); CU_ASSERT(TAILQ_EMPTY(&g_lvol_stores));
free_dev(&dev);
spdk_free_thread(); spdk_free_thread();
} }
static void static void
lvs_init_destroy_success(void) lvs_init_destroy_success(void)
{ {
struct spdk_bs_dev bs_dev; struct lvol_ut_bs_dev dev;
struct spdk_lvs_opts opts; struct spdk_lvs_opts opts;
int rc = 0; int rc = 0;
init_dev(&bs_dev); init_dev(&dev);
spdk_allocate_thread(_lvol_send_msg, NULL, NULL); spdk_allocate_thread(_lvol_send_msg, NULL, NULL);
spdk_lvs_opts_init(&opts); spdk_lvs_opts_init(&opts);
g_lvserrno = -1; 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(rc == 0);
CU_ASSERT(g_lvserrno == 0); CU_ASSERT(g_lvserrno == 0);
SPDK_CU_ASSERT_FATAL(g_lvol_store != NULL); 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); spdk_lvol_close(g_lvol, close_cb, NULL);
CU_ASSERT(g_lvserrno == 0); CU_ASSERT(g_lvserrno == 0);
spdk_lvol_destroy(g_lvol, destroy_cb, NULL);
g_lvserrno = -1; g_lvserrno = -1;
rc = spdk_lvs_destroy(g_lvol_store, true, lvol_store_op_complete, NULL); rc = spdk_lvs_destroy(g_lvol_store, true, lvol_store_op_complete, NULL);
CU_ASSERT(rc == 0); CU_ASSERT(rc == 0);
@ -416,21 +479,21 @@ lvs_init_destroy_success(void)
static void static void
lvs_init_opts_success(void) lvs_init_opts_success(void)
{ {
struct spdk_bs_dev bs_dev; struct lvol_ut_bs_dev dev;
struct spdk_lvs_opts opts; struct spdk_lvs_opts opts;
int rc = 0; int rc = 0;
init_dev(&bs_dev); init_dev(&dev);
spdk_allocate_thread(_lvol_send_msg, NULL, NULL); spdk_allocate_thread(_lvol_send_msg, NULL, NULL);
g_lvserrno = -1; g_lvserrno = -1;
opts.cluster_sz = 8192; 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(rc == 0);
CU_ASSERT(g_lvserrno == 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); SPDK_CU_ASSERT_FATAL(g_lvol_store != NULL);
g_lvserrno = -1; g_lvserrno = -1;
@ -439,6 +502,8 @@ lvs_init_opts_success(void)
CU_ASSERT(g_lvserrno == 0); CU_ASSERT(g_lvserrno == 0);
g_lvol_store = NULL; g_lvol_store = NULL;
free_dev(&dev);
spdk_free_thread(); spdk_free_thread();
} }
@ -460,18 +525,18 @@ lvs_unload_lvs_is_null_fail(void)
static void static void
lvol_create_destroy_success(void) lvol_create_destroy_success(void)
{ {
struct spdk_bs_dev bs_dev; struct lvol_ut_bs_dev dev;
struct spdk_lvs_opts opts; struct spdk_lvs_opts opts;
int rc = 0; int rc = 0;
init_dev(&bs_dev); init_dev(&dev);
spdk_allocate_thread(_lvol_send_msg, NULL, NULL); spdk_allocate_thread(_lvol_send_msg, NULL, NULL);
spdk_lvs_opts_init(&opts); spdk_lvs_opts_init(&opts);
g_lvserrno = -1; 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(rc == 0);
CU_ASSERT(g_lvserrno == 0); CU_ASSERT(g_lvserrno == 0);
SPDK_CU_ASSERT_FATAL(g_lvol_store != NULL); SPDK_CU_ASSERT_FATAL(g_lvol_store != NULL);
@ -491,17 +556,19 @@ lvol_create_destroy_success(void)
CU_ASSERT(g_lvserrno == 0); CU_ASSERT(g_lvserrno == 0);
g_lvol_store = NULL; g_lvol_store = NULL;
free_dev(&dev);
spdk_free_thread(); spdk_free_thread();
} }
static void static void
lvol_create_fail(void) lvol_create_fail(void)
{ {
struct spdk_bs_dev bs_dev; struct lvol_ut_bs_dev dev;
struct spdk_lvs_opts opts; struct spdk_lvs_opts opts;
int rc = 0; int rc = 0;
init_dev(&bs_dev); init_dev(&dev);
spdk_allocate_thread(_lvol_send_msg, NULL, NULL); spdk_allocate_thread(_lvol_send_msg, NULL, NULL);
@ -513,7 +580,7 @@ lvol_create_fail(void)
CU_ASSERT(rc != 0); CU_ASSERT(rc != 0);
CU_ASSERT(g_lvol_store == NULL); 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); CU_ASSERT(rc == 0);
SPDK_CU_ASSERT_FATAL(g_lvol_store != NULL); SPDK_CU_ASSERT_FATAL(g_lvol_store != NULL);
@ -532,23 +599,25 @@ lvol_create_fail(void)
CU_ASSERT(g_lvserrno == 0); CU_ASSERT(g_lvserrno == 0);
g_lvol_store = NULL; g_lvol_store = NULL;
free_dev(&dev);
spdk_free_thread(); spdk_free_thread();
} }
static void static void
lvol_destroy_fail(void) lvol_destroy_fail(void)
{ {
struct spdk_bs_dev bs_dev; struct lvol_ut_bs_dev dev;
struct spdk_lvs_opts opts; struct spdk_lvs_opts opts;
int rc = 0; int rc = 0;
init_dev(&bs_dev); init_dev(&dev);
spdk_allocate_thread(_lvol_send_msg, NULL, NULL); spdk_allocate_thread(_lvol_send_msg, NULL, NULL);
spdk_lvs_opts_init(&opts); 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(rc == 0);
CU_ASSERT(g_lvserrno == 0); CU_ASSERT(g_lvserrno == 0);
SPDK_CU_ASSERT_FATAL(g_lvol_store != NULL); SPDK_CU_ASSERT_FATAL(g_lvol_store != NULL);
@ -568,23 +637,25 @@ lvol_destroy_fail(void)
CU_ASSERT(g_lvserrno == 0); CU_ASSERT(g_lvserrno == 0);
g_lvol_store = NULL; g_lvol_store = NULL;
free_dev(&dev);
spdk_free_thread(); spdk_free_thread();
} }
static void static void
lvol_close_fail(void) lvol_close_fail(void)
{ {
struct spdk_bs_dev bs_dev; struct lvol_ut_bs_dev dev;
struct spdk_lvs_opts opts; struct spdk_lvs_opts opts;
int rc = 0; int rc = 0;
init_dev(&bs_dev); init_dev(&dev);
spdk_allocate_thread(_lvol_send_msg, NULL, NULL); spdk_allocate_thread(_lvol_send_msg, NULL, NULL);
spdk_lvs_opts_init(&opts); 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(rc == 0);
CU_ASSERT(g_lvserrno == 0); CU_ASSERT(g_lvserrno == 0);
SPDK_CU_ASSERT_FATAL(g_lvol_store != NULL); SPDK_CU_ASSERT_FATAL(g_lvol_store != NULL);
@ -602,24 +673,26 @@ lvol_close_fail(void)
CU_ASSERT(g_lvserrno == 0); CU_ASSERT(g_lvserrno == 0);
g_lvol_store = NULL; g_lvol_store = NULL;
free_dev(&dev);
spdk_free_thread(); spdk_free_thread();
} }
static void static void
lvol_close_success(void) lvol_close_success(void)
{ {
struct spdk_bs_dev bs_dev; struct lvol_ut_bs_dev dev;
struct spdk_lvs_opts opts; struct spdk_lvs_opts opts;
int rc = 0; int rc = 0;
init_dev(&bs_dev); init_dev(&dev);
spdk_allocate_thread(_lvol_send_msg, NULL, NULL); spdk_allocate_thread(_lvol_send_msg, NULL, NULL);
spdk_lvs_opts_init(&opts); spdk_lvs_opts_init(&opts);
g_lvserrno = -1; 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(rc == 0);
CU_ASSERT(g_lvserrno == 0); CU_ASSERT(g_lvserrno == 0);
SPDK_CU_ASSERT_FATAL(g_lvol_store != NULL); SPDK_CU_ASSERT_FATAL(g_lvol_store != NULL);
@ -637,17 +710,19 @@ lvol_close_success(void)
CU_ASSERT(g_lvserrno == 0); CU_ASSERT(g_lvserrno == 0);
g_lvol_store = NULL; g_lvol_store = NULL;
free_dev(&dev);
spdk_free_thread(); spdk_free_thread();
} }
static void static void
lvol_resize(void) lvol_resize(void)
{ {
struct spdk_bs_dev bs_dev; struct lvol_ut_bs_dev dev;
struct spdk_lvs_opts opts; struct spdk_lvs_opts opts;
int rc = 0; int rc = 0;
init_dev(&bs_dev); init_dev(&dev);
spdk_allocate_thread(_lvol_send_msg, NULL, NULL); spdk_allocate_thread(_lvol_send_msg, NULL, NULL);
@ -655,7 +730,7 @@ lvol_resize(void)
g_resize_rc = 0; g_resize_rc = 0;
g_lvserrno = -1; 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(rc == 0);
CU_ASSERT(g_lvserrno == 0); CU_ASSERT(g_lvserrno == 0);
SPDK_CU_ASSERT_FATAL(g_lvol_store != NULL); SPDK_CU_ASSERT_FATAL(g_lvol_store != NULL);
@ -706,76 +781,86 @@ lvol_resize(void)
CU_ASSERT(g_lvserrno == 0); CU_ASSERT(g_lvserrno == 0);
g_lvol_store = NULL; g_lvol_store = NULL;
free_dev(&dev);
spdk_free_thread(); spdk_free_thread();
} }
static void
null_cb(void *ctx, struct spdk_blob_store *bs, int bserrno)
{
SPDK_CU_ASSERT_FATAL(bs != NULL);
}
static void static void
lvs_load(void) lvs_load(void)
{ {
int rc = -1; int rc = -1;
struct spdk_bs_dev bs_dev; struct lvol_ut_bs_dev dev;
struct spdk_lvs_with_handle_req *req; struct spdk_lvs_with_handle_req *req;
struct spdk_bs_opts bs_opts = {};
struct spdk_blob *super_blob;
req = calloc(1, sizeof(*req)); req = calloc(1, sizeof(*req));
SPDK_CU_ASSERT_FATAL(req != NULL); 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); spdk_allocate_thread(_lvol_send_msg, NULL, NULL);
/* Fail on bs load */ /* Fail on bs load */
g_bs_load_status = -1; dev.load_status = -1;
CU_ASSERT(TAILQ_EMPTY(&g_lvol_stores)); 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_lvserrno != 0);
CU_ASSERT(g_lvol_store == NULL); CU_ASSERT(g_lvol_store == NULL);
CU_ASSERT(TAILQ_EMPTY(&g_lvol_stores)); CU_ASSERT(TAILQ_EMPTY(&g_lvol_stores));
/* Fail on getting super blob */ /* Fail on getting super blob */
g_bs_load_status = 0; dev.load_status = 0;
g_get_super_status = -1; dev.bs->get_super_status = -1;
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 == -ENODEV); CU_ASSERT(g_lvserrno == -ENODEV);
CU_ASSERT(g_lvol_store == NULL); CU_ASSERT(g_lvol_store == NULL);
CU_ASSERT(TAILQ_EMPTY(&g_lvol_stores)); CU_ASSERT(TAILQ_EMPTY(&g_lvol_stores));
/* Fail on opening super blob */ /* Fail on opening super blob */
g_lvserrno = 0; g_lvserrno = 0;
g_get_super_status = 0; super_blob = calloc(1, sizeof(*super_blob));
g_open_blob_status = -1; super_blob->id = 0x100;
spdk_lvs_load(&bs_dev, lvol_store_op_with_handle_complete, req); 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_lvserrno == -ENODEV);
CU_ASSERT(g_lvol_store == NULL); CU_ASSERT(g_lvol_store == NULL);
CU_ASSERT(TAILQ_EMPTY(&g_lvol_stores)); CU_ASSERT(TAILQ_EMPTY(&g_lvol_stores));
/* Fail on getting uuid */ /* Fail on getting uuid */
g_lvserrno = 0; g_lvserrno = 0;
g_get_super_status = 0; super_blob->open_status = 0;
g_open_blob_status = 0; spdk_lvs_load(&dev.bs_dev, lvol_store_op_with_handle_complete, req);
g_get_uuid_status = -1;
spdk_lvs_load(&bs_dev, lvol_store_op_with_handle_complete, req);
CU_ASSERT(g_lvserrno == -ENODEV); CU_ASSERT(g_lvserrno == -ENODEV);
CU_ASSERT(g_lvol_store == NULL); CU_ASSERT(g_lvol_store == NULL);
CU_ASSERT(TAILQ_EMPTY(&g_lvol_stores)); CU_ASSERT(TAILQ_EMPTY(&g_lvol_stores));
/* Fail on closing super blob */ /* Fail on closing super blob */
g_lvserrno = 0; g_lvserrno = 0;
g_get_super_status = 0; spdk_blob_md_set_xattr(super_blob, "uuid", uuid, UUID_STRING_LEN);
g_open_blob_status = 0; super_blob->close_status = -1;
g_get_uuid_status = 0; spdk_lvs_load(&dev.bs_dev, lvol_store_op_with_handle_complete, req);
g_close_super_status = -1;
spdk_lvs_load(&bs_dev, lvol_store_op_with_handle_complete, req);
CU_ASSERT(g_lvserrno == -ENODEV); CU_ASSERT(g_lvserrno == -ENODEV);
CU_ASSERT(g_lvol_store == NULL); CU_ASSERT(g_lvol_store == NULL);
CU_ASSERT(TAILQ_EMPTY(&g_lvol_stores)); CU_ASSERT(TAILQ_EMPTY(&g_lvol_stores));
/* Load successfully */ /* Load successfully */
g_lvserrno = 0; g_lvserrno = 0;
g_get_super_status = 0; super_blob->close_status = 0;
g_open_blob_status = 0; spdk_lvs_load(&dev.bs_dev, lvol_store_op_with_handle_complete, req);
g_get_uuid_status = 0;
g_close_super_status = 0;
spdk_lvs_load(&bs_dev, lvol_store_op_with_handle_complete, req);
CU_ASSERT(g_lvserrno == 0); CU_ASSERT(g_lvserrno == 0);
CU_ASSERT(g_lvol_store != NULL); CU_ASSERT(g_lvol_store != NULL);
CU_ASSERT(!TAILQ_EMPTY(&g_lvol_stores)); CU_ASSERT(!TAILQ_EMPTY(&g_lvol_stores));
@ -787,6 +872,7 @@ lvs_load(void)
CU_ASSERT(TAILQ_EMPTY(&g_lvol_stores)); CU_ASSERT(TAILQ_EMPTY(&g_lvol_stores));
free(req); free(req);
free_dev(&dev);
spdk_free_thread(); spdk_free_thread();
} }
@ -795,32 +881,80 @@ static void
lvols_load(void) lvols_load(void)
{ {
int rc = -1; int rc = -1;
struct spdk_bs_dev bs_dev; struct lvol_ut_bs_dev dev;
struct spdk_lvs_with_handle_req *req; 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)); req = calloc(1, sizeof(*req));
SPDK_CU_ASSERT_FATAL(req != NULL); 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); spdk_allocate_thread(_lvol_send_msg, NULL, NULL);
/* Load lvs */ /* Load lvs with 0 blobs */
g_lvserrno = 0; g_lvserrno = 0;
g_get_super_status = 0; spdk_lvs_load(&dev.bs_dev, lvol_store_op_with_handle_complete, req);
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);
CU_ASSERT(g_lvserrno == 0); CU_ASSERT(g_lvserrno == 0);
CU_ASSERT(g_lvol_store != NULL); CU_ASSERT(g_lvol_store != NULL);
CU_ASSERT(g_lvserrno == 0);
g_lvserrno = -1; g_lvserrno = -1;
rc = spdk_lvs_unload(g_lvol_store, lvol_store_op_complete, NULL); rc = spdk_lvs_unload(g_lvol_store, lvol_store_op_complete, NULL);
CU_ASSERT(rc == 0); CU_ASSERT(rc == 0);
CU_ASSERT(g_lvserrno == 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(req);
free_dev(&dev);
spdk_free_thread(); spdk_free_thread();
} }