failtest: fcntl handling
[ccan] / ccan / failtest / test / run-history.c
1 #include <stdlib.h>
2 #include <stdio.h>
3 #include <stdarg.h>
4 #include <ccan/tap/tap.h>
5
6 #define printf saved_printf
7 static int saved_printf(const char *fmt, ...);
8
9 #define fprintf saved_fprintf
10 static int saved_fprintf(FILE *ignored, const char *fmt, ...);
11
12 /* Include the C files directly. */
13 #include <ccan/failtest/failtest.c>
14
15 static char *output = NULL;
16
17 static int saved_vprintf(const char *fmt, va_list ap)
18 {
19         int ret = vsnprintf(NULL, 0, fmt, ap);
20         int len = 0;
21
22         if (output)
23                 len = strlen(output);
24
25         output = realloc(output, len + ret + 1);
26         return vsprintf(output + len, fmt, ap);
27 }
28
29 static int saved_printf(const char *fmt, ...)
30 {
31         va_list ap;
32         int ret;
33
34         va_start(ap, fmt);
35         ret = saved_vprintf(fmt, ap);
36         va_end(ap);
37         return ret;
38 }       
39
40 static int saved_fprintf(FILE *ignored, const char *fmt, ...)
41 {
42         va_list ap;
43         int ret;
44
45         va_start(ap, fmt);
46         ret = saved_vprintf(fmt, ap);
47         va_end(ap);
48         return ret;
49 }       
50
51 int main(void)
52 {
53         struct failtest_call *call;
54         struct calloc_call calloc_call;
55         struct malloc_call malloc_call;
56         struct realloc_call realloc_call;
57         struct open_call open_call;
58         struct pipe_call pipe_call;
59         struct read_call read_call;
60         struct write_call write_call;
61         char buf[20];
62         unsigned int i;
63
64         /* This is how many tests you plan to run */
65         plan_tests(47);
66
67         calloc_call.ret = calloc(1, 2);
68         calloc_call.nmemb = 1;
69         calloc_call.size = 2;
70         call = add_history(FAILTEST_CALLOC, "run-history.c", 1, &calloc_call);
71         ok1(call->type == FAILTEST_CALLOC);
72         ok1(strcmp(call->file, "run-history.c") == 0);
73         ok1(call->line == 1);
74         ok1(call->u.calloc.ret == calloc_call.ret);
75         ok1(call->u.calloc.nmemb == calloc_call.nmemb);
76         ok1(call->u.calloc.size == calloc_call.size);
77
78         malloc_call.ret = malloc(2);
79         malloc_call.size = 2;
80         call = add_history(FAILTEST_MALLOC, "run-history.c", 2, &malloc_call);
81         ok1(call->type == FAILTEST_MALLOC);
82         ok1(strcmp(call->file, "run-history.c") == 0);
83         ok1(call->line == 2);
84         ok1(call->u.malloc.ret == malloc_call.ret);
85         ok1(call->u.malloc.size == malloc_call.size);
86
87         realloc_call.ret = realloc(malloc_call.ret, 3);
88         realloc_call.ptr = malloc_call.ret;
89         realloc_call.size = 3;
90         call = add_history(FAILTEST_REALLOC, "run-history.c",
91                            3, &realloc_call);
92         ok1(call->type == FAILTEST_REALLOC);
93         ok1(strcmp(call->file, "run-history.c") == 0);
94         ok1(call->line == 3);
95         ok1(call->u.realloc.ret == realloc_call.ret);
96         ok1(call->u.realloc.ptr == realloc_call.ptr);
97         ok1(call->u.realloc.size == realloc_call.size);
98
99         open_call.ret = open("test/run_history.c", O_RDONLY);
100         open_call.pathname = "test/run_history.c";
101         open_call.flags = O_RDONLY;
102         open_call.mode = 0;
103         call = add_history(FAILTEST_OPEN, "run-history.c", 4, &open_call);
104         ok1(call->type == FAILTEST_OPEN);
105         ok1(strcmp(call->file, "run-history.c") == 0);
106         ok1(call->line == 4);
107         ok1(call->u.open.ret == open_call.ret);
108         ok1(strcmp(call->u.open.pathname, open_call.pathname) == 0);
109         ok1(call->u.open.flags == open_call.flags);
110         ok1(call->u.open.mode == open_call.mode);
111
112         pipe_call.ret = pipe(pipe_call.fds);
113         call = add_history(FAILTEST_PIPE, "run-history.c", 5, &pipe_call);
114         ok1(call->type == FAILTEST_PIPE);
115         ok1(strcmp(call->file, "run-history.c") == 0);
116         ok1(call->line == 5);
117         ok1(call->u.pipe.ret == pipe_call.ret);
118         ok1(call->u.pipe.fds[0] == pipe_call.fds[0]);
119         ok1(call->u.pipe.fds[1] == pipe_call.fds[1]);
120
121         read_call.ret = read(open_call.ret, buf, 20);
122         read_call.buf = buf;
123         read_call.fd = open_call.ret;
124         read_call.count = 20;
125         call = add_history(FAILTEST_READ, "run-history.c", 6, &read_call);
126         ok1(call->type == FAILTEST_READ);
127         ok1(strcmp(call->file, "run-history.c") == 0);
128         ok1(call->line == 6);
129         ok1(call->u.read.ret == read_call.ret);
130         ok1(call->u.read.buf == read_call.buf);
131         ok1(call->u.read.fd == read_call.fd);
132         ok1(call->u.read.count == read_call.count);
133
134         write_call.ret = 20;
135         write_call.buf = buf;
136         write_call.fd = open_call.ret;
137         write_call.count = 20;
138         call = add_history(FAILTEST_WRITE, "run-history.c", 7, &write_call);
139         ok1(call->type == FAILTEST_WRITE);
140         ok1(strcmp(call->file, "run-history.c") == 0);
141         ok1(call->line == 7);
142         ok1(call->u.write.ret == write_call.ret);
143         ok1(call->u.write.buf == write_call.buf);
144         ok1(call->u.write.fd == write_call.fd);
145         ok1(call->u.write.count == write_call.count);
146
147         ok1(history_num == 7);
148
149         for (i = 0; i < history_num; i++)
150                 history[i].fail = false;
151
152         print_reproduce();
153         ok1(strcmp(output, "To reproduce: --failpath=cmeoprw\n") == 0);
154         free(output);
155         output = NULL;
156
157         for (i = 0; i < history_num; i++)
158                 history[i].fail = true;
159
160         print_reproduce();
161         ok1(strcmp(output, "To reproduce: --failpath=CMEOPRW\n") == 0);
162         free(output);
163         output = NULL;
164
165         return exit_status();
166 }