X-Git-Url: http://git.ozlabs.org/?a=blobdiff_plain;f=ccan%2Ftdb2%2Ftest%2Frun-delete.c;fp=ccan%2Ftdb2%2Ftest%2Frun-delete.c;h=b506003b8a61c97c08c47379762a3b6beb71fb39;hb=2088fa3cd72332f5517edeb9267e381fdf35db01;hp=0000000000000000000000000000000000000000;hpb=0939b69164c65329fa8f6b2c4ab5e9c7d9162678;p=ccan diff --git a/ccan/tdb2/test/run-delete.c b/ccan/tdb2/test/run-delete.c new file mode 100644 index 00000000..b506003b --- /dev/null +++ b/ccan/tdb2/test/run-delete.c @@ -0,0 +1,101 @@ +#include +#include +#include +#include +#include +#include +#include "logging.h" + +/* We rig the hash so adjacent-numbered records always clash. */ +static uint64_t clash(const void *key, size_t len, uint64_t seed, void *priv) +{ + return *(unsigned int *)key / 2; +} + +static void test_val(struct tdb_context *tdb, unsigned int val) +{ + unsigned int v; + struct tdb_data key = { (unsigned char *)&v, sizeof(v) }; + struct tdb_data data = { (unsigned char *)&v, sizeof(v) }; + + /* Insert an entry, then delete it. */ + v = val; + /* Delete should fail. */ + ok1(tdb_delete(tdb, key) == -1); + ok1(tdb_error(tdb) == TDB_ERR_NOEXIST); + ok1(tdb_check(tdb, NULL, NULL) == 0); + + /* Insert should succeed. */ + ok1(tdb_store(tdb, key, data, TDB_INSERT) == 0); + ok1(tdb_check(tdb, NULL, NULL) == 0); + + /* Delete should succeed. */ + ok1(tdb_delete(tdb, key) == 0); + ok1(tdb_check(tdb, NULL, NULL) == 0); + + /* Re-add it, then add collision. */ + ok1(tdb_store(tdb, key, data, TDB_INSERT) == 0); + v = val + 1; + ok1(tdb_store(tdb, key, data, TDB_INSERT) == 0); + ok1(tdb_check(tdb, NULL, NULL) == 0); + + /* Can find both? */ + ok1(tdb_fetch(tdb, key).dsize == data.dsize); + v = val; + ok1(tdb_fetch(tdb, key).dsize == data.dsize); + + /* Delete second one. */ + v = val + 1; + ok1(tdb_delete(tdb, key) == 0); + ok1(tdb_check(tdb, NULL, NULL) == 0); + + /* Re-add */ + ok1(tdb_store(tdb, key, data, TDB_INSERT) == 0); + ok1(tdb_check(tdb, NULL, NULL) == 0); + + /* Now, try deleting first one. */ + v = val; + ok1(tdb_delete(tdb, key) == 0); + ok1(tdb_check(tdb, NULL, NULL) == 0); + + /* Can still find second? */ + v = val + 1; + ok1(tdb_fetch(tdb, key).dsize == data.dsize); + + /* Delete that, so we are empty. */ + ok1(tdb_delete(tdb, key) == 0); + ok1(tdb_check(tdb, NULL, NULL) == 0); +} + +int main(int argc, char *argv[]) +{ + unsigned int i; + struct tdb_context *tdb; + union tdb_attribute hattr = { .hash = { .base = { TDB_ATTRIBUTE_HASH }, + .hash_fn = clash } }; + int flags[] = { TDB_INTERNAL, TDB_DEFAULT, + TDB_INTERNAL|TDB_CONVERT, TDB_CONVERT }; + + hattr.base.next = &tap_log_attr; + + plan_tests(sizeof(flags) / sizeof(flags[0]) * 44 + 1); + for (i = 0; i < sizeof(flags) / sizeof(flags[0]); i++) { + tdb = tdb_open("run-delete.tdb", flags[i], + O_RDWR|O_CREAT|O_TRUNC, 0600, &hattr); + ok1(tdb); + if (!tdb) + continue; + + /* Check start of hash table. */ + test_val(tdb, 0); + + /* Check end of hash table (will wrap around!). */ + test_val(tdb, ((1 << tdb->header.v.hash_bits) - 1) * 2); + + ok1(!tdb_has_locks(tdb)); + tdb_close(tdb); + } + + ok1(tap_log_messages == 0); + return exit_status(); +}