LCOV - code coverage report
Current view: top level - spdk/test/unit/lib/nvme/nvme_rdma.c - nvme_rdma_ut.c (source / functions) Hit Total Coverage
Test: Combined Lines: 906 936 96.8 %
Date: 2024-07-15 16:46:43 Functions: 26 60 43.3 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 89 228 39.0 %

           Branch data     Line data    Source code
       1                 :            : /*   SPDX-License-Identifier: BSD-3-Clause
       2                 :            :  *   Copyright (C) 2018 Intel Corporation. All rights reserved.
       3                 :            :  *   Copyright (c) 2021-2024 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
       4                 :            :  */
       5                 :            : 
       6                 :            : #include "spdk/stdinc.h"
       7                 :            : #include "spdk_internal/cunit.h"
       8                 :            : #include "nvme/nvme_rdma.c"
       9                 :            : #include "common/lib/nvme/common_stubs.h"
      10                 :            : #include "common/lib/test_rdma.c"
      11                 :            : 
      12                 :          3 : SPDK_LOG_REGISTER_COMPONENT(nvme)
      13                 :            : 
      14         [ #  # ]:          0 : DEFINE_STUB(spdk_mem_map_set_translation, int, (struct spdk_mem_map *map, uint64_t vaddr,
      15                 :            :                 uint64_t size, uint64_t translation), 0);
      16         [ #  # ]:          0 : DEFINE_STUB(spdk_mem_map_clear_translation, int, (struct spdk_mem_map *map, uint64_t vaddr,
      17                 :            :                 uint64_t size), 0);
      18                 :            : 
      19         [ #  # ]:          0 : DEFINE_STUB(spdk_mem_map_alloc, struct spdk_mem_map *, (uint64_t default_translation,
      20                 :            :                 const struct spdk_mem_map_ops *ops, void *cb_ctx), NULL);
      21                 :          0 : DEFINE_STUB_V(spdk_mem_map_free, (struct spdk_mem_map **pmap));
      22                 :            : 
      23         [ #  # ]:          0 : DEFINE_STUB(nvme_poll_group_connect_qpair, int, (struct spdk_nvme_qpair *qpair), 0);
      24                 :            : 
      25                 :          0 : DEFINE_STUB_V(nvme_qpair_resubmit_requests, (struct spdk_nvme_qpair *qpair, uint32_t num_requests));
      26         [ #  # ]:          0 : DEFINE_STUB(spdk_nvme_poll_group_process_completions, int64_t, (struct spdk_nvme_poll_group *group,
      27                 :            :                 uint32_t completions_per_qpair, spdk_nvme_disconnected_qpair_cb disconnected_qpair_cb), 0);
      28                 :            : 
      29   [ -  +  -  - ]:         36 : DEFINE_STUB(rdma_ack_cm_event, int, (struct rdma_cm_event *event), 0);
      30                 :          3 : DEFINE_STUB_V(rdma_free_devices, (struct ibv_context **list));
      31   [ -  +  -  - ]:         30 : DEFINE_STUB(fcntl, int, (int fd, int cmd, ...), 0);
      32                 :          3 : DEFINE_STUB_V(rdma_destroy_event_channel, (struct rdma_event_channel *channel));
      33                 :            : 
      34   [ #  #  #  # ]:          0 : DEFINE_STUB(ibv_dereg_mr, int, (struct ibv_mr *mr), 0);
      35   [ -  +  -  - ]:          6 : DEFINE_STUB(ibv_resize_cq, int, (struct ibv_cq *cq, int cqe), 0);
      36                 :            : 
      37         [ #  # ]:          0 : DEFINE_STUB(spdk_memory_domain_get_context, struct spdk_memory_domain_ctx *,
      38                 :            :             (struct spdk_memory_domain *device), NULL);
      39         [ #  # ]:          0 : DEFINE_STUB(spdk_memory_domain_get_dma_device_type, enum spdk_dma_device_type,
      40                 :            :             (struct spdk_memory_domain *device), SPDK_DMA_DEVICE_TYPE_RDMA);
      41                 :          0 : DEFINE_STUB_V(spdk_memory_domain_destroy, (struct spdk_memory_domain *device));
      42         [ #  # ]:          0 : DEFINE_STUB(spdk_memory_domain_pull_data, int, (struct spdk_memory_domain *src_domain,
      43                 :            :                 void *src_domain_ctx, struct iovec *src_iov, uint32_t src_iov_cnt, struct iovec *dst_iov,
      44                 :            :                 uint32_t dst_iov_cnt, spdk_memory_domain_data_cpl_cb cpl_cb, void *cpl_cb_arg), 0);
      45                 :            : 
      46                 :          0 : DEFINE_STUB_V(spdk_nvme_qpair_print_command, (struct spdk_nvme_qpair *qpair,
      47                 :            :                 struct spdk_nvme_cmd *cmd));
      48                 :            : 
      49                 :          0 : DEFINE_STUB_V(spdk_nvme_qpair_print_completion, (struct spdk_nvme_qpair *qpair,
      50                 :            :                 struct spdk_nvme_cpl *cpl));
      51                 :            : 
      52         [ #  # ]:          0 : DEFINE_RETURN_MOCK(spdk_memory_domain_create, int);
      53                 :            : int
      54                 :          0 : spdk_memory_domain_create(struct spdk_memory_domain **domain, enum spdk_dma_device_type type,
      55                 :            :                           struct spdk_memory_domain_ctx *ctx, const char *id)
      56                 :            : {
      57                 :            :         static struct spdk_memory_domain *__dma_dev = (struct spdk_memory_domain *)0xdeaddead;
      58                 :            : 
      59   [ #  #  #  #  :          0 :         HANDLE_RETURN_MOCK(spdk_memory_domain_create);
                   #  # ]
      60                 :            : 
      61                 :          0 :         *domain = __dma_dev;
      62                 :            : 
      63                 :          0 :         return 0;
      64                 :            : }
      65                 :            : 
      66                 :            : static struct spdk_memory_domain_translation_result g_memory_translation_translation = {.size = sizeof(struct spdk_memory_domain_translation_result) };
      67                 :            : 
      68         [ #  # ]:          0 : DEFINE_RETURN_MOCK(spdk_memory_domain_translate_data, int);
      69                 :            : int
      70                 :          6 : spdk_memory_domain_translate_data(struct spdk_memory_domain *src_domain, void *src_domain_ctx,
      71                 :            :                                   struct spdk_memory_domain *dst_domain, struct spdk_memory_domain_translation_ctx *dst_domain_ctx,
      72                 :            :                                   void *addr, size_t len, struct spdk_memory_domain_translation_result *result)
      73                 :            : {
      74                 :            : 
      75   [ -  +  +  +  :          6 :         HANDLE_RETURN_MOCK(spdk_memory_domain_translate_data);
                   +  + ]
      76                 :            : 
      77   [ -  +  -  + ]:          3 :         memcpy(result, &g_memory_translation_translation, sizeof(g_memory_translation_translation));
      78                 :            : 
      79                 :          3 :         return 0;
      80                 :            : }
      81                 :            : 
      82                 :            : /* ibv_reg_mr can be a macro, need to undefine it */
      83                 :            : #ifdef ibv_reg_mr
      84                 :            : #undef ibv_reg_mr
      85                 :            : #endif
      86                 :            : 
      87         [ #  # ]:          0 : DEFINE_RETURN_MOCK(ibv_reg_mr, struct ibv_mr *);
      88                 :            : struct ibv_mr *
      89                 :            : ibv_reg_mr(struct ibv_pd *pd, void *addr, size_t length, int access)
      90                 :            : {
      91   [ #  #  #  #  :          0 :         HANDLE_RETURN_MOCK(ibv_reg_mr);
                   #  # ]
      92         [ #  # ]:          0 :         if (length > 0) {
      93                 :          0 :                 return &g_rdma_mr;
      94                 :            :         } else {
      95                 :          0 :                 return NULL;
      96                 :            :         }
      97                 :            : }
      98                 :            : 
      99                 :            : struct nvme_rdma_ut_bdev_io {
     100                 :            :         struct iovec iovs[NVME_RDMA_MAX_SGL_DESCRIPTORS];
     101                 :            :         int iovpos;
     102                 :            :         int iovcnt;
     103                 :            : };
     104                 :            : 
     105         [ #  # ]:          0 : DEFINE_RETURN_MOCK(rdma_get_devices, struct ibv_context **);
     106                 :            : struct ibv_context **
     107                 :            : rdma_get_devices(int *num_devices)
     108                 :            : {
     109                 :            :         static struct ibv_context *_contexts[] = {
     110                 :            :                 (struct ibv_context *)0xDEADBEEF,
     111                 :            :                 (struct ibv_context *)0xFEEDBEEF,
     112                 :            :                 NULL
     113                 :            :         };
     114                 :            : 
     115   [ -  +  -  +  :          3 :         HANDLE_RETURN_MOCK(rdma_get_devices);
                   -  + ]
     116                 :          3 :         return _contexts;
     117                 :            : }
     118                 :            : 
     119         [ #  # ]:          0 : DEFINE_RETURN_MOCK(rdma_create_event_channel, struct rdma_event_channel *);
     120                 :            : struct rdma_event_channel *
     121                 :            : rdma_create_event_channel(void)
     122                 :            : {
     123   [ -  +  +  +  :          3 :         HANDLE_RETURN_MOCK(rdma_create_event_channel);
                   +  - ]
     124                 :          0 :         return NULL;
     125                 :            : }
     126                 :            : 
     127         [ #  # ]:          0 : DEFINE_RETURN_MOCK(ibv_query_device, int);
     128                 :            : int
     129                 :            : ibv_query_device(struct ibv_context *context,
     130                 :            :                  struct ibv_device_attr *device_attr)
     131                 :            : {
     132         [ +  - ]:          9 :         if (device_attr) {
     133                 :          9 :                 device_attr->max_sge = NVME_RDMA_MAX_SGL_DESCRIPTORS;
     134                 :            :         }
     135   [ -  +  -  +  :          9 :         HANDLE_RETURN_MOCK(ibv_query_device);
                   -  + ]
     136                 :            : 
     137                 :          9 :         return 0;
     138                 :            : }
     139                 :            : 
     140                 :            : /* essentially a simplification of bdev_nvme_next_sge and bdev_nvme_reset_sgl */
     141                 :            : static void
     142                 :         30 : nvme_rdma_ut_reset_sgl(void *cb_arg, uint32_t offset)
     143                 :            : {
     144                 :         30 :         struct nvme_rdma_ut_bdev_io *bio = cb_arg;
     145                 :            :         struct iovec *iov;
     146                 :            : 
     147         [ +  - ]:         30 :         for (bio->iovpos = 0; bio->iovpos < NVME_RDMA_MAX_SGL_DESCRIPTORS; bio->iovpos++) {
     148                 :         30 :                 iov = &bio->iovs[bio->iovpos];
     149                 :            :                 /* Only provide offsets at the beginning of an iov */
     150         [ +  - ]:         30 :                 if (offset == 0) {
     151                 :         30 :                         break;
     152                 :            :                 }
     153                 :            : 
     154                 :          0 :                 offset -= iov->iov_len;
     155                 :            :         }
     156                 :            : 
     157         [ -  + ]:         30 :         SPDK_CU_ASSERT_FATAL(bio->iovpos < NVME_RDMA_MAX_SGL_DESCRIPTORS);
     158                 :         30 : }
     159                 :            : 
     160                 :            : static int
     161                 :         63 : nvme_rdma_ut_next_sge(void *cb_arg, void **address, uint32_t *length)
     162                 :            : {
     163                 :         63 :         struct nvme_rdma_ut_bdev_io *bio = cb_arg;
     164                 :            :         struct iovec *iov;
     165                 :            : 
     166         [ -  + ]:         63 :         SPDK_CU_ASSERT_FATAL(bio->iovpos < NVME_RDMA_MAX_SGL_DESCRIPTORS);
     167                 :            : 
     168         [ +  + ]:         63 :         if (bio->iovpos == bio->iovcnt) {
     169                 :          3 :                 return -1;
     170                 :            :         }
     171                 :            : 
     172                 :         60 :         iov = &bio->iovs[bio->iovpos];
     173                 :            : 
     174                 :         60 :         *address = iov->iov_base;
     175                 :         60 :         *length = iov->iov_len;
     176                 :         60 :         bio->iovpos++;
     177                 :            : 
     178                 :         60 :         return 0;
     179                 :            : }
     180                 :            : 
     181                 :            : static void
     182                 :          3 : test_nvme_rdma_build_sgl_request(void)
     183                 :            : {
     184                 :          3 :         struct nvme_rdma_qpair rqpair;
     185                 :          3 :         struct spdk_nvme_ctrlr ctrlr = {0};
     186                 :          3 :         struct spdk_nvmf_cmd cmd = {{0}};
     187                 :          3 :         struct spdk_nvme_rdma_req rdma_req = {0};
     188                 :          3 :         struct nvme_request req = {{0}};
     189                 :          3 :         struct nvme_rdma_ut_bdev_io bio = { .iovcnt = NVME_RDMA_MAX_SGL_DESCRIPTORS };
     190                 :            :         uint64_t i;
     191                 :            :         int rc;
     192                 :            : 
     193                 :          3 :         ctrlr.max_sges = NVME_RDMA_MAX_SGL_DESCRIPTORS;
     194                 :          3 :         ctrlr.cdata.nvmf_specific.msdbd = 16;
     195                 :          3 :         ctrlr.ioccsz_bytes = 4096;
     196                 :            : 
     197                 :          3 :         rqpair.mr_map = (struct spdk_rdma_utils_mem_map *)0xdeadbeef;
     198                 :          3 :         rqpair.rdma_qp = (struct spdk_rdma_provider_qp *)0xdeadbeef;
     199                 :          3 :         rqpair.qpair.ctrlr = &ctrlr;
     200                 :          3 :         rqpair.cmds = &cmd;
     201                 :          3 :         cmd.sgl[0].address = 0x1111;
     202                 :          3 :         rdma_req.id = 0;
     203                 :          3 :         rdma_req.req = &req;
     204                 :            : 
     205                 :          3 :         req.payload = NVME_PAYLOAD_SGL(nvme_rdma_ut_reset_sgl, nvme_rdma_ut_next_sge, &bio, NULL);
     206                 :          3 :         req.qpair = &rqpair.qpair;
     207                 :            : 
     208         [ +  + ]:         51 :         for (i = 0; i < NVME_RDMA_MAX_SGL_DESCRIPTORS; i++) {
     209                 :         48 :                 bio.iovs[i].iov_base = (void *)i + 1;
     210                 :         48 :                 bio.iovs[i].iov_len = 0;
     211                 :            :         }
     212                 :            : 
     213                 :            :         /* Test case 1: single SGL. Expected: PASS */
     214                 :          3 :         bio.iovpos = 0;
     215                 :          3 :         req.payload_offset = 0;
     216                 :          3 :         req.payload_size = 0x1000;
     217                 :          3 :         bio.iovs[0].iov_len = 0x1000;
     218                 :          3 :         rc = nvme_rdma_build_sgl_request(&rqpair, &rdma_req);
     219         [ -  + ]:          3 :         SPDK_CU_ASSERT_FATAL(rc == 0);
     220                 :          3 :         CU_ASSERT(bio.iovpos == 1);
     221                 :          3 :         CU_ASSERT(req.cmd.dptr.sgl1.keyed.type == SPDK_NVME_SGL_TYPE_KEYED_DATA_BLOCK);
     222                 :          3 :         CU_ASSERT(req.cmd.dptr.sgl1.keyed.subtype == SPDK_NVME_SGL_SUBTYPE_ADDRESS);
     223                 :          3 :         CU_ASSERT(req.cmd.dptr.sgl1.keyed.length == req.payload_size);
     224                 :          3 :         CU_ASSERT(req.cmd.dptr.sgl1.keyed.key == RDMA_UT_RKEY);
     225                 :          3 :         CU_ASSERT(req.cmd.dptr.sgl1.address == (uint64_t)bio.iovs[0].iov_base);
     226                 :          3 :         CU_ASSERT(rdma_req.send_sgl[0].length == sizeof(struct spdk_nvme_cmd));
     227                 :            : 
     228                 :            :         /* Test case 2: multiple SGL. Expected: PASS */
     229                 :          3 :         bio.iovpos = 0;
     230                 :          3 :         req.payload_offset = 0;
     231                 :          3 :         req.payload_size = 0x4000;
     232         [ +  + ]:         15 :         for (i = 0; i < 4; i++) {
     233                 :         12 :                 bio.iovs[i].iov_len = 0x1000;
     234                 :            :         }
     235                 :          3 :         rc = nvme_rdma_build_sgl_request(&rqpair, &rdma_req);
     236         [ -  + ]:          3 :         SPDK_CU_ASSERT_FATAL(rc == 0);
     237                 :          3 :         CU_ASSERT(bio.iovpos == 4);
     238                 :          3 :         CU_ASSERT(req.cmd.dptr.sgl1.unkeyed.type == SPDK_NVME_SGL_TYPE_LAST_SEGMENT);
     239                 :          3 :         CU_ASSERT(req.cmd.dptr.sgl1.unkeyed.subtype == SPDK_NVME_SGL_SUBTYPE_OFFSET);
     240                 :          3 :         CU_ASSERT(req.cmd.dptr.sgl1.unkeyed.length == 4 * sizeof(struct spdk_nvme_sgl_descriptor));
     241                 :          3 :         CU_ASSERT(req.cmd.dptr.sgl1.address == (uint64_t)0);
     242                 :          3 :         CU_ASSERT(rdma_req.send_sgl[0].length == 4 * sizeof(struct spdk_nvme_sgl_descriptor) + sizeof(
     243                 :            :                           struct spdk_nvme_cmd))
     244         [ +  + ]:         15 :         for (i = 0; i < 4; i++) {
     245                 :         12 :                 CU_ASSERT(cmd.sgl[i].keyed.type == SPDK_NVME_SGL_TYPE_KEYED_DATA_BLOCK);
     246                 :         12 :                 CU_ASSERT(cmd.sgl[i].keyed.subtype == SPDK_NVME_SGL_SUBTYPE_ADDRESS);
     247                 :         12 :                 CU_ASSERT(cmd.sgl[i].keyed.length == bio.iovs[i].iov_len);
     248                 :         12 :                 CU_ASSERT(cmd.sgl[i].keyed.key == RDMA_UT_RKEY);
     249                 :         12 :                 CU_ASSERT(cmd.sgl[i].address == (uint64_t)bio.iovs[i].iov_base);
     250                 :            :         }
     251                 :            : 
     252                 :            :         /* Test case 3: Multiple SGL, SGL 2X mr size. Expected: FAIL */
     253                 :          3 :         bio.iovpos = 0;
     254                 :          3 :         req.payload_offset = 0;
     255                 :          3 :         g_mr_size = 0x800;
     256                 :          3 :         rc = nvme_rdma_build_sgl_request(&rqpair, &rdma_req);
     257         [ -  + ]:          3 :         SPDK_CU_ASSERT_FATAL(rc != 0);
     258                 :          3 :         CU_ASSERT(bio.iovpos == 1);
     259                 :            : 
     260                 :            :         /* Test case 4: Multiple SGL, SGL size smaller than I/O size. Expected: FAIL */
     261                 :          3 :         bio.iovpos = 0;
     262                 :          3 :         bio.iovcnt = 4;
     263                 :          3 :         req.payload_offset = 0;
     264                 :          3 :         req.payload_size = 0x6000;
     265                 :          3 :         g_mr_size = 0x0;
     266                 :          3 :         rc = nvme_rdma_build_sgl_request(&rqpair, &rdma_req);
     267         [ -  + ]:          3 :         SPDK_CU_ASSERT_FATAL(rc != 0);
     268                 :          3 :         CU_ASSERT(bio.iovpos == bio.iovcnt);
     269                 :          3 :         bio.iovcnt = NVME_RDMA_MAX_SGL_DESCRIPTORS;
     270                 :            : 
     271                 :            :         /* Test case 5: SGL length exceeds 3 bytes. Expected: FAIL */
     272                 :          3 :         req.payload_size = 0x1000 + (1 << 24);
     273                 :          3 :         bio.iovs[0].iov_len = 0x1000;
     274                 :          3 :         bio.iovs[1].iov_len = 1 << 24;
     275                 :          3 :         rc = nvme_rdma_build_sgl_request(&rqpair, &rdma_req);
     276         [ -  + ]:          3 :         SPDK_CU_ASSERT_FATAL(rc != 0);
     277                 :            : 
     278                 :            :         /* Test case 6: 4 SGL descriptors, size of SGL descriptors exceeds ICD. Expected: FAIL */
     279                 :          3 :         ctrlr.ioccsz_bytes = 60;
     280                 :          3 :         bio.iovpos = 0;
     281                 :          3 :         req.payload_offset = 0;
     282                 :          3 :         req.payload_size = 0x4000;
     283         [ +  + ]:         15 :         for (i = 0; i < 4; i++) {
     284                 :         12 :                 bio.iovs[i].iov_len = 0x1000;
     285                 :            :         }
     286                 :          3 :         rc = nvme_rdma_build_sgl_request(&rqpair, &rdma_req);
     287         [ -  + ]:          3 :         SPDK_CU_ASSERT_FATAL(rc == -1);
     288                 :          3 : }
     289                 :            : 
     290                 :            : static void
     291                 :          3 : test_nvme_rdma_build_sgl_inline_request(void)
     292                 :            : {
     293                 :          3 :         struct nvme_rdma_qpair rqpair;
     294                 :          3 :         struct spdk_nvme_ctrlr ctrlr = {0};
     295                 :          3 :         struct spdk_nvmf_cmd cmd = {{0}};
     296                 :          3 :         struct spdk_nvme_rdma_req rdma_req = {0};
     297                 :          3 :         struct nvme_request req = {{0}};
     298                 :          3 :         struct nvme_rdma_ut_bdev_io bio = { .iovcnt = NVME_RDMA_MAX_SGL_DESCRIPTORS };
     299                 :            :         int rc;
     300                 :            : 
     301                 :          3 :         ctrlr.max_sges = NVME_RDMA_MAX_SGL_DESCRIPTORS;
     302                 :          3 :         ctrlr.cdata.nvmf_specific.msdbd = 16;
     303                 :            : 
     304                 :          3 :         rqpair.mr_map = (struct spdk_rdma_utils_mem_map *)0xdeadbeef;
     305                 :          3 :         rqpair.rdma_qp = (struct spdk_rdma_provider_qp *)0xdeadbeef;
     306                 :          3 :         rqpair.qpair.ctrlr = &ctrlr;
     307                 :          3 :         rqpair.cmds = &cmd;
     308                 :          3 :         cmd.sgl[0].address = 0x1111;
     309                 :          3 :         rdma_req.id = 0;
     310                 :          3 :         rdma_req.req = &req;
     311                 :            : 
     312                 :          3 :         req.payload = NVME_PAYLOAD_SGL(nvme_rdma_ut_reset_sgl, nvme_rdma_ut_next_sge, &bio, NULL);
     313                 :          3 :         req.qpair = &rqpair.qpair;
     314                 :            : 
     315                 :            :         /* Test case 1: single inline SGL. Expected: PASS */
     316                 :          3 :         bio.iovpos = 0;
     317                 :          3 :         req.payload_offset = 0;
     318                 :          3 :         req.payload_size = 0x1000;
     319                 :          3 :         bio.iovs[0].iov_base = (void *)0xdeadbeef;
     320                 :          3 :         bio.iovs[0].iov_len = 0x1000;
     321                 :          3 :         rc = nvme_rdma_build_sgl_inline_request(&rqpair, &rdma_req);
     322         [ -  + ]:          3 :         SPDK_CU_ASSERT_FATAL(rc == 0);
     323                 :          3 :         CU_ASSERT(bio.iovpos == 1);
     324                 :          3 :         CU_ASSERT(req.cmd.dptr.sgl1.unkeyed.type == SPDK_NVME_SGL_TYPE_DATA_BLOCK);
     325                 :          3 :         CU_ASSERT(req.cmd.dptr.sgl1.unkeyed.subtype == SPDK_NVME_SGL_SUBTYPE_OFFSET);
     326                 :          3 :         CU_ASSERT(req.cmd.dptr.sgl1.unkeyed.length == req.payload_size);
     327                 :          3 :         CU_ASSERT(req.cmd.dptr.sgl1.address == 0);
     328                 :          3 :         CU_ASSERT(rdma_req.send_sgl[0].length == sizeof(struct spdk_nvme_cmd));
     329                 :          3 :         CU_ASSERT(rdma_req.send_sgl[1].length == req.payload_size);
     330                 :          3 :         CU_ASSERT(rdma_req.send_sgl[1].addr == (uint64_t)bio.iovs[0].iov_base);
     331                 :          3 :         CU_ASSERT(rdma_req.send_sgl[1].lkey == RDMA_UT_LKEY);
     332                 :            : 
     333                 :            :         /* Test case 2: SGL length exceeds 3 bytes. Expected: PASS */
     334                 :          3 :         bio.iovpos = 0;
     335                 :          3 :         req.payload_offset = 0;
     336                 :          3 :         req.payload_size = 1 << 24;
     337                 :          3 :         bio.iovs[0].iov_len = 1 << 24;
     338                 :          3 :         rc = nvme_rdma_build_sgl_inline_request(&rqpair, &rdma_req);
     339         [ -  + ]:          3 :         SPDK_CU_ASSERT_FATAL(rc == 0);
     340                 :          3 :         CU_ASSERT(bio.iovpos == 1);
     341                 :          3 :         CU_ASSERT(req.cmd.dptr.sgl1.unkeyed.type == SPDK_NVME_SGL_TYPE_DATA_BLOCK);
     342                 :          3 :         CU_ASSERT(req.cmd.dptr.sgl1.unkeyed.subtype == SPDK_NVME_SGL_SUBTYPE_OFFSET);
     343                 :          3 :         CU_ASSERT(req.cmd.dptr.sgl1.unkeyed.length == req.payload_size);
     344                 :          3 :         CU_ASSERT(req.cmd.dptr.sgl1.address == 0);
     345                 :          3 :         CU_ASSERT(rdma_req.send_sgl[0].length == sizeof(struct spdk_nvme_cmd));
     346                 :          3 :         CU_ASSERT(rdma_req.send_sgl[1].length == req.payload_size);
     347                 :          3 :         CU_ASSERT(rdma_req.send_sgl[1].addr == (uint64_t)bio.iovs[0].iov_base);
     348                 :          3 :         CU_ASSERT(rdma_req.send_sgl[1].lkey == RDMA_UT_LKEY);
     349                 :          3 : }
     350                 :            : 
     351                 :            : static void
     352                 :          3 : test_nvme_rdma_build_contig_request(void)
     353                 :            : {
     354                 :          3 :         struct nvme_rdma_qpair rqpair;
     355                 :          3 :         struct spdk_nvme_ctrlr ctrlr = {0};
     356                 :          3 :         struct spdk_nvmf_cmd cmd = {{0}};
     357                 :          3 :         struct spdk_nvme_rdma_req rdma_req = {0};
     358                 :          3 :         struct nvme_request req = {{0}};
     359                 :            :         int rc;
     360                 :            : 
     361                 :          3 :         ctrlr.max_sges = NVME_RDMA_MAX_SGL_DESCRIPTORS;
     362                 :          3 :         ctrlr.cdata.nvmf_specific.msdbd = 16;
     363                 :            : 
     364                 :          3 :         rqpair.mr_map = (struct spdk_rdma_utils_mem_map *)0xdeadbeef;
     365                 :          3 :         rqpair.rdma_qp = (struct spdk_rdma_provider_qp *)0xdeadbeef;
     366                 :          3 :         rqpair.qpair.ctrlr = &ctrlr;
     367                 :          3 :         rqpair.cmds = &cmd;
     368                 :          3 :         cmd.sgl[0].address = 0x1111;
     369                 :          3 :         rdma_req.id = 0;
     370                 :          3 :         rdma_req.req = &req;
     371                 :            : 
     372                 :          3 :         req.payload = NVME_PAYLOAD_CONTIG((void *)0xdeadbeef, NULL);
     373                 :          3 :         req.qpair = &rqpair.qpair;
     374                 :            : 
     375                 :            :         /* Test case 1: contig request. Expected: PASS */
     376                 :          3 :         req.payload_offset = 0;
     377                 :          3 :         req.payload_size = 0x1000;
     378                 :          3 :         rc = nvme_rdma_build_contig_request(&rqpair, &rdma_req);
     379         [ -  + ]:          3 :         SPDK_CU_ASSERT_FATAL(rc == 0);
     380                 :          3 :         CU_ASSERT(req.cmd.dptr.sgl1.keyed.type == SPDK_NVME_SGL_TYPE_KEYED_DATA_BLOCK);
     381                 :          3 :         CU_ASSERT(req.cmd.dptr.sgl1.keyed.subtype == SPDK_NVME_SGL_SUBTYPE_ADDRESS);
     382                 :          3 :         CU_ASSERT(req.cmd.dptr.sgl1.keyed.length == req.payload_size);
     383                 :          3 :         CU_ASSERT(req.cmd.dptr.sgl1.keyed.key == RDMA_UT_RKEY);
     384                 :          3 :         CU_ASSERT(req.cmd.dptr.sgl1.address == (uint64_t)req.payload.contig_or_cb_arg);
     385                 :          3 :         CU_ASSERT(rdma_req.send_sgl[0].length == sizeof(struct spdk_nvme_cmd));
     386                 :            : 
     387                 :            :         /* Test case 2: SGL length exceeds 3 bytes. Expected: FAIL */
     388                 :          3 :         req.payload_offset = 0;
     389                 :          3 :         req.payload_size = 1 << 24;
     390                 :          3 :         rc = nvme_rdma_build_contig_request(&rqpair, &rdma_req);
     391         [ -  + ]:          3 :         SPDK_CU_ASSERT_FATAL(rc != 0);
     392                 :          3 : }
     393                 :            : 
     394                 :            : static void
     395                 :          3 : test_nvme_rdma_build_contig_inline_request(void)
     396                 :            : {
     397                 :          3 :         struct nvme_rdma_qpair rqpair;
     398                 :          3 :         struct spdk_nvme_ctrlr ctrlr = {0};
     399                 :          3 :         struct spdk_nvmf_cmd cmd = {{0}};
     400                 :          3 :         struct spdk_nvme_rdma_req rdma_req = {0};
     401                 :          3 :         struct nvme_request req = {{0}};
     402                 :            :         int rc;
     403                 :            : 
     404                 :          3 :         ctrlr.max_sges = NVME_RDMA_MAX_SGL_DESCRIPTORS;
     405                 :          3 :         ctrlr.cdata.nvmf_specific.msdbd = 16;
     406                 :            : 
     407                 :          3 :         rqpair.mr_map = (struct spdk_rdma_utils_mem_map *)0xdeadbeef;
     408                 :          3 :         rqpair.rdma_qp = (struct spdk_rdma_provider_qp *)0xdeadbeef;
     409                 :          3 :         rqpair.qpair.ctrlr = &ctrlr;
     410                 :          3 :         rqpair.cmds = &cmd;
     411                 :          3 :         cmd.sgl[0].address = 0x1111;
     412                 :          3 :         rdma_req.id = 0;
     413                 :          3 :         rdma_req.req = &req;
     414                 :            : 
     415                 :          3 :         req.payload = NVME_PAYLOAD_CONTIG((void *)0xdeadbeef, NULL);
     416                 :          3 :         req.qpair = &rqpair.qpair;
     417                 :            : 
     418                 :            :         /* Test case 1: single inline SGL. Expected: PASS */
     419                 :          3 :         req.payload_offset = 0;
     420                 :          3 :         req.payload_size = 0x1000;
     421                 :          3 :         rc = nvme_rdma_build_contig_inline_request(&rqpair, &rdma_req);
     422         [ -  + ]:          3 :         SPDK_CU_ASSERT_FATAL(rc == 0);
     423                 :          3 :         CU_ASSERT(req.cmd.dptr.sgl1.unkeyed.type == SPDK_NVME_SGL_TYPE_DATA_BLOCK);
     424                 :          3 :         CU_ASSERT(req.cmd.dptr.sgl1.unkeyed.subtype == SPDK_NVME_SGL_SUBTYPE_OFFSET);
     425                 :          3 :         CU_ASSERT(req.cmd.dptr.sgl1.unkeyed.length == req.payload_size);
     426                 :          3 :         CU_ASSERT(req.cmd.dptr.sgl1.address == 0);
     427                 :          3 :         CU_ASSERT(rdma_req.send_sgl[0].length == sizeof(struct spdk_nvme_cmd));
     428                 :          3 :         CU_ASSERT(rdma_req.send_sgl[1].length == req.payload_size);
     429                 :          3 :         CU_ASSERT(rdma_req.send_sgl[1].addr == (uint64_t)req.payload.contig_or_cb_arg);
     430                 :          3 :         CU_ASSERT(rdma_req.send_sgl[1].lkey == RDMA_UT_LKEY);
     431                 :            : 
     432                 :            :         /* Test case 2: SGL length exceeds 3 bytes. Expected: PASS */
     433                 :          3 :         req.payload_offset = 0;
     434                 :          3 :         req.payload_size = 1 << 24;
     435                 :          3 :         rc = nvme_rdma_build_contig_inline_request(&rqpair, &rdma_req);
     436         [ -  + ]:          3 :         SPDK_CU_ASSERT_FATAL(rc == 0);
     437                 :          3 :         CU_ASSERT(req.cmd.dptr.sgl1.unkeyed.type == SPDK_NVME_SGL_TYPE_DATA_BLOCK);
     438                 :          3 :         CU_ASSERT(req.cmd.dptr.sgl1.unkeyed.subtype == SPDK_NVME_SGL_SUBTYPE_OFFSET);
     439                 :          3 :         CU_ASSERT(req.cmd.dptr.sgl1.unkeyed.length == req.payload_size);
     440                 :          3 :         CU_ASSERT(req.cmd.dptr.sgl1.address == 0);
     441                 :          3 :         CU_ASSERT(rdma_req.send_sgl[0].length == sizeof(struct spdk_nvme_cmd));
     442                 :          3 :         CU_ASSERT(rdma_req.send_sgl[1].length == req.payload_size);
     443                 :          3 :         CU_ASSERT(rdma_req.send_sgl[1].addr == (uint64_t)req.payload.contig_or_cb_arg);
     444                 :          3 :         CU_ASSERT(rdma_req.send_sgl[1].lkey == RDMA_UT_LKEY);
     445                 :          3 : }
     446                 :            : 
     447                 :            : static void
     448                 :          3 : test_nvme_rdma_create_reqs(void)
     449                 :            : {
     450                 :          3 :         struct nvme_rdma_qpair rqpair = {};
     451                 :            :         int rc;
     452                 :            : 
     453                 :          3 :         memset(&g_nvme_hooks, 0, sizeof(g_nvme_hooks));
     454                 :            : 
     455                 :            :         /* Test case 1: zero entry. Expect: FAIL */
     456                 :          3 :         rqpair.num_entries = 0;
     457                 :            : 
     458                 :          3 :         rc = nvme_rdma_create_reqs(&rqpair);
     459                 :          3 :         CU_ASSERT(rqpair.rdma_reqs == NULL);
     460         [ -  + ]:          3 :         SPDK_CU_ASSERT_FATAL(rc == -ENOMEM);
     461                 :            : 
     462                 :            :         /* Test case 2: single entry. Expect: PASS */
     463                 :          3 :         memset(&rqpair, 0, sizeof(rqpair));
     464                 :          3 :         rqpair.num_entries = 1;
     465                 :            : 
     466                 :          3 :         rc = nvme_rdma_create_reqs(&rqpair);
     467                 :          3 :         CU_ASSERT(rc == 0);
     468                 :          3 :         CU_ASSERT(rqpair.rdma_reqs[0].send_sgl[0].lkey == g_rdma_mr.lkey);
     469                 :          3 :         CU_ASSERT(rqpair.rdma_reqs[0].send_sgl[0].addr
     470                 :            :                   == (uint64_t)&rqpair.cmds[0]);
     471                 :          3 :         CU_ASSERT(rqpair.rdma_reqs[0].send_wr.wr_id
     472                 :            :                   == (uint64_t)&rqpair.rdma_reqs[0].rdma_wr);
     473                 :          3 :         CU_ASSERT(rqpair.rdma_reqs[0].send_wr.next == NULL);
     474                 :          3 :         CU_ASSERT(rqpair.rdma_reqs[0].send_wr.opcode == IBV_WR_SEND);
     475                 :          3 :         CU_ASSERT(rqpair.rdma_reqs[0].send_wr.send_flags == IBV_SEND_SIGNALED);
     476                 :          3 :         CU_ASSERT(rqpair.rdma_reqs[0].send_wr.sg_list
     477                 :            :                   == rqpair.rdma_reqs[0].send_sgl);
     478                 :          3 :         CU_ASSERT(rqpair.rdma_reqs[0].send_wr.imm_data == 0);
     479                 :          3 :         spdk_free(rqpair.rdma_reqs);
     480                 :          3 :         spdk_free(rqpair.cmds);
     481                 :            : 
     482                 :            :         /* Test case 3: multiple entries. Expect: PASS */
     483                 :          3 :         memset(&rqpair, 0, sizeof(rqpair));
     484                 :          3 :         rqpair.num_entries = 5;
     485                 :            : 
     486                 :          3 :         rc = nvme_rdma_create_reqs(&rqpair);
     487                 :          3 :         CU_ASSERT(rc == 0);
     488         [ +  + ]:         18 :         for (int i = 0; i < 5; i++) {
     489                 :         15 :                 CU_ASSERT(rqpair.rdma_reqs[i].send_sgl[0].lkey == g_rdma_mr.lkey);
     490                 :         15 :                 CU_ASSERT(rqpair.rdma_reqs[i].send_sgl[0].addr
     491                 :            :                           == (uint64_t)&rqpair.cmds[i]);
     492                 :         15 :                 CU_ASSERT(rqpair.rdma_reqs[i].send_wr.wr_id
     493                 :            :                           == (uint64_t)&rqpair.rdma_reqs[i].rdma_wr);
     494                 :         15 :                 CU_ASSERT(rqpair.rdma_reqs[i].send_wr.next == NULL);
     495                 :         15 :                 CU_ASSERT(rqpair.rdma_reqs[i].send_wr.opcode == IBV_WR_SEND);
     496                 :         15 :                 CU_ASSERT(rqpair.rdma_reqs[i].send_wr.send_flags
     497                 :            :                           == IBV_SEND_SIGNALED);
     498                 :         15 :                 CU_ASSERT(rqpair.rdma_reqs[i].send_wr.sg_list
     499                 :            :                           == rqpair.rdma_reqs[i].send_sgl);
     500                 :         15 :                 CU_ASSERT(rqpair.rdma_reqs[i].send_wr.imm_data == 0);
     501                 :            :         }
     502                 :          3 :         spdk_free(rqpair.rdma_reqs);
     503                 :          3 :         spdk_free(rqpair.cmds);
     504                 :          3 : }
     505                 :            : 
     506                 :            : static void
     507                 :          3 : test_nvme_rdma_create_rsps(void)
     508                 :            : {
     509                 :          3 :         struct nvme_rdma_rsp_opts opts = {};
     510                 :            :         struct nvme_rdma_rsps *rsps;
     511                 :          3 :         struct spdk_rdma_provider_qp *rdma_qp = (struct spdk_rdma_provider_qp *)0xfeedf00d;
     512                 :          3 :         struct nvme_rdma_qpair rqpair = { .rdma_qp = rdma_qp, };
     513                 :            : 
     514                 :          3 :         memset(&g_nvme_hooks, 0, sizeof(g_nvme_hooks));
     515                 :            : 
     516                 :          3 :         opts.rqpair = &rqpair;
     517                 :            : 
     518                 :            :         /* Test case 1 calloc false */
     519                 :          3 :         opts.num_entries = 0;
     520                 :          3 :         rsps = nvme_rdma_create_rsps(&opts);
     521         [ -  + ]:          3 :         SPDK_CU_ASSERT_FATAL(rsps == NULL);
     522                 :            : 
     523                 :            :         /* Test case 2 calloc success */
     524                 :          3 :         opts.num_entries = 1;
     525                 :            : 
     526                 :          3 :         rsps = nvme_rdma_create_rsps(&opts);
     527         [ -  + ]:          3 :         SPDK_CU_ASSERT_FATAL(rsps != NULL);
     528                 :          3 :         CU_ASSERT(rsps->rsp_sgls != NULL);
     529                 :          3 :         CU_ASSERT(rsps->rsp_recv_wrs != NULL);
     530                 :          3 :         CU_ASSERT(rsps->rsps != NULL);
     531                 :          3 :         CU_ASSERT(rsps->rsp_sgls[0].lkey == g_rdma_mr.lkey);
     532                 :          3 :         CU_ASSERT(rsps->rsp_sgls[0].addr == (uint64_t)&rsps->rsps[0]);
     533                 :          3 :         CU_ASSERT(rsps->rsp_recv_wrs[0].wr_id == (uint64_t)&rsps->rsps[0].rdma_wr);
     534                 :            : 
     535                 :          3 :         nvme_rdma_free_rsps(rsps);
     536                 :          3 : }
     537                 :            : 
     538                 :            : static void
     539                 :          3 : test_nvme_rdma_ctrlr_create_qpair(void)
     540                 :            : {
     541                 :          3 :         struct spdk_nvme_ctrlr ctrlr = {};
     542                 :            :         uint16_t qid, qsize;
     543                 :            :         struct spdk_nvme_qpair *qpair;
     544                 :            :         struct nvme_rdma_qpair *rqpair;
     545                 :            : 
     546                 :            :         /* Test case 1: max qsize. Expect: PASS */
     547                 :          3 :         qsize = 0xffff;
     548                 :          3 :         qid = 1;
     549                 :            : 
     550                 :          3 :         qpair = nvme_rdma_ctrlr_create_qpair(&ctrlr, qid, qsize,
     551                 :            :                                              SPDK_NVME_QPRIO_URGENT, 1,
     552                 :            :                                              false, false);
     553                 :          3 :         CU_ASSERT(qpair != NULL);
     554                 :          3 :         rqpair = SPDK_CONTAINEROF(qpair, struct nvme_rdma_qpair, qpair);
     555                 :          3 :         CU_ASSERT(qpair == &rqpair->qpair);
     556                 :          3 :         CU_ASSERT(rqpair->num_entries == qsize - 1);
     557         [ -  + ]:          3 :         CU_ASSERT(rqpair->delay_cmd_submit == false);
     558                 :            : 
     559                 :          3 :         spdk_free(rqpair);
     560                 :          3 :         rqpair = NULL;
     561                 :            : 
     562                 :            :         /* Test case 2: queue size 2. Expect: PASS */
     563                 :          3 :         qsize = 2;
     564                 :          3 :         qpair = nvme_rdma_ctrlr_create_qpair(&ctrlr, qid, qsize,
     565                 :            :                                              SPDK_NVME_QPRIO_URGENT, 1,
     566                 :            :                                              false, false);
     567                 :          3 :         CU_ASSERT(qpair != NULL);
     568                 :          3 :         rqpair = SPDK_CONTAINEROF(qpair, struct nvme_rdma_qpair, qpair);
     569                 :          3 :         CU_ASSERT(rqpair->num_entries == qsize - 1);
     570                 :            : 
     571                 :          3 :         spdk_free(rqpair);
     572                 :          3 :         rqpair = NULL;
     573                 :            : 
     574                 :            :         /* Test case 3: queue size zero. Expect: FAIL */
     575                 :          3 :         qsize = 0;
     576                 :            : 
     577                 :          3 :         qpair = nvme_rdma_ctrlr_create_qpair(&ctrlr, qid, qsize,
     578                 :            :                                              SPDK_NVME_QPRIO_URGENT, 1,
     579                 :            :                                              false, false);
     580         [ -  + ]:          3 :         SPDK_CU_ASSERT_FATAL(qpair == NULL);
     581                 :            : 
     582                 :            :         /* Test case 4: queue size 1. Expect: FAIL */
     583                 :          3 :         qsize = 1;
     584                 :          3 :         qpair = nvme_rdma_ctrlr_create_qpair(&ctrlr, qid, qsize,
     585                 :            :                                              SPDK_NVME_QPRIO_URGENT, 1,
     586                 :            :                                              false, false);
     587         [ -  + ]:          3 :         SPDK_CU_ASSERT_FATAL(qpair == NULL);
     588                 :          3 : }
     589                 :            : 
     590   [ -  +  -  - ]:         30 : DEFINE_STUB(ibv_create_cq, struct ibv_cq *, (struct ibv_context *context, int cqe, void *cq_context,
     591                 :            :                 struct ibv_comp_channel *channel, int comp_vector), (struct ibv_cq *)0xFEEDBEEF);
     592   [ -  +  -  - ]:         21 : DEFINE_STUB(ibv_destroy_cq, int, (struct ibv_cq *cq), 0);
     593                 :            : 
     594                 :            : static void
     595                 :          3 : test_nvme_rdma_poller_create(void)
     596                 :            : {
     597                 :          3 :         struct nvme_rdma_poll_group     group = {};
     598                 :          3 :         struct ibv_context context = {
     599                 :            :                 .device = (struct ibv_device *)0xDEADBEEF
     600                 :            :         };
     601                 :          3 :         struct ibv_context context_2 = {
     602                 :            :                 .device = (struct ibv_device *)0xBAADBEEF
     603                 :            :         };
     604                 :            :         struct nvme_rdma_poller *poller_1, *poller_2, *poller_3;
     605                 :            : 
     606                 :            :         /* Case: calloc and ibv not need to fail test */
     607                 :          3 :         STAILQ_INIT(&group.pollers);
     608                 :            : 
     609                 :          3 :         poller_1 = nvme_rdma_poll_group_get_poller(&group, &context);
     610         [ -  + ]:          3 :         SPDK_CU_ASSERT_FATAL(poller_1 != NULL);
     611                 :          3 :         CU_ASSERT(group.num_pollers == 1);
     612                 :          3 :         CU_ASSERT(STAILQ_FIRST(&group.pollers) == poller_1);
     613                 :          3 :         CU_ASSERT(poller_1->refcnt == 1);
     614                 :          3 :         CU_ASSERT(poller_1->device == &context);
     615                 :          3 :         CU_ASSERT(poller_1->cq == (struct ibv_cq *)0xFEEDBEEF);
     616                 :          3 :         CU_ASSERT(poller_1->current_num_wc == DEFAULT_NVME_RDMA_CQ_SIZE);
     617                 :          3 :         CU_ASSERT(poller_1->required_num_wc == 0);
     618                 :            : 
     619                 :          3 :         poller_2 = nvme_rdma_poll_group_get_poller(&group, &context_2);
     620         [ -  + ]:          3 :         SPDK_CU_ASSERT_FATAL(poller_2 != NULL);
     621                 :          3 :         CU_ASSERT(group.num_pollers == 2);
     622                 :          3 :         CU_ASSERT(STAILQ_FIRST(&group.pollers) == poller_2);
     623                 :          3 :         CU_ASSERT(poller_2->refcnt == 1);
     624                 :          3 :         CU_ASSERT(poller_2->device == &context_2);
     625                 :            : 
     626                 :          3 :         poller_3 = nvme_rdma_poll_group_get_poller(&group, &context);
     627         [ -  + ]:          3 :         SPDK_CU_ASSERT_FATAL(poller_3 != NULL);
     628                 :          3 :         CU_ASSERT(poller_3 == poller_1);
     629                 :          3 :         CU_ASSERT(group.num_pollers == 2);
     630                 :          3 :         CU_ASSERT(poller_3->refcnt == 2);
     631                 :            : 
     632                 :          3 :         nvme_rdma_poll_group_put_poller(&group, poller_2);
     633                 :          3 :         CU_ASSERT(group.num_pollers == 1);
     634                 :            : 
     635                 :          3 :         nvme_rdma_poll_group_put_poller(&group, poller_1);
     636                 :          3 :         CU_ASSERT(group.num_pollers == 1);
     637                 :          3 :         CU_ASSERT(poller_3->refcnt == 1);
     638                 :            : 
     639                 :          3 :         nvme_rdma_poll_group_put_poller(&group, poller_3);
     640                 :          3 :         CU_ASSERT(STAILQ_EMPTY(&group.pollers));
     641                 :          3 :         CU_ASSERT(group.num_pollers == 0);
     642                 :            : 
     643                 :          3 :         nvme_rdma_poll_group_free_pollers(&group);
     644                 :          3 : }
     645                 :            : 
     646                 :            : static void
     647                 :          3 : test_nvme_rdma_qpair_process_cm_event(void)
     648                 :            : {
     649                 :          3 :         struct nvme_rdma_qpair rqpair = {};
     650                 :          3 :         struct rdma_cm_event     event = {};
     651                 :          3 :         struct spdk_nvmf_rdma_accept_private_data       accept_data = {};
     652                 :          3 :         int rc = 0;
     653                 :            : 
     654                 :            :         /* case1: event == RDMA_CM_EVENT_ADDR_RESOLVED */
     655                 :          3 :         rqpair.evt = &event;
     656                 :          3 :         event.event = RDMA_CM_EVENT_ADDR_RESOLVED;
     657                 :          3 :         rc = nvme_rdma_qpair_process_cm_event(&rqpair);
     658                 :          3 :         CU_ASSERT(rc == 0);
     659                 :            : 
     660                 :            :         /* case2: event == RDMA_CM_EVENT_CONNECT_REQUEST */
     661                 :          3 :         rqpair.evt = &event;
     662                 :          3 :         event.event = RDMA_CM_EVENT_CONNECT_REQUEST;
     663                 :          3 :         rc = nvme_rdma_qpair_process_cm_event(&rqpair);
     664                 :          3 :         CU_ASSERT(rc == 0);
     665                 :            : 
     666                 :            :         /* case3: event == RDMA_CM_EVENT_CONNECT_ERROR */
     667                 :          3 :         rqpair.evt = &event;
     668                 :          3 :         event.event = RDMA_CM_EVENT_CONNECT_ERROR;
     669                 :          3 :         rc = nvme_rdma_qpair_process_cm_event(&rqpair);
     670                 :          3 :         CU_ASSERT(rc == 0);
     671                 :            : 
     672                 :            :         /* case4: event == RDMA_CM_EVENT_UNREACHABLE */
     673                 :          3 :         rqpair.evt = &event;
     674                 :          3 :         event.event = RDMA_CM_EVENT_UNREACHABLE;
     675                 :          3 :         rc = nvme_rdma_qpair_process_cm_event(&rqpair);
     676                 :          3 :         CU_ASSERT(rc == 0);
     677                 :            : 
     678                 :            :         /* case5: event == RDMA_CM_EVENT_CONNECT_RESPONSE */
     679                 :          3 :         rqpair.evt = &event;
     680                 :          3 :         event.event = RDMA_CM_EVENT_CONNECT_RESPONSE;
     681                 :          3 :         event.param.conn.private_data = NULL;
     682                 :          3 :         rc = nvme_rdma_qpair_process_cm_event(&rqpair);
     683                 :          3 :         CU_ASSERT(rc == -1);
     684                 :            : 
     685                 :          3 :         rqpair.evt = &event;
     686                 :          3 :         event.event = RDMA_CM_EVENT_CONNECT_RESPONSE;
     687                 :          3 :         event.param.conn.private_data = &accept_data;
     688                 :          3 :         accept_data.crqsize = 512;
     689                 :          3 :         rqpair.num_entries = 1024;
     690                 :          3 :         rc = nvme_rdma_qpair_process_cm_event(&rqpair);
     691                 :          3 :         CU_ASSERT(rc == 0);
     692                 :          3 :         CU_ASSERT(rqpair.num_entries == 1024);
     693                 :            : 
     694                 :            :         /* case6: event == RDMA_CM_EVENT_DISCONNECTED */
     695                 :          3 :         rqpair.evt = &event;
     696                 :          3 :         event.event = RDMA_CM_EVENT_DISCONNECTED;
     697                 :          3 :         rc = nvme_rdma_qpair_process_cm_event(&rqpair);
     698                 :          3 :         CU_ASSERT(rc == 0);
     699                 :          3 :         CU_ASSERT(rqpair.qpair.transport_failure_reason == SPDK_NVME_QPAIR_FAILURE_REMOTE);
     700                 :            : 
     701                 :            :         /* case7: event == RDMA_CM_EVENT_DEVICE_REMOVAL */
     702                 :          3 :         rqpair.evt = &event;
     703                 :          3 :         event.event = RDMA_CM_EVENT_DEVICE_REMOVAL;
     704                 :          3 :         rc = nvme_rdma_qpair_process_cm_event(&rqpair);
     705                 :          3 :         CU_ASSERT(rc == 0);
     706                 :          3 :         CU_ASSERT(rqpair.qpair.transport_failure_reason == SPDK_NVME_QPAIR_FAILURE_LOCAL);
     707                 :            : 
     708                 :            :         /* case8: event == RDMA_CM_EVENT_MULTICAST_JOIN */
     709                 :          3 :         rqpair.evt = &event;
     710                 :          3 :         event.event = RDMA_CM_EVENT_MULTICAST_JOIN;
     711                 :          3 :         rc = nvme_rdma_qpair_process_cm_event(&rqpair);
     712                 :          3 :         CU_ASSERT(rc == 0);
     713                 :            : 
     714                 :            :         /* case9: event == RDMA_CM_EVENT_ADDR_CHANGE */
     715                 :          3 :         rqpair.evt = &event;
     716                 :          3 :         event.event = RDMA_CM_EVENT_ADDR_CHANGE;
     717                 :          3 :         rc = nvme_rdma_qpair_process_cm_event(&rqpair);
     718                 :          3 :         CU_ASSERT(rc == 0);
     719                 :          3 :         CU_ASSERT(rqpair.qpair.transport_failure_reason == SPDK_NVME_QPAIR_FAILURE_LOCAL);
     720                 :            : 
     721                 :            :         /* case10: event == RDMA_CM_EVENT_TIMEWAIT_EXIT */
     722                 :          3 :         rqpair.evt = &event;
     723                 :          3 :         event.event = RDMA_CM_EVENT_TIMEWAIT_EXIT;
     724                 :          3 :         rc = nvme_rdma_qpair_process_cm_event(&rqpair);
     725                 :          3 :         CU_ASSERT(rc == 0);
     726                 :            : 
     727                 :            :         /* case11: default event == 0xFF */
     728                 :          3 :         rqpair.evt = &event;
     729                 :          3 :         event.event = 0xFF;
     730                 :          3 :         rc = nvme_rdma_qpair_process_cm_event(&rqpair);
     731                 :          3 :         CU_ASSERT(rc == 0);
     732                 :          3 : }
     733                 :            : 
     734                 :            : static void
     735                 :          3 : test_nvme_rdma_ctrlr_construct(void)
     736                 :            : {
     737                 :            :         struct spdk_nvme_ctrlr *ctrlr;
     738                 :          3 :         struct spdk_nvme_transport_id trid = {};
     739                 :          3 :         struct spdk_nvme_ctrlr_opts opts = {};
     740                 :          3 :         struct nvme_rdma_qpair *rqpair = NULL;
     741                 :          3 :         struct nvme_rdma_ctrlr *rctrlr = NULL;
     742                 :          3 :         struct rdma_event_channel cm_channel = {};
     743                 :          3 :         void *devhandle = NULL;
     744                 :            :         int rc;
     745                 :            : 
     746                 :          3 :         opts.transport_retry_count = NVME_RDMA_CTRLR_MAX_TRANSPORT_RETRY_COUNT + 1;
     747                 :          3 :         opts.transport_ack_timeout = NVME_RDMA_CTRLR_MAX_TRANSPORT_ACK_TIMEOUT + 1;
     748                 :          3 :         opts.admin_queue_size = 0xFFFF;
     749                 :          3 :         trid.trtype = SPDK_NVME_TRANSPORT_RDMA;
     750                 :          3 :         trid.adrfam = SPDK_NVMF_ADRFAM_IPV4;
     751                 :          3 :         MOCK_SET(rdma_create_event_channel, &cm_channel);
     752                 :            : 
     753                 :          3 :         ctrlr = nvme_rdma_ctrlr_construct(&trid, &opts, devhandle);
     754         [ -  + ]:          3 :         SPDK_CU_ASSERT_FATAL(ctrlr != NULL);
     755                 :          3 :         CU_ASSERT(ctrlr->opts.transport_retry_count ==
     756                 :            :                   NVME_RDMA_CTRLR_MAX_TRANSPORT_RETRY_COUNT);
     757                 :          3 :         CU_ASSERT(ctrlr->opts.transport_ack_timeout ==
     758                 :            :                   NVME_RDMA_CTRLR_MAX_TRANSPORT_ACK_TIMEOUT);
     759                 :          3 :         CU_ASSERT(ctrlr->opts.admin_queue_size == opts.admin_queue_size);
     760                 :          3 :         rctrlr = SPDK_CONTAINEROF(ctrlr, struct nvme_rdma_ctrlr, ctrlr);
     761                 :          3 :         CU_ASSERT(rctrlr->max_sge == NVME_RDMA_MAX_SGL_DESCRIPTORS);
     762                 :          3 :         CU_ASSERT(rctrlr->cm_channel == &cm_channel);
     763         [ -  + ]:          3 :         CU_ASSERT(!strncmp((char *)&rctrlr->ctrlr.trid,
     764                 :            :                            (char *)&trid, sizeof(trid)));
     765                 :            : 
     766         [ -  + ]:          3 :         SPDK_CU_ASSERT_FATAL(ctrlr->adminq != NULL);
     767                 :          3 :         rqpair = SPDK_CONTAINEROF(ctrlr->adminq, struct nvme_rdma_qpair, qpair);
     768                 :          3 :         CU_ASSERT(rqpair->num_entries == opts.admin_queue_size - 1);
     769         [ -  + ]:          3 :         CU_ASSERT(rqpair->delay_cmd_submit == false);
     770   [ -  -  -  + ]:          3 :         MOCK_CLEAR(rdma_create_event_channel);
     771                 :            : 
     772                 :            :         /* Hardcode the trtype, because nvme_qpair_init() is stub function. */
     773                 :          3 :         rqpair->qpair.trtype = SPDK_NVME_TRANSPORT_RDMA;
     774                 :          3 :         rc = nvme_rdma_ctrlr_destruct(ctrlr);
     775                 :          3 :         CU_ASSERT(rc == 0);
     776                 :          3 : }
     777                 :            : 
     778                 :            : static void
     779                 :          3 : test_nvme_rdma_req_put_and_get(void)
     780                 :            : {
     781                 :          3 :         struct nvme_rdma_qpair rqpair = {};
     782                 :          3 :         struct spdk_nvme_rdma_req rdma_req = {};
     783                 :            :         struct spdk_nvme_rdma_req *rdma_req_get;
     784                 :            : 
     785                 :            :         /* case 1: nvme_rdma_req_put */
     786                 :          3 :         TAILQ_INIT(&rqpair.free_reqs);
     787                 :          3 :         rdma_req.completion_flags = 1;
     788                 :          3 :         rdma_req.req = (struct nvme_request *)0xDEADBEFF;
     789                 :          3 :         rdma_req.id = 10086;
     790                 :          3 :         nvme_rdma_req_put(&rqpair, &rdma_req);
     791                 :            : 
     792                 :          3 :         CU_ASSERT(rqpair.free_reqs.tqh_first == &rdma_req);
     793                 :          3 :         CU_ASSERT(rqpair.free_reqs.tqh_first->completion_flags == 0);
     794                 :          3 :         CU_ASSERT(rqpair.free_reqs.tqh_first->req == NULL);
     795                 :          3 :         CU_ASSERT(rqpair.free_reqs.tqh_first->id == 10086);
     796                 :          3 :         CU_ASSERT(rdma_req.completion_flags == 0);
     797                 :          3 :         CU_ASSERT(rdma_req.req == NULL);
     798                 :            : 
     799                 :            :         /* case 2: nvme_rdma_req_get */
     800                 :          3 :         rdma_req_get = nvme_rdma_req_get(&rqpair);
     801                 :          3 :         CU_ASSERT(rdma_req_get == &rdma_req);
     802                 :          3 :         CU_ASSERT(rdma_req_get->id == 10086);
     803                 :          3 :         CU_ASSERT(rqpair.free_reqs.tqh_first == NULL);
     804                 :          3 : }
     805                 :            : 
     806                 :            : static void
     807                 :          3 : test_nvme_rdma_req_init(void)
     808                 :            : {
     809                 :          3 :         struct nvme_rdma_qpair rqpair = {};
     810                 :          3 :         struct spdk_nvme_ctrlr ctrlr = {};
     811                 :          3 :         struct spdk_nvmf_cmd cmd = {};
     812                 :          3 :         struct spdk_nvme_rdma_req rdma_req = {};
     813                 :          3 :         struct nvme_request req = {};
     814                 :          3 :         struct nvme_rdma_ut_bdev_io bio = { .iovcnt = NVME_RDMA_MAX_SGL_DESCRIPTORS };
     815                 :          3 :         int rc = 1;
     816                 :            : 
     817                 :          3 :         ctrlr.max_sges = NVME_RDMA_MAX_SGL_DESCRIPTORS;
     818                 :          3 :         ctrlr.cdata.nvmf_specific.msdbd = 16;
     819                 :            : 
     820                 :          3 :         rqpair.mr_map = (struct spdk_rdma_utils_mem_map *)0xdeadbeef;
     821                 :          3 :         rqpair.rdma_qp = (struct spdk_rdma_provider_qp *)0xdeadbeef;
     822                 :          3 :         rqpair.qpair.ctrlr = &ctrlr;
     823                 :          3 :         rqpair.cmds = &cmd;
     824                 :          3 :         cmd.sgl[0].address = 0x1111;
     825                 :          3 :         rdma_req.id = 0;
     826                 :          3 :         req.cmd.opc = SPDK_NVME_DATA_HOST_TO_CONTROLLER;
     827                 :            : 
     828                 :          3 :         req.payload = NVME_PAYLOAD_CONTIG((void *)0xdeadbeef, NULL);
     829                 :            :         /* case 1: req->payload_size == 0, expect: pass. */
     830                 :          3 :         req.payload_size = 0;
     831                 :          3 :         rqpair.qpair.ctrlr->ioccsz_bytes = 1024;
     832                 :          3 :         rqpair.qpair.ctrlr->icdoff = 0;
     833                 :          3 :         rc = nvme_rdma_req_init(&rqpair, &req, &rdma_req);
     834                 :          3 :         CU_ASSERT(rc == 0);
     835                 :          3 :         CU_ASSERT(req.cmd.psdt == SPDK_NVME_PSDT_SGL_MPTR_CONTIG);
     836                 :          3 :         CU_ASSERT(rdma_req.send_sgl[0].length == sizeof(struct spdk_nvme_cmd));
     837                 :          3 :         CU_ASSERT(rdma_req.send_wr.num_sge == 1);
     838                 :          3 :         CU_ASSERT(req.cmd.dptr.sgl1.keyed.type == SPDK_NVME_SGL_TYPE_KEYED_DATA_BLOCK);
     839                 :          3 :         CU_ASSERT(req.cmd.dptr.sgl1.keyed.subtype == SPDK_NVME_SGL_SUBTYPE_ADDRESS);
     840                 :          3 :         CU_ASSERT(req.cmd.dptr.sgl1.keyed.length == 0);
     841                 :          3 :         CU_ASSERT(req.cmd.dptr.sgl1.keyed.key == 0);
     842                 :          3 :         CU_ASSERT(req.cmd.dptr.sgl1.address == 0);
     843                 :            : 
     844                 :            :         /* case 2: payload_type == NVME_PAYLOAD_TYPE_CONTIG, expect: pass. */
     845                 :            :         /* icd_supported is true */
     846                 :          3 :         rdma_req.req = NULL;
     847                 :          3 :         rqpair.qpair.ctrlr->icdoff = 0;
     848                 :          3 :         req.payload_offset = 0;
     849                 :          3 :         req.payload_size = 1024;
     850                 :          3 :         req.payload = NVME_PAYLOAD_CONTIG((void *)0xdeadbeef, NULL);
     851                 :          3 :         rc = nvme_rdma_req_init(&rqpair, &req, &rdma_req);
     852                 :          3 :         CU_ASSERT(rc == 0);
     853                 :          3 :         CU_ASSERT(req.cmd.dptr.sgl1.unkeyed.type == SPDK_NVME_SGL_TYPE_DATA_BLOCK);
     854                 :          3 :         CU_ASSERT(req.cmd.dptr.sgl1.unkeyed.subtype == SPDK_NVME_SGL_SUBTYPE_OFFSET);
     855                 :          3 :         CU_ASSERT(req.cmd.dptr.sgl1.unkeyed.length == req.payload_size);
     856                 :          3 :         CU_ASSERT(req.cmd.dptr.sgl1.address == 0);
     857                 :          3 :         CU_ASSERT(rdma_req.send_sgl[0].length == sizeof(struct spdk_nvme_cmd));
     858                 :          3 :         CU_ASSERT(rdma_req.send_sgl[1].length == req.payload_size);
     859                 :          3 :         CU_ASSERT(rdma_req.send_sgl[1].addr == (uint64_t)req.payload.contig_or_cb_arg);
     860                 :          3 :         CU_ASSERT(rdma_req.send_sgl[1].lkey == RDMA_UT_LKEY);
     861                 :            : 
     862                 :            :         /* icd_supported is false */
     863                 :          3 :         rdma_req.req = NULL;
     864                 :          3 :         rqpair.qpair.ctrlr->icdoff = 1;
     865                 :          3 :         req.payload_offset = 0;
     866                 :          3 :         req.payload_size = 1024;
     867                 :          3 :         req.payload = NVME_PAYLOAD_CONTIG((void *)0xdeadbeef, NULL);
     868                 :          3 :         rc = nvme_rdma_req_init(&rqpair, &req, &rdma_req);
     869                 :          3 :         CU_ASSERT(rc == 0);
     870                 :          3 :         CU_ASSERT(req.cmd.dptr.sgl1.keyed.type == SPDK_NVME_SGL_TYPE_KEYED_DATA_BLOCK);
     871                 :          3 :         CU_ASSERT(req.cmd.dptr.sgl1.keyed.subtype == SPDK_NVME_SGL_SUBTYPE_ADDRESS);
     872                 :          3 :         CU_ASSERT(req.cmd.dptr.sgl1.keyed.length == req.payload_size);
     873                 :          3 :         CU_ASSERT(req.cmd.dptr.sgl1.keyed.key == RDMA_UT_RKEY);
     874                 :          3 :         CU_ASSERT(req.cmd.dptr.sgl1.address == (uint64_t)req.payload.contig_or_cb_arg);
     875                 :          3 :         CU_ASSERT(rdma_req.send_sgl[0].length == sizeof(struct spdk_nvme_cmd));
     876                 :            : 
     877                 :            :         /* case 3: payload_type == NVME_PAYLOAD_TYPE_SGL, expect: pass. */
     878                 :            :         /* icd_supported is true */
     879                 :          3 :         rdma_req.req = NULL;
     880                 :          3 :         rqpair.qpair.ctrlr->icdoff = 0;
     881                 :          3 :         req.payload = NVME_PAYLOAD_SGL(nvme_rdma_ut_reset_sgl, nvme_rdma_ut_next_sge, &bio, NULL);
     882                 :          3 :         req.qpair = &rqpair.qpair;
     883                 :          3 :         bio.iovpos = 0;
     884                 :          3 :         req.payload_offset = 0;
     885                 :          3 :         req.payload_size = 1024;
     886                 :          3 :         bio.iovs[0].iov_base = (void *)0xdeadbeef;
     887                 :          3 :         bio.iovs[0].iov_len = 1024;
     888                 :          3 :         rc = nvme_rdma_req_init(&rqpair, &req, &rdma_req);
     889                 :          3 :         CU_ASSERT(rc == 0);
     890                 :          3 :         CU_ASSERT(bio.iovpos == 1);
     891                 :          3 :         CU_ASSERT(req.cmd.dptr.sgl1.unkeyed.type == SPDK_NVME_SGL_TYPE_DATA_BLOCK);
     892                 :          3 :         CU_ASSERT(req.cmd.dptr.sgl1.unkeyed.subtype == SPDK_NVME_SGL_SUBTYPE_OFFSET);
     893                 :          3 :         CU_ASSERT(req.cmd.dptr.sgl1.unkeyed.length == req.payload_size);
     894                 :          3 :         CU_ASSERT(req.cmd.dptr.sgl1.address == 0);
     895                 :          3 :         CU_ASSERT(rdma_req.send_sgl[0].length == sizeof(struct spdk_nvme_cmd));
     896                 :          3 :         CU_ASSERT(rdma_req.send_sgl[1].length == req.payload_size);
     897                 :          3 :         CU_ASSERT(rdma_req.send_sgl[1].addr == (uint64_t)bio.iovs[0].iov_base);
     898                 :          3 :         CU_ASSERT(rdma_req.send_sgl[1].lkey == RDMA_UT_LKEY);
     899                 :            : 
     900                 :            :         /* icd_supported is false */
     901                 :          3 :         rdma_req.req = NULL;
     902                 :          3 :         rqpair.qpair.ctrlr->icdoff = 1;
     903                 :          3 :         req.payload = NVME_PAYLOAD_SGL(nvme_rdma_ut_reset_sgl, nvme_rdma_ut_next_sge, &bio, NULL);
     904                 :          3 :         req.qpair = &rqpair.qpair;
     905                 :          3 :         bio.iovpos = 0;
     906                 :          3 :         req.payload_offset = 0;
     907                 :          3 :         req.payload_size = 1024;
     908                 :          3 :         bio.iovs[0].iov_base = (void *)0xdeadbeef;
     909                 :          3 :         bio.iovs[0].iov_len = 1024;
     910                 :          3 :         rc = nvme_rdma_req_init(&rqpair, &req, &rdma_req);
     911                 :          3 :         CU_ASSERT(rc == 0);
     912                 :          3 :         CU_ASSERT(bio.iovpos == 1);
     913                 :          3 :         CU_ASSERT(req.cmd.dptr.sgl1.keyed.type == SPDK_NVME_SGL_TYPE_KEYED_DATA_BLOCK);
     914                 :          3 :         CU_ASSERT(req.cmd.dptr.sgl1.keyed.subtype == SPDK_NVME_SGL_SUBTYPE_ADDRESS);
     915                 :          3 :         CU_ASSERT(req.cmd.dptr.sgl1.keyed.length == req.payload_size);
     916                 :          3 :         CU_ASSERT(req.cmd.dptr.sgl1.keyed.key == RDMA_UT_RKEY);
     917                 :          3 :         CU_ASSERT(req.cmd.dptr.sgl1.address == (uint64_t)bio.iovs[0].iov_base);
     918                 :          3 :         CU_ASSERT(rdma_req.send_sgl[0].length == sizeof(struct spdk_nvme_cmd));
     919                 :          3 : }
     920                 :            : 
     921                 :            : static void
     922                 :          3 : test_nvme_rdma_validate_cm_event(void)
     923                 :            : {
     924                 :            :         enum rdma_cm_event_type expected_evt_type;
     925                 :          3 :         struct rdma_cm_event reaped_evt = {};
     926                 :            :         int rc;
     927                 :            : 
     928                 :            :         /* case 1: expected_evt_type == reaped_evt->event, expect: pass */
     929                 :          3 :         expected_evt_type = RDMA_CM_EVENT_ADDR_RESOLVED;
     930                 :          3 :         reaped_evt.event = RDMA_CM_EVENT_ADDR_RESOLVED;
     931                 :            : 
     932                 :          3 :         rc = nvme_rdma_validate_cm_event(expected_evt_type, &reaped_evt);
     933                 :          3 :         CU_ASSERT(rc == 0);
     934                 :            : 
     935                 :            :         /* case 2: expected_evt_type != RDMA_CM_EVENT_ESTABLISHED and is not equal to reaped_evt->event, expect: fail */
     936                 :          3 :         reaped_evt.event = RDMA_CM_EVENT_CONNECT_RESPONSE;
     937                 :            : 
     938                 :          3 :         rc = nvme_rdma_validate_cm_event(expected_evt_type, &reaped_evt);
     939                 :          3 :         CU_ASSERT(rc == -EBADMSG);
     940                 :            : 
     941                 :            :         /* case 3: expected_evt_type == RDMA_CM_EVENT_ESTABLISHED */
     942                 :          3 :         expected_evt_type = RDMA_CM_EVENT_ESTABLISHED;
     943                 :            :         /* reaped_evt->event == RDMA_CM_EVENT_REJECTED and reaped_evt->status == 10, expect: fail */
     944                 :          3 :         reaped_evt.event = RDMA_CM_EVENT_REJECTED;
     945                 :          3 :         reaped_evt.status = 10;
     946                 :            : 
     947                 :          3 :         rc = nvme_rdma_validate_cm_event(expected_evt_type, &reaped_evt);
     948                 :          3 :         CU_ASSERT(rc == -ESTALE);
     949                 :            : 
     950                 :            :         /* reaped_evt->event == RDMA_CM_EVENT_CONNECT_RESPONSE, expect: pass */
     951                 :          3 :         reaped_evt.event = RDMA_CM_EVENT_CONNECT_RESPONSE;
     952                 :            : 
     953                 :          3 :         rc = nvme_rdma_validate_cm_event(expected_evt_type, &reaped_evt);
     954                 :          3 :         CU_ASSERT(rc == 0);
     955                 :          3 : }
     956                 :            : 
     957                 :            : static void
     958                 :          3 : test_nvme_rdma_qpair_init(void)
     959                 :            : {
     960                 :          3 :         struct nvme_rdma_qpair          rqpair = {};
     961                 :          3 :         struct rdma_cm_id               cm_id = {};
     962                 :          3 :         struct ibv_pd                   *pd = (struct ibv_pd *)0xfeedbeef;
     963                 :          3 :         struct spdk_memory_domain       *domain = (struct spdk_memory_domain *)0xf00dfeed;
     964                 :          3 :         struct ibv_qp                   qp = { .pd = pd };
     965                 :          3 :         struct nvme_rdma_ctrlr          rctrlr = {};
     966                 :          3 :         int                             rc = 0;
     967                 :            : 
     968                 :          3 :         rctrlr.ctrlr.trid.trtype = SPDK_NVME_TRANSPORT_RDMA;
     969                 :          3 :         rqpair.cm_id = &cm_id;
     970                 :          3 :         g_nvme_hooks.get_ibv_pd = NULL;
     971                 :          3 :         rqpair.qpair.poll_group = NULL;
     972                 :          3 :         rqpair.qpair.ctrlr = &rctrlr.ctrlr;
     973                 :          3 :         g_spdk_rdma_qp.qp = &qp;
     974                 :          3 :         MOCK_SET(spdk_rdma_utils_get_pd, pd);
     975                 :          3 :         MOCK_SET(spdk_rdma_utils_get_memory_domain, domain);
     976                 :            : 
     977                 :          3 :         rc = nvme_rdma_qpair_init(&rqpair);
     978                 :          3 :         CU_ASSERT(rc == 0);
     979                 :            : 
     980                 :          3 :         CU_ASSERT(rqpair.cm_id->context == &rqpair.qpair);
     981                 :          3 :         CU_ASSERT(rqpair.max_send_sge == NVME_RDMA_DEFAULT_TX_SGE);
     982                 :          3 :         CU_ASSERT(rqpair.max_recv_sge == NVME_RDMA_DEFAULT_RX_SGE);
     983                 :          3 :         CU_ASSERT(rqpair.current_num_sends == 0);
     984                 :          3 :         CU_ASSERT(rqpair.cq == (struct ibv_cq *)0xFEEDBEEF);
     985                 :          3 :         CU_ASSERT(rqpair.memory_domain == domain);
     986                 :            : 
     987   [ -  -  -  + ]:          3 :         MOCK_CLEAR(spdk_rdma_utils_get_pd);
     988   [ -  -  -  + ]:          3 :         MOCK_CLEAR(spdk_rdma_utils_get_memory_domain);
     989                 :          3 : }
     990                 :            : 
     991                 :            : static void
     992                 :          3 : test_nvme_rdma_qpair_submit_request(void)
     993                 :            : {
     994                 :            :         int                             rc;
     995                 :          3 :         struct nvme_rdma_qpair          rqpair = {};
     996                 :          3 :         struct spdk_nvme_ctrlr          ctrlr = {};
     997                 :          3 :         struct nvme_request             req = {};
     998                 :          3 :         struct nvme_rdma_poller         poller = {};
     999                 :          3 :         struct spdk_nvme_rdma_req       *rdma_req = NULL;
    1000                 :            : 
    1001                 :          3 :         req.cmd.opc = SPDK_NVME_DATA_HOST_TO_CONTROLLER;
    1002                 :          3 :         req.payload = NVME_PAYLOAD_CONTIG((void *)0xdeadbeef, NULL);
    1003                 :          3 :         req.payload_size = 0;
    1004                 :          3 :         rqpair.mr_map = (struct spdk_rdma_utils_mem_map *)0xdeadbeef;
    1005                 :          3 :         rqpair.rdma_qp = (struct spdk_rdma_provider_qp *)0xdeadbeef;
    1006                 :          3 :         rqpair.qpair.ctrlr = &ctrlr;
    1007                 :          3 :         rqpair.num_entries = 1;
    1008                 :          3 :         rqpair.qpair.trtype = SPDK_NVME_TRANSPORT_RDMA;
    1009                 :          3 :         rqpair.poller = &poller;
    1010                 :            : 
    1011                 :          3 :         rc = nvme_rdma_create_reqs(&rqpair);
    1012                 :          3 :         CU_ASSERT(rc == 0);
    1013                 :            :         /* Give send_wr.next a non null value */
    1014                 :          3 :         rdma_req = TAILQ_FIRST(&rqpair.free_reqs);
    1015         [ -  + ]:          3 :         SPDK_CU_ASSERT_FATAL(rdma_req != NULL);
    1016                 :          3 :         rdma_req->send_wr.next = (void *)0xdeadbeef;
    1017                 :            : 
    1018                 :          3 :         rc = nvme_rdma_qpair_submit_request(&rqpair.qpair, &req);
    1019                 :          3 :         CU_ASSERT(rc == 0);
    1020                 :          3 :         CU_ASSERT(rqpair.current_num_sends == 1);
    1021                 :          3 :         CU_ASSERT(rdma_req->send_wr.next == NULL);
    1022         [ -  + ]:          3 :         TAILQ_REMOVE(&rqpair.outstanding_reqs, rdma_req, link);
    1023                 :          3 :         CU_ASSERT(TAILQ_EMPTY(&rqpair.outstanding_reqs));
    1024                 :            : 
    1025                 :            :         /* No request available */
    1026                 :          3 :         rc = nvme_rdma_qpair_submit_request(&rqpair.qpair, &req);
    1027                 :          3 :         CU_ASSERT(rc == -EAGAIN);
    1028                 :          3 :         CU_ASSERT(rqpair.poller->stats.queued_requests == 1);
    1029                 :            : 
    1030                 :          3 :         nvme_rdma_free_reqs(&rqpair);
    1031                 :          3 : }
    1032                 :            : 
    1033                 :            : static void
    1034                 :          3 : test_rdma_ctrlr_get_memory_domains(void)
    1035                 :            : {
    1036                 :          3 :         struct nvme_rdma_ctrlr rctrlr = {};
    1037                 :          3 :         struct nvme_rdma_qpair rqpair = {};
    1038                 :          3 :         struct spdk_memory_domain *domain = (struct spdk_memory_domain *)0xbaadbeef;
    1039                 :          3 :         struct spdk_memory_domain *domains[1] = {NULL};
    1040                 :            : 
    1041                 :          3 :         rqpair.memory_domain = domain;
    1042                 :          3 :         rqpair.qpair.trtype = SPDK_NVME_TRANSPORT_RDMA;
    1043                 :          3 :         rctrlr.ctrlr.adminq = &rqpair.qpair;
    1044                 :            : 
    1045                 :            :         /* Test 1, input domains pointer is NULL */
    1046                 :          3 :         CU_ASSERT(nvme_rdma_ctrlr_get_memory_domains(&rctrlr.ctrlr, NULL, 1) == 1);
    1047                 :            : 
    1048                 :            :         /* Test 2, input array_size is 0 */
    1049                 :          3 :         CU_ASSERT(nvme_rdma_ctrlr_get_memory_domains(&rctrlr.ctrlr, domains, 0) == 1);
    1050                 :          3 :         CU_ASSERT(domains[0] == NULL);
    1051                 :            : 
    1052                 :            :         /* Test 3, both input domains pointer and array_size are NULL/0 */
    1053                 :          3 :         CU_ASSERT(nvme_rdma_ctrlr_get_memory_domains(&rctrlr.ctrlr, NULL, 0) == 1);
    1054                 :            : 
    1055                 :            :         /* Test 2, input parameters are valid */
    1056                 :          3 :         CU_ASSERT(nvme_rdma_ctrlr_get_memory_domains(&rctrlr.ctrlr, domains, 1) == 1);
    1057                 :          3 :         CU_ASSERT(domains[0] == domain);
    1058                 :          3 : }
    1059                 :            : 
    1060                 :            : static void
    1061                 :          3 : test_rdma_get_memory_translation(void)
    1062                 :            : {
    1063                 :          3 :         struct ibv_qp qp = {.pd = (struct ibv_pd *) 0xfeedbeef};
    1064                 :          3 :         struct spdk_rdma_provider_qp rdma_qp = {.qp = &qp};
    1065                 :          3 :         struct nvme_rdma_qpair rqpair = {.rdma_qp = &rdma_qp};
    1066                 :          3 :         struct spdk_nvme_ns_cmd_ext_io_opts io_opts = {
    1067                 :            :                 .memory_domain = (struct spdk_memory_domain *) 0xdeaddead
    1068                 :            :         };
    1069                 :          3 :         struct nvme_request req = {.payload = {.opts = &io_opts}};
    1070                 :          3 :         struct nvme_rdma_memory_translation_ctx ctx = {
    1071                 :            :                 .addr = (void *) 0xBAADF00D,
    1072                 :            :                 .length = 0x100
    1073                 :            :         };
    1074                 :            :         int rc;
    1075                 :            : 
    1076                 :          3 :         rqpair.memory_domain = (struct spdk_memory_domain *) 0xfeedbeef;
    1077                 :            : 
    1078                 :            :         /* case 1, using extended IO opts with DMA device.
    1079                 :            :          * Test 1 - spdk_dma_translate_data error, expect fail */
    1080                 :          3 :         MOCK_SET(spdk_memory_domain_translate_data, -1);
    1081                 :          3 :         rc = nvme_rdma_get_memory_translation(&req, &rqpair, &ctx);
    1082                 :          3 :         CU_ASSERT(rc != 0);
    1083   [ -  -  -  + ]:          3 :         MOCK_CLEAR(spdk_memory_domain_translate_data);
    1084                 :            : 
    1085                 :            :         /* Test 2 - expect pass */
    1086                 :          3 :         g_memory_translation_translation.iov_count = 1;
    1087                 :          3 :         g_memory_translation_translation.iov.iov_base = ctx.addr + 1;
    1088                 :          3 :         g_memory_translation_translation.iov.iov_len = ctx.length;
    1089                 :          3 :         g_memory_translation_translation.rdma.lkey = 123;
    1090                 :          3 :         g_memory_translation_translation.rdma.rkey = 321;
    1091                 :            : 
    1092                 :          3 :         rc = nvme_rdma_get_memory_translation(&req, &rqpair, &ctx);
    1093                 :          3 :         CU_ASSERT(rc == 0);
    1094                 :          3 :         CU_ASSERT(ctx.lkey == g_memory_translation_translation.rdma.lkey);
    1095                 :          3 :         CU_ASSERT(ctx.rkey == g_memory_translation_translation.rdma.rkey);
    1096                 :          3 :         CU_ASSERT(ctx.addr == g_memory_translation_translation.iov.iov_base);
    1097                 :          3 :         CU_ASSERT(ctx.length == g_memory_translation_translation.iov.iov_len);
    1098                 :            : 
    1099                 :            :         /* case 2, using rdma translation
    1100                 :            :          * Test 1 - spdk_rdma_get_translation error, expect fail */
    1101                 :          3 :         req.payload.opts = NULL;
    1102                 :          3 :         MOCK_SET(spdk_rdma_utils_get_translation, -1);
    1103                 :          3 :         rc = nvme_rdma_get_memory_translation(&req, &rqpair, &ctx);
    1104                 :          3 :         CU_ASSERT(rc != 0);
    1105   [ -  -  -  + ]:          3 :         MOCK_CLEAR(spdk_rdma_utils_get_translation);
    1106                 :            : 
    1107                 :            :         /* Test 2 - expect pass */
    1108                 :          3 :         rc = nvme_rdma_get_memory_translation(&req, &rqpair, &ctx);
    1109                 :          3 :         CU_ASSERT(rc == 0);
    1110                 :          3 :         CU_ASSERT(ctx.lkey == RDMA_UT_LKEY);
    1111                 :          3 :         CU_ASSERT(ctx.rkey == RDMA_UT_RKEY);
    1112                 :          3 : }
    1113                 :            : 
    1114                 :            : static void
    1115                 :          3 : test_get_rdma_qpair_from_wc(void)
    1116                 :            : {
    1117                 :          3 :         const uint32_t test_qp_num = 123;
    1118                 :          3 :         struct nvme_rdma_poll_group     group = {};
    1119                 :          3 :         struct nvme_rdma_qpair rqpair = {};
    1120                 :          3 :         struct spdk_rdma_provider_qp rdma_qp = {};
    1121                 :          3 :         struct ibv_qp qp = { .qp_num = test_qp_num };
    1122                 :          3 :         struct ibv_wc wc = { .qp_num = test_qp_num };
    1123                 :            : 
    1124                 :          3 :         STAILQ_INIT(&group.group.disconnected_qpairs);
    1125                 :          3 :         STAILQ_INIT(&group.group.connected_qpairs);
    1126                 :          3 :         rqpair.qpair.trtype = SPDK_NVME_TRANSPORT_RDMA;
    1127                 :            : 
    1128                 :            :         /* Test 1 - Simulate case when nvme_rdma_qpair is disconnected but still in one of lists.
    1129                 :            :          * get_rdma_qpair_from_wc must return NULL */
    1130         [ +  - ]:          3 :         STAILQ_INSERT_HEAD(&group.group.disconnected_qpairs, &rqpair.qpair, poll_group_stailq);
    1131                 :          3 :         CU_ASSERT(get_rdma_qpair_from_wc(&group, &wc) == NULL);
    1132         [ +  - ]:          3 :         STAILQ_REMOVE_HEAD(&group.group.disconnected_qpairs, poll_group_stailq);
    1133                 :            : 
    1134         [ +  - ]:          3 :         STAILQ_INSERT_HEAD(&group.group.connected_qpairs, &rqpair.qpair, poll_group_stailq);
    1135                 :          3 :         CU_ASSERT(get_rdma_qpair_from_wc(&group, &wc) == NULL);
    1136         [ +  - ]:          3 :         STAILQ_REMOVE_HEAD(&group.group.connected_qpairs, poll_group_stailq);
    1137                 :            : 
    1138                 :            :         /* Test 2 - nvme_rdma_qpair with valid rdma_qp/ibv_qp and qp_num */
    1139                 :          3 :         rdma_qp.qp = &qp;
    1140                 :          3 :         rqpair.rdma_qp = &rdma_qp;
    1141                 :            : 
    1142         [ +  - ]:          3 :         STAILQ_INSERT_HEAD(&group.group.disconnected_qpairs, &rqpair.qpair, poll_group_stailq);
    1143                 :          3 :         CU_ASSERT(get_rdma_qpair_from_wc(&group, &wc) == &rqpair);
    1144         [ +  - ]:          3 :         STAILQ_REMOVE_HEAD(&group.group.disconnected_qpairs, poll_group_stailq);
    1145                 :            : 
    1146         [ +  - ]:          3 :         STAILQ_INSERT_HEAD(&group.group.connected_qpairs, &rqpair.qpair, poll_group_stailq);
    1147                 :          3 :         CU_ASSERT(get_rdma_qpair_from_wc(&group, &wc) == &rqpair);
    1148         [ +  - ]:          3 :         STAILQ_REMOVE_HEAD(&group.group.connected_qpairs, poll_group_stailq);
    1149                 :          3 : }
    1150                 :            : 
    1151                 :            : static void
    1152                 :          3 : test_nvme_rdma_ctrlr_get_max_sges(void)
    1153                 :            : {
    1154                 :          3 :         struct nvme_rdma_ctrlr  rctrlr = {};
    1155                 :            : 
    1156                 :          3 :         rctrlr.ctrlr.trid.trtype = SPDK_NVME_TRANSPORT_RDMA;
    1157                 :          3 :         rctrlr.max_sge = NVME_RDMA_MAX_SGL_DESCRIPTORS;
    1158                 :          3 :         rctrlr.ctrlr.cdata.nvmf_specific.msdbd = 16;
    1159                 :          3 :         rctrlr.ctrlr.cdata.nvmf_specific.ioccsz = 4096;
    1160                 :          3 :         CU_ASSERT(nvme_rdma_ctrlr_get_max_sges(&rctrlr.ctrlr) == 16);
    1161                 :            : 
    1162                 :          3 :         rctrlr.ctrlr.cdata.nvmf_specific.msdbd = 32;
    1163                 :          3 :         rctrlr.ctrlr.cdata.nvmf_specific.ioccsz = 4096;
    1164                 :          3 :         CU_ASSERT(nvme_rdma_ctrlr_get_max_sges(&rctrlr.ctrlr) == 16);
    1165                 :            : 
    1166                 :          3 :         rctrlr.ctrlr.cdata.nvmf_specific.msdbd = 8;
    1167                 :          3 :         rctrlr.ctrlr.cdata.nvmf_specific.ioccsz = 4096;
    1168                 :          3 :         CU_ASSERT(nvme_rdma_ctrlr_get_max_sges(&rctrlr.ctrlr) == 8);
    1169                 :            : 
    1170                 :          3 :         rctrlr.ctrlr.cdata.nvmf_specific.msdbd = 16;
    1171                 :          3 :         rctrlr.ctrlr.cdata.nvmf_specific.ioccsz = 4;
    1172                 :          3 :         CU_ASSERT(nvme_rdma_ctrlr_get_max_sges(&rctrlr.ctrlr) == 1);
    1173                 :            : 
    1174                 :          3 :         rctrlr.ctrlr.cdata.nvmf_specific.msdbd = 16;
    1175                 :          3 :         rctrlr.ctrlr.cdata.nvmf_specific.ioccsz = 6;
    1176                 :          3 :         CU_ASSERT(nvme_rdma_ctrlr_get_max_sges(&rctrlr.ctrlr) == 2);
    1177                 :          3 : }
    1178                 :            : 
    1179                 :            : static void
    1180                 :          3 : test_nvme_rdma_poll_group_get_stats(void)
    1181                 :            : {
    1182                 :          3 :         int rc = -1;
    1183                 :          3 :         struct spdk_nvme_transport_poll_group_stat *tpointer = NULL;
    1184                 :          3 :         struct nvme_rdma_poll_group tgroup = {};
    1185                 :          3 :         struct ibv_device dev1, dev2 = {};
    1186                 :          3 :         struct ibv_context contexts1, contexts2 = {};
    1187                 :          3 :         struct nvme_rdma_poller *tpoller1 = NULL;
    1188                 :          3 :         struct nvme_rdma_poller *tpoller2 = NULL;
    1189                 :            : 
    1190                 :          3 :         memcpy(dev1.name, "/dev/test1", sizeof("/dev/test1"));
    1191                 :          3 :         memcpy(dev2.name, "/dev/test2", sizeof("/dev/test2"));
    1192                 :          3 :         contexts1.device = &dev1;
    1193                 :          3 :         contexts2.device = &dev2;
    1194                 :            : 
    1195                 :            :         /* Initialization */
    1196                 :          3 :         STAILQ_INIT(&tgroup.pollers);
    1197                 :          3 :         tpoller2 = nvme_rdma_poller_create(&tgroup, &contexts1);
    1198         [ -  + ]:          3 :         SPDK_CU_ASSERT_FATAL(tpoller2 != NULL);
    1199                 :          3 :         CU_ASSERT(tgroup.num_pollers == 1);
    1200                 :            : 
    1201                 :          3 :         tpoller1 = nvme_rdma_poller_create(&tgroup, &contexts2);
    1202         [ -  + ]:          3 :         SPDK_CU_ASSERT_FATAL(tpoller1 != NULL);
    1203                 :          3 :         CU_ASSERT(tgroup.num_pollers == 2);
    1204                 :          3 :         CU_ASSERT(&tgroup.pollers != NULL);
    1205                 :            : 
    1206                 :          3 :         CU_ASSERT(tpoller1->device == &contexts2);
    1207                 :          3 :         CU_ASSERT(tpoller2->device == &contexts1);
    1208         [ -  + ]:          3 :         CU_ASSERT(strcmp(tpoller1->device->device->name, "/dev/test2") == 0);
    1209         [ -  + ]:          3 :         CU_ASSERT(strcmp(tpoller2->device->device->name, "/dev/test1") == 0);
    1210                 :          3 :         CU_ASSERT(tpoller1->current_num_wc == DEFAULT_NVME_RDMA_CQ_SIZE);
    1211                 :          3 :         CU_ASSERT(tpoller2->current_num_wc == DEFAULT_NVME_RDMA_CQ_SIZE);
    1212                 :          3 :         CU_ASSERT(tpoller1->required_num_wc == 0);
    1213                 :          3 :         CU_ASSERT(tpoller2->required_num_wc == 0);
    1214                 :            : 
    1215                 :            :         /* Test1: Invalid stats */
    1216                 :          3 :         rc = nvme_rdma_poll_group_get_stats(NULL, &tpointer);
    1217                 :          3 :         CU_ASSERT(rc == -EINVAL);
    1218                 :            : 
    1219                 :            :         /* Test2: Invalid group pointer */
    1220                 :          3 :         rc = nvme_rdma_poll_group_get_stats(&tgroup.group, NULL);
    1221                 :          3 :         CU_ASSERT(rc == -EINVAL);
    1222                 :            : 
    1223                 :            :         /* Test3: Success member variables should be correct */
    1224                 :          3 :         tpoller1->stats.polls = 111;
    1225                 :          3 :         tpoller1->stats.idle_polls = 112;
    1226                 :          3 :         tpoller1->stats.completions = 113;
    1227                 :          3 :         tpoller1->stats.queued_requests = 114;
    1228                 :          3 :         tpoller1->stats.rdma_stats.send.num_submitted_wrs = 121;
    1229                 :          3 :         tpoller1->stats.rdma_stats.send.doorbell_updates = 122;
    1230                 :          3 :         tpoller1->stats.rdma_stats.recv.num_submitted_wrs = 131;
    1231                 :          3 :         tpoller1->stats.rdma_stats.recv.doorbell_updates = 132;
    1232                 :          3 :         tpoller2->stats.polls = 211;
    1233                 :          3 :         tpoller2->stats.idle_polls = 212;
    1234                 :          3 :         tpoller2->stats.completions = 213;
    1235                 :          3 :         tpoller2->stats.queued_requests = 214;
    1236                 :          3 :         tpoller2->stats.rdma_stats.send.num_submitted_wrs = 221;
    1237                 :          3 :         tpoller2->stats.rdma_stats.send.doorbell_updates = 222;
    1238                 :          3 :         tpoller2->stats.rdma_stats.recv.num_submitted_wrs = 231;
    1239                 :          3 :         tpoller2->stats.rdma_stats.recv.doorbell_updates = 232;
    1240                 :            : 
    1241                 :          3 :         rc = nvme_rdma_poll_group_get_stats(&tgroup.group, &tpointer);
    1242                 :          3 :         CU_ASSERT(rc == 0);
    1243                 :          3 :         CU_ASSERT(tpointer != NULL);
    1244                 :          3 :         CU_ASSERT(tpointer->trtype == SPDK_NVME_TRANSPORT_RDMA);
    1245                 :          3 :         CU_ASSERT(tpointer->rdma.num_devices == tgroup.num_pollers);
    1246                 :          3 :         CU_ASSERT(tpointer->rdma.device_stats != NULL);
    1247                 :            : 
    1248         [ -  + ]:          3 :         CU_ASSERT(strcmp(tpointer->rdma.device_stats[0].name, "/dev/test2") == 0);
    1249                 :          3 :         CU_ASSERT(tpointer->rdma.device_stats[0].polls == 111);
    1250                 :          3 :         CU_ASSERT(tpointer->rdma.device_stats[0].idle_polls == 112);
    1251                 :          3 :         CU_ASSERT(tpointer->rdma.device_stats[0].completions == 113);
    1252                 :          3 :         CU_ASSERT(tpointer->rdma.device_stats[0].queued_requests == 114);
    1253                 :          3 :         CU_ASSERT(tpointer->rdma.device_stats[0].total_send_wrs == 121);
    1254                 :          3 :         CU_ASSERT(tpointer->rdma.device_stats[0].send_doorbell_updates == 122);
    1255                 :          3 :         CU_ASSERT(tpointer->rdma.device_stats[0].total_recv_wrs == 131);
    1256                 :          3 :         CU_ASSERT(tpointer->rdma.device_stats[0].recv_doorbell_updates == 132);
    1257                 :            : 
    1258         [ -  + ]:          3 :         CU_ASSERT(strcmp(tpointer->rdma.device_stats[1].name, "/dev/test1") == 0);
    1259                 :          3 :         CU_ASSERT(tpointer->rdma.device_stats[1].polls == 211);
    1260                 :          3 :         CU_ASSERT(tpointer->rdma.device_stats[1].idle_polls == 212);
    1261                 :          3 :         CU_ASSERT(tpointer->rdma.device_stats[1].completions == 213);
    1262                 :          3 :         CU_ASSERT(tpointer->rdma.device_stats[1].queued_requests == 214);
    1263                 :          3 :         CU_ASSERT(tpointer->rdma.device_stats[1].total_send_wrs == 221);
    1264                 :          3 :         CU_ASSERT(tpointer->rdma.device_stats[1].send_doorbell_updates == 222);
    1265                 :          3 :         CU_ASSERT(tpointer->rdma.device_stats[1].total_recv_wrs == 231);
    1266                 :          3 :         CU_ASSERT(tpointer->rdma.device_stats[1].recv_doorbell_updates == 232);
    1267                 :            : 
    1268                 :          3 :         nvme_rdma_poll_group_free_stats(&tgroup.group, tpointer);
    1269                 :          3 :         nvme_rdma_poll_group_free_pollers(&tgroup);
    1270                 :          3 : }
    1271                 :            : 
    1272                 :            : static void
    1273                 :          3 : test_nvme_rdma_qpair_set_poller(void)
    1274                 :            : {
    1275                 :          3 :         int rc = -1;
    1276                 :            :         struct nvme_rdma_poll_group *group;
    1277                 :            :         struct spdk_nvme_transport_poll_group *tgroup;
    1278                 :            :         struct nvme_rdma_poller *poller;
    1279                 :          3 :         struct nvme_rdma_qpair rqpair = {};
    1280                 :          3 :         struct rdma_cm_id cm_id = {};
    1281                 :            : 
    1282                 :            :         /* Case1: Test function nvme_rdma_poll_group_create */
    1283                 :            :         /* Test1: Function nvme_rdma_poll_group_create success */
    1284                 :          3 :         tgroup = nvme_rdma_poll_group_create();
    1285         [ -  + ]:          3 :         SPDK_CU_ASSERT_FATAL(tgroup != NULL);
    1286                 :            : 
    1287                 :          3 :         group = nvme_rdma_poll_group(tgroup);
    1288                 :          3 :         CU_ASSERT(group != NULL);
    1289                 :          3 :         CU_ASSERT(STAILQ_EMPTY(&group->pollers));
    1290                 :            : 
    1291                 :            :         /* Case2: Test function nvme_rdma_qpair_set_poller */
    1292                 :          3 :         rqpair.qpair.poll_group = tgroup;
    1293                 :          3 :         rqpair.qpair.trtype = SPDK_NVME_TRANSPORT_RDMA;
    1294                 :          3 :         rqpair.cm_id = &cm_id;
    1295                 :            : 
    1296                 :            :         /* Test1: Function ibv_create_cq failed */
    1297                 :          3 :         cm_id.verbs = (void *)0xFEEDBEEF;
    1298                 :          3 :         MOCK_SET(ibv_create_cq, NULL);
    1299                 :            : 
    1300                 :          3 :         rc = nvme_rdma_qpair_set_poller(&rqpair.qpair);
    1301                 :          3 :         CU_ASSERT(rc == -EINVAL);
    1302                 :          3 :         CU_ASSERT(rqpair.cq == NULL);
    1303                 :          3 :         CU_ASSERT(STAILQ_EMPTY(&group->pollers));
    1304                 :            : 
    1305   [ -  -  -  + ]:          3 :         MOCK_CLEAR(ibv_create_cq);
    1306                 :            : 
    1307                 :            :         /* Test2: Unable to find a cq for qpair on poll group */
    1308                 :          3 :         cm_id.verbs = NULL;
    1309                 :            : 
    1310                 :          3 :         rc = nvme_rdma_qpair_set_poller(&rqpair.qpair);
    1311                 :          3 :         CU_ASSERT(rc == -EINVAL);
    1312                 :          3 :         CU_ASSERT(rqpair.cq == NULL);
    1313                 :          3 :         CU_ASSERT(STAILQ_EMPTY(&group->pollers));
    1314                 :            : 
    1315                 :            :         /* Test3: Match cq success, current_num_wc is enough */
    1316                 :          3 :         MOCK_SET(ibv_create_cq, (struct ibv_cq *)0xFEEDBEEF);
    1317                 :            : 
    1318                 :          3 :         cm_id.verbs = (void *)0xFEEDBEEF;
    1319                 :          3 :         rqpair.num_entries = 0;
    1320                 :            : 
    1321                 :          3 :         rc = nvme_rdma_qpair_set_poller(&rqpair.qpair);
    1322                 :          3 :         CU_ASSERT(rc == 0);
    1323                 :          3 :         CU_ASSERT(rqpair.cq == (void *)0xFEEDBEEF);
    1324                 :            : 
    1325                 :          3 :         poller = STAILQ_FIRST(&group->pollers);
    1326         [ -  + ]:          3 :         SPDK_CU_ASSERT_FATAL(poller != NULL);
    1327                 :          3 :         CU_ASSERT(STAILQ_NEXT(poller, link) == NULL);
    1328                 :          3 :         CU_ASSERT(poller->device == (struct ibv_context *)0xFEEDBEEF);
    1329                 :          3 :         CU_ASSERT(poller->current_num_wc == DEFAULT_NVME_RDMA_CQ_SIZE);
    1330                 :          3 :         CU_ASSERT(poller->required_num_wc == 0);
    1331                 :          3 :         CU_ASSERT(rqpair.poller == poller);
    1332                 :            : 
    1333                 :          3 :         rqpair.qpair.poll_group_tailq_head = &tgroup->disconnected_qpairs;
    1334                 :            : 
    1335                 :          3 :         nvme_rdma_poll_group_put_poller(group, rqpair.poller);
    1336                 :          3 :         CU_ASSERT(STAILQ_EMPTY(&group->pollers));
    1337                 :            : 
    1338                 :          3 :         rqpair.qpair.poll_group_tailq_head = &tgroup->connected_qpairs;
    1339                 :            : 
    1340                 :            :         /* Test4: Match cq success, function ibv_resize_cq failed */
    1341                 :          3 :         rqpair.cq = NULL;
    1342                 :          3 :         rqpair.num_entries = DEFAULT_NVME_RDMA_CQ_SIZE - 1;
    1343                 :          3 :         MOCK_SET(ibv_resize_cq, -1);
    1344                 :            : 
    1345                 :          3 :         rc = nvme_rdma_qpair_set_poller(&rqpair.qpair);
    1346                 :          3 :         CU_ASSERT(rc == -EPROTO);
    1347                 :          3 :         CU_ASSERT(STAILQ_EMPTY(&group->pollers));
    1348                 :            : 
    1349                 :            :         /* Test5: Current_num_wc is not enough, resize success */
    1350                 :          3 :         MOCK_SET(ibv_resize_cq, 0);
    1351                 :            : 
    1352                 :          3 :         rc = nvme_rdma_qpair_set_poller(&rqpair.qpair);
    1353                 :          3 :         CU_ASSERT(rc == 0);
    1354                 :            : 
    1355                 :          3 :         poller = STAILQ_FIRST(&group->pollers);
    1356         [ -  + ]:          3 :         SPDK_CU_ASSERT_FATAL(poller != NULL);
    1357                 :          3 :         CU_ASSERT(poller->current_num_wc == DEFAULT_NVME_RDMA_CQ_SIZE * 2);
    1358                 :          3 :         CU_ASSERT(poller->required_num_wc == (DEFAULT_NVME_RDMA_CQ_SIZE - 1) * 2);
    1359                 :          3 :         CU_ASSERT(rqpair.cq == poller->cq);
    1360                 :          3 :         CU_ASSERT(rqpair.poller == poller);
    1361                 :            : 
    1362                 :          3 :         rqpair.qpair.poll_group_tailq_head = &tgroup->disconnected_qpairs;
    1363                 :            : 
    1364                 :          3 :         nvme_rdma_poll_group_put_poller(group, rqpair.poller);
    1365                 :          3 :         CU_ASSERT(STAILQ_EMPTY(&group->pollers));
    1366                 :            : 
    1367                 :          3 :         rc = nvme_rdma_poll_group_destroy(tgroup);
    1368                 :          3 :         CU_ASSERT(rc == 0);
    1369                 :          3 : }
    1370                 :            : 
    1371                 :            : int
    1372                 :          3 : main(int argc, char **argv)
    1373                 :            : {
    1374                 :          3 :         CU_pSuite       suite = NULL;
    1375                 :            :         unsigned int    num_failures;
    1376                 :            : 
    1377                 :          3 :         CU_initialize_registry();
    1378                 :            : 
    1379                 :          3 :         suite = CU_add_suite("nvme_rdma", NULL, NULL);
    1380                 :          3 :         CU_ADD_TEST(suite, test_nvme_rdma_build_sgl_request);
    1381                 :          3 :         CU_ADD_TEST(suite, test_nvme_rdma_build_sgl_inline_request);
    1382                 :          3 :         CU_ADD_TEST(suite, test_nvme_rdma_build_contig_request);
    1383                 :          3 :         CU_ADD_TEST(suite, test_nvme_rdma_build_contig_inline_request);
    1384                 :          3 :         CU_ADD_TEST(suite, test_nvme_rdma_create_reqs);
    1385                 :          3 :         CU_ADD_TEST(suite, test_nvme_rdma_create_rsps);
    1386                 :          3 :         CU_ADD_TEST(suite, test_nvme_rdma_ctrlr_create_qpair);
    1387                 :          3 :         CU_ADD_TEST(suite, test_nvme_rdma_poller_create);
    1388                 :          3 :         CU_ADD_TEST(suite, test_nvme_rdma_qpair_process_cm_event);
    1389                 :          3 :         CU_ADD_TEST(suite, test_nvme_rdma_ctrlr_construct);
    1390                 :          3 :         CU_ADD_TEST(suite, test_nvme_rdma_req_put_and_get);
    1391                 :          3 :         CU_ADD_TEST(suite, test_nvme_rdma_req_init);
    1392                 :          3 :         CU_ADD_TEST(suite, test_nvme_rdma_validate_cm_event);
    1393                 :          3 :         CU_ADD_TEST(suite, test_nvme_rdma_qpair_init);
    1394                 :          3 :         CU_ADD_TEST(suite, test_nvme_rdma_qpair_submit_request);
    1395                 :          3 :         CU_ADD_TEST(suite, test_rdma_ctrlr_get_memory_domains);
    1396                 :          3 :         CU_ADD_TEST(suite, test_rdma_get_memory_translation);
    1397                 :          3 :         CU_ADD_TEST(suite, test_get_rdma_qpair_from_wc);
    1398                 :          3 :         CU_ADD_TEST(suite, test_nvme_rdma_ctrlr_get_max_sges);
    1399                 :          3 :         CU_ADD_TEST(suite, test_nvme_rdma_poll_group_get_stats);
    1400                 :          3 :         CU_ADD_TEST(suite, test_nvme_rdma_qpair_set_poller);
    1401                 :            : 
    1402                 :          3 :         num_failures = spdk_ut_run_tests(argc, argv, NULL);
    1403                 :          3 :         CU_cleanup_registry();
    1404                 :          3 :         return num_failures;
    1405                 :            : }

Generated by: LCOV version 1.14