libctdb: test: improve logging of failure paths
authorRusty Russell <rusty@rustcorp.com.au>
Mon, 21 Jun 2010 05:27:11 +0000 (14:57 +0930)
committerRusty Russell <rusty@rustcorp.com.au>
Mon, 21 Jun 2010 05:27:11 +0000 (14:57 +0930)
We include the file and line which called the functions, so the printed
failure path now looks like:

[malloc(ctdb.c:144)]:1:S[socket(ctdb.c:168)]:1:S...

The form is:
    [ <function> ( <caller> ) ] : <input line> : <result>

<function> is the function which is called (eg. malloc).
<caller> is the file and line number which called <function>.
<input line> is the 1-based line number in the input which we were up to.
<result> is 'S' (success) or 'F' (failure).

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
libctdb/test/ctdb-test.c
libctdb/test/failtest.c
libctdb/test/failtest.h

index b4c12ff9abbf753652078f33273b21c0a437e66d..1587a4f8c3082ad488cf058f85f248b3c6f81020 100644 (file)
@@ -251,7 +251,7 @@ static char *get_cmdline_optstr(void)
 static int ctdb_test_poll(struct pollfd *fds, nfds_t nfds, int timeout,
                          const char *location)
 {
-       if (should_i_fail("poll")) {
+       if (should_i_fail("poll", location)) {
                errno = EINVAL;
                return -1;
        }
@@ -260,7 +260,7 @@ static int ctdb_test_poll(struct pollfd *fds, nfds_t nfds, int timeout,
 
 static void *ctdb_test_malloc(size_t size, const char *location)
 {
-       if (should_i_fail("malloc")) {
+       if (should_i_fail("malloc", location)) {
                errno = ENOMEM;
                return NULL;
        }
@@ -274,7 +274,7 @@ static void ctdb_test_free(void *ptr, const char *location)
 
 static void *ctdb_test_realloc(void *ptr, size_t size, const char *location)
 {
-       if (should_i_fail("realloc")) {
+       if (should_i_fail("realloc", location)) {
                errno = ENOMEM;
                return NULL;
        }
@@ -288,7 +288,7 @@ static void *ctdb_test_realloc(void *ptr, size_t size, const char *location)
 static ssize_t ctdb_test_read(int fd, void *buf, size_t count,
                              const char *location)
 {
-       if (should_i_fail("read")) {
+       if (should_i_fail("read", location)) {
                errno = EBADF;
                return -1;
        }
@@ -305,7 +305,7 @@ static ssize_t ctdb_test_read(int fd, void *buf, size_t count,
 static ssize_t ctdb_test_write(int fd, const void *buf, size_t count,
                               const char *location)
 {
-       if (should_i_fail("write")) {
+       if (should_i_fail("write", location)) {
                errno = EBADF;
                return -1;
        }
@@ -323,7 +323,7 @@ static ssize_t ctdb_test_write(int fd, const void *buf, size_t count,
 static int ctdb_test_socket(int domain, int type, int protocol,
                            const char *location)
 {
-       if (should_i_fail("socket")) {
+       if (should_i_fail("socket", location)) {
                errno = EINVAL;
                return -1;
        }
@@ -333,7 +333,7 @@ static int ctdb_test_socket(int domain, int type, int protocol,
 static int ctdb_test_connect(int sockfd, const struct sockaddr *addr,
                             socklen_t addrlen, const char *location)
 {
-       if (should_i_fail("connect")) {
+       if (should_i_fail("connect", location)) {
                errno = EINVAL;
                return -1;
        }
@@ -347,7 +347,7 @@ static struct tdb_context *ctdb_test_tdb_open_ex(const char *name,
                                                 tdb_hash_func hash_fn,
                                                 const char *location)
 {
-       if (should_i_fail("tdb_open_ex")) {
+       if (should_i_fail("tdb_open_ex", location)) {
                errno = ENOENT;
                return NULL;
        }
index d42ab057094be07f1167a959c0ea7966c1f853ee..c12d4fcaed78ddead09f0cb8ec21d0d3de13be0d 100644 (file)
@@ -199,11 +199,23 @@ bool am_parent(void)
        return true;
 }
 
+static char *make_location(const char *func, const char *caller)
+{
+       const char *afterslash;
+
+       afterslash = strrchr(caller, '/');
+       if (afterslash)
+               afterslash++;
+       else
+               afterslash = caller;
+       return talloc_asprintf(working, "%s(%s)", func, afterslash);
+}
+
 /* Should I fail at this point?  Once only: it would be too expensive
  * to fail at every possible call. */
-bool should_i_fail_once(const char *location)
+bool should_i_fail_once(const char *func, const char *caller)
 {
-       char *p;
+       char *p, *location = make_location(func, caller);
        struct fail_decision *i;
 
        if (failpath) {
@@ -219,7 +231,7 @@ bool should_i_fail_once(const char *location)
                if (streq(location, i->location))
                        return false;
 
-       if (should_i_fail(location)) {
+       if (should_i_fail(func, caller)) {
                excessive_fails++;
                return true;
        }
@@ -227,16 +239,17 @@ bool should_i_fail_once(const char *location)
 }
 
 /* Should I fail at this point? */
-bool should_i_fail(const char *func)
+bool should_i_fail(const char *func, const char *caller)
 {
        pid_t child;
        int status, pfd[2];
        struct fail_decision *dec;
        size_t log_size;
        char *log;
+       char *location = make_location(func, caller);
 
        if (failpath)
-               return do_failpath(func);
+               return do_failpath(location);
 
        failpoints++;
        if (!failtest)
@@ -251,7 +264,7 @@ bool should_i_fail(const char *func)
        }
 
        dec = talloc(NULL, struct fail_decision);
-       dec->location = talloc_strdup(dec, func);
+       dec->location = talloc_steal(dec, location);
        dec->tui_line = tui_linenum;
 
        DLIST_ADD_END(decisions, dec, struct fail_decision);
index c361f84c9bcbbb23e4987e3cd0e1fe4f78b1e057..4d0c579f20ed669821d491e1f864d6dba43b561d 100644 (file)
@@ -2,8 +2,8 @@
 #define FAILTEST_H
 #include <stdbool.h>
 
-bool should_i_fail_once(const char *location);
-bool should_i_fail(const char *func);
+bool should_i_fail_once(const char *func, const char *caller);
+bool should_i_fail(const char *func, const char *caller);
 
 bool failtest;