Annotation of src/external/mpl/bind/dist/lib/dns/tests/dbversion_test.c, Revision 1.10
1.10 ! christos 1: /* $NetBSD: dbversion_test.c,v 1.1.1.9 2023/01/25 20:36:47 christos Exp $ */
1.1 christos 2:
3: /*
4: * Copyright (C) Internet Systems Consortium, Inc. ("ISC")
5: *
1.9 christos 6: * SPDX-License-Identifier: MPL-2.0
7: *
1.1 christos 8: * This Source Code Form is subject to the terms of the Mozilla Public
9: * License, v. 2.0. If a copy of the MPL was not distributed with this
1.7 christos 10: * file, you can obtain one at https://mozilla.org/MPL/2.0/.
1.1 christos 11: *
12: * See the COPYRIGHT file distributed with this work for additional
13: * information regarding copyright ownership.
14: */
15:
1.3 christos 16: #if HAVE_CMOCKA
1.1 christos 17:
1.6 christos 18: #include <sched.h> /* IWYU pragma: keep */
19: #include <setjmp.h>
1.3 christos 20: #include <stdarg.h>
21: #include <stddef.h>
1.1 christos 22: #include <stdlib.h>
1.3 christos 23: #include <string.h>
1.1 christos 24: #include <unistd.h>
25:
1.3 christos 26: #define UNIT_TESTING
27: #include <cmocka.h>
28:
1.1 christos 29: #include <isc/file.h>
30: #include <isc/result.h>
31: #include <isc/serial.h>
32: #include <isc/stdtime.h>
1.3 christos 33: #include <isc/string.h>
34: #include <isc/util.h>
1.1 christos 35:
36: #include <dns/db.h>
1.6 christos 37: #include <dns/nsec3.h>
1.1 christos 38: #include <dns/rdatalist.h>
39: #include <dns/rdataset.h>
40: #include <dns/rdatasetiter.h>
41:
42: #include "dnstest.h"
43:
44: static char tempname[11] = "dtXXXXXXXX";
1.3 christos 45: static dns_db_t *db1 = NULL, *db2 = NULL;
46: static dns_dbversion_t *v1 = NULL, *v2 = NULL;
47:
48: /*
49: * The code below enables us to trap assertion failures for testing
50: * purposes. local_callback() is set as the callback function for
51: * isc_assertion_failed(). It calls mock_assert() so that CMOCKA
1.6 christos 52: * will be able to see it, then returns to the calling function via
1.3 christos 53: * longjmp() so that the abort() call in isc_assertion_failed() will
54: * never be reached. Use check_assertion() to check for assertions
55: * instead of expect_assert_failure().
56: */
57: jmp_buf assertion;
58:
1.6 christos 59: #define check_assertion(function_call) \
60: do { \
61: const int r = setjmp(assertion); \
62: if (r == 0) { \
63: expect_assert_failure(function_call); \
64: } \
65: } while (false);
1.1 christos 66:
67: static void
68: local_callback(const char *file, int line, isc_assertiontype_t type,
1.6 christos 69: const char *cond) {
1.3 christos 70: UNUSED(type);
71:
72: mock_assert(1, cond, file, line);
73: longjmp(assertion, 1);
1.1 christos 74: }
1.3 christos 75:
76: static int
77: _setup(void **state) {
78: isc_result_t res;
1.1 christos 79:
1.3 christos 80: UNUSED(state);
81:
82: isc_assertion_setcallback(local_callback);
83:
84: res = dns_test_begin(NULL, false);
85: assert_int_equal(res, ISC_R_SUCCESS);
1.1 christos 86:
1.6 christos 87: res = dns_db_create(dt_mctx, "rbt", dns_rootname, dns_dbtype_zone,
88: dns_rdataclass_in, 0, NULL, &db1);
1.3 christos 89: assert_int_equal(res, ISC_R_SUCCESS);
1.1 christos 90: dns_db_newversion(db1, &v1);
1.3 christos 91: assert_non_null(v1);
1.1 christos 92:
1.6 christos 93: res = dns_db_create(dt_mctx, "rbt", dns_rootname, dns_dbtype_zone,
94: dns_rdataclass_in, 0, NULL, &db2);
1.3 christos 95: assert_int_equal(res, ISC_R_SUCCESS);
1.1 christos 96: dns_db_newversion(db2, &v2);
1.3 christos 97: assert_non_null(v1);
98:
99: return (0);
1.1 christos 100: }
101:
1.3 christos 102: static int
103: _teardown(void **state) {
104: UNUSED(state);
105:
106: if (strcmp(tempname, "dtXXXXXXXX") != 0) {
107: unlink(tempname);
108: }
109:
1.1 christos 110: if (v1 != NULL) {
1.3 christos 111: dns_db_closeversion(db1, &v1, false);
112: assert_null(v1);
1.1 christos 113: }
114: if (db1 != NULL) {
115: dns_db_detach(&db1);
1.3 christos 116: assert_null(db1);
1.1 christos 117: }
118:
119: if (v2 != NULL) {
1.3 christos 120: dns_db_closeversion(db2, &v2, false);
121: assert_null(v2);
1.1 christos 122: }
123: if (db2 != NULL) {
124: dns_db_detach(&db2);
1.3 christos 125: assert_null(db2);
1.1 christos 126: }
1.3 christos 127:
128: dns_test_end();
129:
130: return (0);
1.1 christos 131: }
132:
133: /*
1.3 christos 134: * Check dns_db_attachversion() passes with matching db and version, and
135: * asserts with mis-matching db and version.
1.1 christos 136: */
137: static void
1.3 christos 138: attachversion(void **state) {
1.1 christos 139: dns_dbversion_t *v = NULL;
140:
1.3 christos 141: UNUSED(state);
1.1 christos 142:
1.3 christos 143: dns_db_attachversion(db1, v1, &v);
144: assert_ptr_equal(v, v1);
145: dns_db_closeversion(db1, &v, false);
146: assert_null(v);
1.1 christos 147:
1.3 christos 148: check_assertion(dns_db_attachversion(db1, v2, &v));
1.1 christos 149: }
150:
1.3 christos 151: /*
152: * Check dns_db_closeversion() passes with matching db and version, and
153: * asserts with mis-matching db and version.
154: */
1.1 christos 155: static void
1.3 christos 156: closeversion(void **state) {
157: UNUSED(state);
1.1 christos 158:
1.3 christos 159: assert_non_null(v1);
160: dns_db_closeversion(db1, &v1, false);
161: assert_null(v1);
1.1 christos 162:
1.3 christos 163: check_assertion(dns_db_closeversion(db1, &v2, false));
1.1 christos 164: }
165:
1.3 christos 166: /*
167: * Check dns_db_find() passes with matching db and version, and
168: * asserts with mis-matching db and version.
169: */
1.1 christos 170: static void
1.3 christos 171: find(void **state) {
172: isc_result_t res;
1.1 christos 173: dns_rdataset_t rdataset;
174: dns_fixedname_t fixed;
1.3 christos 175: dns_name_t *name = NULL;
1.1 christos 176:
1.3 christos 177: UNUSED(state);
1.1 christos 178:
1.3 christos 179: name = dns_fixedname_initname(&fixed);
1.1 christos 180:
181: dns_rdataset_init(&rdataset);
1.6 christos 182: res = dns_db_find(db1, dns_rootname, v1, dns_rdatatype_soa, 0, 0, NULL,
183: name, &rdataset, NULL);
1.3 christos 184: assert_int_equal(res, DNS_R_NXDOMAIN);
1.1 christos 185:
1.3 christos 186: if (dns_rdataset_isassociated(&rdataset)) {
187: dns_rdataset_disassociate(&rdataset);
188: }
1.1 christos 189:
1.3 christos 190: dns_rdataset_init(&rdataset);
1.6 christos 191: check_assertion((void)dns_db_find(db1, dns_rootname, v2,
192: dns_rdatatype_soa, 0, 0, NULL, name,
193: &rdataset, NULL));
1.1 christos 194: }
195:
1.3 christos 196: /*
197: * Check dns_db_allrdatasets() passes with matching db and version, and
198: * asserts with mis-matching db and version.
199: */
1.1 christos 200: static void
1.3 christos 201: allrdatasets(void **state) {
202: isc_result_t res;
1.1 christos 203: dns_dbnode_t *node = NULL;
204: dns_rdatasetiter_t *iterator = NULL;
205:
1.3 christos 206: UNUSED(state);
1.1 christos 207:
1.3 christos 208: res = dns_db_findnode(db1, dns_rootname, false, &node);
209: assert_int_equal(res, ISC_R_SUCCESS);
1.1 christos 210:
1.10 ! christos 211: res = dns_db_allrdatasets(db1, node, v1, 0, 0, &iterator);
1.3 christos 212: assert_int_equal(res, ISC_R_SUCCESS);
1.1 christos 213:
1.10 ! christos 214: check_assertion(dns_db_allrdatasets(db1, node, v2, 0, 0, &iterator));
1.1 christos 215:
216: dns_rdatasetiter_destroy(&iterator);
1.3 christos 217: assert_null(iterator);
1.1 christos 218:
219: dns_db_detachnode(db1, &node);
1.3 christos 220: assert_null(node);
1.1 christos 221: }
222:
1.3 christos 223: /*
224: * Check dns_db_findrdataset() passes with matching db and version, and
225: * asserts with mis-matching db and version.
226: */
1.1 christos 227: static void
1.3 christos 228: findrdataset(void **state) {
229: isc_result_t res;
1.1 christos 230: dns_rdataset_t rdataset;
231: dns_dbnode_t *node = NULL;
232:
1.3 christos 233: UNUSED(state);
1.1 christos 234:
1.3 christos 235: res = dns_db_findnode(db1, dns_rootname, false, &node);
236: assert_int_equal(res, ISC_R_SUCCESS);
1.1 christos 237:
238: dns_rdataset_init(&rdataset);
1.6 christos 239: res = dns_db_findrdataset(db1, node, v1, dns_rdatatype_soa, 0, 0,
240: &rdataset, NULL);
1.3 christos 241: assert_int_equal(res, ISC_R_NOTFOUND);
1.1 christos 242:
1.3 christos 243: if (dns_rdataset_isassociated(&rdataset)) {
244: dns_rdataset_disassociate(&rdataset);
245: }
1.1 christos 246:
1.3 christos 247: dns_rdataset_init(&rdataset);
1.6 christos 248: check_assertion(dns_db_findrdataset(db1, node, v2, dns_rdatatype_soa, 0,
249: 0, &rdataset, NULL));
1.1 christos 250:
251: dns_db_detachnode(db1, &node);
1.3 christos 252: assert_null(node);
1.1 christos 253: }
254:
1.3 christos 255: /*
256: * Check dns_db_deleterdataset() passes with matching db and version, and
257: * asserts with mis-matching db and version.
258: */
1.1 christos 259: static void
1.3 christos 260: deleterdataset(void **state) {
261: isc_result_t res;
1.1 christos 262: dns_dbnode_t *node = NULL;
263:
1.3 christos 264: UNUSED(state);
1.1 christos 265:
1.3 christos 266: res = dns_db_findnode(db1, dns_rootname, false, &node);
267: assert_int_equal(res, ISC_R_SUCCESS);
1.1 christos 268:
1.3 christos 269: res = dns_db_deleterdataset(db1, node, v1, dns_rdatatype_soa, 0);
270: assert_int_equal(res, DNS_R_UNCHANGED);
1.1 christos 271:
1.6 christos 272: check_assertion(
273: dns_db_deleterdataset(db1, node, v2, dns_rdatatype_soa, 0));
1.1 christos 274: dns_db_detachnode(db1, &node);
1.3 christos 275: assert_null(node);
1.1 christos 276: }
277:
1.3 christos 278: /*
279: * Check dns_db_subtractrdataset() passes with matching db and version, and
280: * asserts with mis-matching db and version.
281: */
1.1 christos 282: static void
1.3 christos 283: subtract(void **state) {
284: isc_result_t res;
1.1 christos 285: dns_rdataset_t rdataset;
1.3 christos 286: dns_rdatalist_t rdatalist;
1.1 christos 287: dns_dbnode_t *node = NULL;
288:
1.3 christos 289: UNUSED(state);
1.1 christos 290:
291: dns_rdataset_init(&rdataset);
292: dns_rdatalist_init(&rdatalist);
293:
294: rdatalist.rdclass = dns_rdataclass_in;
295:
1.3 christos 296: res = dns_rdatalist_tordataset(&rdatalist, &rdataset);
297: assert_int_equal(res, ISC_R_SUCCESS);
1.1 christos 298:
1.3 christos 299: res = dns_db_findnode(db1, dns_rootname, false, &node);
300: assert_int_equal(res, ISC_R_SUCCESS);
1.1 christos 301:
1.3 christos 302: res = dns_db_subtractrdataset(db1, node, v1, &rdataset, 0, NULL);
303: assert_int_equal(res, DNS_R_UNCHANGED);
1.1 christos 304:
1.3 christos 305: if (dns_rdataset_isassociated(&rdataset)) {
306: dns_rdataset_disassociate(&rdataset);
307: }
1.1 christos 308:
1.3 christos 309: dns_rdataset_init(&rdataset);
310: res = dns_rdatalist_tordataset(&rdatalist, &rdataset);
311: assert_int_equal(res, ISC_R_SUCCESS);
1.1 christos 312:
1.6 christos 313: check_assertion(
314: dns_db_subtractrdataset(db1, node, v2, &rdataset, 0, NULL));
1.1 christos 315:
1.3 christos 316: dns_db_detachnode(db1, &node);
317: assert_null(node);
1.1 christos 318: }
319:
1.3 christos 320: /*
321: * Check dns_db_dump() passes with matching db and version, and
322: * asserts with mis-matching db and version.
323: */
1.1 christos 324: static void
1.3 christos 325: dump(void **state) {
326: isc_result_t res;
1.1 christos 327: FILE *f = NULL;
328:
1.3 christos 329: UNUSED(state);
1.1 christos 330:
1.3 christos 331: res = isc_file_openunique(tempname, &f);
1.1 christos 332: fclose(f);
1.3 christos 333: assert_int_equal(res, ISC_R_SUCCESS);
1.1 christos 334:
1.3 christos 335: res = dns_db_dump(db1, v1, tempname);
336: assert_int_equal(res, ISC_R_SUCCESS);
1.1 christos 337:
1.3 christos 338: check_assertion(dns_db_dump(db1, v2, tempname));
1.1 christos 339: }
340:
1.3 christos 341: /*
342: * Check dns_db_addrdataset() passes with matching db and version, and
343: * asserts with mis-matching db and version.
344: */
1.1 christos 345: static void
1.3 christos 346: addrdataset(void **state) {
347: isc_result_t res;
1.1 christos 348: dns_rdataset_t rdataset;
349: dns_dbnode_t *node = NULL;
350: dns_rdatalist_t rdatalist;
351:
1.3 christos 352: UNUSED(state);
1.1 christos 353:
354: dns_rdataset_init(&rdataset);
355: dns_rdatalist_init(&rdatalist);
356:
357: rdatalist.rdclass = dns_rdataclass_in;
358:
1.3 christos 359: res = dns_rdatalist_tordataset(&rdatalist, &rdataset);
360: assert_int_equal(res, ISC_R_SUCCESS);
1.1 christos 361:
1.3 christos 362: res = dns_db_findnode(db1, dns_rootname, false, &node);
363: assert_int_equal(res, ISC_R_SUCCESS);
1.1 christos 364:
1.3 christos 365: res = dns_db_addrdataset(db1, node, v1, 0, &rdataset, 0, NULL);
366: assert_int_equal(res, ISC_R_SUCCESS);
367:
1.6 christos 368: check_assertion(
369: dns_db_addrdataset(db1, node, v2, 0, &rdataset, 0, NULL));
1.1 christos 370:
371: dns_db_detachnode(db1, &node);
1.3 christos 372: assert_null(node);
1.1 christos 373: }
374:
1.3 christos 375: /*
376: * Check dns_db_getnsec3parameters() passes with matching db and version,
377: * and asserts with mis-matching db and version.
378: */
1.1 christos 379: static void
1.3 christos 380: getnsec3parameters(void **state) {
381: isc_result_t res;
1.1 christos 382: dns_hash_t hash;
1.3 christos 383: uint8_t flags;
384: uint16_t iterations;
1.1 christos 385: unsigned char salt[DNS_NSEC3_SALTSIZE];
386: size_t salt_length = sizeof(salt);
387:
1.3 christos 388: UNUSED(state);
1.1 christos 389:
1.6 christos 390: res = dns_db_getnsec3parameters(db1, v1, &hash, &flags, &iterations,
391: salt, &salt_length);
1.3 christos 392: assert_int_equal(res, ISC_R_NOTFOUND);
1.1 christos 393:
1.6 christos 394: check_assertion(dns_db_getnsec3parameters(
395: db1, v2, &hash, &flags, &iterations, salt, &salt_length));
1.1 christos 396: }
397:
1.3 christos 398: /*
399: * Check dns_db_resigned() passes with matching db and version, and
400: * asserts with mis-matching db and version.
401: */
1.1 christos 402: static void
1.3 christos 403: resigned(void **state) {
404: isc_result_t res;
1.1 christos 405: dns_rdataset_t rdataset, added;
406: dns_dbnode_t *node = NULL;
407: dns_rdatalist_t rdatalist;
408: dns_rdata_rrsig_t rrsig;
409: dns_rdata_t rdata = DNS_RDATA_INIT;
410: isc_buffer_t b;
411: unsigned char buf[1024];
412:
1.3 christos 413: UNUSED(state);
1.1 christos 414:
415: /*
416: * Create a dummy RRSIG record and set a resigning time.
417: */
418: dns_rdataset_init(&added);
419: dns_rdataset_init(&rdataset);
420: dns_rdatalist_init(&rdatalist);
421: isc_buffer_init(&b, buf, sizeof(buf));
422:
423: DNS_RDATACOMMON_INIT(&rrsig, dns_rdatatype_rrsig, dns_rdataclass_in);
424: rrsig.covered = dns_rdatatype_a;
425: rrsig.algorithm = 100;
426: rrsig.labels = 0;
427: rrsig.originalttl = 0;
428: rrsig.timeexpire = 3600;
429: rrsig.timesigned = 0;
430: rrsig.keyid = 0;
431: dns_name_init(&rrsig.signer, NULL);
432: dns_name_clone(dns_rootname, &rrsig.signer);
433: rrsig.siglen = 0;
434: rrsig.signature = NULL;
435:
1.3 christos 436: res = dns_rdata_fromstruct(&rdata, dns_rdataclass_in,
437: dns_rdatatype_rrsig, &rrsig, &b);
438: assert_int_equal(res, ISC_R_SUCCESS);
1.1 christos 439:
440: rdatalist.rdclass = dns_rdataclass_in;
441: rdatalist.type = dns_rdatatype_rrsig;
442: ISC_LIST_APPEND(rdatalist.rdata, &rdata, link);
443:
1.3 christos 444: res = dns_rdatalist_tordataset(&rdatalist, &rdataset);
445: assert_int_equal(res, ISC_R_SUCCESS);
1.1 christos 446:
447: rdataset.attributes |= DNS_RDATASETATTR_RESIGN;
448: rdataset.resign = 7200;
449:
1.3 christos 450: res = dns_db_findnode(db1, dns_rootname, false, &node);
451: assert_int_equal(res, ISC_R_SUCCESS);
1.1 christos 452:
1.3 christos 453: res = dns_db_addrdataset(db1, node, v1, 0, &rdataset, 0, &added);
454: assert_int_equal(res, ISC_R_SUCCESS);
1.1 christos 455:
456: dns_db_detachnode(db1, &node);
1.3 christos 457: assert_null(node);
1.1 christos 458:
1.3 christos 459: check_assertion(dns_db_resigned(db1, &added, v2));
460:
461: dns_db_resigned(db1, &added, v1);
1.1 christos 462:
463: dns_rdataset_disassociate(&added);
464: }
465:
1.3 christos 466: int
467: main(void) {
468: const struct CMUnitTest tests[] = {
469: cmocka_unit_test_setup_teardown(dump, _setup, _teardown),
470: cmocka_unit_test_setup_teardown(find, _setup, _teardown),
1.6 christos 471: cmocka_unit_test_setup_teardown(allrdatasets, _setup,
472: _teardown),
473: cmocka_unit_test_setup_teardown(findrdataset, _setup,
474: _teardown),
475: cmocka_unit_test_setup_teardown(deleterdataset, _setup,
476: _teardown),
477: cmocka_unit_test_setup_teardown(subtract, _setup, _teardown),
478: cmocka_unit_test_setup_teardown(addrdataset, _setup, _teardown),
479: cmocka_unit_test_setup_teardown(getnsec3parameters, _setup,
480: _teardown),
481: cmocka_unit_test_setup_teardown(resigned, _setup, _teardown),
482: cmocka_unit_test_setup_teardown(attachversion, _setup,
483: _teardown),
484: cmocka_unit_test_setup_teardown(closeversion, _setup,
485: _teardown),
1.3 christos 486: };
487:
488: return (cmocka_run_group_tests(tests, NULL, NULL));
489: }
490:
491: #else /* HAVE_CMOCKA */
492:
493: #include <stdio.h>
494:
495: int
496: main(void) {
497: printf("1..0 # Skipped: cmocka not available\n");
1.8 christos 498: return (SKIPPED_TEST_EXIT_CODE);
1.1 christos 499: }
500:
1.6 christos 501: #endif /* if HAVE_CMOCKA */
CVSweb <webmaster@jp.NetBSD.org>