Browse Source

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

This makes some cases simpler, where you no longer want malloc etc.
to fail.
Rusty Russell 15 years ago
parent
commit
97f93f5091
3 changed files with 51 additions and 1 deletions
  1. 2 1
      ccan/failtest/_info
  2. 13 0
      ccan/failtest/failtest.c
  3. 36 0
      ccan/failtest/failtest_undo.h

+ 2 - 1
ccan/failtest/_info

@@ -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

+ 13 - 0
ccan/failtest/failtest.c

@@ -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)
 	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,
 		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? */

+ 36 - 0
ccan/failtest/failtest_undo.h

@@ -0,0 +1,36 @@
+#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 */