Create an additional test case which always runs after cleanup and checks

for memory leaks.  It may be necessary to make this optional at some point,
but for now, none of our tests leak memory.
This commit is contained in:
Dag-Erling Smørgrav 2014-10-30 16:31:03 +00:00 committed by des
parent 44230ff5e3
commit 1f0fd8d9fe
3 changed files with 52 additions and 12 deletions

1
t/t.h
View file

@ -119,5 +119,6 @@ extern int t_malloc_fatal;
#ifdef _IONBF /* proxy for <stdio.h> */
void t_malloc_printstats(FILE *);
#endif
extern struct t_test t_memory_leak;
#endif

View file

@ -137,6 +137,24 @@ t_add_tests(struct t_test *t, int n)
t_plan[t_plan_len] = NULL;
}
/*
* Run a single test
*/
static int
t_run_test(struct t_test *t, int n)
{
char *desc;
desc = t->desc ? t->desc : "no description";
if ((*t->func)(&desc, t->arg)) {
printf("ok %d - %s\n", n + 1, desc);
return (1);
} else {
printf("not ok %d - %s\n", n + 1, desc);
return (0);
}
}
/*
* Print usage string and exit.
*/
@ -152,7 +170,6 @@ int
main(int argc, char *argv[])
{
unsigned int n, pass, fail;
char *desc;
int opt;
/* make all unintentional allocation failures fatal */
@ -189,17 +206,9 @@ main(int argc, char *argv[])
errx(1, "no plan\n");
/* run the tests */
printf("1..%zu\n", t_plan_len);
for (n = pass = fail = 0; n < t_plan_len; ++n) {
desc = t_plan[n]->desc ? t_plan[n]->desc : "no description";
if ((*t_plan[n]->func)(&desc, t_plan[n]->arg)) {
printf("ok %d - %s\n", n + 1, desc);
++pass;
} else {
printf("not ok %d - %s\n", n + 1, desc);
++fail;
}
}
printf("1..%zu\n", t_plan_len + 1);
for (n = pass = fail = 0; n < t_plan_len; ++n)
t_run_test(t_plan[n], n + 1) ? ++pass : ++fail;
/* clean up as much as possible before we exit */
t_cleanup();
@ -212,5 +221,6 @@ main(int argc, char *argv[])
setvbuf(stdout, NULL, _IONBF, 0);
if (verbose)
t_malloc_printstats(stderr);
t_run_test(&t_memory_leak, t_plan_len + 1) ? ++pass : ++fail;
exit(fail > 0 ? 1 : 0);
}

View file

@ -467,3 +467,32 @@ t_malloc_printstats(FILE *f)
b->nalloc - b->nfree);
}
}
/*
* Test that fails if we leaked memory
*/
static int
t_malloc_leaked(char **desc, void *arg CRYB_UNUSED)
{
struct bucket *b;
unsigned int shift;
unsigned long nleaked;
for (nleaked = shift = 0; shift <= BUCKET_MAX_SHIFT; ++shift) {
b = &buckets[shift];
nleaked += b->nalloc - b->nfree;
}
if (nleaked > 0) {
asprintf(desc, "%lu allocation(s) leaked", nleaked);
return (0);
} else {
*desc = "no memory leaked";
return (1);
}
}
struct t_test t_memory_leak = {
.func = &t_malloc_leaked,
.arg = NULL,
.desc = "memory leak check",
};