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