diff options
Diffstat (limited to 'src/spdk/test/unit/lib/bdev/bdev_zone.c/bdev_zone_ut.c')
-rw-r--r-- | src/spdk/test/unit/lib/bdev/bdev_zone.c/bdev_zone_ut.c | 429 |
1 files changed, 429 insertions, 0 deletions
diff --git a/src/spdk/test/unit/lib/bdev/bdev_zone.c/bdev_zone_ut.c b/src/spdk/test/unit/lib/bdev/bdev_zone.c/bdev_zone_ut.c new file mode 100644 index 000000000..589e105b9 --- /dev/null +++ b/src/spdk/test/unit/lib/bdev/bdev_zone.c/bdev_zone_ut.c @@ -0,0 +1,429 @@ +/*- + * BSD LICENSE + * + * Copyright (c) Intel Corporation. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Intel Corporation nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE AiRE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "spdk/stdinc.h" +#include "spdk_cunit.h" +#include "spdk/env.h" +#include "spdk_internal/mock.h" + +#include "bdev/bdev_zone.c" + +DEFINE_STUB_V(bdev_io_init, (struct spdk_bdev_io *bdev_io, + struct spdk_bdev *bdev, void *cb_arg, + spdk_bdev_io_completion_cb cb)); + +DEFINE_STUB_V(bdev_io_submit, (struct spdk_bdev_io *bdev_io)); + +/* Construct zone_io_operation structure */ +struct zone_io_operation { + struct spdk_bdev_desc *desc; + struct spdk_io_channel *ch; + struct iovec iov; + union { + struct { + uint64_t zone_id; + size_t num_zones; + enum spdk_bdev_zone_action zone_action; + void *buf; + struct spdk_bdev_zone_info *info_; + } zone_mgmt; + struct { + void *md_buf; + struct iovec *iovs; + int iovcnt; + uint64_t num_blocks; + uint64_t offset_blocks; + uint64_t start_lba; + } bdev; + }; + spdk_bdev_io_completion_cb cb; + void *cb_arg; + enum spdk_bdev_io_type io_type; +}; + +/* Global variables */ +struct zone_io_operation *g_zone_op = NULL; +static struct spdk_bdev *g_bdev = NULL; +static struct spdk_bdev_io *g_bdev_io = NULL; +static struct spdk_bdev_zone_info g_zone_info = {0}; +static enum spdk_bdev_zone_action g_zone_action = SPDK_BDEV_ZONE_OPEN; +static enum spdk_bdev_zone_action g_unexpected_zone_action = SPDK_BDEV_ZONE_CLOSE; +static enum spdk_bdev_io_type g_io_type = SPDK_BDEV_IO_TYPE_GET_ZONE_INFO; + +static uint64_t g_expected_zone_id; +static uint64_t g_expected_num_zones; +static uint64_t g_unexpected_zone_id; +static uint64_t g_unexpected_num_zones; +static uint64_t g_num_blocks; +static uint64_t g_unexpected_num_blocks; +static uint64_t g_start_lba; +static uint64_t g_unexpected_start_lba; +static uint64_t g_bdev_blocklen; +static uint64_t g_unexpected_bdev_blocklen; +static bool g_append_with_md; +static int g_unexpected_iovcnt; +static void *g_md_buf; +static void *g_unexpetced_md_buf; +static void *g_buf; +static void *g_unexpected_buf; + +static int +test_setup(void) +{ + /* Initiate expected and unexpected value here */ + g_expected_zone_id = 0x1000; + g_expected_num_zones = 1024; + g_unexpected_zone_id = 0xFFFF; + g_unexpected_num_zones = 0; + g_num_blocks = 4096 * 1024; + g_unexpected_num_blocks = 0; + g_start_lba = 4096; + g_unexpected_start_lba = 0; + g_bdev_blocklen = 4096; + g_unexpected_bdev_blocklen = 0; + g_append_with_md = false; + g_unexpected_iovcnt = 1000; + g_md_buf = (void *)0xEFDCFEDE; + g_unexpetced_md_buf = (void *)0xFECDEFDC; + g_buf = (void *)0xFEEDBEEF; + g_unexpected_buf = (void *)0xDEADBEEF; + + return 0; +} + +static int +test_cleanup(void) +{ + return 0; +} + +static void +start_operation(void) +{ + g_zone_op = calloc(1, sizeof(struct zone_io_operation)); + SPDK_CU_ASSERT_FATAL(g_zone_op != NULL); + + switch (g_io_type) { + case SPDK_BDEV_IO_TYPE_ZONE_APPEND: + g_zone_op->bdev.iovs = &g_zone_op->iov; + g_zone_op->bdev.iovs[0].iov_base = g_unexpected_buf; + g_zone_op->bdev.iovs[0].iov_len = g_unexpected_num_blocks * g_unexpected_bdev_blocklen; + g_zone_op->bdev.iovcnt = g_unexpected_iovcnt; + g_zone_op->bdev.md_buf = g_unexpetced_md_buf; + g_zone_op->bdev.num_blocks = g_unexpected_num_blocks; + g_zone_op->bdev.offset_blocks = g_unexpected_zone_id; + g_zone_op->bdev.start_lba = g_unexpected_start_lba; + break; + default: + g_zone_op->bdev.iovcnt = 0; + g_zone_op->zone_mgmt.zone_id = g_unexpected_zone_id; + g_zone_op->zone_mgmt.num_zones = g_unexpected_num_zones; + g_zone_op->zone_mgmt.zone_action = g_unexpected_zone_action; + g_zone_op->zone_mgmt.buf = g_unexpected_buf; + break; + } +} + +static void +stop_operation(void) +{ + free(g_bdev_io); + free(g_bdev); + free(g_zone_op); + g_bdev_io = NULL; + g_bdev = NULL; + g_zone_op = NULL; +} + +struct spdk_bdev_io * +bdev_channel_get_io(struct spdk_bdev_channel *channel) +{ + struct spdk_bdev_io *bdev_io; + + bdev_io = calloc(1, sizeof(struct spdk_bdev_io)); + SPDK_CU_ASSERT_FATAL(bdev_io != NULL); + + bdev_io->internal.ch = channel; + bdev_io->type = g_io_type; + + CU_ASSERT(g_zone_op != NULL); + + switch (g_io_type) { + case SPDK_BDEV_IO_TYPE_GET_ZONE_INFO: + case SPDK_BDEV_IO_TYPE_ZONE_MANAGEMENT: + bdev_io->u.bdev.iovcnt = 0; + bdev_io->u.zone_mgmt.zone_id = g_zone_op->zone_mgmt.zone_id; + bdev_io->u.zone_mgmt.num_zones = g_zone_op->zone_mgmt.num_zones; + bdev_io->u.zone_mgmt.zone_action = g_zone_op->zone_mgmt.zone_action; + bdev_io->u.zone_mgmt.buf = g_zone_op->zone_mgmt.buf; + break; + case SPDK_BDEV_IO_TYPE_ZONE_APPEND: + bdev_io->u.bdev.iovs = g_zone_op->bdev.iovs; + bdev_io->u.bdev.iovs[0].iov_base = g_zone_op->bdev.iovs[0].iov_base; + bdev_io->u.bdev.iovs[0].iov_len = g_zone_op->bdev.iovs[0].iov_len; + bdev_io->u.bdev.iovcnt = g_zone_op->bdev.iovcnt; + bdev_io->u.bdev.md_buf = g_zone_op->bdev.md_buf; + bdev_io->u.bdev.num_blocks = g_zone_op->bdev.num_blocks; + bdev_io->u.bdev.offset_blocks = g_zone_op->bdev.offset_blocks; + break; + default: + CU_ASSERT(0); + } + + g_bdev_io = bdev_io; + + return bdev_io; +} + +int +spdk_bdev_open(struct spdk_bdev *bdev, bool write, spdk_bdev_remove_cb_t remove_cb, + void *remove_ctx, struct spdk_bdev_desc **_desc) +{ + *_desc = (void *)0x1; + return 0; +} + +struct spdk_io_channel * +spdk_bdev_get_io_channel(struct spdk_bdev_desc *desc) +{ + return (struct spdk_io_channel *)0x1; +} + +void +spdk_put_io_channel(struct spdk_io_channel *ch) +{ + CU_ASSERT(ch == (void *)1); +} + +struct spdk_bdev * +spdk_bdev_desc_get_bdev(struct spdk_bdev_desc *desc) +{ + struct spdk_bdev *bdev; + + bdev = calloc(1, sizeof(struct spdk_bdev)); + SPDK_CU_ASSERT_FATAL(bdev != NULL); + + if (g_io_type == SPDK_BDEV_IO_TYPE_ZONE_APPEND) { + bdev->blocklen = g_bdev_blocklen; + } + + g_bdev = bdev; + + return bdev; +} + +static void +test_get_zone_size(void) +{ + struct spdk_bdev bdev = {}; + uint64_t get_zone_size; + + bdev.zone_size = 1024 * 4096; + + get_zone_size = spdk_bdev_get_zone_size(&bdev); + CU_ASSERT(get_zone_size == 1024 * 4096); +} + +static void +test_get_max_open_zones(void) +{ + struct spdk_bdev bdev = {}; + uint32_t get_max_open_zones; + + bdev.max_open_zones = 8192; + + get_max_open_zones = spdk_bdev_get_max_open_zones(&bdev); + CU_ASSERT(get_max_open_zones == 8192); +} + +static void +test_get_optimal_open_zones(void) +{ + struct spdk_bdev bdev = {}; + uint32_t get_optimal_open_zones; + + bdev.optimal_open_zones = 4096; + + get_optimal_open_zones = spdk_bdev_get_optimal_open_zones(&bdev); + CU_ASSERT(get_optimal_open_zones == 4096); +} + +static void +test_bdev_io_get_append_location(void) +{ + struct spdk_bdev_io bdev_io = {}; + uint64_t get_offset_blocks; + + bdev_io.u.bdev.offset_blocks = 1024 * 10; + + get_offset_blocks = spdk_bdev_io_get_append_location(&bdev_io); + CU_ASSERT(get_offset_blocks == 1024 * 10); +} + +static void +test_zone_get_operation(void) +{ + test_get_zone_size(); + test_get_max_open_zones(); + test_get_optimal_open_zones(); +} + +#define DECLARE_VIRTUAL_BDEV_START() \ + struct spdk_bdev bdev; \ + struct spdk_io_channel *ch; \ + struct spdk_bdev_desc *desc = NULL; \ + int rc; \ + memset(&bdev, 0, sizeof(bdev)); \ + bdev.name = "bdev_zone_ut"; \ + rc = spdk_bdev_open(&bdev, true, NULL, NULL, &desc); \ + CU_ASSERT(rc == 0); \ + SPDK_CU_ASSERT_FATAL(desc != NULL); \ + ch = spdk_bdev_get_io_channel(desc); \ + CU_ASSERT(ch != NULL);\ + +static void +test_bdev_zone_get_info(void) +{ + DECLARE_VIRTUAL_BDEV_START(); + + g_zone_info.zone_id = g_expected_zone_id; + g_io_type = SPDK_BDEV_IO_TYPE_GET_ZONE_INFO; + + start_operation(); + + rc = spdk_bdev_get_zone_info(desc, ch, g_expected_zone_id, g_expected_num_zones, &g_zone_info, NULL, + NULL); + CU_ASSERT(rc == 0); + CU_ASSERT(g_bdev_io->type == SPDK_BDEV_IO_TYPE_GET_ZONE_INFO); + CU_ASSERT(g_bdev_io->u.zone_mgmt.zone_id == g_expected_zone_id); + CU_ASSERT(g_bdev_io->u.zone_mgmt.num_zones == g_expected_num_zones); + CU_ASSERT(g_bdev_io->u.zone_mgmt.buf == &g_zone_info); + + stop_operation(); +} + +static void +test_bdev_zone_management(void) +{ + DECLARE_VIRTUAL_BDEV_START(); + + g_zone_info.zone_id = g_expected_zone_id; + g_io_type = SPDK_BDEV_IO_TYPE_ZONE_MANAGEMENT; + + start_operation(); + + rc = spdk_bdev_zone_management(desc, ch, g_expected_zone_id, g_zone_action, NULL, + NULL); + CU_ASSERT(rc == 0); + CU_ASSERT(g_bdev_io->type == SPDK_BDEV_IO_TYPE_ZONE_MANAGEMENT); + CU_ASSERT(g_bdev_io->u.zone_mgmt.zone_id == g_expected_zone_id); + CU_ASSERT(g_bdev_io->u.zone_mgmt.zone_action == g_zone_action); + CU_ASSERT(g_bdev_io->u.zone_mgmt.num_zones == 1); + + stop_operation(); +} + +static void +test_bdev_zone_append(void) +{ + DECLARE_VIRTUAL_BDEV_START(); + + g_io_type = SPDK_BDEV_IO_TYPE_ZONE_APPEND; + g_append_with_md = false; + + start_operation(); + + rc = spdk_bdev_zone_append(desc, ch, g_buf, g_start_lba, g_num_blocks, NULL, NULL); + + CU_ASSERT(rc == 0); + CU_ASSERT(g_bdev_io->internal.desc == desc); + CU_ASSERT(g_bdev_io->type == SPDK_BDEV_IO_TYPE_ZONE_APPEND); + CU_ASSERT(g_bdev_io->u.bdev.iovs[0].iov_base == g_buf); + CU_ASSERT(g_bdev_io->u.bdev.iovs[0].iov_len == g_num_blocks * g_bdev_blocklen); + CU_ASSERT(g_bdev_io->u.bdev.iovcnt == 1); + CU_ASSERT(g_bdev_io->u.bdev.md_buf == NULL); + CU_ASSERT(g_bdev_io->u.bdev.num_blocks == g_num_blocks); + CU_ASSERT(g_bdev_io->u.bdev.offset_blocks == g_expected_zone_id); + + stop_operation(); +} + +static void +test_bdev_zone_append_with_md(void) +{ + DECLARE_VIRTUAL_BDEV_START(); + + g_io_type = SPDK_BDEV_IO_TYPE_ZONE_APPEND; + g_append_with_md = true; + + start_operation(); + + rc = spdk_bdev_zone_append_with_md(desc, ch, g_buf, g_md_buf, g_start_lba, g_num_blocks, NULL, + NULL); + + CU_ASSERT(rc == 0); + CU_ASSERT(g_bdev_io->internal.desc == desc); + CU_ASSERT(g_bdev_io->type == SPDK_BDEV_IO_TYPE_ZONE_APPEND); + CU_ASSERT(g_bdev_io->u.bdev.iovs[0].iov_base == g_buf); + CU_ASSERT(g_bdev_io->u.bdev.iovs[0].iov_len == g_num_blocks * g_bdev_blocklen); + CU_ASSERT(g_bdev_io->u.bdev.iovcnt == 1); + CU_ASSERT(g_bdev_io->u.bdev.md_buf == g_md_buf); + CU_ASSERT(g_bdev_io->u.bdev.num_blocks == g_num_blocks); + CU_ASSERT(g_bdev_io->u.bdev.offset_blocks == g_expected_zone_id); + + stop_operation(); +} + +int +main(int argc, char **argv) +{ + CU_pSuite suite = NULL; + unsigned int num_failures; + + CU_set_error_action(CUEA_ABORT); + CU_initialize_registry(); + + suite = CU_add_suite("zone", test_setup, test_cleanup); + CU_ADD_TEST(suite, test_zone_get_operation); + CU_ADD_TEST(suite, test_bdev_zone_get_info); + CU_ADD_TEST(suite, test_bdev_zone_management); + CU_ADD_TEST(suite, test_bdev_zone_append); + CU_ADD_TEST(suite, test_bdev_zone_append_with_md); + CU_ADD_TEST(suite, test_bdev_io_get_append_location); + + CU_basic_set_mode(CU_BRM_VERBOSE); + CU_basic_run_tests(); + num_failures = CU_get_number_of_failures(); + CU_cleanup_registry(); + return num_failures; +} |