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 #include "spdk_internal/mock.h" 38 #include "spdk_internal/thread.h" 39 40 #include "common/lib/test_env.c" 41 #include "nvmf/ctrlr.c" 42 #include "nvmf/tcp.c" 43 44 #define UT_IPV4_ADDR "192.168.0.1" 45 #define UT_PORT "4420" 46 #define UT_NVMF_ADRFAM_INVALID 0xf 47 #define UT_MAX_QUEUE_DEPTH 128 48 #define UT_MAX_QPAIRS_PER_CTRLR 128 49 #define UT_IN_CAPSULE_DATA_SIZE 1024 50 #define UT_MAX_IO_SIZE 4096 51 #define UT_IO_UNIT_SIZE 1024 52 #define UT_MAX_AQ_DEPTH 64 53 #define UT_SQ_HEAD_MAX 128 54 #define UT_NUM_SHARED_BUFFERS 128 55 56 SPDK_LOG_REGISTER_COMPONENT("nvmf", SPDK_LOG_NVMF) 57 SPDK_LOG_REGISTER_COMPONENT("nvme", SPDK_LOG_NVME) 58 59 DEFINE_STUB(spdk_nvmf_qpair_get_listen_trid, 60 int, 61 (struct spdk_nvmf_qpair *qpair, struct spdk_nvme_transport_id *trid), 62 0); 63 64 DEFINE_STUB(spdk_nvmf_subsystem_add_ctrlr, 65 int, 66 (struct spdk_nvmf_subsystem *subsystem, struct spdk_nvmf_ctrlr *ctrlr), 67 0); 68 69 DEFINE_STUB(spdk_nvmf_subsystem_get_ctrlr, 70 struct spdk_nvmf_ctrlr *, 71 (struct spdk_nvmf_subsystem *subsystem, uint16_t cntlid), 72 NULL); 73 74 DEFINE_STUB(spdk_nvmf_tgt_find_subsystem, 75 struct spdk_nvmf_subsystem *, 76 (struct spdk_nvmf_tgt *tgt, const char *subnqn), 77 NULL); 78 79 DEFINE_STUB(spdk_nvmf_subsystem_listener_allowed, 80 bool, 81 (struct spdk_nvmf_subsystem *subsystem, struct spdk_nvme_transport_id *trid), 82 true); 83 84 DEFINE_STUB(spdk_nvmf_transport_qpair_set_sqsize, 85 int, 86 (struct spdk_nvmf_qpair *qpair), 87 0); 88 89 DEFINE_STUB_V(spdk_nvmf_get_discovery_log_page, 90 (struct spdk_nvmf_tgt *tgt, struct iovec *iov, uint32_t iovcnt, uint64_t offset, uint32_t length)); 91 92 DEFINE_STUB_V(spdk_nvmf_subsystem_remove_ctrlr, 93 (struct spdk_nvmf_subsystem *subsystem, struct spdk_nvmf_ctrlr *ctrlr)); 94 95 DEFINE_STUB(spdk_nvmf_subsystem_get_first_ns, 96 struct spdk_nvmf_ns *, 97 (struct spdk_nvmf_subsystem *subsystem), 98 NULL); 99 100 DEFINE_STUB(spdk_nvmf_subsystem_get_next_ns, 101 struct spdk_nvmf_ns *, 102 (struct spdk_nvmf_subsystem *subsystem, struct spdk_nvmf_ns *prev_ns), 103 NULL); 104 105 DEFINE_STUB(spdk_nvmf_subsystem_host_allowed, 106 bool, 107 (struct spdk_nvmf_subsystem *subsystem, const char *hostnqn), 108 true); 109 110 DEFINE_STUB(spdk_nvmf_ctrlr_dsm_supported, 111 bool, 112 (struct spdk_nvmf_ctrlr *ctrlr), 113 false); 114 115 DEFINE_STUB(spdk_nvmf_ctrlr_write_zeroes_supported, 116 bool, 117 (struct spdk_nvmf_ctrlr *ctrlr), 118 false); 119 120 DEFINE_STUB(spdk_nvmf_bdev_ctrlr_read_cmd, 121 int, 122 (struct spdk_bdev *bdev, struct spdk_bdev_desc *desc, struct spdk_io_channel *ch, 123 struct spdk_nvmf_request *req), 124 0); 125 126 DEFINE_STUB(spdk_nvmf_bdev_ctrlr_write_cmd, 127 int, 128 (struct spdk_bdev *bdev, struct spdk_bdev_desc *desc, struct spdk_io_channel *ch, 129 struct spdk_nvmf_request *req), 130 0); 131 132 DEFINE_STUB(spdk_nvmf_bdev_ctrlr_write_zeroes_cmd, 133 int, 134 (struct spdk_bdev *bdev, struct spdk_bdev_desc *desc, struct spdk_io_channel *ch, 135 struct spdk_nvmf_request *req), 136 0); 137 138 DEFINE_STUB(spdk_nvmf_bdev_ctrlr_flush_cmd, 139 int, 140 (struct spdk_bdev *bdev, struct spdk_bdev_desc *desc, struct spdk_io_channel *ch, 141 struct spdk_nvmf_request *req), 142 0); 143 144 DEFINE_STUB(spdk_nvmf_bdev_ctrlr_dsm_cmd, 145 int, 146 (struct spdk_bdev *bdev, struct spdk_bdev_desc *desc, struct spdk_io_channel *ch, 147 struct spdk_nvmf_request *req), 148 0); 149 150 DEFINE_STUB(spdk_nvmf_bdev_ctrlr_nvme_passthru_io, 151 int, 152 (struct spdk_bdev *bdev, struct spdk_bdev_desc *desc, struct spdk_io_channel *ch, 153 struct spdk_nvmf_request *req), 154 0); 155 156 DEFINE_STUB(spdk_nvmf_transport_req_complete, 157 int, 158 (struct spdk_nvmf_request *req), 159 0); 160 161 DEFINE_STUB_V(spdk_nvmf_ns_reservation_request, (void *ctx)); 162 163 struct spdk_trace_histories *g_trace_histories; 164 165 struct spdk_bdev { 166 int ut_mock; 167 uint64_t blockcnt; 168 }; 169 170 int 171 spdk_nvme_transport_id_compare(const struct spdk_nvme_transport_id *trid1, 172 const struct spdk_nvme_transport_id *trid2) 173 { 174 return 0; 175 } 176 177 void 178 spdk_trace_register_object(uint8_t type, char id_prefix) 179 { 180 } 181 182 void 183 spdk_trace_register_description(const char *name, const char *short_name, 184 uint16_t tpoint_id, uint8_t owner_type, 185 uint8_t object_type, uint8_t new_object, 186 uint8_t arg1_is_ptr, const char *arg1_name) 187 { 188 } 189 190 void 191 _spdk_trace_record(uint64_t tsc, uint16_t tpoint_id, uint16_t poller_id, 192 uint32_t size, uint64_t object_id, uint64_t arg1) 193 { 194 } 195 196 int 197 spdk_nvmf_qpair_disconnect(struct spdk_nvmf_qpair *qpair, nvmf_qpair_disconnect_cb cb_fn, void *ctx) 198 { 199 return 0; 200 } 201 202 void 203 spdk_nvmf_bdev_ctrlr_identify_ns(struct spdk_nvmf_ns *ns, struct spdk_nvme_ns_data *nsdata) 204 { 205 uint64_t num_blocks; 206 207 SPDK_CU_ASSERT_FATAL(ns->bdev != NULL); 208 num_blocks = ns->bdev->blockcnt; 209 nsdata->nsze = num_blocks; 210 nsdata->ncap = num_blocks; 211 nsdata->nuse = num_blocks; 212 nsdata->nlbaf = 0; 213 nsdata->flbas.format = 0; 214 nsdata->lbaf[0].lbads = spdk_u32log2(512); 215 } 216 217 const char * 218 spdk_nvmf_subsystem_get_sn(const struct spdk_nvmf_subsystem *subsystem) 219 { 220 return subsystem->sn; 221 } 222 223 const char * 224 spdk_nvmf_subsystem_get_mn(const struct spdk_nvmf_subsystem *subsystem) 225 { 226 return subsystem->mn; 227 } 228 229 void 230 spdk_trace_add_register_fn(struct spdk_trace_register_fn *reg_fn) 231 { 232 } 233 234 static void 235 test_nvmf_tcp_create(void) 236 { 237 struct spdk_thread *thread; 238 struct spdk_nvmf_transport *transport; 239 struct spdk_nvmf_tcp_transport *ttransport; 240 struct spdk_nvmf_transport_opts opts; 241 242 thread = spdk_thread_create(NULL); 243 SPDK_CU_ASSERT_FATAL(thread != NULL); 244 spdk_set_thread(thread); 245 246 /* case 1 */ 247 memset(&opts, 0, sizeof(opts)); 248 opts.max_queue_depth = UT_MAX_QUEUE_DEPTH; 249 opts.max_qpairs_per_ctrlr = UT_MAX_QPAIRS_PER_CTRLR; 250 opts.in_capsule_data_size = UT_IN_CAPSULE_DATA_SIZE; 251 opts.max_io_size = UT_MAX_IO_SIZE; 252 opts.io_unit_size = UT_IO_UNIT_SIZE; 253 opts.max_aq_depth = UT_MAX_AQ_DEPTH; 254 opts.num_shared_buffers = UT_NUM_SHARED_BUFFERS; 255 /* expect success */ 256 transport = spdk_nvmf_tcp_create(&opts); 257 CU_ASSERT_PTR_NOT_NULL(transport); 258 ttransport = SPDK_CONTAINEROF(transport, struct spdk_nvmf_tcp_transport, transport); 259 SPDK_CU_ASSERT_FATAL(ttransport != NULL); 260 transport->opts = opts; 261 CU_ASSERT(transport->opts.max_queue_depth == UT_MAX_QUEUE_DEPTH); 262 CU_ASSERT(transport->opts.max_io_size == UT_MAX_IO_SIZE); 263 CU_ASSERT(transport->opts.in_capsule_data_size == UT_IN_CAPSULE_DATA_SIZE); 264 CU_ASSERT(transport->opts.io_unit_size == UT_IO_UNIT_SIZE); 265 /* destroy transport */ 266 spdk_mempool_free(ttransport->transport.data_buf_pool); 267 free(ttransport); 268 269 /* case 2 */ 270 memset(&opts, 0, sizeof(opts)); 271 opts.max_queue_depth = UT_MAX_QUEUE_DEPTH; 272 opts.max_qpairs_per_ctrlr = UT_MAX_QPAIRS_PER_CTRLR; 273 opts.in_capsule_data_size = UT_IN_CAPSULE_DATA_SIZE; 274 opts.max_io_size = UT_MAX_IO_SIZE; 275 opts.io_unit_size = UT_MAX_IO_SIZE + 1; 276 opts.max_aq_depth = UT_MAX_AQ_DEPTH; 277 opts.num_shared_buffers = UT_NUM_SHARED_BUFFERS; 278 /* expect success */ 279 transport = spdk_nvmf_tcp_create(&opts); 280 CU_ASSERT_PTR_NOT_NULL(transport); 281 ttransport = SPDK_CONTAINEROF(transport, struct spdk_nvmf_tcp_transport, transport); 282 SPDK_CU_ASSERT_FATAL(ttransport != NULL); 283 transport->opts = opts; 284 CU_ASSERT(transport->opts.max_queue_depth == UT_MAX_QUEUE_DEPTH); 285 CU_ASSERT(transport->opts.max_io_size == UT_MAX_IO_SIZE); 286 CU_ASSERT(transport->opts.in_capsule_data_size == UT_IN_CAPSULE_DATA_SIZE); 287 CU_ASSERT(transport->opts.io_unit_size == UT_MAX_IO_SIZE); 288 /* destroy transport */ 289 spdk_mempool_free(ttransport->transport.data_buf_pool); 290 free(ttransport); 291 292 /* case 3 */ 293 memset(&opts, 0, sizeof(opts)); 294 opts.max_queue_depth = UT_MAX_QUEUE_DEPTH; 295 opts.max_qpairs_per_ctrlr = UT_MAX_QPAIRS_PER_CTRLR; 296 opts.in_capsule_data_size = UT_IN_CAPSULE_DATA_SIZE; 297 opts.max_io_size = UT_MAX_IO_SIZE; 298 opts.io_unit_size = 16; 299 opts.max_aq_depth = UT_MAX_AQ_DEPTH; 300 /* expect failse */ 301 transport = spdk_nvmf_tcp_create(&opts); 302 CU_ASSERT_PTR_NULL(transport); 303 304 spdk_thread_exit(thread); 305 } 306 307 static void 308 test_nvmf_tcp_destroy(void) 309 { 310 struct spdk_thread *thread; 311 struct spdk_nvmf_transport *transport; 312 struct spdk_nvmf_transport_opts opts; 313 314 thread = spdk_thread_create(NULL); 315 SPDK_CU_ASSERT_FATAL(thread != NULL); 316 spdk_set_thread(thread); 317 318 /* case 1 */ 319 memset(&opts, 0, sizeof(opts)); 320 opts.max_queue_depth = UT_MAX_QUEUE_DEPTH; 321 opts.max_qpairs_per_ctrlr = UT_MAX_QPAIRS_PER_CTRLR; 322 opts.in_capsule_data_size = UT_IN_CAPSULE_DATA_SIZE; 323 opts.max_io_size = UT_MAX_IO_SIZE; 324 opts.io_unit_size = UT_IO_UNIT_SIZE; 325 opts.max_aq_depth = UT_MAX_AQ_DEPTH; 326 opts.num_shared_buffers = UT_NUM_SHARED_BUFFERS; 327 transport = spdk_nvmf_tcp_create(&opts); 328 CU_ASSERT_PTR_NOT_NULL(transport); 329 transport->opts = opts; 330 /* destroy transport */ 331 CU_ASSERT(spdk_nvmf_tcp_destroy(transport) == 0); 332 333 spdk_thread_exit(thread); 334 } 335 336 static void 337 test_nvmf_tcp_poll_group_create(void) 338 { 339 struct spdk_nvmf_transport *transport; 340 struct spdk_nvmf_transport_poll_group *group; 341 struct spdk_thread *thread; 342 struct spdk_nvmf_transport_opts opts; 343 344 thread = spdk_thread_create(NULL); 345 SPDK_CU_ASSERT_FATAL(thread != NULL); 346 spdk_set_thread(thread); 347 348 memset(&opts, 0, sizeof(opts)); 349 opts.max_queue_depth = UT_MAX_QUEUE_DEPTH; 350 opts.max_qpairs_per_ctrlr = UT_MAX_QPAIRS_PER_CTRLR; 351 opts.in_capsule_data_size = UT_IN_CAPSULE_DATA_SIZE; 352 opts.max_io_size = UT_MAX_IO_SIZE; 353 opts.io_unit_size = UT_IO_UNIT_SIZE; 354 opts.max_aq_depth = UT_MAX_AQ_DEPTH; 355 opts.num_shared_buffers = UT_NUM_SHARED_BUFFERS; 356 transport = spdk_nvmf_tcp_create(&opts); 357 CU_ASSERT_PTR_NOT_NULL(transport); 358 transport->opts = opts; 359 group = spdk_nvmf_tcp_poll_group_create(transport); 360 SPDK_CU_ASSERT_FATAL(group); 361 group->transport = transport; 362 spdk_nvmf_tcp_poll_group_destroy(group); 363 spdk_nvmf_tcp_destroy(transport); 364 365 spdk_thread_exit(thread); 366 } 367 368 int main(int argc, char **argv) 369 { 370 CU_pSuite suite = NULL; 371 unsigned int num_failures; 372 373 if (CU_initialize_registry() != CUE_SUCCESS) { 374 return CU_get_error(); 375 } 376 377 suite = CU_add_suite("nvmf", NULL, NULL); 378 if (suite == NULL) { 379 CU_cleanup_registry(); 380 return CU_get_error(); 381 } 382 383 if ( 384 CU_add_test(suite, "nvmf_tcp_create", test_nvmf_tcp_create) == NULL || 385 CU_add_test(suite, "nvmf_tcp_destroy", test_nvmf_tcp_destroy) == NULL || 386 CU_add_test(suite, "nvmf_tcp_poll_group_create", test_nvmf_tcp_poll_group_create) == NULL 387 ) { 388 CU_cleanup_registry(); 389 return CU_get_error(); 390 } 391 392 CU_basic_set_mode(CU_BRM_VERBOSE); 393 CU_basic_run_tests(); 394 num_failures = CU_get_number_of_failures(); 395 CU_cleanup_registry(); 396 return num_failures; 397 } 398