LCOV - code coverage report
Current view: top level - spdk/test/unit/lib/nvme/nvme_poll_group.c - nvme_poll_group_ut.c (source / functions) Hit Total Coverage
Test: Combined Lines: 284 325 87.4 %
Date: 2024-11-17 00:42:00 Functions: 18 21 85.7 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 665 1942 34.2 %

           Branch data     Line data    Source code
       1                 :            : /*   SPDX-License-Identifier: BSD-3-Clause
       2                 :            :  *   Copyright (C) 2020 Intel Corporation.
       3                 :            :  *   All rights reserved.
       4                 :            :  *   Copyright (c) 2021 Mellanox Technologies LTD. All rights reserved.
       5                 :            :  */
       6                 :            : 
       7                 :            : #include "spdk_internal/cunit.h"
       8                 :            : 
       9                 :            : #include "nvme/nvme_poll_group.c"
      10                 :            : #include "common/lib/test_env.c"
      11                 :            : 
      12                 :          6 : SPDK_LOG_REGISTER_COMPONENT(nvme)
      13                 :            : 
      14                 :            : struct spdk_nvme_transport {
      15                 :            :         const char                              name[32];
      16                 :            :         TAILQ_ENTRY(spdk_nvme_transport)        link;
      17                 :            : };
      18                 :            : 
      19                 :            : struct spdk_nvme_transport t1 = {
      20                 :            :         .name = "transport1",
      21                 :            : };
      22                 :            : 
      23                 :            : struct spdk_nvme_transport t2 = {
      24                 :            :         .name = "transport2",
      25                 :            : };
      26                 :            : 
      27                 :            : struct spdk_nvme_transport t3 = {
      28                 :            :         .name = "transport3",
      29                 :            : };
      30                 :            : 
      31                 :            : struct spdk_nvme_transport t4 = {
      32                 :            :         .name = "transport4",
      33                 :            : };
      34                 :            : 
      35                 :            : int64_t g_process_completions_return_value = 0;
      36                 :            : int g_destroy_return_value = 0;
      37                 :            : 
      38                 :            : TAILQ_HEAD(nvme_transport_list, spdk_nvme_transport) g_spdk_nvme_transports =
      39                 :            :         TAILQ_HEAD_INITIALIZER(g_spdk_nvme_transports);
      40                 :            : 
      41                 :          0 : DEFINE_STUB(nvme_transport_qpair_get_optimal_poll_group,
      42                 :            :             struct spdk_nvme_transport_poll_group *,
      43                 :            :             (const struct spdk_nvme_transport *transport,
      44                 :            :              struct spdk_nvme_qpair *qpair),
      45                 :            :             NULL);
      46                 :         36 : DEFINE_STUB(nvme_transport_get_trtype,
      47                 :            :             enum spdk_nvme_transport_type,
      48                 :            :             (const struct spdk_nvme_transport *transport),
      49                 :            :             SPDK_NVME_TRANSPORT_PCIE);
      50                 :            : 
      51                 :            : int
      52                 :         18 : nvme_transport_poll_group_get_stats(struct spdk_nvme_transport_poll_group *tgroup,
      53                 :            :                                     struct spdk_nvme_transport_poll_group_stat **stats)
      54                 :            : {
      55         [ +  - ]:         18 :         *stats = calloc(1, sizeof(**stats));
      56   [ +  +  +  -  :         18 :         SPDK_CU_ASSERT_FATAL(*stats != NULL);
                   #  # ]
      57   [ +  -  +  -  :         18 :         (*stats)->trtype = nvme_transport_get_trtype(NULL);
                   +  - ]
      58                 :            : 
      59                 :         18 :         return 0;
      60                 :            : }
      61                 :            : 
      62                 :            : void
      63                 :         18 : nvme_transport_poll_group_free_stats(struct spdk_nvme_transport_poll_group *tgroup,
      64                 :            :                                      struct spdk_nvme_transport_poll_group_stat *stats)
      65                 :            : {
      66                 :         18 :         free(stats);
      67                 :         18 : }
      68                 :            : 
      69                 :            : static void
      70                 :          0 : unit_test_disconnected_qpair_cb(struct spdk_nvme_qpair *qpair, void *poll_group_ctx)
      71                 :            : {
      72                 :            : 
      73                 :          0 : }
      74                 :            : 
      75                 :            : const struct spdk_nvme_transport *
      76                 :         42 : nvme_get_first_transport(void)
      77                 :            : {
      78                 :         42 :         return TAILQ_FIRST(&g_spdk_nvme_transports);
      79                 :            : }
      80                 :            : 
      81                 :            : const struct spdk_nvme_transport *
      82                 :         60 : nvme_get_next_transport(const struct spdk_nvme_transport *transport)
      83                 :            : {
      84   [ +  -  +  -  :         60 :         return TAILQ_NEXT(transport, link);
                   +  - ]
      85                 :            : }
      86                 :            : 
      87                 :            : int
      88                 :          0 : nvme_transport_poll_group_disconnect_qpair(struct spdk_nvme_qpair *qpair)
      89                 :            : {
      90                 :          0 :         struct spdk_nvme_transport_poll_group *tgroup;
      91                 :          0 :         struct spdk_nvme_qpair *iter_qp, *tmp_iter_qp;
      92                 :            : 
      93   [ #  #  #  # ]:          0 :         tgroup = qpair->poll_group;
      94                 :            : 
      95   [ #  #  #  #  :          0 :         STAILQ_FOREACH_SAFE(iter_qp, &tgroup->connected_qpairs, poll_group_stailq, tmp_iter_qp) {
          #  #  #  #  #  
          #  #  #  #  #  
                   #  # ]
      96         [ #  # ]:          0 :                 if (qpair == iter_qp) {
      97   [ #  #  #  #  :          0 :                         STAILQ_REMOVE(&tgroup->connected_qpairs, qpair, spdk_nvme_qpair, poll_group_stailq);
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
             #  #  #  # ]
      98   [ #  #  #  #  :          0 :                         STAILQ_INSERT_TAIL(&tgroup->disconnected_qpairs, qpair, poll_group_stailq);
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
             #  #  #  #  
                      # ]
      99                 :          0 :                         return 0;
     100                 :            :                 }
     101                 :          0 :         }
     102                 :            : 
     103   [ #  #  #  #  :          0 :         STAILQ_FOREACH(iter_qp, &tgroup->disconnected_qpairs, poll_group_stailq) {
          #  #  #  #  #  
             #  #  #  #  
                      # ]
     104         [ #  # ]:          0 :                 if (qpair == iter_qp) {
     105                 :          0 :                         return 0;
     106                 :            :                 }
     107                 :          0 :         }
     108                 :            : 
     109                 :          0 :         return -EINVAL;
     110                 :          0 : }
     111                 :            : 
     112                 :            : int
     113                 :          6 : nvme_transport_poll_group_connect_qpair(struct spdk_nvme_qpair *qpair)
     114                 :            : {
     115                 :          1 :         struct spdk_nvme_transport_poll_group *tgroup;
     116                 :          1 :         struct spdk_nvme_qpair *iter_qp, *tmp_iter_qp;
     117                 :            : 
     118   [ +  -  +  - ]:          6 :         tgroup = qpair->poll_group;
     119                 :            : 
     120   [ +  +  +  -  :          6 :         STAILQ_FOREACH_SAFE(iter_qp, &tgroup->disconnected_qpairs, poll_group_stailq, tmp_iter_qp) {
          +  -  -  +  #  
          #  #  #  #  #  
                   -  + ]
     121         [ #  # ]:          0 :                 if (qpair == iter_qp) {
     122   [ #  #  #  #  :          0 :                         STAILQ_REMOVE(&tgroup->disconnected_qpairs, qpair, spdk_nvme_qpair, poll_group_stailq);
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
             #  #  #  # ]
     123   [ #  #  #  #  :          0 :                         STAILQ_INSERT_TAIL(&tgroup->connected_qpairs, qpair, poll_group_stailq);
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
             #  #  #  #  
                      # ]
     124                 :          0 :                         return 0;
     125                 :            :                 }
     126                 :          0 :         }
     127                 :            : 
     128   [ +  -  +  -  :          6 :         STAILQ_FOREACH(iter_qp, &tgroup->connected_qpairs, poll_group_stailq) {
          +  -  +  -  #  
             #  #  #  #  
                      # ]
     129         [ +  + ]:          6 :                 if (qpair == iter_qp) {
     130                 :          6 :                         return 0;
     131                 :            :                 }
     132                 :          0 :         }
     133                 :            : 
     134                 :          0 :         return -EINVAL;
     135                 :          1 : }
     136                 :            : 
     137                 :            : struct spdk_nvme_transport_poll_group *
     138                 :         30 : nvme_transport_poll_group_create(const struct spdk_nvme_transport *transport)
     139                 :            : {
     140                 :         30 :         struct spdk_nvme_transport_poll_group *group = NULL;
     141                 :            : 
     142                 :            :         /* TODO: separate this transport function table from the transport specific one. */
     143                 :         30 :         group = calloc(1, sizeof(*group));
     144         [ +  - ]:         30 :         if (group) {
     145   [ +  -  +  - ]:         30 :                 group->transport = transport;
     146   [ +  -  +  -  :         30 :                 STAILQ_INIT(&group->connected_qpairs);
          +  -  +  -  +  
          -  +  -  +  -  
                   +  - ]
     147   [ +  -  +  -  :         30 :                 STAILQ_INIT(&group->disconnected_qpairs);
          +  -  +  -  +  
          -  +  -  +  -  
                   +  - ]
     148                 :          5 :         }
     149                 :            : 
     150                 :         35 :         return group;
     151                 :          5 : }
     152                 :            : 
     153                 :            : int
     154                 :         12 : nvme_transport_poll_group_destroy(struct spdk_nvme_transport_poll_group *tgroup)
     155                 :            : {
     156                 :         12 :         return g_destroy_return_value;
     157                 :            : }
     158                 :            : 
     159                 :            : int
     160                 :         42 : nvme_transport_poll_group_add(struct spdk_nvme_transport_poll_group *tgroup,
     161                 :            :                               struct spdk_nvme_qpair *qpair)
     162                 :            : {
     163   [ +  -  +  -  :         42 :         STAILQ_INSERT_TAIL(&tgroup->connected_qpairs, qpair, poll_group_stailq);
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
             -  +  -  +  
                      - ]
     164   [ +  -  +  - ]:         42 :         qpair->poll_group = tgroup;
     165                 :            : 
     166                 :         42 :         return 0;
     167                 :            : }
     168                 :            : 
     169                 :            : int
     170                 :         36 : nvme_transport_poll_group_remove(struct spdk_nvme_transport_poll_group *tgroup,
     171                 :            :                                  struct spdk_nvme_qpair *qpair)
     172                 :            : {
     173                 :          6 :         struct spdk_nvme_qpair *iter_qp, *tmp_iter_qp;
     174                 :            : 
     175   [ +  -  +  -  :         36 :         STAILQ_FOREACH_SAFE(iter_qp, &tgroup->connected_qpairs, poll_group_stailq, tmp_iter_qp) {
          +  -  +  -  +  
          -  +  -  +  -  
                   +  - ]
     176         [ +  + ]:         36 :                 if (qpair == iter_qp) {
     177   [ +  -  +  +  :         36 :                         STAILQ_REMOVE(&tgroup->connected_qpairs, qpair, spdk_nvme_qpair, poll_group_stailq);
          +  -  -  +  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  +  +  
          -  +  -  +  -  
          +  -  +  -  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
             #  #  #  # ]
     178                 :         36 :                         return 0;
     179                 :            :                 }
     180                 :          0 :         }
     181                 :            : 
     182   [ #  #  #  #  :          0 :         STAILQ_FOREACH_SAFE(iter_qp, &tgroup->disconnected_qpairs, poll_group_stailq, tmp_iter_qp) {
          #  #  #  #  #  
          #  #  #  #  #  
                   #  # ]
     183         [ #  # ]:          0 :                 if (qpair == iter_qp) {
     184   [ #  #  #  #  :          0 :                         STAILQ_REMOVE(&tgroup->disconnected_qpairs, qpair, spdk_nvme_qpair, poll_group_stailq);
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
             #  #  #  # ]
     185                 :          0 :                         return 0;
     186                 :            :                 }
     187                 :          0 :         }
     188                 :            : 
     189                 :          0 :         return -ENODEV;
     190                 :          6 : }
     191                 :            : 
     192                 :            : int64_t
     193                 :          6 : nvme_transport_poll_group_process_completions(struct spdk_nvme_transport_poll_group *group,
     194                 :            :                 uint32_t completions_per_qpair, spdk_nvme_disconnected_qpair_cb disconnected_qpair_cb)
     195                 :            : {
     196                 :          6 :         return g_process_completions_return_value;
     197                 :            : }
     198                 :            : 
     199                 :            : static void
     200                 :          6 : test_spdk_nvme_poll_group_create(void)
     201                 :            : {
     202                 :          1 :         struct spdk_nvme_poll_group *group;
     203                 :            : 
     204                 :            :         /* basic case - create a poll group with no internal transport poll groups. */
     205                 :          6 :         group = spdk_nvme_poll_group_create(NULL, NULL);
     206                 :            : 
     207   [ +  +  #  # ]:          6 :         SPDK_CU_ASSERT_FATAL(group != NULL);
     208   [ +  -  +  -  :          6 :         CU_ASSERT(STAILQ_EMPTY(&group->tgroups));
                   +  - ]
     209   [ +  +  #  # ]:          6 :         SPDK_CU_ASSERT_FATAL(spdk_nvme_poll_group_destroy(group) == 0);
     210                 :            : 
     211   [ +  -  +  -  :          6 :         TAILQ_INSERT_TAIL(&g_spdk_nvme_transports, &t1, link);
          +  -  +  -  +  
          -  +  -  +  -  
             +  -  +  - ]
     212   [ +  -  +  -  :          6 :         TAILQ_INSERT_TAIL(&g_spdk_nvme_transports, &t2, link);
          +  -  +  -  +  
          -  +  -  +  -  
             +  -  +  - ]
     213   [ +  -  +  -  :          6 :         TAILQ_INSERT_TAIL(&g_spdk_nvme_transports, &t3, link);
          +  -  +  -  +  
          -  +  -  +  -  
             +  -  +  - ]
     214                 :            : 
     215                 :            :         /* advanced case - create a poll group with three internal poll groups. */
     216                 :          6 :         group = spdk_nvme_poll_group_create(NULL, NULL);
     217   [ +  -  +  -  :          6 :         CU_ASSERT(STAILQ_EMPTY(&group->tgroups));
                   +  - ]
     218   [ +  +  #  # ]:          6 :         SPDK_CU_ASSERT_FATAL(spdk_nvme_poll_group_destroy(group) == 0);
     219                 :            : 
     220                 :            :         /* Failing case - failed to allocate a poll group. */
     221                 :          6 :         MOCK_SET(calloc, NULL);
     222                 :          6 :         group = spdk_nvme_poll_group_create(NULL, NULL);
     223                 :          6 :         CU_ASSERT(group == NULL);
     224                 :          6 :         MOCK_CLEAR(calloc);
     225                 :            : 
     226   [ +  -  +  -  :          6 :         TAILQ_REMOVE(&g_spdk_nvme_transports, &t1, link);
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  #  #  #  #  
          #  #  +  -  +  
          -  +  -  +  -  
                   +  - ]
     227   [ +  -  +  -  :          6 :         TAILQ_REMOVE(&g_spdk_nvme_transports, &t2, link);
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  #  #  #  #  
          #  #  +  -  +  
          -  +  -  +  -  
                   +  - ]
     228   [ +  +  +  -  :          6 :         TAILQ_REMOVE(&g_spdk_nvme_transports, &t3, link);
          -  +  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
                   +  - ]
     229                 :          6 : }
     230                 :            : 
     231                 :            : static void
     232                 :          6 : test_spdk_nvme_poll_group_add_remove(void)
     233                 :            : {
     234                 :          1 :         struct spdk_nvme_poll_group *group;
     235                 :          7 :         struct spdk_nvme_transport_poll_group *tgroup = NULL, *tmp_tgroup, *tgroup_1 = NULL,
     236                 :          6 :                                                        *tgroup_2 = NULL,
     237                 :          6 :                                                         *tgroup_4 = NULL;
     238                 :          1 :         struct spdk_nvme_qpair *qpair;
     239                 :          6 :         struct spdk_nvme_qpair qpair1_1 = {0};
     240                 :          6 :         struct spdk_nvme_qpair qpair1_2 = {0};
     241                 :          6 :         struct spdk_nvme_qpair qpair2_1 = {0};
     242                 :          6 :         struct spdk_nvme_qpair qpair2_2 = {0};
     243                 :          6 :         struct spdk_nvme_qpair qpair4_1 = {0};
     244                 :          6 :         struct spdk_nvme_qpair qpair4_2 = {0};
     245                 :          6 :         int i = 0;
     246                 :            : 
     247   [ +  -  +  -  :          6 :         TAILQ_INSERT_TAIL(&g_spdk_nvme_transports, &t1, link);
          +  -  +  -  +  
          -  +  -  +  -  
             +  -  +  - ]
     248   [ +  -  +  -  :          6 :         TAILQ_INSERT_TAIL(&g_spdk_nvme_transports, &t2, link);
          +  -  +  -  +  
          -  +  -  +  -  
             +  -  +  - ]
     249   [ +  -  +  -  :          6 :         TAILQ_INSERT_TAIL(&g_spdk_nvme_transports, &t3, link);
          +  -  +  -  +  
          -  +  -  +  -  
             +  -  +  - ]
     250                 :            : 
     251                 :          6 :         group = spdk_nvme_poll_group_create(NULL, NULL);
     252   [ +  +  #  # ]:          6 :         SPDK_CU_ASSERT_FATAL(group != NULL);
     253   [ +  -  +  -  :          6 :         CU_ASSERT(STAILQ_EMPTY(&group->tgroups));
                   +  - ]
     254                 :            : 
     255                 :            :         /* Add qpairs to a single transport. */
     256         [ +  - ]:          6 :         qpair1_1.transport = &t1;
     257                 :          6 :         qpair1_1.state = NVME_QPAIR_DISCONNECTED;
     258         [ +  - ]:          6 :         qpair1_2.transport = &t1;
     259                 :          6 :         qpair1_2.state = NVME_QPAIR_ENABLED;
     260                 :          6 :         CU_ASSERT(spdk_nvme_poll_group_add(group, &qpair1_1) == 0);
     261                 :          6 :         CU_ASSERT(spdk_nvme_poll_group_add(group, &qpair1_2) == -EINVAL);
     262   [ +  +  +  -  :         12 :         STAILQ_FOREACH(tmp_tgroup, &group->tgroups, link) {
          +  -  +  +  +  
             -  +  -  +  
                      - ]
     263   [ +  -  +  -  :          6 :                 if (tmp_tgroup->transport == &t1) {
                   -  + ]
     264                 :          6 :                         tgroup = tmp_tgroup;
     265                 :          1 :                 } else {
     266   [ #  #  #  #  :          0 :                         CU_ASSERT(STAILQ_EMPTY(&tmp_tgroup->connected_qpairs));
                   #  # ]
     267                 :            :                 }
     268         [ +  - ]:          6 :                 i++;
     269                 :          1 :         }
     270                 :          6 :         CU_ASSERT(i == 1);
     271   [ +  +  #  # ]:          6 :         SPDK_CU_ASSERT_FATAL(tgroup != NULL);
     272   [ +  -  +  -  :          6 :         qpair = STAILQ_FIRST(&tgroup->connected_qpairs);
                   +  - ]
     273   [ +  +  #  # ]:          6 :         SPDK_CU_ASSERT_FATAL(qpair == &qpair1_1);
     274   [ +  -  +  -  :          6 :         qpair = STAILQ_NEXT(qpair, poll_group_stailq);
                   +  - ]
     275                 :          6 :         CU_ASSERT(qpair == NULL);
     276                 :            : 
     277                 :            :         /* Add qpairs to a second transport. */
     278         [ +  - ]:          6 :         qpair2_1.transport = &t2;
     279         [ +  - ]:          6 :         qpair2_2.transport = &t2;
     280                 :          6 :         CU_ASSERT(spdk_nvme_poll_group_add(group, &qpair2_1) == 0);
     281                 :          6 :         CU_ASSERT(spdk_nvme_poll_group_add(group, &qpair2_2) == 0);
     282         [ +  - ]:          6 :         qpair4_1.transport = &t4;
     283         [ +  - ]:          6 :         qpair4_2.transport = &t4;
     284                 :            :         /* Add qpairs for a transport that doesn't exist. */
     285                 :          6 :         CU_ASSERT(spdk_nvme_poll_group_add(group, &qpair4_1) == -ENODEV);
     286                 :          6 :         CU_ASSERT(spdk_nvme_poll_group_add(group, &qpair4_2) == -ENODEV);
     287                 :          6 :         i = 0;
     288   [ +  +  +  -  :         18 :         STAILQ_FOREACH(tmp_tgroup, &group->tgroups, link) {
          +  -  +  +  +  
             -  +  -  +  
                      - ]
     289   [ +  +  +  -  :         12 :                 if (tmp_tgroup->transport == &t1) {
                   +  + ]
     290                 :          6 :                         tgroup_1 = tmp_tgroup;
     291   [ +  -  +  -  :          7 :                 } else if (tmp_tgroup->transport == &t2) {
                   +  - ]
     292                 :          6 :                         tgroup_2 = tmp_tgroup;
     293                 :          1 :                 } else {
     294   [ #  #  #  #  :          0 :                         CU_ASSERT(STAILQ_EMPTY(&tmp_tgroup->connected_qpairs));
                   #  # ]
     295                 :            :                 }
     296         [ +  - ]:         12 :                 i++;
     297                 :          2 :         }
     298                 :          6 :         CU_ASSERT(i == 2);
     299   [ +  +  #  # ]:          6 :         SPDK_CU_ASSERT_FATAL(tgroup_1 != NULL);
     300   [ +  -  +  -  :          6 :         qpair = STAILQ_FIRST(&tgroup_1->connected_qpairs);
                   +  - ]
     301   [ +  +  #  # ]:          6 :         SPDK_CU_ASSERT_FATAL(qpair == &qpair1_1);
     302   [ +  -  +  -  :          6 :         qpair = STAILQ_NEXT(qpair, poll_group_stailq);
                   +  - ]
     303                 :          6 :         CU_ASSERT(qpair == NULL);
     304   [ +  +  #  # ]:          6 :         SPDK_CU_ASSERT_FATAL(tgroup_2 != NULL);
     305   [ +  -  +  -  :          6 :         qpair = STAILQ_FIRST(&tgroup_2->connected_qpairs);
                   +  - ]
     306   [ +  +  #  # ]:          6 :         SPDK_CU_ASSERT_FATAL(qpair == &qpair2_1);
     307   [ +  -  +  -  :          6 :         qpair = STAILQ_NEXT(qpair, poll_group_stailq);
                   +  - ]
     308   [ +  +  #  # ]:          6 :         SPDK_CU_ASSERT_FATAL(qpair == &qpair2_2);
     309   [ +  -  +  -  :          6 :         qpair = STAILQ_NEXT(qpair, poll_group_stailq);
                   +  - ]
     310                 :          6 :         CU_ASSERT(qpair == NULL);
     311                 :            : 
     312                 :            :         /* Try removing a qpair that belongs to a transport not in our poll group. */
     313                 :          6 :         CU_ASSERT(spdk_nvme_poll_group_remove(group, &qpair4_1) == -ENODEV);
     314                 :            : 
     315   [ +  -  +  -  :          6 :         TAILQ_INSERT_TAIL(&g_spdk_nvme_transports, &t4, link);
          +  -  +  -  +  
          -  +  -  +  -  
             +  -  +  - ]
     316                 :          6 :         CU_ASSERT(spdk_nvme_poll_group_add(group, &qpair4_1) == 0);
     317                 :          6 :         CU_ASSERT(spdk_nvme_poll_group_add(group, &qpair4_2) == 0);
     318   [ +  +  +  -  :         24 :         STAILQ_FOREACH(tmp_tgroup, &group->tgroups, link) {
          +  -  +  +  +  
             -  +  -  +  
                      - ]
     319   [ +  +  +  -  :         18 :                 if (tmp_tgroup->transport == &t1) {
                   +  + ]
     320                 :          6 :                         tgroup_1 = tmp_tgroup;
     321   [ +  +  +  -  :         13 :                 } else if (tmp_tgroup->transport == &t2) {
                   +  + ]
     322                 :          6 :                         tgroup_2 = tmp_tgroup;
     323   [ +  -  +  -  :          7 :                 } else if (tmp_tgroup->transport == &t4) {
                   +  - ]
     324                 :          6 :                         tgroup_4 = tmp_tgroup;
     325                 :          1 :                 } else {
     326   [ #  #  #  #  :          0 :                         CU_ASSERT(STAILQ_EMPTY(&tmp_tgroup->connected_qpairs));
                   #  # ]
     327                 :            :                 }
     328                 :          3 :         }
     329   [ +  +  #  # ]:          6 :         SPDK_CU_ASSERT_FATAL(tgroup_1 != NULL);
     330   [ +  -  +  -  :          6 :         qpair = STAILQ_FIRST(&tgroup_1->connected_qpairs);
                   +  - ]
     331   [ +  +  #  # ]:          6 :         SPDK_CU_ASSERT_FATAL(qpair == &qpair1_1);
     332   [ +  -  +  -  :          6 :         qpair = STAILQ_NEXT(qpair, poll_group_stailq);
                   +  - ]
     333                 :          6 :         CU_ASSERT(qpair == NULL);
     334   [ +  +  #  # ]:          6 :         SPDK_CU_ASSERT_FATAL(tgroup_2 != NULL);
     335   [ +  -  +  -  :          6 :         qpair = STAILQ_FIRST(&tgroup_2->connected_qpairs);
                   +  - ]
     336   [ +  +  #  # ]:          6 :         SPDK_CU_ASSERT_FATAL(qpair == &qpair2_1);
     337   [ +  -  +  -  :          6 :         qpair = STAILQ_NEXT(qpair, poll_group_stailq);
                   +  - ]
     338   [ +  +  #  # ]:          6 :         SPDK_CU_ASSERT_FATAL(qpair == &qpair2_2);
     339   [ +  -  +  -  :          6 :         qpair = STAILQ_NEXT(qpair, poll_group_stailq);
                   +  - ]
     340                 :          6 :         CU_ASSERT(qpair == NULL);
     341   [ +  +  #  # ]:          6 :         SPDK_CU_ASSERT_FATAL(tgroup_4 != NULL);
     342   [ +  -  +  -  :          6 :         qpair = STAILQ_FIRST(&tgroup_4->connected_qpairs);
                   +  - ]
     343   [ +  +  #  # ]:          6 :         SPDK_CU_ASSERT_FATAL(qpair == &qpair4_1);
     344   [ +  -  +  -  :          6 :         qpair = STAILQ_NEXT(qpair, poll_group_stailq);
                   +  - ]
     345   [ +  +  #  # ]:          6 :         SPDK_CU_ASSERT_FATAL(qpair == &qpair4_2);
     346   [ +  -  +  -  :          6 :         qpair = STAILQ_NEXT(qpair, poll_group_stailq);
                   +  - ]
     347                 :          6 :         CU_ASSERT(qpair == NULL);
     348                 :            : 
     349                 :            :         /* remove all qpairs */
     350                 :          6 :         CU_ASSERT(spdk_nvme_poll_group_remove(group, &qpair1_1) == 0);
     351                 :          6 :         CU_ASSERT(spdk_nvme_poll_group_remove(group, &qpair2_1) == 0);
     352                 :          6 :         CU_ASSERT(spdk_nvme_poll_group_remove(group, &qpair2_2) == 0);
     353                 :          6 :         CU_ASSERT(spdk_nvme_poll_group_remove(group, &qpair4_1) == 0);
     354                 :          6 :         CU_ASSERT(spdk_nvme_poll_group_remove(group, &qpair4_2) == 0);
     355                 :            :         /* Confirm the fourth transport group was created. */
     356                 :          6 :         i = 0;
     357   [ +  +  +  -  :         24 :         STAILQ_FOREACH_SAFE(tgroup, &group->tgroups, link, tmp_tgroup) {
          +  -  +  +  +  
          -  +  -  +  -  
                   +  + ]
     358   [ +  -  +  -  :         18 :                 CU_ASSERT(STAILQ_EMPTY(&tgroup->connected_qpairs));
                   +  - ]
     359   [ +  -  +  +  :         18 :                 STAILQ_REMOVE(&group->tgroups, tgroup, spdk_nvme_transport_poll_group, link);
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  +  +  
          -  +  -  +  -  
          +  -  +  -  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
             #  #  #  # ]
     360                 :         18 :                 free(tgroup);
     361         [ +  - ]:         18 :                 i++;
     362                 :          3 :         }
     363                 :          6 :         CU_ASSERT(i == 3);
     364   [ +  +  #  # ]:          6 :         SPDK_CU_ASSERT_FATAL(spdk_nvme_poll_group_destroy(group) == 0);
     365                 :            : 
     366   [ +  -  +  -  :          6 :         TAILQ_REMOVE(&g_spdk_nvme_transports, &t1, link);
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  #  #  #  #  
          #  #  +  -  +  
          -  +  -  +  -  
                   +  - ]
     367   [ +  -  +  -  :          6 :         TAILQ_REMOVE(&g_spdk_nvme_transports, &t2, link);
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  #  #  #  #  
          #  #  +  -  +  
          -  +  -  +  -  
                   +  - ]
     368   [ +  -  +  -  :          6 :         TAILQ_REMOVE(&g_spdk_nvme_transports, &t3, link);
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  #  #  #  #  
          #  #  +  -  +  
          -  +  -  +  -  
                   +  - ]
     369   [ +  +  +  -  :          6 :         TAILQ_REMOVE(&g_spdk_nvme_transports, &t4, link);
          -  +  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
                   +  - ]
     370                 :          6 : }
     371                 :            : 
     372                 :            : static void
     373                 :          6 : test_spdk_nvme_poll_group_process_completions(void)
     374                 :            : {
     375                 :          1 :         struct spdk_nvme_poll_group *group;
     376                 :          1 :         struct spdk_nvme_transport_poll_group *tgroup, *tmp_tgroup;
     377                 :          6 :         struct spdk_nvme_qpair qpair1_1 = {0};
     378                 :            : 
     379                 :          6 :         group = spdk_nvme_poll_group_create(NULL, NULL);
     380   [ +  +  #  # ]:          6 :         SPDK_CU_ASSERT_FATAL(group != NULL);
     381                 :            : 
     382                 :            :         /* If we don't have any transport poll groups, we shouldn't get any completions. */
     383                 :          6 :         g_process_completions_return_value = 32;
     384                 :          6 :         CU_ASSERT(spdk_nvme_poll_group_process_completions(group, 128,
     385                 :            :                         unit_test_disconnected_qpair_cb) == 0);
     386   [ +  +  #  # ]:          6 :         SPDK_CU_ASSERT_FATAL(spdk_nvme_poll_group_destroy(group) == 0);
     387                 :            : 
     388   [ +  -  +  -  :          6 :         TAILQ_INSERT_TAIL(&g_spdk_nvme_transports, &t1, link);
          +  -  +  -  +  
          -  +  -  +  -  
             +  -  +  - ]
     389   [ +  -  +  -  :          6 :         TAILQ_INSERT_TAIL(&g_spdk_nvme_transports, &t2, link);
          +  -  +  -  +  
          -  +  -  +  -  
             +  -  +  - ]
     390   [ +  -  +  -  :          6 :         TAILQ_INSERT_TAIL(&g_spdk_nvme_transports, &t3, link);
          +  -  +  -  +  
          -  +  -  +  -  
             +  -  +  - ]
     391                 :            : 
     392                 :            :         /* try it with three transport poll groups. */
     393                 :          6 :         group = spdk_nvme_poll_group_create(NULL, NULL);
     394   [ +  +  #  # ]:          6 :         SPDK_CU_ASSERT_FATAL(group != NULL);
     395                 :          6 :         qpair1_1.state = NVME_QPAIR_DISCONNECTED;
     396         [ +  - ]:          6 :         qpair1_1.transport = &t1;
     397                 :          6 :         CU_ASSERT(spdk_nvme_poll_group_add(group, &qpair1_1) == 0);
     398                 :          6 :         qpair1_1.state = NVME_QPAIR_ENABLED;
     399                 :          6 :         CU_ASSERT(nvme_poll_group_connect_qpair(&qpair1_1) == 0);
     400                 :          6 :         CU_ASSERT(spdk_nvme_poll_group_process_completions(group, 128,
     401                 :            :                         unit_test_disconnected_qpair_cb) == 32);
     402                 :          6 :         CU_ASSERT(spdk_nvme_poll_group_remove(group, &qpair1_1) == 0);
     403   [ +  +  +  -  :         12 :         STAILQ_FOREACH_SAFE(tgroup, &group->tgroups, link, tmp_tgroup) {
          +  -  +  +  +  
          -  +  -  +  -  
                   +  + ]
     404   [ +  -  +  -  :          6 :                 CU_ASSERT(STAILQ_EMPTY(&tgroup->connected_qpairs));
                   +  - ]
     405   [ +  -  +  -  :          6 :                 STAILQ_REMOVE(&group->tgroups, tgroup, spdk_nvme_transport_poll_group, link);
          +  -  -  +  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  -  +  +  
          -  +  -  +  -  
          +  -  +  -  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
             #  #  #  # ]
     406                 :          6 :                 free(tgroup);
     407                 :          1 :         }
     408   [ +  +  #  # ]:          6 :         SPDK_CU_ASSERT_FATAL(spdk_nvme_poll_group_destroy(group) == 0);
     409                 :            : 
     410   [ +  -  +  -  :          6 :         TAILQ_REMOVE(&g_spdk_nvme_transports, &t1, link);
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  #  #  #  #  
          #  #  +  -  +  
          -  +  -  +  -  
                   +  - ]
     411   [ +  -  +  -  :          6 :         TAILQ_REMOVE(&g_spdk_nvme_transports, &t2, link);
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  #  #  #  #  
          #  #  +  -  +  
          -  +  -  +  -  
                   +  - ]
     412   [ +  +  +  -  :          6 :         TAILQ_REMOVE(&g_spdk_nvme_transports, &t3, link);
          -  +  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
                   +  - ]
     413                 :          6 : }
     414                 :            : 
     415                 :            : static void
     416                 :          6 : test_spdk_nvme_poll_group_destroy(void)
     417                 :            : {
     418                 :          1 :         struct spdk_nvme_poll_group *group;
     419                 :          1 :         struct spdk_nvme_transport_poll_group *tgroup, *tgroup_1, *tgroup_2;
     420                 :          6 :         struct spdk_nvme_qpair qpair1_1 = {0};
     421                 :          6 :         int num_tgroups = 0;
     422                 :            : 
     423                 :            :         /* Simple destruction of empty poll group. */
     424                 :          6 :         group = spdk_nvme_poll_group_create(NULL, NULL);
     425   [ +  +  #  # ]:          6 :         SPDK_CU_ASSERT_FATAL(group != NULL);
     426   [ +  +  #  # ]:          6 :         SPDK_CU_ASSERT_FATAL(spdk_nvme_poll_group_destroy(group) == 0);
     427                 :            : 
     428   [ +  -  +  -  :          6 :         TAILQ_INSERT_TAIL(&g_spdk_nvme_transports, &t1, link);
          +  -  +  -  +  
          -  +  -  +  -  
             +  -  +  - ]
     429   [ +  -  +  -  :          6 :         TAILQ_INSERT_TAIL(&g_spdk_nvme_transports, &t2, link);
          +  -  +  -  +  
          -  +  -  +  -  
             +  -  +  - ]
     430   [ +  -  +  -  :          6 :         TAILQ_INSERT_TAIL(&g_spdk_nvme_transports, &t3, link);
          +  -  +  -  +  
          -  +  -  +  -  
             +  -  +  - ]
     431                 :          6 :         group = spdk_nvme_poll_group_create(NULL, NULL);
     432   [ +  +  #  # ]:          6 :         SPDK_CU_ASSERT_FATAL(group != NULL);
     433                 :            : 
     434         [ +  - ]:          6 :         qpair1_1.transport = &t1;
     435                 :          6 :         CU_ASSERT(spdk_nvme_poll_group_add(group, &qpair1_1) == 0);
     436                 :            : 
     437                 :            :         /* Don't remove busy poll groups. */
     438                 :          6 :         g_destroy_return_value = -EBUSY;
     439   [ +  +  #  # ]:          6 :         SPDK_CU_ASSERT_FATAL(spdk_nvme_poll_group_destroy(group) == -EBUSY);
     440   [ +  +  +  -  :         12 :         STAILQ_FOREACH(tgroup, &group->tgroups, link) {
          +  -  +  +  +  
             -  +  -  +  
                      - ]
     441         [ +  - ]:          6 :                 num_tgroups++;
     442                 :          1 :         }
     443                 :          6 :         CU_ASSERT(num_tgroups == 1);
     444                 :            : 
     445                 :            :         /* destroy poll group with internal poll groups. */
     446                 :          6 :         g_destroy_return_value = 0;
     447   [ +  -  +  -  :          6 :         tgroup_1 = STAILQ_FIRST(&group->tgroups);
                   +  - ]
     448   [ +  -  +  -  :          6 :         tgroup_2 = STAILQ_NEXT(tgroup_1, link);
                   +  - ]
     449                 :          6 :         CU_ASSERT(tgroup_2 == NULL)
     450   [ +  +  #  # ]:          6 :         SPDK_CU_ASSERT_FATAL(spdk_nvme_poll_group_destroy(group) == 0);
     451                 :          6 :         free(tgroup_1);
     452                 :          6 : }
     453                 :            : 
     454                 :            : static void
     455                 :          6 : test_spdk_nvme_poll_group_get_free_stats(void)
     456                 :            : {
     457                 :          6 :         struct spdk_nvme_poll_group group = {};
     458                 :          6 :         struct spdk_nvme_poll_group_stat *stats = NULL;
     459                 :          6 :         struct spdk_nvme_transport_poll_group tgroup[3] = {};
     460                 :          1 :         int rc, i;
     461                 :            : 
     462                 :            :         /* Multiple tgroups */
     463   [ +  -  +  -  :          6 :         STAILQ_INIT(&group.tgroups);
          +  -  +  -  +  
                      - ]
     464   [ +  +  +  - ]:         24 :         for (i = 0; i < 3; i++) {
     465   [ +  -  +  -  :         18 :                 STAILQ_INSERT_TAIL(&group.tgroups, &tgroup[i], link);
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
                -  +  - ]
     466                 :          3 :         }
     467                 :            : 
     468                 :          6 :         rc = spdk_nvme_poll_group_get_stats(&group, &stats);
     469                 :          6 :         CU_ASSERT(rc == 0);
     470   [ +  -  +  - ]:          6 :         CU_ASSERT(stats->num_transports == 3);
     471                 :            : 
     472                 :          6 :         spdk_nvme_poll_group_free_stats(&group, stats);
     473   [ +  +  +  - ]:         24 :         for (i = 0; i < 3; i++) {
     474   [ +  -  +  +  :         18 :                 STAILQ_REMOVE(&group.tgroups, &tgroup[i], spdk_nvme_transport_poll_group, link);
          +  -  +  -  -  
          +  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  +  +  -  +  
          -  +  -  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
                #  #  # ]
     475                 :          3 :         }
     476   [ +  +  +  -  :          6 :         SPDK_CU_ASSERT_FATAL(STAILQ_EMPTY(&group.tgroups));
             +  -  #  # ]
     477                 :            : 
     478                 :            :         /* No available tgroup */
     479                 :          6 :         rc = spdk_nvme_poll_group_get_stats(&group, &stats);
     480                 :          6 :         CU_ASSERT(rc == -ENOTSUP);
     481                 :          6 : }
     482                 :            : 
     483                 :            : int
     484                 :          6 : main(int argc, char **argv)
     485                 :            : {
     486                 :          6 :         CU_pSuite       suite = NULL;
     487                 :          1 :         unsigned int    num_failures;
     488                 :            : 
     489         [ -  + ]:          6 :         if (CU_initialize_registry() != CUE_SUCCESS) {
     490                 :          0 :                 return CU_get_error();
     491                 :            :         }
     492                 :            : 
     493                 :          6 :         suite = CU_add_suite("nvme_ns_cmd", NULL, NULL);
     494         [ +  + ]:          6 :         if (suite == NULL) {
     495                 :          0 :                 CU_cleanup_registry();
     496                 :          0 :                 return CU_get_error();
     497                 :            :         }
     498                 :            : 
     499         [ +  - ]:          5 :         if (
     500   [ +  -  +  - ]:         12 :                 CU_add_test(suite, "nvme_poll_group_create_test", test_spdk_nvme_poll_group_create) == NULL ||
     501                 :          6 :                 CU_add_test(suite, "nvme_poll_group_add_remove_test",
     502         [ +  - ]:          6 :                             test_spdk_nvme_poll_group_add_remove) == NULL ||
     503                 :          6 :                 CU_add_test(suite, "nvme_poll_group_process_completions",
     504         [ +  - ]:          6 :                             test_spdk_nvme_poll_group_process_completions) == NULL ||
     505         [ +  + ]:         11 :                 CU_add_test(suite, "nvme_poll_group_destroy_test", test_spdk_nvme_poll_group_destroy) == NULL ||
     506                 :          6 :                 CU_add_test(suite, "nvme_poll_group_get_free_stats",
     507                 :          1 :                             test_spdk_nvme_poll_group_get_free_stats) == NULL
     508                 :            :         ) {
     509                 :          0 :                 CU_cleanup_registry();
     510                 :          0 :                 return CU_get_error();
     511                 :            :         }
     512                 :            : 
     513                 :          6 :         num_failures = spdk_ut_run_tests(argc, argv, NULL);
     514                 :          6 :         CU_cleanup_registry();
     515                 :          6 :         return num_failures;
     516                 :          1 : }

Generated by: LCOV version 1.14