1 /* $NetBSD: dbiterator_test.c,v 1.1.1.5 2014/12/10 03:34:42 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 #include <stdlib.h>
29
30 #include <dns/db.h>
31 #include <dns/dbiterator.h>
32 #include <dns/name.h>
33
34 #include "dnstest.h"
35
36 /*
37 * Helper functions
38 */
39
40 #define BUFLEN 255
41 #define BIGBUFLEN (64 * 1024)
42 #define TEST_ORIGIN "test"
43
44 static isc_result_t
make_name(const char * src,dns_name_t * name)45 make_name(const char *src, dns_name_t *name) {
46 isc_buffer_t b;
47 isc_buffer_constinit(&b, src, strlen(src));
48 isc_buffer_add(&b, strlen(src));
49 return (dns_name_fromtext(name, &b, dns_rootname, 0, NULL));
50 }
51
52 /*
53 * Individual unit tests
54 */
55
56 /* create: make sure we can create a dbiterator */
57 static void
test_create(const atf_tc_t * tc)58 test_create(const atf_tc_t *tc) {
59 isc_result_t result;
60 dns_db_t *db = NULL;
61 dns_dbiterator_t *iter = NULL;
62
63 result = dns_test_begin(NULL, ISC_FALSE);
64 ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
65
66 result = dns_test_loaddb(&db, dns_dbtype_cache, TEST_ORIGIN,
67 atf_tc_get_md_var(tc, "X-filename"));
68 ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
69
70 result = dns_db_createiterator(db, 0, &iter);
71 ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
72
73 dns_dbiterator_destroy(&iter);
74 dns_db_detach(&db);
75 dns_test_end();
76 }
77
78 ATF_TC(create);
ATF_TC_HEAD(create,tc)79 ATF_TC_HEAD(create, tc) {
80 atf_tc_set_md_var(tc, "descr", "create a database iterator");
81 atf_tc_set_md_var(tc, "X-filename", "testdata/dbiterator/zone1.data");
82 }
ATF_TC_BODY(create,tc)83 ATF_TC_BODY(create, tc) {
84 test_create(tc);
85 }
86
87 ATF_TC(create_nsec3);
ATF_TC_HEAD(create_nsec3,tc)88 ATF_TC_HEAD(create_nsec3, tc) {
89 atf_tc_set_md_var(tc, "descr", "create a database iterator (NSEC3)");
90 atf_tc_set_md_var(tc, "X-filename", "testdata/dbiterator/zone2.data");
91 }
ATF_TC_BODY(create_nsec3,tc)92 ATF_TC_BODY(create_nsec3, tc) {
93 test_create(tc);
94 }
95
96 /* walk: walk a database */
97 static void
test_walk(const atf_tc_t * tc)98 test_walk(const atf_tc_t *tc) {
99 isc_result_t result;
100 dns_db_t *db = NULL;
101 dns_dbiterator_t *iter = NULL;
102 dns_dbnode_t *node = NULL;
103 dns_name_t *name;
104 dns_fixedname_t f;
105 int i = 0;
106
107 UNUSED(tc);
108
109 dns_fixedname_init(&f);
110 name = dns_fixedname_name(&f);
111
112 result = dns_test_begin(NULL, ISC_FALSE);
113 ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
114
115 result = dns_test_loaddb(&db, dns_dbtype_cache, TEST_ORIGIN,
116 atf_tc_get_md_var(tc, "X-filename"));
117 ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
118
119 result = dns_db_createiterator(db, 0, &iter);
120 ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
121
122 for (result = dns_dbiterator_first(iter);
123 result == ISC_R_SUCCESS;
124 result = dns_dbiterator_next(iter)) {
125 result = dns_dbiterator_current(iter, &node, name);
126 if (result == DNS_R_NEWORIGIN)
127 result = ISC_R_SUCCESS;
128 ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
129 dns_db_detachnode(db, &node);
130 i++;
131 }
132
133 ATF_CHECK_EQ(i, atoi(atf_tc_get_md_var(tc, "X-nodes")));
134
135 dns_dbiterator_destroy(&iter);
136 dns_db_detach(&db);
137 dns_test_end();
138 }
139
140 ATF_TC(walk);
ATF_TC_HEAD(walk,tc)141 ATF_TC_HEAD(walk, tc) {
142 atf_tc_set_md_var(tc, "descr", "walk database");
143 atf_tc_set_md_var(tc, "X-filename", "testdata/dbiterator/zone1.data");
144 atf_tc_set_md_var(tc, "X-nodes", "12");
145 }
ATF_TC_BODY(walk,tc)146 ATF_TC_BODY(walk, tc) {
147 test_walk(tc);
148 }
149
150 ATF_TC(walk_nsec3);
ATF_TC_HEAD(walk_nsec3,tc)151 ATF_TC_HEAD(walk_nsec3, tc) {
152 atf_tc_set_md_var(tc, "descr", "walk database");
153 atf_tc_set_md_var(tc, "X-filename", "testdata/dbiterator/zone2.data");
154 atf_tc_set_md_var(tc, "X-nodes", "33");
155 }
ATF_TC_BODY(walk_nsec3,tc)156 ATF_TC_BODY(walk_nsec3, tc) {
157 test_walk(tc);
158 }
159
160 /* reverse: walk database backwards */
test_reverse(const atf_tc_t * tc)161 static void test_reverse(const atf_tc_t *tc) {
162 isc_result_t result;
163 dns_db_t *db = NULL;
164 dns_dbiterator_t *iter = NULL;
165 dns_dbnode_t *node = NULL;
166 dns_name_t *name;
167 dns_fixedname_t f;
168 int i = 0;
169
170 UNUSED(tc);
171
172 dns_fixedname_init(&f);
173 name = dns_fixedname_name(&f);
174
175 result = dns_test_begin(NULL, ISC_FALSE);
176 ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
177
178 result = dns_test_loaddb(&db, dns_dbtype_cache, TEST_ORIGIN,
179 atf_tc_get_md_var(tc, "X-filename"));
180 ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
181
182 result = dns_db_createiterator(db, 0, &iter);
183 ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
184
185 for (result = dns_dbiterator_last(iter);
186 result == ISC_R_SUCCESS;
187 result = dns_dbiterator_prev(iter)) {
188 result = dns_dbiterator_current(iter, &node, name);
189 if (result == DNS_R_NEWORIGIN)
190 result = ISC_R_SUCCESS;
191 ATF_CHECK_EQ(result, ISC_R_SUCCESS);
192 dns_db_detachnode(db, &node);
193 i++;
194 }
195
196 ATF_CHECK_EQ(i, 12);
197
198 dns_dbiterator_destroy(&iter);
199 dns_db_detach(&db);
200 dns_test_end();
201 }
202
203 ATF_TC(reverse);
ATF_TC_HEAD(reverse,tc)204 ATF_TC_HEAD(reverse, tc) {
205 atf_tc_set_md_var(tc, "descr", "walk database backwards");
206 atf_tc_set_md_var(tc, "X-filename", "testdata/dbiterator/zone1.data");
207 }
ATF_TC_BODY(reverse,tc)208 ATF_TC_BODY(reverse, tc) {
209 test_reverse(tc);
210 }
211
212 ATF_TC(reverse_nsec3);
ATF_TC_HEAD(reverse_nsec3,tc)213 ATF_TC_HEAD(reverse_nsec3, tc) {
214 atf_tc_set_md_var(tc, "descr", "walk database backwards");
215 atf_tc_set_md_var(tc, "X-filename", "testdata/dbiterator/zone2.data");
216 }
ATF_TC_BODY(reverse_nsec3,tc)217 ATF_TC_BODY(reverse_nsec3, tc) {
218 test_reverse(tc);
219 }
220
221 /* seek: walk database starting at a particular node */
test_seek(const atf_tc_t * tc)222 static void test_seek(const atf_tc_t *tc) {
223 isc_result_t result;
224 dns_db_t *db = NULL;
225 dns_dbiterator_t *iter = NULL;
226 dns_dbnode_t *node = NULL;
227 dns_name_t *name, *seekname;
228 dns_fixedname_t f1, f2;
229 int i = 0;
230
231 UNUSED(tc);
232
233 dns_fixedname_init(&f1);
234 name = dns_fixedname_name(&f1);
235 dns_fixedname_init(&f2);
236 seekname = dns_fixedname_name(&f2);
237
238 result = dns_test_begin(NULL, ISC_FALSE);
239 ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
240
241 result = dns_test_loaddb(&db, dns_dbtype_cache, TEST_ORIGIN,
242 atf_tc_get_md_var(tc, "X-filename"));
243 ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
244
245 result = dns_db_createiterator(db, 0, &iter);
246 ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
247
248 result = make_name("c." TEST_ORIGIN, seekname);
249 ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
250
251 result = dns_dbiterator_seek(iter, seekname);
252 ATF_CHECK_EQ(result, ISC_R_SUCCESS);
253
254 while (result == ISC_R_SUCCESS) {
255 result = dns_dbiterator_current(iter, &node, name);
256 if (result == DNS_R_NEWORIGIN)
257 result = ISC_R_SUCCESS;
258 ATF_CHECK_EQ(result, ISC_R_SUCCESS);
259 dns_db_detachnode(db, &node);
260 result = dns_dbiterator_next(iter);
261 i++;
262 }
263
264 ATF_CHECK_EQ(i, atoi(atf_tc_get_md_var(tc, "X-nodes")));
265
266 dns_dbiterator_destroy(&iter);
267 dns_db_detach(&db);
268 dns_test_end();
269 }
270
271 ATF_TC(seek);
ATF_TC_HEAD(seek,tc)272 ATF_TC_HEAD(seek, tc) {
273 atf_tc_set_md_var(tc, "descr", "walk database starting at "
274 "a particular node");
275 atf_tc_set_md_var(tc, "X-filename", "testdata/dbiterator/zone1.data");
276 atf_tc_set_md_var(tc, "X-nodes", "9");
277 }
ATF_TC_BODY(seek,tc)278 ATF_TC_BODY(seek, tc) {
279 test_seek(tc);
280 }
281
282 ATF_TC(seek_nsec3);
ATF_TC_HEAD(seek_nsec3,tc)283 ATF_TC_HEAD(seek_nsec3, tc) {
284 atf_tc_set_md_var(tc, "descr", "walk database starting at "
285 "a particular node");
286 atf_tc_set_md_var(tc, "X-filename", "testdata/dbiterator/zone2.data");
287 atf_tc_set_md_var(tc, "X-nodes", "30");
288 }
ATF_TC_BODY(seek_nsec3,tc)289 ATF_TC_BODY(seek_nsec3, tc) {
290 test_seek(tc);
291 }
292
293 /*
294 * seek_emty: walk database starting at an empty nonterminal node
295 * (should fail)
296 */
test_seek_empty(const atf_tc_t * tc)297 static void test_seek_empty(const atf_tc_t *tc) {
298 isc_result_t result;
299 dns_db_t *db = NULL;
300 dns_dbiterator_t *iter = NULL;
301 dns_name_t *seekname;
302 dns_fixedname_t f1;
303
304 UNUSED(tc);
305
306 dns_fixedname_init(&f1);
307 seekname = dns_fixedname_name(&f1);
308
309 result = dns_test_begin(NULL, ISC_FALSE);
310 ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
311
312 result = dns_test_loaddb(&db, dns_dbtype_cache, TEST_ORIGIN,
313 atf_tc_get_md_var(tc, "X-filename"));
314 ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
315
316 result = dns_db_createiterator(db, 0, &iter);
317 ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
318
319 result = make_name("d." TEST_ORIGIN, seekname);
320 ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
321
322 result = dns_dbiterator_seek(iter, seekname);
323 ATF_CHECK_EQ(result, ISC_R_NOTFOUND);
324
325 dns_dbiterator_destroy(&iter);
326 dns_db_detach(&db);
327 dns_test_end();
328 }
329
330 ATF_TC(seek_empty);
ATF_TC_HEAD(seek_empty,tc)331 ATF_TC_HEAD(seek_empty, tc) {
332 atf_tc_set_md_var(tc, "descr", "walk database starting at an "
333 "empty nonterminal node");
334 atf_tc_set_md_var(tc, "X-filename", "testdata/dbiterator/zone1.data");
335 }
ATF_TC_BODY(seek_empty,tc)336 ATF_TC_BODY(seek_empty, tc) {
337 test_seek_empty(tc);
338 }
339
340 ATF_TC(seek_empty_nsec3);
ATF_TC_HEAD(seek_empty_nsec3,tc)341 ATF_TC_HEAD(seek_empty_nsec3, tc) {
342 atf_tc_set_md_var(tc, "descr", "walk database starting at an "
343 "empty nonterminal node");
344 atf_tc_set_md_var(tc, "X-filename", "testdata/dbiterator/zone2.data");
345 }
ATF_TC_BODY(seek_empty_nsec3,tc)346 ATF_TC_BODY(seek_empty_nsec3, tc) {
347 test_seek_empty(tc);
348 }
349
350 /*
351 * seek_emty: walk database starting at an empty nonterminal node
352 * (should fail)
353 */
test_seek_nx(const atf_tc_t * tc)354 static void test_seek_nx(const atf_tc_t *tc) {
355 isc_result_t result;
356 dns_db_t *db = NULL;
357 dns_dbiterator_t *iter = NULL;
358 dns_name_t *seekname;
359 dns_fixedname_t f1;
360
361 UNUSED(tc);
362
363 dns_fixedname_init(&f1);
364 seekname = dns_fixedname_name(&f1);
365
366 result = dns_test_begin(NULL, ISC_FALSE);
367 ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
368
369 result = dns_test_loaddb(&db, dns_dbtype_cache, TEST_ORIGIN,
370 atf_tc_get_md_var(tc, "X-filename"));
371 ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
372
373 result = dns_db_createiterator(db, 0, &iter);
374 ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
375
376 result = make_name("nonexistent." TEST_ORIGIN, seekname);
377 ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
378
379 result = dns_dbiterator_seek(iter, seekname);
380 ATF_CHECK_EQ(result, ISC_R_NOTFOUND);
381
382 dns_dbiterator_destroy(&iter);
383 dns_db_detach(&db);
384 dns_test_end();
385 }
386
387 ATF_TC(seek_nx);
ATF_TC_HEAD(seek_nx,tc)388 ATF_TC_HEAD(seek_nx, tc) {
389 atf_tc_set_md_var(tc, "descr", "attempt to walk database starting "
390 "at a nonexistent node");
391 atf_tc_set_md_var(tc, "X-filename", "testdata/dbiterator/zone1.data");
392 }
ATF_TC_BODY(seek_nx,tc)393 ATF_TC_BODY(seek_nx, tc) {
394 test_seek_nx(tc);
395 }
396
397 ATF_TC(seek_nx_nsec3);
ATF_TC_HEAD(seek_nx_nsec3,tc)398 ATF_TC_HEAD(seek_nx_nsec3, tc) {
399 atf_tc_set_md_var(tc, "descr", "attempt to walk database starting "
400 "at a nonexistent node");
401 atf_tc_set_md_var(tc, "X-filename", "testdata/dbiterator/zone2.data");
402 }
ATF_TC_BODY(seek_nx_nsec3,tc)403 ATF_TC_BODY(seek_nx_nsec3, tc) {
404 test_seek_nx(tc);
405 }
406
407 /*
408 * Main
409 */
ATF_TP_ADD_TCS(tp)410 ATF_TP_ADD_TCS(tp) {
411 ATF_TP_ADD_TC(tp, create);
412 ATF_TP_ADD_TC(tp, create_nsec3);
413 ATF_TP_ADD_TC(tp, walk);
414 ATF_TP_ADD_TC(tp, walk_nsec3);
415 ATF_TP_ADD_TC(tp, reverse);
416 ATF_TP_ADD_TC(tp, reverse_nsec3);
417 ATF_TP_ADD_TC(tp, seek);
418 ATF_TP_ADD_TC(tp, seek_nsec3);
419 ATF_TP_ADD_TC(tp, seek_empty);
420 ATF_TP_ADD_TC(tp, seek_empty_nsec3);
421 ATF_TP_ADD_TC(tp, seek_nx);
422 ATF_TP_ADD_TC(tp, seek_nx_nsec3);
423 return (atf_no_error());
424 }
425
426 /*
427 * XXX:
428 * dns_dbiterator API calls that are not yet part of this unit test:
429 *
430 * dns_dbiterator_pause
431 * dns_dbiterator_origin
432 * dns_dbiterator_setcleanmode
433 */
434