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