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: 255 287 88.9 %
Date: 2024-07-15 14:51:33 Functions: 18 23 78.3 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 92 214 43.0 %

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

Generated by: LCOV version 1.14