LCOV - code coverage report
Current view: top level - spdk/test/unit/lib/util/fd_group.c - fd_group_ut.c (source / functions) Hit Total Coverage
Test: Combined Lines: 182 184 98.9 %
Date: 2024-12-12 10:09:12 Functions: 4 5 80.0 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 42 76 55.3 %

           Branch data     Line data    Source code
       1                 :            : /*   SPDX-License-Identifier: BSD-3-Clause
       2                 :            :  *   Copyright (C) 2024 Samsung Electronics Co., Ltd.
       3                 :            :  *   All rights reserved.
       4                 :            :  */
       5                 :            : 
       6                 :            : #include "spdk/stdinc.h"
       7                 :            : #include "spdk_internal/cunit.h"
       8                 :            : #include "util/fd_group.c"
       9                 :            : 
      10                 :            : static int
      11                 :          0 : fd_group_cb_fn(void *ctx)
      12                 :            : {
      13                 :          0 :         return 0;
      14                 :            : }
      15                 :            : 
      16                 :            : static void
      17                 :          3 : test_fd_group_basic(void)
      18                 :            : {
      19                 :          3 :         struct spdk_fd_group *fgrp;
      20                 :          3 :         struct event_handler *ehdlr = NULL;
      21                 :            :         int fd;
      22                 :            :         int rc;
      23                 :          3 :         int cb_arg;
      24                 :            : 
      25                 :          3 :         rc = spdk_fd_group_create(&fgrp);
      26         [ -  + ]:          3 :         SPDK_CU_ASSERT_FATAL(rc == 0);
      27                 :            : 
      28                 :          3 :         fd = epoll_create1(0);
      29         [ -  + ]:          3 :         SPDK_CU_ASSERT_FATAL(fd >= 0);
      30                 :            : 
      31                 :          3 :         rc = SPDK_FD_GROUP_ADD(fgrp, fd, fd_group_cb_fn, &cb_arg);
      32         [ -  + ]:          3 :         SPDK_CU_ASSERT_FATAL(rc == 0);
      33         [ -  + ]:          3 :         SPDK_CU_ASSERT_FATAL(fgrp->num_fds == 1);
      34                 :            : 
      35                 :            :         /* Verify that event handler is initialized correctly */
      36                 :          3 :         ehdlr = TAILQ_FIRST(&fgrp->event_handlers);
      37         [ -  + ]:          3 :         SPDK_CU_ASSERT_FATAL(ehdlr != NULL);
      38                 :          3 :         CU_ASSERT(ehdlr->fd == fd);
      39                 :          3 :         CU_ASSERT(ehdlr->state == EVENT_HANDLER_STATE_WAITING);
      40                 :          3 :         CU_ASSERT(ehdlr->events == EPOLLIN);
      41                 :            : 
      42                 :            :         /* Modify event type and see if event handler is updated correctly */
      43                 :          3 :         rc = spdk_fd_group_event_modify(fgrp, fd, EPOLLIN | EPOLLERR);
      44         [ -  + ]:          3 :         SPDK_CU_ASSERT_FATAL(rc == 0);
      45                 :            : 
      46                 :          3 :         ehdlr = TAILQ_FIRST(&fgrp->event_handlers);
      47         [ -  + ]:          3 :         SPDK_CU_ASSERT_FATAL(ehdlr != NULL);
      48                 :          3 :         CU_ASSERT(ehdlr->events == (EPOLLIN | EPOLLERR));
      49                 :            : 
      50                 :          3 :         spdk_fd_group_remove(fgrp, fd);
      51         [ -  + ]:          3 :         SPDK_CU_ASSERT_FATAL(fgrp->num_fds == 0);
      52                 :            : 
      53                 :          3 :         rc = close(fd);
      54                 :          3 :         CU_ASSERT(rc == 0);
      55                 :            : 
      56                 :          3 :         spdk_fd_group_destroy(fgrp);
      57                 :          3 : }
      58                 :            : 
      59                 :            : static void
      60                 :          3 : test_fd_group_nest_unnest(void)
      61                 :            : {
      62                 :          3 :         struct spdk_fd_group *parent, *child, *not_parent;
      63                 :            :         int fd_parent, fd_child, fd_child_2;
      64                 :            :         int rc;
      65                 :          3 :         int cb_arg;
      66                 :            : 
      67                 :          3 :         rc = spdk_fd_group_create(&parent);
      68         [ -  + ]:          3 :         SPDK_CU_ASSERT_FATAL(rc == 0);
      69                 :            : 
      70                 :          3 :         rc = spdk_fd_group_create(&child);
      71         [ -  + ]:          3 :         SPDK_CU_ASSERT_FATAL(rc == 0);
      72                 :            : 
      73                 :          3 :         rc = spdk_fd_group_create(&not_parent);
      74         [ -  + ]:          3 :         SPDK_CU_ASSERT_FATAL(rc == 0);
      75                 :            : 
      76                 :          3 :         fd_parent = epoll_create1(0);
      77         [ -  + ]:          3 :         SPDK_CU_ASSERT_FATAL(fd_parent >= 0);
      78                 :            : 
      79                 :          3 :         fd_child = epoll_create1(0);
      80         [ -  + ]:          3 :         SPDK_CU_ASSERT_FATAL(fd_child >= 0);
      81                 :            : 
      82                 :          3 :         fd_child_2 = epoll_create1(0);
      83         [ -  + ]:          3 :         SPDK_CU_ASSERT_FATAL(fd_child_2 >= 0);
      84                 :            : 
      85                 :          3 :         rc = SPDK_FD_GROUP_ADD(parent, fd_parent, fd_group_cb_fn, &cb_arg);
      86         [ -  + ]:          3 :         SPDK_CU_ASSERT_FATAL(rc == 0);
      87         [ -  + ]:          3 :         SPDK_CU_ASSERT_FATAL(parent->num_fds == 1);
      88                 :            : 
      89                 :          3 :         rc = SPDK_FD_GROUP_ADD(child, fd_child, fd_group_cb_fn, &cb_arg);
      90         [ -  + ]:          3 :         SPDK_CU_ASSERT_FATAL(rc == 0);
      91         [ -  + ]:          3 :         SPDK_CU_ASSERT_FATAL(child->num_fds == 1);
      92                 :            : 
      93                 :            :         /* Nest child fd group to a parent fd group and verify their relation */
      94                 :          3 :         rc = spdk_fd_group_nest(parent, child);
      95         [ -  + ]:          3 :         SPDK_CU_ASSERT_FATAL(rc == 0);
      96         [ -  + ]:          3 :         SPDK_CU_ASSERT_FATAL(child->parent == parent);
      97         [ -  + ]:          3 :         SPDK_CU_ASSERT_FATAL(parent->num_fds == 2);
      98         [ -  + ]:          3 :         SPDK_CU_ASSERT_FATAL(child->num_fds == 0);
      99                 :            : 
     100                 :            :         /* Register second child fd to the child fd group and verify that the parent fd group
     101                 :            :          * has the correct number of fds.
     102                 :            :          */
     103                 :          3 :         rc = SPDK_FD_GROUP_ADD(child, fd_child_2, fd_group_cb_fn, &cb_arg);
     104         [ -  + ]:          3 :         SPDK_CU_ASSERT_FATAL(rc == 0);
     105         [ -  + ]:          3 :         SPDK_CU_ASSERT_FATAL(child->num_fds == 0);
     106         [ -  + ]:          3 :         SPDK_CU_ASSERT_FATAL(parent->num_fds == 3);
     107                 :            : 
     108                 :            :         /* Unnest child fd group from wrong parent fd group and verify that it fails. */
     109                 :          3 :         rc = spdk_fd_group_unnest(not_parent, child);
     110         [ -  + ]:          3 :         SPDK_CU_ASSERT_FATAL(rc == -EINVAL);
     111                 :            : 
     112                 :            :         /* Unnest child fd group from its parent fd group and verify it. */
     113                 :          3 :         rc = spdk_fd_group_unnest(parent, child);
     114         [ -  + ]:          3 :         SPDK_CU_ASSERT_FATAL(rc == 0);
     115         [ -  + ]:          3 :         SPDK_CU_ASSERT_FATAL(child->parent == NULL);
     116         [ -  + ]:          3 :         SPDK_CU_ASSERT_FATAL(parent->num_fds == 1);
     117         [ -  + ]:          3 :         SPDK_CU_ASSERT_FATAL(child->num_fds == 2);
     118                 :            : 
     119                 :          3 :         spdk_fd_group_remove(child, fd_child);
     120         [ -  + ]:          3 :         SPDK_CU_ASSERT_FATAL(child->num_fds == 1);
     121                 :            : 
     122                 :          3 :         spdk_fd_group_remove(child, fd_child_2);
     123         [ -  + ]:          3 :         SPDK_CU_ASSERT_FATAL(child->num_fds == 0);
     124                 :            : 
     125                 :          3 :         spdk_fd_group_remove(parent, fd_parent);
     126         [ -  + ]:          3 :         SPDK_CU_ASSERT_FATAL(parent->num_fds == 0);
     127                 :            : 
     128                 :          3 :         rc = close(fd_child);
     129                 :          3 :         CU_ASSERT(rc == 0);
     130                 :            : 
     131                 :          3 :         rc = close(fd_child_2);
     132                 :          3 :         CU_ASSERT(rc == 0);
     133                 :            : 
     134                 :          3 :         rc = close(fd_parent);
     135                 :          3 :         CU_ASSERT(rc == 0);
     136                 :            : 
     137                 :          3 :         spdk_fd_group_destroy(child);
     138                 :          3 :         spdk_fd_group_destroy(parent);
     139                 :          3 :         spdk_fd_group_destroy(not_parent);
     140                 :          3 : }
     141                 :            : 
     142                 :            : struct ut_fgrp {
     143                 :            :         struct spdk_fd_group    *fgrp;
     144                 :            :         size_t                  num_fds;
     145                 :            : #define UT_MAX_FDS 4
     146                 :            :         int                     fd[UT_MAX_FDS];
     147                 :            : };
     148                 :            : 
     149                 :            : static void
     150                 :          3 : test_fd_group_multi_nest(void)
     151                 :            : {
     152                 :          3 :         struct ut_fgrp fgrp[] = {
     153                 :            :                 { .num_fds = 1 },
     154                 :            :                 { .num_fds = 2 },
     155                 :            :                 { .num_fds = 2 },
     156                 :            :                 { .num_fds = 3 },
     157                 :            :         };
     158                 :            :         size_t i, j;
     159                 :            :         int fd, rc;
     160                 :            : 
     161                 :            :         /* Create four fd_groups with the folowing hierarchy:
     162                 :            :          *           fgrp[0]
     163                 :            :          *           (fd:0)
     164                 :            :          *              |
     165                 :            :          *  fgrp[1]-----+-----fgrp[2]
     166                 :            :          * (fd:1,2)          (fd:3,4)
     167                 :            :          *     |
     168                 :            :          *  fgrp[3]
     169                 :            :          * (fd:5,6,7)
     170                 :            :          */
     171         [ +  + ]:         15 :         for (i = 0; i < SPDK_COUNTOF(fgrp); i++) {
     172                 :         12 :                 rc = spdk_fd_group_create(&fgrp[i].fgrp);
     173         [ -  + ]:         12 :                 SPDK_CU_ASSERT_FATAL(rc == 0);
     174         [ +  + ]:         36 :                 for (j = 0; j < fgrp[i].num_fds; j++) {
     175                 :         24 :                         fgrp[i].fd[j] = fd = eventfd(0, 0);
     176                 :         24 :                         CU_ASSERT(fd >= 0);
     177                 :         24 :                         rc = SPDK_FD_GROUP_ADD(fgrp[i].fgrp, fd, fd_group_cb_fn, NULL);
     178                 :         24 :                         CU_ASSERT_EQUAL(rc, 0);
     179                 :            :                 }
     180                 :            :         }
     181                 :            : 
     182                 :          3 :         CU_ASSERT_EQUAL(fgrp[0].fgrp->num_fds, fgrp[0].num_fds);
     183                 :          3 :         CU_ASSERT_EQUAL(fgrp[1].fgrp->num_fds, fgrp[1].num_fds);
     184                 :          3 :         CU_ASSERT_EQUAL(fgrp[2].fgrp->num_fds, fgrp[2].num_fds);
     185                 :          3 :         CU_ASSERT_EQUAL(fgrp[3].fgrp->num_fds, fgrp[3].num_fds);
     186                 :            : 
     187                 :          3 :         rc = spdk_fd_group_nest(fgrp[0].fgrp, fgrp[2].fgrp);
     188                 :          3 :         CU_ASSERT_EQUAL(rc, 0);
     189                 :          3 :         rc = spdk_fd_group_nest(fgrp[1].fgrp, fgrp[3].fgrp);
     190                 :          3 :         CU_ASSERT_EQUAL(rc, 0);
     191                 :          3 :         rc = spdk_fd_group_nest(fgrp[0].fgrp, fgrp[1].fgrp);
     192                 :          3 :         CU_ASSERT_EQUAL(rc, 0);
     193                 :            : 
     194                 :          3 :         CU_ASSERT_PTR_EQUAL(fgrp[0].fgrp->parent, NULL);
     195                 :          3 :         CU_ASSERT_PTR_EQUAL(fgrp[1].fgrp->parent, fgrp[0].fgrp);
     196                 :          3 :         CU_ASSERT_PTR_EQUAL(fgrp[2].fgrp->parent, fgrp[0].fgrp);
     197                 :          3 :         CU_ASSERT_PTR_EQUAL(fgrp[3].fgrp->parent, fgrp[1].fgrp);
     198                 :          3 :         CU_ASSERT_EQUAL(fgrp[0].fgrp->num_fds,
     199                 :            :                         fgrp[0].num_fds + fgrp[1].num_fds +
     200                 :            :                         fgrp[2].num_fds + fgrp[3].num_fds);
     201                 :          3 :         CU_ASSERT_EQUAL(fgrp[1].fgrp->num_fds, 0);
     202                 :          3 :         CU_ASSERT_EQUAL(fgrp[2].fgrp->num_fds, 0);
     203                 :          3 :         CU_ASSERT_EQUAL(fgrp[3].fgrp->num_fds, 0);
     204                 :            : 
     205                 :            :         /* Unnest fgrp[1] and verify that it now owns its own fds along with fgrp[3] fds */
     206                 :          3 :         rc = spdk_fd_group_unnest(fgrp[0].fgrp, fgrp[1].fgrp);
     207                 :          3 :         CU_ASSERT_EQUAL(rc, 0);
     208                 :            : 
     209                 :          3 :         CU_ASSERT_PTR_EQUAL(fgrp[0].fgrp->parent, NULL);
     210                 :          3 :         CU_ASSERT_PTR_EQUAL(fgrp[1].fgrp->parent, NULL);
     211                 :          3 :         CU_ASSERT_PTR_EQUAL(fgrp[2].fgrp->parent, fgrp[0].fgrp);
     212                 :          3 :         CU_ASSERT_PTR_EQUAL(fgrp[3].fgrp->parent, fgrp[1].fgrp);
     213                 :          3 :         CU_ASSERT_EQUAL(fgrp[0].fgrp->num_fds, fgrp[0].num_fds + fgrp[2].num_fds);
     214                 :          3 :         CU_ASSERT_EQUAL(fgrp[1].fgrp->num_fds, fgrp[1].num_fds + fgrp[3].num_fds);
     215                 :          3 :         CU_ASSERT_EQUAL(fgrp[2].fgrp->num_fds, 0);
     216                 :          3 :         CU_ASSERT_EQUAL(fgrp[3].fgrp->num_fds, 0);
     217                 :            : 
     218                 :            :         /* Nest it again, keeping the same configuration */
     219                 :          3 :         rc = spdk_fd_group_nest(fgrp[0].fgrp, fgrp[1].fgrp);
     220                 :          3 :         CU_ASSERT_EQUAL(rc, 0);
     221                 :          3 :         CU_ASSERT_PTR_EQUAL(fgrp[0].fgrp->parent, NULL);
     222                 :          3 :         CU_ASSERT_PTR_EQUAL(fgrp[1].fgrp->parent, fgrp[0].fgrp);
     223                 :          3 :         CU_ASSERT_PTR_EQUAL(fgrp[2].fgrp->parent, fgrp[0].fgrp);
     224                 :          3 :         CU_ASSERT_PTR_EQUAL(fgrp[3].fgrp->parent, fgrp[1].fgrp);
     225                 :          3 :         CU_ASSERT_EQUAL(fgrp[0].fgrp->num_fds,
     226                 :            :                         fgrp[0].num_fds + fgrp[1].num_fds +
     227                 :            :                         fgrp[2].num_fds + fgrp[3].num_fds);
     228                 :          3 :         CU_ASSERT_EQUAL(fgrp[1].fgrp->num_fds, 0);
     229                 :          3 :         CU_ASSERT_EQUAL(fgrp[2].fgrp->num_fds, 0);
     230                 :          3 :         CU_ASSERT_EQUAL(fgrp[3].fgrp->num_fds, 0);
     231                 :            : 
     232                 :            :         /* Add a new fd to the fgrp at the bottom, fgrp[3] */
     233                 :          3 :         fgrp[3].fd[fgrp[3].num_fds++] = fd = eventfd(0, 0);
     234                 :          3 :         rc = SPDK_FD_GROUP_ADD(fgrp[3].fgrp, fd, fd_group_cb_fn, NULL);
     235                 :          3 :         CU_ASSERT_EQUAL(rc, 0);
     236                 :          3 :         CU_ASSERT_EQUAL(fgrp[0].fgrp->num_fds,
     237                 :            :                         fgrp[0].num_fds + fgrp[1].num_fds +
     238                 :            :                         fgrp[2].num_fds + fgrp[3].num_fds);
     239                 :          3 :         CU_ASSERT_EQUAL(fgrp[1].fgrp->num_fds, 0);
     240                 :          3 :         CU_ASSERT_EQUAL(fgrp[2].fgrp->num_fds, 0);
     241                 :          3 :         CU_ASSERT_EQUAL(fgrp[3].fgrp->num_fds, 0);
     242                 :            : 
     243                 :            :         /* Remove one of the fds from fgrp[2] */
     244                 :          3 :         fd = fgrp[2].fd[--fgrp[2].num_fds];
     245                 :          3 :         spdk_fd_group_remove(fgrp[2].fgrp, fd);
     246                 :          3 :         close(fd);
     247                 :          3 :         CU_ASSERT_EQUAL(fgrp[0].fgrp->num_fds,
     248                 :            :                         fgrp[0].num_fds + fgrp[1].num_fds +
     249                 :            :                         fgrp[2].num_fds + fgrp[3].num_fds);
     250                 :          3 :         CU_ASSERT_EQUAL(fgrp[1].fgrp->num_fds, 0);
     251                 :          3 :         CU_ASSERT_EQUAL(fgrp[2].fgrp->num_fds, 0);
     252                 :          3 :         CU_ASSERT_EQUAL(fgrp[3].fgrp->num_fds, 0);
     253                 :            : 
     254                 :            :         /* Unnest the fgrp at the bottom, fgrp[3] */
     255                 :          3 :         rc = spdk_fd_group_unnest(fgrp[1].fgrp, fgrp[3].fgrp);
     256                 :          3 :         CU_ASSERT_EQUAL(rc, 0);
     257                 :          3 :         CU_ASSERT_PTR_EQUAL(fgrp[0].fgrp->parent, NULL);
     258                 :          3 :         CU_ASSERT_PTR_EQUAL(fgrp[1].fgrp->parent, fgrp[0].fgrp);
     259                 :          3 :         CU_ASSERT_PTR_EQUAL(fgrp[2].fgrp->parent, fgrp[0].fgrp);
     260                 :          3 :         CU_ASSERT_PTR_EQUAL(fgrp[3].fgrp->parent, NULL);
     261                 :          3 :         CU_ASSERT_EQUAL(fgrp[0].fgrp->num_fds, fgrp[0].num_fds + fgrp[1].num_fds + fgrp[2].num_fds);
     262                 :          3 :         CU_ASSERT_EQUAL(fgrp[1].fgrp->num_fds, 0);
     263                 :          3 :         CU_ASSERT_EQUAL(fgrp[2].fgrp->num_fds, 0);
     264                 :          3 :         CU_ASSERT_EQUAL(fgrp[3].fgrp->num_fds, fgrp[3].num_fds);
     265                 :            : 
     266                 :            :         /* Unnest the remaining fgrps, fgrp[1] and fgrp[2] */
     267                 :          3 :         rc = spdk_fd_group_unnest(fgrp[0].fgrp, fgrp[1].fgrp);
     268                 :          3 :         CU_ASSERT_EQUAL(rc, 0);
     269                 :          3 :         CU_ASSERT_PTR_EQUAL(fgrp[0].fgrp->parent, NULL);
     270                 :          3 :         CU_ASSERT_PTR_EQUAL(fgrp[1].fgrp->parent, NULL);
     271                 :          3 :         CU_ASSERT_PTR_EQUAL(fgrp[2].fgrp->parent, fgrp[0].fgrp);
     272                 :          3 :         CU_ASSERT_EQUAL(fgrp[0].fgrp->num_fds, fgrp[0].num_fds + fgrp[2].num_fds);
     273                 :          3 :         CU_ASSERT_EQUAL(fgrp[1].fgrp->num_fds, fgrp[1].num_fds);
     274                 :          3 :         CU_ASSERT_EQUAL(fgrp[2].fgrp->num_fds, 0);
     275                 :            : 
     276                 :          3 :         rc = spdk_fd_group_unnest(fgrp[0].fgrp, fgrp[2].fgrp);
     277                 :          3 :         CU_ASSERT_EQUAL(rc, 0);
     278                 :          3 :         CU_ASSERT_PTR_EQUAL(fgrp[0].fgrp->parent, NULL);
     279                 :          3 :         CU_ASSERT_PTR_EQUAL(fgrp[2].fgrp->parent, NULL);;
     280                 :          3 :         CU_ASSERT_EQUAL(fgrp[0].fgrp->num_fds, fgrp[0].num_fds);
     281                 :          3 :         CU_ASSERT_EQUAL(fgrp[2].fgrp->num_fds, fgrp[2].num_fds);
     282                 :            : 
     283         [ +  + ]:         15 :         for (i = 0; i < SPDK_COUNTOF(fgrp); i++) {
     284         [ +  + ]:         36 :                 for (j = 0; j < fgrp[i].num_fds; j++) {
     285                 :         24 :                         spdk_fd_group_remove(fgrp[i].fgrp, fgrp[i].fd[j]);
     286                 :         24 :                         close(fgrp[i].fd[j]);
     287                 :            :                 }
     288                 :         12 :                 spdk_fd_group_destroy(fgrp[i].fgrp);
     289                 :            :         }
     290                 :          3 : }
     291                 :            : 
     292                 :            : int
     293                 :          3 : main(int argc, char **argv)
     294                 :            : {
     295                 :          3 :         CU_pSuite       suite = NULL;
     296                 :            :         unsigned int    num_failures;
     297                 :            : 
     298                 :          3 :         CU_initialize_registry();
     299                 :            : 
     300                 :          3 :         suite = CU_add_suite("fd_group", NULL, NULL);
     301                 :            : 
     302                 :          3 :         CU_ADD_TEST(suite, test_fd_group_basic);
     303                 :          3 :         CU_ADD_TEST(suite, test_fd_group_nest_unnest);
     304                 :          3 :         CU_ADD_TEST(suite, test_fd_group_multi_nest);
     305                 :            : 
     306                 :          3 :         num_failures = spdk_ut_run_tests(argc, argv, NULL);
     307                 :            : 
     308                 :          3 :         CU_cleanup_registry();
     309                 :            : 
     310                 :          3 :         return num_failures;
     311                 :            : }

Generated by: LCOV version 1.15