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 "spdk/stdinc.h" 35 #include "spdk_cunit.h" 36 #include "nvme/nvme_cuse.c" 37 #include "common/lib/nvme/common_stubs.h" 38 39 SPDK_LOG_REGISTER_COMPONENT(nvme) 40 41 DEFINE_STUB(spdk_nvme_ctrlr_alloc_cmb_io_buffer, void *, 42 (struct spdk_nvme_ctrlr *ctrlr, size_t size), NULL); 43 44 DEFINE_STUB(spdk_nvme_ctrlr_cmd_admin_raw, int, (struct spdk_nvme_ctrlr *ctrlr, 45 struct spdk_nvme_cmd *cmd, void *buf, uint32_t len, 46 spdk_nvme_cmd_cb cb_fn, void *cb_arg), 0); 47 48 DEFINE_STUB(spdk_nvme_ctrlr_get_num_ns, uint32_t, 49 (struct spdk_nvme_ctrlr *ctrlr), 128); 50 51 DEFINE_STUB(spdk_nvme_ctrlr_reset, int, (struct spdk_nvme_ctrlr *ctrlr), 0); 52 53 DEFINE_STUB(spdk_nvme_ns_cmd_read, int, 54 (struct spdk_nvme_ns *ns, struct spdk_nvme_qpair *qpair, 55 void *payload, uint64_t lba, uint32_t lba_count, 56 spdk_nvme_cmd_cb cb_fn, void *cb_arg, uint32_t io_flags), 0); 57 58 DEFINE_STUB(spdk_nvme_ns_cmd_write, int, 59 (struct spdk_nvme_ns *ns, struct spdk_nvme_qpair *qpair, 60 void *payload, uint64_t lba, uint32_t lba_count, 61 spdk_nvme_cmd_cb cb_fn, void *cb_arg, uint32_t io_flags), 0); 62 63 DEFINE_STUB(spdk_nvme_ns_get_num_sectors, uint64_t, 64 (struct spdk_nvme_ns *ns), 0); 65 66 DEFINE_STUB(spdk_nvme_ns_get_sector_size, uint32_t, 67 (struct spdk_nvme_ns *ns), 0); 68 69 DEFINE_STUB_V(spdk_unaffinitize_thread, (void)); 70 71 DEFINE_STUB(spdk_nvme_ctrlr_get_ns, struct spdk_nvme_ns *, 72 (struct spdk_nvme_ctrlr *ctrlr, uint32_t nsid), NULL); 73 74 DEFINE_STUB(nvme_io_msg_ctrlr_register, int, 75 (struct spdk_nvme_ctrlr *ctrlr, 76 struct nvme_io_msg_producer *io_msg_producer), 0); 77 78 DEFINE_STUB_V(nvme_io_msg_ctrlr_unregister, 79 (struct spdk_nvme_ctrlr *ctrlr, 80 struct nvme_io_msg_producer *io_msg_producer)); 81 82 DEFINE_STUB(spdk_nvme_ctrlr_is_active_ns, bool, 83 (struct spdk_nvme_ctrlr *ctrlr, uint32_t nsid), true); 84 85 DEFINE_STUB(fuse_reply_err, int, (fuse_req_t req, int err), 0); 86 87 struct cuse_io_ctx *g_ut_ctx; 88 89 DEFINE_RETURN_MOCK(nvme_io_msg_send, int); 90 int 91 nvme_io_msg_send(struct spdk_nvme_ctrlr *ctrlr, 92 uint32_t nsid, spdk_nvme_io_msg_fn fn, void *arg) 93 { 94 g_ut_ctx = arg; 95 96 HANDLE_RETURN_MOCK(nvme_io_msg_send); 97 return 0; 98 } 99 100 static void 101 test_cuse_nvme_submit_io_read_write(void) 102 { 103 struct cuse_device cuse_device = {}; 104 struct fuse_file_info fi = {}; 105 struct nvme_user_io *user_io = NULL; 106 char arg[1024] = {}; 107 fuse_req_t req = (void *)0xDEEACDFF; 108 unsigned flags = FUSE_IOCTL_DIR; 109 uint32_t block_size = 4096; 110 size_t in_bufsz = 4096; 111 size_t out_bufsz = 4096; 112 113 /* Allocate memory to avoid stack buffer overflow */ 114 user_io = calloc(3, 4096); 115 SPDK_CU_ASSERT_FATAL(user_io != NULL); 116 cuse_device.ctrlr = (void *)0xDEADBEEF; 117 cuse_device.nsid = 1; 118 user_io->slba = 1024; 119 user_io->nblocks = 1; 120 g_ut_ctx = NULL; 121 122 /* Submit IO read */ 123 cuse_nvme_submit_io_read(&cuse_device, req, 0, arg, &fi, flags, 124 block_size, user_io, in_bufsz, out_bufsz); 125 CU_ASSERT(g_ut_ctx != NULL); 126 CU_ASSERT(g_ut_ctx->req == req); 127 CU_ASSERT(g_ut_ctx->lba = user_io->slba); 128 CU_ASSERT(g_ut_ctx->lba_count == (uint32_t)(user_io->nblocks + 1)); 129 CU_ASSERT(g_ut_ctx->data_len == 130 (int)((user_io->nblocks + 1) * block_size)); 131 CU_ASSERT(g_ut_ctx->data != NULL); 132 cuse_io_ctx_free(g_ut_ctx); 133 134 /* Submit IO write */ 135 g_ut_ctx = NULL; 136 137 cuse_nvme_submit_io_write(&cuse_device, req, 0, arg, &fi, flags, 138 block_size, user_io, in_bufsz, out_bufsz); 139 CU_ASSERT(g_ut_ctx != NULL); 140 CU_ASSERT(g_ut_ctx->req == req); 141 CU_ASSERT(g_ut_ctx->lba = user_io->slba); 142 CU_ASSERT(g_ut_ctx->lba_count == (uint32_t)(user_io->nblocks + 1)); 143 CU_ASSERT(g_ut_ctx->data_len == 144 (int)((user_io->nblocks + 1) * block_size)); 145 CU_ASSERT(g_ut_ctx->data != NULL); 146 cuse_io_ctx_free(g_ut_ctx); 147 free(user_io); 148 } 149 150 int main(int argc, char **argv) 151 { 152 CU_pSuite suite = NULL; 153 unsigned int num_failures; 154 155 CU_set_error_action(CUEA_ABORT); 156 CU_initialize_registry(); 157 158 suite = CU_add_suite("nvme_cuse", NULL, NULL); 159 CU_ADD_TEST(suite, test_cuse_nvme_submit_io_read_write); 160 161 CU_basic_set_mode(CU_BRM_VERBOSE); 162 CU_basic_run_tests(); 163 num_failures = CU_get_number_of_failures(); 164 CU_cleanup_registry(); 165 return num_failures; 166 } 167