Commit c56e2b1b authored by Rusty Russell's avatar Rusty Russell

tdb2: fix leak in tests.

parent 04cf551d
......@@ -187,3 +187,10 @@ const char *operation_name(enum operation op)
}
return "**INVALID**";
}
void free_external_agent(struct agent *agent)
{
close(agent->cmdfd);
close(agent->responsefd);
free(agent);
}
......@@ -37,4 +37,5 @@ enum agent_return external_agent_operation(struct agent *handle,
const char *agent_return_name(enum agent_return ret);
const char *operation_name(enum operation op);
void free_external_agent(struct agent *agent);
#endif /* TDB2_TEST_EXTERNAL_AGENT_H */
......@@ -320,3 +320,17 @@ struct tdb_context *tdb_layout_get(struct tdb_layout *layout)
return tdb;
}
void tdb_layout_free(struct tdb_layout *layout)
{
unsigned int i;
for (i = 0; i < layout->num_elems; i++) {
if (layout->elem[i].base.type == DATA) {
free(layout->elem[i].used.key.dptr);
free(layout->elem[i].used.data.dptr);
}
}
free(layout->elem);
free(layout);
}
......@@ -16,6 +16,7 @@ void tdb_layout_add_hashtable(struct tdb_layout *layout,
tdb_len_t extra);
#endif
struct tdb_context *tdb_layout_get(struct tdb_layout *layout);
void tdb_layout_free(struct tdb_layout *layout);
enum layout_type {
FREETABLE, FREE, DATA, HASHTABLE,
......
......@@ -54,6 +54,7 @@ int main(int argc, char *argv[])
ok1(free_record_length(tdb, layout->elem[1].base.off) == len);
ok1(tdb_check(tdb, NULL, NULL) == 0);
tdb_close(tdb);
tdb_layout_free(layout);
/* No coalescing can be done due to used record */
layout = new_tdb_layout(NULL);
......@@ -73,6 +74,7 @@ int main(int argc, char *argv[])
ok1(free_record_length(tdb, layout->elem[1].base.off) == 1024);
ok1(tdb_check(tdb, NULL, NULL) == 0);
tdb_close(tdb);
tdb_layout_free(layout);
/* Coalescing can be done due to two free records, then EOF */
layout = new_tdb_layout(NULL);
......@@ -94,6 +96,7 @@ int main(int argc, char *argv[])
== 1024 + sizeof(struct tdb_used_record) + 2048);
ok1(tdb_check(tdb, NULL, NULL) == 0);
tdb_close(tdb);
tdb_layout_free(layout);
/* Coalescing can be done due to two free records, then data */
layout = new_tdb_layout(NULL);
......@@ -116,6 +119,7 @@ int main(int argc, char *argv[])
== 1024 + sizeof(struct tdb_used_record) + 512);
ok1(tdb_check(tdb, NULL, NULL) == 0);
tdb_close(tdb);
tdb_layout_free(layout);
/* Coalescing can be done due to three free records, then EOF */
layout = new_tdb_layout(NULL);
......@@ -140,6 +144,7 @@ int main(int argc, char *argv[])
+ sizeof(struct tdb_used_record) + 256);
ok1(tdb_check(tdb, NULL, NULL) == 0);
tdb_close(tdb);
tdb_layout_free(layout);
ok1(tap_log_messages == 0);
return exit_status();
......
......@@ -37,6 +37,7 @@ int main(int argc, char *argv[])
/* Fetch should now work. */
d = tdb_fetch(tdb, key);
ok1(data_equal(d, data));
free(d.dptr);
ok1(tdb_check(tdb, NULL, NULL) == 0);
tdb_close(tdb);
}
......
......@@ -50,8 +50,11 @@ int main(int argc, char *argv[])
/* We seemed to lose some keys.
* Insert and check they're in there! */
for (j = 0; j < 500; j++) {
struct tdb_data d;
ok1(tdb_store(tdb, key, data, TDB_REPLACE) == 0);
ok1(equal(tdb_fetch(tdb, key), data));
d = tdb_fetch(tdb, key);
ok1(equal(d, data));
free(d.dptr);
}
tdb_close(tdb);
}
......
......@@ -26,13 +26,17 @@ static bool store_records(struct tdb_context *tdb)
{
int i;
struct tdb_data key = { (unsigned char *)&i, sizeof(i) };
struct tdb_data data = { (unsigned char *)&i, sizeof(i) };
struct tdb_data d, data = { (unsigned char *)&i, sizeof(i) };
for (i = 0; i < 1000; i++) {
if (tdb_store(tdb, key, data, TDB_REPLACE) != 0)
return false;
if (tdb_fetch(tdb, key).dsize != data.dsize)
d = tdb_fetch(tdb, key);
if (d.dsize != data.dsize)
return false;
if (memcmp(d.dptr, data.dptr, d.dsize) != 0)
return false;
free(d.dptr);
}
return true;
}
......@@ -41,7 +45,7 @@ static void test_val(struct tdb_context *tdb, uint64_t val)
{
uint64_t v;
struct tdb_data key = { (unsigned char *)&v, sizeof(v) };
struct tdb_data data = { (unsigned char *)&v, sizeof(v) };
struct tdb_data d, data = { (unsigned char *)&v, sizeof(v) };
/* Insert an entry, then delete it. */
v = val;
......@@ -65,9 +69,13 @@ static void test_val(struct tdb_context *tdb, uint64_t val)
ok1(tdb_check(tdb, NULL, NULL) == 0);
/* Can find both? */
ok1(tdb_fetch(tdb, key).dsize == data.dsize);
d = tdb_fetch(tdb, key);
ok1(d.dsize == data.dsize);
free(d.dptr);
v = val;
ok1(tdb_fetch(tdb, key).dsize == data.dsize);
d = tdb_fetch(tdb, key);
ok1(d.dsize == data.dsize);
free(d.dptr);
/* Delete second one. */
v = val + 1;
......@@ -85,7 +93,9 @@ static void test_val(struct tdb_context *tdb, uint64_t val)
/* Can still find second? */
v = val + 1;
ok1(tdb_fetch(tdb, key).dsize == data.dsize);
d = tdb_fetch(tdb, key);
ok1(d.dsize == data.dsize);
free(d.dptr);
/* Now, this will be ideally placed. */
v = val + 2;
......@@ -97,11 +107,17 @@ static void test_val(struct tdb_context *tdb, uint64_t val)
ok1(tdb_store(tdb, key, data, TDB_INSERT) == 0);
/* We can still find them all, right? */
ok1(tdb_fetch(tdb, key).dsize == data.dsize);
d = tdb_fetch(tdb, key);
ok1(d.dsize == data.dsize);
free(d.dptr);
v = val + 1;
ok1(tdb_fetch(tdb, key).dsize == data.dsize);
d = tdb_fetch(tdb, key);
ok1(d.dsize == data.dsize);
free(d.dptr);
v = val + 2;
ok1(tdb_fetch(tdb, key).dsize == data.dsize);
d = tdb_fetch(tdb, key);
ok1(d.dsize == data.dsize);
free(d.dptr);
/* And if we delete val + 1, that val + 2 should not move! */
v = val + 1;
......@@ -109,9 +125,13 @@ static void test_val(struct tdb_context *tdb, uint64_t val)
ok1(tdb_check(tdb, NULL, NULL) == 0);
v = val;
ok1(tdb_fetch(tdb, key).dsize == data.dsize);
d = tdb_fetch(tdb, key);
ok1(d.dsize == data.dsize);
free(d.dptr);
v = val + 2;
ok1(tdb_fetch(tdb, key).dsize == data.dsize);
d = tdb_fetch(tdb, key);
ok1(d.dsize == data.dsize);
free(d.dptr);
/* Delete those two, so we are empty. */
ok1(tdb_delete(tdb, key) == 0);
......
......@@ -126,5 +126,6 @@ int main(int argc, char *argv[])
}
ok1(tap_log_messages == 0);
free(buffer);
return exit_status();
}
......@@ -62,6 +62,7 @@ int main(int argc, char *argv[])
ok1(d.dsize == sizeof(j));
ok1(d.dptr != NULL);
ok1(d.dptr && memcmp(d.dptr, &j, d.dsize) == 0);
free(d.dptr);
}
/* Now add a *lot* more. */
......@@ -73,6 +74,7 @@ int main(int argc, char *argv[])
ok1(d.dsize == sizeof(j));
ok1(d.dptr != NULL);
ok1(d.dptr && memcmp(d.dptr, &j, d.dsize) == 0);
free(d.dptr);
}
ok1(tdb_check(tdb, NULL, NULL) == 0);
......@@ -92,6 +94,7 @@ int main(int argc, char *argv[])
ok1(d.dsize == sizeof(j));
ok1(d.dptr != NULL);
ok1(d.dptr && memcmp(d.dptr, &j, d.dsize) == 0);
free(d.dptr);
}
/* Traverse through them. */
......
......@@ -65,6 +65,7 @@ int main(int argc, char *argv[])
ok1(off == 0);
tdb_close(tdb);
tdb_layout_free(layout);
ok1(tap_log_messages == 0);
return exit_status();
......
......@@ -69,5 +69,6 @@ int main(int argc, char *argv[])
}
ok1(tap_log_messages == 0);
free(buffer);
return exit_status();
}
#define _XOPEN_SOURCE 500
#include <unistd.h>
#include "lock-tracking.h"
#include <ccan/tap/tap.h>
#include <stdlib.h>
#include <assert.h>
static ssize_t pwrite_check(int fd, const void *buf, size_t count, off_t offset);
static ssize_t write_check(int fd, const void *buf, size_t count);
static int ftruncate_check(int fd, off_t length);
......@@ -10,6 +13,51 @@ static int ftruncate_check(int fd, off_t length);
#define fcntl fcntl_with_lockcheck
#define ftruncate ftruncate_check
/* There's a malloc inside transaction_setup_recovery, and valgrind complains
* when we longjmp and leak it. */
#define MAX_ALLOCATIONS 200
static void *allocated[MAX_ALLOCATIONS];
static void *malloc_noleak(size_t len)
{
unsigned int i;
for (i = 0; i < MAX_ALLOCATIONS; i++)
if (!allocated[i]) {
allocated[i] = malloc(len);
return allocated[i];
}
diag("Too many allocations!");
abort();
}
static void free_noleak(void *p)
{
unsigned int i;
/* We don't catch realloc, so don't care if we miss one. */
for (i = 0; i < MAX_ALLOCATIONS; i++) {
if (allocated[i] == p) {
allocated[i] = NULL;
break;
}
}
free(p);
}
static void free_all(void)
{
unsigned int i;
for (i = 0; i < MAX_ALLOCATIONS; i++) {
free(allocated[i]);
allocated[i] = NULL;
}
}
#define malloc malloc_noleak
#define free free_noleak
#include <ccan/tdb2/tdb.c>
#include <ccan/tdb2/free.c>
#include <ccan/tdb2/lock.c>
......@@ -17,8 +65,13 @@ static int ftruncate_check(int fd, off_t length);
#include <ccan/tdb2/hash.c>
#include <ccan/tdb2/check.c>
#include <ccan/tdb2/transaction.c>
#include <ccan/tap/tap.h>
#include <stdlib.h>
#undef malloc
#undef free
#undef write
#undef pwrite
#undef fcntl
#undef ftruncate
#include <stdbool.h>
#include <stdarg.h>
#include <err.h>
......@@ -26,11 +79,6 @@ static int ftruncate_check(int fd, off_t length);
#include "external-agent.h"
#include "logging.h"
#undef write
#undef pwrite
#undef fcntl
#undef ftruncate
static bool in_transaction;
static int target, current;
static jmp_buf jmpbuf;
......@@ -150,6 +198,7 @@ reset:
suppress_lockcheck = false;
target++;
current = 0;
free_all();
goto reset;
}
......@@ -217,5 +266,6 @@ int main(int argc, char *argv[])
ok1(test_death(ops[i], agent));
}
free_external_agent(agent);
return exit_status();
}
......@@ -46,5 +46,7 @@ int main(int argc, char *argv[])
tdb_close(tdb);
}
ok1(tap_log_messages == 0);
free(data.dptr);
return exit_status();
}
......@@ -58,5 +58,6 @@ int main(int argc, char *argv[])
/* Now store something! */
ok1(tdb_store(tdb, d, d, TDB_INSERT) == 0);
ok1(tap_log_messages == 0);
free_external_agent(agent);
return exit_status();
}
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