]> git.ozlabs.org Git - ccan/blob - ccan/failtest/failtest.h
tdb2: suppress failtest more than once on mmap.
[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 };
52
53 struct calloc_call {
54         void *ret;
55         size_t nmemb;
56         size_t size;
57 };
58
59 struct malloc_call {
60         void *ret;
61         size_t size;
62 };
63
64 struct realloc_call {
65         void *ret;
66         void *ptr;
67         size_t size;
68 };
69
70 struct open_call {
71         int ret;
72         const char *pathname;
73         int flags;
74         mode_t mode;
75 };
76
77 struct close_call {
78         int fd;
79 };
80
81 struct pipe_call {
82         int ret;
83         int fds[2];
84         bool closed[2];
85 };
86
87 struct read_call {
88         ssize_t ret;
89         off_t off;
90         int fd;
91         void *buf;
92         size_t count;
93 };
94
95 struct write_call {
96         ssize_t ret;
97         int fd;
98         const void *buf;
99         size_t count;
100         off_t off;
101 };
102
103 struct fcntl_call {
104         int ret;
105         int fd;
106         int cmd;
107         union {
108                 struct flock fl;
109                 long l;
110                 int i;
111         } arg;
112 };
113
114 struct mmap_call {
115         void *ret;
116         void *addr;
117         size_t length;
118         int prot;
119         int flags;
120         int fd;
121         off_t offset;
122 };
123
124 /**
125  * struct failtest_call - description of a call redirected to failtest module
126  * @type: the call type
127  * @file: the filename of the caller
128  * @line: the line number of the caller
129  * @fail: did this call fail
130  * @error: the errno (if any)
131  * @u: the union of call data
132  *
133  * This structure is used to represent the ordered history of calls.
134  *
135  * See Also:
136  *      failtest_hook, failtest_exit_check
137  */
138 struct failtest_call {
139         /* We're in the history list. */
140         struct list_node list;
141         enum failtest_call_type type;
142         /* Where we were called from. */
143         const char *file;
144         unsigned int line;
145         /* Did we fail? */
146         bool fail;
147         /* What we set errno to. */
148         int error;
149         /* How do we clean this up? */
150         void (*cleanup)(void *u);
151         /* Backtrace of call chain. */
152         void **backtrace;
153         unsigned int backtrace_num;
154         /* The actual call data. */
155         union {
156                 struct calloc_call calloc;
157                 struct malloc_call malloc;
158                 struct realloc_call realloc;
159                 struct open_call open;
160                 struct close_call close;
161                 struct pipe_call pipe;
162                 struct read_call read;
163                 struct write_call write;
164                 struct fcntl_call fcntl;
165                 struct mmap_call mmap;
166         } u;
167 };
168
169 /* This defines struct tlist_calls. */
170 TLIST_TYPE(calls, struct failtest_call);
171
172 enum failtest_result {
173         /* Yes try failing this call. */
174         FAIL_OK,
175         /* No, don't try failing this call. */
176         FAIL_DONT_FAIL,
177         /* Try failing this call but don't go too far down that path. */
178         FAIL_PROBE,
179 };
180
181 /**
182  * failtest_hook - whether a certain call should fail or not.
183  * @history: the ordered history of all failtest calls.
184  *
185  * The default value of this hook is failtest_default_hook(), which returns
186  * FAIL_OK (ie. yes, fail the call).
187  *
188  * You can override it, and avoid failing certain calls.  The parameters
189  * of the call (but not the return value(s)) will be filled in for the last
190  * call.
191  *
192  * Example:
193  *      static enum failtest_result dont_fail_alloc(struct tlist_calls *history)
194  *      {
195  *              struct failtest_call *call;
196  *              call = tlist_tail(history, struct failtest_call, list);
197  *              if (call->type == FAILTEST_MALLOC
198  *                      || call->type == FAILTEST_CALLOC
199  *                      || call->type == FAILTEST_REALLOC)
200  *                      return FAIL_DONT_FAIL;
201  *              return FAIL_OK;
202  *      }
203  *      ...
204  *              failtest_hook = dont_fail_alloc;
205  */
206 extern enum failtest_result (*failtest_hook)(struct tlist_calls *history);
207
208 /**
209  * failtest_exit_check - hook for additional checks on a failed child.
210  * @history: the ordered history of all failtest calls.
211  *
212  * Your program might have additional checks to do on failure, such as
213  * check that a file is not corrupted, or than an error message has been
214  * logged.
215  *
216  * If this returns false, the path to this failure will be printed and the
217  * overall test will fail.
218  */
219 extern bool (*failtest_exit_check)(struct tlist_calls *history);
220
221 /**
222  * failtest_has_failed - determine if a failure has occurred.
223  *
224  * Sometimes you want to exit immediately if you've experienced an
225  * injected failure.  This is useful when you have four separate tests
226  * in your test suite, and you don't want to do the next one if you've
227  * had a failure in a previous one.
228  */
229 extern bool failtest_has_failed(void);
230
231 /**
232  * failtest_timeout_ms - how long to wait before killing child.
233  *
234  * Default is 20,000 (20 seconds).
235  */
236 extern unsigned int failtest_timeout_ms;
237 #endif /* CCAN_FAILTEST_H */