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