1 /*
2  * Copyright (C) Internet Systems Consortium, Inc. ("ISC")
3  *
4  * This Source Code Form is subject to the terms of the Mozilla Public
5  * License, v. 2.0. If a copy of the MPL was not distributed with this
6  * file, you can obtain one at https://mozilla.org/MPL/2.0/.
7  *
8  * See the COPYRIGHT file distributed with this work for additional
9  * information regarding copyright ownership.
10  */
11 
12 #include <config.h>
13 
14 #if HAVE_CMOCKA
15 
16 #include <stdarg.h>
17 #include <stddef.h>
18 #include <setjmp.h>
19 
20 #include <sched.h> /* IWYU pragma: keep */
21 #include <stdlib.h>
22 #include <unistd.h>
23 
24 #define UNIT_TESTING
25 #include <cmocka.h>
26 
27 #include <isc/print.h>
28 
29 #include <dns/db.h>
30 #include <dns/dbiterator.h>
31 #include <dns/name.h>
32 #include <dns/journal.h>
33 
34 #include "dnstest.h"
35 
36 static int
_setup(void ** state)37 _setup(void **state) {
38 	isc_result_t result;
39 
40 	UNUSED(state);
41 
42 	result = dns_test_begin(NULL, false);
43 	assert_int_equal(result, ISC_R_SUCCESS);
44 
45 	return (0);
46 }
47 
48 static int
_teardown(void ** state)49 _teardown(void **state) {
50 	UNUSED(state);
51 
52 	dns_test_end();
53 
54 	return (0);
55 }
56 
57 #define	BUFLEN		255
58 #define	BIGBUFLEN	(64 * 1024)
59 #define TEST_ORIGIN	"test"
60 
61 /*
62  * Individual unit tests
63  */
64 
65 /* test multiple calls to dns_db_getoriginnode */
66 static void
getoriginnode_test(void ** state)67 getoriginnode_test(void **state) {
68 	dns_db_t *db = NULL;
69 	dns_dbnode_t *node = NULL;
70 	isc_mem_t *mymctx = NULL;
71 	isc_result_t result;
72 
73 	UNUSED(state);
74 
75 	result = isc_mem_create(0, 0, &mymctx);
76 	assert_int_equal(result, ISC_R_SUCCESS);
77 
78 	result = dns_db_create(mymctx, "rbt", dns_rootname, dns_dbtype_zone,
79 			    dns_rdataclass_in, 0, NULL, &db);
80 	assert_int_equal(result, ISC_R_SUCCESS);
81 
82 	result = dns_db_getoriginnode(db, &node);
83 	assert_int_equal(result, ISC_R_SUCCESS);
84 	dns_db_detachnode(db, &node);
85 
86 	result = dns_db_getoriginnode(db, &node);
87 	assert_int_equal(result, ISC_R_SUCCESS);
88 	dns_db_detachnode(db, &node);
89 
90 	dns_db_detach(&db);
91 	isc_mem_detach(&mymctx);
92 }
93 
94 /* database class */
95 static void
class_test(void ** state)96 class_test(void **state) {
97 	isc_result_t result;
98 	dns_db_t *db = NULL;
99 
100 	UNUSED(state);
101 
102 	result = dns_db_create(mctx, "rbt", dns_rootname, dns_dbtype_zone,
103 			       dns_rdataclass_in, 0, NULL, &db);
104 	assert_int_equal(result, ISC_R_SUCCESS);
105 
106 	result = dns_db_load(db, "testdata/db/data.db");
107 	assert_int_equal(result, ISC_R_SUCCESS);
108 
109 	assert_int_equal(dns_db_class(db), dns_rdataclass_in);
110 
111 	dns_db_detach(&db);
112 }
113 
114 /* database type */
115 static void
dbtype_test(void ** state)116 dbtype_test(void **state) {
117 	isc_result_t result;
118 	dns_db_t *db = NULL;
119 
120 	UNUSED(state);
121 
122 	/* DB has zone semantics */
123 	result = dns_db_create(mctx, "rbt", dns_rootname, dns_dbtype_zone,
124 			       dns_rdataclass_in, 0, NULL, &db);
125 	assert_int_equal(result, ISC_R_SUCCESS);
126 	result = dns_db_load(db, "testdata/db/data.db");
127 	assert_int_equal(result, ISC_R_SUCCESS);
128 	assert_true(dns_db_iszone(db));
129 	assert_false(dns_db_iscache(db));
130 	dns_db_detach(&db);
131 
132 	/* DB has cache semantics */
133 	result = dns_db_create(mctx, "rbt", dns_rootname, dns_dbtype_cache,
134 			       dns_rdataclass_in, 0, NULL, &db);
135 	assert_int_equal(result, ISC_R_SUCCESS);
136 	result = dns_db_load(db, "testdata/db/data.db");
137 	assert_int_equal(result, ISC_R_SUCCESS);
138 	assert_true(dns_db_iscache(db));
139 	assert_false(dns_db_iszone(db));
140 	dns_db_detach(&db);
141 
142 }
143 
144 /* database versions */
145 static void
version_test(void ** state)146 version_test(void **state) {
147 	isc_result_t result;
148 	dns_fixedname_t fname, ffound;
149 	dns_name_t *name, *foundname;
150 	dns_db_t *db = NULL;
151 	dns_dbversion_t *ver = NULL, *new = NULL;
152 	dns_dbnode_t *node = NULL;
153 	dns_rdataset_t rdataset;
154 
155 	UNUSED(state);
156 
157 	result = dns_test_loaddb(&db, dns_dbtype_zone, "test.test",
158 				 "testdata/db/data.db");
159 	assert_int_equal(result, ISC_R_SUCCESS);
160 
161 	/* Open current version for reading */
162 	dns_db_currentversion(db, &ver);
163 	dns_test_namefromstring("b.test.test", &fname);
164 	name = dns_fixedname_name(&fname);
165 	foundname = dns_fixedname_initname(&ffound);
166 	dns_rdataset_init(&rdataset);
167 	result = dns_db_find(db, name , ver, dns_rdatatype_a, 0, 0, &node,
168 			     foundname, &rdataset, NULL);
169 	assert_int_equal(result, ISC_R_SUCCESS);
170 	dns_rdataset_disassociate(&rdataset);
171 	dns_db_detachnode(db, &node);
172 	dns_db_closeversion(db, &ver, false);
173 
174 	/* Open new version for writing */
175 	dns_db_currentversion(db, &ver);
176 	dns_test_namefromstring("b.test.test", &fname);
177 	name = dns_fixedname_name(&fname);
178 	foundname = dns_fixedname_initname(&ffound);
179 	dns_rdataset_init(&rdataset);
180 	result = dns_db_find(db, name , ver, dns_rdatatype_a, 0, 0, &node,
181 			     foundname, &rdataset, NULL);
182 	assert_int_equal(result, ISC_R_SUCCESS);
183 
184 	result = dns_db_newversion(db, &new);
185 	assert_int_equal(result, ISC_R_SUCCESS);
186 
187 	/* Delete the rdataset from the new version */
188 	result = dns_db_deleterdataset(db, node, new, dns_rdatatype_a, 0);
189 	assert_int_equal(result, ISC_R_SUCCESS);
190 
191 	dns_rdataset_disassociate(&rdataset);
192 	dns_db_detachnode(db, &node);
193 
194 	/* This should fail now */
195 	result = dns_db_find(db, name, new, dns_rdatatype_a, 0, 0, &node,
196 			     foundname, &rdataset, NULL);
197 	assert_int_equal(result, DNS_R_NXDOMAIN);
198 
199 	dns_db_closeversion(db, &new, true);
200 
201 	/* But this should still succeed */
202 	result = dns_db_find(db, name, ver, dns_rdatatype_a, 0, 0, &node,
203 			     foundname, &rdataset, NULL);
204 	assert_int_equal(result, ISC_R_SUCCESS);
205 	dns_rdataset_disassociate(&rdataset);
206 	dns_db_detachnode(db, &node);
207 	dns_db_closeversion(db, &ver, false);
208 
209 	dns_db_detach(&db);
210 }
211 
212 int
main(void)213 main(void) {
214 	const struct CMUnitTest tests[] = {
215 		cmocka_unit_test(getoriginnode_test),
216 		cmocka_unit_test_setup_teardown(class_test,
217 						_setup, _teardown),
218 		cmocka_unit_test_setup_teardown(dbtype_test,
219 						_setup, _teardown),
220 		cmocka_unit_test_setup_teardown(version_test,
221 						_setup, _teardown),
222 	};
223 
224 	return (cmocka_run_group_tests(tests, dns_test_init, dns_test_final));
225 }
226 
227 #else /* HAVE_CMOCKA */
228 
229 #include <stdio.h>
230 
231 int
main(void)232 main(void) {
233 	printf("1..0 # Skipped: cmocka not available\n");
234 	return (0);
235 }
236 
237 #endif
238