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