]> git.ozlabs.org Git - ccan/blob - ccan/failtest/failtest.h
Fix missing va_end()s
[ccan] / ccan / failtest / failtest.h
1 /* Licensed under LGPL - see LICENSE file for details */
2 #ifndef CCAN_FAILTEST_H
3 #define CCAN_FAILTEST_H
4 #include "config.h"
5 #if HAVE_FILE_OFFSET_BITS
6 #define _FILE_OFFSET_BITS 64
7 #endif
8 #include <sys/types.h>
9 #include <stdbool.h>
10 #include <fcntl.h>
11 #include <ccan/compiler/compiler.h>
12 #include <ccan/tlist/tlist.h>
13
14 /**
15  * failtest_init - initialize the failtest module
16  * @argc: the number of commandline arguments
17  * @argv: the commandline argument array
18  *
19  * This initializes the module, and in particular if argv[1] is "--failpath="
20  * then it ensures that failures follow that pattern.  This allows easy
21  * debugging of complex failure paths.
22  */
23 void failtest_init(int argc, char *argv[]);
24
25 /**
26  * failtest_exit - clean up and exit the test
27  * @status: the status (usually exit_status() from ccan/tap).
28  *
29  * This cleans up and changes to files made in this child, and exits the test.
30  * It also calls your failtest_default_hook, if any.
31  *
32  * A child which does not exit via failtest_exit() will cause the overall test
33  * to fail.
34  */
35 void NORETURN failtest_exit(int status);
36
37 /**
38  * enum failtest_call_type - discriminator for failtest_call.u
39  */
40 enum failtest_call_type {
41         FAILTEST_MALLOC,
42         FAILTEST_CALLOC,
43         FAILTEST_REALLOC,
44         FAILTEST_OPEN,
45         FAILTEST_CLOSE,
46         FAILTEST_PIPE,
47         FAILTEST_READ,
48         FAILTEST_WRITE,
49         FAILTEST_FCNTL,
50         FAILTEST_MMAP,
51         FAILTEST_LSEEK
52 };
53
54 struct calloc_call {
55         void *ret;
56         size_t nmemb;
57         size_t size;
58 };
59
60 struct malloc_call {
61         void *ret;
62         size_t size;
63 };
64
65 struct realloc_call {
66         void *ret;
67         void *ptr;
68         size_t size;
69 };
70
71 struct open_call {
72         int ret;
73         const char *pathname;
74         int flags;
75         mode_t mode;
76         bool always_save;
77         bool closed;
78         /* This is used for O_TRUNC opens on existing files. */
79         struct contents_saved *saved;
80 };
81
82 struct close_call {
83         int fd;
84 };
85
86 struct pipe_call {
87         int ret;
88         int fds[2];
89         bool closed[2];
90 };
91
92 struct read_call {
93         ssize_t ret;
94         off_t off;
95         int fd;
96         void *buf;
97         size_t count;
98 };
99
100 struct write_call {
101         ssize_t ret;
102         int fd;
103         const void *buf;
104         size_t count;
105         off_t off;
106         bool is_pwrite;
107         struct failtest_call *opener;
108         struct contents_saved *saved;
109 };
110
111 struct fcntl_call {
112         int ret;
113         int fd;
114         int cmd;
115         union {
116                 struct flock fl;
117                 long l;
118                 int i;
119         } arg;
120 };
121
122 struct mmap_call {
123         void *ret;
124         void *addr;
125         size_t length;
126         int prot;
127         int flags;
128         int fd;
129         off_t offset;
130         struct failtest_call *opener;
131         struct contents_saved *saved;
132 };
133
134 struct lseek_call {
135         ssize_t ret;
136         int fd;
137         off_t offset;
138         int whence;
139         off_t old_off;
140 };
141
142 /**
143  * struct failtest_call - description of a call redirected to failtest module
144  * @type: the call type
145  * @file: the filename of the caller
146  * @line: the line number of the caller
147  * @fail: did this call fail
148  * @error: the errno (if any)
149  * @u: the union of call data
150  *
151  * This structure is used to represent the ordered history of calls.
152  *
153  * See Also:
154  *      failtest_hook, failtest_exit_check
155  */
156 struct failtest_call {
157         /* We're in the history list. */
158         struct list_node list;
159         enum failtest_call_type type;
160         /* Where we were called from. */
161         const char *file;
162         unsigned int line;
163         /* Did we fail? */
164         bool fail;
165         /* What we set errno to. */
166         int error;
167         /* How do we clean this up? */
168         void (*cleanup)(void *u, bool restore);
169         /* Should their program have cleaned up? */
170         bool can_leak;
171         /* Backtrace of call chain. */
172         void **backtrace;
173         unsigned int backtrace_num;
174         /* The actual call data. */
175         union {
176                 struct calloc_call calloc;
177                 struct malloc_call malloc;
178                 struct realloc_call realloc;
179                 struct open_call open;
180                 struct close_call close;
181                 struct pipe_call pipe;
182                 struct read_call read;
183                 struct write_call write;
184                 struct fcntl_call fcntl;
185                 struct mmap_call mmap;
186                 struct lseek_call lseek;
187         } u;
188 };
189
190 /* This defines struct tlist_calls. */
191 TLIST_TYPE(calls, struct failtest_call);
192
193 enum failtest_result {
194         /* Yes try failing this call. */
195         FAIL_OK,
196         /* No, don't try failing this call. */
197         FAIL_DONT_FAIL,
198         /* Try failing this call but don't go too far down that path. */
199         FAIL_PROBE,
200 };
201
202 /**
203  * failtest_hook - whether a certain call should fail or not.
204  * @history: the ordered history of all failtest calls.
205  *
206  * The default value of this hook is failtest_default_hook(), which returns
207  * FAIL_OK (ie. yes, fail the call).
208  *
209  * You can override it, and avoid failing certain calls.  The parameters
210  * of the call (but not the return value(s)) will be filled in for the last
211  * call.
212  *
213  * Example:
214  *      static enum failtest_result dont_fail_alloc(struct tlist_calls *history)
215  *      {
216  *              struct failtest_call *call;
217  *              call = tlist_tail(history, list);
218  *              if (call->type == FAILTEST_MALLOC
219  *                      || call->type == FAILTEST_CALLOC
220  *                      || call->type == FAILTEST_REALLOC)
221  *                      return FAIL_DONT_FAIL;
222  *              return FAIL_OK;
223  *      }
224  *      ...
225  *              failtest_hook = dont_fail_alloc;
226  */
227 extern enum failtest_result (*failtest_hook)(struct tlist_calls *history);
228
229 /**
230  * failtest_exit_check - hook for additional checks on a failed child.
231  * @history: the ordered history of all failtest calls.
232  *
233  * Your program might have additional checks to do on failure, such as
234  * check that a file is not corrupted, or than an error message has been
235  * logged.
236  *
237  * If this returns false, the path to this failure will be printed and the
238  * overall test will fail.
239  */
240 extern bool (*failtest_exit_check)(struct tlist_calls *history);
241
242 /**
243  * failtest_has_failed - determine if a failure has occurred.
244  *
245  * Sometimes you want to exit immediately if you've experienced an
246  * injected failure.  This is useful when you have four separate tests
247  * in your test suite, and you don't want to do the next one if you've
248  * had a failure in a previous one.
249  */
250 extern bool failtest_has_failed(void);
251
252 /**
253  * failtest_timeout_ms - how long to wait before killing child.
254  *
255  * Default is 20,000 (20 seconds).
256  */
257 extern unsigned int failtest_timeout_ms;
258 #endif /* CCAN_FAILTEST_H */