failtest: detect leaks in children.
authorRusty Russell <rusty@rustcorp.com.au>
Tue, 15 Feb 2011 13:02:13 +0000 (23:32 +1030)
committerRusty Russell <rusty@rustcorp.com.au>
Tue, 15 Feb 2011 13:02:13 +0000 (23:32 +1030)
If we need to clean up the children, they didn't exit cleanly.

This takes a bit more care when writing tests, but found a leak in tdb2.

ccan/failtest/failtest.c
ccan/failtest/test/run-write.c

index 9972db3cd29fc8ad83a9d3c51bc8fedf65ef4a76..77aea9a7de6e185226f07a63b7ecb47dadf3a93b 100644 (file)
@@ -317,21 +317,28 @@ static NORETURN void failtest_cleanup(bool forced_cleanup, int status)
 {
        int i;
 
+       /* For children, we don't care if they "failed" the testing. */
+       if (control_fd != -1)
+               status = 0;
+
        if (forced_cleanup)
                history_num--;
 
        /* Cleanup everything, in reverse order. */
-       for (i = history_num - 1; i >= 0; i--)
-               if (history[i].cleanup)
-                       history[i].cleanup(&history[i].u);
+       for (i = history_num - 1; i >= 0; i--) {
+               if (!history[i].cleanup)
+                       continue;
+               if (!forced_cleanup) {
+                       printf("Leak at %s:%u\n",
+                              history[i].file, history[i].line);
+                       status = 1;
+               }
+               history[i].cleanup(&history[i].u);
+       }
 
        free_everything();
-
-       if (control_fd == -1)
-               exit(status);
-
        tell_parent(SUCCESS);
-       exit(0);
+       exit(status);
 }
 
 static bool should_fail(struct failtest_call *call)
index d3d7c6041871c96884e28c488a0f86a1982a9f24..9f1f1d7fc8005fdda59cbe46684157329f2469be 100644 (file)
@@ -7,15 +7,16 @@
 /* Include the C files directly. */
 #include <ccan/failtest/failtest.c>
 
-int main(void)
+int main(int argc, char *argv[])
 {
        int fd;
        char *p;
        char buf[] = "Hello world!";
 
        plan_tests(5);
+       failtest_init(argc, argv);
 
-       fd = failtest_open("run-write-scratchpad", "run-write.c", 1,
+       fd = failtest_open("run-write-scratchpad", __FILE__, __LINE__,
                           O_RDWR|O_CREAT, 0600);
        /* Child will fail, ignore. */
        if (fd < 0)
@@ -23,14 +24,16 @@ int main(void)
        write(fd, buf, strlen(buf));
        ok1(lseek(fd, 0, SEEK_CUR) == strlen(buf));
 
-       p = failtest_malloc(100, "run-write.c", 1);
+       p = failtest_malloc(100, __FILE__, __LINE__);
        if (!p) {
                /* We are the child.  Do a heap of writes. */
                unsigned int i;
 
                for (i = 0; i < strlen(buf)+1; i++)
-                       if (failtest_write(fd, "x", 1, "run-write.c", 1) == 1)
+                       if (failtest_write(fd, "x", 1, __FILE__, __LINE__)
+                           == 1)
                                break;
+               failtest_close(fd, __FILE__, __LINE__);
                failtest_exit(0);
        }
 
@@ -41,6 +44,7 @@ int main(void)
        lseek(fd, 0, SEEK_SET);
        ok1(read(fd, buf, strlen(buf)) == strlen("Hello world!"));
        ok1(strcmp(buf, "Hello world!") == 0);
+       failtest_close(fd, __FILE__, __LINE__);
 
        return exit_status();
 }