Annotation of embedaddon/dhcp/tests/t_api.c, revision 1.1
1.1 ! misho 1: /*
! 2: * Copyright (C) 2004, 2005, 2007, 2009 Internet Systems Consortium, Inc. ("ISC")
! 3: * Copyright (C) 1999-2003 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_api.c,v 1.2.244.1 2009-01-22 02:07:42 sar Exp $ */
! 19:
! 20: /*! \file */
! 21:
! 22: /*
! 23: * This test API framework is taken from the BIND 9 code. It has been
! 24: * modified to remove the DNS-specific parts, and the BIND-specific
! 25: * parts.
! 26: *
! 27: * The DNS-specific parts are now wrapped with the DNS_SUPPORT macro,
! 28: * and the BIND-specific parts are now wrapped with the BIND_SUPPORT
! 29: * macro.
! 30: */
! 31:
! 32: #include <config.h>
! 33:
! 34: #include <ctype.h>
! 35: #include <errno.h>
! 36: #include <limits.h>
! 37: #include <signal.h>
! 38: #include <stdarg.h>
! 39: #include <stdio.h>
! 40: #include <stdlib.h>
! 41: #include <time.h>
! 42: #include <unistd.h>
! 43:
! 44: #include <sys/wait.h>
! 45:
! 46: #include <isc-dhcp/boolean.h>
! 47: #include <isc-dhcp/commandline.h>
! 48: #include <isc-dhcp/print.h>
! 49: #include <isc-dhcp/string.h>
! 50: #include <isc-dhcp/mem.h>
! 51:
! 52: #ifdef DNS_SUPPORT
! 53: #include <dns/compress.h>
! 54: #include <dns/result.h>
! 55: #endif /* DNS_SUPPORT */
! 56:
! 57: #ifndef BIND_SUPPORT
! 58: #define isc_commandline_parse getopt
! 59: #define isc_commandline_argument optarg
! 60: #define isc_commandline_option optopt
! 61: #endif /* BIND_SUPPORT */
! 62:
! 63: #include "t_api.h"
! 64: #include "cdefs.h"
! 65:
! 66: static const char *Usage =
! 67: "\t-a : run all tests\n"
! 68: "\t-b <dir> : chdir to dir before running tests"
! 69: "\t-c <config_file> : use specified config file\n"
! 70: "\t-d <debug_level> : set debug level to debug_level\n"
! 71: "\t-h : print test info\n"
! 72: "\t-u : print usage info\n"
! 73: "\t-n <test_name> : run specified test name\n"
! 74: "\t-t <test_number> : run specified test number\n"
! 75: "\t-x : don't execute tests in a subproc\n"
! 76: "\t-q <timeout> : use 'timeout' as the timeout value\n";
! 77: /*!<
! 78: * -a --> run all tests
! 79: * -b dir --> chdir to dir before running tests
! 80: * -c config --> use config file 'config'
! 81: * -d --> turn on api debugging
! 82: * -h --> print out available test names
! 83: * -u --> print usage info
! 84: * -n name --> run test named name
! 85: * -tn --> run test n
! 86: * -x --> don't execute testcases in a subproc
! 87: * -q timeout --> use 'timeout' as the timeout value
! 88: */
! 89:
! 90: #define T_MAXTESTS 256 /*% must be 0 mod 8 */
! 91: #define T_MAXENV 256
! 92: #define T_DEFAULT_CONFIG "t_config"
! 93: #define T_BUFSIZ 256
! 94: #define T_BIGBUF 4096
! 95:
! 96: #define T_TCTOUT 60
! 97:
! 98: int T_debug;
! 99: int T_timeout;
! 100: pid_t T_pid;
! 101: static const char * T_config;
! 102: static char T_tvec[T_MAXTESTS / 8];
! 103: static char * T_env[T_MAXENV + 1];
! 104: static char T_buf[T_BIGBUF];
! 105: static char * T_dir;
! 106:
! 107: static int
! 108: t_initconf(const char *path);
! 109:
! 110: static int
! 111: t_dumpconf(const char *path);
! 112:
! 113: static int
! 114: t_putinfo(const char *key, const char *info);
! 115:
! 116: static char *
! 117: t_getdate(char *buf, size_t buflen);
! 118:
! 119: static void
! 120: printhelp(void);
! 121:
! 122: static void
! 123: printusage(void);
! 124:
! 125: static int T_int;
! 126:
! 127: static void
! 128: t_sighandler(int sig) {
! 129: T_int = sig;
! 130: }
! 131:
! 132: int
! 133: main(int argc, char **argv) {
! 134: int c;
! 135: int tnum;
! 136: int subprocs;
! 137: pid_t deadpid;
! 138: int status;
! 139: int len;
! 140: isc_boolean_t first;
! 141: testspec_t *pts;
! 142: struct sigaction sa;
! 143:
! 144: #ifdef BIND_SUPPORT
! 145: isc_mem_debugging = ISC_MEM_DEBUGRECORD;
! 146: #endif /* BIND_SUPPORT */
! 147: first = ISC_TRUE;
! 148: subprocs = 1;
! 149: T_timeout = T_TCTOUT;
! 150:
! 151: /*
! 152: * -a option is now default.
! 153: */
! 154: memset(T_tvec, 0xffff, sizeof(T_tvec));
! 155:
! 156: /*
! 157: * Parse args.
! 158: */
! 159: while ((c = isc_commandline_parse(argc, argv, ":at:c:d:n:huxq:b:"))
! 160: != -1) {
! 161: if (c == 'a') {
! 162: /*
! 163: * Flag all tests to be run.
! 164: */
! 165: memset(T_tvec, 0xffff, sizeof(T_tvec));
! 166: }
! 167: else if (c == 'b') {
! 168: T_dir = isc_commandline_argument;
! 169: }
! 170: else if (c == 't') {
! 171: tnum = atoi(isc_commandline_argument);
! 172: if ((tnum > 0) && (tnum < T_MAXTESTS)) {
! 173: if (first) {
! 174: /*
! 175: * Turn off effect of -a default
! 176: * and allow multiple -t and -n
! 177: * options.
! 178: */
! 179: memset(T_tvec, 0, sizeof(T_tvec));
! 180: first = ISC_FALSE;
! 181: }
! 182: /*
! 183: * Flag test tnum to be run.
! 184: */
! 185: tnum -= 1;
! 186: T_tvec[tnum / 8] |= (0x01 << (tnum % 8));
! 187: }
! 188: }
! 189: else if (c == 'c') {
! 190: T_config = isc_commandline_argument;
! 191: }
! 192: else if (c == 'd') {
! 193: T_debug = atoi(isc_commandline_argument);
! 194: }
! 195: else if (c == 'n') {
! 196: pts = &T_testlist[0];
! 197: tnum = 0;
! 198: while (pts->pfv != NULL) {
! 199: if (! strcmp(pts->func_name,
! 200: isc_commandline_argument)) {
! 201: if (first) {
! 202: memset(T_tvec, 0,
! 203: sizeof(T_tvec));
! 204: first = ISC_FALSE;
! 205: }
! 206: T_tvec[tnum/8] |= (0x01 << (tnum%8));
! 207: break;
! 208: }
! 209: ++pts;
! 210: ++tnum;
! 211: }
! 212: if (pts->pfv == NULL) {
! 213: fprintf(stderr, "no such test %s\n",
! 214: isc_commandline_argument);
! 215: exit(1);
! 216: }
! 217: }
! 218: else if (c == 'h') {
! 219: printhelp();
! 220: exit(0);
! 221: }
! 222: else if (c == 'u') {
! 223: printusage();
! 224: exit(0);
! 225: }
! 226: else if (c == 'x') {
! 227: subprocs = 0;
! 228: }
! 229: else if (c == 'q') {
! 230: T_timeout = atoi(isc_commandline_argument);
! 231: }
! 232: else if (c == ':') {
! 233: fprintf(stderr, "Option -%c requires an argument\n",
! 234: isc_commandline_option);
! 235: exit(1);
! 236: }
! 237: else if (c == '?') {
! 238: fprintf(stderr, "Unrecognized option -%c\n",
! 239: isc_commandline_option);
! 240: exit(1);
! 241: }
! 242: }
! 243:
! 244: /*
! 245: * Set cwd.
! 246: */
! 247:
! 248: if (T_dir != NULL)
! 249: IGNORE_RET (chdir(T_dir));
! 250:
! 251: /*
! 252: * We don't want buffered output.
! 253: */
! 254:
! 255: (void)setbuf(stdout, NULL);
! 256: (void)setbuf(stderr, NULL);
! 257:
! 258: /*
! 259: * Setup signals.
! 260: */
! 261:
! 262: sa.sa_flags = 0;
! 263: sigfillset(&sa.sa_mask);
! 264:
! 265: #ifdef SIGCHLD
! 266: /*
! 267: * This is mostly here for NetBSD's pthread implementation, until
! 268: * people catch up to the latest unproven-pthread package.
! 269: */
! 270: sa.sa_handler = SIG_DFL;
! 271: (void)sigaction(SIGCHLD, &sa, NULL);
! 272: #endif
! 273:
! 274: sa.sa_handler = t_sighandler;
! 275: (void)sigaction(SIGINT, &sa, NULL);
! 276: (void)sigaction(SIGALRM, &sa, NULL);
! 277:
! 278: /*
! 279: * Output start stanza to journal.
! 280: */
! 281:
! 282: snprintf(T_buf, sizeof(T_buf), "%s:", argv[0]);
! 283: len = strlen(T_buf);
! 284: (void) t_getdate(T_buf + len, T_BIGBUF - len);
! 285: t_putinfo("S", T_buf);
! 286:
! 287: /*
! 288: * Setup the test environment using the config file.
! 289: */
! 290:
! 291: if (T_config == NULL)
! 292: T_config = T_DEFAULT_CONFIG;
! 293:
! 294: t_initconf(T_config);
! 295: if (T_debug)
! 296: t_dumpconf(T_config);
! 297:
! 298: /*
! 299: * Now invoke all the test cases.
! 300: */
! 301:
! 302: tnum = 0;
! 303: pts = &T_testlist[0];
! 304: while (*pts->pfv != NULL) {
! 305: if (T_tvec[tnum / 8] & (0x01 << (tnum % 8))) {
! 306: if (subprocs) {
! 307: T_pid = fork();
! 308: if (T_pid == 0) {
! 309: (*pts->pfv)();
! 310: exit(0);
! 311: } else if (T_pid > 0) {
! 312:
! 313: T_int = 0;
! 314: sa.sa_handler = t_sighandler;
! 315: (void)sigaction(SIGALRM, &sa, NULL);
! 316: alarm(T_timeout);
! 317:
! 318: deadpid = (pid_t) -1;
! 319: while (deadpid != T_pid) {
! 320: deadpid =
! 321: waitpid(T_pid, &status, 0);
! 322: if (deadpid == T_pid) {
! 323: if (WIFSIGNALED(status)) {
! 324: if (WTERMSIG(status) ==
! 325: SIGTERM)
! 326: t_info(
! 327: "the test case timed out\n");
! 328: else
! 329: t_info(
! 330: "the test case caused exception %d\n",
! 331: WTERMSIG(status));
! 332: t_result(T_UNRESOLVED);
! 333: }
! 334: } else if ((deadpid == -1) &&
! 335: (errno == EINTR) &&
! 336: T_int) {
! 337: kill(T_pid, SIGTERM);
! 338: T_int = 0;
! 339: }
! 340: else if ((deadpid == -1) &&
! 341: ((errno == ECHILD) ||
! 342: (errno == ESRCH)))
! 343: break;
! 344: }
! 345:
! 346: alarm(0);
! 347: sa.sa_handler = SIG_IGN;
! 348: (void)sigaction(SIGALRM, &sa, NULL);
! 349: } else {
! 350: t_info("fork failed, errno == %d\n",
! 351: errno);
! 352: t_result(T_UNRESOLVED);
! 353: }
! 354: }
! 355: else {
! 356: (*pts->pfv)();
! 357: }
! 358: }
! 359: ++pts;
! 360: ++tnum;
! 361: }
! 362:
! 363: snprintf(T_buf, sizeof(T_buf), "%s:", argv[0]);
! 364: len = strlen(T_buf);
! 365: (void) t_getdate(T_buf + len, T_BIGBUF - len);
! 366: t_putinfo("E", T_buf);
! 367:
! 368: return(0);
! 369: }
! 370:
! 371: void
! 372: t_assert(const char *component, int anum, int class, const char *what, ...) {
! 373: va_list args;
! 374:
! 375: (void)printf("T:%s:%d:%s\n", component, anum, class == T_REQUIRED ?
! 376: "A" : "C");
! 377:
! 378: /*
! 379: * Format text to a buffer.
! 380: */
! 381: va_start(args, what);
! 382: (void)vsnprintf(T_buf, sizeof(T_buf), what, args);
! 383: va_end(args);
! 384:
! 385: (void)t_putinfo("A", T_buf);
! 386: (void)printf("\n");
! 387: }
! 388:
! 389: void
! 390: t_info(const char *format, ...) {
! 391: va_list args;
! 392:
! 393: va_start(args, format);
! 394: (void) vsnprintf(T_buf, sizeof(T_buf), format, args);
! 395: va_end(args);
! 396: (void) t_putinfo("I", T_buf);
! 397: }
! 398:
! 399: void
! 400: t_result(int result) {
! 401: const char *p;
! 402:
! 403: switch (result) {
! 404: case T_PASS:
! 405: p = "PASS";
! 406: break;
! 407: case T_FAIL:
! 408: p = "FAIL";
! 409: break;
! 410: case T_UNRESOLVED:
! 411: p = "UNRESOLVED";
! 412: break;
! 413: case T_UNSUPPORTED:
! 414: p = "UNSUPPORTED";
! 415: break;
! 416: case T_UNTESTED:
! 417: p = "UNTESTED";
! 418: break;
! 419: case T_THREADONLY:
! 420: p = "THREADONLY";
! 421: break;
! 422: default:
! 423: p = "UNKNOWN";
! 424: break;
! 425: }
! 426: printf("R:%s\n", p);
! 427: }
! 428:
! 429: char *
! 430: t_getenv(const char *name) {
! 431: char *n;
! 432: char **p;
! 433: size_t len;
! 434:
! 435: n = NULL;
! 436: if (name && *name) {
! 437:
! 438: p = &T_env[0];
! 439: len = strlen(name);
! 440:
! 441: while (*p != NULL) {
! 442: if (strncmp(*p, name, len) == 0) {
! 443: if ( *(*p + len) == '=') {
! 444: n = *p + len + 1;
! 445: break;
! 446: }
! 447: }
! 448: ++p;
! 449: }
! 450: }
! 451: return(n);
! 452: }
! 453:
! 454: /*
! 455: *
! 456: * Read in the config file at path, initializing T_env.
! 457: *
! 458: * note: no format checking for now ...
! 459: *
! 460: */
! 461:
! 462: static int
! 463: t_initconf(const char *path) {
! 464:
! 465: int n;
! 466: int rval;
! 467: char **p;
! 468: FILE *fp;
! 469:
! 470: rval = -1;
! 471:
! 472: fp = fopen(path, "r");
! 473: if (fp != NULL) {
! 474: n = 0;
! 475: p = &T_env[0];
! 476: while (n < T_MAXENV) {
! 477: *p = t_fgetbs(fp);
! 478: if (*p == NULL)
! 479: break;
! 480: if ((**p == '#') || (strchr(*p, '=') == NULL)) {
! 481: /*
! 482: * Skip comments and other junk.
! 483: */
! 484: (void)free(*p);
! 485: continue;
! 486: }
! 487: ++p; ++n;
! 488: }
! 489: (void)fclose(fp);
! 490: rval = 0;
! 491: }
! 492:
! 493: return (rval);
! 494: }
! 495:
! 496: /*
! 497: *
! 498: * Dump T_env to stdout.
! 499: *
! 500: */
! 501:
! 502: static int
! 503: t_dumpconf(const char *path) {
! 504: int rval;
! 505: char **p;
! 506: FILE *fp;
! 507:
! 508: rval = -1;
! 509: fp = fopen(path, "r");
! 510: if (fp != NULL) {
! 511: p = &T_env[0];
! 512: while (*p != NULL) {
! 513: printf("C:%s\n", *p);
! 514: ++p;
! 515: }
! 516: (void) fclose(fp);
! 517: rval = 0;
! 518: }
! 519: return(rval);
! 520: }
! 521:
! 522: /*
! 523: *
! 524: * Read a newline or EOF terminated string from fp.
! 525: * On success:
! 526: * return a malloc'd buf containing the string with
! 527: * the newline converted to a '\0'.
! 528: * On error:
! 529: * return NULL.
! 530: *
! 531: * Caller is responsible for freeing buf.
! 532: *
! 533: */
! 534:
! 535: char *
! 536: t_fgetbs(FILE *fp) {
! 537: int c;
! 538: size_t n;
! 539: size_t size;
! 540: char *buf;
! 541: char *p;
! 542:
! 543: n = 0;
! 544: size = T_BUFSIZ;
! 545: buf = (char *) malloc(T_BUFSIZ * sizeof(char));
! 546:
! 547: if (buf != NULL) {
! 548: p = buf;
! 549: while ((c = fgetc(fp)) != EOF) {
! 550:
! 551: if (c == '\n')
! 552: break;
! 553:
! 554: *p++ = c;
! 555: ++n;
! 556: if ( n >= size ) {
! 557: size += T_BUFSIZ;
! 558: buf = (char *)realloc(buf,
! 559: size * sizeof(char));
! 560: if (buf == NULL)
! 561: break;
! 562: p = buf + n;
! 563: }
! 564: }
! 565: *p = '\0';
! 566: if (c == EOF && n == 0U) {
! 567: free(buf);
! 568: return (NULL);
! 569: }
! 570: return (buf);
! 571: } else {
! 572: fprintf(stderr, "malloc failed %d", errno);
! 573: return(NULL);
! 574: }
! 575: }
! 576:
! 577: /*
! 578: *
! 579: * Put info to log, using key.
! 580: * For now, just dump it out.
! 581: * Later format into pretty lines.
! 582: *
! 583: */
! 584:
! 585: static int
! 586: t_putinfo(const char *key, const char *info) {
! 587: int rval;
! 588:
! 589: /*
! 590: * For now.
! 591: */
! 592: rval = printf("%s:%s", key, info);
! 593: return(rval);
! 594: }
! 595:
! 596: static char *
! 597: t_getdate(char *buf, size_t buflen) {
! 598: size_t n;
! 599: time_t t;
! 600: struct tm *p;
! 601:
! 602: t = time(NULL);
! 603: p = localtime(&t);
! 604: n = strftime(buf, buflen - 1, "%A %d %B %H:%M:%S %Y\n", p);
! 605: return(n != 0U ? buf : NULL);
! 606: }
! 607:
! 608: /*
! 609: * Some generally used utilities.
! 610: */
! 611: #ifdef DNS_SUPPORT
! 612: struct dns_errormap {
! 613: isc_result_t result;
! 614: const char *text;
! 615: } dns_errormap[] = {
! 616: { ISC_R_SUCCESS, "ISC_R_SUCCESS" },
! 617: { ISC_R_EXISTS, "ISC_R_EXISTS" },
! 618: { ISC_R_NOTFOUND, "ISC_R_NOTFOUND" },
! 619: { ISC_R_NOSPACE, "ISC_R_NOSPACE" },
! 620: { ISC_R_UNEXPECTED, "ISC_R_UNEXPECTED" },
! 621: { ISC_R_UNEXPECTEDEND, "ISC_R_UNEXPECTEDEND" },
! 622: { ISC_R_RANGE, "ISC_R_RANGE" },
! 623: { DNS_R_LABELTOOLONG, "DNS_R_LABELTOOLONG" },
! 624: { DNS_R_BADESCAPE, "DNS_R_BADESCAPE" },
! 625: /* { DNS_R_BADBITSTRING, "DNS_R_BADBITSTRING" }, */
! 626: /* { DNS_R_BITSTRINGTOOLONG, "DNS_R_BITSTRINGTOOLONG"}, */
! 627: { DNS_R_EMPTYLABEL, "DNS_R_EMPTYLABEL" },
! 628: { DNS_R_BADDOTTEDQUAD, "DNS_R_BADDOTTEDQUAD" },
! 629: { DNS_R_UNKNOWN, "DNS_R_UNKNOWN" },
! 630: { DNS_R_BADLABELTYPE, "DNS_R_BADLABELTYPE" },
! 631: { DNS_R_BADPOINTER, "DNS_R_BADPOINTER" },
! 632: { DNS_R_TOOMANYHOPS, "DNS_R_TOOMANYHOPS" },
! 633: { DNS_R_DISALLOWED, "DNS_R_DISALLOWED" },
! 634: { DNS_R_EXTRATOKEN, "DNS_R_EXTRATOKEN" },
! 635: { DNS_R_EXTRADATA, "DNS_R_EXTRADATA" },
! 636: { DNS_R_TEXTTOOLONG, "DNS_R_TEXTTOOLONG" },
! 637: { DNS_R_SYNTAX, "DNS_R_SYNTAX" },
! 638: { DNS_R_BADCKSUM, "DNS_R_BADCKSUM" },
! 639: { DNS_R_BADAAAA, "DNS_R_BADAAAA" },
! 640: { DNS_R_NOOWNER, "DNS_R_NOOWNER" },
! 641: { DNS_R_NOTTL, "DNS_R_NOTTL" },
! 642: { DNS_R_BADCLASS, "DNS_R_BADCLASS" },
! 643: { DNS_R_PARTIALMATCH, "DNS_R_PARTIALMATCH" },
! 644: { DNS_R_NEWORIGIN, "DNS_R_NEWORIGIN" },
! 645: { DNS_R_UNCHANGED, "DNS_R_UNCHANGED" },
! 646: { DNS_R_BADTTL, "DNS_R_BADTTL" },
! 647: { DNS_R_NOREDATA, "DNS_R_NOREDATA" },
! 648: { DNS_R_CONTINUE, "DNS_R_CONTINUE" },
! 649: { DNS_R_DELEGATION, "DNS_R_DELEGATION" },
! 650: { DNS_R_GLUE, "DNS_R_GLUE" },
! 651: { DNS_R_DNAME, "DNS_R_DNAME" },
! 652: { DNS_R_CNAME, "DNS_R_CNAME" },
! 653: { DNS_R_NXDOMAIN, "DNS_R_NXDOMAIN" },
! 654: { DNS_R_NXRRSET, "DNS_R_NXRRSET" },
! 655: { DNS_R_BADDB, "DNS_R_BADDB" },
! 656: { DNS_R_ZONECUT, "DNS_R_ZONECUT" },
! 657: { DNS_R_NOTZONETOP, "DNS_R_NOTZONETOP" },
! 658: { DNS_R_SEENINCLUDE, "DNS_R_SEENINCLUDE" },
! 659: { DNS_R_SINGLETON, "DNS_R_SINGLETON" },
! 660: { (isc_result_t)0, NULL }
! 661: };
! 662:
! 663: isc_result_t
! 664: t_dns_result_fromtext(char *name) {
! 665:
! 666: isc_result_t result;
! 667: struct dns_errormap *pmap;
! 668:
! 669: result = ISC_R_UNEXPECTED;
! 670:
! 671: pmap = dns_errormap;
! 672: while (pmap->text != NULL) {
! 673: if (strcmp(name, pmap->text) == 0)
! 674: break;
! 675: ++pmap;
! 676: }
! 677:
! 678: if (pmap->text != NULL)
! 679: result = pmap->result;
! 680:
! 681: return (result);
! 682: }
! 683:
! 684: struct dc_method_map {
! 685: unsigned int dc_method;
! 686: const char *text;
! 687: } dc_method_map[] = {
! 688:
! 689: { DNS_COMPRESS_NONE, "DNS_COMPRESS_NONE" },
! 690: { DNS_COMPRESS_GLOBAL14, "DNS_COMPRESS_GLOBAL14" },
! 691: { DNS_COMPRESS_ALL, "DNS_COMPRESS_ALL" },
! 692: { 0, NULL }
! 693: };
! 694:
! 695: unsigned int
! 696: t_dc_method_fromtext(char *name) {
! 697: unsigned int dc_method;
! 698: struct dc_method_map *pmap;
! 699:
! 700: dc_method = DNS_COMPRESS_NONE;
! 701:
! 702: pmap = dc_method_map;
! 703: while (pmap->text != NULL) {
! 704: if (strcmp(name, pmap->text) == 0)
! 705: break;
! 706: ++pmap;
! 707: }
! 708:
! 709: if (pmap->text != NULL)
! 710: dc_method = pmap->dc_method;
! 711:
! 712: return(dc_method);
! 713: }
! 714: #endif /* DNS_SUPPORT */
! 715:
! 716: int
! 717: t_bustline(char *line, char **toks) {
! 718: int cnt;
! 719: char *p;
! 720:
! 721: cnt = 0;
! 722: if (line && *line) {
! 723: while ((p = strtok(line, "\t")) && (cnt < T_MAXTOKS)) {
! 724: *toks++ = p;
! 725: line = NULL;
! 726: ++cnt;
! 727: }
! 728: }
! 729: return(cnt);
! 730: }
! 731:
! 732: static void
! 733: printhelp(void) {
! 734: int cnt;
! 735: testspec_t *pts;
! 736:
! 737: cnt = 1;
! 738: pts = &T_testlist[0];
! 739:
! 740: printf("Available tests:\n");
! 741: while (pts->func_name) {
! 742: printf("\t%d\t%s\n", cnt, pts->func_name);
! 743: ++pts;
! 744: ++cnt;
! 745: }
! 746: }
! 747:
! 748: static void
! 749: printusage(void) {
! 750: printf("Usage:\n%s\n", Usage);
! 751: }
! 752:
! 753: int
! 754: t_eval(const char *filename, int (*func)(char **), int nargs) {
! 755: FILE *fp;
! 756: char *p;
! 757: int line;
! 758: int cnt;
! 759: int result;
! 760: int nfails;
! 761: int nprobs;
! 762: int npass;
! 763: char *tokens[T_MAXTOKS + 1];
! 764:
! 765: npass = 0;
! 766: nfails = 0;
! 767: nprobs = 0;
! 768:
! 769: fp = fopen(filename, "r");
! 770: if (fp != NULL) {
! 771: line = 0;
! 772: while ((p = t_fgetbs(fp)) != NULL) {
! 773:
! 774: ++line;
! 775:
! 776: /*
! 777: * Skip comment lines.
! 778: */
! 779: if ((isspace((unsigned char)*p)) || (*p == '#')) {
! 780: (void)free(p);
! 781: continue;
! 782: }
! 783:
! 784: cnt = t_bustline(p, tokens);
! 785: if (cnt == nargs) {
! 786: result = func(tokens);
! 787: switch (result) {
! 788: case T_PASS:
! 789: ++npass;
! 790: break;
! 791: case T_FAIL:
! 792: ++nfails;
! 793: break;
! 794: case T_UNTESTED:
! 795: break;
! 796: default:
! 797: ++nprobs;
! 798: break;
! 799: }
! 800: } else {
! 801: t_info("bad format in %s at line %d\n",
! 802: filename, line);
! 803: ++nprobs;
! 804: }
! 805:
! 806: (void)free(p);
! 807: }
! 808: (void)fclose(fp);
! 809: } else {
! 810: t_info("Missing datafile %s\n", filename);
! 811: ++nprobs;
! 812: }
! 813:
! 814: result = T_UNRESOLVED;
! 815:
! 816: if (nfails == 0 && nprobs == 0 && npass > 0)
! 817: result = T_PASS;
! 818: else if (nfails > 0)
! 819: result = T_FAIL;
! 820: else if (npass == 0)
! 821: result = T_UNTESTED;
! 822:
! 823: return (result);
! 824: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>