-#include "config.h"
+#include <ccan/tdb2/private.h>
#include <unistd.h>
#include "lock-tracking.h"
#include <ccan/tap/tap.h>
/* There's a malloc inside transaction_setup_recovery, and valgrind complains
* when we longjmp and leak it. */
-#define MAX_ALLOCATIONS 200
+#define MAX_ALLOCATIONS 10
static void *allocated[MAX_ALLOCATIONS];
+static unsigned max_alloc = 0;
static void *malloc_noleak(size_t len)
{
for (i = 0; i < MAX_ALLOCATIONS; i++)
if (!allocated[i]) {
allocated[i] = malloc(len);
+ if (i > max_alloc) {
+ max_alloc = i;
+ diag("max_alloc: %i", max_alloc);
+ }
return allocated[i];
}
diag("Too many allocations!");
abort();
}
+static void *realloc_noleak(void *p, size_t size)
+{
+ unsigned int i;
+
+ for (i = 0; i < MAX_ALLOCATIONS; i++) {
+ if (allocated[i] == p) {
+ if (i > max_alloc) {
+ max_alloc = i;
+ diag("max_alloc: %i", max_alloc);
+ }
+ return allocated[i] = realloc(p, size);
+ }
+ }
+ diag("Untracked realloc!");
+ abort();
+}
+
static void free_noleak(void *p)
{
unsigned int i;
- /* We don't catch realloc, so don't care if we miss one. */
+ /* We don't catch asprintf, so don't complain if we miss one. */
for (i = 0; i < MAX_ALLOCATIONS; i++) {
if (allocated[i] == p) {
allocated[i] = NULL;
#define malloc malloc_noleak
#define free free_noleak
+#define realloc realloc_noleak
+
+#include "tdb2-source.h"
-#include <ccan/tdb2/tdb.c>
-#include <ccan/tdb2/open.c>
-#include <ccan/tdb2/free.c>
-#include <ccan/tdb2/lock.c>
-#include <ccan/tdb2/io.c>
-#include <ccan/tdb2/hash.c>
-#include <ccan/tdb2/check.c>
-#include <ccan/tdb2/transaction.c>
#undef malloc
#undef free
+#undef realloc
#undef write
#undef pwrite
#undef fcntl
return ret;
}
-static bool test_death(enum operation op, struct agent *agent)
+static bool test_death(enum operation op, struct agent *agent, int flags)
{
struct tdb_context *tdb = NULL;
TDB_DATA key;
current = target = 0;
reset:
unlink(TEST_DBNAME);
- tdb = tdb_open(TEST_DBNAME, TDB_NOMMAP,
+ tdb = tdb_open(TEST_DBNAME, flags|TDB_NOMMAP,
O_CREAT|O_TRUNC|O_RDWR, 0600, &tap_log_attr);
if (!tdb) {
diag("Failed opening TDB: %s", strerror(errno));
if (setjmp(jmpbuf) != 0) {
/* We're partway through. Simulate our death. */
- close(tdb->fd);
+ close(tdb->file->fd);
forget_locking();
in_transaction = false;
}
/* Put key for agent to fetch. */
- key.dsize = strlen(KEY_STRING);
- key.dptr = (void *)KEY_STRING;
+ key = tdb_mkdata(KEY_STRING, strlen(KEY_STRING));
if (tdb_store(tdb, key, key, TDB_INSERT) != 0)
return false;
{
enum operation ops[] = { FETCH, STORE, TRANSACTION_START };
struct agent *agent;
- int i;
+ int i, flags;
- plan_tests(12);
+ plan_tests(24);
unlock_callback = maybe_die;
+ external_agent_free = free_noleak;
agent = prepare_external_agent();
if (!agent)
err(1, "preparing agent");
- for (i = 0; i < sizeof(ops)/sizeof(ops[0]); i++) {
- diag("Testing %s after death", operation_name(ops[i]));
- ok1(test_death(ops[i], agent));
+ for (flags = TDB_DEFAULT; flags <= TDB_VERSION1; flags += TDB_VERSION1) {
+ for (i = 0; i < sizeof(ops)/sizeof(ops[0]); i++) {
+ diag("Testing %s after death", operation_name(ops[i]));
+ ok1(test_death(ops[i], agent, flags));
+ }
}
free_external_agent(agent);