xref: /minix/external/bsd/bind/dist/lib/dns/tests/dnstest.c (revision 00b67f09)
1 /*	$NetBSD: dnstest.c,v 1.1.1.6 2014/12/10 03:34:42 christos Exp $	*/
2 
3 /*
4  * Copyright (C) 2011-2014  Internet Systems Consortium, Inc. ("ISC")
5  *
6  * Permission to use, copy, modify, and/or distribute this software for any
7  * purpose with or without fee is hereby granted, provided that the above
8  * copyright notice and this permission notice appear in all copies.
9  *
10  * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
11  * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
12  * AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
13  * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
14  * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
15  * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
16  * PERFORMANCE OF THIS SOFTWARE.
17  */
18 
19 /* Id */
20 
21 /*! \file */
22 
23 #include <config.h>
24 
25 #include <time.h>
26 #include <unistd.h>
27 
28 #include <isc/app.h>
29 #include <isc/buffer.h>
30 #include <isc/entropy.h>
31 #include <isc/hash.h>
32 #include <isc/mem.h>
33 #include <isc/os.h>
34 #include <isc/string.h>
35 #include <isc/socket.h>
36 #include <isc/task.h>
37 #include <isc/timer.h>
38 #include <isc/util.h>
39 
40 #include <dns/db.h>
41 #include <dns/fixedname.h>
42 #include <dns/log.h>
43 #include <dns/name.h>
44 #include <dns/result.h>
45 #include <dns/view.h>
46 #include <dns/zone.h>
47 
48 #include <dst/dst.h>
49 
50 #include "dnstest.h"
51 
52 isc_mem_t *mctx = NULL;
53 isc_entropy_t *ectx = NULL;
54 isc_log_t *lctx = NULL;
55 isc_taskmgr_t *taskmgr = NULL;
56 isc_task_t *maintask = NULL;
57 isc_timermgr_t *timermgr = NULL;
58 isc_socketmgr_t *socketmgr = NULL;
59 dns_zonemgr_t *zonemgr = NULL;
60 isc_boolean_t app_running = ISC_FALSE;
61 int ncpus;
62 
63 static isc_boolean_t hash_active = ISC_FALSE, dst_active = ISC_FALSE;
64 
65 /*
66  * Logging categories: this needs to match the list in bin/named/log.c.
67  */
68 static isc_logcategory_t categories[] = {
69 		{ "",                0 },
70 		{ "client",          0 },
71 		{ "network",         0 },
72 		{ "update",          0 },
73 		{ "queries",         0 },
74 		{ "unmatched",       0 },
75 		{ "update-security", 0 },
76 		{ "query-errors",    0 },
77 		{ NULL,              0 }
78 };
79 
80 static void
cleanup_managers(void)81 cleanup_managers(void) {
82 	if (app_running)
83 		isc_app_finish();
84 	if (socketmgr != NULL)
85 		isc_socketmgr_destroy(&socketmgr);
86 	if (maintask != NULL)
87 		isc_task_destroy(&maintask);
88 	if (taskmgr != NULL)
89 		isc_taskmgr_destroy(&taskmgr);
90 	if (timermgr != NULL)
91 		isc_timermgr_destroy(&timermgr);
92 }
93 
94 static isc_result_t
create_managers(void)95 create_managers(void) {
96 	isc_result_t result;
97 #ifdef ISC_PLATFORM_USETHREADS
98 	ncpus = isc_os_ncpus();
99 #else
100 	ncpus = 1;
101 #endif
102 
103 	CHECK(isc_taskmgr_create(mctx, ncpus, 0, &taskmgr));
104 	CHECK(isc_timermgr_create(mctx, &timermgr));
105 	CHECK(isc_socketmgr_create(mctx, &socketmgr));
106 	CHECK(isc_task_create(taskmgr, 0, &maintask));
107 	return (ISC_R_SUCCESS);
108 
109   cleanup:
110 	cleanup_managers();
111 	return (result);
112 }
113 
114 isc_result_t
dns_test_begin(FILE * logfile,isc_boolean_t start_managers)115 dns_test_begin(FILE *logfile, isc_boolean_t start_managers) {
116 	isc_result_t result;
117 
118 	if (start_managers)
119 		CHECK(isc_app_start());
120 	isc_mem_debugging |= ISC_MEM_DEBUGRECORD;
121 	CHECK(isc_mem_create(0, 0, &mctx));
122 	CHECK(isc_entropy_create(mctx, &ectx));
123 
124 	CHECK(isc_hash_create(mctx, ectx, DNS_NAME_MAXWIRE));
125 	hash_active = ISC_TRUE;
126 
127 	CHECK(dst_lib_init(mctx, ectx, ISC_ENTROPY_BLOCKING));
128 	dst_active = ISC_TRUE;
129 
130 	if (logfile != NULL) {
131 		isc_logdestination_t destination;
132 		isc_logconfig_t *logconfig = NULL;
133 
134 		CHECK(isc_log_create(mctx, &lctx, &logconfig));
135 		isc_log_registercategories(lctx, categories);
136 		isc_log_setcontext(lctx);
137 		dns_log_init(lctx);
138 		dns_log_setcontext(lctx);
139 
140 		destination.file.stream = logfile;
141 		destination.file.name = NULL;
142 		destination.file.versions = ISC_LOG_ROLLNEVER;
143 		destination.file.maximum_size = 0;
144 		CHECK(isc_log_createchannel(logconfig, "stderr",
145 					    ISC_LOG_TOFILEDESC,
146 					    ISC_LOG_DYNAMIC,
147 					    &destination, 0));
148 		CHECK(isc_log_usechannel(logconfig, "stderr", NULL, NULL));
149 	}
150 
151 	dns_result_register();
152 
153 	if (start_managers)
154 		CHECK(create_managers());
155 
156 	/*
157 	 * atf-run changes us to a /tmp directory, so tests
158 	 * that access test data files must first chdir to the proper
159 	 * location.
160 	 */
161 	if (chdir(TESTS) == -1)
162 		CHECK(ISC_R_FAILURE);
163 
164 	return (ISC_R_SUCCESS);
165 
166   cleanup:
167 	dns_test_end();
168 	return (result);
169 }
170 
171 void
dns_test_end(void)172 dns_test_end(void) {
173 	if (lctx != NULL)
174 		isc_log_destroy(&lctx);
175 	if (dst_active) {
176 		dst_lib_destroy();
177 		dst_active = ISC_FALSE;
178 	}
179 	if (hash_active) {
180 		isc_hash_destroy();
181 		hash_active = ISC_FALSE;
182 	}
183 	if (ectx != NULL)
184 		isc_entropy_detach(&ectx);
185 
186 	cleanup_managers();
187 
188 	if (mctx != NULL)
189 		isc_mem_destroy(&mctx);
190 }
191 
192 /*
193  * Create a zone with origin 'name', return a pointer to the zone object in
194  * 'zonep'.  If 'view' is set, add the zone to that view; otherwise, create
195  * a new view for the purpose.
196  *
197  * If the created view is going to be needed by the caller subsequently,
198  * then 'keepview' should be set to true; this will prevent the view
199  * from being detached.  In this case, the caller is responsible for
200  * detaching the view.
201  */
202 isc_result_t
dns_test_makezone(const char * name,dns_zone_t ** zonep,dns_view_t * view,isc_boolean_t keepview)203 dns_test_makezone(const char *name, dns_zone_t **zonep, dns_view_t *view,
204 		  isc_boolean_t keepview)
205 {
206 	isc_result_t result;
207 	dns_zone_t *zone = NULL;
208 	isc_buffer_t buffer;
209 	dns_fixedname_t fixorigin;
210 	dns_name_t *origin;
211 
212 	if (view == NULL)
213 		CHECK(dns_view_create(mctx, dns_rdataclass_in, "view", &view));
214 	else if (!keepview)
215 		keepview = ISC_TRUE;
216 
217 	zone = *zonep;
218 	if (zone == NULL)
219 		CHECK(dns_zone_create(&zone, mctx));
220 
221 	isc_buffer_constinit(&buffer, name, strlen(name));
222 	isc_buffer_add(&buffer, strlen(name));
223 	dns_fixedname_init(&fixorigin);
224 	origin = dns_fixedname_name(&fixorigin);
225 	CHECK(dns_name_fromtext(origin, &buffer, dns_rootname, 0, NULL));
226 	CHECK(dns_zone_setorigin(zone, origin));
227 	dns_zone_setview(zone, view);
228 	dns_zone_settype(zone, dns_zone_master);
229 	dns_zone_setclass(zone, view->rdclass);
230 	dns_view_addzone(view, zone);
231 
232 	if (!keepview)
233 		dns_view_detach(&view);
234 
235 	*zonep = zone;
236 
237 	return (ISC_R_SUCCESS);
238 
239   cleanup:
240 	if (zone != NULL)
241 		dns_zone_detach(&zone);
242 	if (view != NULL)
243 		dns_view_detach(&view);
244 	return (result);
245 }
246 
247 isc_result_t
dns_test_setupzonemgr(void)248 dns_test_setupzonemgr(void) {
249 	isc_result_t result;
250 	REQUIRE(zonemgr == NULL);
251 
252 	result = dns_zonemgr_create(mctx, taskmgr, timermgr, socketmgr,
253 				    &zonemgr);
254 	return (result);
255 }
256 
257 isc_result_t
dns_test_managezone(dns_zone_t * zone)258 dns_test_managezone(dns_zone_t *zone) {
259 	isc_result_t result;
260 	REQUIRE(zonemgr != NULL);
261 
262 	result = dns_zonemgr_setsize(zonemgr, 1);
263 	if (result != ISC_R_SUCCESS)
264 		return (result);
265 
266 	result = dns_zonemgr_managezone(zonemgr, zone);
267 	return (result);
268 }
269 
270 void
dns_test_releasezone(dns_zone_t * zone)271 dns_test_releasezone(dns_zone_t *zone) {
272 	REQUIRE(zonemgr != NULL);
273 	dns_zonemgr_releasezone(zonemgr, zone);
274 }
275 
276 void
dns_test_closezonemgr(void)277 dns_test_closezonemgr(void) {
278 	REQUIRE(zonemgr != NULL);
279 
280 	dns_zonemgr_shutdown(zonemgr);
281 	dns_zonemgr_detach(&zonemgr);
282 }
283 
284 /*
285  * Sleep for 'usec' microseconds.
286  */
287 void
dns_test_nap(isc_uint32_t usec)288 dns_test_nap(isc_uint32_t usec) {
289 #ifdef HAVE_NANOSLEEP
290 	struct timespec ts;
291 
292 	ts.tv_sec = usec / 1000000;
293 	ts.tv_nsec = (usec % 1000000) * 1000;
294 	nanosleep(&ts, NULL);
295 #elif HAVE_USLEEP
296 	usleep(usec);
297 #else
298 	/*
299 	 * No fractional-second sleep function is available, so we
300 	 * round up to the nearest second and sleep instead
301 	 */
302 	sleep((usec / 1000000) + 1);
303 #endif
304 }
305 
306 isc_result_t
dns_test_loaddb(dns_db_t ** db,dns_dbtype_t dbtype,const char * origin,const char * testfile)307 dns_test_loaddb(dns_db_t **db, dns_dbtype_t dbtype, const char *origin,
308 		const char *testfile)
309 {
310 	isc_result_t		result;
311 	dns_fixedname_t		fixed;
312 	dns_name_t		*name;
313 
314 	dns_fixedname_init(&fixed);
315 	name = dns_fixedname_name(&fixed);
316 
317 	result = dns_name_fromstring(name, origin, 0, NULL);
318 	if (result != ISC_R_SUCCESS)
319 		return(result);
320 
321 	result = dns_db_create(mctx, "rbt", name, dbtype, dns_rdataclass_in,
322 			       0, NULL, db);
323 	if (result != ISC_R_SUCCESS)
324 		return (result);
325 
326 	result = dns_db_load(*db, testfile);
327 	return (result);
328 }
329