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 36 #include "spdk_cunit.h" 37 38 #include "spdk_internal/mock.h" 39 40 #include "nvmf/ctrlr_bdev.c" 41 42 43 SPDK_LOG_REGISTER_COMPONENT("nvmf", SPDK_LOG_NVMF) 44 45 DEFINE_STUB(spdk_nvmf_request_complete, int, (struct spdk_nvmf_request *req), -1); 46 47 DEFINE_STUB(spdk_bdev_get_name, const char *, (const struct spdk_bdev *bdev), "test"); 48 49 struct spdk_bdev { 50 uint32_t blocklen; 51 uint32_t md_len; 52 }; 53 54 uint32_t 55 spdk_bdev_get_block_size(const struct spdk_bdev *bdev) 56 { 57 return bdev->blocklen; 58 } 59 60 uint64_t 61 spdk_bdev_get_num_blocks(const struct spdk_bdev *bdev) 62 { 63 abort(); 64 return 0; 65 } 66 67 uint32_t 68 spdk_bdev_get_optimal_io_boundary(const struct spdk_bdev *bdev) 69 { 70 abort(); 71 return 0; 72 } 73 74 uint32_t 75 spdk_bdev_get_md_size(const struct spdk_bdev *bdev) 76 { 77 return bdev->md_len; 78 } 79 80 DEFINE_STUB(spdk_bdev_is_md_interleaved, bool, (const struct spdk_bdev *bdev), false); 81 82 DEFINE_STUB(spdk_bdev_get_dif_type, enum spdk_dif_type, 83 (const struct spdk_bdev *bdev), SPDK_DIF_DISABLE); 84 85 DEFINE_STUB(spdk_bdev_is_dif_head_of_md, bool, (const struct spdk_bdev *bdev), false); 86 87 DEFINE_STUB(spdk_bdev_is_dif_check_enabled, bool, 88 (const struct spdk_bdev *bdev, enum spdk_dif_check_type check_type), false); 89 90 DEFINE_STUB(spdk_bdev_get_io_channel, struct spdk_io_channel *, 91 (struct spdk_bdev_desc *desc), NULL); 92 93 DEFINE_STUB(spdk_bdev_flush_blocks, int, 94 (struct spdk_bdev_desc *desc, struct spdk_io_channel *ch, 95 uint64_t offset_blocks, uint64_t num_blocks, 96 spdk_bdev_io_completion_cb cb, void *cb_arg), 97 0); 98 99 DEFINE_STUB(spdk_bdev_unmap_blocks, int, 100 (struct spdk_bdev_desc *desc, struct spdk_io_channel *ch, 101 uint64_t offset_blocks, uint64_t num_blocks, 102 spdk_bdev_io_completion_cb cb, void *cb_arg), 103 0); 104 105 DEFINE_STUB(spdk_bdev_io_type_supported, bool, 106 (struct spdk_bdev *bdev, enum spdk_bdev_io_type io_type), false); 107 108 DEFINE_STUB(spdk_bdev_queue_io_wait, int, 109 (struct spdk_bdev *bdev, struct spdk_io_channel *ch, 110 struct spdk_bdev_io_wait_entry *entry), 111 0); 112 113 DEFINE_STUB(spdk_bdev_write_blocks, int, 114 (struct spdk_bdev_desc *desc, struct spdk_io_channel *ch, void *buf, 115 uint64_t offset_blocks, uint64_t num_blocks, 116 spdk_bdev_io_completion_cb cb, void *cb_arg), 117 0); 118 119 DEFINE_STUB(spdk_bdev_writev_blocks, int, 120 (struct spdk_bdev_desc *desc, struct spdk_io_channel *ch, 121 struct iovec *iov, int iovcnt, uint64_t offset_blocks, uint64_t num_blocks, 122 spdk_bdev_io_completion_cb cb, void *cb_arg), 123 0); 124 125 DEFINE_STUB(spdk_bdev_read_blocks, int, 126 (struct spdk_bdev_desc *desc, struct spdk_io_channel *ch, void *buf, 127 uint64_t offset_blocks, uint64_t num_blocks, 128 spdk_bdev_io_completion_cb cb, void *cb_arg), 129 0); 130 131 DEFINE_STUB(spdk_bdev_readv_blocks, int, 132 (struct spdk_bdev_desc *desc, struct spdk_io_channel *ch, 133 struct iovec *iov, int iovcnt, uint64_t offset_blocks, uint64_t num_blocks, 134 spdk_bdev_io_completion_cb cb, void *cb_arg), 135 0); 136 137 DEFINE_STUB(spdk_bdev_write_zeroes_blocks, int, 138 (struct spdk_bdev_desc *desc, struct spdk_io_channel *ch, 139 uint64_t offset_blocks, uint64_t num_blocks, 140 spdk_bdev_io_completion_cb cb, void *cb_arg), 141 0); 142 143 DEFINE_STUB(spdk_bdev_nvme_io_passthru, int, 144 (struct spdk_bdev_desc *desc, struct spdk_io_channel *ch, 145 const struct spdk_nvme_cmd *cmd, void *buf, size_t nbytes, 146 spdk_bdev_io_completion_cb cb, void *cb_arg), 147 0); 148 149 DEFINE_STUB_V(spdk_bdev_free_io, (struct spdk_bdev_io *bdev_io)); 150 151 DEFINE_STUB(spdk_nvmf_subsystem_get_nqn, const char *, 152 (struct spdk_nvmf_subsystem *subsystem), NULL); 153 154 struct spdk_nvmf_ns * 155 spdk_nvmf_subsystem_get_ns(struct spdk_nvmf_subsystem *subsystem, uint32_t nsid) 156 { 157 abort(); 158 return NULL; 159 } 160 161 struct spdk_nvmf_ns * 162 spdk_nvmf_subsystem_get_first_ns(struct spdk_nvmf_subsystem *subsystem) 163 { 164 abort(); 165 return NULL; 166 } 167 168 struct spdk_nvmf_ns * 169 spdk_nvmf_subsystem_get_next_ns(struct spdk_nvmf_subsystem *subsystem, struct spdk_nvmf_ns *prev_ns) 170 { 171 abort(); 172 return NULL; 173 } 174 175 DEFINE_STUB_V(spdk_bdev_io_get_nvme_status, 176 (const struct spdk_bdev_io *bdev_io, int *sct, int *sc)); 177 178 int 179 spdk_dif_ctx_init(struct spdk_dif_ctx *ctx, uint32_t block_size, uint32_t md_size, 180 bool md_interleave, bool dif_loc, enum spdk_dif_type dif_type, uint32_t dif_flags, 181 uint32_t init_ref_tag, uint16_t apptag_mask, uint16_t app_tag, 182 uint32_t data_offset, uint16_t guard_seed) 183 { 184 ctx->block_size = block_size; 185 ctx->md_size = md_size; 186 ctx->init_ref_tag = init_ref_tag; 187 188 return 0; 189 } 190 191 static void 192 test_get_rw_params(void) 193 { 194 struct spdk_nvme_cmd cmd = {0}; 195 uint64_t lba; 196 uint64_t count; 197 198 lba = 0; 199 count = 0; 200 to_le64(&cmd.cdw10, 0x1234567890ABCDEF); 201 to_le32(&cmd.cdw12, 0x9875 | SPDK_NVME_IO_FLAGS_FORCE_UNIT_ACCESS); 202 nvmf_bdev_ctrlr_get_rw_params(&cmd, &lba, &count); 203 CU_ASSERT(lba == 0x1234567890ABCDEF); 204 CU_ASSERT(count == 0x9875 + 1); /* NOTE: this field is 0's based, hence the +1 */ 205 } 206 207 static void 208 test_lba_in_range(void) 209 { 210 /* Trivial cases (no overflow) */ 211 CU_ASSERT(nvmf_bdev_ctrlr_lba_in_range(1000, 0, 1) == true); 212 CU_ASSERT(nvmf_bdev_ctrlr_lba_in_range(1000, 0, 1000) == true); 213 CU_ASSERT(nvmf_bdev_ctrlr_lba_in_range(1000, 0, 1001) == false); 214 CU_ASSERT(nvmf_bdev_ctrlr_lba_in_range(1000, 1, 999) == true); 215 CU_ASSERT(nvmf_bdev_ctrlr_lba_in_range(1000, 1, 1000) == false); 216 CU_ASSERT(nvmf_bdev_ctrlr_lba_in_range(1000, 999, 1) == true); 217 CU_ASSERT(nvmf_bdev_ctrlr_lba_in_range(1000, 1000, 1) == false); 218 CU_ASSERT(nvmf_bdev_ctrlr_lba_in_range(1000, 1001, 1) == false); 219 220 /* Overflow edge cases */ 221 CU_ASSERT(nvmf_bdev_ctrlr_lba_in_range(UINT64_MAX, 0, UINT64_MAX) == true); 222 CU_ASSERT(nvmf_bdev_ctrlr_lba_in_range(UINT64_MAX, 1, UINT64_MAX) == false); 223 CU_ASSERT(nvmf_bdev_ctrlr_lba_in_range(UINT64_MAX, UINT64_MAX - 1, 1) == true); 224 CU_ASSERT(nvmf_bdev_ctrlr_lba_in_range(UINT64_MAX, UINT64_MAX, 1) == false); 225 } 226 227 static void 228 test_get_dif_ctx(void) 229 { 230 struct spdk_bdev bdev = {}; 231 struct spdk_nvme_cmd cmd = {}; 232 struct spdk_dif_ctx dif_ctx = {}; 233 bool ret; 234 235 bdev.md_len = 0; 236 237 ret = spdk_nvmf_bdev_ctrlr_get_dif_ctx(&bdev, &cmd, &dif_ctx); 238 CU_ASSERT(ret == false); 239 240 to_le64(&cmd.cdw10, 0x1234567890ABCDEF); 241 bdev.blocklen = 520; 242 bdev.md_len = 8; 243 244 ret = spdk_nvmf_bdev_ctrlr_get_dif_ctx(&bdev, &cmd, &dif_ctx); 245 CU_ASSERT(ret == true); 246 CU_ASSERT(dif_ctx.block_size = 520); 247 CU_ASSERT(dif_ctx.md_size == 8); 248 CU_ASSERT(dif_ctx.init_ref_tag == 0x90ABCDEF); 249 } 250 251 int main(int argc, char **argv) 252 { 253 CU_pSuite suite = NULL; 254 unsigned int num_failures; 255 256 if (CU_initialize_registry() != CUE_SUCCESS) { 257 return CU_get_error(); 258 } 259 260 suite = CU_add_suite("nvmf", NULL, NULL); 261 if (suite == NULL) { 262 CU_cleanup_registry(); 263 return CU_get_error(); 264 } 265 266 if ( 267 CU_add_test(suite, "get_rw_params", test_get_rw_params) == NULL || 268 CU_add_test(suite, "lba_in_range", test_lba_in_range) == NULL || 269 CU_add_test(suite, "get_dif_ctx", test_get_dif_ctx) == NULL 270 ) { 271 CU_cleanup_registry(); 272 return CU_get_error(); 273 } 274 275 CU_basic_set_mode(CU_BRM_VERBOSE); 276 CU_basic_run_tests(); 277 num_failures = CU_get_number_of_failures(); 278 CU_cleanup_registry(); 279 return num_failures; 280 } 281