xref: /netbsd-src/external/mpl/bind/dist/tests/isc/loop_test.c (revision bcda20f65a8566e103791ec395f7f499ef322704)
1 /*	$NetBSD: loop_test.c,v 1.2 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 #include <inttypes.h>
17 #include <sched.h> /* IWYU pragma: keep */
18 #include <setjmp.h>
19 #include <stdarg.h>
20 #include <stddef.h>
21 #include <stdlib.h>
22 #include <string.h>
23 #include <sys/types.h>
24 #include <unistd.h>
25 
26 #define UNIT_TESTING
27 #include <cmocka.h>
28 
29 #include <isc/atomic.h>
30 #include <isc/loop.h>
31 #include <isc/os.h>
32 #include <isc/result.h>
33 #include <isc/util.h>
34 
35 #include "loop.c"
36 
37 #include <tests/isc.h>
38 
39 static atomic_uint scheduled = 0;
40 
41 static void
42 count(void *arg) {
43 	UNUSED(arg);
44 
45 	atomic_fetch_add(&scheduled, 1);
46 }
47 
48 static void
49 shutdown_loopmgr(void *arg) {
50 	UNUSED(arg);
51 
52 	while (atomic_load(&scheduled) != loopmgr->nloops) {
53 		isc_thread_yield();
54 	}
55 
56 	isc_loopmgr_shutdown(loopmgr);
57 }
58 
59 ISC_RUN_TEST_IMPL(isc_loopmgr) {
60 	atomic_store(&scheduled, 0);
61 
62 	isc_loopmgr_setup(loopmgr, count, loopmgr);
63 	isc_loop_setup(mainloop, shutdown_loopmgr, loopmgr);
64 
65 	isc_loopmgr_run(loopmgr);
66 
67 	assert_int_equal(atomic_load(&scheduled), loopmgr->nloops);
68 }
69 
70 static void
71 runjob(void *arg ISC_ATTR_UNUSED) {
72 	isc_async_current(count, loopmgr);
73 	if (isc_tid() == 0) {
74 		isc_async_current(shutdown_loopmgr, loopmgr);
75 	}
76 }
77 
78 ISC_RUN_TEST_IMPL(isc_loopmgr_runjob) {
79 	atomic_store(&scheduled, 0);
80 
81 	isc_loopmgr_setup(loopmgr, runjob, loopmgr);
82 	isc_loopmgr_run(loopmgr);
83 	assert_int_equal(atomic_load(&scheduled), loopmgr->nloops);
84 }
85 
86 static void
87 pause_loopmgr(void *arg) {
88 	UNUSED(arg);
89 
90 	isc_loopmgr_pause(loopmgr);
91 
92 	assert_true(atomic_load(&loopmgr->paused));
93 
94 	for (size_t i = 0; i < loopmgr->nloops; i++) {
95 		isc_loop_t *loop = &loopmgr->loops[i];
96 
97 		assert_true(loop->paused);
98 	}
99 
100 	atomic_init(&scheduled, loopmgr->nloops);
101 
102 	isc_loopmgr_resume(loopmgr);
103 }
104 
105 ISC_RUN_TEST_IMPL(isc_loopmgr_pause) {
106 	isc_loop_setup(mainloop, pause_loopmgr, loopmgr);
107 	isc_loop_setup(mainloop, shutdown_loopmgr, loopmgr);
108 	isc_loopmgr_run(loopmgr);
109 }
110 
111 static void
112 send_sigint(void *arg) {
113 	UNUSED(arg);
114 
115 	kill(getpid(), SIGINT);
116 }
117 
118 ISC_RUN_TEST_IMPL(isc_loopmgr_sigint) {
119 	isc_loop_setup(mainloop, send_sigint, loopmgr);
120 	isc_loopmgr_run(loopmgr);
121 }
122 
123 static void
124 send_sigterm(void *arg) {
125 	UNUSED(arg);
126 
127 	kill(getpid(), SIGINT);
128 }
129 
130 ISC_RUN_TEST_IMPL(isc_loopmgr_sigterm) {
131 	isc_loop_setup(mainloop, send_sigterm, loopmgr);
132 	isc_loopmgr_run(loopmgr);
133 }
134 
135 ISC_TEST_LIST_START
136 ISC_TEST_ENTRY_CUSTOM(isc_loopmgr, setup_loopmgr, teardown_loopmgr)
137 ISC_TEST_ENTRY_CUSTOM(isc_loopmgr_pause, setup_loopmgr, teardown_loopmgr)
138 ISC_TEST_ENTRY_CUSTOM(isc_loopmgr_runjob, setup_loopmgr, teardown_loopmgr)
139 ISC_TEST_ENTRY_CUSTOM(isc_loopmgr_sigint, setup_loopmgr, teardown_loopmgr)
140 ISC_TEST_ENTRY_CUSTOM(isc_loopmgr_sigterm, setup_loopmgr, teardown_loopmgr)
141 ISC_TEST_LIST_END
142 
143 ISC_TEST_MAIN
144