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 #include "spdk_internal/thread.h" 40 41 #include "common/lib/test_env.c" 42 #include "common/lib/test_sock.c" 43 44 #include "nvmf/ctrlr.c" 45 #include "nvmf/tcp.c" 46 47 #define UT_IPV4_ADDR "192.168.0.1" 48 #define UT_PORT "4420" 49 #define UT_NVMF_ADRFAM_INVALID 0xf 50 #define UT_MAX_QUEUE_DEPTH 128 51 #define UT_MAX_QPAIRS_PER_CTRLR 128 52 #define UT_IN_CAPSULE_DATA_SIZE 1024 53 #define UT_MAX_IO_SIZE 4096 54 #define UT_IO_UNIT_SIZE 1024 55 #define UT_MAX_AQ_DEPTH 64 56 #define UT_SQ_HEAD_MAX 128 57 #define UT_NUM_SHARED_BUFFERS 128 58 59 SPDK_LOG_REGISTER_COMPONENT("nvmf", SPDK_LOG_NVMF) 60 SPDK_LOG_REGISTER_COMPONENT("nvme", SPDK_LOG_NVME) 61 62 DEFINE_STUB(spdk_nvmf_qpair_get_listen_trid, 63 int, 64 (struct spdk_nvmf_qpair *qpair, struct spdk_nvme_transport_id *trid), 65 0); 66 67 DEFINE_STUB(spdk_nvmf_subsystem_add_ctrlr, 68 int, 69 (struct spdk_nvmf_subsystem *subsystem, struct spdk_nvmf_ctrlr *ctrlr), 70 0); 71 72 DEFINE_STUB(spdk_nvmf_subsystem_get_ctrlr, 73 struct spdk_nvmf_ctrlr *, 74 (struct spdk_nvmf_subsystem *subsystem, uint16_t cntlid), 75 NULL); 76 77 DEFINE_STUB(spdk_nvmf_tgt_find_subsystem, 78 struct spdk_nvmf_subsystem *, 79 (struct spdk_nvmf_tgt *tgt, const char *subnqn), 80 NULL); 81 82 DEFINE_STUB(spdk_nvmf_subsystem_listener_allowed, 83 bool, 84 (struct spdk_nvmf_subsystem *subsystem, struct spdk_nvme_transport_id *trid), 85 true); 86 87 DEFINE_STUB(spdk_nvmf_transport_qpair_set_sqsize, 88 int, 89 (struct spdk_nvmf_qpair *qpair), 90 0); 91 92 DEFINE_STUB_V(spdk_nvmf_get_discovery_log_page, 93 (struct spdk_nvmf_tgt *tgt, struct iovec *iov, uint32_t iovcnt, uint64_t offset, uint32_t length)); 94 95 DEFINE_STUB_V(spdk_nvmf_subsystem_remove_ctrlr, 96 (struct spdk_nvmf_subsystem *subsystem, struct spdk_nvmf_ctrlr *ctrlr)); 97 98 DEFINE_STUB(spdk_nvmf_subsystem_get_first_ns, 99 struct spdk_nvmf_ns *, 100 (struct spdk_nvmf_subsystem *subsystem), 101 NULL); 102 103 DEFINE_STUB(spdk_nvmf_subsystem_get_next_ns, 104 struct spdk_nvmf_ns *, 105 (struct spdk_nvmf_subsystem *subsystem, struct spdk_nvmf_ns *prev_ns), 106 NULL); 107 108 DEFINE_STUB(spdk_nvmf_subsystem_host_allowed, 109 bool, 110 (struct spdk_nvmf_subsystem *subsystem, const char *hostnqn), 111 true); 112 113 DEFINE_STUB(spdk_nvmf_ctrlr_dsm_supported, 114 bool, 115 (struct spdk_nvmf_ctrlr *ctrlr), 116 false); 117 118 DEFINE_STUB(spdk_nvmf_ctrlr_write_zeroes_supported, 119 bool, 120 (struct spdk_nvmf_ctrlr *ctrlr), 121 false); 122 123 DEFINE_STUB(spdk_nvmf_bdev_ctrlr_read_cmd, 124 int, 125 (struct spdk_bdev *bdev, struct spdk_bdev_desc *desc, struct spdk_io_channel *ch, 126 struct spdk_nvmf_request *req), 127 0); 128 129 DEFINE_STUB(spdk_nvmf_bdev_ctrlr_write_cmd, 130 int, 131 (struct spdk_bdev *bdev, struct spdk_bdev_desc *desc, struct spdk_io_channel *ch, 132 struct spdk_nvmf_request *req), 133 0); 134 135 DEFINE_STUB(spdk_nvmf_bdev_ctrlr_write_zeroes_cmd, 136 int, 137 (struct spdk_bdev *bdev, struct spdk_bdev_desc *desc, struct spdk_io_channel *ch, 138 struct spdk_nvmf_request *req), 139 0); 140 141 DEFINE_STUB(spdk_nvmf_bdev_ctrlr_flush_cmd, 142 int, 143 (struct spdk_bdev *bdev, struct spdk_bdev_desc *desc, struct spdk_io_channel *ch, 144 struct spdk_nvmf_request *req), 145 0); 146 147 DEFINE_STUB(spdk_nvmf_bdev_ctrlr_dsm_cmd, 148 int, 149 (struct spdk_bdev *bdev, struct spdk_bdev_desc *desc, struct spdk_io_channel *ch, 150 struct spdk_nvmf_request *req), 151 0); 152 153 DEFINE_STUB(spdk_nvmf_bdev_ctrlr_nvme_passthru_io, 154 int, 155 (struct spdk_bdev *bdev, struct spdk_bdev_desc *desc, struct spdk_io_channel *ch, 156 struct spdk_nvmf_request *req), 157 0); 158 159 DEFINE_STUB(spdk_nvmf_transport_req_complete, 160 int, 161 (struct spdk_nvmf_request *req), 162 0); 163 164 DEFINE_STUB_V(spdk_nvmf_ns_reservation_request, (void *ctx)); 165 166 struct spdk_trace_histories *g_trace_histories; 167 168 struct spdk_bdev { 169 int ut_mock; 170 uint64_t blockcnt; 171 }; 172 173 int 174 spdk_nvme_transport_id_compare(const struct spdk_nvme_transport_id *trid1, 175 const struct spdk_nvme_transport_id *trid2) 176 { 177 return 0; 178 } 179 180 void 181 spdk_trace_register_object(uint8_t type, char id_prefix) 182 { 183 } 184 185 void 186 spdk_trace_register_description(const char *name, 187 uint16_t tpoint_id, uint8_t owner_type, 188 uint8_t object_type, uint8_t new_object, 189 uint8_t arg1_type, const char *arg1_name) 190 { 191 } 192 193 void 194 _spdk_trace_record(uint64_t tsc, uint16_t tpoint_id, uint16_t poller_id, 195 uint32_t size, uint64_t object_id, uint64_t arg1) 196 { 197 } 198 199 int 200 spdk_nvmf_qpair_disconnect(struct spdk_nvmf_qpair *qpair, nvmf_qpair_disconnect_cb cb_fn, void *ctx) 201 { 202 return 0; 203 } 204 205 void 206 spdk_nvmf_bdev_ctrlr_identify_ns(struct spdk_nvmf_ns *ns, struct spdk_nvme_ns_data *nsdata) 207 { 208 uint64_t num_blocks; 209 210 SPDK_CU_ASSERT_FATAL(ns->bdev != NULL); 211 num_blocks = ns->bdev->blockcnt; 212 nsdata->nsze = num_blocks; 213 nsdata->ncap = num_blocks; 214 nsdata->nuse = num_blocks; 215 nsdata->nlbaf = 0; 216 nsdata->flbas.format = 0; 217 nsdata->lbaf[0].lbads = spdk_u32log2(512); 218 } 219 220 const char * 221 spdk_nvmf_subsystem_get_sn(const struct spdk_nvmf_subsystem *subsystem) 222 { 223 return subsystem->sn; 224 } 225 226 const char * 227 spdk_nvmf_subsystem_get_mn(const struct spdk_nvmf_subsystem *subsystem) 228 { 229 return subsystem->mn; 230 } 231 232 void 233 spdk_trace_add_register_fn(struct spdk_trace_register_fn *reg_fn) 234 { 235 } 236 237 static void 238 test_nvmf_tcp_create(void) 239 { 240 struct spdk_thread *thread; 241 struct spdk_nvmf_transport *transport; 242 struct spdk_nvmf_tcp_transport *ttransport; 243 struct spdk_nvmf_transport_opts opts; 244 245 thread = spdk_thread_create(NULL, NULL); 246 SPDK_CU_ASSERT_FATAL(thread != NULL); 247 spdk_set_thread(thread); 248 249 /* case 1 */ 250 memset(&opts, 0, sizeof(opts)); 251 opts.max_queue_depth = UT_MAX_QUEUE_DEPTH; 252 opts.max_qpairs_per_ctrlr = UT_MAX_QPAIRS_PER_CTRLR; 253 opts.in_capsule_data_size = UT_IN_CAPSULE_DATA_SIZE; 254 opts.max_io_size = UT_MAX_IO_SIZE; 255 opts.io_unit_size = UT_IO_UNIT_SIZE; 256 opts.max_aq_depth = UT_MAX_AQ_DEPTH; 257 opts.num_shared_buffers = UT_NUM_SHARED_BUFFERS; 258 /* expect success */ 259 transport = spdk_nvmf_tcp_create(&opts); 260 CU_ASSERT_PTR_NOT_NULL(transport); 261 ttransport = SPDK_CONTAINEROF(transport, struct spdk_nvmf_tcp_transport, transport); 262 SPDK_CU_ASSERT_FATAL(ttransport != NULL); 263 transport->opts = opts; 264 CU_ASSERT(transport->opts.max_queue_depth == UT_MAX_QUEUE_DEPTH); 265 CU_ASSERT(transport->opts.max_io_size == UT_MAX_IO_SIZE); 266 CU_ASSERT(transport->opts.in_capsule_data_size == UT_IN_CAPSULE_DATA_SIZE); 267 CU_ASSERT(transport->opts.io_unit_size == UT_IO_UNIT_SIZE); 268 /* destroy transport */ 269 spdk_mempool_free(ttransport->transport.data_buf_pool); 270 free(ttransport); 271 272 /* case 2 */ 273 memset(&opts, 0, sizeof(opts)); 274 opts.max_queue_depth = UT_MAX_QUEUE_DEPTH; 275 opts.max_qpairs_per_ctrlr = UT_MAX_QPAIRS_PER_CTRLR; 276 opts.in_capsule_data_size = UT_IN_CAPSULE_DATA_SIZE; 277 opts.max_io_size = UT_MAX_IO_SIZE; 278 opts.io_unit_size = UT_MAX_IO_SIZE + 1; 279 opts.max_aq_depth = UT_MAX_AQ_DEPTH; 280 opts.num_shared_buffers = UT_NUM_SHARED_BUFFERS; 281 /* expect success */ 282 transport = spdk_nvmf_tcp_create(&opts); 283 CU_ASSERT_PTR_NOT_NULL(transport); 284 ttransport = SPDK_CONTAINEROF(transport, struct spdk_nvmf_tcp_transport, transport); 285 SPDK_CU_ASSERT_FATAL(ttransport != NULL); 286 transport->opts = opts; 287 CU_ASSERT(transport->opts.max_queue_depth == UT_MAX_QUEUE_DEPTH); 288 CU_ASSERT(transport->opts.max_io_size == UT_MAX_IO_SIZE); 289 CU_ASSERT(transport->opts.in_capsule_data_size == UT_IN_CAPSULE_DATA_SIZE); 290 CU_ASSERT(transport->opts.io_unit_size == UT_MAX_IO_SIZE); 291 /* destroy transport */ 292 spdk_mempool_free(ttransport->transport.data_buf_pool); 293 free(ttransport); 294 295 /* case 3 */ 296 memset(&opts, 0, sizeof(opts)); 297 opts.max_queue_depth = UT_MAX_QUEUE_DEPTH; 298 opts.max_qpairs_per_ctrlr = UT_MAX_QPAIRS_PER_CTRLR; 299 opts.in_capsule_data_size = UT_IN_CAPSULE_DATA_SIZE; 300 opts.max_io_size = UT_MAX_IO_SIZE; 301 opts.io_unit_size = 16; 302 opts.max_aq_depth = UT_MAX_AQ_DEPTH; 303 /* expect failse */ 304 transport = spdk_nvmf_tcp_create(&opts); 305 CU_ASSERT_PTR_NULL(transport); 306 307 spdk_thread_exit(thread); 308 spdk_thread_destroy(thread); 309 } 310 311 static void 312 test_nvmf_tcp_destroy(void) 313 { 314 struct spdk_thread *thread; 315 struct spdk_nvmf_transport *transport; 316 struct spdk_nvmf_transport_opts opts; 317 318 thread = spdk_thread_create(NULL, NULL); 319 SPDK_CU_ASSERT_FATAL(thread != NULL); 320 spdk_set_thread(thread); 321 322 /* case 1 */ 323 memset(&opts, 0, sizeof(opts)); 324 opts.max_queue_depth = UT_MAX_QUEUE_DEPTH; 325 opts.max_qpairs_per_ctrlr = UT_MAX_QPAIRS_PER_CTRLR; 326 opts.in_capsule_data_size = UT_IN_CAPSULE_DATA_SIZE; 327 opts.max_io_size = UT_MAX_IO_SIZE; 328 opts.io_unit_size = UT_IO_UNIT_SIZE; 329 opts.max_aq_depth = UT_MAX_AQ_DEPTH; 330 opts.num_shared_buffers = UT_NUM_SHARED_BUFFERS; 331 transport = spdk_nvmf_tcp_create(&opts); 332 CU_ASSERT_PTR_NOT_NULL(transport); 333 transport->opts = opts; 334 /* destroy transport */ 335 CU_ASSERT(spdk_nvmf_tcp_destroy(transport) == 0); 336 337 spdk_thread_exit(thread); 338 spdk_thread_destroy(thread); 339 } 340 341 static void 342 test_nvmf_tcp_poll_group_create(void) 343 { 344 struct spdk_nvmf_transport *transport; 345 struct spdk_nvmf_transport_poll_group *group; 346 struct spdk_thread *thread; 347 struct spdk_nvmf_transport_opts opts; 348 struct spdk_sock_group grp = {}; 349 350 thread = spdk_thread_create(NULL, NULL); 351 SPDK_CU_ASSERT_FATAL(thread != NULL); 352 spdk_set_thread(thread); 353 354 memset(&opts, 0, sizeof(opts)); 355 opts.max_queue_depth = UT_MAX_QUEUE_DEPTH; 356 opts.max_qpairs_per_ctrlr = UT_MAX_QPAIRS_PER_CTRLR; 357 opts.in_capsule_data_size = UT_IN_CAPSULE_DATA_SIZE; 358 opts.max_io_size = UT_MAX_IO_SIZE; 359 opts.io_unit_size = UT_IO_UNIT_SIZE; 360 opts.max_aq_depth = UT_MAX_AQ_DEPTH; 361 opts.num_shared_buffers = UT_NUM_SHARED_BUFFERS; 362 transport = spdk_nvmf_tcp_create(&opts); 363 CU_ASSERT_PTR_NOT_NULL(transport); 364 transport->opts = opts; 365 MOCK_SET(spdk_sock_group_create, &grp); 366 group = spdk_nvmf_tcp_poll_group_create(transport); 367 MOCK_CLEAR_P(spdk_sock_group_create); 368 SPDK_CU_ASSERT_FATAL(group); 369 group->transport = transport; 370 spdk_nvmf_tcp_poll_group_destroy(group); 371 spdk_nvmf_tcp_destroy(transport); 372 373 spdk_thread_exit(thread); 374 spdk_thread_destroy(thread); 375 } 376 377 static void 378 test_nvmf_tcp_send_c2h_data(void) 379 { 380 struct spdk_thread *thread; 381 struct spdk_nvmf_tcp_transport ttransport = {}; 382 struct spdk_nvmf_tcp_qpair tqpair = {}; 383 struct spdk_nvmf_tcp_req tcp_req = {}; 384 struct nvme_tcp_pdu pdu = {}; 385 struct spdk_nvme_tcp_c2h_data_hdr *c2h_data; 386 387 thread = spdk_thread_create(NULL, NULL); 388 SPDK_CU_ASSERT_FATAL(thread != NULL); 389 spdk_set_thread(thread); 390 391 tqpair.qpair.transport = &ttransport.transport; 392 TAILQ_INIT(&tqpair.free_queue); 393 TAILQ_INIT(&tqpair.send_queue); 394 TAILQ_INIT(&tqpair.queued_c2h_data_tcp_req); 395 396 /* Set qpair state to make unrelated operations NOP */ 397 tqpair.state = NVME_TCP_QPAIR_STATE_RUNNING; 398 tqpair.recv_state = NVME_TCP_PDU_RECV_STATE_ERROR; 399 400 TAILQ_INSERT_TAIL(&tqpair.free_queue, &pdu, tailq); 401 tqpair.free_pdu_num++; 402 403 tcp_req.req.cmd = (union nvmf_h2c_msg *)&tcp_req.cmd; 404 405 tcp_req.req.iov[0].iov_base = (void *)0xDEADBEEF; 406 tcp_req.req.iov[0].iov_len = NVMF_TCP_PDU_MAX_C2H_DATA_SIZE; 407 tcp_req.req.iov[1].iov_base = (void *)0xFEEDBEEF; 408 tcp_req.req.iov[1].iov_len = NVMF_TCP_PDU_MAX_C2H_DATA_SIZE; 409 tcp_req.req.iov[2].iov_base = (void *)0xC0FFEE; 410 tcp_req.req.iov[2].iov_len = NVMF_TCP_PDU_MAX_C2H_DATA_SIZE; 411 tcp_req.req.iovcnt = 3; 412 tcp_req.req.length = NVMF_TCP_PDU_MAX_C2H_DATA_SIZE * 3; 413 414 CU_ASSERT(spdk_nvmf_tcp_calc_c2h_data_pdu_num(&tcp_req) == 3); 415 416 TAILQ_INSERT_TAIL(&tqpair.queued_c2h_data_tcp_req, &tcp_req, link); 417 418 tcp_req.c2h_data_offset = NVMF_TCP_PDU_MAX_C2H_DATA_SIZE / 2; 419 420 /* 1st C2H */ 421 spdk_nvmf_tcp_send_c2h_data(&tqpair, &tcp_req); 422 423 CU_ASSERT(TAILQ_FIRST(&tqpair.send_queue) == &pdu); 424 TAILQ_REMOVE(&tqpair.send_queue, &pdu, tailq); 425 TAILQ_INSERT_TAIL(&tqpair.free_queue, &pdu, tailq); 426 tqpair.free_pdu_num++; 427 428 c2h_data = &pdu.hdr.c2h_data; 429 CU_ASSERT(c2h_data->datao == NVMF_TCP_PDU_MAX_C2H_DATA_SIZE / 2); 430 CU_ASSERT(c2h_data->datal = NVMF_TCP_PDU_MAX_C2H_DATA_SIZE); 431 CU_ASSERT(c2h_data->common.plen == sizeof(*c2h_data) + NVMF_TCP_PDU_MAX_C2H_DATA_SIZE); 432 CU_ASSERT(!(c2h_data->common.flags & SPDK_NVME_TCP_C2H_DATA_FLAGS_LAST_PDU)); 433 434 CU_ASSERT(pdu.data_iovcnt == 2); 435 CU_ASSERT((uint64_t)pdu.data_iov[0].iov_base == 0xDEADBEEF + NVMF_TCP_PDU_MAX_C2H_DATA_SIZE / 2); 436 CU_ASSERT(pdu.data_iov[0].iov_len == NVMF_TCP_PDU_MAX_C2H_DATA_SIZE / 2); 437 CU_ASSERT((uint64_t)pdu.data_iov[1].iov_base == 0xFEEDBEEF); 438 CU_ASSERT(pdu.data_iov[1].iov_len == NVMF_TCP_PDU_MAX_C2H_DATA_SIZE / 2); 439 440 CU_ASSERT(tcp_req.c2h_data_offset == (NVMF_TCP_PDU_MAX_C2H_DATA_SIZE / 2) * 3); 441 CU_ASSERT(TAILQ_FIRST(&tqpair.queued_c2h_data_tcp_req) == &tcp_req); 442 443 /* 2nd C2H */ 444 spdk_nvmf_tcp_send_c2h_data(&tqpair, &tcp_req); 445 446 CU_ASSERT(TAILQ_FIRST(&tqpair.send_queue) == &pdu); 447 TAILQ_REMOVE(&tqpair.send_queue, &pdu, tailq); 448 TAILQ_INSERT_TAIL(&tqpair.free_queue, &pdu, tailq); 449 tqpair.free_pdu_num++; 450 451 c2h_data = &pdu.hdr.c2h_data; 452 CU_ASSERT(c2h_data->datao == (NVMF_TCP_PDU_MAX_C2H_DATA_SIZE / 2) * 3); 453 CU_ASSERT(c2h_data->datal = NVMF_TCP_PDU_MAX_C2H_DATA_SIZE); 454 CU_ASSERT(c2h_data->common.plen == sizeof(*c2h_data) + NVMF_TCP_PDU_MAX_C2H_DATA_SIZE); 455 CU_ASSERT(!(c2h_data->common.flags & SPDK_NVME_TCP_C2H_DATA_FLAGS_LAST_PDU)); 456 457 CU_ASSERT(pdu.data_iovcnt == 2); 458 CU_ASSERT((uint64_t)pdu.data_iov[0].iov_base == 0xFEEDBEEF + NVMF_TCP_PDU_MAX_C2H_DATA_SIZE / 2); 459 CU_ASSERT(pdu.data_iov[0].iov_len == NVMF_TCP_PDU_MAX_C2H_DATA_SIZE / 2); 460 CU_ASSERT((uint64_t)pdu.data_iov[1].iov_base == 0xC0FFEE); 461 CU_ASSERT(pdu.data_iov[1].iov_len == NVMF_TCP_PDU_MAX_C2H_DATA_SIZE / 2); 462 463 CU_ASSERT(tcp_req.c2h_data_offset == (NVMF_TCP_PDU_MAX_C2H_DATA_SIZE / 2) * 5); 464 CU_ASSERT(TAILQ_FIRST(&tqpair.queued_c2h_data_tcp_req) == &tcp_req); 465 466 /* 3rd C2H */ 467 spdk_nvmf_tcp_send_c2h_data(&tqpair, &tcp_req); 468 469 CU_ASSERT(TAILQ_FIRST(&tqpair.send_queue) == &pdu); 470 TAILQ_REMOVE(&tqpair.send_queue, &pdu, tailq); 471 CU_ASSERT(TAILQ_EMPTY(&tqpair.send_queue)); 472 473 c2h_data = &pdu.hdr.c2h_data; 474 CU_ASSERT(c2h_data->datao == (NVMF_TCP_PDU_MAX_C2H_DATA_SIZE / 2) * 5); 475 CU_ASSERT(c2h_data->datal = NVMF_TCP_PDU_MAX_C2H_DATA_SIZE / 2); 476 CU_ASSERT(c2h_data->common.plen == sizeof(*c2h_data) + NVMF_TCP_PDU_MAX_C2H_DATA_SIZE / 2); 477 CU_ASSERT(c2h_data->common.flags & SPDK_NVME_TCP_C2H_DATA_FLAGS_LAST_PDU); 478 479 CU_ASSERT(pdu.data_iovcnt == 1); 480 CU_ASSERT((uint64_t)pdu.data_iov[0].iov_base == 0xC0FFEE + NVMF_TCP_PDU_MAX_C2H_DATA_SIZE / 2); 481 CU_ASSERT(pdu.data_iov[0].iov_len == NVMF_TCP_PDU_MAX_C2H_DATA_SIZE / 2); 482 483 CU_ASSERT(tcp_req.c2h_data_offset == NVMF_TCP_PDU_MAX_C2H_DATA_SIZE * 3); 484 CU_ASSERT(tqpair.c2h_data_pdu_cnt == 3); 485 CU_ASSERT(TAILQ_EMPTY(&tqpair.queued_c2h_data_tcp_req)); 486 487 spdk_poller_unregister(&tqpair.flush_poller); 488 489 spdk_thread_exit(thread); 490 spdk_thread_destroy(thread); 491 } 492 493 static void 494 test_nvmf_tcp_h2c_data_hdr_handle(void) 495 { 496 struct spdk_nvmf_tcp_transport ttransport = {}; 497 struct spdk_nvmf_tcp_qpair tqpair = {}; 498 struct nvme_tcp_pdu pdu = {}; 499 struct spdk_nvmf_tcp_req tcp_req = {}; 500 struct spdk_nvme_tcp_h2c_data_hdr *h2c_data; 501 502 TAILQ_INIT(&tqpair.state_queue[TCP_REQUEST_STATE_TRANSFERRING_HOST_TO_CONTROLLER]); 503 tqpair.maxh2cdata = NVMF_TCP_PDU_MAX_H2C_DATA_SIZE; 504 505 /* Set qpair state to make unrelated operations NOP */ 506 tqpair.state = NVME_TCP_QPAIR_STATE_RUNNING; 507 tqpair.recv_state = NVME_TCP_PDU_RECV_STATE_ERROR; 508 509 tcp_req.req.iov[0].iov_base = (void *)0xDEADBEEF; 510 tcp_req.req.iov[0].iov_len = (NVMF_TCP_PDU_MAX_H2C_DATA_SIZE / 2) * 5; 511 tcp_req.req.iov[1].iov_base = (void *)0xFEEDBEEF; 512 tcp_req.req.iov[1].iov_len = NVMF_TCP_PDU_MAX_H2C_DATA_SIZE / 2; 513 tcp_req.req.iovcnt = 2; 514 tcp_req.req.length = NVMF_TCP_PDU_MAX_H2C_DATA_SIZE * 3; 515 516 tcp_req.req.cmd = (union nvmf_h2c_msg *)&tcp_req.cmd; 517 tcp_req.req.cmd->nvme_cmd.cid = 1; 518 tcp_req.req.length = NVMF_TCP_PDU_MAX_H2C_DATA_SIZE * 3; 519 tcp_req.ttag = 2; 520 tcp_req.next_expected_r2t_offset = NVMF_TCP_PDU_MAX_H2C_DATA_SIZE * 2; 521 522 TAILQ_INSERT_TAIL(&tqpair.state_queue[TCP_REQUEST_STATE_TRANSFERRING_HOST_TO_CONTROLLER], 523 &tcp_req, state_link); 524 525 h2c_data = &pdu.hdr.h2c_data; 526 h2c_data->cccid = 1; 527 h2c_data->ttag = 2; 528 h2c_data->datao = NVMF_TCP_PDU_MAX_H2C_DATA_SIZE * 2; 529 h2c_data->datal = NVMF_TCP_PDU_MAX_H2C_DATA_SIZE; 530 531 spdk_nvmf_tcp_h2c_data_hdr_handle(&ttransport, &tqpair, &pdu); 532 533 CU_ASSERT(pdu.data_iovcnt == 2); 534 CU_ASSERT((uint64_t)pdu.data_iov[0].iov_base == 0xDEADBEEF + NVMF_TCP_PDU_MAX_H2C_DATA_SIZE * 2); 535 CU_ASSERT(pdu.data_iov[0].iov_len == NVMF_TCP_PDU_MAX_H2C_DATA_SIZE / 2); 536 CU_ASSERT((uint64_t)pdu.data_iov[1].iov_base == 0xFEEDBEEF); 537 CU_ASSERT(pdu.data_iov[1].iov_len == NVMF_TCP_PDU_MAX_H2C_DATA_SIZE / 2); 538 539 CU_ASSERT(TAILQ_FIRST(&tqpair.state_queue[TCP_REQUEST_STATE_TRANSFERRING_HOST_TO_CONTROLLER]) == 540 &tcp_req); 541 TAILQ_REMOVE(&tqpair.state_queue[TCP_REQUEST_STATE_TRANSFERRING_HOST_TO_CONTROLLER], 542 &tcp_req, state_link); 543 } 544 545 int main(int argc, char **argv) 546 { 547 CU_pSuite suite = NULL; 548 unsigned int num_failures; 549 550 if (CU_initialize_registry() != CUE_SUCCESS) { 551 return CU_get_error(); 552 } 553 554 suite = CU_add_suite("nvmf", NULL, NULL); 555 if (suite == NULL) { 556 CU_cleanup_registry(); 557 return CU_get_error(); 558 } 559 560 if ( 561 CU_add_test(suite, "nvmf_tcp_create", test_nvmf_tcp_create) == NULL || 562 CU_add_test(suite, "nvmf_tcp_destroy", test_nvmf_tcp_destroy) == NULL || 563 CU_add_test(suite, "nvmf_tcp_poll_group_create", test_nvmf_tcp_poll_group_create) == NULL || 564 CU_add_test(suite, "nvmf_tcp_send_c2h_data", test_nvmf_tcp_send_c2h_data) == NULL || 565 CU_add_test(suite, "nvmf_tcp_h2c_data_hdr_handle", test_nvmf_tcp_h2c_data_hdr_handle) == NULL 566 ) { 567 CU_cleanup_registry(); 568 return CU_get_error(); 569 } 570 571 CU_basic_set_mode(CU_BRM_VERBOSE); 572 CU_basic_run_tests(); 573 num_failures = CU_get_number_of_failures(); 574 CU_cleanup_registry(); 575 return num_failures; 576 } 577