Fix up line numbers after commit 109
[ccan] / ccan / tap / test / run.c
1 /* We use the fact that pipes have a buffer greater than the size of
2  * any output, and change stdout and stderr to use that.
3  *
4  * Since we don't use libtap for output, this looks like one big test. */
5 #include "tap/tap.h"
6 #include <stdio.h>
7 #include <unistd.h>
8 #include <stdarg.h>
9 #include <err.h>
10 #include <string.h>
11 #include <stdlib.h>
12 #include <limits.h>
13 #include <stdbool.h>
14 #include <fnmatch.h>
15
16 /* We dup stderr to here. */
17 static int stderrfd;
18
19 /* write_all inlined here to avoid circular dependency. */
20 static void write_all(int fd, const void *data, size_t size)
21 {
22         while (size) {
23                 ssize_t done;
24
25                 done = write(fd, data, size);
26                 if (done <= 0)
27                         _exit(1);
28                 data += done;
29                 size -= done;
30         }
31 }
32
33 /* Simple replacement for err() */
34 static void failmsg(const char *fmt, ...)
35 {
36         char buf[1024];
37         va_list ap;
38
39         /* Write into buffer. */
40         va_start(ap, fmt);
41         vsprintf(buf, fmt, ap);
42         va_end(ap);
43
44         write_all(stderrfd, "# ", 2);
45         write_all(stderrfd, buf, strlen(buf));
46         write_all(stderrfd, "\n", 1);
47         _exit(1);
48 }
49
50 static void expect(int fd, const char *pattern)
51 {
52         char buffer[PIPE_BUF+1];
53         int r;
54
55         r = read(fd, buffer, sizeof(buffer)-1);
56         if (r < 0)
57                 failmsg("reading from pipe");
58         buffer[r] = '\0';
59
60         if (fnmatch(pattern, buffer, 0) != 0)
61                 failmsg("Expected '%s' got '%s'", pattern, buffer);
62 }
63
64 int main(int argc, char *argv[])
65 {
66         int p[2];
67         int stdoutfd;
68
69         printf("1..1\n");
70         fflush(stdout);
71         stderrfd = dup(STDERR_FILENO);
72         if (stderrfd < 0)
73                 err(1, "dup of stderr failed");
74
75         stdoutfd = dup(STDOUT_FILENO);
76         if (stdoutfd < 0)
77                 err(1, "dup of stdout failed");
78
79         if (pipe(p) != 0)
80                 failmsg("pipe failed");
81
82         if (dup2(p[1], STDERR_FILENO) < 0 || dup2(p[1], STDOUT_FILENO) < 0)
83                 failmsg("Duplicating file descriptor");
84
85         plan_tests(10);
86         expect(p[0], "1..10\n");
87
88         ok(1, "msg1");
89         expect(p[0], "ok 1 - msg1\n");
90
91         ok(0, "msg2");
92         expect(p[0], "not ok 2 - msg2\n"
93                "#     Failed test (*tap/test/run.c:main() at line 91)\n");
94
95         ok1(true);
96         expect(p[0], "ok 3 - true\n");
97
98         ok1(false);
99         expect(p[0], "not ok 4 - false\n"
100                "#     Failed test (*tap/test/run.c:main() at line 98)\n");
101
102         pass("passed");
103         expect(p[0], "ok 5 - passed\n");
104
105         fail("failed");
106         expect(p[0], "not ok 6 - failed\n"
107                "#     Failed test (*tap/test/run.c:main() at line 105)\n");
108
109         skip(2, "skipping %s", "test");
110         expect(p[0], "ok 7 # skip skipping test\n"
111                "ok 8 # skip skipping test\n");
112
113         todo_start("todo");
114         ok1(false);
115         expect(p[0], "not ok 9 - false # TODO todo\n"
116                "#     Failed (TODO) test (*tap/test/run.c:main() at line 114)\n");
117         ok1(true);
118         expect(p[0], "ok 10 - true # TODO todo\n");
119         todo_end();
120
121         if (exit_status() != 3)
122                 failmsg("Expected exit status 3, not %i", exit_status());
123
124 #if 0
125         /* Manually run the atexit command. */
126         _cleanup();
127         expect(p[0], "# Looks like you failed 2 tests of 9.\n");
128 #endif
129
130         write_all(stdoutfd, "ok 1 - All passed\n",
131                   strlen("ok 1 - All passed\n"));
132         _exit(0);
133 }