Home | History | Annotate | Line # | Download | only in dns
      1  1.1  christos /*	$NetBSD: dbversion_test.c,v 1.4 2025/05/21 14:48:06 christos Exp $	*/
      2  1.1  christos 
      3  1.1  christos /*
      4  1.1  christos  * Copyright (C) Internet Systems Consortium, Inc. ("ISC")
      5  1.1  christos  *
      6  1.1  christos  * SPDX-License-Identifier: MPL-2.0
      7  1.1  christos  *
      8  1.1  christos  * This Source Code Form is subject to the terms of the Mozilla Public
      9  1.1  christos  * License, v. 2.0. If a copy of the MPL was not distributed with this
     10  1.1  christos  * file, you can obtain one at https://mozilla.org/MPL/2.0/.
     11  1.1  christos  *
     12  1.1  christos  * See the COPYRIGHT file distributed with this work for additional
     13  1.1  christos  * information regarding copyright ownership.
     14  1.1  christos  */
     15  1.1  christos 
     16  1.1  christos #include <inttypes.h>
     17  1.1  christos #include <sched.h> /* IWYU pragma: keep */
     18  1.1  christos #include <setjmp.h>
     19  1.1  christos #include <stdarg.h>
     20  1.1  christos #include <stddef.h>
     21  1.1  christos #include <stdlib.h>
     22  1.1  christos #include <string.h>
     23  1.1  christos #include <unistd.h>
     24  1.1  christos 
     25  1.1  christos #define UNIT_TESTING
     26  1.1  christos #include <cmocka.h>
     27  1.1  christos 
     28  1.1  christos #include <isc/file.h>
     29  1.1  christos #include <isc/result.h>
     30  1.1  christos #include <isc/serial.h>
     31  1.1  christos #include <isc/stdtime.h>
     32  1.1  christos #include <isc/string.h>
     33  1.1  christos #include <isc/util.h>
     34  1.1  christos 
     35  1.1  christos #include <dns/db.h>
     36  1.1  christos #include <dns/nsec3.h>
     37  1.1  christos #include <dns/rdatalist.h>
     38  1.1  christos #include <dns/rdataset.h>
     39  1.1  christos #include <dns/rdatasetiter.h>
     40  1.1  christos 
     41  1.1  christos #include <tests/dns.h>
     42  1.1  christos 
     43  1.1  christos static char tempname[11] = "dtXXXXXXXX";
     44  1.1  christos static dns_db_t *db1 = NULL, *db2 = NULL;
     45  1.1  christos static dns_dbversion_t *v1 = NULL, *v2 = NULL;
     46  1.1  christos 
     47  1.1  christos /*
     48  1.1  christos  * The code below enables us to trap assertion failures for testing
     49  1.1  christos  * purposes. local_callback() is set as the callback function for
     50  1.1  christos  * isc_assertion_failed(). It calls mock_assert() so that CMOCKA
     51  1.1  christos  * will be able to see it, then returns to the calling function via
     52  1.1  christos  * longjmp() so that the abort() call in isc_assertion_failed() will
     53  1.1  christos  * never be reached. Use check_assertion() to check for assertions
     54  1.1  christos  * instead of expect_assert_failure().
     55  1.1  christos  */
     56  1.1  christos jmp_buf assertion;
     57  1.1  christos 
     58  1.1  christos #define check_assertion(function_call)                        \
     59  1.1  christos 	do {                                                  \
     60  1.1  christos 		const int r = setjmp(assertion);              \
     61  1.1  christos 		if (r == 0) {                                 \
     62  1.1  christos 			expect_assert_failure(function_call); \
     63  1.1  christos 		}                                             \
     64  1.1  christos 	} while (false);
     65  1.1  christos 
     66  1.1  christos static void
     67  1.1  christos local_callback(const char *file, int line, isc_assertiontype_t type,
     68  1.1  christos 	       const char *cond) {
     69  1.1  christos 	UNUSED(type);
     70  1.1  christos 
     71  1.1  christos 	mock_assert(1, cond, file, line);
     72  1.1  christos 	longjmp(assertion, 1);
     73  1.1  christos }
     74  1.1  christos 
     75  1.1  christos static int
     76  1.1  christos setup_test(void **state) {
     77  1.1  christos 	isc_result_t res;
     78  1.1  christos 
     79  1.1  christos 	UNUSED(state);
     80  1.1  christos 
     81  1.1  christos 	isc_assertion_setcallback(local_callback);
     82  1.1  christos 
     83  1.3  christos 	res = dns_db_create(mctx, ZONEDB_DEFAULT, dns_rootname, dns_dbtype_zone,
     84  1.1  christos 			    dns_rdataclass_in, 0, NULL, &db1);
     85  1.1  christos 	assert_int_equal(res, ISC_R_SUCCESS);
     86  1.1  christos 	dns_db_newversion(db1, &v1);
     87  1.1  christos 	assert_non_null(v1);
     88  1.1  christos 
     89  1.3  christos 	res = dns_db_create(mctx, ZONEDB_DEFAULT, dns_rootname, dns_dbtype_zone,
     90  1.1  christos 			    dns_rdataclass_in, 0, NULL, &db2);
     91  1.1  christos 	assert_int_equal(res, ISC_R_SUCCESS);
     92  1.1  christos 	dns_db_newversion(db2, &v2);
     93  1.1  christos 	assert_non_null(v1);
     94  1.1  christos 
     95  1.3  christos 	return 0;
     96  1.1  christos }
     97  1.1  christos 
     98  1.1  christos static int
     99  1.1  christos teardown_test(void **state) {
    100  1.1  christos 	UNUSED(state);
    101  1.1  christos 
    102  1.1  christos 	if (strcmp(tempname, "dtXXXXXXXX") != 0) {
    103  1.1  christos 		unlink(tempname);
    104  1.1  christos 	}
    105  1.1  christos 
    106  1.1  christos 	if (v1 != NULL) {
    107  1.1  christos 		dns_db_closeversion(db1, &v1, false);
    108  1.1  christos 		assert_null(v1);
    109  1.1  christos 	}
    110  1.1  christos 	if (db1 != NULL) {
    111  1.1  christos 		dns_db_detach(&db1);
    112  1.1  christos 		assert_null(db1);
    113  1.1  christos 	}
    114  1.1  christos 
    115  1.1  christos 	if (v2 != NULL) {
    116  1.1  christos 		dns_db_closeversion(db2, &v2, false);
    117  1.1  christos 		assert_null(v2);
    118  1.1  christos 	}
    119  1.1  christos 	if (db2 != NULL) {
    120  1.1  christos 		dns_db_detach(&db2);
    121  1.1  christos 		assert_null(db2);
    122  1.1  christos 	}
    123  1.1  christos 
    124  1.3  christos 	return 0;
    125  1.1  christos }
    126  1.1  christos 
    127  1.1  christos /*
    128  1.1  christos  * Check dns_db_attachversion() passes with matching db and version, and
    129  1.1  christos  * asserts with mis-matching db and version.
    130  1.1  christos  */
    131  1.1  christos ISC_RUN_TEST_IMPL(attachversion) {
    132  1.1  christos 	dns_dbversion_t *v = NULL;
    133  1.1  christos 
    134  1.1  christos 	UNUSED(state);
    135  1.1  christos 
    136  1.1  christos 	dns_db_attachversion(db1, v1, &v);
    137  1.1  christos 	assert_ptr_equal(v, v1);
    138  1.1  christos 	dns_db_closeversion(db1, &v, false);
    139  1.1  christos 	assert_null(v);
    140  1.1  christos 
    141  1.1  christos 	check_assertion(dns_db_attachversion(db1, v2, &v));
    142  1.1  christos }
    143  1.1  christos 
    144  1.1  christos /*
    145  1.1  christos  * Check dns_db_closeversion() passes with matching db and version, and
    146  1.1  christos  * asserts with mis-matching db and version.
    147  1.1  christos  */
    148  1.1  christos ISC_RUN_TEST_IMPL(closeversion) {
    149  1.1  christos 	UNUSED(state);
    150  1.1  christos 
    151  1.1  christos 	assert_non_null(v1);
    152  1.1  christos 	dns_db_closeversion(db1, &v1, false);
    153  1.1  christos 	assert_null(v1);
    154  1.1  christos 
    155  1.1  christos 	check_assertion(dns_db_closeversion(db1, &v2, false));
    156  1.1  christos }
    157  1.1  christos 
    158  1.1  christos /*
    159  1.1  christos  * Check dns_db_find() passes with matching db and version, and
    160  1.1  christos  * asserts with mis-matching db and version.
    161  1.1  christos  */
    162  1.1  christos ISC_RUN_TEST_IMPL(find) {
    163  1.1  christos 	isc_result_t res;
    164  1.1  christos 	dns_rdataset_t rdataset;
    165  1.1  christos 	dns_fixedname_t fixed;
    166  1.1  christos 	dns_name_t *name = NULL;
    167  1.1  christos 
    168  1.1  christos 	UNUSED(state);
    169  1.1  christos 
    170  1.1  christos 	name = dns_fixedname_initname(&fixed);
    171  1.1  christos 
    172  1.1  christos 	dns_rdataset_init(&rdataset);
    173  1.1  christos 	res = dns_db_find(db1, dns_rootname, v1, dns_rdatatype_soa, 0, 0, NULL,
    174  1.1  christos 			  name, &rdataset, NULL);
    175  1.4  christos 	/*
    176  1.4  christos 	 * Note: in the QPzone database, the root node always exists,
    177  1.4  christos 	 * even if it's empty, so we would get DNS_R_NXRRSET from this
    178  1.4  christos 	 * query. In other databases (including the old RBTDB) the root
    179  1.4  christos 	 * node can be nonexistent, and the query would then return
    180  1.4  christos 	 * DNS_R_NXDOMAIN. Allow for both possibilities.
    181  1.4  christos 	 */
    182  1.4  christos 	assert_true(res == DNS_R_NXRRSET || res == DNS_R_NXDOMAIN);
    183  1.1  christos 
    184  1.1  christos 	if (dns_rdataset_isassociated(&rdataset)) {
    185  1.1  christos 		dns_rdataset_disassociate(&rdataset);
    186  1.1  christos 	}
    187  1.1  christos 
    188  1.1  christos 	dns_rdataset_init(&rdataset);
    189  1.1  christos 	check_assertion((void)dns_db_find(db1, dns_rootname, v2,
    190  1.1  christos 					  dns_rdatatype_soa, 0, 0, NULL, name,
    191  1.1  christos 					  &rdataset, NULL));
    192  1.1  christos }
    193  1.1  christos 
    194  1.1  christos /*
    195  1.1  christos  * Check dns_db_allrdatasets() passes with matching db and version, and
    196  1.1  christos  * asserts with mis-matching db and version.
    197  1.1  christos  */
    198  1.1  christos ISC_RUN_TEST_IMPL(allrdatasets) {
    199  1.1  christos 	isc_result_t res;
    200  1.1  christos 	dns_dbnode_t *node = NULL;
    201  1.1  christos 	dns_rdatasetiter_t *iterator = NULL;
    202  1.1  christos 
    203  1.1  christos 	UNUSED(state);
    204  1.1  christos 
    205  1.1  christos 	res = dns_db_findnode(db1, dns_rootname, false, &node);
    206  1.1  christos 	assert_int_equal(res, ISC_R_SUCCESS);
    207  1.1  christos 
    208  1.1  christos 	res = dns_db_allrdatasets(db1, node, v1, 0, 0, &iterator);
    209  1.1  christos 	assert_int_equal(res, ISC_R_SUCCESS);
    210  1.1  christos 
    211  1.1  christos 	check_assertion(dns_db_allrdatasets(db1, node, v2, 0, 0, &iterator));
    212  1.1  christos 
    213  1.1  christos 	dns_rdatasetiter_destroy(&iterator);
    214  1.1  christos 	assert_null(iterator);
    215  1.1  christos 
    216  1.1  christos 	dns_db_detachnode(db1, &node);
    217  1.1  christos 	assert_null(node);
    218  1.1  christos }
    219  1.1  christos 
    220  1.1  christos /*
    221  1.1  christos  * Check dns_db_findrdataset() passes with matching db and version, and
    222  1.1  christos  * asserts with mis-matching db and version.
    223  1.1  christos  */
    224  1.1  christos ISC_RUN_TEST_IMPL(findrdataset) {
    225  1.1  christos 	isc_result_t res;
    226  1.1  christos 	dns_rdataset_t rdataset;
    227  1.1  christos 	dns_dbnode_t *node = NULL;
    228  1.1  christos 
    229  1.1  christos 	UNUSED(state);
    230  1.1  christos 
    231  1.1  christos 	res = dns_db_findnode(db1, dns_rootname, false, &node);
    232  1.1  christos 	assert_int_equal(res, ISC_R_SUCCESS);
    233  1.1  christos 
    234  1.1  christos 	dns_rdataset_init(&rdataset);
    235  1.1  christos 	res = dns_db_findrdataset(db1, node, v1, dns_rdatatype_soa, 0, 0,
    236  1.1  christos 				  &rdataset, NULL);
    237  1.1  christos 	assert_int_equal(res, ISC_R_NOTFOUND);
    238  1.1  christos 
    239  1.1  christos 	if (dns_rdataset_isassociated(&rdataset)) {
    240  1.1  christos 		dns_rdataset_disassociate(&rdataset);
    241  1.1  christos 	}
    242  1.1  christos 
    243  1.1  christos 	dns_rdataset_init(&rdataset);
    244  1.1  christos 	check_assertion(dns_db_findrdataset(db1, node, v2, dns_rdatatype_soa, 0,
    245  1.1  christos 					    0, &rdataset, NULL));
    246  1.1  christos 
    247  1.1  christos 	dns_db_detachnode(db1, &node);
    248  1.1  christos 	assert_null(node);
    249  1.1  christos }
    250  1.1  christos 
    251  1.1  christos /*
    252  1.1  christos  * Check dns_db_deleterdataset() passes with matching db and version, and
    253  1.1  christos  * asserts with mis-matching db and version.
    254  1.1  christos  */
    255  1.1  christos ISC_RUN_TEST_IMPL(deleterdataset) {
    256  1.1  christos 	isc_result_t res;
    257  1.1  christos 	dns_dbnode_t *node = NULL;
    258  1.1  christos 
    259  1.1  christos 	UNUSED(state);
    260  1.1  christos 
    261  1.1  christos 	res = dns_db_findnode(db1, dns_rootname, false, &node);
    262  1.1  christos 	assert_int_equal(res, ISC_R_SUCCESS);
    263  1.1  christos 
    264  1.1  christos 	res = dns_db_deleterdataset(db1, node, v1, dns_rdatatype_soa, 0);
    265  1.1  christos 	assert_int_equal(res, DNS_R_UNCHANGED);
    266  1.1  christos 
    267  1.1  christos 	check_assertion(
    268  1.1  christos 		dns_db_deleterdataset(db1, node, v2, dns_rdatatype_soa, 0));
    269  1.1  christos 	dns_db_detachnode(db1, &node);
    270  1.1  christos 	assert_null(node);
    271  1.1  christos }
    272  1.1  christos 
    273  1.1  christos /*
    274  1.1  christos  * Check dns_db_subtractrdataset() passes with matching db and version, and
    275  1.1  christos  * asserts with mis-matching db and version.
    276  1.1  christos  */
    277  1.1  christos ISC_RUN_TEST_IMPL(subtract) {
    278  1.1  christos 	isc_result_t res;
    279  1.1  christos 	dns_rdataset_t rdataset;
    280  1.1  christos 	dns_rdatalist_t rdatalist;
    281  1.1  christos 	dns_dbnode_t *node = NULL;
    282  1.1  christos 
    283  1.1  christos 	UNUSED(state);
    284  1.1  christos 
    285  1.1  christos 	dns_rdataset_init(&rdataset);
    286  1.1  christos 	dns_rdatalist_init(&rdatalist);
    287  1.1  christos 
    288  1.1  christos 	rdatalist.rdclass = dns_rdataclass_in;
    289  1.1  christos 
    290  1.3  christos 	dns_rdatalist_tordataset(&rdatalist, &rdataset);
    291  1.1  christos 
    292  1.1  christos 	res = dns_db_findnode(db1, dns_rootname, false, &node);
    293  1.1  christos 	assert_int_equal(res, ISC_R_SUCCESS);
    294  1.1  christos 
    295  1.1  christos 	res = dns_db_subtractrdataset(db1, node, v1, &rdataset, 0, NULL);
    296  1.1  christos 	assert_int_equal(res, DNS_R_UNCHANGED);
    297  1.1  christos 
    298  1.1  christos 	if (dns_rdataset_isassociated(&rdataset)) {
    299  1.1  christos 		dns_rdataset_disassociate(&rdataset);
    300  1.1  christos 	}
    301  1.1  christos 
    302  1.1  christos 	dns_rdataset_init(&rdataset);
    303  1.3  christos 	dns_rdatalist_tordataset(&rdatalist, &rdataset);
    304  1.1  christos 
    305  1.1  christos 	check_assertion(
    306  1.1  christos 		dns_db_subtractrdataset(db1, node, v2, &rdataset, 0, NULL));
    307  1.1  christos 
    308  1.1  christos 	dns_db_detachnode(db1, &node);
    309  1.1  christos 	assert_null(node);
    310  1.1  christos }
    311  1.1  christos 
    312  1.1  christos /*
    313  1.1  christos  * Check dns_db_addrdataset() passes with matching db and version, and
    314  1.1  christos  * asserts with mis-matching db and version.
    315  1.1  christos  */
    316  1.1  christos ISC_RUN_TEST_IMPL(addrdataset) {
    317  1.1  christos 	isc_result_t res;
    318  1.1  christos 	dns_rdataset_t rdataset;
    319  1.1  christos 	dns_dbnode_t *node = NULL;
    320  1.1  christos 	dns_rdatalist_t rdatalist;
    321  1.1  christos 
    322  1.1  christos 	UNUSED(state);
    323  1.1  christos 
    324  1.1  christos 	dns_rdataset_init(&rdataset);
    325  1.1  christos 	dns_rdatalist_init(&rdatalist);
    326  1.1  christos 
    327  1.1  christos 	rdatalist.rdclass = dns_rdataclass_in;
    328  1.1  christos 
    329  1.3  christos 	dns_rdatalist_tordataset(&rdatalist, &rdataset);
    330  1.1  christos 
    331  1.1  christos 	res = dns_db_findnode(db1, dns_rootname, false, &node);
    332  1.1  christos 	assert_int_equal(res, ISC_R_SUCCESS);
    333  1.1  christos 
    334  1.1  christos 	res = dns_db_addrdataset(db1, node, v1, 0, &rdataset, 0, NULL);
    335  1.1  christos 	assert_int_equal(res, ISC_R_SUCCESS);
    336  1.1  christos 
    337  1.1  christos 	check_assertion(
    338  1.1  christos 		dns_db_addrdataset(db1, node, v2, 0, &rdataset, 0, NULL));
    339  1.1  christos 
    340  1.1  christos 	dns_db_detachnode(db1, &node);
    341  1.1  christos 	assert_null(node);
    342  1.1  christos }
    343  1.1  christos 
    344  1.1  christos /*
    345  1.1  christos  * Check dns_db_getnsec3parameters() passes with matching db and version,
    346  1.1  christos  * and asserts with mis-matching db and version.
    347  1.1  christos  */
    348  1.1  christos ISC_RUN_TEST_IMPL(getnsec3parameters) {
    349  1.1  christos 	isc_result_t res;
    350  1.1  christos 	dns_hash_t hash;
    351  1.1  christos 	uint8_t flags;
    352  1.1  christos 	uint16_t iterations;
    353  1.1  christos 	unsigned char salt[DNS_NSEC3_SALTSIZE];
    354  1.1  christos 	size_t salt_length = sizeof(salt);
    355  1.1  christos 
    356  1.1  christos 	UNUSED(state);
    357  1.1  christos 
    358  1.1  christos 	res = dns_db_getnsec3parameters(db1, v1, &hash, &flags, &iterations,
    359  1.1  christos 					salt, &salt_length);
    360  1.1  christos 	assert_int_equal(res, ISC_R_NOTFOUND);
    361  1.1  christos 
    362  1.1  christos 	check_assertion(dns_db_getnsec3parameters(
    363  1.1  christos 		db1, v2, &hash, &flags, &iterations, salt, &salt_length));
    364  1.1  christos }
    365  1.1  christos 
    366  1.4  christos /*
    367  1.4  christos  * Check that the correct node contents are found after a rollback.
    368  1.4  christos  */
    369  1.4  christos ISC_RUN_TEST_IMPL(rollback) {
    370  1.4  christos 	isc_result_t res;
    371  1.4  christos 	dns_rdata_t rdata1 = DNS_RDATA_INIT, rdata2 = DNS_RDATA_INIT;
    372  1.4  christos 	dns_rdataset_t input1 = DNS_RDATASET_INIT;
    373  1.4  christos 	dns_rdataset_t input2 = DNS_RDATASET_INIT;
    374  1.4  christos 	dns_rdataset_t rdataset1 = DNS_RDATASET_INIT;
    375  1.4  christos 	dns_rdataset_t rdataset2 = DNS_RDATASET_INIT;
    376  1.4  christos 	dns_rdatalist_t rdatalist1, rdatalist2;
    377  1.4  christos 	dns_rdata_t out1 = DNS_RDATA_INIT, out2 = DNS_RDATA_INIT;
    378  1.4  christos 	dns_dbnode_t *node = NULL;
    379  1.4  christos 	char *txt1 = (char *)"\006text 1";
    380  1.4  christos 	char *txt2 = (char *)"\006text 2";
    381  1.4  christos 	size_t len1 = strlen(txt1), len2 = strlen(txt2);
    382  1.4  christos 	char buf[1024];
    383  1.4  christos 	isc_buffer_t b;
    384  1.4  christos 
    385  1.4  christos 	UNUSED(state);
    386  1.4  christos 
    387  1.4  christos 	isc_buffer_init(&b, buf, sizeof(buf));
    388  1.4  christos 
    389  1.4  christos 	/* Set up two rdatasets to insert */
    390  1.4  christos 	rdata1.rdclass = dns_rdataclass_in;
    391  1.4  christos 	rdata1.type = dns_rdatatype_txt;
    392  1.4  christos 	rdata2 = rdata1;
    393  1.4  christos 
    394  1.4  christos 	rdata1.length = len1;
    395  1.4  christos 	rdata1.data = (unsigned char *)txt1;
    396  1.4  christos 	rdata2.length = len2;
    397  1.4  christos 	rdata2.data = (unsigned char *)txt2;
    398  1.4  christos 
    399  1.4  christos 	dns_rdatalist_init(&rdatalist1);
    400  1.4  christos 	rdatalist1.rdclass = dns_rdataclass_in;
    401  1.4  christos 	rdatalist1.type = dns_rdatatype_txt;
    402  1.4  christos 	rdatalist1.ttl = 3600;
    403  1.4  christos 	rdatalist2 = rdatalist1;
    404  1.4  christos 
    405  1.4  christos 	ISC_LIST_APPEND(rdatalist1.rdata, &rdata1, link);
    406  1.4  christos 	ISC_LIST_APPEND(rdatalist2.rdata, &rdata2, link);
    407  1.4  christos 
    408  1.4  christos 	dns_rdatalist_tordataset(&rdatalist1, &input1);
    409  1.4  christos 	dns_rdatalist_tordataset(&rdatalist2, &input2);
    410  1.4  christos 
    411  1.4  christos 	/* db1: Insert the first version ("text 1"), and commit */
    412  1.4  christos 	res = dns_db_findnode(db1, dns_rootname, true, &node);
    413  1.4  christos 	assert_int_equal(res, ISC_R_SUCCESS);
    414  1.4  christos 	res = dns_db_addrdataset(db1, node, v1, 0, &input1, 0, NULL);
    415  1.4  christos 	assert_int_equal(res, ISC_R_SUCCESS);
    416  1.4  christos 	dns_db_closeversion(db1, &v1, true); /* commit */
    417  1.4  christos 	assert_null(v1);
    418  1.4  christos 	dns_db_detachnode(db1, &node);
    419  1.4  christos 	assert_null(node);
    420  1.4  christos 
    421  1.4  christos 	/* db2: Insert the first version ("text 1"), and commit */
    422  1.4  christos 	res = dns_db_findnode(db2, dns_rootname, true, &node);
    423  1.4  christos 	assert_int_equal(res, ISC_R_SUCCESS);
    424  1.4  christos 	res = dns_db_addrdataset(db2, node, v2, 0, &input1, 0, NULL);
    425  1.4  christos 	assert_int_equal(res, ISC_R_SUCCESS);
    426  1.4  christos 	dns_db_closeversion(db2, &v2, true); /* commit */
    427  1.4  christos 	assert_null(v2);
    428  1.4  christos 	dns_db_detachnode(db2, &node);
    429  1.4  christos 	assert_null(node);
    430  1.4  christos 
    431  1.4  christos 	/* Reopen the versions */
    432  1.4  christos 	dns_db_newversion(db1, &v1);
    433  1.4  christos 	assert_non_null(v1);
    434  1.4  christos 	dns_db_newversion(db2, &v2);
    435  1.4  christos 	assert_non_null(v2);
    436  1.4  christos 
    437  1.4  christos 	/* db1: Insert the second version ("text 2"), and roll back */
    438  1.4  christos 	res = dns_db_findnode(db1, dns_rootname, true, &node);
    439  1.4  christos 	assert_int_equal(res, ISC_R_SUCCESS);
    440  1.4  christos 	res = dns_db_addrdataset(db1, node, v1, 0, &input2, 0, NULL);
    441  1.4  christos 	assert_int_equal(res, ISC_R_SUCCESS);
    442  1.4  christos 	dns_db_closeversion(db1, &v1, false); /* rollback */
    443  1.4  christos 	assert_null(v1);
    444  1.4  christos 	dns_db_detachnode(db1, &node);
    445  1.4  christos 	assert_null(node);
    446  1.4  christos 
    447  1.4  christos 	/* db2: Insert the second version ("text 2"), and commit */
    448  1.4  christos 	res = dns_db_findnode(db2, dns_rootname, true, &node);
    449  1.4  christos 	assert_int_equal(res, ISC_R_SUCCESS);
    450  1.4  christos 	res = dns_db_addrdataset(db2, node, v2, 0, &input2, 0, NULL);
    451  1.4  christos 	assert_int_equal(res, ISC_R_SUCCESS);
    452  1.4  christos 	dns_db_closeversion(db2, &v2, true); /* commit */
    453  1.4  christos 	assert_null(v2);
    454  1.4  christos 	dns_db_detachnode(db2, &node);
    455  1.4  christos 	assert_null(node);
    456  1.4  christos 
    457  1.4  christos 	/* db1: Look it up and check that the first version is found */
    458  1.4  christos 	dns_db_currentversion(db1, &v1);
    459  1.4  christos 	assert_non_null(v1);
    460  1.4  christos 	res = dns_db_findnode(db1, dns_rootname, true, &node);
    461  1.4  christos 	assert_int_equal(res, ISC_R_SUCCESS);
    462  1.4  christos 	res = dns_db_findrdataset(db1, node, v1, dns_rdatatype_txt, 0, 0,
    463  1.4  christos 				  &rdataset1, NULL);
    464  1.4  christos 	assert_int_equal(res, ISC_R_SUCCESS);
    465  1.4  christos 
    466  1.4  christos 	/* db1: Convert result to text */
    467  1.4  christos 	res = dns_rdataset_first(&rdataset1);
    468  1.4  christos 	assert_int_equal(res, ISC_R_SUCCESS);
    469  1.4  christos 	dns_rdataset_current(&rdataset1, &out1);
    470  1.4  christos 
    471  1.4  christos 	res = dns_rdata_totext(&out1, NULL, &b);
    472  1.4  christos 	assert_int_equal(res, ISC_R_SUCCESS);
    473  1.4  christos 	isc_buffer_putuint8(&b, 0);
    474  1.4  christos 
    475  1.4  christos 	/* db1: We should have "text 1" */
    476  1.4  christos 	assert_string_equal(buf, "\"text 1\"");
    477  1.4  christos 
    478  1.4  christos 	dns_rdataset_disassociate(&rdataset1);
    479  1.4  christos 
    480  1.4  christos 	dns_db_closeversion(db1, &v1, true);
    481  1.4  christos 	assert_null(v1);
    482  1.4  christos 	dns_db_detachnode(db1, &node);
    483  1.4  christos 	assert_null(node);
    484  1.4  christos 
    485  1.4  christos 	/* db2: Look it up and check that the second version is found */
    486  1.4  christos 	dns_db_currentversion(db2, &v2);
    487  1.4  christos 	assert_non_null(v2);
    488  1.4  christos 	res = dns_db_findnode(db2, dns_rootname, true, &node);
    489  1.4  christos 	assert_int_equal(res, ISC_R_SUCCESS);
    490  1.4  christos 	res = dns_db_findrdataset(db2, node, v2, dns_rdatatype_txt, 0, 0,
    491  1.4  christos 				  &rdataset2, NULL);
    492  1.4  christos 	assert_int_equal(res, ISC_R_SUCCESS);
    493  1.4  christos 
    494  1.4  christos 	/* db2: Convert result to text */
    495  1.4  christos 	res = dns_rdataset_first(&rdataset2);
    496  1.4  christos 	assert_int_equal(res, ISC_R_SUCCESS);
    497  1.4  christos 	dns_rdataset_current(&rdataset2, &out2);
    498  1.4  christos 	isc_buffer_init(&b, buf, sizeof(buf));
    499  1.4  christos 	res = dns_rdata_totext(&out2, NULL, &b);
    500  1.4  christos 	assert_int_equal(res, ISC_R_SUCCESS);
    501  1.4  christos 	isc_buffer_putuint8(&b, 0);
    502  1.4  christos 
    503  1.4  christos 	/* db2: We should have "text 2" */
    504  1.4  christos 	assert_string_equal(buf, "\"text 2\"");
    505  1.4  christos 
    506  1.4  christos 	dns_rdataset_disassociate(&rdataset2);
    507  1.4  christos 
    508  1.4  christos 	dns_db_closeversion(db2, &v2, true);
    509  1.4  christos 	assert_null(v2);
    510  1.4  christos 	dns_db_detachnode(db2, &node);
    511  1.4  christos 	assert_null(node);
    512  1.4  christos }
    513  1.4  christos 
    514  1.1  christos ISC_TEST_LIST_START
    515  1.1  christos ISC_TEST_ENTRY_CUSTOM(find, setup_test, teardown_test)
    516  1.1  christos ISC_TEST_ENTRY_CUSTOM(allrdatasets, setup_test, teardown_test)
    517  1.1  christos ISC_TEST_ENTRY_CUSTOM(findrdataset, setup_test, teardown_test)
    518  1.1  christos ISC_TEST_ENTRY_CUSTOM(deleterdataset, setup_test, teardown_test)
    519  1.1  christos ISC_TEST_ENTRY_CUSTOM(subtract, setup_test, teardown_test)
    520  1.1  christos ISC_TEST_ENTRY_CUSTOM(addrdataset, setup_test, teardown_test)
    521  1.1  christos ISC_TEST_ENTRY_CUSTOM(getnsec3parameters, setup_test, teardown_test)
    522  1.1  christos ISC_TEST_ENTRY_CUSTOM(attachversion, setup_test, teardown_test)
    523  1.1  christos ISC_TEST_ENTRY_CUSTOM(closeversion, setup_test, teardown_test)
    524  1.4  christos ISC_TEST_ENTRY_CUSTOM(rollback, setup_test, teardown_test)
    525  1.1  christos ISC_TEST_LIST_END
    526  1.1  christos 
    527  1.1  christos ISC_TEST_MAIN
    528