xref: /netbsd/external/mpl/bind/dist/lib/dns/tests/db_test.c (revision c0b5d9fb)
1*c0b5d9fbSchristos /*	$NetBSD: db_test.c,v 1.10 2022/09/23 12:15:32 christos Exp $	*/
2e2b1b9c0Schristos 
3e2b1b9c0Schristos /*
4e2b1b9c0Schristos  * Copyright (C) Internet Systems Consortium, Inc. ("ISC")
5e2b1b9c0Schristos  *
6*c0b5d9fbSchristos  * SPDX-License-Identifier: MPL-2.0
7*c0b5d9fbSchristos  *
8e2b1b9c0Schristos  * This Source Code Form is subject to the terms of the Mozilla Public
9e2b1b9c0Schristos  * License, v. 2.0. If a copy of the MPL was not distributed with this
1073584a28Schristos  * file, you can obtain one at https://mozilla.org/MPL/2.0/.
11e2b1b9c0Schristos  *
12e2b1b9c0Schristos  * See the COPYRIGHT file distributed with this work for additional
13e2b1b9c0Schristos  * information regarding copyright ownership.
14e2b1b9c0Schristos  */
15e2b1b9c0Schristos 
16f2e20987Schristos #if HAVE_CMOCKA
17f2e20987Schristos 
189742fdb4Schristos #include <sched.h> /* IWYU pragma: keep */
199742fdb4Schristos #include <setjmp.h>
20f2e20987Schristos #include <stdarg.h>
21f2e20987Schristos #include <stddef.h>
22e2b1b9c0Schristos #include <stdlib.h>
239ad14dd7Schristos #include <unistd.h>
24e2b1b9c0Schristos 
25f2e20987Schristos #define UNIT_TESTING
26f2e20987Schristos #include <cmocka.h>
27f2e20987Schristos 
28e2b1b9c0Schristos #include <dns/db.h>
29e2b1b9c0Schristos #include <dns/dbiterator.h>
30e2b1b9c0Schristos #include <dns/journal.h>
31e2b1b9c0Schristos #include <dns/name.h>
32e2b1b9c0Schristos #include <dns/rdatalist.h>
33e2b1b9c0Schristos 
34e2b1b9c0Schristos #include "dnstest.h"
35e2b1b9c0Schristos 
36f2e20987Schristos static int
_setup(void ** state)37f2e20987Schristos _setup(void **state) {
38f2e20987Schristos 	isc_result_t result;
39f2e20987Schristos 
40f2e20987Schristos 	UNUSED(state);
41f2e20987Schristos 
42f2e20987Schristos 	result = dns_test_begin(NULL, false);
43f2e20987Schristos 	assert_int_equal(result, ISC_R_SUCCESS);
44f2e20987Schristos 
45f2e20987Schristos 	return (0);
46f2e20987Schristos }
47f2e20987Schristos 
48f2e20987Schristos static int
_teardown(void ** state)49f2e20987Schristos _teardown(void **state) {
50f2e20987Schristos 	UNUSED(state);
51f2e20987Schristos 
52f2e20987Schristos 	dns_test_end();
53f2e20987Schristos 
54f2e20987Schristos 	return (0);
55f2e20987Schristos }
56e2b1b9c0Schristos 
57e2b1b9c0Schristos #define BUFLEN	    255
58e2b1b9c0Schristos #define BIGBUFLEN   (64 * 1024)
59e2b1b9c0Schristos #define TEST_ORIGIN "test"
60e2b1b9c0Schristos 
61e2b1b9c0Schristos /*
62e2b1b9c0Schristos  * Individual unit tests
63e2b1b9c0Schristos  */
64e2b1b9c0Schristos 
65f2e20987Schristos /* test multiple calls to dns_db_getoriginnode */
66f2e20987Schristos static void
getoriginnode_test(void ** state)67f2e20987Schristos getoriginnode_test(void **state) {
68e2b1b9c0Schristos 	dns_db_t *db = NULL;
69e2b1b9c0Schristos 	dns_dbnode_t *node = NULL;
709742fdb4Schristos 	isc_mem_t *mctx = NULL;
71e2b1b9c0Schristos 	isc_result_t result;
72e2b1b9c0Schristos 
73f2e20987Schristos 	UNUSED(state);
74e2b1b9c0Schristos 
759742fdb4Schristos 	isc_mem_create(&mctx);
76e2b1b9c0Schristos 
779742fdb4Schristos 	result = dns_db_create(mctx, "rbt", dns_rootname, dns_dbtype_zone,
78e2b1b9c0Schristos 			       dns_rdataclass_in, 0, NULL, &db);
79f2e20987Schristos 	assert_int_equal(result, ISC_R_SUCCESS);
80e2b1b9c0Schristos 
81e2b1b9c0Schristos 	result = dns_db_getoriginnode(db, &node);
82f2e20987Schristos 	assert_int_equal(result, ISC_R_SUCCESS);
83e2b1b9c0Schristos 	dns_db_detachnode(db, &node);
84e2b1b9c0Schristos 
85e2b1b9c0Schristos 	result = dns_db_getoriginnode(db, &node);
86f2e20987Schristos 	assert_int_equal(result, ISC_R_SUCCESS);
87e2b1b9c0Schristos 	dns_db_detachnode(db, &node);
88e2b1b9c0Schristos 
89e2b1b9c0Schristos 	dns_db_detach(&db);
909742fdb4Schristos 	isc_mem_detach(&mctx);
91e2b1b9c0Schristos }
92e2b1b9c0Schristos 
93f2e20987Schristos /* test getservestalettl and setservestalettl */
94f2e20987Schristos static void
getsetservestalettl_test(void ** state)95f2e20987Schristos getsetservestalettl_test(void **state) {
96e2b1b9c0Schristos 	dns_db_t *db = NULL;
979742fdb4Schristos 	isc_mem_t *mctx = NULL;
98e2b1b9c0Schristos 	isc_result_t result;
99e2b1b9c0Schristos 	dns_ttl_t ttl;
100e2b1b9c0Schristos 
101f2e20987Schristos 	UNUSED(state);
102e2b1b9c0Schristos 
1039742fdb4Schristos 	isc_mem_create(&mctx);
104e2b1b9c0Schristos 
1059742fdb4Schristos 	result = dns_db_create(mctx, "rbt", dns_rootname, dns_dbtype_cache,
106e2b1b9c0Schristos 			       dns_rdataclass_in, 0, NULL, &db);
107f2e20987Schristos 	assert_int_equal(result, ISC_R_SUCCESS);
108e2b1b9c0Schristos 
109e2b1b9c0Schristos 	ttl = 5000;
110e2b1b9c0Schristos 	result = dns_db_getservestalettl(db, &ttl);
111f2e20987Schristos 	assert_int_equal(result, ISC_R_SUCCESS);
112f2e20987Schristos 	assert_int_equal(ttl, 0);
113e2b1b9c0Schristos 
114e2b1b9c0Schristos 	ttl = 6 * 3600;
115e2b1b9c0Schristos 	result = dns_db_setservestalettl(db, ttl);
116f2e20987Schristos 	assert_int_equal(result, ISC_R_SUCCESS);
117e2b1b9c0Schristos 
118e2b1b9c0Schristos 	ttl = 5000;
119e2b1b9c0Schristos 	result = dns_db_getservestalettl(db, &ttl);
120f2e20987Schristos 	assert_int_equal(result, ISC_R_SUCCESS);
121f2e20987Schristos 	assert_int_equal(ttl, 6 * 3600);
122e2b1b9c0Schristos 
123e2b1b9c0Schristos 	dns_db_detach(&db);
1249742fdb4Schristos 	isc_mem_detach(&mctx);
125e2b1b9c0Schristos }
126e2b1b9c0Schristos 
127f2e20987Schristos /* check DNS_DBFIND_STALEOK works */
128f2e20987Schristos static void
dns_dbfind_staleok_test(void ** state)129f2e20987Schristos dns_dbfind_staleok_test(void **state) {
130e2b1b9c0Schristos 	dns_db_t *db = NULL;
131e2b1b9c0Schristos 	dns_dbnode_t *node = NULL;
132e2b1b9c0Schristos 	dns_fixedname_t example_fixed;
133e2b1b9c0Schristos 	dns_fixedname_t found_fixed;
134e2b1b9c0Schristos 	dns_name_t *example;
135e2b1b9c0Schristos 	dns_name_t *found;
136e2b1b9c0Schristos 	dns_rdatalist_t rdatalist;
137e2b1b9c0Schristos 	dns_rdataset_t rdataset;
138e2b1b9c0Schristos 	int count;
139e2b1b9c0Schristos 	int pass;
1409742fdb4Schristos 	isc_mem_t *mctx = NULL;
141e2b1b9c0Schristos 	isc_result_t result;
142e2b1b9c0Schristos 	unsigned char data[] = { 0x0a, 0x00, 0x00, 0x01 };
143e2b1b9c0Schristos 
144f2e20987Schristos 	UNUSED(state);
145e2b1b9c0Schristos 
1469742fdb4Schristos 	isc_mem_create(&mctx);
147e2b1b9c0Schristos 
1489742fdb4Schristos 	result = dns_db_create(mctx, "rbt", dns_rootname, dns_dbtype_cache,
149e2b1b9c0Schristos 			       dns_rdataclass_in, 0, NULL, &db);
150f2e20987Schristos 	assert_int_equal(result, ISC_R_SUCCESS);
151e2b1b9c0Schristos 
152e2b1b9c0Schristos 	example = dns_fixedname_initname(&example_fixed);
153e2b1b9c0Schristos 	found = dns_fixedname_initname(&found_fixed);
154e2b1b9c0Schristos 
155e2b1b9c0Schristos 	result = dns_name_fromstring(example, "example", 0, NULL);
156f2e20987Schristos 	assert_int_equal(result, ISC_R_SUCCESS);
157e2b1b9c0Schristos 
158e2b1b9c0Schristos 	/*
159e2b1b9c0Schristos 	 * Pass 0: default; no stale processing permitted.
160e2b1b9c0Schristos 	 * Pass 1: stale processing for 1 second.
161e2b1b9c0Schristos 	 * Pass 2: stale turned off after being on.
162e2b1b9c0Schristos 	 */
163e2b1b9c0Schristos 	for (pass = 0; pass < 3; pass++) {
164e2b1b9c0Schristos 		dns_rdata_t rdata = DNS_RDATA_INIT;
165e2b1b9c0Schristos 
166e2b1b9c0Schristos 		/* 10.0.0.1 */
167e2b1b9c0Schristos 		rdata.data = data;
168e2b1b9c0Schristos 		rdata.length = 4;
169e2b1b9c0Schristos 		rdata.rdclass = dns_rdataclass_in;
170e2b1b9c0Schristos 		rdata.type = dns_rdatatype_a;
171e2b1b9c0Schristos 
172e2b1b9c0Schristos 		dns_rdatalist_init(&rdatalist);
173e2b1b9c0Schristos 		rdatalist.ttl = 2;
174e2b1b9c0Schristos 		rdatalist.type = dns_rdatatype_a;
175e2b1b9c0Schristos 		rdatalist.rdclass = dns_rdataclass_in;
176e2b1b9c0Schristos 		ISC_LIST_APPEND(rdatalist.rdata, &rdata, link);
177e2b1b9c0Schristos 
178e2b1b9c0Schristos 		switch (pass) {
179e2b1b9c0Schristos 		case 0:
180e2b1b9c0Schristos 			/* default: stale processing off */
181e2b1b9c0Schristos 			break;
182e2b1b9c0Schristos 		case 1:
183e2b1b9c0Schristos 			/* turn on stale processing */
184e2b1b9c0Schristos 			result = dns_db_setservestalettl(db, 1);
185f2e20987Schristos 			assert_int_equal(result, ISC_R_SUCCESS);
186e2b1b9c0Schristos 			break;
187e2b1b9c0Schristos 		case 2:
188e2b1b9c0Schristos 			/* turn off stale processing */
189e2b1b9c0Schristos 			result = dns_db_setservestalettl(db, 0);
190f2e20987Schristos 			assert_int_equal(result, ISC_R_SUCCESS);
191e2b1b9c0Schristos 			break;
192e2b1b9c0Schristos 		}
193e2b1b9c0Schristos 
194e2b1b9c0Schristos 		dns_rdataset_init(&rdataset);
195e2b1b9c0Schristos 		result = dns_rdatalist_tordataset(&rdatalist, &rdataset);
196f2e20987Schristos 		assert_int_equal(result, ISC_R_SUCCESS);
197e2b1b9c0Schristos 
198f2e20987Schristos 		result = dns_db_findnode(db, example, true, &node);
199f2e20987Schristos 		assert_int_equal(result, ISC_R_SUCCESS);
200e2b1b9c0Schristos 
201e2b1b9c0Schristos 		result = dns_db_addrdataset(db, node, NULL, 0, &rdataset, 0,
202e2b1b9c0Schristos 					    NULL);
203f2e20987Schristos 		assert_int_equal(result, ISC_R_SUCCESS);
204e2b1b9c0Schristos 
205e2b1b9c0Schristos 		dns_db_detachnode(db, &node);
206e2b1b9c0Schristos 		dns_rdataset_disassociate(&rdataset);
207e2b1b9c0Schristos 
2089742fdb4Schristos 		result = dns_db_find(db, example, NULL, dns_rdatatype_a, 0, 0,
2099742fdb4Schristos 				     &node, found, &rdataset, NULL);
210f2e20987Schristos 		assert_int_equal(result, ISC_R_SUCCESS);
211e2b1b9c0Schristos 
212e2b1b9c0Schristos 		/*
213e2b1b9c0Schristos 		 * May loop for up to 2 seconds performing non stale lookups.
214e2b1b9c0Schristos 		 */
215e2b1b9c0Schristos 		count = 0;
216e2b1b9c0Schristos 		do {
217e2b1b9c0Schristos 			count++;
218803e9293Schristos 			assert_in_range(count, 1, 21); /* loop sanity */
219f2e20987Schristos 			assert_int_equal(rdataset.attributes &
2209742fdb4Schristos 						 DNS_RDATASETATTR_STALE,
2219742fdb4Schristos 					 0);
222f2e20987Schristos 			assert_true(rdataset.ttl > 0);
223e2b1b9c0Schristos 			dns_db_detachnode(db, &node);
224e2b1b9c0Schristos 			dns_rdataset_disassociate(&rdataset);
225e2b1b9c0Schristos 
226e2b1b9c0Schristos 			usleep(100000); /* 100 ms */
227e2b1b9c0Schristos 
2289742fdb4Schristos 			result = dns_db_find(db, example, NULL, dns_rdatatype_a,
2299742fdb4Schristos 					     0, 0, &node, found, &rdataset,
2309742fdb4Schristos 					     NULL);
231e2b1b9c0Schristos 		} while (result == ISC_R_SUCCESS);
232e2b1b9c0Schristos 
233f2e20987Schristos 		assert_int_equal(result, ISC_R_NOTFOUND);
234e2b1b9c0Schristos 
235e2b1b9c0Schristos 		/*
236e2b1b9c0Schristos 		 * Check whether we can get stale data.
237e2b1b9c0Schristos 		 */
238e2b1b9c0Schristos 		result = dns_db_find(db, example, NULL, dns_rdatatype_a,
2399742fdb4Schristos 				     DNS_DBFIND_STALEOK, 0, &node, found,
2409742fdb4Schristos 				     &rdataset, NULL);
241e2b1b9c0Schristos 		switch (pass) {
242e2b1b9c0Schristos 		case 0:
243f2e20987Schristos 			assert_int_equal(result, ISC_R_NOTFOUND);
244e2b1b9c0Schristos 			break;
245e2b1b9c0Schristos 		case 1:
246e2b1b9c0Schristos 			/*
247e2b1b9c0Schristos 			 * Should loop for 1 second with stale lookups then
248e2b1b9c0Schristos 			 * stop.
249e2b1b9c0Schristos 			 */
250e2b1b9c0Schristos 			count = 0;
251e2b1b9c0Schristos 			do {
252e2b1b9c0Schristos 				count++;
253f2e20987Schristos 				assert_in_range(count, 0, 49); /* loop sanity */
254f2e20987Schristos 				assert_int_equal(result, ISC_R_SUCCESS);
255f2e20987Schristos 				assert_int_equal(rdataset.attributes &
256e2b1b9c0Schristos 							 DNS_RDATASETATTR_STALE,
257e2b1b9c0Schristos 						 DNS_RDATASETATTR_STALE);
258e2b1b9c0Schristos 				dns_db_detachnode(db, &node);
259e2b1b9c0Schristos 				dns_rdataset_disassociate(&rdataset);
260e2b1b9c0Schristos 
261e2b1b9c0Schristos 				usleep(100000); /* 100 ms */
262e2b1b9c0Schristos 
2639742fdb4Schristos 				result = dns_db_find(
2649742fdb4Schristos 					db, example, NULL, dns_rdatatype_a,
2659742fdb4Schristos 					DNS_DBFIND_STALEOK, 0, &node, found,
266e2b1b9c0Schristos 					&rdataset, NULL);
267e2b1b9c0Schristos 			} while (result == ISC_R_SUCCESS);
268fadf0758Schristos 			/*
269fadf0758Schristos 			 * usleep(100000) can be slightly less than 10ms so
270fadf0758Schristos 			 * allow the count to reach 11.
271fadf0758Schristos 			 */
272fadf0758Schristos 			assert_in_range(count, 1, 11);
273f2e20987Schristos 			assert_int_equal(result, ISC_R_NOTFOUND);
274e2b1b9c0Schristos 			break;
275e2b1b9c0Schristos 		case 2:
276f2e20987Schristos 			assert_int_equal(result, ISC_R_NOTFOUND);
277e2b1b9c0Schristos 			break;
278e2b1b9c0Schristos 		}
279e2b1b9c0Schristos 	}
280e2b1b9c0Schristos 
281e2b1b9c0Schristos 	dns_db_detach(&db);
2829742fdb4Schristos 	isc_mem_detach(&mctx);
283e2b1b9c0Schristos }
284e2b1b9c0Schristos 
285f2e20987Schristos /* database class */
286f2e20987Schristos static void
class_test(void ** state)287f2e20987Schristos class_test(void **state) {
288e2b1b9c0Schristos 	isc_result_t result;
289e2b1b9c0Schristos 	dns_db_t *db = NULL;
290e2b1b9c0Schristos 
291f2e20987Schristos 	UNUSED(state);
292e2b1b9c0Schristos 
2939742fdb4Schristos 	result = dns_db_create(dt_mctx, "rbt", dns_rootname, dns_dbtype_zone,
294e2b1b9c0Schristos 			       dns_rdataclass_in, 0, NULL, &db);
295f2e20987Schristos 	assert_int_equal(result, ISC_R_SUCCESS);
296e2b1b9c0Schristos 
2979742fdb4Schristos 	result = dns_db_load(db, "testdata/db/data.db", dns_masterformat_text,
2989742fdb4Schristos 			     0);
299f2e20987Schristos 	assert_int_equal(result, ISC_R_SUCCESS);
300e2b1b9c0Schristos 
301f2e20987Schristos 	assert_int_equal(dns_db_class(db), dns_rdataclass_in);
302e2b1b9c0Schristos 
303e2b1b9c0Schristos 	dns_db_detach(&db);
304e2b1b9c0Schristos }
305e2b1b9c0Schristos 
306f2e20987Schristos /* database type */
307f2e20987Schristos static void
dbtype_test(void ** state)308f2e20987Schristos dbtype_test(void **state) {
309e2b1b9c0Schristos 	isc_result_t result;
310e2b1b9c0Schristos 	dns_db_t *db = NULL;
311e2b1b9c0Schristos 
312f2e20987Schristos 	UNUSED(state);
313e2b1b9c0Schristos 
314e2b1b9c0Schristos 	/* DB has zone semantics */
3159742fdb4Schristos 	result = dns_db_create(dt_mctx, "rbt", dns_rootname, dns_dbtype_zone,
316e2b1b9c0Schristos 			       dns_rdataclass_in, 0, NULL, &db);
317f2e20987Schristos 	assert_int_equal(result, ISC_R_SUCCESS);
3189742fdb4Schristos 	result = dns_db_load(db, "testdata/db/data.db", dns_masterformat_text,
3199742fdb4Schristos 			     0);
320f2e20987Schristos 	assert_int_equal(result, ISC_R_SUCCESS);
321f2e20987Schristos 	assert_true(dns_db_iszone(db));
322f2e20987Schristos 	assert_false(dns_db_iscache(db));
323e2b1b9c0Schristos 	dns_db_detach(&db);
324e2b1b9c0Schristos 
325e2b1b9c0Schristos 	/* DB has cache semantics */
3269742fdb4Schristos 	result = dns_db_create(dt_mctx, "rbt", dns_rootname, dns_dbtype_cache,
327e2b1b9c0Schristos 			       dns_rdataclass_in, 0, NULL, &db);
328f2e20987Schristos 	assert_int_equal(result, ISC_R_SUCCESS);
3299742fdb4Schristos 	result = dns_db_load(db, "testdata/db/data.db", dns_masterformat_text,
3309742fdb4Schristos 			     0);
331f2e20987Schristos 	assert_int_equal(result, ISC_R_SUCCESS);
332f2e20987Schristos 	assert_true(dns_db_iscache(db));
333f2e20987Schristos 	assert_false(dns_db_iszone(db));
334e2b1b9c0Schristos 	dns_db_detach(&db);
335e2b1b9c0Schristos }
336e2b1b9c0Schristos 
337f2e20987Schristos /* database versions */
338f2e20987Schristos static void
version_test(void ** state)339f2e20987Schristos version_test(void **state) {
340e2b1b9c0Schristos 	isc_result_t result;
341e2b1b9c0Schristos 	dns_fixedname_t fname, ffound;
342e2b1b9c0Schristos 	dns_name_t *name, *foundname;
343e2b1b9c0Schristos 	dns_db_t *db = NULL;
344e2b1b9c0Schristos 	dns_dbversion_t *ver = NULL, *new = NULL;
345e2b1b9c0Schristos 	dns_dbnode_t *node = NULL;
346e2b1b9c0Schristos 	dns_rdataset_t rdataset;
347e2b1b9c0Schristos 
348f2e20987Schristos 	UNUSED(state);
349e2b1b9c0Schristos 
350e2b1b9c0Schristos 	result = dns_test_loaddb(&db, dns_dbtype_zone, "test.test",
351e2b1b9c0Schristos 				 "testdata/db/data.db");
352f2e20987Schristos 	assert_int_equal(result, ISC_R_SUCCESS);
353e2b1b9c0Schristos 
354e2b1b9c0Schristos 	/* Open current version for reading */
355e2b1b9c0Schristos 	dns_db_currentversion(db, &ver);
356e2b1b9c0Schristos 	dns_test_namefromstring("b.test.test", &fname);
357e2b1b9c0Schristos 	name = dns_fixedname_name(&fname);
358e2b1b9c0Schristos 	foundname = dns_fixedname_initname(&ffound);
359e2b1b9c0Schristos 	dns_rdataset_init(&rdataset);
360e2b1b9c0Schristos 	result = dns_db_find(db, name, ver, dns_rdatatype_a, 0, 0, &node,
361e2b1b9c0Schristos 			     foundname, &rdataset, NULL);
362f2e20987Schristos 	assert_int_equal(result, ISC_R_SUCCESS);
363e2b1b9c0Schristos 	dns_rdataset_disassociate(&rdataset);
364e2b1b9c0Schristos 	dns_db_detachnode(db, &node);
365f2e20987Schristos 	dns_db_closeversion(db, &ver, false);
366e2b1b9c0Schristos 
367e2b1b9c0Schristos 	/* Open new version for writing */
368e2b1b9c0Schristos 	dns_db_currentversion(db, &ver);
369e2b1b9c0Schristos 	dns_test_namefromstring("b.test.test", &fname);
370e2b1b9c0Schristos 	name = dns_fixedname_name(&fname);
371e2b1b9c0Schristos 	foundname = dns_fixedname_initname(&ffound);
372e2b1b9c0Schristos 	dns_rdataset_init(&rdataset);
373e2b1b9c0Schristos 	result = dns_db_find(db, name, ver, dns_rdatatype_a, 0, 0, &node,
374e2b1b9c0Schristos 			     foundname, &rdataset, NULL);
375f2e20987Schristos 	assert_int_equal(result, ISC_R_SUCCESS);
376e2b1b9c0Schristos 
377e2b1b9c0Schristos 	result = dns_db_newversion(db, &new);
378f2e20987Schristos 	assert_int_equal(result, ISC_R_SUCCESS);
379e2b1b9c0Schristos 
3809742fdb4Schristos 	/* Delete the rdataset from the new version */
381e2b1b9c0Schristos 	result = dns_db_deleterdataset(db, node, new, dns_rdatatype_a, 0);
382f2e20987Schristos 	assert_int_equal(result, ISC_R_SUCCESS);
383e2b1b9c0Schristos 
384e2b1b9c0Schristos 	dns_rdataset_disassociate(&rdataset);
385e2b1b9c0Schristos 	dns_db_detachnode(db, &node);
386e2b1b9c0Schristos 
387e2b1b9c0Schristos 	/* This should fail now */
388e2b1b9c0Schristos 	result = dns_db_find(db, name, new, dns_rdatatype_a, 0, 0, &node,
389e2b1b9c0Schristos 			     foundname, &rdataset, NULL);
390f2e20987Schristos 	assert_int_equal(result, DNS_R_NXDOMAIN);
391e2b1b9c0Schristos 
392f2e20987Schristos 	dns_db_closeversion(db, &new, true);
393e2b1b9c0Schristos 
394e2b1b9c0Schristos 	/* But this should still succeed */
395e2b1b9c0Schristos 	result = dns_db_find(db, name, ver, dns_rdatatype_a, 0, 0, &node,
396e2b1b9c0Schristos 			     foundname, &rdataset, NULL);
397f2e20987Schristos 	assert_int_equal(result, ISC_R_SUCCESS);
398e2b1b9c0Schristos 	dns_rdataset_disassociate(&rdataset);
399e2b1b9c0Schristos 	dns_db_detachnode(db, &node);
400f2e20987Schristos 	dns_db_closeversion(db, &ver, false);
401e2b1b9c0Schristos 
402e2b1b9c0Schristos 	dns_db_detach(&db);
403e2b1b9c0Schristos }
404e2b1b9c0Schristos 
405f2e20987Schristos int
main(void)406f2e20987Schristos main(void) {
407f2e20987Schristos 	const struct CMUnitTest tests[] = {
408f2e20987Schristos 		cmocka_unit_test(getoriginnode_test),
409f2e20987Schristos 		cmocka_unit_test(getsetservestalettl_test),
410f2e20987Schristos 		cmocka_unit_test(dns_dbfind_staleok_test),
4119742fdb4Schristos 		cmocka_unit_test_setup_teardown(class_test, _setup, _teardown),
4129742fdb4Schristos 		cmocka_unit_test_setup_teardown(dbtype_test, _setup, _teardown),
4139742fdb4Schristos 		cmocka_unit_test_setup_teardown(version_test, _setup,
4149742fdb4Schristos 						_teardown),
415f2e20987Schristos 	};
416e2b1b9c0Schristos 
417f2e20987Schristos 	return (cmocka_run_group_tests(tests, NULL, NULL));
418e2b1b9c0Schristos }
419f2e20987Schristos 
420f2e20987Schristos #else /* HAVE_CMOCKA */
421f2e20987Schristos 
422f2e20987Schristos #include <stdio.h>
423f2e20987Schristos 
424f2e20987Schristos int
main(void)425f2e20987Schristos main(void) {
426f2e20987Schristos 	printf("1..0 # Skipped: cmocka not available\n");
42776b1fd8fSchristos 	return (SKIPPED_TEST_EXIT_CODE);
428f2e20987Schristos }
429f2e20987Schristos 
4309742fdb4Schristos #endif /* if HAVE_CMOCKA */
431