t_api.c revision dd19c1a3529e4324ac977bc9e0bc64cc28ce7506
/*
* Copyright (C) 2004, 2005, 2007-2010, 2013 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 1999-2003 Internet Software Consortium.
*
* 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.68 2010/12/21 04:20:23 marka Exp $ */
/*! \file */
#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>
#ifndef WIN32
#else
#include <direct.h>
#endif
#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;
#ifdef WIN32
#endif
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
#ifndef WIN32
#else
#endif
{
int c;
int tnum;
#ifndef WIN32
int subprocs;
int status;
#endif
int len;
#ifndef WIN32
#endif
#ifndef WIN32
subprocs = 1;
#endif
/*
* -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') {
#ifndef WIN32
subprocs = 0;
#endif
}
else if (c == 'q') {
}
else if (c == ':') {
exit(1);
}
else if (c == '?') {
exit(1);
}
}
/*
* Set cwd.
*/
exit(1);
}
/*
* We don't want buffered output.
*/
/*
* Setup signals.
*/
#ifndef WIN32
#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];
#ifndef WIN32
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 {
}
#else
#endif
}
++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_SKIPPED:
p = "SKIPPED";
break;
case T_UNTESTED:
p = "UNTESTED";
break;
case T_THREADONLY:
p = "THREADONLY";
break;
case T_PKCS11ONLY:
p = "PKCS11ONLY";
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 *p;
n = 0;
p = buf;
if ((c == '\r') || (c == '\n'))
break;
*p++ = c;
++n;
if ( n >= size ) {
size * sizeof(char));
goto err;
p = buf + n;
}
}
*p = '\0';
if (c == EOF && n == 0U) {
return (NULL);
}
return (buf);
} else {
err:
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 tresult;
int nfails;
int nprobs;
int npass;
npass = 0;
nfails = 0;
nprobs = 0;
line = 0;
++line;
/*
* Skip comment lines.
*/
if ((isspace((unsigned char)*p)) || (*p == '#')) {
(void)free(p);
continue;
}
switch (tresult) {
case T_PASS:
++npass;
break;
case T_FAIL:
++nfails;
break;
case T_SKIPPED:
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)
return (result);
}
#ifdef WIN32
void
int tnum;
const testspec_t *pts;
break;
}
}
#endif