Annotation of embedaddon/dhcp/tests/t_api.c, revision 1.1.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: 
1.1.1.1 ! misho      18: /* $Id: t_api.c,v 1.2.244.1 2009/01/22 02:07:42 sar Exp $ */
1.1       misho      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>