1 /*
2  * Copyright (C) Internet Systems Consortium, Inc. ("ISC")
3  *
4  * This Source Code Form is subject to the terms of the Mozilla Public
5  * License, v. 2.0. If a copy of the MPL was not distributed with this
6  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
7  *
8  * See the COPYRIGHT file distributed with this work for additional
9  * information regarding copyright ownership.
10  */
11 
12 #if HAVE_CMOCKA
13 
14 #include <sched.h> /* IWYU pragma: keep */
15 #include <setjmp.h>
16 #include <stdarg.h>
17 #include <stddef.h>
18 #include <stdlib.h>
19 #include <unistd.h>
20 
21 #define UNIT_TESTING
22 #include <cmocka.h>
23 
24 #include <isc/app.h>
25 #include <isc/buffer.h>
26 #include <isc/print.h>
27 #include <isc/socket.h>
28 #include <isc/task.h>
29 #include <isc/timer.h>
30 #include <isc/util.h>
31 
32 #include <dns/dispatch.h>
33 #include <dns/name.h>
34 #include <dns/resolver.h>
35 #include <dns/view.h>
36 
37 #include "dnstest.h"
38 
39 static dns_dispatchmgr_t *dispatchmgr = NULL;
40 static dns_dispatch_t *dispatch = NULL;
41 static dns_view_t *view = NULL;
42 
43 static int
_setup(void ** state)44 _setup(void **state) {
45 	isc_result_t result;
46 	isc_sockaddr_t local;
47 
48 	UNUSED(state);
49 
50 	result = dns_test_begin(NULL, true);
51 	assert_int_equal(result, ISC_R_SUCCESS);
52 
53 	result = dns_dispatchmgr_create(dt_mctx, &dispatchmgr);
54 	assert_int_equal(result, ISC_R_SUCCESS);
55 
56 	result = dns_test_makeview("view", &view);
57 	assert_int_equal(result, ISC_R_SUCCESS);
58 
59 	isc_sockaddr_any(&local);
60 	result = dns_dispatch_getudp(dispatchmgr, socketmgr, taskmgr, &local,
61 				     4096, 100, 100, 100, 500, 0, 0, &dispatch);
62 	assert_int_equal(result, ISC_R_SUCCESS);
63 
64 	return (0);
65 }
66 
67 static int
_teardown(void ** state)68 _teardown(void **state) {
69 	UNUSED(state);
70 
71 	dns_dispatch_detach(&dispatch);
72 	dns_view_detach(&view);
73 	dns_dispatchmgr_destroy(&dispatchmgr);
74 	dns_test_end();
75 
76 	return (0);
77 }
78 
79 static void
mkres(dns_resolver_t ** resolverp)80 mkres(dns_resolver_t **resolverp) {
81 	isc_result_t result;
82 
83 	result = dns_resolver_create(view, taskmgr, 1, 1, socketmgr, timermgr,
84 				     0, dispatchmgr, dispatch, NULL, resolverp);
85 	assert_int_equal(result, ISC_R_SUCCESS);
86 }
87 
88 static void
destroy_resolver(dns_resolver_t ** resolverp)89 destroy_resolver(dns_resolver_t **resolverp) {
90 	dns_resolver_shutdown(*resolverp);
91 	dns_resolver_detach(resolverp);
92 }
93 
94 /* dns_resolver_create */
95 static void
create_test(void ** state)96 create_test(void **state) {
97 	dns_resolver_t *resolver = NULL;
98 
99 	UNUSED(state);
100 
101 	mkres(&resolver);
102 	destroy_resolver(&resolver);
103 }
104 
105 /* dns_resolver_gettimeout */
106 static void
gettimeout_test(void ** state)107 gettimeout_test(void **state) {
108 	dns_resolver_t *resolver = NULL;
109 	unsigned int timeout;
110 
111 	UNUSED(state);
112 
113 	mkres(&resolver);
114 
115 	timeout = dns_resolver_gettimeout(resolver);
116 	assert_true(timeout > 0);
117 
118 	destroy_resolver(&resolver);
119 }
120 
121 /* dns_resolver_settimeout */
122 static void
settimeout_test(void ** state)123 settimeout_test(void **state) {
124 	dns_resolver_t *resolver = NULL;
125 	unsigned int default_timeout, timeout;
126 
127 	UNUSED(state);
128 
129 	mkres(&resolver);
130 
131 	default_timeout = dns_resolver_gettimeout(resolver);
132 	dns_resolver_settimeout(resolver, default_timeout + 1);
133 	timeout = dns_resolver_gettimeout(resolver);
134 	assert_true(timeout == default_timeout + 1);
135 
136 	destroy_resolver(&resolver);
137 }
138 
139 /* dns_resolver_settimeout */
140 static void
settimeout_default_test(void ** state)141 settimeout_default_test(void **state) {
142 	dns_resolver_t *resolver = NULL;
143 	unsigned int default_timeout, timeout;
144 
145 	UNUSED(state);
146 
147 	mkres(&resolver);
148 
149 	default_timeout = dns_resolver_gettimeout(resolver);
150 	dns_resolver_settimeout(resolver, default_timeout + 100);
151 
152 	timeout = dns_resolver_gettimeout(resolver);
153 	assert_int_equal(timeout, default_timeout + 100);
154 
155 	dns_resolver_settimeout(resolver, 0);
156 	timeout = dns_resolver_gettimeout(resolver);
157 	assert_int_equal(timeout, default_timeout);
158 
159 	destroy_resolver(&resolver);
160 }
161 
162 /* dns_resolver_settimeout below minimum */
163 static void
settimeout_belowmin_test(void ** state)164 settimeout_belowmin_test(void **state) {
165 	dns_resolver_t *resolver = NULL;
166 	unsigned int default_timeout, timeout;
167 
168 	UNUSED(state);
169 
170 	mkres(&resolver);
171 
172 	default_timeout = dns_resolver_gettimeout(resolver);
173 	dns_resolver_settimeout(resolver, 9000);
174 
175 	timeout = dns_resolver_gettimeout(resolver);
176 	assert_int_equal(timeout, default_timeout);
177 
178 	destroy_resolver(&resolver);
179 }
180 
181 /* dns_resolver_settimeout over maximum */
182 static void
settimeout_overmax_test(void ** state)183 settimeout_overmax_test(void **state) {
184 	dns_resolver_t *resolver = NULL;
185 	unsigned int timeout;
186 
187 	UNUSED(state);
188 
189 	mkres(&resolver);
190 
191 	dns_resolver_settimeout(resolver, 4000000);
192 	timeout = dns_resolver_gettimeout(resolver);
193 	assert_in_range(timeout, 0, 3999999);
194 	destroy_resolver(&resolver);
195 }
196 
197 int
main(void)198 main(void) {
199 	const struct CMUnitTest tests[] = {
200 		cmocka_unit_test_setup_teardown(create_test, _setup, _teardown),
201 		cmocka_unit_test_setup_teardown(gettimeout_test, _setup,
202 						_teardown),
203 		cmocka_unit_test_setup_teardown(settimeout_test, _setup,
204 						_teardown),
205 		cmocka_unit_test_setup_teardown(settimeout_default_test, _setup,
206 						_teardown),
207 		cmocka_unit_test_setup_teardown(settimeout_belowmin_test,
208 						_setup, _teardown),
209 		cmocka_unit_test_setup_teardown(settimeout_overmax_test, _setup,
210 						_teardown),
211 	};
212 
213 	return (cmocka_run_group_tests(tests, NULL, NULL));
214 }
215 
216 #else /* HAVE_CMOCKA */
217 
218 #include <stdio.h>
219 
220 int
main(void)221 main(void) {
222 	printf("1..0 # Skipped: cmocka not available\n");
223 	return (0);
224 }
225 
226 #endif /* if HAVE_CMOCKA */
227