INN commit: trunk (8 files)

INN Commit rra at isc.org
Wed May 16 19:28:16 UTC 2018


    Date: Wednesday, May 16, 2018 @ 12:28:16
  Author: iulius
Revision: 10284

Update to latest C TAP Harness and rra-c-util upstream versions

Modified:
  trunk/include/clibrary.h
  trunk/m4/krb5-config.m4
  trunk/support/getc-tap-harness
  trunk/support/getrra-c-util
  trunk/tests/docs/pod.t
  trunk/tests/lib/getnameinfo-t.c
  trunk/tests/lib/network/client-t.c
  trunk/tests/runtests.c

------------------------------+
 include/clibrary.h           |    5 
 m4/krb5-config.m4            |    3 
 support/getc-tap-harness     |    3 
 support/getrra-c-util        |    6 -
 tests/docs/pod.t             |    8 -
 tests/lib/getnameinfo-t.c    |   10 -
 tests/lib/network/client-t.c |   10 -
 tests/runtests.c             |  211 ++++++++++++++++++++++++++++++++++++-----
 8 files changed, 215 insertions(+), 41 deletions(-)

Modified: include/clibrary.h
===================================================================
--- include/clibrary.h	2018-05-14 12:43:05 UTC (rev 10283)
+++ include/clibrary.h	2018-05-16 19:28:16 UTC (rev 10284)
@@ -77,6 +77,11 @@
 /* Get the bool type. */
 #include "portable/stdbool.h"
 
+/* In case uint32_t and associated limits weren't defined. */
+#ifndef UINT32_MAX
+# define UINT32_MAX 4294967295UL
+#endif
+
 /* Windows provides snprintf under a different name. */
 #ifdef _WIN32
 # define snprintf _snprintf

Modified: m4/krb5-config.m4
===================================================================
--- m4/krb5-config.m4	2018-05-14 12:43:05 UTC (rev 10283)
+++ m4/krb5-config.m4	2018-05-16 19:28:16 UTC (rev 10284)
@@ -12,7 +12,8 @@
 dnl package, available at <https://www.eyrie.org/~eagle/software/rra-c-util/>.
 dnl
 dnl Written by Russ Allbery <eagle at eyrie.org>
-dnl Copyright 2011-2012, 2018
+dnl Copyright 2018 Russ Allbery <eagle at eyrie.org>
+dnl Copyright 2011-2012
 dnl     The Board of Trustees of the Leland Stanford Junior University
 dnl
 dnl This file is free software; the authors give unlimited permission to copy

Modified: support/getc-tap-harness
===================================================================
--- support/getc-tap-harness	2018-05-14 12:43:05 UTC (rev 10283)
+++ support/getc-tap-harness	2018-05-16 19:28:16 UTC (rev 10284)
@@ -217,7 +217,8 @@
 download tests/tap/macros.h tests/tap macros.h
 
 ##  Synchronize the POD checker test suite.
-download tests/docs/pod-t tests/docs pod.t
+##  Disabled since Test::RRA became a dependency.
+#download tests/docs/pod-t tests/docs pod.t
 
 ##  Synchronize the README file from upstream.
 download docs/writing-tests tests README

Modified: support/getrra-c-util
===================================================================
--- support/getrra-c-util	2018-05-14 12:43:05 UTC (rev 10283)
+++ support/getrra-c-util	2018-05-16 19:28:16 UTC (rev 10284)
@@ -107,7 +107,7 @@
                  -e 's/PORTABLE_SYSTEM_H/CLIBRARY_H/g' \
                  -e "8 i \\
  *     #include \"inn/macros.h\"" \
-                 -e "103 i \\
+                 -e "108 i \\
 /*\\
  * This almost certainly isn't necessary, but it's not hurting anything.\\
  * gcc assumes that if SEEK_SET isn't defined none of the rest are either,\\
@@ -119,7 +119,7 @@
 # define SEEK_END 2\\
 #endif\\
 " \
-                 -e "117 i \\
+                 -e "122 i \\
 /*\\
  * Handle defining fseeko and ftello.  If HAVE_FSEEKO is defined, the system\\
  * header files take care of this for us.  Otherwise, see if we're building\\
@@ -161,7 +161,7 @@
 extern int symlink(const char *, const char *);\\
 #endif\\
 " \
-               -e "158 i \\
+               -e "163 i \\
 #if !HAVE_DECL_STRLCAT\\
 extern size_t strlcat(char *, const char *, size_t);\\
 #endif\\

Modified: tests/docs/pod.t
===================================================================
--- tests/docs/pod.t	2018-05-14 12:43:05 UTC (rev 10283)
+++ tests/docs/pod.t	2018-05-16 19:28:16 UTC (rev 10284)
@@ -2,13 +2,15 @@
 #
 # $Id$
 #
-# Test POD formatting.
+# Check all POD documents in the tree for POD formatting errors.
 #
+# Copyright 2016 Russ Allbery <eagle at eyrie.org>
+# Copyright 2012-2014
+#     The Board of Trustees of the Leland Stanford Junior University
+#
 # This file is part of C TAP Harness.  The current version plus supporting
 # documentation is at <https://www.eyrie.org/~eagle/software/c-tap-harness/>.
 #
-# Copyright 2009-2010, 2013-2016 Russ Allbery <eagle at eyrie.org>
-#
 # Permission is hereby granted, free of charge, to any person obtaining a
 # copy of this software and associated documentation files (the "Software"),
 # to deal in the Software without restriction, including without limitation

Modified: tests/lib/getnameinfo-t.c
===================================================================
--- tests/lib/getnameinfo-t.c	2018-05-14 12:43:05 UTC (rev 10283)
+++ tests/lib/getnameinfo-t.c	2018-05-16 19:28:16 UTC (rev 10284)
@@ -6,7 +6,7 @@
  * which can be found at <https://www.eyrie.org/~eagle/software/rra-c-util/>.
  *
  * Written by Russ Allbery <eagle at eyrie.org>
- * Copyright 2005-2006, 2014 Russ Allbery <eagle at eyrie.org>
+ * Copyright 2005-2006, 2014, 2018 Russ Allbery <eagle at eyrie.org>
  * Copyright 2007-2011
  *     The Board of Trustees of the Leland Stanford Junior University
  *
@@ -123,20 +123,20 @@
      * some well-known host and make sure that getnameinfo returns the same
      * results.  This may need to be skipped.
      */
-    hp = gethostbyname("www.isc.org");
+    hp = gethostbyname("a.root-servers.net");
     if (hp == NULL)
-        skip_block(2, "cannot look up www.isc.org");
+        skip_block(2, "cannot look up a.root-servers.net");
     else {
         memcpy(&sin.sin_addr, hp->h_addr, sizeof(sin.sin_addr));
         hp = gethostbyaddr((const void *) &sin.sin_addr, sizeof(sin.sin_addr),
                            AF_INET);
         if (hp == NULL || strchr(hp->h_name, '.') == NULL)
-            skip_block(2, "cannot reverse-lookup www.isc.org");
+            skip_block(2, "cannot reverse-lookup a.root-servers.net");
         else {
             name = xstrdup(hp->h_name);
             status = test_getnameinfo(sa, sizeof(sin), node, sizeof(node),
                                       NULL, 0, 0);
-            is_int(0, status, "lookup of www.isc.org IP address");
+            is_int(0, status, "lookup of a.root-servers.net IP address");
             is_string(name, node, "...matches gethostbyaddr");
             free(name);
         }

Modified: tests/lib/network/client-t.c
===================================================================
--- tests/lib/network/client-t.c	2018-05-14 12:43:05 UTC (rev 10283)
+++ tests/lib/network/client-t.c	2018-05-16 19:28:16 UTC (rev 10284)
@@ -6,7 +6,7 @@
  * which can be found at <https://www.eyrie.org/~eagle/software/rra-c-util/>.
  *
  * Written by Russ Allbery <eagle at eyrie.org>
- * Copyright 2005, 2013-2014, 2016-2017 Russ Allbery <eagle at eyrie.org>
+ * Copyright 2005, 2013-2014, 2016-2018 Russ Allbery <eagle at eyrie.org>
  * Copyright 2009-2013
  *     The Board of Trustees of the Leland Stanford Junior University
  *
@@ -381,10 +381,6 @@
      */
     const size_t bufsize = 15 * 1024 * 1024;
 
-    /* Create the data that we're going to send. */
-    buffer = bmalloc(bufsize);
-    memset(buffer, 'a', bufsize);
-
     /* Create the listening socket. */
     fd = network_bind_ipv4(SOCK_STREAM, "127.0.0.1", 11119);
     if (fd == INVALID_SOCKET)
@@ -401,6 +397,10 @@
         client_delay_reader("127.0.0.1");
     }
 
+    /* Create the data that we're going to send. */
+    buffer = bmalloc(bufsize);
+    memset(buffer, 'a', bufsize);
+
     /* Set an alarm just in case our timeouts don't work. */
     alarm(10);
 

Modified: tests/runtests.c
===================================================================
--- tests/runtests.c	2018-05-14 12:43:05 UTC (rev 10283)
+++ tests/runtests.c	2018-05-16 19:28:16 UTC (rev 10284)
@@ -40,9 +40,10 @@
  *      runtests -o [-h] [-b <build-dir>] [-s <source-dir>] <test>
  *
  * In the first case, expects a list of executables located in the given file,
- * one line per executable.  For each one, runs it as part of a test suite,
- * reporting results.  In the second case, use the same infrastructure, but
- * run only the tests listed on the command line.
+ * one line per executable, possibly followed by a space-separated list of
+ * options.  For each one, runs it as part of a test suite, reporting results.
+ * In the second case, use the same infrastructure, but run only the tests
+ * listed on the command line.
  *
  * Test output should start with a line containing the number of tests
  * (numbered from 1 to this number), optionally preceded by "1..", although
@@ -186,7 +187,7 @@
 /* Structure to hold data for a set of tests. */
 struct testset {
     char *file;                 /* The file name of the test. */
-    char *path;                 /* The path to the test program. */
+    char **command;             /* The argv vector to run the command. */
     enum plan_status plan;      /* The status of our plan. */
     unsigned long count;        /* Expected count of tests. */
     unsigned long current;      /* The last seen test number. */
@@ -197,7 +198,7 @@
     unsigned long allocated;    /* The size of the results table. */
     enum test_status *results;  /* Table of results by test number. */
     unsigned int aborted;       /* Whether the set was aborted. */
-    int reported;               /* Whether the results were reported. */
+    unsigned int reported;      /* Whether the results were reported. */
     int status;                 /* The exit status of the test. */
     unsigned int all_skipped;   /* Whether all tests were skipped. */
     char *reason;               /* Why all tests were skipped. */
@@ -249,6 +250,7 @@
 #define xcalloc(n, size)      x_calloc((n), (size), __FILE__, __LINE__)
 #define xmalloc(size)         x_malloc((size), __FILE__, __LINE__)
 #define xstrdup(p)            x_strdup((p), __FILE__, __LINE__)
+#define xstrndup(p, size)     x_strndup((p), (size), __FILE__, __LINE__)
 #define xreallocarray(p, n, size) \
     x_reallocarray((p), (n), (size), __FILE__, __LINE__)
 
@@ -289,6 +291,8 @@
 #endif
 
 /* Declare internal functions that benefit from compiler attributes. */
+static void die(const char *, ...)
+    __attribute__((__nonnull__, __noreturn__, __format__(printf, 1, 2)));
 static void sysdie(const char *, ...)
     __attribute__((__nonnull__, __noreturn__, __format__(printf, 1, 2)));
 static void *x_calloc(size_t, size_t, const char *, int)
@@ -299,9 +303,29 @@
     __attribute__((__alloc_size__(2, 3), __malloc__, __nonnull__(4)));
 static char *x_strdup(const char *, const char *, int)
     __attribute__((__malloc__, __nonnull__));
+static char *x_strndup(const char *, size_t, const char *, int)
+    __attribute__((__malloc__, __nonnull__));
 
 
 /*
+ * Report a fatal error and exit.
+ */
+static void
+die(const char *format, ...)
+{
+    va_list args;
+
+    fflush(stdout);
+    fprintf(stderr, "runtests: ");
+    va_start(args, format);
+    vfprintf(stderr, format, args);
+    va_end(args);
+    fprintf(stderr, "\n");
+    exit(1);
+}
+
+
+/*
  * Report a fatal error, including the results of strerror, and exit.
  */
 static void
@@ -401,6 +425,35 @@
 
 
 /*
+ * Copy the first n characters of a string, reporting a fatal error and
+ * existing on failure.
+ *
+ * Avoid using the system strndup function since it may not exist (on Mac OS
+ * X, for example), and there's no need to introduce another portability
+ * requirement.
+ */
+char *
+x_strndup(const char *s, size_t size, const char *file, int line)
+{
+    const char *p;
+    size_t len;
+    char *copy;
+
+    /* Don't assume that the source string is nul-terminated. */
+    for (p = s; (size_t) (p - s) < size && *p != '\0'; p++)
+        ;
+    len = (size_t) (p - s);
+    copy = malloc(len + 1);
+    if (copy == NULL)
+        sysdie("failed to strndup %lu bytes at %s line %d",
+               (unsigned long) len, file, line);
+    memcpy(copy, s, len);
+    copy[len] = '\0';
+    return copy;
+}
+
+
+/*
  * Form a new string by concatenating multiple strings.  The arguments must be
  * terminated by (const char *) 0.
  *
@@ -494,12 +547,25 @@
 
 
 /*
+ * Given a pointer to a string, skip any non-whitespace characters and return
+ * a pointer to the first whitespace character, or to the end of the string.
+ */
+static const char *
+skip_non_whitespace(const char *p)
+{
+    while (*p != '\0' && !isspace((unsigned char)(*p)))
+        p++;
+    return p;
+}
+
+
+/*
  * Start a program, connecting its stdout to a pipe on our end and its stderr
  * to /dev/null, and storing the file descriptor to read from in the two
  * argument.  Returns the PID of the new process.  Errors are fatal.
  */
 static pid_t
-test_start(const char *path, int *fd)
+test_start(char *const *command, int *fd)
 {
     int fds[2], infd, errfd;
     pid_t child;
@@ -550,7 +616,7 @@
         }
 
         /* Now, exec our process. */
-        if (execl(path, path, (char *) 0) == -1)
+        if (execv(command[0], command) == -1)
             _exit(CHILDERR_EXEC);
         break;
 
@@ -1045,7 +1111,7 @@
     char buffer[BUFSIZ];
 
     /* Run the test program. */
-    testpid = test_start(ts->path, &outfd);
+    testpid = test_start(ts->command, &outfd);
     output = fdopen(outfd, "r");
     if (!output) {
         puts("ABORTED");
@@ -1215,6 +1281,98 @@
 
 
 /*
+ * Parse a single line of a test list and store the test name and command to
+ * execute it in the given testset struct.
+ *
+ * Normally, each line is just the name of the test, which is located in the
+ * test directory and turned into a command to run.  However, each line may
+ * have whitespace-separated options, which change the command that's run.
+ * Current supported options are:
+ *
+ * valgrind
+ *     Run the test under valgrind if C_TAP_VALGRIND is set.  The contents
+ *     of that environment variable are taken as the valgrind command (with
+ *     options) to run.  The command is parsed with a simple split on
+ *     whitespace and no quoting is supported.
+ *
+ * libtool
+ *     If running under valgrind, use libtool to invoke valgrind.  This avoids
+ *     running valgrind on the wrapper shell script generated by libtool.  If
+ *     set, C_TAP_LIBTOOL must be set to the full path to the libtool program
+ *     to use to run valgrind and thus the test.  Ignored if the test isn't
+ *     being run under valgrind.
+ */
+static void
+parse_test_list_line(const char *line, struct testset *ts, const char *source,
+                     const char *build)
+{
+    const char *p, *end, *option, *libtool;
+    const char *valgrind = NULL;
+    unsigned int use_libtool = 0;
+    unsigned int use_valgrind = 0;
+    size_t len, i;
+
+    /* Determine the name of the test. */
+    p = skip_non_whitespace(line);
+    ts->file = xstrndup(line, p - line);
+
+    /* Check if any test options are set. */
+    p = skip_whitespace(p);
+    while (*p != '\0') {
+        end = skip_non_whitespace(p);
+        if (strncmp(p, "libtool", end - p) == 0) {
+            use_libtool = 1;
+            p = end;
+        } else if (strncmp(p, "valgrind", end - p) == 0) {
+            valgrind = getenv("C_TAP_VALGRIND");
+            use_valgrind = (valgrind != NULL);
+            p = end;
+        } else {
+            option = xstrndup(p, end - p);
+            die("unknown test list option %s", option);
+        }
+        p = skip_whitespace(end);
+    }
+
+    /* Construct the argv to run the test.  First, find the length. */
+    len = 1;
+    if (use_valgrind && valgrind != NULL) {
+        p = skip_whitespace(valgrind);
+        while (*p != '\0') {
+            len++;
+            p = skip_whitespace(skip_non_whitespace(p));
+        }
+        if (use_libtool)
+            len += 2;
+    }
+
+    /* Now, build the command. */
+    ts->command = xcalloc(len + 1, sizeof(char *));
+    i = 0;
+    if (use_valgrind && valgrind != NULL) {
+        if (use_libtool) {
+            libtool = getenv("C_TAP_LIBTOOL");
+            if (libtool == NULL)
+                die("valgrind with libtool requested, but C_TAP_LIBTOOL is not"
+                    " set");
+            ts->command[i++] = xstrdup(libtool);
+            ts->command[i++] = xstrdup("--mode=execute");
+        }
+        p = skip_whitespace(valgrind);
+        while (*p != '\0') {
+            end = skip_non_whitespace(p);
+            ts->command[i++] = xstrndup(p, end - p);
+            p = skip_whitespace(end);
+        }
+    }
+    if (i != len - 1)
+        die("internal error while constructing command line");
+    ts->command[i++] = find_test(ts->file, source, build);
+    ts->command[i] = NULL;
+}
+
+
+/*
  * Read a list of tests from a file, returning the list of tests as a struct
  * testlist, or NULL if there were no tests (such as a file containing only
  * comments).  Reports an error to standard error and exits if the list of
@@ -1221,13 +1379,13 @@
  * tests cannot be read.
  */
 static struct testlist *
-read_test_list(const char *filename)
+read_test_list(const char *filename, const char *source, const char *build)
 {
     FILE *file;
     unsigned int line;
     size_t length;
     char buffer[BUFSIZ];
-    const char *testname;
+    const char *start;
     struct testlist *listhead, *current;
 
     /* Create the initial container list that will hold our results. */
@@ -1252,10 +1410,10 @@
         buffer[length] = '\0';
 
         /* Skip comments, leading spaces, and blank lines. */
-        testname = skip_whitespace(buffer);
-        if (strlen(testname) == 0)
+        start = skip_whitespace(buffer);
+        if (strlen(start) == 0)
             continue;
-        if (testname[0] == '#')
+        if (start[0] == '#')
             continue;
 
         /* Allocate the new testset structure. */
@@ -1267,7 +1425,9 @@
         }
         current->ts = xcalloc(1, sizeof(struct testset));
         current->ts->plan = PLAN_INIT;
-        current->ts->file = xstrdup(testname);
+
+        /* Parse the line and store the results in the testset struct. */
+        parse_test_list_line(start, current->ts, source, build);
     }
     fclose(file);
 
@@ -1289,7 +1449,7 @@
  * freeing.
  */
 static struct testlist *
-build_test_list(char *argv[], int argc)
+build_test_list(char *argv[], int argc, const char *source, const char *build)
 {
     int i;
     struct testlist *listhead, *current;
@@ -1309,6 +1469,9 @@
         current->ts = xcalloc(1, sizeof(struct testset));
         current->ts->plan = PLAN_INIT;
         current->ts->file = xstrdup(argv[i]);
+        current->ts->command = xcalloc(2, sizeof(char *));
+        current->ts->command[0] = find_test(current->ts->file, source, build);
+        current->ts->command[1] = NULL;
     }
 
     /* If there were no tests, current is still NULL. */
@@ -1326,8 +1489,12 @@
 static void
 free_testset(struct testset *ts)
 {
+    size_t i;
+
     free(ts->file);
-    free(ts->path);
+    for (i = 0; ts->command[i] != NULL; i++)
+        free(ts->command[i]);
+    free(ts->command);
     free(ts->results);
     free(ts->reason);
     free(ts);
@@ -1342,8 +1509,7 @@
  * frees the test list that's passed in.
  */
 static int
-test_batch(struct testlist *tests, const char *source, const char *build,
-           enum test_verbose verbose)
+test_batch(struct testlist *tests, enum test_verbose verbose)
 {
     size_t length, i;
     size_t longest = 0;
@@ -1394,7 +1560,6 @@
             fflush(stdout);
 
         /* Run the test. */
-        ts->path = find_test(ts->file, source, build);
         succeeded = test_run(ts, verbose);
         fflush(stdout);
         if (verbose)
@@ -1584,11 +1749,11 @@
         else
             shortlist++;
         printf(banner, shortlist);
-        tests = read_test_list(list);
-        status = test_batch(tests, source, build, verbose) ? 0 : 1;
+        tests = read_test_list(list, source, build);
+        status = test_batch(tests, verbose) ? 0 : 1;
     } else {
-        tests = build_test_list(argv, argc);
-        status = test_batch(tests, source, build, verbose) ? 0 : 1;
+        tests = build_test_list(argv, argc, source, build);
+        status = test_batch(tests, verbose) ? 0 : 1;
     }
 
     /* For valgrind cleanliness, free all our memory. */



More information about the inn-committers mailing list