xref: /minix/external/bsd/bind/dist/lib/dns/tests/zt_test.c (revision bb9622b5)
1 /*	$NetBSD: zt_test.c,v 1.1.1.4 2014/12/10 03:34:43 christos Exp $	*/
2 
3 /*
4  * Copyright (C) 2011, 2012  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 <atf-c.h>
26 
27 #include <unistd.h>
28 
29 #include <isc/app.h>
30 #include <isc/buffer.h>
31 #include <isc/task.h>
32 #include <isc/timer.h>
33 
34 #include <dns/db.h>
35 #include <dns/name.h>
36 #include <dns/view.h>
37 #include <dns/zone.h>
38 #include <dns/zt.h>
39 
40 #include "dnstest.h"
41 
42 struct args {
43 	void *arg1;
44 	void *arg2;
45 };
46 
47 /*
48  * Helper functions
49  */
50 static isc_result_t
51 count_zone(dns_zone_t *zone, void *uap) {
52 	int *nzones = (int *)uap;
53 
54 	UNUSED(zone);
55 
56 	*nzones += 1;
57 	return (ISC_R_SUCCESS);
58 }
59 
60 static isc_result_t
61 load_done(dns_zt_t *zt, dns_zone_t *zone, isc_task_t *task) {
62 	/* We treat zt as a pointer to a boolean for testing purposes */
63 	isc_boolean_t *done = (isc_boolean_t *) zt;
64 
65 	UNUSED(zone);
66 	UNUSED(task);
67 
68 	*done = ISC_TRUE;
69 	isc_app_shutdown();
70 	return (ISC_R_SUCCESS);
71 }
72 
73 static isc_result_t
74 all_done(void *arg) {
75 	isc_boolean_t *done = (isc_boolean_t *) arg;
76 
77 	*done = ISC_TRUE;
78 	isc_app_shutdown();
79 	return (ISC_R_SUCCESS);
80 }
81 
82 static void
83 start_zt_asyncload(isc_task_t *task, isc_event_t *event) {
84 	struct args *args = (struct args *)(event->ev_arg);
85 
86 	UNUSED(task);
87 
88 	dns_zt_asyncload(args->arg1, all_done, args->arg2);
89 
90 	isc_event_free(&event);
91 }
92 
93 static void
94 start_zone_asyncload(isc_task_t *task, isc_event_t *event) {
95 	struct args *args = (struct args *)(event->ev_arg);
96 
97 	UNUSED(task);
98 
99 	dns_zone_asyncload(args->arg1, load_done, args->arg2);
100 	isc_event_free(&event);
101 }
102 
103 /*
104  * Individual unit tests
105  */
106 ATF_TC(apply);
107 ATF_TC_HEAD(apply, tc) {
108 	atf_tc_set_md_var(tc, "descr", "apply a function to a zone table");
109 }
110 ATF_TC_BODY(apply, tc) {
111 	isc_result_t result;
112 	dns_zone_t *zone = NULL;
113 	dns_view_t *view = NULL;
114 	int nzones = 0;
115 
116 	UNUSED(tc);
117 
118 	result = dns_test_begin(NULL, ISC_TRUE);
119 	ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
120 
121 	result = dns_test_makezone("foo", &zone, NULL, ISC_TRUE);
122 	ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
123 
124 	view = dns_zone_getview(zone);
125 	ATF_REQUIRE(view->zonetable != NULL);
126 
127 	ATF_CHECK_EQ(0, nzones);
128 	result = dns_zt_apply(view->zonetable, ISC_FALSE, count_zone, &nzones);
129 	ATF_CHECK_EQ(result, ISC_R_SUCCESS);
130 	ATF_CHECK_EQ(1, nzones);
131 
132 	/* These steps are necessary so the zone can be detached properly */
133 	result = dns_test_setupzonemgr();
134 	ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
135 	result = dns_test_managezone(zone);
136 	ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
137 	dns_test_releasezone(zone);
138 	dns_test_closezonemgr();
139 
140 	/* The view was left attached in dns_test_makezone() */
141 	dns_view_detach(&view);
142 	dns_zone_detach(&zone);
143 
144 	dns_test_end();
145 }
146 
147 ATF_TC(asyncload_zone);
148 ATF_TC_HEAD(asyncload_zone, tc) {
149 	atf_tc_set_md_var(tc, "descr", "asynchronous zone load");
150 }
151 ATF_TC_BODY(asyncload_zone, tc) {
152 	isc_result_t result;
153 	dns_zone_t *zone = NULL;
154 	dns_view_t *view = NULL;
155 	dns_db_t *db = NULL;
156 	isc_boolean_t done = ISC_FALSE;
157 	int i = 0;
158 	struct args args;
159 
160 	UNUSED(tc);
161 
162 	result = dns_test_begin(NULL, ISC_TRUE);
163 	ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
164 
165 	result = dns_test_makezone("foo", &zone, NULL, ISC_TRUE);
166 	ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
167 
168 	result = dns_test_setupzonemgr();
169 	ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
170 	result = dns_test_managezone(zone);
171 	ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
172 
173 	view = dns_zone_getview(zone);
174 	ATF_REQUIRE(view->zonetable != NULL);
175 
176 	ATF_CHECK(!dns__zone_loadpending(zone));
177 	ATF_CHECK(!done);
178 	dns_zone_setfile(zone, "testdata/zt/zone1.db");
179 
180 	args.arg1 = zone;
181 	args.arg2 = &done;
182 	isc_app_onrun(mctx, maintask, start_zone_asyncload, &args);
183 
184 	isc_app_run();
185 	while (dns__zone_loadpending(zone) && i++ < 5000)
186 		dns_test_nap(1000);
187 	ATF_CHECK(done);
188 
189 	/* The zone should now be loaded; test it */
190 	result = dns_zone_getdb(zone, &db);
191 	ATF_CHECK_EQ(result, ISC_R_SUCCESS);
192 	ATF_CHECK(db != NULL);
193 	if (db != NULL)
194 		dns_db_detach(&db);
195 
196 	dns_test_releasezone(zone);
197 	dns_test_closezonemgr();
198 
199 	dns_zone_detach(&zone);
200 	dns_view_detach(&view);
201 
202 	dns_test_end();
203 }
204 
205 ATF_TC(asyncload_zt);
206 ATF_TC_HEAD(asyncload_zt, tc) {
207 	atf_tc_set_md_var(tc, "descr", "asynchronous zone table load");
208 }
209 ATF_TC_BODY(asyncload_zt, tc) {
210 	isc_result_t result;
211 	dns_zone_t *zone1 = NULL, *zone2 = NULL, *zone3 = NULL;
212 	dns_view_t *view;
213 	dns_zt_t *zt;
214 	dns_db_t *db = NULL;
215 	isc_boolean_t done = ISC_FALSE;
216 	int i = 0;
217 	struct args args;
218 
219 	UNUSED(tc);
220 
221 	result = dns_test_begin(NULL, ISC_TRUE);
222 	ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
223 
224 	result = dns_test_makezone("foo", &zone1, NULL, ISC_TRUE);
225 	ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
226 	dns_zone_setfile(zone1, "testdata/zt/zone1.db");
227 	view = dns_zone_getview(zone1);
228 
229 	result = dns_test_makezone("bar", &zone2, view, ISC_TRUE);
230 	ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
231 	dns_zone_setfile(zone2, "testdata/zt/zone1.db");
232 
233 	/* This one will fail to load */
234 	result = dns_test_makezone("fake", &zone3, view, ISC_TRUE);
235 	ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
236 	dns_zone_setfile(zone3, "testdata/zt/nonexistent.db");
237 
238 	zt = view->zonetable;
239 	ATF_REQUIRE(zt != NULL);
240 
241 	result = dns_test_setupzonemgr();
242 	ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
243 	result = dns_test_managezone(zone1);
244 	ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
245 	result = dns_test_managezone(zone2);
246 	ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
247 	result = dns_test_managezone(zone3);
248 	ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
249 
250 	ATF_CHECK(!dns__zone_loadpending(zone1));
251 	ATF_CHECK(!dns__zone_loadpending(zone2));
252 	ATF_CHECK(!done);
253 
254 	args.arg1 = zt;
255 	args.arg2 = &done;
256 	isc_app_onrun(mctx, maintask, start_zt_asyncload, &args);
257 
258 	isc_app_run();
259 	while (!done && i++ < 5000)
260 		dns_test_nap(1000);
261 	ATF_CHECK(done);
262 
263 	/* Both zones should now be loaded; test them */
264 	result = dns_zone_getdb(zone1, &db);
265 	ATF_CHECK_EQ(result, ISC_R_SUCCESS);
266 	ATF_CHECK(db != NULL);
267 	if (db != NULL)
268 		dns_db_detach(&db);
269 
270 	result = dns_zone_getdb(zone2, &db);
271 	ATF_CHECK_EQ(result, ISC_R_SUCCESS);
272 	ATF_CHECK(db != NULL);
273 	if (db != NULL)
274 		dns_db_detach(&db);
275 
276 	dns_test_releasezone(zone3);
277 	dns_test_releasezone(zone2);
278 	dns_test_releasezone(zone1);
279 	dns_test_closezonemgr();
280 
281 	dns_zone_detach(&zone1);
282 	dns_zone_detach(&zone2);
283 	dns_zone_detach(&zone3);
284 	dns_view_detach(&view);
285 
286 	dns_test_end();
287 }
288 
289 /*
290  * Main
291  */
292 ATF_TP_ADD_TCS(tp) {
293 	ATF_TP_ADD_TC(tp, apply);
294 	ATF_TP_ADD_TC(tp, asyncload_zone);
295 	ATF_TP_ADD_TC(tp, asyncload_zt);
296 	return (atf_no_error());
297 }
298