Commit 97f93f50 authored by Rusty Russell's avatar Rusty Russell

failtest: failtest_restore.h as an antidote to function overload.

This makes some cases simpler, where you no longer want malloc etc.
to fail.
parent 67144d5f
...@@ -8,7 +8,8 @@ ...@@ -8,7 +8,8 @@
* The failtest module overrides various standard functions, and forks * The failtest module overrides various standard functions, and forks
* your unit test at those points to test failure paths. The failing * your unit test at those points to test failure paths. The failing
* child are expected to fail (eg. when malloc fails), but should not * child are expected to fail (eg. when malloc fails), but should not
* leak memory or crash. * leak memory or crash. After including failtest_override.h, you can
* include failtest_restore.h to return to non-failing versions.
* *
* The unit test is a normal CCAN tap-style test, except it should * The unit test is a normal CCAN tap-style test, except it should
* start by calling failtest_init() and end by calling * start by calling failtest_init() and end by calling
......
...@@ -66,12 +66,19 @@ static unsigned int fd_orig_num = 0; ...@@ -66,12 +66,19 @@ static unsigned int fd_orig_num = 0;
static const char info_to_arg[] = "mceoprw"; static const char info_to_arg[] = "mceoprw";
/* Dummy call used for failtest_undo wrappers. */
static struct failtest_call unrecorded_call;
static struct failtest_call *add_history_(enum failtest_call_type type, static struct failtest_call *add_history_(enum failtest_call_type type,
const char *file, const char *file,
unsigned int line, unsigned int line,
const void *elem, const void *elem,
size_t elem_size) size_t elem_size)
{ {
/* NULL file is how we suppress failure. */
if (!file)
return &unrecorded_call;
history = realloc(history, (history_num + 1) * sizeof(*history)); history = realloc(history, (history_num + 1) * sizeof(*history));
history[history_num].type = type; history[history_num].type = type;
history[history_num].file = file; history[history_num].file = file;
...@@ -172,6 +179,9 @@ static bool should_fail(struct failtest_call *call) ...@@ -172,6 +179,9 @@ static bool should_fail(struct failtest_call *call)
char *out = NULL; char *out = NULL;
size_t outlen = 0; size_t outlen = 0;
if (call == &unrecorded_call)
return false;
if (failpath) { if (failpath) {
if (tolower(*failpath) != info_to_arg[call->type]) if (tolower(*failpath) != info_to_arg[call->type])
errx(1, "Failpath expected '%c' got '%c'\n", errx(1, "Failpath expected '%c' got '%c'\n",
...@@ -341,6 +351,9 @@ int failtest_open(const char *pathname, int flags, ...@@ -341,6 +351,9 @@ int failtest_open(const char *pathname, int flags,
va_end(ap); va_end(ap);
} }
p = add_history(FAILTEST_OPEN, file, line, &call); p = add_history(FAILTEST_OPEN, file, line, &call);
/* Avoid memory leak! */
if (p == &unrecorded_call)
free((char *)call.pathname);
if (should_fail(p)) { if (should_fail(p)) {
p->u.open.ret = -1; p->u.open.ret = -1;
/* FIXME: Play with error codes? */ /* FIXME: Play with error codes? */
......
#ifndef CCAN_FAILTEST_RESTORE_H
#define CCAN_FAILTEST_RESTORE_H
/* This file undoes the effect of failtest_override.h. */
#undef calloc
#define calloc(nmemb, size) \
failtest_calloc((nmemb), (size), NULL, 0)
#undef malloc
#define malloc(size) \
failtest_malloc((size), NULL, 0)
#undef realloc
#define realloc(ptr, size) \
failtest_realloc((ptr), (size), NULL, 0)
#undef open
#define open(pathname, flags, ...) \
failtest_open((pathname), (flags), NULL, 0, __VA_ARGS__)
#undef pipe
#define pipe(pipefd) \
failtest_pipe((pipefd), NULL, 0)
#undef read
#define read(fd, buf, count) \
failtest_read((fd), (buf), (count), NULL, 0)
#undef write
#define write(fd, buf, count) \
failtest_write((fd), (buf), (count), NULL, 0)
#undef close
#define close(fd) failtest_close(fd)
#endif /* CCAN_FAILTEST_RESTORE_H */
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment