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 fd_group_cb_fn(void *ctx) 12 { 13 return 0; 14 } 15 16 static void 17 test_fd_group_basic(void) 18 { 19 struct spdk_fd_group *fgrp; 20 struct event_handler *ehdlr = NULL; 21 int fd; 22 int rc; 23 int cb_arg; 24 25 rc = spdk_fd_group_create(&fgrp); 26 SPDK_CU_ASSERT_FATAL(rc == 0); 27 28 fd = epoll_create1(0); 29 SPDK_CU_ASSERT_FATAL(fd >= 0); 30 31 rc = SPDK_FD_GROUP_ADD(fgrp, fd, fd_group_cb_fn, &cb_arg); 32 SPDK_CU_ASSERT_FATAL(rc == 0); 33 SPDK_CU_ASSERT_FATAL(fgrp->num_fds == 1); 34 35 /* Verify that event handler is initialized correctly */ 36 ehdlr = TAILQ_FIRST(&fgrp->event_handlers); 37 SPDK_CU_ASSERT_FATAL(ehdlr != NULL); 38 CU_ASSERT(ehdlr->fd == fd); 39 CU_ASSERT(ehdlr->state == EVENT_HANDLER_STATE_WAITING); 40 CU_ASSERT(ehdlr->events == EPOLLIN); 41 42 /* Modify event type and see if event handler is updated correctly */ 43 rc = spdk_fd_group_event_modify(fgrp, fd, EPOLLIN | EPOLLERR); 44 SPDK_CU_ASSERT_FATAL(rc == 0); 45 46 ehdlr = TAILQ_FIRST(&fgrp->event_handlers); 47 SPDK_CU_ASSERT_FATAL(ehdlr != NULL); 48 CU_ASSERT(ehdlr->events == (EPOLLIN | EPOLLERR)); 49 50 spdk_fd_group_remove(fgrp, fd); 51 SPDK_CU_ASSERT_FATAL(fgrp->num_fds == 0); 52 53 rc = close(fd); 54 CU_ASSERT(rc == 0); 55 56 spdk_fd_group_destroy(fgrp); 57 } 58 59 static void 60 test_fd_group_nest_unnest(void) 61 { 62 struct spdk_fd_group *parent, *child, *not_parent; 63 int fd_parent, fd_child, fd_child_2; 64 int rc; 65 int cb_arg; 66 67 rc = spdk_fd_group_create(&parent); 68 SPDK_CU_ASSERT_FATAL(rc == 0); 69 70 rc = spdk_fd_group_create(&child); 71 SPDK_CU_ASSERT_FATAL(rc == 0); 72 73 rc = spdk_fd_group_create(¬_parent); 74 SPDK_CU_ASSERT_FATAL(rc == 0); 75 76 fd_parent = epoll_create1(0); 77 SPDK_CU_ASSERT_FATAL(fd_parent >= 0); 78 79 fd_child = epoll_create1(0); 80 SPDK_CU_ASSERT_FATAL(fd_child >= 0); 81 82 fd_child_2 = epoll_create1(0); 83 SPDK_CU_ASSERT_FATAL(fd_child_2 >= 0); 84 85 rc = SPDK_FD_GROUP_ADD(parent, fd_parent, fd_group_cb_fn, &cb_arg); 86 SPDK_CU_ASSERT_FATAL(rc == 0); 87 SPDK_CU_ASSERT_FATAL(parent->num_fds == 1); 88 89 rc = SPDK_FD_GROUP_ADD(child, fd_child, fd_group_cb_fn, &cb_arg); 90 SPDK_CU_ASSERT_FATAL(rc == 0); 91 SPDK_CU_ASSERT_FATAL(child->num_fds == 1); 92 93 /* Nest child fd group to a parent fd group and verify their relation */ 94 rc = spdk_fd_group_nest(parent, child); 95 SPDK_CU_ASSERT_FATAL(rc == 0); 96 SPDK_CU_ASSERT_FATAL(child->parent == parent); 97 SPDK_CU_ASSERT_FATAL(parent->num_fds == 2); 98 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 rc = SPDK_FD_GROUP_ADD(child, fd_child_2, fd_group_cb_fn, &cb_arg); 104 SPDK_CU_ASSERT_FATAL(rc == 0); 105 SPDK_CU_ASSERT_FATAL(child->num_fds == 0); 106 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 rc = spdk_fd_group_unnest(not_parent, child); 110 SPDK_CU_ASSERT_FATAL(rc == -EINVAL); 111 112 /* Unnest child fd group from its parent fd group and verify it. */ 113 rc = spdk_fd_group_unnest(parent, child); 114 SPDK_CU_ASSERT_FATAL(rc == 0); 115 SPDK_CU_ASSERT_FATAL(child->parent == NULL); 116 SPDK_CU_ASSERT_FATAL(parent->num_fds == 1); 117 SPDK_CU_ASSERT_FATAL(child->num_fds == 2); 118 119 spdk_fd_group_remove(child, fd_child); 120 SPDK_CU_ASSERT_FATAL(child->num_fds == 1); 121 122 spdk_fd_group_remove(child, fd_child_2); 123 SPDK_CU_ASSERT_FATAL(child->num_fds == 0); 124 125 spdk_fd_group_remove(parent, fd_parent); 126 SPDK_CU_ASSERT_FATAL(parent->num_fds == 0); 127 128 rc = close(fd_child); 129 CU_ASSERT(rc == 0); 130 131 rc = close(fd_child_2); 132 CU_ASSERT(rc == 0); 133 134 rc = close(fd_parent); 135 CU_ASSERT(rc == 0); 136 137 spdk_fd_group_destroy(child); 138 spdk_fd_group_destroy(parent); 139 spdk_fd_group_destroy(not_parent); 140 } 141 142 int 143 main(int argc, char **argv) 144 { 145 CU_pSuite suite = NULL; 146 unsigned int num_failures; 147 148 CU_initialize_registry(); 149 150 suite = CU_add_suite("fd_group", NULL, NULL); 151 152 CU_ADD_TEST(suite, test_fd_group_basic); 153 CU_ADD_TEST(suite, test_fd_group_nest_unnest); 154 155 num_failures = spdk_ut_run_tests(argc, argv, NULL); 156 157 CU_cleanup_registry(); 158 159 return num_failures; 160 } 161