Home | History | Annotate | Line # | Download | only in tests
      1 /*	$NetBSD: isc.h,v 1.6 2026/04/08 00:16:17 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 /* cmocka<2.0.0 compatibility */
     72 #ifndef assert_int_in_range
     73 #define assert_int_in_range(value, min, max) \
     74 	assert_in_range((value), (min), (max))
     75 #endif
     76 #ifndef assert_uint_in_range
     77 #define assert_uint_in_range(value, min, max) \
     78 	assert_in_range((value), (min), (max))
     79 #endif
     80 
     81 /* clang-format off */
     82 /* Copied from cmocka */
     83 #define ISC_TEST_ENTRY(name)				\
     84 	{ #name, run_test_##name, NULL, NULL, NULL },
     85 #define ISC_TEST_ENTRY_SETUP(name) \
     86 	{ #name, run_test_##name, setup_test_##name, NULL, NULL },
     87 #define ISC_TEST_ENTRY_TEARDOWN(name) \
     88 	{ #name, run_test_##name, NULL, teardown_test_##name, NULL },
     89 #define ISC_TEST_ENTRY_SETUP_TEARDOWN(name) \
     90 	{ #name, run_test_##name, setup_test_##name, teardown_test_##name, NULL },
     91 #define ISC_TEST_ENTRY_CUSTOM(name, setup, teardown) \
     92 	{ #name, run_test_##name, setup, teardown, NULL },
     93 /* clang-format on */
     94 
     95 #define ISC_SETUP_TEST_DECLARE(name) \
     96 	int setup_test_##name(void **state ISC_ATTR_UNUSED);
     97 
     98 #define ISC_RUN_TEST_DECLARE(name) \
     99 	static void run_test_##name(void **state ISC_ATTR_UNUSED);
    100 
    101 #define ISC_TEARDOWN_TEST_DECLARE(name) \
    102 	int teardown_test_##name(void **state ISC_ATTR_UNUSED)
    103 
    104 #define ISC_LOOP_TEST_CUSTOM_DECLARE(name, setup, teardown) \
    105 	void run_test_##name(void **state ISC_ATTR_UNUSED); \
    106 	void loop_test_##name(void *arg ISC_ATTR_UNUSED);
    107 
    108 #define ISC_LOOP_TEST_DECLARE(name) \
    109 	ISC_LOOP_TEST_CUSTOM_DECLARE(name, NULL, NULL)
    110 
    111 #define ISC_LOOP_TEST_SETUP_DECLARE(name) \
    112 	ISC_LOOP_TEST_CUSTOM_DECLARE(name, setup_loop_##name, NULL)
    113 
    114 #define ISC_LOOP_TEST_SETUP_TEARDOWN_DECLARE(name)            \
    115 	ISC_LOOP_TEST_CUSTOM_DECLARE(name, setup_loop_##name, \
    116 				     teardown_loop_##name)
    117 
    118 #define ISC_LOOP_TEST_TEARDOWN_DECLARE(name) \
    119 	ISC_LOOP_TEST_CUSTOM_DECLARE(name, NULL, teardown_loop_##name)
    120 
    121 #define ISC_LOOP_SETUP_DECLARE(name) \
    122 	void setup_loop_##name(void *arg ISC_ATTR_UNUSED);
    123 
    124 #define ISC_SETUP_TEST_IMPL(name)                            \
    125 	int setup_test_##name(void **state ISC_ATTR_UNUSED); \
    126 	int setup_test_##name(void **state ISC_ATTR_UNUSED)
    127 
    128 #define ISC_RUN_TEST_IMPL(name)                                    \
    129 	static void run_test_##name(void **state ISC_ATTR_UNUSED); \
    130 	static void run_test_##name(void **state ISC_ATTR_UNUSED)
    131 
    132 #define ISC_TEARDOWN_TEST_IMPL(name)                            \
    133 	int teardown_test_##name(void **state ISC_ATTR_UNUSED); \
    134 	int teardown_test_##name(void **state ISC_ATTR_UNUSED)
    135 
    136 #define ISC_TEST_LIST_START const struct CMUnitTest tests[] = {
    137 #define ISC_TEST_LIST_END \
    138 	}                 \
    139 	;
    140 
    141 #define ISC_LOOP_TEST_CUSTOM_IMPL(name, setup, teardown)                   \
    142 	static void run_test_##name(void **state ISC_ATTR_UNUSED);         \
    143 	static void loop_test_##name(void *arg ISC_ATTR_UNUSED);           \
    144 	static void run_test_##name(void **state ISC_ATTR_UNUSED) {        \
    145 		isc_job_cb setup_loop = setup;                             \
    146 		isc_job_cb teardown_loop = teardown;                       \
    147 		if (setup_loop != NULL) {                                  \
    148 			isc_loop_setup(mainloop, setup_loop, state);       \
    149 		}                                                          \
    150 		if (teardown_loop != NULL) {                               \
    151 			isc_loop_teardown(mainloop, teardown_loop, state); \
    152 		}                                                          \
    153 		isc_loop_setup(mainloop, loop_test_##name, state);         \
    154 		isc_loopmgr_run(loopmgr);                                  \
    155 	}                                                                  \
    156 	static void loop_test_##name(void *arg ISC_ATTR_UNUSED)
    157 
    158 #define ISC_LOOP_TEST_IMPL(name) ISC_LOOP_TEST_CUSTOM_IMPL(name, NULL, NULL)
    159 
    160 #define ISC_LOOP_TEST_SETUP_IMPL(name) \
    161 	ISC_LOOP_TEST_CUSTOM_IMPL(name, setup_loop_##name, NULL)
    162 
    163 #define ISC_LOOP_TEST_SETUP_TEARDOWN_IMPL(name) \
    164 	ISC_LOOP_TEST_CUSTOM_IMPL(name, setup_loop_##name, teardown_loop_##name)
    165 
    166 #define ISC_LOOP_TEST_TEARDOWN_IMPL(name) \
    167 	ISC_LOOP_TEST_CUSTOM_IMPL(name, NULL, teardown_loop_##name)
    168 
    169 #define ISC_LOOP_SETUP_IMPL(name)                          \
    170 	void setup_loop_##name(void *arg ISC_ATTR_UNUSED); \
    171 	void setup_loop_##name(void *arg ISC_ATTR_UNUSED)
    172 
    173 #define ISC_LOOP_TEARDOWN_IMPL(name)                          \
    174 	void teardown_loop_##name(void *arg ISC_ATTR_UNUSED); \
    175 	void teardown_loop_##name(void *arg ISC_ATTR_UNUSED)
    176 
    177 #define ISC_TEST_DECLARE(name) void run_test_##name(void **state);
    178 
    179 #define ISC_TEST_LIST_START const struct CMUnitTest tests[] = {
    180 #define ISC_TEST_LIST_END \
    181 	}                 \
    182 	;
    183 
    184 #define ISC_TEST_MAIN ISC_TEST_MAIN_CUSTOM(NULL, NULL)
    185 
    186 #define ISC_TEST_MAIN_CUSTOM(setup, teardown)                                           \
    187 	int main(int argc, char **argv) {                                               \
    188 		int		  c, r;                                                 \
    189 		size_t		  i, j;                                                 \
    190 		struct CMUnitTest selected[ARRAY_SIZE(tests)];                          \
    191                                                                                         \
    192 		signal(SIGPIPE, SIG_IGN);                                               \
    193                                                                                         \
    194 		memset(selected, 0, sizeof(selected));                                  \
    195                                                                                         \
    196 		setup_mctx(NULL);                                                       \
    197 		setup_workers(NULL);                                                    \
    198                                                                                         \
    199 		while ((c = isc_commandline_parse(argc, argv, "dlt:")) !=               \
    200 		       -1) {                                                            \
    201 			switch (c) {                                                    \
    202 			case 'd':                                                       \
    203 				debug = true;                                           \
    204 				break;                                                  \
    205 			case 'l':                                                       \
    206 				for (i = 0;                                             \
    207 				     i < (sizeof(tests) / sizeof(tests[0]));            \
    208 				     i++)                                               \
    209 				{                                                       \
    210 					if (tests[i].name != NULL) {                    \
    211 						fprintf(stdout, "%s\n",                 \
    212 							tests[i].name);                 \
    213 					}                                               \
    214 				}                                                       \
    215 				return (0);                                             \
    216 			case 't':                                                       \
    217 				for (i = 0; i < ARRAY_SIZE(tests) &&                    \
    218 					    tests[i].name != NULL;                      \
    219 				     i++)                                               \
    220 				{                                                       \
    221 					if (strcmp(tests[i].name,                       \
    222 						   isc_commandline_argument) !=         \
    223 					    0)                                          \
    224 					{                                               \
    225 						continue;                               \
    226 					}                                               \
    227 					for (j = 0;                                     \
    228 					     j < ARRAY_SIZE(selected) &&                \
    229 					     selected[j].name != NULL;                  \
    230 					     j++)                                       \
    231 					{                                               \
    232 						if (strcmp(tests[j].name,               \
    233 							   isc_commandline_argument) == \
    234 						    0)                                  \
    235 						{                                       \
    236 							break;                          \
    237 						}                                       \
    238 					}                                               \
    239 					if (j < ARRAY_SIZE(selected) &&                 \
    240 					    selected[j].name == NULL)                   \
    241 					{                                               \
    242 						selected[j] = tests[i];                 \
    243 						break;                                  \
    244 					}                                               \
    245 				}                                                       \
    246 				if (i == ARRAY_SIZE(tests)) {                           \
    247 					fprintf(stderr, "unknown test '%s'\n",          \
    248 						isc_commandline_argument);              \
    249 					exit(1);                                        \
    250 				}                                                       \
    251 				break;                                                  \
    252 			default:                                                        \
    253 				fprintf(stderr, "Usage: %s [-dl] [-t test]\n",          \
    254 					argv[0]);                                       \
    255 				exit(1);                                                \
    256 			}                                                               \
    257 		}                                                                       \
    258                                                                                         \
    259 		if (selected[0].name != NULL) {                                         \
    260 			r = cmocka_run_group_tests(selected, setup, teardown);          \
    261 		} else {                                                                \
    262 			r = cmocka_run_group_tests(tests, setup, teardown);             \
    263 		}                                                                       \
    264                                                                                         \
    265 		isc_mem_destroy(&mctx);                                                 \
    266                                                                                         \
    267 		return (r);                                                             \
    268 	}
    269