xref: /spdk/test/unit/lib/util/fd_group.c/fd_group_ut.c (revision 318515b44ec8b67f83bcc9ca83f0c7d5ea919e62)
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(&not_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