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 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 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); 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 } 83 ATF_TC_BODY(create, tc) { 84 test_create(tc); 85 } 86 87 ATF_TC(create_nsec3); 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 } 92 ATF_TC_BODY(create_nsec3, tc) { 93 test_create(tc); 94 } 95 96 /* walk: walk a database */ 97 static void 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); 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 } 146 ATF_TC_BODY(walk, tc) { 147 test_walk(tc); 148 } 149 150 ATF_TC(walk_nsec3); 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 } 156 ATF_TC_BODY(walk_nsec3, tc) { 157 test_walk(tc); 158 } 159 160 /* reverse: walk database backwards */ 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); 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 } 208 ATF_TC_BODY(reverse, tc) { 209 test_reverse(tc); 210 } 211 212 ATF_TC(reverse_nsec3); 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 } 217 ATF_TC_BODY(reverse_nsec3, tc) { 218 test_reverse(tc); 219 } 220 221 /* seek: walk database starting at a particular node */ 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); 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 } 278 ATF_TC_BODY(seek, tc) { 279 test_seek(tc); 280 } 281 282 ATF_TC(seek_nsec3); 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 } 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 */ 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); 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 } 336 ATF_TC_BODY(seek_empty, tc) { 337 test_seek_empty(tc); 338 } 339 340 ATF_TC(seek_empty_nsec3); 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 } 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 */ 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); 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 } 393 ATF_TC_BODY(seek_nx, tc) { 394 test_seek_nx(tc); 395 } 396 397 ATF_TC(seek_nx_nsec3); 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 } 403 ATF_TC_BODY(seek_nx_nsec3, tc) { 404 test_seek_nx(tc); 405 } 406 407 /* 408 * Main 409 */ 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