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