xref: /netbsd-src/external/mpl/bind/dist/tests/include/tests/isc.h (revision bcda20f65a8566e103791ec395f7f499ef322704)
1 /*	$NetBSD: isc.h,v 1.4 2025/01/26 16:25:49 christos Exp $	*/
2 
3 /*
4  * Copyright (C) Internet Systems Consortium, Inc. ("ISC")
5  *
6  * SPDX-License-Identifier: MPL-2.0
7  *
8  * This Source Code Form is subject to the terms of the Mozilla Public
9  * License, v. 2.0. If a copy of the MPL was not distributed with this
10  * file, you can obtain one at https://mozilla.org/MPL/2.0/.
11  *
12  * See the COPYRIGHT file distributed with this work for additional
13  * information regarding copyright ownership.
14  */
15 
16 #pragma once
17 
18 /*! \file */
19 
20 #include <inttypes.h>
21 #include <stdbool.h>
22 
23 #include <isc/buffer.h>
24 #include <isc/commandline.h>
25 #include <isc/hash.h>
26 #include <isc/log.h>
27 #include <isc/mem.h>
28 #include <isc/netmgr.h>
29 #include <isc/result.h>
30 #include <isc/string.h>
31 #include <isc/timer.h>
32 #include <isc/util.h>
33 #include <isc/uv.h>
34 
35 extern isc_mem_t     *mctx;
36 extern isc_log_t     *lctx;
37 extern isc_loop_t    *mainloop;
38 extern isc_loopmgr_t *loopmgr;
39 extern isc_nm_t	     *netmgr;
40 extern int	      ncpus;
41 extern unsigned int   workers;
42 extern bool	      debug;
43 
44 int
45 setup_mctx(void **state);
46 int
47 teardown_mctx(void **state);
48 
49 int
50 setup_workers(void **state);
51 
52 int
53 setup_loopmgr(void **state);
54 int
55 teardown_loopmgr(void **state);
56 
57 int
58 setup_netmgr(void **state);
59 int
60 teardown_netmgr(void **state);
61 
62 int
63 setup_managers(void **state);
64 int
65 teardown_managers(void **state);
66 
67 #ifndef TESTS_DIR
68 #define TESTS_DIR "./"
69 #endif
70 
71 /* clang-format off */
72 /* Copied from cmocka */
73 #define ISC_TEST_ENTRY(name)				\
74 	{ #name, run_test_##name, NULL, NULL, NULL },
75 #define ISC_TEST_ENTRY_SETUP(name) \
76 	{ #name, run_test_##name, setup_test_##name, NULL, NULL },
77 #define ISC_TEST_ENTRY_TEARDOWN(name) \
78 	{ #name, run_test_##name, NULL, teardown_test_##name, NULL },
79 #define ISC_TEST_ENTRY_SETUP_TEARDOWN(name) \
80 	{ #name, run_test_##name, setup_test_##name, teardown_test_##name, NULL },
81 #define ISC_TEST_ENTRY_CUSTOM(name, setup, teardown) \
82 	{ #name, run_test_##name, setup, teardown, NULL },
83 /* clang-format on */
84 
85 #define ISC_SETUP_TEST_DECLARE(name) \
86 	int setup_test_##name(void **state ISC_ATTR_UNUSED);
87 
88 #define ISC_RUN_TEST_DECLARE(name) \
89 	void run_test_##name(void **state ISC_ATTR_UNUSED);
90 
91 #define ISC_TEARDOWN_TEST_DECLARE(name) \
92 	int teardown_test_##name(void **state ISC_ATTR_UNUSED)
93 
94 #define ISC_LOOP_TEST_CUSTOM_DECLARE(name, setup, teardown) \
95 	void run_test_##name(void **state ISC_ATTR_UNUSED); \
96 	void loop_test_##name(void *arg ISC_ATTR_UNUSED);
97 
98 #define ISC_LOOP_TEST_DECLARE(name) \
99 	ISC_LOOP_TEST_CUSTOM_DECLARE(name, NULL, NULL)
100 
101 #define ISC_LOOP_TEST_SETUP_DECLARE(name) \
102 	ISC_LOOP_TEST_CUSTOM_DECLARE(name, setup_loop_##name, NULL)
103 
104 #define ISC_LOOP_TEST_SETUP_TEARDOWN_DECLARE(name)            \
105 	ISC_LOOP_TEST_CUSTOM_DECLARE(name, setup_loop_##name, \
106 				     teardown_loop_##name)
107 
108 #define ISC_LOOP_TEST_TEARDOWN_DECLARE(name) \
109 	ISC_LOOP_TEST_CUSTOM_DECLARE(name, NULL, teardown_loop_##name)
110 
111 #define ISC_LOOP_SETUP_DECLARE(name) \
112 	void setup_loop_##name(void *arg ISC_ATTR_UNUSED);
113 
114 #define ISC_SETUP_TEST_IMPL(name)                            \
115 	int setup_test_##name(void **state ISC_ATTR_UNUSED); \
116 	int setup_test_##name(void **state ISC_ATTR_UNUSED)
117 
118 #define ISC_RUN_TEST_IMPL(name)                             \
119 	void run_test_##name(void **state ISC_ATTR_UNUSED); \
120 	void run_test_##name(void **state ISC_ATTR_UNUSED)
121 
122 #define ISC_TEARDOWN_TEST_IMPL(name)                            \
123 	int teardown_test_##name(void **state ISC_ATTR_UNUSED); \
124 	int teardown_test_##name(void **state ISC_ATTR_UNUSED)
125 
126 #define ISC_TEST_LIST_START const struct CMUnitTest tests[] = {
127 #define ISC_TEST_LIST_END \
128 	}                 \
129 	;
130 
131 #define ISC_LOOP_TEST_CUSTOM_IMPL(name, setup, teardown)                   \
132 	void run_test_##name(void **state ISC_ATTR_UNUSED);                \
133 	void loop_test_##name(void *arg ISC_ATTR_UNUSED);                  \
134 	void run_test_##name(void **state ISC_ATTR_UNUSED) {               \
135 		isc_job_cb setup_loop = setup;                             \
136 		isc_job_cb teardown_loop = teardown;                       \
137 		if (setup_loop != NULL) {                                  \
138 			isc_loop_setup(mainloop, setup_loop, state);       \
139 		}                                                          \
140 		if (teardown_loop != NULL) {                               \
141 			isc_loop_teardown(mainloop, teardown_loop, state); \
142 		}                                                          \
143 		isc_loop_setup(mainloop, loop_test_##name, state);         \
144 		isc_loopmgr_run(loopmgr);                                  \
145 	}                                                                  \
146 	void loop_test_##name(void *arg ISC_ATTR_UNUSED)
147 
148 #define ISC_LOOP_TEST_IMPL(name) ISC_LOOP_TEST_CUSTOM_IMPL(name, NULL, NULL)
149 
150 #define ISC_LOOP_TEST_SETUP_IMPL(name) \
151 	ISC_LOOP_TEST_CUSTOM_IMPL(name, setup_loop_##name, NULL)
152 
153 #define ISC_LOOP_TEST_SETUP_TEARDOWN_IMPL(name) \
154 	ISC_LOOP_TEST_CUSTOM_IMPL(name, setup_loop_##name, teardown_loop_##name)
155 
156 #define ISC_LOOP_TEST_TEARDOWN_IMPL(name) \
157 	ISC_LOOP_TEST_CUSTOM_IMPL(name, NULL, teardown_loop_##name)
158 
159 #define ISC_LOOP_SETUP_IMPL(name)                          \
160 	void setup_loop_##name(void *arg ISC_ATTR_UNUSED); \
161 	void setup_loop_##name(void *arg ISC_ATTR_UNUSED)
162 
163 #define ISC_LOOP_TEARDOWN_IMPL(name)                          \
164 	void teardown_loop_##name(void *arg ISC_ATTR_UNUSED); \
165 	void teardown_loop_##name(void *arg ISC_ATTR_UNUSED)
166 
167 #define ISC_TEST_DECLARE(name) void run_test_##name(void **state);
168 
169 #define ISC_TEST_LIST_START const struct CMUnitTest tests[] = {
170 #define ISC_TEST_LIST_END \
171 	}                 \
172 	;
173 
174 #define ISC_TEST_MAIN ISC_TEST_MAIN_CUSTOM(NULL, NULL)
175 
176 #define ISC_TEST_MAIN_CUSTOM(setup, teardown)                                           \
177 	int main(int argc, char **argv) {                                               \
178 		int		  c, r;                                                 \
179 		size_t		  i, j;                                                 \
180 		struct CMUnitTest selected[ARRAY_SIZE(tests)];                          \
181                                                                                         \
182 		signal(SIGPIPE, SIG_IGN);                                               \
183                                                                                         \
184 		memset(selected, 0, sizeof(selected));                                  \
185                                                                                         \
186 		setup_mctx(NULL);                                                       \
187 		setup_workers(NULL);                                                    \
188                                                                                         \
189 		while ((c = isc_commandline_parse(argc, argv, "dlt:")) != -1)           \
190 		{                                                                       \
191 			switch (c) {                                                    \
192 			case 'd':                                                       \
193 				debug = true;                                           \
194 				break;                                                  \
195 			case 'l':                                                       \
196 				for (i = 0;                                             \
197 				     i < (sizeof(tests) / sizeof(tests[0]));            \
198 				     i++)                                               \
199 				{                                                       \
200 					if (tests[i].name != NULL) {                    \
201 						fprintf(stdout, "%s\n",                 \
202 							tests[i].name);                 \
203 					}                                               \
204 				}                                                       \
205 				return (0);                                             \
206 			case 't':                                                       \
207 				for (i = 0; i < ARRAY_SIZE(tests) &&                    \
208 					    tests[i].name != NULL;                      \
209 				     i++)                                               \
210 				{                                                       \
211 					if (strcmp(tests[i].name,                       \
212 						   isc_commandline_argument) !=         \
213 					    0)                                          \
214 					{                                               \
215 						continue;                               \
216 					}                                               \
217 					for (j = 0;                                     \
218 					     j < ARRAY_SIZE(selected) &&                \
219 					     selected[j].name != NULL;                  \
220 					     j++)                                       \
221 					{                                               \
222 						if (strcmp(tests[j].name,               \
223 							   isc_commandline_argument) == \
224 						    0)                                  \
225 						{                                       \
226 							break;                          \
227 						}                                       \
228 					}                                               \
229 					if (j < ARRAY_SIZE(selected) &&                 \
230 					    selected[j].name == NULL)                   \
231 					{                                               \
232 						selected[j] = tests[i];                 \
233 						break;                                  \
234 					}                                               \
235 				}                                                       \
236 				if (i == ARRAY_SIZE(tests)) {                           \
237 					fprintf(stderr, "unknown test '%s'\n",          \
238 						isc_commandline_argument);              \
239 					exit(1);                                        \
240 				}                                                       \
241 				break;                                                  \
242 			default:                                                        \
243 				fprintf(stderr, "Usage: %s [-dl] [-t test]\n",          \
244 					argv[0]);                                       \
245 				exit(1);                                                \
246 			}                                                               \
247 		}                                                                       \
248                                                                                         \
249 		if (selected[0].name != NULL) {                                         \
250 			r = cmocka_run_group_tests(selected, setup, teardown);          \
251 		} else {                                                                \
252 			r = cmocka_run_group_tests(tests, setup, teardown);             \
253 		}                                                                       \
254                                                                                         \
255 		isc_mem_destroy(&mctx);                                                 \
256                                                                                         \
257 		return (r);                                                             \
258 	}
259