failtest.h 5.7 KB

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