X-Git-Url: https://git.ozlabs.org/?p=ccan;a=blobdiff_plain;f=ccan%2Ftdb%2Ftest%2Frun-die-during-transaction.c;h=aa6b40f6bbad9eb5246d03334ff9b6c0a738cf9f;hp=f8000b553e2ed029ed93785ceec7c24312c02d17;hb=b10598ebdad2302c637c14961525c0d9cef937f5;hpb=d0b36a7cb734a9e3d290bb3047c012859ce171a3 diff --git a/ccan/tdb/test/run-die-during-transaction.c b/ccan/tdb/test/run-die-during-transaction.c index f8000b55..aa6b40f6 100644 --- a/ccan/tdb/test/run-die-during-transaction.c +++ b/ccan/tdb/test/run-die-during-transaction.c @@ -20,13 +20,15 @@ static int ftruncate_check(int fd, off_t length); #include #include #include +#include #include #include #include #include #include #include -#include "external-transaction.h" +#include "external-agent.h" +#include "logging.h" #undef write #undef pwrite @@ -34,27 +36,10 @@ static int ftruncate_check(int fd, off_t length); #undef ftruncate static bool in_transaction; -static bool suppress_logging; static int target, current; static jmp_buf jmpbuf; -#define TEST_DBNAME "/tmp/test7.tdb" - -static void taplog(struct tdb_context *tdb, - enum tdb_debug_level level, - const char *fmt, ...) -{ - va_list ap; - char line[200]; - - if (suppress_logging) - return; - - va_start(ap, fmt); - vsprintf(line, fmt, ap); - va_end(ap); - - diag("%s", line); -} +#define TEST_DBNAME "run-die-during-transaction.tdb" +#define KEY_STRING "helloworld" static void maybe_die(int fd) { @@ -107,42 +92,60 @@ static int ftruncate_check(int fd, off_t length) static bool test_death(enum operation op, struct agent *agent) { struct tdb_context *tdb = NULL; - TDB_DATA key, data; - struct tdb_logging_context logctx = { taplog, NULL }; + TDB_DATA key; + enum agent_return ret; int needed_recovery = 0; current = target = 0; reset: + unlink(TEST_DBNAME); + tdb = tdb_open_ex(TEST_DBNAME, 1024, TDB_NOMMAP, + O_CREAT|O_TRUNC|O_RDWR, 0600, &taplogctx, NULL); + if (setjmp(jmpbuf) != 0) { /* We're partway through. Simulate our death. */ close(tdb->fd); forget_locking(); in_transaction = false; - if (external_agent_operation(agent, NEEDS_RECOVERY_KEEP_OPENED, - "")) + ret = external_agent_operation(agent, NEEDS_RECOVERY, ""); + if (ret == SUCCESS) needed_recovery++; + else if (ret != FAILED) { + diag("Step %u agent NEEDS_RECOVERY = %s", current, + agent_return_name(ret)); + return false; + } + + ret = external_agent_operation(agent, op, KEY_STRING); + if (ret != SUCCESS) { + diag("Step %u op %s failed = %s", current, + operation_name(op), + agent_return_name(ret)); + return false; + } - if (external_agent_operation(agent, op, "") != 1) { - diag("Step %u op failed", current); + ret = external_agent_operation(agent, NEEDS_RECOVERY, ""); + if (ret != FAILED) { + diag("Still needs recovery after step %u = %s", + current, agent_return_name(ret)); return false; } - if (external_agent_operation(agent, NEEDS_RECOVERY_KEEP_OPENED, - "")) { - diag("Still needs recovery after step %u", current); + ret = external_agent_operation(agent, CHECK, ""); + if (ret != SUCCESS) { + diag("Step %u check failed = %s", current, + agent_return_name(ret)); return false; } - if (external_agent_operation(agent, CHECK_KEEP_OPENED, "") - != 1) { - diag("Step %u check failed", current); -#if 0 + ret = external_agent_operation(agent, CLOSE, ""); + if (ret != SUCCESS) { + diag("Step %u close failed = %s", current, + agent_return_name(ret)); return false; -#endif } - external_agent_operation(agent, CLOSE, ""); /* Suppress logging as this tries to use closed fd. */ suppress_logging = true; suppress_lockcheck = true; @@ -154,24 +157,30 @@ reset: goto reset; } - unlink(TEST_DBNAME); - tdb = tdb_open_ex(TEST_DBNAME, 1024, TDB_NOMMAP, - O_CREAT|O_TRUNC|O_RDWR, 0600, &logctx, NULL); + /* Put key for agent to fetch. */ + key.dsize = strlen(KEY_STRING); + key.dptr = (void *)KEY_STRING; + if (tdb_store(tdb, key, key, TDB_INSERT) != 0) + return false; - if (external_agent_operation(agent, KEEP_OPENED, TEST_DBNAME) != 0) - errx(1, "Agent failed to open?"); + /* This is the key we insert in transaction. */ + key.dsize--; - if (tdb_transaction_start(tdb) != 0) - return false; + ret = external_agent_operation(agent, OPEN, TEST_DBNAME); + if (ret != SUCCESS) + errx(1, "Agent failed to open: %s", agent_return_name(ret)); + + ret = external_agent_operation(agent, FETCH, KEY_STRING); + if (ret != SUCCESS) + errx(1, "Agent failed find key: %s", agent_return_name(ret)); in_transaction = true; - key.dsize = strlen("hi"); - key.dptr = (void *)"hi"; - data.dptr = (void *)"world"; - data.dsize = strlen("world"); + if (tdb_transaction_start(tdb) != 0) + return false; - if (tdb_store(tdb, key, data, TDB_INSERT) != 0) + if (tdb_store(tdb, key, key, TDB_INSERT) != 0) return false; + if (tdb_transaction_commit(tdb) != 0) return false; @@ -180,7 +189,12 @@ reset: /* We made it! */ diag("Completed %u runs", current); tdb_close(tdb); - external_agent_operation(agent, CLOSE, ""); + ret = external_agent_operation(agent, CLOSE, ""); + if (ret != SUCCESS) { + diag("Step %u close failed = %s", current, + agent_return_name(ret)); + return false; + } ok1(needed_recovery); ok1(locking_errors == 0); @@ -191,9 +205,7 @@ reset: int main(int argc, char *argv[]) { - enum operation ops[] = { FETCH_KEEP_OPENED, - STORE_KEEP_OPENED, - TRANSACTION_KEEP_OPENED }; + enum operation ops[] = { FETCH, STORE, TRANSACTION_START }; struct agent *agent; int i; @@ -204,17 +216,8 @@ int main(int argc, char *argv[]) if (!agent) err(1, "preparing agent"); - /* Nice ourselves down: we can't tell the difference between agent - * blocking on lock, and agent not scheduled. */ - nice(15); - for (i = 0; i < sizeof(ops)/sizeof(ops[0]); i++) { - diag("Testing %s after death", - ops[i] == TRANSACTION_KEEP_OPENED ? "transaction" - : ops[i] == FETCH_KEEP_OPENED ? "fetch" - : ops[i] == STORE_KEEP_OPENED ? "store" - : NULL); - + diag("Testing %s after death", operation_name(ops[i])); ok1(test_death(ops[i], agent)); }