update to 9.7.1-P2
[tridge/bind9.git] / bin / tests / db / t_db.c
1 /*
2  * Copyright (C) 2004, 2005, 2007, 2009  Internet Systems Consortium, Inc. ("ISC")
3  * Copyright (C) 1999-2001  Internet Software Consortium.
4  *
5  * Permission to use, copy, modify, and/or distribute this software for any
6  * purpose with or without fee is hereby granted, provided that the above
7  * copyright notice and this permission notice appear in all copies.
8  *
9  * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
10  * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
11  * AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
12  * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
13  * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
14  * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
15  * PERFORMANCE OF THIS SOFTWARE.
16  */
17
18 /* $Id: t_db.c,v 1.39 2009/09/01 00:22:25 jinmei Exp $ */
19
20 #include <config.h>
21
22 #include <ctype.h>
23 #include <stdlib.h>
24
25 #include <isc/entropy.h>
26 #include <isc/hash.h>
27 #include <isc/mem.h>
28 #include <isc/string.h>
29 #include <isc/util.h>
30
31 #include <dns/db.h>
32 #include <dns/fixedname.h>
33 #include <dns/rdata.h>
34 #include <dns/rdataclass.h>
35 #include <dns/rdatatype.h>
36 #include <dns/rdatalist.h>
37 #include <dns/rdataset.h>
38 #include <dns/result.h>
39
40 #include <tests/t_api.h>
41
42 static isc_result_t
43 t_create(const char *db_type, const char *origin, const char *class,
44          const char *model, isc_mem_t *mctx, dns_db_t **db)
45 {
46         int                     len;
47         isc_result_t            dns_result;
48         dns_dbtype_t            dbtype;
49         isc_textregion_t        region;
50         isc_buffer_t            origin_buffer;
51         dns_fixedname_t         dns_origin;
52         dns_rdataclass_t        rdataclass;
53
54
55         dbtype = dns_dbtype_zone;
56         if (strcasecmp(model, "cache") == 0)
57                 dbtype = dns_dbtype_cache;
58
59         dns_fixedname_init(&dns_origin);
60         len = strlen(origin);
61         isc_buffer_init(&origin_buffer, origin, len);
62         isc_buffer_add(&origin_buffer, len);
63         dns_result = dns_name_fromtext(dns_fixedname_name(&dns_origin),
64                                        &origin_buffer, NULL, 0, NULL);
65         if (dns_result != ISC_R_SUCCESS) {
66                 t_info("dns_name_fromtext failed %s\n",
67                        dns_result_totext(dns_result));
68                 return(dns_result);
69         }
70
71         DE_CONST(class, region.base);
72         region.length = strlen(class);
73         dns_result = dns_rdataclass_fromtext(&rdataclass, &region);
74         if (dns_result != ISC_R_SUCCESS) {
75                 t_info("dns_rdataclass_fromtext failed %s\n",
76                        dns_result_totext(dns_result));
77                 return(dns_result);
78         }
79
80         dns_result = dns_db_create(mctx, db_type,
81                                    dns_fixedname_name(&dns_origin),
82                                    dbtype, rdataclass, 0, NULL, db);
83         if (dns_result != ISC_R_SUCCESS)
84                 t_info("dns_db_create failed %s\n",
85                        dns_result_totext(dns_result));
86
87         return(dns_result);
88
89 }
90
91 static int
92 t_dns_db_load(char **av) {
93         char                    *filename;
94         char                    *db_type;
95         char                    *origin;
96         char                    *model;
97         char                    *class;
98         char                    *expected_load_result;
99         char                    *findname;
100         char                    *find_type;
101         char                    *expected_find_result;
102
103         int                     result;
104         int                     len;
105         dns_db_t                *db;
106         isc_result_t            dns_result;
107         isc_result_t            isc_result;
108         isc_mem_t               *mctx;
109         isc_entropy_t           *ectx;
110         dns_dbnode_t            *nodep;
111         isc_textregion_t        textregion;
112         isc_buffer_t            findname_buffer;
113         dns_fixedname_t         dns_findname;
114         dns_fixedname_t         dns_foundname;
115         dns_rdataset_t          rdataset;
116         dns_rdatatype_t         rdatatype;
117         dns_dbversion_t         *versionp;
118         isc_result_t            exp_load_result;
119         isc_result_t            exp_find_result;
120
121         result = T_UNRESOLVED;
122         db = NULL;
123         mctx = NULL;
124         ectx = NULL;
125         filename = T_ARG(0);
126         db_type = T_ARG(1);
127         origin = T_ARG(2);
128         model = T_ARG(3);
129         class = T_ARG(4);
130         expected_load_result = T_ARG(5);
131         findname = T_ARG(6);
132         find_type = T_ARG(7);
133         expected_find_result = T_ARG(8);
134
135         t_info("testing using file %s and name %s\n", filename, findname);
136
137         exp_load_result = t_dns_result_fromtext(expected_load_result);
138         exp_find_result = t_dns_result_fromtext(expected_find_result);
139
140         isc_result = isc_mem_create(0, 0, &mctx);
141         if (isc_result != ISC_R_SUCCESS) {
142                 t_info("isc_mem_create failed %s\n",
143                                 isc_result_totext(isc_result));
144                 return(T_UNRESOLVED);
145         }
146
147         isc_result = isc_entropy_create(mctx, &ectx);
148         if (isc_result != ISC_R_SUCCESS) {
149                 t_info("isc_entropy_create failed %s\n",
150                                 isc_result_totext(isc_result));
151                 isc_mem_destroy(&mctx);
152                 return(T_UNRESOLVED);
153         }
154
155         isc_result = isc_hash_create(mctx, ectx, DNS_NAME_MAXWIRE);
156         if (isc_result != ISC_R_SUCCESS) {
157                 t_info("isc_hash_create failed %s\n",
158                                 isc_result_totext(isc_result));
159                 isc_entropy_detach(&ectx);
160                 isc_mem_destroy(&mctx);
161                 return(T_UNRESOLVED);
162         }
163
164         dns_result = t_create(db_type, origin, class, model, mctx, &db);
165         if (dns_result != ISC_R_SUCCESS) {
166                 isc_hash_destroy();
167                 isc_entropy_detach(&ectx);
168                 isc_mem_destroy(&mctx);
169                 return(T_UNRESOLVED);
170         }
171
172         dns_result = dns_db_load(db, filename);
173         if (dns_result != exp_load_result) {
174                 t_info("dns_db_load returned %s, expected %s\n",
175                                 dns_result_totext(dns_result),
176                                 dns_result_totext(exp_load_result));
177                 dns_db_detach(&db);
178                 isc_hash_destroy();
179                 isc_entropy_detach(&ectx);
180                 isc_mem_destroy(&mctx);
181                 return(T_FAIL);
182         }
183         if (dns_result != ISC_R_SUCCESS) {
184                 result = T_PASS;
185                 goto cleanup_db;
186         }
187
188         dns_fixedname_init(&dns_findname);
189         len = strlen(findname);
190         isc_buffer_init(&findname_buffer, findname, len);
191         isc_buffer_add(&findname_buffer, len);
192         dns_result = dns_name_fromtext(dns_fixedname_name(&dns_findname),
193                                 &findname_buffer, NULL, 0, NULL);
194         if (dns_result != ISC_R_SUCCESS) {
195                 t_info("dns_name_fromtext failed %s\n",
196                         dns_result_totext(dns_result));
197                 dns_db_detach(&db);
198                 isc_hash_destroy();
199                 isc_entropy_detach(&ectx);
200                 isc_mem_destroy(&mctx);
201                 return(T_UNRESOLVED);
202         }
203
204         textregion.base = find_type;
205         textregion.length = strlen(find_type);
206         dns_result = dns_rdatatype_fromtext(&rdatatype, &textregion);
207         if (dns_result != ISC_R_SUCCESS) {
208                 t_info("dns_rdatatype_fromtext %s failed %s\n",
209                                 find_type,
210                                 dns_result_totext(dns_result));
211                 dns_db_detach(&db);
212                 isc_hash_destroy();
213                 isc_entropy_detach(&ectx);
214                 isc_mem_destroy(&mctx);
215                 return(T_UNRESOLVED);
216         }
217
218         versionp = NULL;
219         dns_fixedname_init(&dns_foundname);
220         dns_rdataset_init(&rdataset);
221         if (dns_db_iszone(db))
222                 dns_db_currentversion(db, &versionp);
223         nodep = NULL;
224
225         dns_result = dns_db_find(db,
226                         dns_fixedname_name(&dns_findname),
227                         versionp,
228                         rdatatype,
229                         DNS_DBFIND_GLUEOK,
230                         0,
231                         &nodep,
232                         dns_fixedname_name(&dns_foundname),
233                         &rdataset, NULL);
234
235         if (dns_result != exp_find_result) {
236                 t_info("dns_db_find returned %s, expected %s\n",
237                                 dns_result_totext(dns_result),
238                                 dns_result_totext(exp_find_result));
239                 result = T_FAIL;
240         } else {
241                 result = T_PASS;
242         }
243
244         if (dns_result != ISC_R_NOTFOUND) {
245                 dns_db_detachnode(db, &nodep);
246                 if (dns_rdataset_isassociated(&rdataset))
247                         dns_rdataset_disassociate(&rdataset);
248         }
249
250         if (dns_db_iszone(db))
251                 dns_db_closeversion(db, &versionp, ISC_FALSE);
252  cleanup_db:
253         dns_db_detach(&db);
254         isc_hash_destroy();
255         isc_entropy_detach(&ectx);
256         isc_mem_destroy(&mctx);
257         return(result);
258 }
259
260 static const char *a1 =
261         "A call to dns_db_load(db, filename) loads the contents of "
262         "the database in filename into db.";
263
264 static void
265 t1(void) {
266         int     result;
267
268         t_assert("dns_db_load", 1, T_REQUIRED, "%s", a1);
269         result = t_eval("dns_db_load_data", t_dns_db_load, 9);
270         t_result(result);
271 }
272
273
274 static const char *a2 =
275         "When the database db has cache semantics, a call to "
276         "dns_db_iscache(db) returns ISC_TRUE.";
277
278 static int
279 t_dns_db_zc_x(char *filename, char *db_type, char *origin, char *class,
280               dns_dbtype_t dbtype, isc_boolean_t(*cf)(dns_db_t *),
281               isc_boolean_t exp_result)
282 {
283         int                     result;
284         int                     len;
285         dns_db_t                *db;
286         isc_result_t            dns_result;
287         isc_result_t            isc_result;
288         isc_mem_t               *mctx;
289         isc_entropy_t           *ectx;
290         dns_rdataclass_t        rdataclass;
291         isc_textregion_t        textregion;
292         isc_buffer_t            origin_buffer;
293         dns_fixedname_t         dns_origin;
294
295         result = T_UNRESOLVED;
296
297         db = NULL;
298         mctx = NULL;
299         ectx = NULL;
300
301         t_info("testing using file %s\n", filename);
302
303         dns_fixedname_init(&dns_origin);
304         len = strlen(origin);
305         isc_buffer_init(&origin_buffer, origin, len);
306         isc_buffer_add(&origin_buffer, len);
307         dns_result = dns_name_fromtext(dns_fixedname_name(&dns_origin),
308                                        &origin_buffer, NULL, 0, NULL);
309         if (dns_result != ISC_R_SUCCESS) {
310                 t_info("dns_name_fromtext failed %s\n",
311                        dns_result_totext(dns_result));
312                 return(T_UNRESOLVED);
313         }
314
315         textregion.base = class;
316         textregion.length = strlen(class);
317         dns_result = dns_rdataclass_fromtext(&rdataclass, &textregion);
318         if (dns_result != ISC_R_SUCCESS) {
319                 t_info("dns_rdataclass_fromtext failed %s\n",
320                        dns_result_totext(dns_result));
321                 return(T_UNRESOLVED);
322         }
323
324         isc_result = isc_mem_create(0, 0, &mctx);
325         if (isc_result != ISC_R_SUCCESS) {
326                 t_info("isc_mem_create failed %s\n",
327                        isc_result_totext(isc_result));
328                 return(T_UNRESOLVED);
329         }
330
331         isc_result = isc_entropy_create(mctx, &ectx);
332         if (isc_result != ISC_R_SUCCESS) {
333                 t_info("isc_entropy_create failed %s\n",
334                                 isc_result_totext(isc_result));
335                 isc_mem_destroy(&mctx);
336                 return(T_UNRESOLVED);
337         }
338
339         isc_result = isc_hash_create(mctx, ectx, DNS_NAME_MAXWIRE);
340         if (isc_result != ISC_R_SUCCESS) {
341                 t_info("isc_hash_create failed %s\n",
342                                 isc_result_totext(isc_result));
343                 isc_entropy_detach(&ectx);
344                 isc_mem_destroy(&mctx);
345                 return(T_UNRESOLVED);
346         }
347
348         dns_result = dns_db_create(mctx, db_type,
349                                    dns_fixedname_name(&dns_origin),
350                                    dbtype, rdataclass, 0, NULL, &db);
351         if (dns_result != ISC_R_SUCCESS) {
352                 t_info("dns_db_create failed %s\n",
353                        dns_result_totext(dns_result));
354                 isc_hash_destroy();
355                 isc_entropy_detach(&ectx);
356                 isc_mem_destroy(&mctx);
357                 return(T_UNRESOLVED);
358         }
359
360         dns_result = dns_db_load(db, filename);
361         if (dns_result == ISC_R_SUCCESS) {
362                 if ((*cf)(db) == exp_result)
363                         result = T_PASS;
364                 else
365                         result = T_FAIL;
366         } else {
367                 t_info("dns_db_load failed %s\n",
368                        dns_result_totext(dns_result));
369                 result = T_FAIL;
370         }
371
372         dns_db_detach(&db);
373         isc_hash_destroy();
374         isc_entropy_detach(&ectx);
375         isc_mem_destroy(&mctx);
376         return(result);
377 }
378
379 static int
380 test_dns_db_zc_x(const char *filename, dns_dbtype_t dbtype,
381                  isc_boolean_t(*cf)(dns_db_t *), isc_boolean_t exp_result)
382 {
383
384         FILE            *fp;
385         char            *p;
386         int             line;
387         int             cnt;
388         int             result;
389         int             nfails;
390         int             nprobs;
391         char            *tokens[T_MAXTOKS];
392
393         nfails = 0;
394         nprobs = 0;
395
396         fp = fopen(filename, "r");
397         if (fp != NULL) {
398                 line = 0;
399                 while ((p = t_fgetbs(fp)) != NULL) {
400
401                         ++line;
402
403                         /*
404                          * Skip comment lines.
405                          */
406                         if ((isspace((unsigned char)*p)) || (*p == '#')) {
407                                 (void)free(p);
408                                 continue;
409                         }
410
411                         cnt = t_bustline(p, tokens);
412                         if (cnt == 4) {
413                                 result = t_dns_db_zc_x(tokens[0], /* file */
414                                                        tokens[1], /* type */
415                                                        tokens[2], /* origin */
416                                                        tokens[3], /* class */
417                                                        dbtype,     /* cache */
418                                                        cf,     /* check func */
419                                                        exp_result);/* expect */
420                                 if (result != T_PASS) {
421                                         if (result == T_FAIL)
422                                                 ++nfails;
423                                         else
424                                                 ++nprobs;
425                                 }
426                         } else {
427                                 t_info("bad format in %s at line %d\n",
428                                        filename, line);
429                                 ++nprobs;
430                         }
431
432                         (void)free(p);
433                 }
434                 (void)fclose(fp);
435         } else {
436                 t_info("Missing datafile %s\n", filename);
437                 ++nprobs;
438         }
439
440         result = T_UNRESOLVED;
441
442         if (nfails == 0 && nprobs == 0)
443                 result = T_PASS;
444         else if (nfails)
445                 result = T_FAIL;
446
447         return(result);
448 }
449
450 static void
451 t2(void) {
452         int     result;
453
454         t_assert("dns_db_iscache", 2, T_REQUIRED, "%s", a2);
455         result = test_dns_db_zc_x("dns_db_iscache_1_data",
456                                   dns_dbtype_cache, dns_db_iscache, ISC_TRUE);
457         t_result(result);
458 }
459
460
461 static const char *a3 =
462         "When the database db has zone semantics, a call to "
463         "dns_db_iscache(db) returns ISC_FALSE.";
464
465
466 static void
467 t3(void) {
468         int     result;
469
470         t_assert("dns_db_iscache", 3, T_REQUIRED, "%s", a3);
471         result = test_dns_db_zc_x("dns_db_iscache_2_data",
472                                   dns_dbtype_zone, dns_db_iscache, ISC_FALSE);
473         t_result(result);
474 }
475
476
477 static const char *a4 =
478         "When the database db has zone semantics, a call to "
479         "dns_db_iszone(db) returns ISC_TRUE.";
480
481
482 static void
483 t4(void) {
484         int     result;
485
486         t_assert("dns_db_iszone", 4, T_REQUIRED, "%s", a4);
487         result = test_dns_db_zc_x("dns_db_iszone_1_data",
488                                   dns_dbtype_zone, dns_db_iszone, ISC_TRUE);
489         t_result(result);
490 }
491
492
493 static const char *a5 =
494         "When the database db has cache semantics, a call to "
495         "dns_db_iszone(db) returns ISC_FALSE.";
496
497 static void
498 t5(void) {
499         int     result;
500
501         t_assert("dns_db_iszone", 5, T_REQUIRED, "%s", a5);
502         result = test_dns_db_zc_x("dns_db_iszone_2_data",
503                                   dns_dbtype_cache, dns_db_iszone, ISC_FALSE);
504         t_result(result);
505 }
506
507 static int
508 t_dns_db_origin(char **av) {
509
510         char                    *filename;
511         char                    *origin;
512
513         int                     result;
514         int                     len;
515         int                     order;
516         isc_result_t            dns_result;
517         isc_result_t            isc_result;
518         isc_mem_t               *mctx;
519         isc_entropy_t           *ectx;
520         dns_db_t                *db;
521         dns_fixedname_t         dns_origin;
522         dns_fixedname_t         dns_dborigin;
523         isc_buffer_t            origin_buffer;
524
525         db = NULL;
526         mctx = NULL;
527         ectx = NULL;
528
529         filename = T_ARG(0);
530         origin = T_ARG(1);
531
532         t_info("testing with database %s and origin %s\n",
533                         filename, origin);
534
535         isc_result = isc_mem_create(0, 0, &mctx);
536         if (isc_result != ISC_R_SUCCESS) {
537                 t_info("isc_mem_create failed %s\n",
538                         isc_result_totext(isc_result));
539                 return(T_UNRESOLVED);
540         }
541
542         isc_result = isc_entropy_create(mctx, &ectx);
543         if (isc_result != ISC_R_SUCCESS) {
544                 t_info("isc_entropy_create failed %s\n",
545                                 isc_result_totext(isc_result));
546                 isc_mem_destroy(&mctx);
547                 return(T_UNRESOLVED);
548         }
549
550         isc_result = isc_hash_create(mctx, ectx, DNS_NAME_MAXWIRE);
551         if (isc_result != ISC_R_SUCCESS) {
552                 t_info("isc_hash_create failed %s\n",
553                                 isc_result_totext(isc_result));
554                 isc_entropy_detach(&ectx);
555                 isc_mem_destroy(&mctx);
556                 return(T_UNRESOLVED);
557         }
558
559         dns_result = t_create("rbt", origin, "in", "isc_true", mctx, &db);
560         if (dns_result != ISC_R_SUCCESS) {
561                 t_info("t_create failed %s\n",
562                         dns_result_totext(dns_result));
563                 isc_hash_destroy();
564                 isc_entropy_detach(&ectx);
565                 isc_mem_destroy(&mctx);
566                 return(T_UNRESOLVED);
567         }
568         dns_fixedname_init(&dns_origin);
569         dns_fixedname_init(&dns_dborigin);
570
571         len = strlen(origin);
572         isc_buffer_init(&origin_buffer, origin, len);
573         isc_buffer_add(&origin_buffer, len);
574
575         dns_result = dns_db_load(db, filename);
576         if (dns_result != ISC_R_SUCCESS) {
577                 t_info("dns_db_load failed %s\n",
578                                 dns_result_totext(dns_result));
579                 dns_db_detach(&db);
580                 isc_hash_destroy();
581                 isc_entropy_detach(&ectx);
582                 isc_mem_destroy(&mctx);
583                 return(T_UNRESOLVED);
584         }
585
586         dns_result = dns_name_fromtext(dns_fixedname_name(&dns_origin),
587                                 &origin_buffer, NULL, 0, NULL);
588         if (dns_result != ISC_R_SUCCESS) {
589                 t_info("dns_name_fromtext failed %s\n",
590                                 dns_result_totext(dns_result));
591                 dns_db_detach(&db);
592                 isc_hash_destroy();
593                 isc_entropy_detach(&ectx);
594                 isc_mem_destroy(&mctx);
595                 return(T_UNRESOLVED);
596         }
597         order = dns_name_compare(dns_fixedname_name(&dns_origin),
598                                  dns_db_origin(db));
599         if (order == 0) {
600                 result = T_PASS;
601         } else {
602                 t_info("dns_name_compare returned %d\n", order);
603                 result = T_FAIL;
604         }
605
606         dns_db_detach(&db);
607         isc_hash_destroy();
608         isc_entropy_detach(&ectx);
609         isc_mem_destroy(&mctx);
610         return(result);
611
612 }
613
614 static const char *a6 =
615         "A call to dns_db_origin(db) returns the origin of the database.";
616
617 static void
618 t6(void) {
619         int     result;
620
621         t_assert("dns_db_origin", 6, T_REQUIRED, "%s", a6);
622         result = t_eval("dns_db_origin_data", t_dns_db_origin, 2);
623         t_result(result);
624 }
625
626
627 static const char *a7 =
628         "A call to dns_db_class(db) returns the class of the database.";
629
630
631 #define CLASSBUFLEN     256
632
633 static int
634 t_dns_db_class(char **av) {
635
636         char                    *filename;
637         char                    *class;
638
639         int                     result;
640         isc_result_t            dns_result;
641         isc_result_t            isc_result;
642         isc_mem_t               *mctx;
643         isc_entropy_t           *ectx;
644         dns_db_t                *db;
645         dns_rdataclass_t        rdataclass;
646         dns_rdataclass_t        db_rdataclass;
647         isc_textregion_t        textregion;
648
649         filename = T_ARG(0);
650         class = T_ARG(1);
651         db = NULL;
652         mctx = NULL;
653         ectx = NULL;
654
655         t_info("testing with database %s and class %s\n",
656                         filename, class);
657
658         textregion.base = class;
659         textregion.length = strlen(class);
660         dns_result = dns_rdataclass_fromtext(&rdataclass, &textregion);
661         if (dns_result != ISC_R_SUCCESS) {
662                 t_info("dns_rdataclass_fromtext failed %s\n",
663                                 dns_result_totext(dns_result));
664                 return(T_UNRESOLVED);
665         }
666
667         isc_result = isc_mem_create(0, 0, &mctx);
668         if (isc_result != ISC_R_SUCCESS) {
669                 t_info("isc_mem_create failed %s\n",
670                         isc_result_totext(isc_result));
671                 return(T_UNRESOLVED);
672         }
673
674         isc_result = isc_entropy_create(mctx, &ectx);
675         if (isc_result != ISC_R_SUCCESS) {
676                 t_info("isc_entropy_create failed %s\n",
677                                 isc_result_totext(isc_result));
678                 isc_mem_destroy(&mctx);
679                 return(T_UNRESOLVED);
680         }
681
682         isc_result = isc_hash_create(mctx, ectx, DNS_NAME_MAXWIRE);
683         if (isc_result != ISC_R_SUCCESS) {
684                 t_info("isc_hash_create failed %s\n",
685                                 isc_result_totext(isc_result));
686                 isc_entropy_detach(&ectx);
687                 isc_mem_destroy(&mctx);
688                 return(T_UNRESOLVED);
689         }
690
691         dns_result = t_create("rbt", ".", class, "isc_true", mctx, &db);
692         if (dns_result != ISC_R_SUCCESS) {
693                 t_info("t_create failed %s\n",
694                         dns_result_totext(dns_result));
695                 isc_hash_destroy();
696                 isc_entropy_detach(&ectx);
697                 isc_mem_destroy(&mctx);
698                 return(T_UNRESOLVED);
699         }
700
701         dns_result = dns_db_load(db, filename);
702         if (dns_result != ISC_R_SUCCESS) {
703                 t_info("dns_db_load failed %s\n",
704                                 dns_result_totext(dns_result));
705                 dns_db_detach(&db);
706                 isc_hash_destroy();
707                 isc_entropy_detach(&ectx);
708                 isc_mem_destroy(&mctx);
709                 return(T_UNRESOLVED);
710         }
711
712         db_rdataclass = dns_db_class(db);
713         if (db_rdataclass == rdataclass)
714                 result = T_PASS;
715         else {
716                 char classbuf[DNS_RDATACLASS_FORMATSIZE];
717                 dns_rdataclass_format(db_rdataclass,
718                                       classbuf, sizeof(classbuf));
719                 t_info("dns_db_class returned %s, expected %s\n",
720                        classbuf, class);
721                 result = T_FAIL;
722         }
723
724         dns_db_detach(&db);
725         isc_hash_destroy();
726         isc_entropy_detach(&ectx);
727         isc_mem_destroy(&mctx);
728         return(result);
729
730 }
731 static void
732 t7(void) {
733         int     result;
734
735         t_assert("dns_db_class", 7, T_REQUIRED, "%s", a7);
736         result = t_eval("dns_db_class_data", t_dns_db_class, 2);
737         t_result(result);
738 }
739
740
741 static const char *a8 =
742         "A call to dns_db_currentversion() opens the current "
743         "version for reading.";
744
745 static int
746 t_dns_db_currentversion(char **av) {
747         char                    *filename;
748         char                    *db_type;
749         char                    *origin;
750         char                    *class;
751         char                    *model;
752         char                    *findname;
753         char                    *findtype;
754
755         int                     result;
756         int                     len;
757         dns_db_t                *db;
758         isc_result_t            dns_result;
759         isc_result_t            isc_result;
760         isc_mem_t               *mctx;
761         isc_entropy_t           *ectx;
762         dns_dbnode_t            *nodep;
763         isc_textregion_t        textregion;
764         isc_buffer_t            findname_buffer;
765         dns_fixedname_t         dns_findname;
766         dns_fixedname_t         dns_foundname;
767         dns_rdataset_t          rdataset;
768         dns_rdatatype_t         rdatatype;
769         dns_dbversion_t         *cversionp;
770         dns_dbversion_t         *nversionp;
771
772         result = T_UNRESOLVED;
773
774         filename = T_ARG(0);
775         db_type = T_ARG(1);
776         origin = T_ARG(2);
777         class = T_ARG(3);
778         model = T_ARG(4);
779         findname = T_ARG(5);
780         findtype = T_ARG(6);
781         db = NULL;
782         mctx = NULL;
783         ectx = NULL;
784
785         t_info("testing using file %s and name %s\n", filename, findname);
786
787         isc_result = isc_mem_create(0, 0, &mctx);
788         if (isc_result != ISC_R_SUCCESS) {
789                 t_info("isc_mem_create failed %s\n",
790                                 isc_result_totext(isc_result));
791                 return(T_UNRESOLVED);
792         }
793
794         isc_result = isc_entropy_create(mctx, &ectx);
795         if (isc_result != ISC_R_SUCCESS) {
796                 t_info("isc_entropy_create failed %s\n",
797                                 isc_result_totext(isc_result));
798                 isc_mem_destroy(&mctx);
799                 return(T_UNRESOLVED);
800         }
801
802         isc_result = isc_hash_create(mctx, ectx, DNS_NAME_MAXWIRE);
803         if (isc_result != ISC_R_SUCCESS) {
804                 t_info("isc_hash_create failed %s\n",
805                                 isc_result_totext(isc_result));
806                 isc_entropy_detach(&ectx);
807                 isc_mem_destroy(&mctx);
808                 return(T_UNRESOLVED);
809         }
810
811         dns_result = t_create(db_type, origin, class, model, mctx, &db);
812         if (dns_result != ISC_R_SUCCESS) {
813                 isc_hash_destroy();
814                 isc_entropy_detach(&ectx);
815                 isc_mem_destroy(&mctx);
816                 return(T_UNRESOLVED);
817         }
818
819         dns_result = dns_db_load(db, filename);
820         if (dns_result != ISC_R_SUCCESS) {
821                 t_info("dns_db_load returned %s\n",
822                                 dns_result_totext(dns_result));
823                 dns_db_detach(&db);
824                 isc_hash_destroy();
825                 isc_entropy_detach(&ectx);
826                 isc_mem_destroy(&mctx);
827                 return(T_UNRESOLVED);
828         }
829
830         dns_fixedname_init(&dns_findname);
831         len = strlen(findname);
832         isc_buffer_init(&findname_buffer, findname, len);
833         isc_buffer_add(&findname_buffer, len);
834         dns_result = dns_name_fromtext(dns_fixedname_name(&dns_findname),
835                                 &findname_buffer, NULL, 0, NULL);
836         if (dns_result != ISC_R_SUCCESS) {
837                 t_info("dns_name_fromtext failed %s\n",
838                         dns_result_totext(dns_result));
839                 dns_db_detach(&db);
840                 isc_hash_destroy();
841                 isc_entropy_detach(&ectx);
842                 isc_mem_destroy(&mctx);
843                 return(T_UNRESOLVED);
844         }
845
846         textregion.base = findtype;
847         textregion.length = strlen(findtype);
848         dns_result = dns_rdatatype_fromtext(&rdatatype, &textregion);
849         if (dns_result != ISC_R_SUCCESS) {
850                 t_info("dns_rdatatype_fromtext %s failed %s\n",
851                                 findtype,
852                                 dns_result_totext(dns_result));
853                 dns_db_detach(&db);
854                 isc_hash_destroy();
855                 isc_entropy_detach(&ectx);
856                 isc_mem_destroy(&mctx);
857                 return(T_UNRESOLVED);
858         }
859
860         /*
861          * find a name we know is there
862          */
863
864         cversionp = NULL;
865         dns_fixedname_init(&dns_foundname);
866         dns_rdataset_init(&rdataset);
867         dns_db_currentversion(db, &cversionp);
868         nodep = NULL;
869
870         dns_result = dns_db_find(db,
871                         dns_fixedname_name(&dns_findname),
872                         cversionp,
873                         rdatatype,
874                         0,
875                         0,
876                         &nodep,
877                         dns_fixedname_name(&dns_foundname),
878                         &rdataset, NULL);
879
880         if (dns_result != ISC_R_SUCCESS) {
881                 t_info("unable to find %s using current version\n", findname);
882                 dns_db_closeversion(db, &cversionp, ISC_FALSE);
883                 dns_db_detach(&db);
884                 isc_hash_destroy();
885                 isc_entropy_detach(&ectx);
886                 isc_mem_destroy(&mctx);
887                 return(T_UNRESOLVED);
888         }
889
890         /*
891          * create a new version
892          * delete the found rdataset in the new version
893          * attempt to find the rdataset again and expect the find to fail
894          * close/commit the new version
895          * attempt to find the rdataset in the current version and
896          * expect the find to succeed
897          */
898
899         nversionp = NULL;
900         dns_result = dns_db_newversion(db, &nversionp);
901         if (dns_result != ISC_R_SUCCESS) {
902                 t_info("dns_db_newversion failed %s\n",
903                                 dns_result_totext(dns_result));
904                 dns_db_detachnode(db, &nodep);
905                 dns_rdataset_disassociate(&rdataset);
906                 dns_db_closeversion(db, &cversionp, ISC_FALSE);
907                 dns_db_detach(&db);
908                 isc_hash_destroy();
909                 isc_entropy_detach(&ectx);
910                 isc_mem_destroy(&mctx);
911                 return(T_UNRESOLVED);
912         }
913
914         /*
915          * Delete the found rdataset in the new version.
916          */
917         dns_result = dns_db_deleterdataset(db, nodep, nversionp, rdatatype, 0);
918         if (dns_result != ISC_R_SUCCESS) {
919                 t_info("dns_db_deleterdataset failed %s\n",
920                                 dns_result_totext(dns_result));
921                 dns_rdataset_disassociate(&rdataset);
922                 dns_db_detachnode(db, &nodep);
923                 dns_db_closeversion(db, &nversionp, ISC_FALSE);
924                 dns_db_closeversion(db, &cversionp, ISC_FALSE);
925                 dns_db_detach(&db);
926                 isc_hash_destroy();
927                 isc_entropy_detach(&ectx);
928                 isc_mem_destroy(&mctx);
929                 return(T_UNRESOLVED);
930         }
931
932         /*
933          * Don't need these now.
934          */
935         dns_rdataset_disassociate(&rdataset);
936         dns_db_detachnode(db, &nodep);
937         nodep = NULL;
938
939         /*
940          * Find the deleted rdataset and expect it to fail.
941          */
942         dns_result = dns_db_find(db,
943                         dns_fixedname_name(&dns_findname),
944                         nversionp,
945                         rdatatype,
946                         0,
947                         0,
948                         &nodep,
949                         dns_fixedname_name(&dns_foundname),
950                         &rdataset, NULL);
951
952         if ((dns_result != ISC_R_NOTFOUND) && (dns_result != DNS_R_NXDOMAIN)) {
953                 t_info("unexpectedly found %s using current version\n",
954                        findname);
955                 dns_db_closeversion(db, &cversionp, ISC_FALSE);
956                 dns_db_closeversion(db, &nversionp, ISC_FALSE);
957                 dns_db_detach(&db);
958                 isc_hash_destroy();
959                 isc_entropy_detach(&ectx);
960                 isc_mem_destroy(&mctx);
961                 return(T_FAIL);
962         }
963
964         /*
965          * Close/commit the new version.
966          */
967         dns_db_closeversion(db, &nversionp, ISC_TRUE);
968
969         /*
970          * Find the deleted rdata in the current version.
971          */
972         dns_result = dns_db_find(db, dns_fixedname_name(&dns_findname),
973                                  cversionp, rdatatype, DNS_DBFIND_GLUEOK,
974                                  0, &nodep, dns_fixedname_name(&dns_foundname),
975                                  &rdataset, NULL);
976
977         /*
978          * And expect it to succeed.
979          */
980         if (dns_result == ISC_R_SUCCESS) {
981                 result = T_PASS;
982         } else {
983                 t_info("cound not find %s using current version\n", findname);
984                 dns_db_closeversion(db, &cversionp, ISC_FALSE);
985                 dns_db_detach(&db);
986                 isc_hash_destroy();
987                 isc_entropy_detach(&ectx);
988                 isc_mem_destroy(&mctx);
989                 result = T_FAIL;
990         }
991
992         dns_db_detachnode(db, &nodep);
993         dns_rdataset_disassociate(&rdataset);
994
995         dns_db_closeversion(db, &cversionp, ISC_FALSE);
996         dns_db_detach(&db);
997         isc_hash_destroy();
998         isc_entropy_detach(&ectx);
999         isc_mem_destroy(&mctx);
1000
1001         return(result);
1002 }
1003
1004 static void
1005 t8(void) {
1006         int     result;
1007
1008         t_assert("dns_db_currentversion", 8, T_REQUIRED, "%s", a8);
1009         result = t_eval("dns_db_currentversion_data",
1010                         t_dns_db_currentversion, 7);
1011         t_result(result);
1012 }
1013
1014 static const char *a9 =
1015         "A call to dns_db_newversion() opens a new version for "
1016         "reading and writing.";
1017
1018 static int
1019 t_dns_db_newversion(char **av) {
1020
1021         char                    *filename;
1022         char                    *db_type;
1023         char                    *origin;
1024         char                    *class;
1025         char                    *model;
1026         char                    *newname;
1027         char                    *newtype;
1028
1029         int                     result;
1030         int                     len;
1031         int                     rval;
1032         dns_db_t                *db;
1033         isc_result_t            dns_result;
1034         isc_result_t            isc_result;
1035         isc_mem_t               *mctx;
1036         isc_entropy_t           *ectx;
1037         dns_dbnode_t            *nodep;
1038         dns_dbnode_t            *found_nodep;
1039         isc_textregion_t        textregion;
1040         isc_buffer_t            newname_buffer;
1041         dns_fixedname_t         dns_newname;
1042         dns_fixedname_t         dns_foundname;
1043         dns_rdata_t             added_rdata = DNS_RDATA_INIT;
1044         const char *            added_rdata_data;
1045         dns_rdataset_t          added_rdataset;
1046         dns_rdata_t             found_rdata = DNS_RDATA_INIT;
1047         dns_rdataset_t          found_rdataset;
1048         dns_rdatatype_t         rdatatype;
1049         dns_rdataclass_t        rdataclass;
1050         dns_dbversion_t         *nversionp;
1051         dns_rdatalist_t         rdatalist;
1052
1053         result = T_UNRESOLVED;
1054
1055         filename = T_ARG(0);
1056         db_type = T_ARG(1);
1057         origin = T_ARG(2);
1058         class = T_ARG(3);
1059         model = T_ARG(4);
1060         newname = T_ARG(5);
1061         newtype = T_ARG(6);
1062         db = NULL;
1063         mctx = NULL;
1064         ectx = NULL;
1065
1066         /*
1067          * Open a new version, add some data, commit it,
1068          * close it, open a new version, and check that changes
1069          * are present.
1070          */
1071
1072         t_info("testing using file %s and name %s\n", filename, newname);
1073
1074         isc_result = isc_mem_create(0, 0, &mctx);
1075         if (isc_result != ISC_R_SUCCESS) {
1076                 t_info("isc_mem_create failed %s\n",
1077                                 isc_result_totext(isc_result));
1078                 return(T_UNRESOLVED);
1079         }
1080
1081         isc_result = isc_entropy_create(mctx, &ectx);
1082         if (isc_result != ISC_R_SUCCESS) {
1083                 t_info("isc_entropy_create failed %s\n",
1084                                 isc_result_totext(isc_result));
1085                 isc_mem_destroy(&mctx);
1086                 return(T_UNRESOLVED);
1087         }
1088
1089         isc_result = isc_hash_create(mctx, ectx, DNS_NAME_MAXWIRE);
1090         if (isc_result != ISC_R_SUCCESS) {
1091                 t_info("isc_hash_create failed %s\n",
1092                                 isc_result_totext(isc_result));
1093                 isc_entropy_detach(&ectx);
1094                 isc_mem_destroy(&mctx);
1095                 return(T_UNRESOLVED);
1096         }
1097
1098         dns_result = t_create(db_type, origin, class, model, mctx, &db);
1099         if (dns_result != ISC_R_SUCCESS) {
1100                 isc_hash_destroy();
1101                 isc_entropy_detach(&ectx);
1102                 isc_mem_destroy(&mctx);
1103                 return(T_UNRESOLVED);
1104         }
1105
1106         dns_result = dns_db_load(db, filename);
1107         if (dns_result != ISC_R_SUCCESS) {
1108                 t_info("dns_db_load returned %s\n",
1109                                 dns_result_totext(dns_result));
1110                 dns_db_detach(&db);
1111                 isc_hash_destroy();
1112                 isc_entropy_detach(&ectx);
1113                 isc_mem_destroy(&mctx);
1114                 return(T_UNRESOLVED);
1115         }
1116
1117         /*
1118          * Add a new name.
1119          */
1120
1121         dns_fixedname_init(&dns_newname);
1122         len = strlen(newname);
1123         isc_buffer_init(&newname_buffer, newname, len);
1124         isc_buffer_add(&newname_buffer, len);
1125         dns_result = dns_name_fromtext(dns_fixedname_name(&dns_newname),
1126                                 &newname_buffer, NULL, 0, NULL);
1127         if (dns_result != ISC_R_SUCCESS) {
1128                 t_info("dns_name_fromtext failed %s\n",
1129                         dns_result_totext(dns_result));
1130                 dns_db_detach(&db);
1131                 isc_hash_destroy();
1132                 isc_entropy_detach(&ectx);
1133                 isc_mem_destroy(&mctx);
1134                 return(T_UNRESOLVED);
1135         }
1136
1137         nodep = NULL;
1138         dns_result = dns_db_findnode(db, dns_fixedname_name(&dns_newname),
1139                                 ISC_TRUE, &nodep);
1140         if (dns_result != ISC_R_SUCCESS) {
1141                 t_info("dns_db_findnode failed %s\n",
1142                                 dns_result_totext(dns_result));
1143                 dns_db_detach(&db);
1144                 isc_hash_destroy();
1145                 isc_entropy_detach(&ectx);
1146                 isc_mem_destroy(&mctx);
1147                 return(T_UNRESOLVED);
1148         }
1149
1150         /*
1151          * Open a new version and associate some rdata with the new name.
1152          */
1153
1154         textregion.base = newtype;
1155         textregion.length = strlen(newtype);
1156         dns_result = dns_rdatatype_fromtext(&rdatatype, &textregion);
1157
1158         if (dns_result != ISC_R_SUCCESS) {
1159                 t_info("dns_rdatatype_fromtext %s failed %s\n",
1160                                 newtype,
1161                                 dns_result_totext(dns_result));
1162                 dns_db_detachnode(db, &nodep);
1163                 dns_db_detach(&db);
1164                 isc_hash_destroy();
1165                 isc_entropy_detach(&ectx);
1166                 isc_mem_destroy(&mctx);
1167                 return(T_UNRESOLVED);
1168         }
1169
1170         textregion.base = class;
1171         textregion.length = strlen(class);
1172         dns_result = dns_rdataclass_fromtext(&rdataclass, &textregion);
1173         if (dns_result != ISC_R_SUCCESS) {
1174                 t_info("dns_rdataclass_fromtext failed %s\n",
1175                                 dns_result_totext(dns_result));
1176                 dns_db_detachnode(db, &nodep);
1177                 dns_db_detach(&db);
1178                 isc_hash_destroy();
1179                 isc_entropy_detach(&ectx);
1180                 isc_mem_destroy(&mctx);
1181                 return(T_UNRESOLVED);
1182         }
1183
1184         dns_rdata_init(&added_rdata);
1185         added_rdata_data = "\x10\x00\x00\x01";
1186         DE_CONST(added_rdata_data, added_rdata.data);
1187         added_rdata.length = 4;
1188         added_rdata.rdclass = rdataclass;
1189         added_rdata.type = rdatatype;
1190
1191         dns_rdataset_init(&added_rdataset);
1192         rdatalist.type = rdatatype;
1193         rdatalist.covers = 0;
1194         rdatalist.rdclass = rdataclass;
1195         rdatalist.ttl = 0;
1196         ISC_LIST_INIT(rdatalist.rdata);
1197         ISC_LIST_APPEND(rdatalist.rdata, &added_rdata, link);
1198
1199         dns_result = dns_rdatalist_tordataset(&rdatalist, &added_rdataset);
1200         if (dns_result != ISC_R_SUCCESS) {
1201                 t_info("dns_rdatalist_tordataset failed %s\n",
1202                                 dns_result_totext(dns_result));
1203                 dns_db_detachnode(db, &nodep);
1204                 dns_db_detach(&db);
1205                 isc_hash_destroy();
1206                 isc_entropy_detach(&ectx);
1207                 isc_mem_destroy(&mctx);
1208                 return(T_UNRESOLVED);
1209         }
1210
1211         nversionp = NULL;
1212         dns_result = dns_db_newversion(db, &nversionp);
1213         if (dns_result != ISC_R_SUCCESS) {
1214                 t_info("dns_db_newversion failed %s\n",
1215                                 dns_result_totext(dns_result));
1216                 dns_db_detachnode(db, &nodep);
1217                 dns_db_detach(&db);
1218                 isc_hash_destroy();
1219                 isc_entropy_detach(&ectx);
1220                 isc_mem_destroy(&mctx);
1221                 return(T_UNRESOLVED);
1222         }
1223
1224         dns_result = dns_db_addrdataset(db, nodep, nversionp, 0,
1225                                 &added_rdataset, 0, NULL);
1226         if (dns_result != ISC_R_SUCCESS) {
1227                 t_info("dns_db_addrdataset failed %s\n",
1228                                 dns_result_totext(dns_result));
1229                 dns_db_closeversion(db, &nversionp, ISC_FALSE);
1230                 dns_db_detachnode(db, &nodep);
1231                 dns_db_detach(&db);
1232                 isc_hash_destroy();
1233                 isc_entropy_detach(&ectx);
1234                 isc_mem_destroy(&mctx);
1235                 return(T_UNRESOLVED);
1236         }
1237
1238         /*
1239          * Close and commit the version.
1240          */
1241         dns_db_closeversion(db, &nversionp, ISC_TRUE);
1242         dns_db_detachnode(db, &nodep);
1243         if (dns_rdataset_isassociated(&added_rdataset))
1244                 dns_rdataset_disassociate(&added_rdataset);
1245         nodep = NULL;
1246
1247         /*
1248          * Open a new version and find the data we added.
1249          */
1250         dns_fixedname_init(&dns_foundname);
1251         dns_rdataset_init(&found_rdataset);
1252         nversionp = NULL;
1253         found_nodep = NULL;
1254         dns_db_newversion(db, &nversionp);
1255
1256         /*
1257          * Find the recently added name and rdata.
1258          */
1259         dns_result = dns_db_find(db, dns_fixedname_name(&dns_newname),
1260                                  nversionp, rdatatype, 0, 0, &found_nodep,
1261                                  dns_fixedname_name(&dns_foundname),
1262                                  &found_rdataset, NULL);
1263
1264         if (dns_result != ISC_R_SUCCESS) {
1265                 /* XXXWPK - NXRRSET ???  reference counts ??? */
1266                 t_info("dns_db_find failed %s\n",
1267                        dns_result_totext(dns_result));
1268                 dns_db_closeversion(db, &nversionp, ISC_FALSE);
1269                 dns_db_detachnode(db, &found_nodep);
1270                 if (dns_rdataset_isassociated(&found_rdataset))
1271                         dns_rdataset_disassociate(&found_rdataset);
1272                 dns_db_detach(&db);
1273                 isc_hash_destroy();
1274                 isc_entropy_detach(&ectx);
1275                 isc_mem_destroy(&mctx);
1276                 return(T_FAIL);
1277         }
1278
1279         dns_result = dns_rdataset_first(&found_rdataset);
1280         if (dns_result != ISC_R_SUCCESS) {
1281                 t_info("dns_rdataset_first failed %s\n",
1282                                 dns_result_totext(dns_result));
1283                 dns_db_detachnode(db, &nodep);
1284                 if (dns_rdataset_isassociated(&found_rdataset))
1285                         dns_rdataset_disassociate(&found_rdataset);
1286                 dns_db_closeversion(db, &nversionp, ISC_FALSE);
1287                 dns_db_detach(&db);
1288                 isc_hash_destroy();
1289                 isc_entropy_detach(&ectx);
1290                 isc_mem_destroy(&mctx);
1291                 return(T_FAIL);
1292         }
1293
1294         /*
1295          * Now make sure its what we expect.
1296          */
1297         dns_rdata_init(&found_rdata);
1298         dns_rdataset_current(&found_rdataset, &found_rdata);
1299         rval = dns_rdata_compare(&added_rdata, &found_rdata);
1300         if (rval == 0) {
1301                 result = T_PASS;
1302         } else {
1303                 t_info("dns_rdata_compare returned %d\n", rval);
1304                 result = T_FAIL;
1305         }
1306
1307         /*
1308          * Don't need these now.
1309          */
1310         dns_db_closeversion(db, &nversionp, ISC_FALSE);
1311         if (dns_rdataset_isassociated(&found_rdataset))
1312                 dns_rdataset_disassociate(&found_rdataset);
1313         dns_db_detachnode(db, &found_nodep);
1314         dns_db_detach(&db);
1315         isc_hash_destroy();
1316         isc_entropy_detach(&ectx);
1317         isc_mem_destroy(&mctx);
1318
1319         return(result);
1320 }
1321
1322 static void
1323 t9(void) {
1324         int     result;
1325
1326         t_assert("dns_db_newversion", 9, T_REQUIRED, "%s", a9);
1327         result = t_eval("dns_db_newversion_data", t_dns_db_newversion, 7);
1328         t_result(result);
1329 }
1330
1331 static const char *a10 =
1332         "When versionp points to a read-write version and commit is "
1333         "ISC_TRUE, a call to dns_db_closeversion(db, versionp, commit) "
1334         "causes all changes made in the version to take effect, "
1335         "and returns ISC_R_SUCCESS.";
1336
1337 static int
1338 t_dns_db_closeversion_1(char **av) {
1339         char                    *filename;
1340         char                    *db_type;
1341         char                    *origin;
1342         char                    *class;
1343         char                    *model;
1344         char                    *new_name;
1345         char                    *new_type;
1346         char                    *existing_name;
1347         char                    *existing_type;
1348
1349         int                     result;
1350         int                     len;
1351         int                     rval;
1352         int                     nfails;
1353         dns_db_t                *db;
1354         isc_result_t            dns_result;
1355         isc_result_t            isc_result;
1356         isc_mem_t               *mctx;
1357         isc_entropy_t           *ectx;
1358         dns_dbnode_t            *nodep;
1359         isc_textregion_t        textregion;
1360         isc_buffer_t            name_buffer;
1361         dns_fixedname_t         dns_newname;
1362         dns_fixedname_t         dns_foundname;
1363         dns_fixedname_t         dns_existingname;
1364         dns_rdata_t             added_rdata = DNS_RDATA_INIT;
1365         const char *            added_rdata_data;
1366         dns_rdataset_t          added_rdataset;
1367         dns_rdata_t             found_rdata = DNS_RDATA_INIT;
1368         dns_rdataset_t          found_rdataset;
1369         dns_rdatatype_t         new_rdatatype;
1370         dns_rdatatype_t         existing_rdatatype;
1371         dns_rdataclass_t        rdataclass;
1372         dns_dbversion_t         *nversionp;
1373         dns_dbversion_t         *cversionp;
1374         dns_rdatalist_t         rdatalist;
1375
1376         filename = T_ARG(0);
1377         db_type = T_ARG(1);
1378         origin = T_ARG(2);
1379         class = T_ARG(3);
1380         model = T_ARG(4);
1381         new_name = T_ARG(5);
1382         new_type = T_ARG(6);
1383         existing_name = T_ARG(7);
1384         existing_type = T_ARG(8);
1385
1386         nfails = 0;
1387         result = T_UNRESOLVED;
1388         db = NULL;
1389         mctx = NULL;
1390         ectx = NULL;
1391
1392         /*
1393          * Open a new version, add some data,
1394          * remove some data, close with commit, open the current
1395          * version and check that changes are present.
1396          */
1397
1398         t_info("testing using file %s and name %s\n", filename, new_name);
1399
1400         isc_result = isc_mem_create(0, 0, &mctx);
1401         if (isc_result != ISC_R_SUCCESS) {
1402                 t_info("isc_mem_create failed %s\n",
1403                                 isc_result_totext(isc_result));
1404                 return(T_UNRESOLVED);
1405         }
1406
1407         isc_result = isc_entropy_create(mctx, &ectx);
1408         if (isc_result != ISC_R_SUCCESS) {
1409                 t_info("isc_entropy_create failed %s\n",
1410                                 isc_result_totext(isc_result));
1411                 isc_mem_destroy(&mctx);
1412                 return(T_UNRESOLVED);
1413         }
1414
1415         isc_result = isc_hash_create(mctx, ectx, DNS_NAME_MAXWIRE);
1416         if (isc_result != ISC_R_SUCCESS) {
1417                 t_info("isc_hash_create failed %s\n",
1418                                 isc_result_totext(isc_result));
1419                 isc_entropy_detach(&ectx);
1420                 isc_mem_destroy(&mctx);
1421                 return(T_UNRESOLVED);
1422         }
1423
1424         dns_result = t_create(db_type, origin, class, model, mctx, &db);
1425         if (dns_result != ISC_R_SUCCESS) {
1426                 isc_hash_destroy();
1427                 isc_entropy_detach(&ectx);
1428                 isc_mem_destroy(&mctx);
1429                 return(T_UNRESOLVED);
1430         }
1431
1432         dns_result = dns_db_load(db, filename);
1433         if (dns_result != ISC_R_SUCCESS) {
1434                 t_info("dns_db_load returned %s\n",
1435                                 dns_result_totext(dns_result));
1436                 dns_db_detach(&db);
1437                 isc_hash_destroy();
1438                 isc_entropy_detach(&ectx);
1439                 isc_mem_destroy(&mctx);
1440                 return(T_UNRESOLVED);
1441         }
1442
1443         /*
1444          * Remove all rdata for an existing name.
1445          */
1446
1447         dns_fixedname_init(&dns_existingname);
1448         len = strlen(existing_name);
1449         isc_buffer_init(&name_buffer, existing_name, len);
1450         isc_buffer_add(&name_buffer, len);
1451         dns_result = dns_name_fromtext(dns_fixedname_name(&dns_existingname),
1452                         &name_buffer, NULL, 0, NULL);
1453         if (dns_result != ISC_R_SUCCESS) {
1454                 t_info("dns_name_fromtext failed %s\n",
1455                         dns_result_totext(dns_result));
1456                 dns_db_detach(&db);
1457                 isc_hash_destroy();
1458                 isc_entropy_detach(&ectx);
1459                 isc_mem_destroy(&mctx);
1460                 return(T_UNRESOLVED);
1461         }
1462
1463         textregion.base = existing_type;
1464         textregion.length = strlen(existing_type);
1465         dns_result = dns_rdatatype_fromtext(&existing_rdatatype, &textregion);
1466         if (dns_result != ISC_R_SUCCESS) {
1467                 t_info("dns_rdatatype_fromtext %s failed %s\n",
1468                                 existing_type,
1469                                 dns_result_totext(dns_result));
1470                 dns_db_detachnode(db, &nodep);
1471                 dns_db_detach(&db);
1472                 isc_hash_destroy();
1473                 isc_entropy_detach(&ectx);
1474                 isc_mem_destroy(&mctx);
1475                 return(T_UNRESOLVED);
1476         }
1477
1478         nodep = NULL;
1479         dns_result = dns_db_findnode(db, dns_fixedname_name(&dns_existingname),
1480                                 ISC_FALSE, &nodep);
1481         if (dns_result != ISC_R_SUCCESS) {
1482                 t_info("dns_db_findnode %s\n",
1483                                 dns_result_totext(dns_result));
1484                 dns_db_detach(&db);
1485                 isc_hash_destroy();
1486                 isc_entropy_detach(&ectx);
1487                 isc_mem_destroy(&mctx);
1488                 return(T_UNRESOLVED);
1489         }
1490
1491         /* open a new version */
1492         nversionp = NULL;
1493         dns_result = dns_db_newversion(db, &nversionp);
1494         if (dns_result != ISC_R_SUCCESS) {
1495                 t_info("dns_db_newversion failed %s\n",
1496                                 dns_result_totext(dns_result));
1497                 dns_db_detachnode(db, &nodep);
1498                 dns_db_detach(&db);
1499                 isc_hash_destroy();
1500                 isc_entropy_detach(&ectx);
1501                 isc_mem_destroy(&mctx);
1502                 return(T_UNRESOLVED);
1503         }
1504
1505         dns_result = dns_db_deleterdataset(db, nodep, nversionp,
1506                                            existing_rdatatype, 0);
1507         if (dns_result != ISC_R_SUCCESS) {
1508                 t_info("dns_db_deleterdataset failed %s\n",
1509                                 dns_result_totext(dns_result));
1510                 dns_db_closeversion(db, &nversionp, ISC_FALSE);
1511                 dns_db_detachnode(db, &nodep);
1512                 dns_db_detach(&db);
1513                 isc_hash_destroy();
1514                 isc_entropy_detach(&ectx);
1515                 isc_mem_destroy(&mctx);
1516                 return(T_UNRESOLVED);
1517         }
1518
1519         /*
1520          * add a new name and associate some rdata with it
1521          */
1522
1523         dns_db_detachnode(db, &nodep);
1524         nodep = NULL;
1525
1526         dns_fixedname_init(&dns_newname);
1527         len = strlen(new_name);
1528         isc_buffer_init(&name_buffer, new_name, len);
1529         isc_buffer_add(&name_buffer, len);
1530         dns_result = dns_name_fromtext(dns_fixedname_name(&dns_newname),
1531                                 &name_buffer, NULL, 0, NULL);
1532         if (dns_result != ISC_R_SUCCESS) {
1533                 t_info("dns_name_fromtext failed %s\n",
1534                         dns_result_totext(dns_result));
1535                 dns_db_closeversion(db, &nversionp, ISC_FALSE);
1536                 dns_db_detach(&db);
1537                 isc_hash_destroy();
1538                 isc_entropy_detach(&ectx);
1539                 isc_mem_destroy(&mctx);
1540                 return(T_UNRESOLVED);
1541         }
1542
1543         dns_result = dns_db_findnode(db, dns_fixedname_name(&dns_newname),
1544                                 ISC_TRUE, &nodep);
1545         if (dns_result != ISC_R_SUCCESS) {
1546                 t_info("dns_db_findnode failed %s\n",
1547                                 dns_result_totext(dns_result));
1548                 dns_db_closeversion(db, &nversionp, ISC_FALSE);
1549                 dns_db_detach(&db);
1550                 isc_hash_destroy();
1551                 isc_entropy_detach(&ectx);
1552                 isc_mem_destroy(&mctx);
1553                 return(T_UNRESOLVED);
1554         }
1555
1556         /*
1557          * associate some rdata with the new name
1558          */
1559
1560         textregion.base = new_type;
1561         textregion.length = strlen(new_type);
1562         dns_result = dns_rdatatype_fromtext(&new_rdatatype, &textregion);
1563         if (dns_result != ISC_R_SUCCESS) {
1564                 t_info("dns_rdatatype_fromtext %s failed %s\n",
1565                                 new_type,
1566                                 dns_result_totext(dns_result));
1567                 dns_db_detachnode(db, &nodep);
1568                 dns_db_detach(&db);
1569                 isc_hash_destroy();
1570                 isc_entropy_detach(&ectx);
1571                 isc_mem_destroy(&mctx);
1572                 return(T_UNRESOLVED);
1573         }
1574
1575         textregion.base = class;
1576         textregion.length = strlen(class);
1577         dns_result = dns_rdataclass_fromtext(&rdataclass, &textregion);
1578         if (dns_result != ISC_R_SUCCESS) {
1579                 t_info("dns_rdataclass_fromtext failed %s\n",
1580                                 dns_result_totext(dns_result));
1581                 dns_db_detachnode(db, &nodep);
1582                 dns_db_detach(&db);
1583                 isc_hash_destroy();
1584                 isc_entropy_detach(&ectx);
1585                 isc_mem_destroy(&mctx);
1586                 return(T_UNRESOLVED);
1587         }
1588
1589         dns_rdata_init(&added_rdata);
1590         added_rdata_data = "\x10\x00\x00\x01";
1591         DE_CONST(added_rdata_data, added_rdata.data);
1592         added_rdata.length = 4;
1593         added_rdata.rdclass = rdataclass;
1594         added_rdata.type = new_rdatatype;
1595
1596         dns_rdataset_init(&added_rdataset);
1597         rdatalist.type = new_rdatatype;
1598         rdatalist.covers = 0;
1599         rdatalist.rdclass = rdataclass;
1600         rdatalist.ttl = 0;
1601         ISC_LIST_INIT(rdatalist.rdata);
1602         ISC_LIST_APPEND(rdatalist.rdata, &added_rdata, link);
1603
1604         dns_result = dns_rdatalist_tordataset(&rdatalist, &added_rdataset);
1605         if (dns_result != ISC_R_SUCCESS) {
1606                 t_info("dns_rdatalist_tordataset failed %s\n",
1607                                 dns_result_totext(dns_result));
1608                 dns_db_detachnode(db, &nodep);
1609                 dns_db_detach(&db);
1610                 isc_hash_destroy();
1611                 isc_entropy_detach(&ectx);
1612                 isc_mem_destroy(&mctx);
1613                 return(T_UNRESOLVED);
1614         }
1615
1616         dns_result = dns_db_addrdataset(db, nodep, nversionp, 0,
1617                                 &added_rdataset, 0, NULL);
1618         if (dns_result != ISC_R_SUCCESS) {
1619                 t_info("dns_db_addrdataset failed %s\n",
1620                                 dns_result_totext(dns_result));
1621                 dns_db_closeversion(db, &nversionp, ISC_FALSE);
1622                 dns_db_detachnode(db, &nodep);
1623                 dns_db_detach(&db);
1624                 isc_hash_destroy();
1625                 isc_entropy_detach(&ectx);
1626                 isc_mem_destroy(&mctx);
1627                 return(T_UNRESOLVED);
1628         }
1629
1630         /* close and commit the version */
1631         dns_db_closeversion(db, &nversionp, ISC_TRUE);
1632         dns_db_detachnode(db, &nodep);
1633         nodep = NULL;
1634
1635         /* open the current version and check changes */
1636         dns_fixedname_init(&dns_foundname);
1637         dns_rdataset_init(&found_rdataset);
1638         cversionp = NULL;
1639         dns_db_currentversion(db, &cversionp);
1640
1641         /* find the recently added name and rdata */
1642         dns_result = dns_db_find(db,
1643                         dns_fixedname_name(&dns_newname),
1644                         cversionp,
1645                         new_rdatatype,
1646                         0,
1647                         0,
1648                         &nodep,
1649                         dns_fixedname_name(&dns_foundname),
1650                         &found_rdataset, NULL);
1651
1652         if (dns_result != ISC_R_SUCCESS) {
1653                 /* XXXWPK NXRRSET ??? reference counting ??? */
1654                 t_info("dns_db_find failed %s\n",
1655                                 dns_result_totext(dns_result));
1656                 dns_db_closeversion(db, &cversionp, ISC_FALSE);
1657                 dns_db_detachnode(db, &nodep);
1658                 if (dns_rdataset_isassociated(&found_rdataset))
1659                         dns_rdataset_disassociate(&found_rdataset);
1660                 dns_db_detach(&db);
1661                 isc_hash_destroy();
1662                 isc_entropy_detach(&ectx);
1663                 isc_mem_destroy(&mctx);
1664                 return(T_FAIL);
1665         }
1666
1667         dns_result = dns_rdataset_first(&found_rdataset);
1668         if (dns_result != ISC_R_SUCCESS) {
1669                 t_info("dns_rdataset_first failed %s\n",
1670                                 dns_result_totext(dns_result));
1671                 dns_db_detachnode(db, &nodep);
1672                 if (dns_rdataset_isassociated(&found_rdataset))
1673                         dns_rdataset_disassociate(&found_rdataset);
1674                 dns_db_closeversion(db, &cversionp, ISC_FALSE);
1675                 dns_db_detach(&db);
1676                 isc_hash_destroy();
1677                 isc_entropy_detach(&ectx);
1678                 isc_mem_destroy(&mctx);
1679                 return(T_FAIL);
1680         }
1681
1682         /*
1683          * Now make sure its what we expect.
1684          */
1685         dns_rdata_init(&found_rdata);
1686         dns_rdataset_current(&found_rdataset, &found_rdata);
1687         rval = dns_rdata_compare(&added_rdata, &found_rdata);
1688         if (rval != 0) {
1689                 t_info("dns_rdata_compare returned %d\n", rval);
1690                 ++nfails;
1691         }
1692
1693         /*
1694          * Now check the rdata deletion.
1695          */
1696
1697         if (dns_rdataset_isassociated(&found_rdataset))
1698                 dns_rdataset_disassociate(&found_rdataset);
1699         dns_rdataset_init(&found_rdataset);
1700         dns_db_detachnode(db, &nodep);
1701         nodep = NULL;
1702         dns_fixedname_init(&dns_foundname);
1703
1704         dns_result = dns_db_find(db, dns_fixedname_name(&dns_existingname),
1705                                  cversionp, existing_rdatatype,
1706                                  0, 0, &nodep,
1707                                  dns_fixedname_name(&dns_foundname),
1708                                  &found_rdataset, NULL);
1709
1710
1711         if ((dns_result != ISC_R_NOTFOUND) && (dns_result != DNS_R_NXDOMAIN)) {
1712                 dns_rdataset_disassociate(&found_rdataset);
1713                 dns_db_detachnode(db, &nodep);
1714                 t_info("dns_db_find %s returned %s\n", existing_name,
1715                        dns_result_totext(dns_result));
1716                 ++nfails;
1717         }
1718
1719         dns_db_closeversion(db, &cversionp, ISC_FALSE);
1720         dns_db_detach(&db);
1721         isc_hash_destroy();
1722         isc_entropy_detach(&ectx);
1723         isc_mem_destroy(&mctx);
1724
1725         if (nfails == 0)
1726                 result = T_PASS;
1727         else
1728                 result = T_FAIL;
1729
1730         return(result);
1731 }
1732
1733 static void
1734 t10(void) {
1735         int     result;
1736
1737         t_assert("dns_db_closeversion", 10, T_REQUIRED, "%s", a10);
1738         result = t_eval("dns_db_closeversion_1_data",
1739                         t_dns_db_closeversion_1, 9);
1740         t_result(result);
1741 }
1742
1743 static const char *a11 =
1744         "When versionp points to a read-write version and commit is "
1745         "ISC_FALSE, a call to dns_db_closeversion(db, versionp, commit) "
1746         "causes all changes made in the version to to be rolled back, "
1747         "and returns ISC_R_SUCCESS.";
1748
1749 static int
1750 t_dns_db_closeversion_2(char **av) {
1751         char                    *filename;
1752         char                    *db_type;
1753         char                    *origin;
1754         char                    *class;
1755         char                    *model;
1756         char                    *new_name;
1757         char                    *new_type;
1758         char                    *existing_name;
1759         char                    *existing_type;
1760
1761         int                     result;
1762         int                     len;
1763         int                     rval;
1764         int                     nfails;
1765         dns_db_t                *db;
1766         isc_result_t            dns_result;
1767         isc_result_t            isc_result;
1768         isc_mem_t               *mctx;
1769         isc_entropy_t           *ectx;
1770         dns_dbnode_t            *nodep;
1771         isc_textregion_t        textregion;
1772         isc_buffer_t            name_buffer;
1773         dns_fixedname_t         dns_newname;
1774         dns_fixedname_t         dns_foundname;
1775         dns_fixedname_t         dns_existingname;
1776         dns_rdata_t             added_rdata = DNS_RDATA_INIT;
1777         const char *            added_rdata_data;
1778         dns_rdataset_t          added_rdataset;
1779         dns_rdata_t             found_rdata = DNS_RDATA_INIT;
1780         dns_rdataset_t          found_rdataset;
1781         dns_rdatatype_t         new_rdatatype;
1782         dns_rdatatype_t         existing_rdatatype;
1783         dns_rdataclass_t        rdataclass;
1784         dns_dbversion_t         *nversionp;
1785         dns_dbversion_t         *cversionp;
1786         dns_rdatalist_t         rdatalist;
1787
1788         filename = T_ARG(0);
1789         db_type = T_ARG(1);
1790         origin = T_ARG(2);
1791         class = T_ARG(3);
1792         model = T_ARG(4);
1793         new_name = T_ARG(5);
1794         new_type = T_ARG(6);
1795         existing_name = T_ARG(7);
1796         existing_type = T_ARG(8);
1797
1798         nfails = 0;
1799         result = T_UNRESOLVED;
1800         db = NULL;
1801         mctx = NULL;
1802         ectx = NULL;
1803
1804         /*
1805          * Open a new version, add some data,
1806          * remove some data, close with commit, open the current
1807          * version and check that changes are present.
1808          */
1809
1810         t_info("testing using file %s and name %s\n", filename, new_name);
1811
1812         isc_result = isc_mem_create(0, 0, &mctx);
1813         if (isc_result != ISC_R_SUCCESS) {
1814                 t_info("isc_mem_create failed %s\n",
1815                                 isc_result_totext(isc_result));
1816                 return(T_UNRESOLVED);
1817         }
1818
1819         isc_result = isc_entropy_create(mctx, &ectx);
1820         if (isc_result != ISC_R_SUCCESS) {
1821                 t_info("isc_entropy_create failed %s\n",
1822                                 isc_result_totext(isc_result));
1823                 isc_mem_destroy(&mctx);
1824                 return(T_UNRESOLVED);
1825         }
1826
1827         isc_result = isc_hash_create(mctx, ectx, DNS_NAME_MAXWIRE);
1828         if (isc_result != ISC_R_SUCCESS) {
1829                 t_info("isc_hash_create failed %s\n",
1830                                 isc_result_totext(isc_result));
1831                 isc_entropy_detach(&ectx);
1832                 isc_mem_destroy(&mctx);
1833                 return(T_UNRESOLVED);
1834         }
1835
1836         dns_result = t_create(db_type, origin, class, model, mctx, &db);
1837         if (dns_result != ISC_R_SUCCESS) {
1838                 isc_hash_destroy();
1839                 isc_entropy_detach(&ectx);
1840                 isc_mem_destroy(&mctx);
1841                 return(T_UNRESOLVED);
1842         }
1843
1844         dns_result = dns_db_load(db, filename);
1845         if (dns_result != ISC_R_SUCCESS) {
1846                 t_info("dns_db_load returned %s\n",
1847                                 dns_result_totext(dns_result));
1848                 dns_db_detach(&db);
1849                 isc_hash_destroy();
1850                 isc_entropy_detach(&ectx);
1851                 isc_mem_destroy(&mctx);
1852                 return(T_UNRESOLVED);
1853         }
1854
1855         /*
1856          * Remove all rdata for an existing name.
1857          */
1858
1859         dns_fixedname_init(&dns_existingname);
1860         len = strlen(existing_name);
1861         isc_buffer_init(&name_buffer, existing_name, len);
1862         isc_buffer_add(&name_buffer, len);
1863         dns_result = dns_name_fromtext(dns_fixedname_name(&dns_existingname),
1864                         &name_buffer, NULL, 0, NULL);
1865         if (dns_result != ISC_R_SUCCESS) {
1866                 t_info("dns_name_fromtext failed %s\n",
1867                         dns_result_totext(dns_result));
1868                 dns_db_detach(&db);
1869                 isc_hash_destroy();
1870                 isc_entropy_detach(&ectx);
1871                 isc_mem_destroy(&mctx);
1872                 return(T_UNRESOLVED);
1873         }
1874
1875         textregion.base = existing_type;
1876         textregion.length = strlen(existing_type);
1877         dns_result = dns_rdatatype_fromtext(&existing_rdatatype, &textregion);
1878         if (dns_result != ISC_R_SUCCESS) {
1879                 t_info("dns_rdatatype_fromtext %s failed %s\n",
1880                                 existing_type,
1881                                 dns_result_totext(dns_result));
1882                 dns_db_detachnode(db, &nodep);
1883                 dns_db_detach(&db);
1884                 isc_hash_destroy();
1885                 isc_entropy_detach(&ectx);
1886                 isc_mem_destroy(&mctx);
1887                 return(T_UNRESOLVED);
1888         }
1889
1890         nodep = NULL;
1891         dns_result = dns_db_findnode(db, dns_fixedname_name(&dns_existingname),
1892                                 ISC_FALSE, &nodep);
1893         if (dns_result != ISC_R_SUCCESS) {
1894                 t_info("dns_db_findnode %s\n",
1895                                 dns_result_totext(dns_result));
1896                 dns_db_detach(&db);
1897                 isc_hash_destroy();
1898                 isc_entropy_detach(&ectx);
1899                 isc_mem_destroy(&mctx);
1900                 return(T_UNRESOLVED);
1901         }
1902
1903         /*
1904          * Open a new version.
1905          */
1906         nversionp = NULL;
1907         dns_result = dns_db_newversion(db, &nversionp);
1908         if (dns_result != ISC_R_SUCCESS) {
1909                 t_info("dns_db_newversion failed %s\n",
1910                                 dns_result_totext(dns_result));
1911                 dns_db_detachnode(db, &nodep);
1912                 dns_db_detach(&db);
1913                 isc_hash_destroy();
1914                 isc_entropy_detach(&ectx);
1915                 isc_mem_destroy(&mctx);
1916                 return(T_UNRESOLVED);
1917         }
1918
1919         dns_result = dns_db_deleterdataset(db, nodep, nversionp,
1920                                            existing_rdatatype, 0);
1921         if (dns_result != ISC_R_SUCCESS) {
1922                 t_info("dns_db_deleterdataset failed %s\n",
1923                                 dns_result_totext(dns_result));
1924                 dns_db_closeversion(db, &nversionp, ISC_FALSE);
1925                 dns_db_detachnode(db, &nodep);
1926                 dns_db_detach(&db);
1927                 isc_hash_destroy();
1928                 isc_entropy_detach(&ectx);
1929                 isc_mem_destroy(&mctx);
1930                 return(T_UNRESOLVED);
1931         }
1932
1933         /*
1934          * add a new name and associate some rdata with it
1935          */
1936
1937         dns_db_detachnode(db, &nodep);
1938         nodep = NULL;
1939
1940         dns_fixedname_init(&dns_newname);
1941         len = strlen(new_name);
1942         isc_buffer_init(&name_buffer, new_name, len);
1943         isc_buffer_add(&name_buffer, len);
1944         dns_result = dns_name_fromtext(dns_fixedname_name(&dns_newname),
1945                                        &name_buffer, NULL, 0, NULL);
1946         if (dns_result != ISC_R_SUCCESS) {
1947                 t_info("dns_name_fromtext failed %s\n",
1948                        dns_result_totext(dns_result));
1949                 dns_db_closeversion(db, &nversionp, ISC_FALSE);
1950                 dns_db_detach(&db);
1951                 isc_hash_destroy();
1952                 isc_entropy_detach(&ectx);
1953                 isc_mem_destroy(&mctx);
1954                 return(T_UNRESOLVED);
1955         }
1956
1957         dns_result = dns_db_findnode(db, dns_fixedname_name(&dns_newname),
1958                                      ISC_TRUE, &nodep);
1959         if (dns_result != ISC_R_SUCCESS) {
1960                 t_info("dns_db_findnode failed %s\n",
1961                        dns_result_totext(dns_result));
1962                 dns_db_closeversion(db, &nversionp, ISC_FALSE);
1963                 dns_db_detach(&db);
1964                 isc_hash_destroy();
1965                 isc_entropy_detach(&ectx);
1966                 isc_mem_destroy(&mctx);
1967                 return(T_UNRESOLVED);
1968         }
1969
1970         textregion.base = new_type;
1971         textregion.length = strlen(new_type);
1972         dns_result = dns_rdatatype_fromtext(&new_rdatatype, &textregion);
1973         if (dns_result != ISC_R_SUCCESS) {
1974                 t_info("dns_rdatatype_fromtext %s failed %s\n",
1975                        new_type, dns_result_totext(dns_result));
1976                 dns_db_detachnode(db, &nodep);
1977                 dns_db_detach(&db);
1978                 isc_hash_destroy();
1979                 isc_entropy_detach(&ectx);
1980                 isc_mem_destroy(&mctx);
1981                 return(T_UNRESOLVED);
1982         }
1983
1984         textregion.base = class;
1985         textregion.length = strlen(class);
1986         dns_result = dns_rdataclass_fromtext(&rdataclass, &textregion);
1987         if (dns_result != ISC_R_SUCCESS) {
1988                 t_info("dns_rdataclass_fromtext failed %s\n",
1989                        dns_result_totext(dns_result));
1990                 dns_db_detachnode(db, &nodep);
1991                 dns_db_detach(&db);
1992                 isc_hash_destroy();
1993                 isc_entropy_detach(&ectx);
1994                 isc_mem_destroy(&mctx);
1995                 return(T_UNRESOLVED);
1996         }
1997
1998         dns_rdata_init(&added_rdata);
1999         added_rdata_data = "\x10\x00\x00\x01";
2000         DE_CONST(added_rdata_data, added_rdata.data);
2001         added_rdata.length = 4;
2002         added_rdata.rdclass = rdataclass;
2003         added_rdata.type = new_rdatatype;
2004
2005         dns_rdataset_init(&added_rdataset);
2006         rdatalist.type = new_rdatatype;
2007         rdatalist.covers = 0;
2008         rdatalist.rdclass = rdataclass;
2009         rdatalist.ttl = 0;
2010         ISC_LIST_INIT(rdatalist.rdata);
2011         ISC_LIST_APPEND(rdatalist.rdata, &added_rdata, link);
2012
2013         dns_result = dns_rdatalist_tordataset(&rdatalist, &added_rdataset);
2014         if (dns_result != ISC_R_SUCCESS) {
2015                 t_info("dns_rdatalist_tordataset failed %s\n",
2016                        dns_result_totext(dns_result));
2017                 dns_db_detachnode(db, &nodep);
2018                 dns_db_detach(&db);
2019                 isc_hash_destroy();
2020                 isc_entropy_detach(&ectx);
2021                 isc_mem_destroy(&mctx);
2022                 return(T_UNRESOLVED);
2023         }
2024
2025         dns_result = dns_db_addrdataset(db, nodep, nversionp, 0,
2026                                 &added_rdataset, 0, NULL);
2027         if (dns_result != ISC_R_SUCCESS) {
2028                 t_info("dns_db_addrdataset failed %s\n",
2029                        dns_result_totext(dns_result));
2030                 dns_db_closeversion(db, &nversionp, ISC_FALSE);
2031                 dns_db_detachnode(db, &nodep);
2032                 dns_db_detach(&db);
2033                 isc_hash_destroy();
2034                 isc_entropy_detach(&ectx);
2035                 isc_mem_destroy(&mctx);
2036                 return(T_UNRESOLVED);
2037         }
2038
2039         /*
2040          * Check that our changes took.
2041          */
2042         dns_db_detachnode(db, &nodep);
2043         nodep = NULL;
2044         dns_fixedname_init(&dns_foundname);
2045         dns_rdataset_init(&found_rdataset);
2046
2047         /*
2048          * Find the recently added name and rdata.
2049          */
2050         dns_result = dns_db_find(db, dns_fixedname_name(&dns_newname),
2051                                  nversionp, new_rdatatype, 0, 0, &nodep,
2052                                  dns_fixedname_name(&dns_foundname),
2053                                  &found_rdataset, NULL);
2054
2055         if ((dns_result == ISC_R_NOTFOUND) ||
2056             (dns_result == DNS_R_NXDOMAIN) ||
2057             (dns_result == DNS_R_NXRRSET)) {
2058
2059                 t_info("dns_db_find failed %s\n",
2060                        dns_result_totext(dns_result));
2061                 dns_db_closeversion(db, &nversionp, ISC_FALSE);
2062                 dns_db_detachnode(db, &nodep);
2063                 if (dns_rdataset_isassociated(&found_rdataset))
2064                         dns_rdataset_disassociate(&found_rdataset);
2065                 dns_db_detach(&db);
2066                 isc_hash_destroy();
2067                 isc_entropy_detach(&ectx);
2068                 isc_mem_destroy(&mctx);
2069                 return(T_FAIL);
2070         }
2071
2072         dns_result = dns_rdataset_first(&found_rdataset);
2073         if (dns_result != ISC_R_SUCCESS) {
2074                 t_info("dns_rdataset_first failed %s\n",
2075                                 dns_result_totext(dns_result));
2076                 dns_db_detachnode(db, &nodep);
2077                 if (dns_rdataset_isassociated(&found_rdataset))
2078                         dns_rdataset_disassociate(&found_rdataset);
2079                 dns_db_closeversion(db, &nversionp, ISC_FALSE);
2080                 dns_db_detach(&db);
2081                 isc_hash_destroy();
2082                 isc_entropy_detach(&ectx);
2083                 isc_mem_destroy(&mctx);
2084                 return(T_FAIL);
2085         }
2086
2087         /*
2088          * Now make sure its what we expect.
2089          */
2090         dns_rdata_init(&found_rdata);
2091         dns_rdataset_current(&found_rdataset, &found_rdata);
2092         rval = dns_rdata_compare(&added_rdata, &found_rdata);
2093         if (rval != 0) {
2094                 t_info("dns_rdata_compare returned %d\n", rval);
2095                 ++nfails;
2096         }
2097
2098         /*
2099          * Now check the rdata deletion.
2100          */
2101         if (dns_rdataset_isassociated(&found_rdataset))
2102                 dns_rdataset_disassociate(&found_rdataset);
2103         dns_rdataset_init(&found_rdataset);
2104         dns_db_detachnode(db, &nodep);
2105         nodep = NULL;
2106         dns_fixedname_init(&dns_foundname);
2107
2108         dns_result = dns_db_find(db,
2109                         dns_fixedname_name(&dns_existingname),
2110                         nversionp,
2111                         existing_rdatatype,
2112                         0,
2113                         0,
2114                         &nodep,
2115                         dns_fixedname_name(&dns_foundname),
2116                         &found_rdataset, NULL);
2117
2118
2119         if ((dns_result != ISC_R_NOTFOUND) && (dns_result != DNS_R_NXDOMAIN)) {
2120                 t_info("dns_db_find %s returned %s\n", existing_name,
2121                        dns_result_totext(dns_result));
2122                 if (dns_rdataset_isassociated(&found_rdataset))
2123                         dns_rdataset_disassociate(&found_rdataset);
2124                 dns_db_detachnode(db, &nodep);
2125                 ++nfails;
2126         }
2127
2128
2129         /*
2130          * Close the version without a commit.
2131          */
2132         dns_db_closeversion(db, &nversionp, ISC_FALSE);
2133
2134         /*
2135          * Open the current version and check changes.
2136          */
2137         dns_fixedname_init(&dns_foundname);
2138         dns_rdataset_init(&found_rdataset);
2139         cversionp = NULL;
2140         dns_db_currentversion(db, &cversionp);
2141
2142         /*
2143          * Find the recently added name and rdata.
2144          */
2145         dns_result = dns_db_find(db,
2146                         dns_fixedname_name(&dns_newname),
2147                         cversionp,
2148                         new_rdatatype,
2149                         0,
2150                         0,
2151                         &nodep,
2152                         dns_fixedname_name(&dns_foundname),
2153                         &found_rdataset, NULL);
2154
2155         if ((dns_result != ISC_R_NOTFOUND) && (dns_result != DNS_R_NXDOMAIN)) {
2156                 t_info("dns_db_find %s returned %s\n", new_name,
2157                                 dns_result_totext(dns_result));
2158                 dns_rdataset_disassociate(&found_rdataset);
2159                 dns_db_detachnode(db, &nodep);
2160                 dns_db_closeversion(db, &cversionp, ISC_FALSE);
2161                 dns_db_detach(&db);
2162                 isc_hash_destroy();
2163                 isc_entropy_detach(&ectx);
2164                 isc_mem_destroy(&mctx);
2165                 return(T_FAIL);
2166         }
2167
2168         /*
2169          * Now check the rdata deletion.
2170          */
2171         nodep = NULL;
2172         dns_rdataset_init(&found_rdataset);
2173         dns_fixedname_init(&dns_foundname);
2174
2175         dns_result = dns_db_find(db, dns_fixedname_name(&dns_existingname),
2176                                  cversionp, existing_rdatatype, 0, 0,
2177                                  &nodep, dns_fixedname_name(&dns_foundname),
2178                                  &found_rdataset, NULL);
2179
2180
2181         if ((dns_result == ISC_R_NOTFOUND) ||
2182             (dns_result == DNS_R_NXDOMAIN) ||
2183             (dns_result == DNS_R_NXRRSET)) {
2184
2185                 t_info("dns_db_find %s returned %s\n", existing_name,
2186                        dns_result_totext(dns_result));
2187                 dns_rdataset_disassociate(&found_rdataset);
2188                 dns_db_detachnode(db, &nodep);
2189                 ++nfails;
2190         }
2191
2192         dns_db_detachnode(db, &nodep);
2193         dns_rdataset_disassociate(&found_rdataset);
2194         dns_db_closeversion(db, &cversionp, ISC_FALSE);
2195         dns_db_detach(&db);
2196         isc_hash_destroy();
2197         isc_entropy_detach(&ectx);
2198         isc_mem_destroy(&mctx);
2199
2200         if (nfails == 0)
2201                 result = T_PASS;
2202         else
2203                 result = T_FAIL;
2204
2205         return(result);
2206 }
2207
2208 static void
2209 t11(void) {
2210         int     result;
2211
2212         t_assert("dns_db_closeversion", 11, T_REQUIRED, "%s", a11);
2213         result = t_eval("dns_db_closeversion_2_data",
2214                         t_dns_db_closeversion_2, 9);
2215         t_result(result);
2216 }
2217
2218 static const char *a12 =
2219         "A call to dns_db_expirenode() marks as stale all records at node  "
2220         "which expire at or before 'now'. If 'now' is zero, then the current  "
2221         "time will be used.";
2222
2223 static int
2224 t_dns_db_expirenode(char **av) {
2225         char                    *filename;
2226         char                    *db_type;
2227         char                    *origin;
2228         char                    *class;
2229         char                    *existing_name;
2230         char                    *node_xtime;
2231         char                    *find_xtime;
2232         char                    *exp_find_result;
2233
2234         int                     result;
2235         int                     len;
2236         dns_db_t                *db;
2237         isc_result_t            dns_result;
2238         isc_result_t            exp_result;
2239         isc_result_t            isc_result;
2240         isc_mem_t               *mctx;
2241         isc_entropy_t           *ectx;
2242         dns_dbnode_t            *nodep;
2243         isc_buffer_t            name_buffer;
2244         dns_fixedname_t         dns_foundname;
2245         dns_fixedname_t         dns_existingname;
2246         isc_stdtime_t           node_expire_time;
2247         isc_stdtime_t           find_expire_time;
2248         isc_stdtime_t           now;
2249         dns_rdataset_t          rdataset;
2250
2251         filename = T_ARG(0);
2252         db_type = T_ARG(1);
2253         origin = T_ARG(2);
2254         class = T_ARG(3);
2255         existing_name = T_ARG(4);
2256         node_xtime = T_ARG(5);
2257         find_xtime = T_ARG(6);
2258         exp_find_result = T_ARG(7);
2259         mctx = NULL;
2260         ectx = NULL;
2261
2262         result = T_UNRESOLVED;
2263
2264         /*
2265          * Find a node, mark it as stale, do a dns_db_find on the name and
2266          * expect it to fail.
2267          */
2268
2269         t_info("testing using file %s and name %s\n", filename, existing_name);
2270
2271         node_expire_time = (isc_stdtime_t) strtol(node_xtime, NULL, 10);
2272         find_expire_time = (isc_stdtime_t) strtol(find_xtime, NULL, 10);
2273         exp_result = t_dns_result_fromtext(exp_find_result);
2274
2275         isc_stdtime_get(&now);
2276
2277         dns_fixedname_init(&dns_existingname);
2278         len = strlen(existing_name);
2279         isc_buffer_init(&name_buffer, existing_name, len);
2280         isc_buffer_add(&name_buffer, len);
2281         dns_result = dns_name_fromtext(dns_fixedname_name(&dns_existingname),
2282                                        &name_buffer, NULL, 0, NULL);
2283         if (dns_result != ISC_R_SUCCESS) {
2284                 t_info("dns_name_fromtext failed %s\n",
2285                        dns_result_totext(dns_result));
2286                 return(T_UNRESOLVED);
2287         }
2288
2289         isc_result = isc_mem_create(0, 0, &mctx);
2290         if (isc_result != ISC_R_SUCCESS) {
2291                 t_info("isc_mem_create failed %s\n",
2292                        isc_result_totext(isc_result));
2293                 return(T_UNRESOLVED);
2294         }
2295
2296         isc_result = isc_entropy_create(mctx, &ectx);
2297         if (isc_result != ISC_R_SUCCESS) {
2298                 t_info("isc_entropy_create failed %s\n",
2299                                 isc_result_totext(isc_result));
2300                 isc_mem_destroy(&mctx);
2301                 return(T_UNRESOLVED);
2302         }
2303
2304         isc_result = isc_hash_create(mctx, ectx, DNS_NAME_MAXWIRE);
2305         if (isc_result != ISC_R_SUCCESS) {
2306                 t_info("isc_hash_create failed %s\n",
2307                                 isc_result_totext(isc_result));
2308                 isc_entropy_detach(&ectx);
2309                 isc_mem_destroy(&mctx);
2310                 return(T_UNRESOLVED);
2311         }
2312
2313         db = NULL;
2314         dns_result = t_create(db_type, origin, class, "cache", mctx, &db);
2315         if (dns_result != ISC_R_SUCCESS) {
2316                 isc_hash_destroy();
2317                 isc_entropy_detach(&ectx);
2318                 isc_mem_destroy(&mctx);
2319                 return(T_UNRESOLVED);
2320         }
2321
2322         dns_result = dns_db_load(db, filename);
2323         if (dns_result != ISC_R_SUCCESS) {
2324                 t_info("dns_db_load returned %s\n",
2325                        dns_result_totext(dns_result));
2326                 dns_db_detach(&db);
2327                 isc_hash_destroy();
2328                 isc_entropy_detach(&ectx);
2329                 isc_mem_destroy(&mctx);
2330                 return(T_UNRESOLVED);
2331         }
2332
2333         nodep = NULL;
2334
2335         /*
2336          * Check that the node is there.
2337          */
2338         dns_result = dns_db_findnode(db, dns_fixedname_name(&dns_existingname),
2339                                      ISC_FALSE, &nodep);
2340         if (dns_result != ISC_R_SUCCESS) {
2341                 t_info("unable to find %s\n", existing_name);
2342                 dns_db_detach(&db);
2343                 isc_hash_destroy();
2344                 isc_entropy_detach(&ectx);
2345                 isc_mem_destroy(&mctx);
2346                 return(T_UNRESOLVED);
2347         }
2348
2349         /*
2350          * Expire it.
2351          */
2352         if (node_expire_time != 0)
2353                 node_expire_time += now;
2354
2355         dns_result = dns_db_expirenode(db, nodep, node_expire_time);
2356         if (dns_result != ISC_R_SUCCESS) {
2357                 t_info("dns_db_expirenode failed %s\n",
2358                        dns_result_totext(dns_result));
2359                 dns_db_detachnode(db, &nodep);
2360                 dns_db_detach(&db);
2361                 isc_hash_destroy();
2362                 isc_entropy_detach(&ectx);
2363                 isc_mem_destroy(&mctx);
2364                 return(T_FAIL);
2365         }
2366
2367         dns_fixedname_init(&dns_foundname);
2368         dns_rdataset_init(&rdataset);
2369         dns_db_detachnode(db, &nodep);
2370         nodep = NULL;
2371
2372         if (find_expire_time != 0)
2373                 find_expire_time += now;
2374
2375         dns_result = dns_db_find(db,
2376                                  dns_fixedname_name(&dns_existingname),
2377                                  NULL,
2378                                  dns_rdatatype_any,
2379                                  0,
2380                                  find_expire_time,
2381                                  &nodep,
2382                                  dns_fixedname_name(&dns_foundname),
2383                                  &rdataset, NULL);
2384
2385         if (dns_result == exp_result) {
2386                 result = T_PASS;
2387         } else {
2388                 t_info("dns_db_find %s returned %s\n", existing_name,
2389                        dns_result_totext(dns_result));
2390                 result = T_FAIL;
2391         }
2392
2393         if ((dns_result != ISC_R_NOTFOUND) &&
2394             (dns_result != DNS_R_NXDOMAIN) &&
2395             (dns_result != DNS_R_NXRRSET)) {
2396
2397                 /*
2398                  * Don't need to disassociate the rdataset because
2399                  * we're searching with dns_rdatatype_any.
2400                  */
2401                 dns_db_detachnode(db, &nodep);
2402         }
2403
2404
2405         dns_db_detach(&db);
2406         isc_hash_destroy();
2407         isc_entropy_detach(&ectx);
2408         isc_mem_destroy(&mctx);
2409
2410         return(result);
2411 }
2412
2413 static void
2414 t12(void) {
2415         int     result;
2416
2417         t_assert("dns_db_expirenode", 12, T_REQUIRED, "%s", a12);
2418         result = t_eval("dns_db_expirenode_data", t_dns_db_expirenode, 8);
2419         t_result(result);
2420 }
2421
2422 static const char *a13 =
2423         "If the node name exists, then a call to "
2424         "dns_db_findnode(db, name, ISC_FALSE, nodep) initializes nodep "
2425         "to point to the node and returns ISC_R_SUCCESS, otherwise "
2426         "it returns ISC_R_NOTFOUND.";
2427
2428 static int
2429 t_dns_db_findnode_1(char **av) {
2430         char            *filename;
2431         char            *db_type;
2432         char            *origin;
2433         char            *class;
2434         char            *model;
2435         char            *find_name;
2436         char            *find_type;
2437         char            *expected_result;
2438
2439         int                     result;
2440         int                     len;
2441         dns_db_t                *db;
2442         isc_result_t            dns_result;
2443         isc_result_t            isc_result;
2444         isc_mem_t               *mctx;
2445         isc_entropy_t           *ectx;
2446         dns_dbnode_t            *nodep;
2447         isc_buffer_t            name_buffer;
2448         dns_rdataset_t          rdataset;
2449         dns_rdatatype_t         rdatatype;
2450         isc_textregion_t        textregion;
2451         dns_fixedname_t         dns_name;
2452         dns_dbversion_t         *cversionp;
2453         isc_result_t            exp_result;
2454
2455         filename = T_ARG(0);
2456         db_type = T_ARG(1);
2457         origin = T_ARG(2);
2458         class = T_ARG(3);
2459         model = T_ARG(4);
2460         find_name = T_ARG(5);
2461         find_type = T_ARG(6);
2462         expected_result = T_ARG(7);
2463
2464         db = NULL;
2465         mctx = NULL;
2466         ectx = NULL;
2467         result = T_UNRESOLVED;
2468
2469         t_info("testing using file %s and name %s\n", filename, find_name);
2470
2471         exp_result = t_dns_result_fromtext(expected_result);
2472
2473         textregion.base = find_type;
2474         textregion.length = strlen(find_type);
2475         dns_result = dns_rdatatype_fromtext(&rdatatype, &textregion);
2476         if (dns_result != ISC_R_SUCCESS) {
2477                 t_info("dns_rdatatype_fromtext %s failed %s\n",
2478                                 find_type,
2479                                 dns_result_totext(dns_result));
2480                 return(T_UNRESOLVED);
2481         }
2482
2483         isc_result = isc_mem_create(0, 0, &mctx);
2484         if (isc_result != ISC_R_SUCCESS) {
2485                 t_info("isc_mem_create failed %s\n",
2486                                 isc_result_totext(isc_result));
2487                 return(T_UNRESOLVED);
2488         }
2489
2490         isc_result = isc_entropy_create(mctx, &ectx);
2491         if (isc_result != ISC_R_SUCCESS) {
2492                 t_info("isc_entropy_create failed %s\n",
2493                                 isc_result_totext(isc_result));
2494                 isc_mem_destroy(&mctx);
2495                 return(T_UNRESOLVED);
2496         }
2497
2498         isc_result = isc_hash_create(mctx, ectx, DNS_NAME_MAXWIRE);
2499         if (isc_result != ISC_R_SUCCESS) {
2500                 t_info("isc_hash_create failed %s\n",
2501                                 isc_result_totext(isc_result));
2502                 isc_mem_destroy(&mctx);
2503                 return(T_UNRESOLVED);
2504         }
2505
2506         dns_result = t_create(db_type, origin, class, model, mctx, &db);
2507         if (dns_result != ISC_R_SUCCESS) {
2508                 isc_mem_destroy(&mctx);
2509                 return(T_UNRESOLVED);
2510         }
2511
2512         dns_result = dns_db_load(db, filename);
2513         if (dns_result != ISC_R_SUCCESS) {
2514                 t_info("dns_db_load returned %s\n",
2515                                 dns_result_totext(dns_result));
2516                 dns_db_detach(&db);
2517                 isc_mem_destroy(&mctx);
2518                 return(T_UNRESOLVED);
2519         }
2520
2521         nodep = NULL;
2522         dns_fixedname_init(&dns_name);
2523
2524         len = strlen(find_name);
2525         isc_buffer_init(&name_buffer, find_name, len);
2526         isc_buffer_add(&name_buffer, len);
2527         dns_result = dns_name_fromtext(dns_fixedname_name(&dns_name),
2528                                 &name_buffer, NULL, 0, NULL);
2529
2530         dns_result = dns_db_findnode(db, dns_fixedname_name(&dns_name),
2531                                 ISC_FALSE, &nodep);
2532         if (dns_result != exp_result) {
2533                 t_info("dns_db_findnode failed %s\n",
2534                                 dns_result_totext(dns_result));
2535                 if (dns_result == ISC_R_SUCCESS)
2536                         dns_db_detachnode(db, &nodep);
2537                 dns_db_detach(&db);
2538                 isc_mem_destroy(&mctx);
2539                 return(T_FAIL);
2540         }
2541
2542         /*
2543          * if we're expecting the find to succeed and it did,
2544          * check that the node has been initialized
2545          * by checking for the specified type of rdata
2546          * and expecting the search to succeed
2547          */
2548
2549         if (dns_result == ISC_R_SUCCESS) {
2550                 cversionp = NULL;
2551                 dns_db_currentversion(db, &cversionp);
2552                 dns_rdataset_init(&rdataset);
2553
2554                 dns_result = dns_db_findrdataset(db, nodep, cversionp,
2555                                                  rdatatype, 0,
2556                                                  0, &rdataset, NULL);
2557                 if (dns_result == ISC_R_SUCCESS) {
2558                         dns_rdataset_disassociate(&rdataset);
2559                         result = T_PASS;
2560                 } else {
2561                         t_info("dns_db_findrdataset failed %s\n",
2562                                         dns_result_totext(dns_result));
2563                         result = T_FAIL;
2564                 }
2565                 dns_db_closeversion(db, &cversionp, ISC_FALSE);
2566                 dns_db_detachnode(db, &nodep);
2567         } else {
2568                 result = T_PASS;
2569         }
2570
2571         dns_db_detach(&db);
2572         isc_hash_destroy();
2573         isc_entropy_detach(&ectx);
2574         isc_mem_destroy(&mctx);
2575
2576         return(result);
2577 }
2578
2579 static void
2580 t13(void) {
2581         int     result;
2582
2583         t_assert("dns_db_findnode", 13, T_REQUIRED, "%s", a13);
2584         result = t_eval("dns_db_findnode_1_data", t_dns_db_findnode_1, 8);
2585         t_result(result);
2586 }
2587
2588 static const char *a14 =
2589         "If the node name does not exist and create is ISC_TRUE, "
2590         "then a call to dns_db_findnode(db, name, create, nodep) "
2591         "creates the node, initializes nodep to point to the node, "
2592         "and returns ISC_R_SUCCESS.";
2593
2594 static int
2595 t_dns_db_findnode_2(char **av) {
2596         char                    *filename;
2597         char                    *db_type;
2598         char                    *origin;
2599         char                    *class;
2600         char                    *model;
2601         char                    *newname;
2602
2603         int                     nfails;
2604         int                     result;
2605         int                     len;
2606         dns_db_t                *db;
2607         isc_result_t            dns_result;
2608         isc_result_t            isc_result;
2609         isc_mem_t               *mctx;
2610         isc_entropy_t           *ectx;
2611         dns_dbnode_t            *nodep;
2612         dns_dbnode_t            *newnodep;
2613         isc_buffer_t            name_buffer;
2614         dns_rdataset_t          rdataset;
2615         dns_fixedname_t         dns_name;
2616         dns_fixedname_t         dns_foundname;
2617         dns_dbversion_t         *cversionp;
2618
2619         filename = T_ARG(0);
2620         db_type = T_ARG(1);
2621         origin = T_ARG(2);
2622         class = T_ARG(3);
2623         model = T_ARG(4);
2624         newname = T_ARG(5);
2625
2626         result = T_UNRESOLVED;
2627         db = NULL;
2628         mctx = NULL;
2629         ectx = NULL;
2630         nfails = 0;
2631
2632         t_info("testing using file %s and name %s\n", filename, newname);
2633
2634         isc_result = isc_mem_create(0, 0, &mctx);
2635         if (isc_result != ISC_R_SUCCESS) {
2636                 t_info("isc_mem_create failed %s\n",
2637                                 isc_result_totext(isc_result));
2638                 return(T_UNRESOLVED);
2639         }
2640
2641         isc_result = isc_entropy_create(mctx, &ectx);
2642         if (isc_result != ISC_R_SUCCESS) {
2643                 t_info("isc_entropy_create failed %s\n",
2644                                 isc_result_totext(isc_result));
2645                 return(T_UNRESOLVED);
2646         }
2647
2648         isc_result = isc_hash_create(mctx, ectx, DNS_NAME_MAXWIRE);
2649         if (isc_result != ISC_R_SUCCESS) {
2650                 t_info("isc_hash_create failed %s\n",
2651                                 isc_result_totext(isc_result));
2652                 return(T_UNRESOLVED);
2653         }
2654
2655         dns_result = t_create(db_type, origin, class, model, mctx, &db);
2656         if (dns_result != ISC_R_SUCCESS) {
2657                 isc_hash_destroy();
2658                 isc_entropy_detach(&ectx);
2659                 isc_mem_destroy(&mctx);
2660                 return(T_UNRESOLVED);
2661         }
2662
2663         dns_result = dns_db_load(db, filename);
2664         if (dns_result != ISC_R_SUCCESS) {
2665                 t_info("dns_db_load returned %s\n",
2666                                 dns_result_totext(dns_result));
2667                 dns_db_detach(&db);
2668                 isc_hash_destroy();
2669                 isc_entropy_detach(&ectx);
2670                 isc_mem_destroy(&mctx);
2671                 return(T_UNRESOLVED);
2672         }
2673
2674         nodep = NULL;
2675         dns_fixedname_init(&dns_name);
2676
2677         /*
2678          * Make sure the name isn't there
2679          */
2680         len = strlen(newname);
2681         isc_buffer_init(&name_buffer, newname, len);
2682         isc_buffer_add(&name_buffer, len);
2683         dns_result = dns_name_fromtext(dns_fixedname_name(&dns_name),
2684                                        &name_buffer, NULL, 0, NULL);
2685
2686         dns_result = dns_db_findnode(db, dns_fixedname_name(&dns_name),
2687                                      ISC_FALSE, &nodep);
2688         if ((dns_result != ISC_R_NOTFOUND) &&
2689             (dns_result != DNS_R_NXDOMAIN) &&
2690             (dns_result != DNS_R_NXRRSET)) {
2691                 t_info("dns_db_findnode %s\n",
2692                        dns_result_totext(dns_result));
2693                 dns_db_detachnode(db, &nodep);
2694                 dns_db_detach(&db);
2695                 isc_hash_destroy();
2696                 isc_entropy_detach(&ectx);
2697                 isc_mem_destroy(&mctx);
2698                 return(T_UNRESOLVED);
2699         }
2700
2701         /*
2702          * Add it.
2703          */
2704         dns_result = dns_db_findnode(db, dns_fixedname_name(&dns_name),
2705                                 ISC_TRUE, &nodep);
2706         if (dns_result != ISC_R_SUCCESS) {
2707                 t_info("dns_db_findnode %s\n",
2708                                 dns_result_totext(dns_result));
2709                 dns_db_detach(&db);
2710                 isc_hash_destroy();
2711                 isc_entropy_detach(&ectx);
2712                 isc_mem_destroy(&mctx);
2713                 return(T_FAIL);
2714         }
2715
2716         /*
2717          * Check it.
2718          */
2719         newnodep = NULL;
2720         dns_rdataset_init(&rdataset);
2721         dns_fixedname_init(&dns_foundname);
2722         cversionp = NULL;
2723         dns_db_currentversion(db, &cversionp);
2724
2725         /*
2726          * First try dns_db_find DNS_R_NXDOMAIN.
2727          */
2728         dns_result = dns_db_find(db,
2729                         dns_fixedname_name(&dns_name),
2730                         cversionp,
2731                         dns_rdatatype_any,
2732                         0,
2733                         0,
2734                         &newnodep,
2735                         dns_fixedname_name(&dns_foundname),
2736                         &rdataset, NULL);
2737         if ((dns_result != ISC_R_NOTFOUND) && (dns_result != DNS_R_NXDOMAIN)) {
2738                 dns_db_detachnode(db, &newnodep);
2739         }
2740
2741         if (dns_result != DNS_R_NXDOMAIN) {
2742                 t_info("dns_db_find %s\n",
2743                                 dns_result_totext(dns_result));
2744                 ++nfails;
2745         }
2746
2747         /*
2748          * Then try dns_db_findnode ISC_R_SUCCESS.
2749          */
2750         dns_result = dns_db_findnode(db, dns_fixedname_name(&dns_name),
2751                                      ISC_FALSE, &newnodep);
2752         t_info("dns_db_findnode %s\n", dns_result_totext(dns_result));
2753         if (dns_result == ISC_R_SUCCESS) {
2754                 dns_db_detachnode(db, &newnodep);
2755         } else {
2756                 t_info("dns_db_findnode %s failed %s\n", newname,
2757                                 dns_result_totext(dns_result));
2758                 ++nfails;
2759         }
2760
2761
2762         dns_db_detachnode(db, &nodep);
2763         dns_db_closeversion(db, &cversionp, ISC_FALSE);
2764         dns_db_detach(&db);
2765         isc_hash_destroy();
2766         isc_entropy_detach(&ectx);
2767         isc_mem_destroy(&mctx);
2768
2769         if (nfails == 0)
2770                 result = T_PASS;
2771         else
2772                 result = T_FAIL;
2773
2774         return(result);
2775 }
2776
2777 static void
2778 t14(void) {
2779         int     result;
2780
2781         t_assert("dns_db_findnode", 14, T_REQUIRED, "%s", a14);
2782         result = t_eval("dns_db_findnode_2_data", t_dns_db_findnode_2, 6);
2783         t_result(result);
2784 }
2785
2786 static int
2787 t_dns_db_find_x(char **av) {
2788         char                    *dbfile;
2789         char                    *dbtype;
2790         char                    *dborigin;
2791         char                    *dbclass;
2792         char                    *dbmodel;
2793         char                    *findname;
2794         char                    *findtype;
2795         char                    *findopts;
2796         char                    *findtime;
2797         char                    *expected_result;
2798
2799         int                     result;
2800         int                     len;
2801         int                     opts;
2802         dns_db_t                *db;
2803         isc_result_t            dns_result;
2804         isc_result_t            isc_result;
2805         isc_stdtime_t           ftime;
2806         isc_stdtime_t           now;
2807         isc_result_t            exp_result;
2808         isc_mem_t               *mctx;
2809         isc_entropy_t           *ectx;
2810         dns_dbnode_t            *nodep;
2811         isc_textregion_t        textregion;
2812         isc_buffer_t            findname_buffer;
2813         dns_fixedname_t         dns_findname;
2814         dns_fixedname_t         dns_foundname;
2815         dns_rdataset_t          rdataset;
2816         dns_rdatatype_t         rdatatype;
2817         dns_dbversion_t         *cversionp;
2818
2819         result = T_UNRESOLVED;
2820
2821         dbfile = T_ARG(0);
2822         dbtype = T_ARG(1);
2823         dborigin = T_ARG(2);
2824         dbclass = T_ARG(3);
2825         dbmodel = T_ARG(4);
2826         findname = T_ARG(5);
2827         findtype = T_ARG(6);
2828         findopts = T_ARG(7);
2829         findtime = T_ARG(8);
2830         expected_result = T_ARG(9);
2831         db = NULL;
2832         mctx = NULL;
2833         ectx = NULL;
2834         opts = 0;
2835
2836         t_info("testing using %s, name %s, type %s\n", dbfile, findname,
2837                findtype);
2838
2839         isc_result = isc_mem_create(0, 0, &mctx);
2840         if (isc_result != ISC_R_SUCCESS) {
2841                 t_info("isc_mem_create failed %s\n",
2842                                 isc_result_totext(isc_result));
2843                 return(T_UNRESOLVED);
2844         }
2845
2846         isc_result = isc_entropy_create(mctx, &ectx);
2847         if (isc_result != ISC_R_SUCCESS) {
2848                 t_info("isc_entropy_create failed %s\n",
2849                                 isc_result_totext(isc_result));
2850                 isc_mem_destroy(&mctx);
2851                 return(T_UNRESOLVED);
2852         }
2853
2854         isc_result = isc_hash_create(mctx, ectx, DNS_NAME_MAXWIRE);
2855         if (isc_result != ISC_R_SUCCESS) {
2856                 t_info("isc_hash_create failed %s\n",
2857                                 isc_result_totext(isc_result));
2858                 isc_entropy_detach(&ectx);
2859                 isc_mem_destroy(&mctx);
2860                 return(T_UNRESOLVED);
2861         }
2862
2863         dns_result = t_create(dbtype, dborigin, dbclass, dbmodel, mctx, &db);
2864         if (dns_result != ISC_R_SUCCESS) {
2865                 isc_hash_destroy();
2866                 isc_entropy_detach(&ectx);
2867                 isc_mem_destroy(&mctx);
2868                 return(T_UNRESOLVED);
2869         }
2870
2871         dns_result = dns_db_load(db, dbfile);
2872         if (dns_result != ISC_R_SUCCESS) {
2873                 t_info("dns_db_load returned %s\n",
2874                                 dns_result_totext(dns_result));
2875                 dns_db_detach(&db);
2876                 isc_hash_destroy();
2877                 isc_entropy_detach(&ectx);
2878                 isc_mem_destroy(&mctx);
2879                 return(T_UNRESOLVED);
2880         }
2881
2882         exp_result = t_dns_result_fromtext(expected_result);
2883
2884         dns_fixedname_init(&dns_findname);
2885         len = strlen(findname);
2886         isc_buffer_init(&findname_buffer, findname, len);
2887         isc_buffer_add(&findname_buffer, len);
2888         dns_result = dns_name_fromtext(dns_fixedname_name(&dns_findname),
2889                                 &findname_buffer, NULL, 0, NULL);
2890         if (dns_result != ISC_R_SUCCESS) {
2891                 t_info("dns_name_fromtext failed %s\n",
2892                         dns_result_totext(dns_result));
2893                 dns_db_detach(&db);
2894                 isc_hash_destroy();
2895                 isc_entropy_detach(&ectx);
2896                 isc_mem_destroy(&mctx);
2897                 return(T_UNRESOLVED);
2898         }
2899
2900         textregion.base = findtype;
2901         textregion.length = strlen(findtype);
2902         dns_result = dns_rdatatype_fromtext(&rdatatype, &textregion);
2903         if (dns_result != ISC_R_SUCCESS) {
2904                 t_info("dns_rdatatype_fromtext %s failed %s\n",
2905                                 findtype,
2906                                 dns_result_totext(dns_result));
2907                 dns_db_detach(&db);
2908                 isc_hash_destroy();
2909                 isc_entropy_detach(&ectx);
2910                 isc_mem_destroy(&mctx);
2911                 return(T_UNRESOLVED);
2912         }
2913
2914         if (strstr(findopts, "DNS_DBFIND_GLUEOK"))
2915                 opts |= DNS_DBFIND_GLUEOK;
2916         if (strstr(findopts, "DNS_DBFIND_VALIDATEGLUE"))
2917                 opts |= DNS_DBFIND_VALIDATEGLUE;
2918
2919         isc_stdtime_get(&now);
2920
2921         ftime = strtol(findtime, NULL, 10);
2922         if (ftime != 0)
2923                 ftime += now;
2924
2925         cversionp = NULL;
2926         dns_fixedname_init(&dns_foundname);
2927         dns_rdataset_init(&rdataset);
2928         if (dns_db_iszone(db))
2929                 dns_db_currentversion(db, &cversionp);
2930         nodep = NULL;
2931
2932         dns_result = dns_db_find(db,
2933                         dns_fixedname_name(&dns_findname),
2934                         cversionp,
2935                         rdatatype,
2936                         opts,
2937                         ftime,
2938                         &nodep,
2939                         dns_fixedname_name(&dns_foundname),
2940                         &rdataset, NULL);
2941
2942         if (dns_result != exp_result) {
2943                 t_info("dns_db_find %s %s unexpectedly returned %s, "
2944                        "expected %s\n",
2945                        findname, findtype, dns_result_totext(dns_result),
2946                        dns_result_totext(exp_result));
2947                 result = T_FAIL;
2948         } else {
2949                 result = T_PASS;
2950         }
2951
2952         if ((dns_result != ISC_R_NOTFOUND) && (dns_result != DNS_R_NXDOMAIN)) {
2953
2954                 if ((dns_result != DNS_R_NXRRSET) &&
2955                     (dns_result != DNS_R_ZONECUT))
2956                         if (dns_rdataset_isassociated(&rdataset))
2957                                 dns_rdataset_disassociate(&rdataset);
2958                 dns_db_detachnode(db, &nodep);
2959         }
2960
2961         if (dns_db_iszone(db))
2962                 dns_db_closeversion(db, &cversionp, ISC_FALSE);
2963         dns_db_detach(&db);
2964         isc_hash_destroy();
2965         isc_entropy_detach(&ectx);
2966         isc_mem_destroy(&mctx);
2967
2968         return(result);
2969 }
2970
2971 static const char *a15 =
2972         "A call to dns_db_find(db, name, version, type, options, now, ...)  "
2973         "finds the best match for 'name' and 'type' in version 'version' "
2974         "of 'db'.";
2975
2976 static void
2977 t15(void) {
2978         int     result;
2979
2980         t_assert("dns_db_find", 15, T_REQUIRED, "%s", a15);
2981         result = t_eval("dns_db_find_1_data", t_dns_db_find_x, 10);
2982         t_result(result);
2983 }
2984
2985
2986 static const char *a16 =
2987         "When the desired node and type were found, but are glue, "
2988         "and the DNS_DBFIND_GLUEOK option is set, a call to "
2989         "dns_db_find(db, name, version, type, options, now, ...)  "
2990         "returns DNS_R_GLUE.";
2991
2992 static void
2993 t16(void) {
2994         int     result;
2995
2996         t_assert("dns_db_find", 16, T_REQUIRED, "%s", a16);
2997         result = t_eval("dns_db_find_2_data", t_dns_db_find_x, 10);
2998         t_result(result);
2999 }
3000
3001 static const char *a17 =
3002         "A call to dns_db_find() returns DNS_R_DELEGATION when the data "
3003         "requested is beneath a zone cut.";
3004
3005 static void
3006 t17(void) {
3007         int     result;
3008
3009         t_assert("dns_db_find", 17, T_REQUIRED, "%s", a17);
3010         result = t_eval("dns_db_find_3_data", t_dns_db_find_x, 10);
3011         t_result(result);
3012 }
3013
3014 static const char *a18 =
3015         "A call to dns_db_find() returns DNS_R_DELEGATION when type is "
3016         "dns_rdatatype_any and the desired node is a zone cut.";
3017
3018 static void
3019 t18(void) {
3020         int     result;
3021
3022         t_assert("dns_db_find", 18, T_REQUIRED, "%s", a18);
3023         result = t_eval("dns_db_find_4_data", t_dns_db_find_x, 10);
3024         t_result(result);
3025 }
3026
3027 static const char *a19 =
3028         "A call to dns_db_find() returns DNS_R_DNAME when the data "
3029         "requested is beneath a DNAME.";
3030
3031 static void
3032 t19(void) {
3033         int     result;
3034
3035         t_assert("dns_db_find", 19, T_REQUIRED, "%s", a19);
3036         result = t_eval("dns_db_find_5_data", t_dns_db_find_x, 10);
3037         t_result(result);
3038 }
3039
3040 static const char *a20 =
3041         "A call to dns_db_find() returns DNS_R_CNAME when the requested "
3042         "rdataset was not found but there is a CNAME at the desired name.";
3043
3044 static void
3045 t20(void) {
3046         int     result;
3047
3048         t_assert("dns_db_find", 20, T_REQUIRED, "%s", a20);
3049         result = t_eval("dns_db_find_6_data", t_dns_db_find_x, 10);
3050         t_result(result);
3051 }
3052
3053 static const char *a21 =
3054         "A call to dns_db_find() returns DNS_R_NXDOMAIN when name "
3055         "does not exist.";
3056
3057 static void
3058 t21(void) {
3059         int     result;
3060
3061         t_assert("dns_db_find", 21, T_REQUIRED, "%s", a21);
3062         result = t_eval("dns_db_find_7_data", t_dns_db_find_x, 10);
3063         t_result(result);
3064 }
3065
3066 static const char *a22 =
3067         "A call to dns_db_find() returns DNS_R_NXRRSET when "
3068         "the desired name exists, but the desired type does not.";
3069
3070 static void
3071 t22(void) {
3072         int     result;
3073
3074         t_assert("dns_db_find", 22, T_REQUIRED, "%s", a22);
3075         result = t_eval("dns_db_find_8_data", t_dns_db_find_x, 10);
3076         t_result(result);
3077 }
3078
3079 static const char *a23 =
3080         "When db is a cache database, a call to dns_db_find() "
3081         "returns ISC_R_NOTFOUND when the desired name does not exist, "
3082         "and no delegation could be found.";
3083
3084 static void
3085 t23(void) {
3086         int     result;
3087
3088         t_assert("dns_db_find", 23, T_REQUIRED, "%s", a23);
3089         result = t_eval("dns_db_find_9_data", t_dns_db_find_x, 10);
3090         t_result(result);
3091 }
3092
3093 static const char *a24 =
3094         "When db is a cache database, an rdataset will be found only "
3095         "if at least one rdataset at the found node expires after 'now'.";
3096
3097 static void
3098 t24(void) {
3099         int     result;
3100
3101         t_assert("dns_db_find", 24, T_REQUIRED, "%s", a24);
3102         result = t_eval("dns_db_find_10_data", t_dns_db_find_x, 10);
3103         t_result(result);
3104 }
3105
3106 static const char *a25 =
3107         "A call to dns_db_load(db, filename) returns DNS_R_NOTZONETOP "
3108         "when the zone data contains a SOA not at the zone apex.";
3109
3110 static void
3111 t25(void) {
3112         int     result;
3113
3114         t_assert("dns_db_load", 25, T_REQUIRED, "%s", a25);
3115         result = t_eval("dns_db_load_soa_not_top", t_dns_db_load, 9);
3116         t_result(result);
3117 }
3118
3119 testspec_t      T_testlist[] = {
3120         {       t1,             "dns_db_load"           },
3121         {       t2,             "dns_db_iscache"        },
3122         {       t3,             "dns_db_iscache"        },
3123         {       t4,             "dns_db_iszone"         },
3124         {       t5,             "dns_db_iszone"         },
3125         {       t6,             "dns_db_origin"         },
3126         {       t7,             "dns_db_class"          },
3127         {       t8,             "dns_db_currentversion" },
3128         {       t9,             "dns_db_newversion"     },
3129         {       t10,            "dns_db_closeversion"   },
3130         {       t11,            "dns_db_closeversion"   },
3131         {       t12,            "dns_db_expirenode"     },
3132         {       t13,            "dns_db_findnode"       },
3133         {       t14,            "dns_db_findnode"       },
3134         {       t15,            "dns_db_find"           },
3135         {       t16,            "dns_db_find"           },
3136         {       t17,            "dns_db_find"           },
3137         {       t18,            "dns_db_find"           },
3138         {       t19,            "dns_db_find"           },
3139         {       t20,            "dns_db_find"           },
3140         {       t21,            "dns_db_find"           },
3141         {       t22,            "dns_db_find"           },
3142         {       t23,            "dns_db_find"           },
3143         {       t24,            "dns_db_find"           },
3144         {       t25,            "dns_db_load"           },
3145         {       NULL,           NULL                    }
3146 };