t_api.c revision dafcb997e390efa4423883dafd100c975c4095d6
/*
* Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 1999-2003 Internet Software Consortium.
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
* REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
* INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
* LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
* OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
* PERFORMANCE OF THIS SOFTWARE.
*/
/* $Id: t_api.c,v 1.52 2004/03/05 05:13:39 marka Exp $ */
#include <config.h>
#include <ctype.h>
#include <errno.h>
#include <limits.h>
#include <signal.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <unistd.h>
#include <isc/commandline.h>
#include <dns/compress.h>
static const char *Usage =
"\t-a : run all tests\n"
"\t-b <dir> : chdir to dir before running tests"
"\t-c <config_file> : use specified config file\n"
"\t-d <debug_level> : set debug level to debug_level\n"
"\t-h : print test info\n"
"\t-u : print usage info\n"
"\t-n <test_name> : run specified test name\n"
"\t-t <test_number> : run specified test number\n"
"\t-x : don't execute tests in a subproc\n"
"\t-q <timeout> : use 'timeout' as the timeout value\n";
/*
* -a --> run all tests
* -b dir --> chdir to dir before running tests
* -c config --> use config file 'config'
* -d --> turn on api debugging
* -h --> print out available test names
* -u --> print usage info
* -n name --> run test named name
* -tn --> run test n
* -x --> don't execute testcases in a subproc
* -q timeout --> use 'timeout' as the timeout value
*/
#define T_MAXENV 256
#define T_DEFAULT_CONFIG "t_config"
#define T_BUFSIZ 256
#define T_BIGBUF 4096
#define T_TCTOUT 60
int T_debug;
int T_timeout;
static const char * T_config;
static char * T_dir;
static int
t_initconf(const char *path);
static int
t_dumpconf(const char *path);
static int
static char *
static void
printhelp(void);
static void
printusage(void);
static int T_int;
static void
t_sighandler(int sig) {
}
int
int c;
int tnum;
int subprocs;
int status;
int len;
subprocs = 1;
/*
* -a option is now default.
*/
/*
* Parse args.
*/
!= -1) {
if (c == 'a') {
/*
* Flag all tests to be run.
*/
}
else if (c == 'b') {
}
else if (c == 't') {
if (first) {
/*
* Turn off effect of -a default
* and allow multiple -t and -n
* options.
*/
}
/*
* Flag test tnum to be run.
*/
tnum -= 1;
}
}
else if (c == 'c') {
}
else if (c == 'd') {
}
else if (c == 'n') {
pts = &T_testlist[0];
tnum = 0;
if (first) {
sizeof(T_tvec));
}
break;
}
++pts;
++tnum;
}
exit(1);
}
}
else if (c == 'h') {
printhelp();
exit(0);
}
else if (c == 'u') {
printusage();
exit(0);
}
else if (c == 'x') {
subprocs = 0;
}
else if (c == 'q') {
}
else if (c == ':') {
exit(1);
}
else if (c == '?') {
exit(1);
}
}
/*
* Set cwd.
*/
/*
* We don't want buffered output.
*/
/*
* Setup signals.
*/
#ifdef SIGCHLD
/*
* This is mostly here for NetBSD's pthread implementation, until
* people catch up to the latest unproven-pthread package.
*/
#endif
/*
* Output start stanza to journal.
*/
/*
* Setup the test environment using the config file.
*/
if (T_debug)
/*
* Now invoke all the test cases.
*/
tnum = 0;
pts = &T_testlist[0];
if (subprocs) {
if (T_pid == 0) {
exit(0);
} else if (T_pid > 0) {
T_int = 0;
deadpid =
if (WIFSIGNALED(status)) {
"the test case timed out\n");
else
"the test case caused exception %d\n",
}
} else if ((deadpid == -1) &&
T_int) {
T_int = 0;
}
else if ((deadpid == -1) &&
break;
}
alarm(0);
} else {
t_info("fork failed, errno == %d\n",
errno);
}
}
else {
}
}
++pts;
++tnum;
}
return(0);
}
void
"A" : "C");
/*
* Format text to a buffer.
*/
(void)printf("\n");
}
void
}
void
const char *p;
switch (result) {
case T_PASS:
p = "PASS";
break;
case T_FAIL:
p = "FAIL";
break;
case T_UNRESOLVED:
p = "UNRESOLVED";
break;
case T_UNSUPPORTED:
p = "UNSUPPORTED";
break;
case T_UNTESTED:
p = "UNTESTED";
break;
default:
p = "UNKNOWN";
break;
}
printf("R:%s\n", p);
}
char *
char *n;
char **p;
n = NULL;
p = &T_env[0];
while (*p != NULL) {
if ( *(*p + len) == '=') {
n = *p + len + 1;
break;
}
}
++p;
}
}
return(n);
}
/*
*
* Read in the config file at path, initializing T_env.
*
* note: no format checking for now ...
*
*/
static int
t_initconf(const char *path) {
int n;
int rval;
char **p;
rval = -1;
n = 0;
p = &T_env[0];
while (n < T_MAXENV) {
if (*p == NULL)
break;
/*
* Skip comments and other junk.
*/
(void)free(*p);
continue;
}
++p; ++n;
}
rval = 0;
}
return (rval);
}
/*
*
* Dump T_env to stdout.
*
*/
static int
t_dumpconf(const char *path) {
int rval;
char **p;
rval = -1;
p = &T_env[0];
while (*p != NULL) {
printf("C:%s\n", *p);
++p;
}
rval = 0;
}
return(rval);
}
/*
*
* Read a newline or EOF terminated string from fp.
* On success:
* return a malloc'd buf containing the string with
* the newline converted to a '\0'.
* On error:
* return NULL.
*
* Caller is responsible for freeing buf.
*
*/
char *
int c;
size_t n;
char *buf;
char *p;
n = 0;
p = buf;
if (c == '\n')
break;
*p++ = c;
++n;
if ( n >= size ) {
size * sizeof(char));
break;
p = buf + n;
}
}
*p = '\0';
} else {
return(NULL);
}
}
/*
*
* Put info to log, using key.
* For now, just dump it out.
* Later format into pretty lines.
*
*/
static int
int rval;
/*
* For now.
*/
return(rval);
}
static char *
size_t n;
time_t t;
struct tm *p;
p = localtime(&t);
}
/*
* Some generally used utilities.
*/
struct dns_errormap {
const char *text;
} dns_errormap[] = {
{ ISC_R_SUCCESS, "ISC_R_SUCCESS" },
{ ISC_R_EXISTS, "ISC_R_EXISTS" },
{ ISC_R_NOTFOUND, "ISC_R_NOTFOUND" },
{ ISC_R_NOSPACE, "ISC_R_NOSPACE" },
{ ISC_R_UNEXPECTED, "ISC_R_UNEXPECTED" },
{ ISC_R_UNEXPECTEDEND, "ISC_R_UNEXPECTEDEND" },
{ ISC_R_RANGE, "ISC_R_RANGE" },
{ DNS_R_LABELTOOLONG, "DNS_R_LABELTOOLONG" },
{ DNS_R_BADESCAPE, "DNS_R_BADESCAPE" },
/* { DNS_R_BADBITSTRING, "DNS_R_BADBITSTRING" }, */
/* { DNS_R_BITSTRINGTOOLONG, "DNS_R_BITSTRINGTOOLONG"}, */
{ DNS_R_EMPTYLABEL, "DNS_R_EMPTYLABEL" },
{ DNS_R_BADDOTTEDQUAD, "DNS_R_BADDOTTEDQUAD" },
{ DNS_R_UNKNOWN, "DNS_R_UNKNOWN" },
{ DNS_R_BADLABELTYPE, "DNS_R_BADLABELTYPE" },
{ DNS_R_BADPOINTER, "DNS_R_BADPOINTER" },
{ DNS_R_TOOMANYHOPS, "DNS_R_TOOMANYHOPS" },
{ DNS_R_DISALLOWED, "DNS_R_DISALLOWED" },
{ DNS_R_EXTRATOKEN, "DNS_R_EXTRATOKEN" },
{ DNS_R_EXTRADATA, "DNS_R_EXTRADATA" },
{ DNS_R_TEXTTOOLONG, "DNS_R_TEXTTOOLONG" },
{ DNS_R_SYNTAX, "DNS_R_SYNTAX" },
{ DNS_R_BADCKSUM, "DNS_R_BADCKSUM" },
{ DNS_R_BADAAAA, "DNS_R_BADAAAA" },
{ DNS_R_NOOWNER, "DNS_R_NOOWNER" },
{ DNS_R_NOTTL, "DNS_R_NOTTL" },
{ DNS_R_BADCLASS, "DNS_R_BADCLASS" },
{ DNS_R_PARTIALMATCH, "DNS_R_PARTIALMATCH" },
{ DNS_R_NEWORIGIN, "DNS_R_NEWORIGIN" },
{ DNS_R_UNCHANGED, "DNS_R_UNCHANGED" },
{ DNS_R_BADTTL, "DNS_R_BADTTL" },
{ DNS_R_NOREDATA, "DNS_R_NOREDATA" },
{ DNS_R_CONTINUE, "DNS_R_CONTINUE" },
{ DNS_R_DELEGATION, "DNS_R_DELEGATION" },
{ DNS_R_GLUE, "DNS_R_GLUE" },
{ DNS_R_DNAME, "DNS_R_DNAME" },
{ DNS_R_CNAME, "DNS_R_CNAME" },
{ DNS_R_NXDOMAIN, "DNS_R_NXDOMAIN" },
{ DNS_R_NXRRSET, "DNS_R_NXRRSET" },
{ DNS_R_BADDB, "DNS_R_BADDB" },
{ DNS_R_ZONECUT, "DNS_R_ZONECUT" },
{ DNS_R_NOTZONETOP, "DNS_R_NOTZONETOP" },
{ DNS_R_SEENINCLUDE, "DNS_R_SEENINCLUDE" },
{ DNS_R_SINGLETON, "DNS_R_SINGLETON" },
{ (isc_result_t)0, NULL }
};
t_dns_result_fromtext(char *name) {
struct dns_errormap *pmap;
pmap = dns_errormap;
break;
++pmap;
}
return (result);
}
struct dc_method_map {
unsigned int dc_method;
const char *text;
} dc_method_map[] = {
{ DNS_COMPRESS_NONE, "DNS_COMPRESS_NONE" },
{ DNS_COMPRESS_GLOBAL14, "DNS_COMPRESS_GLOBAL14" },
{ DNS_COMPRESS_ALL, "DNS_COMPRESS_ALL" },
{ 0, NULL }
};
unsigned int
t_dc_method_fromtext(char *name) {
unsigned int dc_method;
struct dc_method_map *pmap;
break;
++pmap;
}
return(dc_method);
}
int
int cnt;
char *p;
cnt = 0;
*toks++ = p;
++cnt;
}
}
return(cnt);
}
static void
printhelp(void) {
int cnt;
cnt = 1;
pts = &T_testlist[0];
printf("Available tests:\n");
++pts;
++cnt;
}
}
static void
printusage(void) {
}
int
char *p;
int line;
int cnt;
int result;
int nfails;
int nprobs;
int npass;
npass = 0;
nfails = 0;
nprobs = 0;
line = 0;
++line;
/*
* Skip comment lines.
*/
if ((isspace((unsigned char)*p)) || (*p == '#'))
continue;
switch (result) {
case T_PASS:
++npass;
break;
case T_FAIL:
++nfails;
break;
case T_UNTESTED:
break;
default:
++nprobs;
break;
}
} else {
t_info("bad format in %s at line %d\n",
++nprobs;
}
(void)free(p);
}
} else {
++nprobs;
}
else if (nfails > 0)
else if (npass == 0)
result = T_UNTESTED;
return (result);
}