failtest: capture pread/pwrite
[ccan] / ccan / failtest / failtest.h
1 #ifndef CCAN_FAILTEST_H
2 #define CCAN_FAILTEST_H
3 #include <sys/types.h>
4 #include <stdbool.h>
5 #include <fcntl.h>
6 #include <ccan/compiler/compiler.h>
7
8 /**
9  * failtest_init - initialize the failtest module
10  * @argc: the number of commandline arguments
11  * @argv: the commandline argument array
12  *
13  * This initializes the module, and in particular if argv[1] is "--failpath="
14  * then it ensures that failures follow that pattern.  This allows easy
15  * debugging of complex failure paths.
16  */
17 void failtest_init(int argc, char *argv[]);
18
19 /**
20  * failtest_exit - clean up and exit the test
21  * @status: the status (usually exit_status() from ccan/tap).
22  *
23  * This cleans up and changes to files made in this child, and exits the test.
24  * It also calls your failtest_default_hook, if any.
25  *
26  * A child which does not exit via failtest_exit() will cause the overall test
27  * to fail.
28  */
29 void NORETURN failtest_exit(int status);
30
31 /**
32  * enum failtest_call_type - discriminator for failtest_call.u
33  */
34 enum failtest_call_type {
35         FAILTEST_MALLOC,
36         FAILTEST_CALLOC,
37         FAILTEST_REALLOC,
38         FAILTEST_OPEN,
39         FAILTEST_PIPE,
40         FAILTEST_READ,
41         FAILTEST_WRITE,
42         FAILTEST_FCNTL,
43 };
44
45 struct calloc_call {
46         void *ret;
47         size_t nmemb;
48         size_t size;
49 };
50
51 struct malloc_call {
52         void *ret;
53         size_t size;
54 };
55
56 struct realloc_call {
57         void *ret;
58         void *ptr;
59         size_t size;
60 };
61
62 struct open_call {
63         int ret;
64         const char *pathname;
65         int flags;
66         mode_t mode;
67 };
68
69 struct pipe_call {
70         int ret;
71         int fds[2];
72 };
73
74 struct read_call {
75         ssize_t ret;
76         int fd;
77         void *buf;
78         size_t count;
79         off_t off;
80 };
81
82 struct write_call {
83         ssize_t ret;
84         int fd;
85         const void *buf;
86         size_t count;
87         off_t off;
88 };
89
90 struct fcntl_call {
91         int ret;
92         int fd;
93         int cmd;
94         union {
95                 struct flock fl;
96                 long l;
97                 int i;
98         } arg;
99 };
100
101 /**
102  * struct failtest_call - description of a call redirected to failtest module
103  * @type: the call type
104  * @file: the filename of the caller
105  * @line: the line number of the caller
106  * @fail: did this call fail
107  * @error: the errno (if any)
108  * @u: the union of call data
109  *
110  * This structure is used to represent the ordered history of calls.
111  *
112  * See Also:
113  *      failtest_hook, failtest_exit_check
114  */
115 struct failtest_call {
116         enum failtest_call_type type;
117         /* Where we were called from. */
118         const char *file;
119         unsigned int line;
120         /* Did we fail? */
121         bool fail;
122         /* What we set errno to. */
123         int error;
124         /* The actual call data. */
125         union {
126                 struct calloc_call calloc;
127                 struct malloc_call malloc;
128                 struct realloc_call realloc;
129                 struct open_call open;
130                 struct pipe_call pipe;
131                 struct read_call read;
132                 struct write_call write;
133                 struct fcntl_call fcntl;
134         } u;
135 };
136
137 /**
138  * failtest_hook - whether a certain call should fail or not.
139  * @history: the ordered history of all failtest calls.
140  * @num: the number of elements in @history (greater than 0)
141  *
142  * The default value of this hook is failtest_default_hook(), which returns
143  * true (ie. yes, fail the call).
144  *
145  * You can override it, and avoid failing certain calls.  The parameters
146  * of the call (but not the return value(s)) will be filled in for the last
147  * call.
148  *
149  * Example:
150  *      static bool dont_fail_allocations(struct failtest_call *history,
151  *                                        unsigned num)
152  *      {
153  *              return history[num-1].type != FAILTEST_MALLOC
154  *                      && history[num-1].type != FAILTEST_CALLOC
155  *                      && history[num-1].type != FAILTEST_REALLOC;
156  *      }
157  *      ...
158  *              failtest_hook = dont_fail_allocations;
159  */
160 extern bool (*failtest_hook)(struct failtest_call *history, unsigned num);
161
162 /**
163  * failtest_exit_check - hook for additional checks on a failed child.
164  * @history: the ordered history of all failtest calls.
165  * @num: the number of elements in @history (greater than 0)
166  *
167  * Your program might have additional checks to do on failure, such as
168  * check that a file is not corrupted, or than an error message has been
169  * logged.
170  *
171  * If this returns false, the path to this failure will be printed and the
172  * overall test will fail.
173  */
174 extern bool (*failtest_exit_check)(struct failtest_call *history,
175                                    unsigned num);
176
177 /* This usually fails the call. */
178 bool failtest_default_hook(struct failtest_call *history, unsigned num);
179
180 /**
181  * failtest_timeout_ms - how long to wait before killing child.
182  *
183  * Default is 20,000 (20 seconds).
184  */
185 extern unsigned int failtest_timeout_ms;
186 #endif /* CCAN_FAILTEST_H */