1 #define _XOPEN_SOURCE 500
2 #include <ccan/tdb/tdb.h>
3 #include <ccan/tdb/io.c>
4 #include <ccan/tdb/tdb.c>
5 #include <ccan/tdb/lock.c>
6 #include <ccan/tdb/freelist.c>
7 #include <ccan/tdb/traverse.c>
8 #include <ccan/tdb/transaction.c>
9 #include <ccan/tdb/error.c>
10 #include <ccan/tdb/open.c>
11 #include <ccan/tdb/check.c>
12 #include <ccan/tdb/hash.c>
13 #include <ccan/tap/tap.h>
17 static unsigned int tdb_dumb_hash(TDB_DATA *key)
22 static void log_fn(struct tdb_context *tdb, enum tdb_debug_level level, const char *fmt, ...)
24 unsigned int *count = tdb_get_logging_private(tdb);
25 if (strstr(fmt, "hash"))
29 static unsigned int hdr_rwlocks(const char *fname)
31 struct tdb_header hdr;
33 int fd = open(fname, O_RDONLY);
37 if (read(fd, &hdr, sizeof(hdr)) != sizeof(hdr))
44 int main(int argc, char *argv[])
46 struct tdb_context *tdb;
47 unsigned int log_count, flags;
49 struct tdb_logging_context log_ctx = { log_fn, &log_count };
53 for (flags = 0; flags <= TDB_CONVERT; flags += TDB_CONVERT) {
54 unsigned int rwmagic = TDB_HASH_RWLOCK_MAGIC;
56 if (flags & TDB_CONVERT)
57 tdb_convert(&rwmagic, sizeof(rwmagic));
59 /* Create an old-style hash. */
61 tdb = tdb_open_ex("run-incompatible.tdb", 0, flags,
62 O_CREAT|O_RDWR|O_TRUNC, 0600, &log_ctx,
66 d.dptr = (void *)"Hello";
68 ok1(tdb_store(tdb, d, d, TDB_INSERT) == 0);
71 /* Should not have marked rwlocks field. */
72 ok1(hdr_rwlocks("run-incompatible.tdb") == 0);
74 /* We can still open any old-style with incompat flag. */
76 tdb = tdb_open_ex("run-incompatible.tdb", 0,
77 TDB_INCOMPATIBLE_HASH,
78 O_RDWR, 0600, &log_ctx, NULL);
81 r = tdb_fetch(tdb, d);
84 ok1(tdb_check(tdb, NULL, NULL) == 0);
88 tdb = tdb_open_ex("test/jenkins-le-hash.tdb", 0, 0, O_RDONLY,
89 0, &log_ctx, tdb_jenkins_hash);
92 ok1(tdb_check(tdb, NULL, NULL) == 0);
96 tdb = tdb_open_ex("test/jenkins-be-hash.tdb", 0, 0, O_RDONLY,
97 0, &log_ctx, tdb_jenkins_hash);
100 ok1(tdb_check(tdb, NULL, NULL) == 0);
103 /* OK, now create with incompatible flag, default hash. */
105 tdb = tdb_open_ex("run-incompatible.tdb", 0,
106 flags|TDB_INCOMPATIBLE_HASH,
107 O_CREAT|O_RDWR|O_TRUNC, 0600, &log_ctx,
111 d.dptr = (void *)"Hello";
113 ok1(tdb_store(tdb, d, d, TDB_INSERT) == 0);
116 /* Should have marked rwlocks field. */
117 ok1(hdr_rwlocks("run-incompatible.tdb") == rwmagic);
119 /* Cannot open with old hash. */
121 tdb = tdb_open_ex("run-incompatible.tdb", 0, 0,
122 O_RDWR, 0600, &log_ctx, tdb_old_hash);
126 /* Can open with jenkins hash. */
128 tdb = tdb_open_ex("run-incompatible.tdb", 0, 0,
129 O_RDWR, 0600, &log_ctx, tdb_jenkins_hash);
132 r = tdb_fetch(tdb, d);
135 ok1(tdb_check(tdb, NULL, NULL) == 0);
138 /* Can open by letting it figure it out itself. */
140 tdb = tdb_open_ex("run-incompatible.tdb", 0, 0,
141 O_RDWR, 0600, &log_ctx, NULL);
144 r = tdb_fetch(tdb, d);
147 ok1(tdb_check(tdb, NULL, NULL) == 0);
150 /* We can also use incompatible hash with other hashes. */
152 tdb = tdb_open_ex("run-incompatible.tdb", 0,
153 flags|TDB_INCOMPATIBLE_HASH,
154 O_CREAT|O_RDWR|O_TRUNC, 0600, &log_ctx,
158 d.dptr = (void *)"Hello";
160 ok1(tdb_store(tdb, d, d, TDB_INSERT) == 0);
163 /* Should have marked rwlocks field. */
164 ok1(hdr_rwlocks("run-incompatible.tdb") == rwmagic);
166 /* It should not open if we don't specify. */
168 tdb = tdb_open_ex("run-incompatible.tdb", 0, 0, O_RDWR, 0,
173 /* Should reopen with correct hash. */
175 tdb = tdb_open_ex("run-incompatible.tdb", 0, 0, O_RDWR, 0,
176 &log_ctx, tdb_dumb_hash);
179 r = tdb_fetch(tdb, d);
182 ok1(tdb_check(tdb, NULL, NULL) == 0);
186 return exit_status();