failtest: --debugpath= for really hard-to-find bugs.
[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         bool closed[2];
73 };
74
75 struct read_call {
76         ssize_t ret;
77         off_t off;
78         int fd;
79         void *buf;
80         size_t count;
81 };
82
83 struct write_call {
84         ssize_t ret;
85         int fd;
86         const void *buf;
87         size_t count;
88         off_t off;
89 };
90
91 struct fcntl_call {
92         int ret;
93         int fd;
94         int cmd;
95         union {
96                 struct flock fl;
97                 long l;
98                 int i;
99         } arg;
100 };
101
102 /**
103  * struct failtest_call - description of a call redirected to failtest module
104  * @type: the call type
105  * @file: the filename of the caller
106  * @line: the line number of the caller
107  * @fail: did this call fail
108  * @error: the errno (if any)
109  * @u: the union of call data
110  *
111  * This structure is used to represent the ordered history of calls.
112  *
113  * See Also:
114  *      failtest_hook, failtest_exit_check
115  */
116 struct failtest_call {
117         enum failtest_call_type type;
118         /* Where we were called from. */
119         const char *file;
120         unsigned int line;
121         /* Did we fail? */
122         bool fail;
123         /* What we set errno to. */
124         int error;
125         /* How do we clean this up? */
126         void (*cleanup)(void *u);
127         /* The actual call data. */
128         union {
129                 struct calloc_call calloc;
130                 struct malloc_call malloc;
131                 struct realloc_call realloc;
132                 struct open_call open;
133                 struct pipe_call pipe;
134                 struct read_call read;
135                 struct write_call write;
136                 struct fcntl_call fcntl;
137         } u;
138 };
139
140 /**
141  * failtest_hook - whether a certain call should fail or not.
142  * @history: the ordered history of all failtest calls.
143  * @num: the number of elements in @history (greater than 0)
144  *
145  * The default value of this hook is failtest_default_hook(), which returns
146  * true (ie. yes, fail the call).
147  *
148  * You can override it, and avoid failing certain calls.  The parameters
149  * of the call (but not the return value(s)) will be filled in for the last
150  * call.
151  *
152  * Example:
153  *      static bool dont_fail_allocations(struct failtest_call *history,
154  *                                        unsigned num)
155  *      {
156  *              return history[num-1].type != FAILTEST_MALLOC
157  *                      && history[num-1].type != FAILTEST_CALLOC
158  *                      && history[num-1].type != FAILTEST_REALLOC;
159  *      }
160  *      ...
161  *              failtest_hook = dont_fail_allocations;
162  */
163 extern bool (*failtest_hook)(struct failtest_call *history, unsigned num);
164
165 /**
166  * failtest_exit_check - hook for additional checks on a failed child.
167  * @history: the ordered history of all failtest calls.
168  * @num: the number of elements in @history (greater than 0)
169  *
170  * Your program might have additional checks to do on failure, such as
171  * check that a file is not corrupted, or than an error message has been
172  * logged.
173  *
174  * If this returns false, the path to this failure will be printed and the
175  * overall test will fail.
176  */
177 extern bool (*failtest_exit_check)(struct failtest_call *history,
178                                    unsigned num);
179
180 /* This usually fails the call. */
181 bool failtest_default_hook(struct failtest_call *history, unsigned num);
182
183 /**
184  * failtest_timeout_ms - how long to wait before killing child.
185  *
186  * Default is 20,000 (20 seconds).
187  */
188 extern unsigned int failtest_timeout_ms;
189 #endif /* CCAN_FAILTEST_H */