diff options
Diffstat (limited to 'test')
-rw-r--r-- | test/run-test.c | 301 |
1 files changed, 152 insertions, 149 deletions
diff --git a/test/run-test.c b/test/run-test.c index 7084189..78fb7d1 100644 --- a/test/run-test.c +++ b/test/run-test.c @@ -52,181 +52,184 @@ static int fork_exec(int *pfdin, int *pfdout, const char *path, char *const *arg) { - int pin[2], pout[2]; - int pid; - - if (pfdin && (pipe(pin) == -1)) - return 0; - if (pfdout && (pipe(pout) == -1)) - return 0; - - if ((pid = fork()) == 0) { - if (pfdout) { - if (dup2(pout[0], STDIN_FILENO) < 0) - _exit(127); - close(pout[0]); - close(pout[1]); - } - - if (pfdin) { - if (dup2(pin[1], STDOUT_FILENO) < 0) - _exit(127); - close(pin[0]); - close(pin[1]); - } - - execvp(path, arg); - _exit(127); - } else { - if (pfdin) - close(pin[1]); - if (pfdout) - close(pout[0]); - - if (pid > 0) { - if (pfdin) { - fcntl(pin[0], F_SETFD, FD_CLOEXEC); - *pfdin = pin[0]; - } - if (pfdout) { - fcntl(pout[1], F_SETFD, FD_CLOEXEC); - *pfdout = pout[1]; - } - } else { - if (pfdin) - close(pin[0]); - if (pfdout) - close(pout[1]); - return 0; - } - } - return pid; + int pin[2], pout[2]; + int pid; + + if (pfdin && (pipe(pin) == -1)) + return 0; + if (pfdout && (pipe(pout) == -1)) + return 0; + + if ((pid = fork()) == 0) { + if (pfdout) { + if (dup2(pout[0], STDIN_FILENO) < 0) + _exit(127); + close(pout[0]); + close(pout[1]); + } + + if (pfdin) { + if (dup2(pin[1], STDOUT_FILENO) < 0) + _exit(127); + close(pin[0]); + close(pin[1]); + } + + execvp(path, arg); + _exit(127); + } else { + if (pfdin) + close(pin[1]); + if (pfdout) + close(pout[0]); + + if (pid > 0) { + if (pfdin) { + fcntl(pin[0], F_SETFD, FD_CLOEXEC); + *pfdin = pin[0]; + } + if (pfdout) { + fcntl(pout[1], F_SETFD, FD_CLOEXEC); + *pfdout = pout[1]; + } + } else { + if (pfdin) + close(pin[0]); + if (pfdout) + close(pout[1]); + return 0; + } + } + return pid; } /* Wait for a child process to terminate. */ static int child_wait(int *pfdin, int *pfdout, int pid) { - int stat; + int stat; - if (pfdin) - close(*pfdin); - if (pfdout) - close(*pfdout); + if (pfdin) + close(*pfdin); + if (pfdout) + close(*pfdout); - waitpid(pid, &stat, 0); - return stat; + waitpid(pid, &stat, 0); + return stat; } /* Print error message and bail out. */ static void die(const char *format, ...) { - va_list arg; + va_list arg; - va_start(arg, format); - fprintf(stderr, "error: "); - vfprintf(stderr, format, arg); - va_end(arg); + va_start(arg, format); + fprintf(stderr, "error: "); + vfprintf(stderr, format, arg); + va_end(arg); - exit(1); + exit(1); } /* Print usage message. */ static void usage(void) { - printf("usage: run-test [-h|--help] <test>...\n"); + printf("usage: run-test [-h|--help] <test>...\n"); } /* Run test with a specific name. */ static int run_test(const char *name, int expect_failure) { - char filename[BUFSIZ]; - char *arg1[3], *arg2[3]; - int pid1 = -1, pin1, pid2 = -1, pin2; - FILE *fpin1 = NULL, *fpin2 = NULL; - char buf1[BUFSIZ], buf2[BUFSIZ]; - int ret = 1; - - if (snprintf(filename, BUFSIZ, "./%s", name) >= BUFSIZ) - die("file name too long\n"); - - if (access(filename, F_OK) != 0) { - if (snprintf(filename, BUFSIZ, "./%s.sh", name) >= BUFSIZ) - die("file name too long\n"); - - if (access(filename, F_OK) != 0) - die("test not found: %s\n", name); - } - - if (access(filename, X_OK) != 0) - die("script is not executable: %s\n", filename); - - arg1[0] = arg2[0] = filename; - arg1[1] = "expected"; - arg2[1] = "actual"; - arg1[2] = arg2[2] = NULL; - - printf("Running %s...", name); - - if ((pid1 = fork_exec(&pin1, NULL, *arg1, arg1)) < 0) - die("failed to execute %s: %s\n", filename, strerror(errno)); - - if ((pid2 = fork_exec(&pin2, NULL, *arg2, arg2)) < 0) - die("failed to execute %s: %s\n", filename, strerror(errno)); - - fpin1 = fdopen(pin1, "r"); - fpin2 = fdopen(pin2, "r"); - - while (fgets(buf1, BUFSIZ, fpin1)) { - if (!fgets(buf2, BUFSIZ, fpin2) || strcmp(buf1, buf2) != 0) { - ret = 0; - break; - } - } - - if (fgets(buf2, BUFSIZ, fpin2)) - ret = 0; - - if (fpin1) - fclose(fpin1); - if (fpin2) - fclose(fpin2); - - if (child_wait(&pin1, NULL, pid1) != 0) - ret = 0; - if (child_wait(&pin2, NULL, pid2) != 0) - ret = 0; - - if (expect_failure) - ret = 1 - ret; - - if (ret == 1) - printf(" ok\n"); - else - printf(" FAIL\n"); - - return ret; + char filename[BUFSIZ]; + char *arg1[3], *arg2[3]; + int pid1 = -1, pin1, pid2 = -1, pin2; + FILE *fpin1 = NULL, *fpin2 = NULL; + char buf1[BUFSIZ], buf2[BUFSIZ]; + int ret = 1; + + if (snprintf(filename, BUFSIZ, "./%s", name) >= BUFSIZ) + die("file name too long\n"); + + if (access(filename, F_OK) != 0) { + if (snprintf(filename, BUFSIZ, "./%s.sh", name) >= BUFSIZ) + die("file name too long\n"); + + if (access(filename, F_OK) != 0) + die("test not found: %s\n", name); + } + + if (access(filename, X_OK) != 0) + die("script is not executable: %s\n", filename); + + arg1[0] = arg2[0] = filename; + arg1[1] = "expected"; + arg2[1] = "actual"; + arg1[2] = arg2[2] = NULL; + + printf("Running %s...", name); + + if ((pid1 = fork_exec(&pin1, NULL, *arg1, arg1)) < 0) + die("failed to execute %s: %s\n", filename, + strerror(errno)); + + if ((pid2 = fork_exec(&pin2, NULL, *arg2, arg2)) < 0) + die("failed to execute %s: %s\n", filename, + strerror(errno)); + + fpin1 = fdopen(pin1, "r"); + fpin2 = fdopen(pin2, "r"); + + while (fgets(buf1, BUFSIZ, fpin1)) { + if (!fgets(buf2, BUFSIZ, fpin2) || strcmp(buf1, buf2) != 0) { + ret = 0; + break; + } + } + + if (fgets(buf2, BUFSIZ, fpin2)) + ret = 0; + + if (fpin1) + fclose(fpin1); + if (fpin2) + fclose(fpin2); + + if (child_wait(&pin1, NULL, pid1) != 0) + ret = 0; + if (child_wait(&pin2, NULL, pid2) != 0) + ret = 0; + + if (expect_failure) + ret = 1 - ret; + + if (ret == 1) + printf(" ok\n"); + else + printf(" FAIL\n"); + + return ret; } int main(int argc, char **argv) { - int i; - - if (!argv[1]) - die("no tests specified, bailing out\n"); - else if (strcmp(argv[1], "-h") == 0 || strcmp(argv[1], "--help") == 0) { - usage(); - return 0; - } - - for (i = 1; i < argc; i++) { - if (*argv[i] == '!') { - if (!run_test(argv[i] + 1, 1)) - return 1; - } else { - if (!run_test(argv[i], 0)) - return 1; - } - } - - return 0; + int i; + + if (!argv[1]) + die("no tests specified, bailing out\n"); + else if (strcmp(argv[1], "-h") == 0 + || strcmp(argv[1], "--help") == 0) { + usage(); + return 0; + } + + for (i = 1; i < argc; i++) { + if (*argv[i] == '!') { + if (!run_test(argv[i] + 1, 1)) + return 1; + } else { + if (!run_test(argv[i], 0)) + return 1; + } + } + + return 0; } |