📄 t_api.c
字号:
/* * 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.48.2.1.2.6 2004/08/28 06:25:27 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 <sys/wait.h>#include <isc/boolean.h>#include <isc/commandline.h>#include <isc/print.h>#include <isc/string.h>#include <dns/compress.h>#include <dns/result.h>#include "include/tests/t_api.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_MAXTESTS 256 /* must be 0 mod 8 */#define T_MAXENV 256#define T_DEFAULT_CONFIG "t_config"#define T_BUFSIZ 256#define T_BIGBUF 4096#define T_TCTOUT 60int T_debug;int T_timeout;pid_t T_pid;static const char * T_config;static char T_tvec[T_MAXTESTS / 8];static char * T_env[T_MAXENV + 1];static char T_buf[T_BIGBUF];static char * T_dir;static intt_initconf(const char *path);static intt_dumpconf(const char *path);static intt_putinfo(const char *key, const char *info);static char *t_getdate(char *buf, size_t buflen);static voidprinthelp(void);static voidprintusage(void);static int T_int;static voidt_sighandler(int sig) { T_int = sig;}intmain(int argc, char **argv) { int c; int tnum; int subprocs; pid_t deadpid; int status; int len; isc_boolean_t first; testspec_t *pts; struct sigaction sa; first = ISC_TRUE; subprocs = 1; T_timeout = T_TCTOUT; /* * -a option is now default. */ memset(T_tvec, 0xffff, sizeof(T_tvec)); /* * Parse args. */ while ((c = isc_commandline_parse(argc, argv, ":at:c:d:n:huxq:b:")) != -1) { if (c == 'a') { /* * Flag all tests to be run. */ memset(T_tvec, 0xffff, sizeof(T_tvec)); } else if (c == 'b') { T_dir = isc_commandline_argument; } else if (c == 't') { tnum = atoi(isc_commandline_argument); if ((tnum > 0) && (tnum < T_MAXTESTS)) { if (first) { /* * Turn off effect of -a default * and allow multiple -t and -n * options. */ memset(T_tvec, 0, sizeof(T_tvec)); first = ISC_FALSE; } /* * Flag test tnum to be run. */ tnum -= 1; T_tvec[tnum / 8] |= (0x01 << (tnum % 8)); } } else if (c == 'c') { T_config = isc_commandline_argument; } else if (c == 'd') { T_debug = atoi(isc_commandline_argument); } else if (c == 'n') { pts = &T_testlist[0]; tnum = 0; while (pts->pfv != NULL) { if (! strcmp(pts->func_name, isc_commandline_argument)) { if (first) { memset(T_tvec, 0, sizeof(T_tvec)); first = ISC_FALSE; } T_tvec[tnum/8] |= (0x01 << (tnum%8)); break; } ++pts; ++tnum; } if (pts->pfv == NULL) { fprintf(stderr, "no such test %s\n", isc_commandline_argument); 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') { T_timeout = atoi(isc_commandline_argument); } else if (c == ':') { fprintf(stderr, "Option -%c requires an argument\n", isc_commandline_option); exit(1); } else if (c == '?') { fprintf(stderr, "Unrecognized option -%c\n", isc_commandline_option); exit(1); } } /* * Set cwd. */ if (T_dir != NULL) (void) chdir(T_dir); /* * We don't want buffered output. */ (void)setbuf(stdout, NULL); (void)setbuf(stderr, NULL); /* * Setup signals. */ sa.sa_flags = 0; sigfillset(&sa.sa_mask);#ifdef SIGCHLD /* * This is mostly here for NetBSD's pthread implementation, until * people catch up to the latest unproven-pthread package. */ sa.sa_handler = SIG_DFL; (void)sigaction(SIGCHLD, &sa, NULL);#endif sa.sa_handler = t_sighandler; (void)sigaction(SIGINT, &sa, NULL); (void)sigaction(SIGALRM, &sa, NULL); /* * Output start stanza to journal. */ snprintf(T_buf, sizeof(T_buf), "%s:", argv[0]); len = strlen(T_buf); (void) t_getdate(T_buf + len, T_BIGBUF - len); t_putinfo("S", T_buf); /* * Setup the test environment using the config file. */ if (T_config == NULL) T_config = T_DEFAULT_CONFIG; t_initconf(T_config); if (T_debug) t_dumpconf(T_config); /* * Now invoke all the test cases. */ tnum = 0; pts = &T_testlist[0]; while (*pts->pfv != NULL) { if (T_tvec[tnum / 8] & (0x01 << (tnum % 8))) { if (subprocs) { T_pid = fork(); if (T_pid == 0) { (*pts->pfv)(); exit(0); } else if (T_pid > 0) { T_int = 0; sa.sa_handler = t_sighandler; (void)sigaction(SIGALRM, &sa, NULL); alarm(T_timeout); deadpid = (pid_t) -1; while (deadpid != T_pid) { deadpid = waitpid(T_pid, &status, 0); if (deadpid == T_pid) { if (WIFSIGNALED(status)) { if (WTERMSIG(status) == SIGTERM) t_info( "the test case timed out\n"); else t_info( "the test case caused exception %d\n", WTERMSIG(status)); t_result(T_UNRESOLVED); } } else if ((deadpid == -1) && (errno == EINTR) && T_int) { kill(T_pid, SIGTERM); T_int = 0; } else if ((deadpid == -1) && ((errno == ECHILD) || (errno == ESRCH))) break; } alarm(0); sa.sa_handler = SIG_IGN; (void)sigaction(SIGALRM, &sa, NULL); } else { t_info("fork failed, errno == %d\n", errno); t_result(T_UNRESOLVED); } } else { (*pts->pfv)(); } } ++pts; ++tnum; } snprintf(T_buf, sizeof(T_buf), "%s:", argv[0]); len = strlen(T_buf); (void) t_getdate(T_buf + len, T_BIGBUF - len); t_putinfo("E", T_buf); return(0);}voidt_assert(const char *component, int anum, int class, const char *what, ...) { va_list args; (void)printf("T:%s:%d:%s\n", component, anum, class == T_REQUIRED ? "A" : "C"); /* * Format text to a buffer. */ va_start(args, what); (void)vsnprintf(T_buf, sizeof(T_buf), what, args); va_end(args); (void)t_putinfo("A", T_buf); (void)printf("\n");}voidt_info(const char *format, ...) { va_list args; va_start(args, format); (void) vsnprintf(T_buf, sizeof(T_buf), format, args); va_end(args); (void) t_putinfo("I", T_buf);}voidt_result(int result) { 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; case T_THREADONLY: p = "THREADONLY"; break;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -