t_db.c 77.2 KB
Newer Older
1
/*
2
 * Copyright (C) Internet Systems Consortium, Inc. ("ISC")
3
 *
4 5 6
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
7 8 9
 *
 * See the COPYRIGHT file distributed with this work for additional
 * information regarding copyright ownership.
10 11
 */

Automatic Updater's avatar
Automatic Updater committed
12
/* $Id: t_db.c,v 1.41 2011/03/12 04:59:46 tbox Exp $ */
David Lawrence's avatar
David Lawrence committed
13

14 15 16 17
#include <config.h>

#include <ctype.h>
#include <stdlib.h>
18

19 20
#include <isc/entropy.h>
#include <isc/hash.h>
21 22
#include <isc/mem.h>
#include <isc/string.h>
David Lawrence's avatar
David Lawrence committed
23
#include <isc/util.h>
24 25

#include <dns/db.h>
26 27 28 29 30 31
#include <dns/fixedname.h>
#include <dns/rdata.h>
#include <dns/rdataclass.h>
#include <dns/rdatatype.h>
#include <dns/rdatalist.h>
#include <dns/rdataset.h>
32
#include <dns/result.h>
33 34 35

#include <tests/t_api.h>

36
static isc_result_t
37
t_create(const char *db_type, const char *origin, const char *classname,
38
	 const char *model, isc_mem_t *mctx, dns_db_t **db)
39
{
40
	int			len;
41
	isc_result_t		dns_result;
42
	dns_dbtype_t		dbtype;
Mark Andrews's avatar
Mark Andrews committed
43
	isc_textregion_t	region;
44 45 46 47 48
	isc_buffer_t		origin_buffer;
	dns_fixedname_t		dns_origin;
	dns_rdataclass_t	rdataclass;


49
	dbtype = dns_dbtype_zone;
50
	if (strcasecmp(model, "cache") == 0)
51
		dbtype = dns_dbtype_cache;
52 53 54

	dns_fixedname_init(&dns_origin);
	len = strlen(origin);
55
	isc_buffer_constinit(&origin_buffer, origin, len);
56 57
	isc_buffer_add(&origin_buffer, len);
	dns_result = dns_name_fromtext(dns_fixedname_name(&dns_origin),
58
				       &origin_buffer, NULL, 0, NULL);
59
	if (dns_result != ISC_R_SUCCESS) {
60
		t_info("dns_name_fromtext failed %s\n",
61
		       dns_result_totext(dns_result));
62 63 64
		return(dns_result);
	}

65 66
	DE_CONST(classname, region.base);
	region.length = strlen(classname);
Mark Andrews's avatar
Mark Andrews committed
67
	dns_result = dns_rdataclass_fromtext(&rdataclass, &region);
68
	if (dns_result != ISC_R_SUCCESS) {
69
		t_info("dns_rdataclass_fromtext failed %s\n",
70
		       dns_result_totext(dns_result));
71 72 73
		return(dns_result);
	}

David Lawrence's avatar
David Lawrence committed
74 75
	dns_result = dns_db_create(mctx, db_type,
				   dns_fixedname_name(&dns_origin),
76
				   dbtype, rdataclass, 0, NULL, db);
David Lawrence's avatar
David Lawrence committed
77
	if (dns_result != ISC_R_SUCCESS)
78
		t_info("dns_db_create failed %s\n",
79
		       dns_result_totext(dns_result));
80 81 82 83 84 85 86 87 88 89

	return(dns_result);

}

static int
t_dns_db_load(char **av) {
	char			*filename;
	char			*db_type;
	char			*origin;
90
	char			*model;
91
	char			*db_class;
92 93 94 95 96 97 98 99
	char			*expected_load_result;
	char			*findname;
	char			*find_type;
	char			*expected_find_result;

	int			result;
	int			len;
	dns_db_t		*db;
100
	isc_result_t		dns_result;
101 102
	isc_result_t		isc_result;
	isc_mem_t		*mctx;
103
	isc_entropy_t		*ectx;
104 105 106 107 108 109 110 111
	dns_dbnode_t		*nodep;
	isc_textregion_t	textregion;
	isc_buffer_t		findname_buffer;
	dns_fixedname_t		dns_findname;
	dns_fixedname_t		dns_foundname;
	dns_rdataset_t		rdataset;
	dns_rdatatype_t		rdatatype;
	dns_dbversion_t		*versionp;
112 113
	isc_result_t		exp_load_result;
	isc_result_t		exp_find_result;
114 115 116

	db = NULL;
	mctx = NULL;
117
	ectx = NULL;
118 119 120
	filename = T_ARG(0);
	db_type = T_ARG(1);
	origin = T_ARG(2);
121
	model = T_ARG(3);
122
	db_class = T_ARG(4);
123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139
	expected_load_result = T_ARG(5);
	findname = T_ARG(6);
	find_type = T_ARG(7);
	expected_find_result = T_ARG(8);

	t_info("testing using file %s and name %s\n", filename, findname);

	exp_load_result = t_dns_result_fromtext(expected_load_result);
	exp_find_result = t_dns_result_fromtext(expected_find_result);

	isc_result = isc_mem_create(0, 0, &mctx);
	if (isc_result != ISC_R_SUCCESS) {
		t_info("isc_mem_create failed %s\n",
				isc_result_totext(isc_result));
		return(T_UNRESOLVED);
	}

140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156
	isc_result = isc_entropy_create(mctx, &ectx);
	if (isc_result != ISC_R_SUCCESS) {
		t_info("isc_entropy_create failed %s\n",
				isc_result_totext(isc_result));
		isc_mem_destroy(&mctx);
		return(T_UNRESOLVED);
	}

	isc_result = isc_hash_create(mctx, ectx, DNS_NAME_MAXWIRE);
	if (isc_result != ISC_R_SUCCESS) {
		t_info("isc_hash_create failed %s\n",
				isc_result_totext(isc_result));
		isc_entropy_detach(&ectx);
		isc_mem_destroy(&mctx);
		return(T_UNRESOLVED);
	}

157
	dns_result = t_create(db_type, origin, db_class, model, mctx, &db);
158
	if (dns_result != ISC_R_SUCCESS) {
159 160
		isc_hash_destroy();
		isc_entropy_detach(&ectx);
161 162 163 164 165 166 167 168 169 170
		isc_mem_destroy(&mctx);
		return(T_UNRESOLVED);
	}

	dns_result = dns_db_load(db, filename);
	if (dns_result != exp_load_result) {
		t_info("dns_db_load returned %s, expected %s\n",
				dns_result_totext(dns_result),
				dns_result_totext(exp_load_result));
		dns_db_detach(&db);
171 172
		isc_hash_destroy();
		isc_entropy_detach(&ectx);
173 174 175
		isc_mem_destroy(&mctx);
		return(T_FAIL);
	}
176 177 178 179
	if (dns_result != ISC_R_SUCCESS) {
		result = T_PASS;
		goto cleanup_db;
	}
180 181 182

	dns_fixedname_init(&dns_findname);
	len = strlen(findname);
183
	isc_buffer_init(&findname_buffer, findname, len);
184 185
	isc_buffer_add(&findname_buffer, len);
	dns_result = dns_name_fromtext(dns_fixedname_name(&dns_findname),
186
				&findname_buffer, NULL, 0, NULL);
187
	if (dns_result != ISC_R_SUCCESS) {
188 189 190
		t_info("dns_name_fromtext failed %s\n",
			dns_result_totext(dns_result));
		dns_db_detach(&db);
191 192
		isc_hash_destroy();
		isc_entropy_detach(&ectx);
193 194 195 196 197 198 199
		isc_mem_destroy(&mctx);
		return(T_UNRESOLVED);
	}

	textregion.base = find_type;
	textregion.length = strlen(find_type);
	dns_result = dns_rdatatype_fromtext(&rdatatype, &textregion);
200
	if (dns_result != ISC_R_SUCCESS) {
201 202 203 204
		t_info("dns_rdatatype_fromtext %s failed %s\n",
				find_type,
				dns_result_totext(dns_result));
		dns_db_detach(&db);
205 206
		isc_hash_destroy();
		isc_entropy_detach(&ectx);
207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225
		isc_mem_destroy(&mctx);
		return(T_UNRESOLVED);
	}

	versionp = NULL;
	dns_fixedname_init(&dns_foundname);
	dns_rdataset_init(&rdataset);
	if (dns_db_iszone(db))
		dns_db_currentversion(db, &versionp);
	nodep = NULL;

	dns_result = dns_db_find(db,
			dns_fixedname_name(&dns_findname),
			versionp,
			rdatatype,
			DNS_DBFIND_GLUEOK,
			0,
			&nodep,
			dns_fixedname_name(&dns_foundname),
Bob Halley's avatar
Bob Halley committed
226
			&rdataset, NULL);
227 228

	if (dns_result != exp_find_result) {
Bob Halley's avatar
Bob Halley committed
229
		t_info("dns_db_find returned %s, expected %s\n",
230 231 232
				dns_result_totext(dns_result),
				dns_result_totext(exp_find_result));
		result = T_FAIL;
233
	} else {
234 235 236
		result = T_PASS;
	}

237
	if (dns_result != ISC_R_NOTFOUND) {
238
		dns_db_detachnode(db, &nodep);
William King's avatar
William King committed
239 240
		if (dns_rdataset_isassociated(&rdataset))
			dns_rdataset_disassociate(&rdataset);
241 242 243 244
	}

	if (dns_db_iszone(db))
		dns_db_closeversion(db, &versionp, ISC_FALSE);
245
 cleanup_db:
246
	dns_db_detach(&db);
247 248
	isc_hash_destroy();
	isc_entropy_detach(&ectx);
249 250 251 252
	isc_mem_destroy(&mctx);
	return(result);
}

David Lawrence's avatar
David Lawrence committed
253
static const char *a1 =
254 255 256 257
	"A call to dns_db_load(db, filename) loads the contents of "
	"the database in filename into db.";

static void
258
t1(void) {
259 260
	int	result;

261
	t_assert("dns_db_load", 1, T_REQUIRED, "%s", a1);
262
	result = t_eval("dns_db_load_data", t_dns_db_load, 9);
263 264 265 266
	t_result(result);
}


David Lawrence's avatar
David Lawrence committed
267
static const char *a2 =
268 269 270 271
	"When the database db has cache semantics, a call to "
	"dns_db_iscache(db) returns ISC_TRUE.";

static int
272
t_dns_db_zc_x(char *filename, char *db_type, char *origin, char *db_class,
273
	      dns_dbtype_t dbtype, isc_boolean_t(*cf)(dns_db_t *),
274 275
	      isc_boolean_t exp_result)
{
276 277 278
	int			result;
	int			len;
	dns_db_t		*db;
279
	isc_result_t		dns_result;
280 281
	isc_result_t		isc_result;
	isc_mem_t		*mctx;
282
	isc_entropy_t		*ectx;
283 284 285 286 287 288 289
	dns_rdataclass_t	rdataclass;
	isc_textregion_t	textregion;
	isc_buffer_t		origin_buffer;
	dns_fixedname_t		dns_origin;

	db = NULL;
	mctx = NULL;
290
	ectx = NULL;
291 292 293 294 295

	t_info("testing using file %s\n", filename);

	dns_fixedname_init(&dns_origin);
	len = strlen(origin);
296
	isc_buffer_init(&origin_buffer, origin, len);
297 298
	isc_buffer_add(&origin_buffer, len);
	dns_result = dns_name_fromtext(dns_fixedname_name(&dns_origin),
299
				       &origin_buffer, NULL, 0, NULL);
300
	if (dns_result != ISC_R_SUCCESS) {
301
		t_info("dns_name_fromtext failed %s\n",
302
		       dns_result_totext(dns_result));
303 304 305
		return(T_UNRESOLVED);
	}

306 307
	textregion.base = db_class;
	textregion.length = strlen(db_class);
308
	dns_result = dns_rdataclass_fromtext(&rdataclass, &textregion);
309
	if (dns_result != ISC_R_SUCCESS) {
310
		t_info("dns_rdataclass_fromtext failed %s\n",
311
		       dns_result_totext(dns_result));
312 313 314 315 316 317
		return(T_UNRESOLVED);
	}

	isc_result = isc_mem_create(0, 0, &mctx);
	if (isc_result != ISC_R_SUCCESS) {
		t_info("isc_mem_create failed %s\n",
318
		       isc_result_totext(isc_result));
319 320 321
		return(T_UNRESOLVED);
	}

322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338
	isc_result = isc_entropy_create(mctx, &ectx);
	if (isc_result != ISC_R_SUCCESS) {
		t_info("isc_entropy_create failed %s\n",
				isc_result_totext(isc_result));
		isc_mem_destroy(&mctx);
		return(T_UNRESOLVED);
	}

	isc_result = isc_hash_create(mctx, ectx, DNS_NAME_MAXWIRE);
	if (isc_result != ISC_R_SUCCESS) {
		t_info("isc_hash_create failed %s\n",
				isc_result_totext(isc_result));
		isc_entropy_detach(&ectx);
		isc_mem_destroy(&mctx);
		return(T_UNRESOLVED);
	}

339
	dns_result = dns_db_create(mctx, db_type,
340
				   dns_fixedname_name(&dns_origin),
341
				   dbtype, rdataclass, 0, NULL, &db);
342
	if (dns_result != ISC_R_SUCCESS) {
343
		t_info("dns_db_create failed %s\n",
344
		       dns_result_totext(dns_result));
345 346
		isc_hash_destroy();
		isc_entropy_detach(&ectx);
347 348 349 350 351
		isc_mem_destroy(&mctx);
		return(T_UNRESOLVED);
	}

	dns_result = dns_db_load(db, filename);
352
	if (dns_result == ISC_R_SUCCESS) {
353 354 355 356
		if ((*cf)(db) == exp_result)
			result = T_PASS;
		else
			result = T_FAIL;
357
	} else {
358
		t_info("dns_db_load failed %s\n",
359
		       dns_result_totext(dns_result));
360 361 362 363
		result = T_FAIL;
	}

	dns_db_detach(&db);
364 365
	isc_hash_destroy();
	isc_entropy_detach(&ectx);
366 367 368 369 370
	isc_mem_destroy(&mctx);
	return(result);
}

static int
371
test_dns_db_zc_x(const char *filename, dns_dbtype_t dbtype,
372 373
		 isc_boolean_t(*cf)(dns_db_t *), isc_boolean_t exp_result)
{
374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393

	FILE		*fp;
	char		*p;
	int		line;
	int		cnt;
	int		result;
	int		nfails;
	int		nprobs;
	char		*tokens[T_MAXTOKS];

	nfails = 0;
	nprobs = 0;

	fp = fopen(filename, "r");
	if (fp != NULL) {
		line = 0;
		while ((p = t_fgetbs(fp)) != NULL) {

			++line;

394 395 396
			/*
			 * Skip comment lines.
			 */
397 398
			if ((isspace((unsigned char)*p)) || (*p == '#')) {
				(void)free(p);
399
				continue;
400
			}
401 402 403

			cnt = t_bustline(p, tokens);
			if (cnt == 4) {
404 405 406 407
				result = t_dns_db_zc_x(tokens[0], /* file */
						       tokens[1], /* type */
						       tokens[2], /* origin */
						       tokens[3], /* class */
408
						       dbtype,     /* cache */
409 410
						       cf,     /* check func */
						       exp_result);/* expect */
411 412 413 414 415 416
				if (result != T_PASS) {
					if (result == T_FAIL)
						++nfails;
					else
						++nprobs;
				}
417
			} else {
418
				t_info("bad format in %s at line %d\n",
419
				       filename, line);
420 421 422
				++nprobs;
			}

423
			(void)free(p);
424
		}
425 426
		(void)fclose(fp);
	} else {
427 428 429 430 431 432
		t_info("Missing datafile %s\n", filename);
		++nprobs;
	}

	result = T_UNRESOLVED;

433
	if (nfails == 0 && nprobs == 0)
434 435 436 437 438 439 440 441
		result = T_PASS;
	else if (nfails)
		result = T_FAIL;

	return(result);
}

static void
442
t2(void) {
443 444
	int	result;

445
	t_assert("dns_db_iscache", 2, T_REQUIRED, "%s", a2);
446
	result = test_dns_db_zc_x("dns_db_iscache_1_data",
447
				  dns_dbtype_cache, dns_db_iscache, ISC_TRUE);
448 449 450 451
	t_result(result);
}


David Lawrence's avatar
David Lawrence committed
452
static const char *a3 =
453 454 455 456 457
	"When the database db has zone semantics, a call to "
	"dns_db_iscache(db) returns ISC_FALSE.";


static void
458
t3(void) {
459 460
	int	result;

461
	t_assert("dns_db_iscache", 3, T_REQUIRED, "%s", a3);
462
	result = test_dns_db_zc_x("dns_db_iscache_2_data",
463
				  dns_dbtype_zone, dns_db_iscache, ISC_FALSE);
464 465 466 467
	t_result(result);
}


David Lawrence's avatar
David Lawrence committed
468
static const char *a4 =
469 470 471 472 473
	"When the database db has zone semantics, a call to "
	"dns_db_iszone(db) returns ISC_TRUE.";


static void
474
t4(void) {
475 476
	int	result;

477
	t_assert("dns_db_iszone", 4, T_REQUIRED, "%s", a4);
478
	result = test_dns_db_zc_x("dns_db_iszone_1_data",
479
				  dns_dbtype_zone, dns_db_iszone, ISC_TRUE);
480 481 482 483
	t_result(result);
}


David Lawrence's avatar
David Lawrence committed
484
static const char *a5 =
485 486 487 488
	"When the database db has cache semantics, a call to "
	"dns_db_iszone(db) returns ISC_FALSE.";

static void
489
t5(void) {
490 491
	int	result;

492
	t_assert("dns_db_iszone", 5, T_REQUIRED, "%s", a5);
493
	result = test_dns_db_zc_x("dns_db_iszone_2_data",
494
				  dns_dbtype_cache, dns_db_iszone, ISC_FALSE);
495 496 497 498 499 500 501 502 503 504 505 506
	t_result(result);
}

static int
t_dns_db_origin(char **av) {

	char			*filename;
	char			*origin;

	int			result;
	int			len;
	int			order;
507
	isc_result_t		dns_result;
508 509
	isc_result_t		isc_result;
	isc_mem_t		*mctx;
510
	isc_entropy_t		*ectx;
511 512 513 514 515 516 517
	dns_db_t		*db;
	dns_fixedname_t		dns_origin;
	dns_fixedname_t		dns_dborigin;
	isc_buffer_t		origin_buffer;

	db = NULL;
	mctx = NULL;
518
	ectx = NULL;
519 520 521 522 523 524 525 526 527 528 529 530 531 532

	filename = T_ARG(0);
	origin = T_ARG(1);

	t_info("testing with database %s and origin %s\n",
			filename, origin);

	isc_result = isc_mem_create(0, 0, &mctx);
	if (isc_result != ISC_R_SUCCESS) {
		t_info("isc_mem_create failed %s\n",
			isc_result_totext(isc_result));
		return(T_UNRESOLVED);
	}

533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549
	isc_result = isc_entropy_create(mctx, &ectx);
	if (isc_result != ISC_R_SUCCESS) {
		t_info("isc_entropy_create failed %s\n",
				isc_result_totext(isc_result));
		isc_mem_destroy(&mctx);
		return(T_UNRESOLVED);
	}

	isc_result = isc_hash_create(mctx, ectx, DNS_NAME_MAXWIRE);
	if (isc_result != ISC_R_SUCCESS) {
		t_info("isc_hash_create failed %s\n",
				isc_result_totext(isc_result));
		isc_entropy_detach(&ectx);
		isc_mem_destroy(&mctx);
		return(T_UNRESOLVED);
	}

550
	dns_result = t_create("rbt", origin, "in", "isc_true", mctx, &db);
551
	if (dns_result != ISC_R_SUCCESS) {
552 553
		t_info("t_create failed %s\n",
			dns_result_totext(dns_result));
554 555
		isc_hash_destroy();
		isc_entropy_detach(&ectx);
556 557 558 559 560 561 562
		isc_mem_destroy(&mctx);
		return(T_UNRESOLVED);
	}
	dns_fixedname_init(&dns_origin);
	dns_fixedname_init(&dns_dborigin);

	len = strlen(origin);
563
	isc_buffer_init(&origin_buffer, origin, len);
564 565 566
	isc_buffer_add(&origin_buffer, len);

	dns_result = dns_db_load(db, filename);
567
	if (dns_result != ISC_R_SUCCESS) {
568 569 570
		t_info("dns_db_load failed %s\n",
				dns_result_totext(dns_result));
		dns_db_detach(&db);
571 572
		isc_hash_destroy();
		isc_entropy_detach(&ectx);
573 574 575 576 577
		isc_mem_destroy(&mctx);
		return(T_UNRESOLVED);
	}

	dns_result = dns_name_fromtext(dns_fixedname_name(&dns_origin),
578
				&origin_buffer, NULL, 0, NULL);
579
	if (dns_result != ISC_R_SUCCESS) {
580 581 582
		t_info("dns_name_fromtext failed %s\n",
				dns_result_totext(dns_result));
		dns_db_detach(&db);
583 584
		isc_hash_destroy();
		isc_entropy_detach(&ectx);
585 586 587
		isc_mem_destroy(&mctx);
		return(T_UNRESOLVED);
	}
588 589
	order = dns_name_compare(dns_fixedname_name(&dns_origin),
				 dns_db_origin(db));
590 591
	if (order == 0) {
		result = T_PASS;
592
	} else {
593 594 595 596 597
		t_info("dns_name_compare returned %d\n", order);
		result = T_FAIL;
	}

	dns_db_detach(&db);
598 599
	isc_hash_destroy();
	isc_entropy_detach(&ectx);
600 601 602 603 604
	isc_mem_destroy(&mctx);
	return(result);

}

David Lawrence's avatar
David Lawrence committed
605
static const char *a6 =
606 607 608
	"A call to dns_db_origin(db) returns the origin of the database.";

static void
609
t6(void) {
610 611
	int	result;

612
	t_assert("dns_db_origin", 6, T_REQUIRED, "%s", a6);
613 614 615 616 617
	result = t_eval("dns_db_origin_data", t_dns_db_origin, 2);
	t_result(result);
}


David Lawrence's avatar
David Lawrence committed
618
static const char *a7 =
619 620 621 622 623 624 625 626 627
	"A call to dns_db_class(db) returns the class of the database.";


#define	CLASSBUFLEN	256

static int
t_dns_db_class(char **av) {

	char			*filename;
628
	char			*db_class;
629 630

	int			result;
631
	isc_result_t		dns_result;
632 633
	isc_result_t		isc_result;
	isc_mem_t		*mctx;
634
	isc_entropy_t		*ectx;
635 636 637 638 639 640
	dns_db_t		*db;
	dns_rdataclass_t	rdataclass;
	dns_rdataclass_t	db_rdataclass;
	isc_textregion_t	textregion;

	filename = T_ARG(0);
641
	db_class = T_ARG(1);
642 643
	db = NULL;
	mctx = NULL;
644
	ectx = NULL;
645 646

	t_info("testing with database %s and class %s\n",
647
			filename, db_class);
648

649 650
	textregion.base = db_class;
	textregion.length = strlen(db_class);
651
	dns_result = dns_rdataclass_fromtext(&rdataclass, &textregion);
652
	if (dns_result != ISC_R_SUCCESS) {
653 654 655 656 657 658 659 660 661 662 663 664
		t_info("dns_rdataclass_fromtext failed %s\n",
				dns_result_totext(dns_result));
		return(T_UNRESOLVED);
	}

	isc_result = isc_mem_create(0, 0, &mctx);
	if (isc_result != ISC_R_SUCCESS) {
		t_info("isc_mem_create failed %s\n",
			isc_result_totext(isc_result));
		return(T_UNRESOLVED);
	}

665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681
	isc_result = isc_entropy_create(mctx, &ectx);
	if (isc_result != ISC_R_SUCCESS) {
		t_info("isc_entropy_create failed %s\n",
				isc_result_totext(isc_result));
		isc_mem_destroy(&mctx);
		return(T_UNRESOLVED);
	}

	isc_result = isc_hash_create(mctx, ectx, DNS_NAME_MAXWIRE);
	if (isc_result != ISC_R_SUCCESS) {
		t_info("isc_hash_create failed %s\n",
				isc_result_totext(isc_result));
		isc_entropy_detach(&ectx);
		isc_mem_destroy(&mctx);
		return(T_UNRESOLVED);
	}

682
	dns_result = t_create("rbt", ".", db_class, "isc_true", mctx, &db);
683
	if (dns_result != ISC_R_SUCCESS) {
684 685
		t_info("t_create failed %s\n",
			dns_result_totext(dns_result));
686 687
		isc_hash_destroy();
		isc_entropy_detach(&ectx);
688 689 690 691 692
		isc_mem_destroy(&mctx);
		return(T_UNRESOLVED);
	}

	dns_result = dns_db_load(db, filename);
693
	if (dns_result != ISC_R_SUCCESS) {
694 695 696
		t_info("dns_db_load failed %s\n",
				dns_result_totext(dns_result));
		dns_db_detach(&db);
697 698
		isc_hash_destroy();
		isc_entropy_detach(&ectx);
699 700 701 702 703
		isc_mem_destroy(&mctx);
		return(T_UNRESOLVED);
	}

	db_rdataclass = dns_db_class(db);
704
	if (db_rdataclass == rdataclass)
705 706
		result = T_PASS;
	else {
707 708 709 710
		char classbuf[DNS_RDATACLASS_FORMATSIZE];
		dns_rdataclass_format(db_rdataclass,
				      classbuf, sizeof(classbuf));
		t_info("dns_db_class returned %s, expected %s\n",
711
		       classbuf, db_class);
712 713 714 715
		result = T_FAIL;
	}

	dns_db_detach(&db);
716 717
	isc_hash_destroy();
	isc_entropy_detach(&ectx);
718 719 720 721 722
	isc_mem_destroy(&mctx);
	return(result);

}
static void
723
t7(void) {
724 725
	int	result;

726
	t_assert("dns_db_class", 7, T_REQUIRED, "%s", a7);
727 728 729 730 731
	result = t_eval("dns_db_class_data", t_dns_db_class, 2);
	t_result(result);
}


David Lawrence's avatar
David Lawrence committed
732
static const char *a8 =
733 734 735 736 737 738 739 740
	"A call to dns_db_currentversion() opens the current "
	"version for reading.";

static int
t_dns_db_currentversion(char **av) {
	char			*filename;
	char			*db_type;
	char			*origin;
741
	char			*db_class;
742
	char			*model;
743 744 745 746 747 748
	char			*findname;
	char			*findtype;

	int			result;
	int			len;
	dns_db_t		*db;
749
	isc_result_t		dns_result;
750 751
	isc_result_t		isc_result;
	isc_mem_t		*mctx;
752
	isc_entropy_t		*ectx;
753 754 755 756 757 758 759 760 761 762 763 764 765
	dns_dbnode_t		*nodep;
	isc_textregion_t	textregion;
	isc_buffer_t		findname_buffer;
	dns_fixedname_t		dns_findname;
	dns_fixedname_t		dns_foundname;
	dns_rdataset_t		rdataset;
	dns_rdatatype_t		rdatatype;
	dns_dbversion_t		*cversionp;
	dns_dbversion_t		*nversionp;

	filename = T_ARG(0);
	db_type = T_ARG(1);
	origin = T_ARG(2);
766
	db_class = T_ARG(3);
767
	model = T_ARG(4);
768 769 770 771
	findname = T_ARG(5);
	findtype = T_ARG(6);
	db = NULL;
	mctx = NULL;
772
	ectx = NULL;
773 774 775 776 777 778 779 780 781 782

	t_info("testing using file %s and name %s\n", filename, findname);

	isc_result = isc_mem_create(0, 0, &mctx);
	if (isc_result != ISC_R_SUCCESS) {
		t_info("isc_mem_create failed %s\n",
				isc_result_totext(isc_result));
		return(T_UNRESOLVED);
	}

783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799
	isc_result = isc_entropy_create(mctx, &ectx);
	if (isc_result != ISC_R_SUCCESS) {
		t_info("isc_entropy_create failed %s\n",
				isc_result_totext(isc_result));
		isc_mem_destroy(&mctx);
		return(T_UNRESOLVED);
	}

	isc_result = isc_hash_create(mctx, ectx, DNS_NAME_MAXWIRE);
	if (isc_result != ISC_R_SUCCESS) {
		t_info("isc_hash_create failed %s\n",
				isc_result_totext(isc_result));
		isc_entropy_detach(&ectx);
		isc_mem_destroy(&mctx);
		return(T_UNRESOLVED);
	}

800
	dns_result = t_create(db_type, origin, db_class, model, mctx, &db);
801
	if (dns_result != ISC_R_SUCCESS) {
802 803
		isc_hash_destroy();
		isc_entropy_detach(&ectx);
804 805 806 807 808
		isc_mem_destroy(&mctx);
		return(T_UNRESOLVED);
	}

	dns_result = dns_db_load(db, filename);
809
	if (dns_result != ISC_R_SUCCESS) {
810 811 812
		t_info("dns_db_load returned %s\n",
				dns_result_totext(dns_result));
		dns_db_detach(&db);
813 814
		isc_hash_destroy();
		isc_entropy_detach(&ectx);
815 816 817 818 819 820
		isc_mem_destroy(&mctx);
		return(T_UNRESOLVED);
	}

	dns_fixedname_init(&dns_findname);
	len = strlen(findname);
821
	isc_buffer_init(&findname_buffer, findname, len);
822 823
	isc_buffer_add(&findname_buffer, len);
	dns_result = dns_name_fromtext(dns_fixedname_name(&dns_findname),
824
				&findname_buffer, NULL, 0, NULL);
825
	if (dns_result != ISC_R_SUCCESS) {
826 827 828
		t_info("dns_name_fromtext failed %s\n",
			dns_result_totext(dns_result));
		dns_db_detach(&db);
829 830
		isc_hash_destroy();
		isc_entropy_detach(&ectx);
831 832 833 834 835 836 837
		isc_mem_destroy(&mctx);
		return(T_UNRESOLVED);
	}

	textregion.base = findtype;
	textregion.length = strlen(findtype);
	dns_result = dns_rdatatype_fromtext(&rdatatype, &textregion);
838
	if (dns_result != ISC_R_SUCCESS) {
839 840 841 842
		t_info("dns_rdatatype_fromtext %s failed %s\n",
				findtype,
				dns_result_totext(dns_result));
		dns_db_detach(&db);
843 844
		isc_hash_destroy();
		isc_entropy_detach(&ectx);
845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866
		isc_mem_destroy(&mctx);
		return(T_UNRESOLVED);
	}

	/*
	 * find a name we know is there
	 */

	cversionp = NULL;
	dns_fixedname_init(&dns_foundname);
	dns_rdataset_init(&rdataset);
	dns_db_currentversion(db, &cversionp);
	nodep = NULL;

	dns_result = dns_db_find(db,
			dns_fixedname_name(&dns_findname),
			cversionp,
			rdatatype,
			0,
			0,
			&nodep,
			dns_fixedname_name(&dns_foundname),
Bob Halley's avatar
Bob Halley committed
867
			&rdataset, NULL);
868

869
	if (dns_result != ISC_R_SUCCESS) {
870 871 872
		t_info("unable to find %s using current version\n", findname);
		dns_db_closeversion(db, &cversionp, ISC_FALSE);
		dns_db_detach(&db);
873 874
		isc_hash_destroy();
		isc_entropy_detach(&ectx);
875 876 877 878 879 880 881 882 883 884 885 886 887 888 889
		isc_mem_destroy(&mctx);
		return(T_UNRESOLVED);
	}

	/*
	 * create a new version
	 * delete the found rdataset in the new version
	 * attempt to find the rdataset again and expect the find to fail
	 * close/commit the new version
	 * attempt to find the rdataset in the current version and
	 * expect the find to succeed
	 */

	nversionp = NULL;
	dns_result = dns_db_newversion(db, &nversionp);
890
	if (dns_result != ISC_R_SUCCESS) {
891 892 893 894 895 896
		t_info("dns_db_newversion failed %s\n",
				dns_result_totext(dns_result));
		dns_db_detachnode(db, &nodep);
		dns_rdataset_disassociate(&rdataset);
		dns_db_closeversion(db, &cversionp, ISC_FALSE);
		dns_db_detach(&db);
897 898
		isc_hash_destroy();
		isc_entropy_detach(&ectx);
899 900 901 902
		isc_mem_destroy(&mctx);
		return(T_UNRESOLVED);
	}

903 904 905
	/*
	 * Delete the found rdataset in the new version.
	 */
906
	dns_result = dns_db_deleterdataset(db, nodep, nversionp, rdatatype, 0);
907
	if (dns_result != ISC_R_SUCCESS) {
908 909 910 911 912 913 914
		t_info("dns_db_deleterdataset failed %s\n",
				dns_result_totext(dns_result));
		dns_rdataset_disassociate(&rdataset);
		dns_db_detachnode(db, &nodep);
		dns_db_closeversion(db, &nversionp, ISC_FALSE);
		dns_db_closeversion(db, &cversionp, ISC_FALSE);
		dns_db_detach(&db);
915 916
		isc_hash_destroy();
		isc_entropy_detach(&ectx);
917 918 919 920
		isc_mem_destroy(&mctx);
		return(T_UNRESOLVED);
	}

921 922 923
	/*
	 * Don't need these now.
	 */
924 925 926 927
	dns_rdataset_disassociate(&rdataset);
	dns_db_detachnode(db, &nodep);
	nodep = NULL;

928 929 930
	/*
	 * Find the deleted rdataset and expect it to fail.
	 */
931 932 933 934 935 936 937 938
	dns_result = dns_db_find(db,
			dns_fixedname_name(&dns_findname),
			nversionp,
			rdatatype,
			0,
			0,
			&nodep,
			dns_fixedname_name(&dns_foundname),
Bob Halley's avatar
Bob Halley committed
939
			&rdataset, NULL);
940

941
	if ((dns_result != ISC_R_NOTFOUND) && (dns_result != DNS_R_NXDOMAIN)) {
942 943
		t_info("unexpectedly found %s using current version\n",
		       findname);
944 945 946
		dns_db_closeversion(db, &cversionp, ISC_FALSE);
		dns_db_closeversion(db, &nversionp, ISC_FALSE);
		dns_db_detach(&db);
947 948
		isc_hash_destroy();
		isc_entropy_detach(&ectx);
949 950 951 952
		isc_mem_destroy(&mctx);
		return(T_FAIL);
	}

953 954 955
	/*
	 * Close/commit the new version.
	 */
956 957
	dns_db_closeversion(db, &nversionp, ISC_TRUE);

958 959 960 961 962 963 964
	/*
	 * Find the deleted rdata in the current version.
	 */
	dns_result = dns_db_find(db, dns_fixedname_name(&dns_findname),
				 cversionp, rdatatype, DNS_DBFIND_GLUEOK,
				 0, &nodep, dns_fixedname_name(&dns_foundname),
				 &rdataset, NULL);
965

966 967 968
	/*
	 * And expect it to succeed.
	 */
969
	if (dns_result == ISC_R_SUCCESS) {
970
		result = T_PASS;
971
	} else {
972 973 974
		t_info("cound not find %s using current version\n", findname);
		dns_db_closeversion(db, &cversionp, ISC_FALSE);
		dns_db_detach(&db);
975 976
		isc_hash_destroy();
		isc_entropy_detach(&ectx);
977 978 979 980 981 982 983 984 985
		isc_mem_destroy(&mctx);
		result = T_FAIL;
	}

	dns_db_detachnode(db, &nodep);
	dns_rdataset_disassociate(&rdataset);

	dns_db_closeversion(db, &cversionp, ISC_FALSE);
	dns_db_detach(&db);
986 987
	isc_hash_destroy();
	isc_entropy_detach(&ectx);
988 989 990 991 992 993
	isc_mem_destroy(&mctx);

	return(result);
}

static void
994
t8(void) {
995 996
	int	result;

997
	t_assert("dns_db_currentversion", 8, T_REQUIRED, "%s", a8);
998 999
	result = t_eval("dns_db_currentversion_data",
			t_dns_db_currentversion, 7);
1000 1001 1002
	t_result(result);
}

David Lawrence's avatar
David Lawrence committed
1003
static const char *a9 =
1004 1005 1006 1007 1008 1009 1010 1011 1012
	"A call to dns_db_newversion() opens a new version for "
	"reading and writing.";

static int
t_dns_db_newversion(char **av) {

	char			*filename;
	char			*db_type;
	char			*origin;
1013
	char			*db_class;
1014
	char			*model;
1015 1016