t_rbt.c revision 0c27b3fe77ac1d5094ba3521e8142d9e7973133f
/*
* Copyright (C) 1998-2001, 2003-2005, 2007, 2009, 2011-2013, 2015, 2016 Internet Systems Consortium, Inc. ("ISC")
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
/* $Id: t_rbt.c,v 1.35 2011/03/12 04:59:46 tbox Exp $ */
#include <config.h>
#include <ctype.h>
#include <stdlib.h>
#include <dns/fixedname.h>
#define BUFLEN 1024
#define DNSNAMELEN 255
char *progname;
static int
char *firstname, char *firstorigin,
char *nextname, char *nextorigin,
char *prevname, char *prevorigin,
char *lastname, char *lastorigin);
static char *
static int
static char *
static int
/*
* Parts adapted from the original rbt_test.c.
*/
static int
char *name;
return(0);
return(1);
} else {
}
}
static char *
}
static char *
}
#ifdef NEED_PRINT_DATA
static isc_result_t
print_data(void *data) {
char *buffer[DNSNAMELEN];
if (dns_result != ISC_R_SUCCESS) {
t_info("dns_name_totext failed %s\n",
}
return(dns_result);
}
#endif /* NEED_PRINT_DATA */
static int
int nfails;
int length;
nfails = 0;
if (s && *s) {
/*
* The buffer for the actual name will immediately follow the
* name structure.
*/
t_info("isc_mem_get failed\n");
++nfails;
} else {
0, &target);
if (result != ISC_R_SUCCESS) {
++nfails;
t_info("dns_name_fromtext(%s) failed %s\n",
s, dns_result_totext(result));
sizeof(*name) + DNSNAMELEN);
} else
}
} else {
++nfails;
t_info("create_name: empty name\n");
}
return(nfails);
}
static void
}
/*
* Adapted from the original rbt_test.c.
*/
static int
int nprobs;
nprobs = 0;
if (name && dns_result) {
if (T_debug)
t_info("dns_rbt_addname succeeded\n");
if (*dns_result != ISC_R_SUCCESS) {
t_info("dns_rbt_addname failed %s\n",
++nprobs;
}
} else {
++nprobs;
}
} else {
++nprobs;
}
return(nprobs);
}
static int
{
int nprobs;
nprobs = 0;
if (name && dns_result) {
} else {
++nprobs;
}
} else {
++nprobs;
}
return(nprobs);
}
static int
{
int nprobs;
void *data;
nprobs = 0;
if (name && dns_result) {
dns_foundname, &data);
} else {
++nprobs;
}
} else {
++nprobs;
}
return(nprobs);
}
/*
* Initialize a database from filename.
*/
static int
int rval;
char *p;
return(1);
}
if (dns_result != ISC_R_SUCCESS) {
t_info("dns_rbt_create failed %s\n",
return(1);
}
/*
* Skip any comment lines.
*/
if ((*p == '#') || (*p == '\0') || (*p == ' ')) {
(void)free(p);
continue;
}
if (T_debug)
t_info("adding name %s to the rbt\n", p);
t_info("add of %s failed\n", p);
(void) free(p);
return(1);
}
(void) free(p);
}
return(0);
}
static int
{
int rval;
int result;
if (isc_result != ISC_R_SUCCESS) {
t_info("isc_mem_create: %s: exiting\n",
return(T_UNRESOLVED);
}
if (isc_result != ISC_R_SUCCESS) {
t_info("isc_entropy_create: %s: exiting\n",
return(T_UNRESOLVED);
}
if (isc_result != ISC_R_SUCCESS) {
t_info("isc_hash_create: %s: exiting\n",
return(T_UNRESOLVED);
}
return(result);
}
/*
* Now try the database command.
*/
if (dns_result != ISC_R_SUCCESS)
if (dns_result == exp_result) {
if (dns_result == ISC_R_SUCCESS) {
&dns_result);
if (rval == 0) {
if (dns_result == ISC_R_SUCCESS) {
} else {
}
} else {
t_info("t1_search failed\n");
}
} else {
}
} else {
t_info("dns_rbt_addname returned %s, "
"expected %s\n",
}
} else {
t_info("create_name failed\n");
}
if (rval == 0) {
if (dns_result == exp_result) {
&dns_result);
if (rval == 0) {
if (dns_result == ISC_R_SUCCESS) {
t_info("dns_rbt_deletename "
"didn't delete "
"the name");
} else {
}
}
} else {
t_info("delete returned %s, expected %s\n",
}
}
if (rval == 0) {
if (dns_result == exp_result) {
} else {
t_info("find returned %s, expected %s\n",
}
}
}
return(result);
}
static int
test_dns_rbt_x(const char *filename) {
char *p;
int line;
int cnt;
int result;
int nfails;
int nprobs;
nfails = 0;
nprobs = 0;
line = 0;
++line;
/*
* Skip comment lines.
*/
if ((isspace((unsigned char)*p)) || (*p == '#')) {
(void)free(p);
continue;
}
/*
* Name of db file, command, testname,
* expected result.
*/
if (cnt == 4) {
Tokens[2],
++nfails;
} else {
t_info("bad format in %s at line %d\n",
++nprobs;
}
(void)free(p);
}
} else {
++nprobs;
}
else if (nfails)
return(result);
}
static const char *a1 = "dns_rbt_create creates a rbt and returns "
"ISC_R_SUCCESS on success";
static void
t1() {
int result;
}
static const char *a2 = "dns_rbt_addname adds a name to a database and "
"returns ISC_R_SUCCESS on success";
static void
t2() {
int result;
}
static const char *a3 = "when name already exists, dns_rbt_addname() "
"returns ISC_R_EXISTS";
static void
t3() {
int result;
}
static const char *a4 = "when name exists, dns_rbt_deletename() returns "
"ISC_R_SUCCESS";
static void
t4() {
int result;
}
static const char *a5 = "when name does not exist, dns_rbt_deletename() "
"returns ISC_R_NOTFOUND";
static void
t5() {
int result;
}
static const char *a6 = "when name exists and exactly matches the "
"search name dns_rbt_findname() returns ISC_R_SUCCESS";
static void
t6() {
int result;
}
static const char *a7 = "when a name does not exist, "
"dns_rbt_findname returns ISC_R_NOTFOUND";
static void
t7() {
int result;
}
static const char *a8 = "when a superdomain is found with data matching name, "
"dns_rbt_findname returns DNS_R_PARTIALMATCH";
static void
t8() {
int result;
}
static const char *a9 = "a call to dns_rbtnodechain_init(chain, mctx) "
"initializes chain";
static int
int cnt;
int order;
unsigned int nlabels;
int nprobs;
cnt = 0;
nprobs = 0;
do {
if (cnt == 0) {
if (dns_result != DNS_R_NEWORIGIN) {
t_info("dns_rbtnodechain_first returned %s, "
"expecting DNS_R_NEWORIGIN\n",
++nprobs;
break;
}
t_info("first origin:\t<%s>\n",
} else {
if (dns_result != ISC_R_SUCCESS) {
t_info("dns_name_concatenate failed %s\n",
++nprobs;
break;
}
/*
* Expecting origin not to get touched if next
* doesn't return NEWORIGIN.
*/
if ((dns_result != ISC_R_SUCCESS) &&
(dns_result != DNS_R_NEWORIGIN)) {
if (dns_result != ISC_R_NOMORE) {
t_info("dns_rbtnodechain_next "
"failed %s\n",
++nprobs;
}
break;
}
t_info("next origin:\t<%s>\n",
if (dns_result != ISC_R_SUCCESS) {
t_info("dns_name_concatenate failed %s\n",
++nprobs;
break;
}
t_info("comparing\t<%s>\n",
(void)dns_name_fullcompare(
if (order >= 0) {
t_info("unexpected order %s %s %s\n",
++nprobs;
}
}
++cnt;
} while (1);
return (nprobs);
}
/*
* Test by exercising the first|last|next|prev funcs in useful ways.
*/
static int
{
int nfails;
nfails = 0;
t_info("\texpected name of %s, got %s\n",
++nfails;
}
if (exp_origin != NULL) {
t_info("checking for DNS_R_NEWORIGIN\n");
if (dns_result == exp_result) {
t_info("\torigin %s, expected %s\n",
++nfails;
}
} else {
++nfails;
}
}
return(nfails);
}
static int
char *nextname, char *nextorigin,
char *prevname, char *prevorigin,
char *firstname, char *firstorigin,
char *lastname, char *lastorigin)
{
int result;
int len;
int nfails;
nfails = 0;
if (isc_result != ISC_R_SUCCESS) {
t_info("isc_mem_create failed %s\n",
return(result);
}
if (isc_result != ISC_R_SUCCESS) {
t_info("isc_entropy_create: %s: exiting\n",
return(T_UNRESOLVED);
}
if (isc_result != ISC_R_SUCCESS) {
t_info("isc_hash_create: %s: exiting\n",
return(T_UNRESOLVED);
}
return(result);
}
if (dns_result != ISC_R_SUCCESS) {
t_info("dns_name_fromtext failed %s\n",
return(result);
}
/*
* Set the starting node.
*/
if (dns_result != ISC_R_SUCCESS) {
t_info("dns_rbt_findnode failed %s\n",
return(result);
}
/*
* Check next.
*/
t_info("checking for next name of %s and new origin of %s\n",
if ((dns_result != ISC_R_SUCCESS) &&
(dns_result != DNS_R_NEWORIGIN)) {
t_info("dns_rbtnodechain_next unexpectedly returned %s\n",
}
/*
* Set the starting node again.
*/
if (dns_result != ISC_R_SUCCESS) {
t_info("\tdns_rbt_findnode failed %s\n",
return(result);
}
/*
* Check previous.
*/
t_info("checking for previous name of %s and new origin of %s\n",
if ((dns_result != ISC_R_SUCCESS) &&
(dns_result != DNS_R_NEWORIGIN)) {
t_info("dns_rbtnodechain_prev unexpectedly returned %s\n",
}
/*
* Check first.
*/
t_info("checking for first name of %s and new origin of %s\n",
if (dns_result != DNS_R_NEWORIGIN) {
t_info("dns_rbtnodechain_first unexpectedly returned %s\n",
}
/*
* Check last.
*/
if (dns_result != DNS_R_NEWORIGIN) {
t_info("dns_rbtnodechain_last unexpectedly returned %s\n",
}
/*
* Check node ordering.
*/
t_info("checking node ordering\n");
if (nfails)
else
return(result);
}
static int
test_dns_rbtnodechain_init(const char *filename) {
char *p;
int line;
int cnt;
int result;
int nfails;
int nprobs;
nfails = 0;
nprobs = 0;
line = 0;
++line;
/*
* Skip comment lines.
*/
if ((isspace((unsigned char)*p)) || (*p == '#')) {
(void)free(p);
continue;
}
if (cnt == 10) {
Tokens[0], /* dbfile */
++nfails;
else
++nprobs;
}
} else {
t_info("bad format in %s at line %d\n",
++nprobs;
}
(void)free(p);
}
} else {
++nprobs;
}
else if (nfails)
return(result);
}
static void
t9() {
int result;
}
static int
char *expected_firstorigin,
char *expected_nextname,
char *expected_nextorigin)
{
int result;
int nfails;
nfails = 0;
if (isc_result != ISC_R_SUCCESS) {
t_info("isc_mem_create failed %s\n",
return(result);
}
if (isc_result != ISC_R_SUCCESS) {
t_info("isc_entropy_create: %s: exiting\n",
return(T_UNRESOLVED);
}
if (isc_result != ISC_R_SUCCESS) {
t_info("isc_hash_create: %s: exiting\n",
return(T_UNRESOLVED);
}
return(result);
}
t_info("testing for first name of %s, origin of %s\n",
if (dns_result != DNS_R_NEWORIGIN)
t_info("dns_rbtnodechain_first unexpectedly returned %s\n",
t_info("testing for next name of %s, origin of %s\n",
t_info("dns_rbtnodechain_next unexpectedly returned %s\n",
else
if (nfails)
else
return(result);
}
static int
test_dns_rbtnodechain_first(const char *filename) {
char *p;
int line;
int cnt;
int result;
int nfails;
int nprobs;
nfails = 0;
nprobs = 0;
line = 0;
++line;
/*
* Skip comment lines.
*/
if ((isspace((unsigned char)*p)) || (*p == '#')) {
(void)free(p);
continue;
}
if (cnt == 5) {
Tokens[0], /* dbfile */
++nfails;
else
++nprobs;
}
} else {
t_info("bad format in %s at line %d\n",
++nprobs;
}
(void)free(p);
}
} else {
++nprobs;
}
else if (nfails)
return(result);
}
static const char *a10 = "a call to "
"dns_rbtnodechain_first(chain, rbt, name, origin) "
"sets name to point to the root of the tree, "
"origin to point to the origin, "
"and returns DNS_R_NEWORIGIN";
static void
t10() {
int result;
}
static int
char *expected_lastorigin,
char *expected_prevname,
char *expected_prevorigin)
{
int result;
int nfails;
nfails = 0;
if (isc_result != ISC_R_SUCCESS) {
t_info("isc_mem_create failed %s\n",
return(result);
}
if (isc_result != ISC_R_SUCCESS) {
t_info("isc_entropy_create: %s: exiting\n",
return(T_UNRESOLVED);
}
if (isc_result != ISC_R_SUCCESS) {
t_info("isc_hash_create: %s: exiting\n",
return(T_UNRESOLVED);
}
return(result);
}
t_info("testing for last name of %s, origin of %s\n",
if (dns_result != DNS_R_NEWORIGIN) {
t_info("dns_rbtnodechain_last unexpectedly returned %s\n",
}
t_info("testing for previous name of %s, origin of %s\n",
if ((dns_result != ISC_R_SUCCESS) &&
(dns_result != DNS_R_NEWORIGIN)) {
t_info("dns_rbtnodechain_prev unexpectedly returned %s\n",
}
else
if (nfails)
else
return(result);
}
static int
test_dns_rbtnodechain_last(const char *filename) {
char *p;
int line;
int cnt;
int result;
int nfails;
int nprobs;
nfails = 0;
nprobs = 0;
line = 0;
++line;
/*
* Skip comment lines.
*/
if ((isspace((unsigned char)*p)) || (*p == '#')) {
(void)free(p);
continue;
}
if (cnt == 5) {
Tokens[0], /* dbfile */
++nfails;
else
++nprobs;
}
} else {
t_info("bad format in %s at line %d\n",
++nprobs;
}
(void)free(p);
}
} else {
++nprobs;
}
else if (nfails)
return(result);
}
static const char *a11 = "a call to "
"dns_rbtnodechain_last(chain, rbt, name, origin) "
"sets name to point to the last node of the megatree, "
"origin to the name of the level above it, "
"and returns DNS_R_NEWORIGIN";
static void
t11() {
int result;
}
static int
char *nextname, char *nextorigin)
{
int result;
int len;
int nfails;
nfails = 0;
if (isc_result != ISC_R_SUCCESS) {
t_info("isc_mem_create failed %s\n",
return(result);
}
if (isc_result != ISC_R_SUCCESS) {
t_info("isc_entropy_create: %s: exiting\n",
return(T_UNRESOLVED);
}
if (isc_result != ISC_R_SUCCESS) {
t_info("isc_hash_create: %s: exiting\n",
return(T_UNRESOLVED);
}
return(result);
}
if (dns_result != ISC_R_SUCCESS) {
t_info("dns_name_fromtext failed %s\n",
return(result);
}
/*
* Set the starting node.
*/
if (dns_result != ISC_R_SUCCESS) {
t_info("dns_rbt_findnode failed %s\n",
return(result);
}
/*
* Check next.
*/
t_info("checking for next name of %s and new origin of %s\n",
t_info("dns_rbtnodechain_next unexpectedly returned %s\n",
}
if (nfails)
else
return(result);
}
static int
test_dns_rbtnodechain_next(const char *filename) {
char *p;
int line;
int cnt;
int result;
int nfails;
int nprobs;
nfails = 0;
nprobs = 0;
line = 0;
++line;
/*
* Skip comment lines.
*/
if ((isspace((unsigned char)*p)) || (*p == '#')) {
(void)free(p);
continue;
}
if (cnt == 4) {
Tokens[0], /* dbfile */
++nfails;
else
++nprobs;
}
} else {
t_info("bad format in %s at line %d\n",
++nprobs;
}
(void)free(p);
}
} else {
++nprobs;
}
else if (nfails)
return(result);
}
static const char *a12 = "a call to "
"dns_rbtnodechain_next(chain, name, origin) "
"sets name to point to the next node of the tree "
"and returns ISC_R_SUCCESS or "
"DNS_R_NEWORIGIN on success";
static void
t12() {
int result;
}
static int
char *prevorigin)
{
int result;
int len;
int nfails;
nfails = 0;
if (isc_result != ISC_R_SUCCESS) {
t_info("isc_mem_create failed %s\n",
return(result);
}
if (isc_result != ISC_R_SUCCESS) {
t_info("isc_entropy_create: %s: exiting\n",
return(T_UNRESOLVED);
}
if (isc_result != ISC_R_SUCCESS) {
t_info("isc_hash_create: %s: exiting\n",
return(T_UNRESOLVED);
}
return(result);
}
if (dns_result != ISC_R_SUCCESS) {
t_info("dns_name_fromtext failed %s\n",
return(result);
}
/*
* Set the starting node.
*/
if (dns_result != ISC_R_SUCCESS) {
t_info("dns_rbt_findnode failed %s\n",
return(result);
}
/*
* Check next.
*/
t_info("checking for next name of %s and new origin of %s\n",
t_info("dns_rbtnodechain_prev unexpectedly returned %s\n",
}
if (nfails)
else
return(result);
}
static int
test_dns_rbtnodechain_prev(const char *filename) {
char *p;
int line;
int cnt;
int result;
int nfails;
int nprobs;
nfails = 0;
nprobs = 0;
line = 0;
++line;
/*
* Skip comment lines.
*/
if ((isspace((unsigned char)*p)) || (*p == '#')) {
(void)free(p);
continue;
}
if (cnt == 4) {
Tokens[0], /* dbfile */
++nfails;
else
++nprobs;
}
} else {
t_info("bad format in %s at line %d\n",
++nprobs;
}
(void)free(p);
}
} else {
++nprobs;
}
else if (nfails)
return(result);
}
static const char *a13 = "a call to "
"dns_rbtnodechain_prev(chain, name, origin) "
"sets name to point to the previous node of the tree "
"and returns ISC_R_SUCCESS or "
"DNS_R_NEWORIGIN on success";
static void
t13() {
int result;
}
testspec_t T_testlist[] = {
};
#ifdef WIN32
int
}
#endif