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 ok1(tdb_fetch(tdb, d).dsize == 5);
82 ok1(tdb_check(tdb, NULL, NULL) == 0);
86 tdb = tdb_open_ex("test/jenkins-le-hash.tdb", 0, 0, O_RDONLY,
87 0, &log_ctx, tdb_jenkins_hash);
90 ok1(tdb_check(tdb, NULL, NULL) == 0);
94 tdb = tdb_open_ex("test/jenkins-be-hash.tdb", 0, 0, O_RDONLY,
95 0, &log_ctx, tdb_jenkins_hash);
98 ok1(tdb_check(tdb, NULL, NULL) == 0);
101 /* OK, now create with incompatible flag, default hash. */
103 tdb = tdb_open_ex("run-incompatible.tdb", 0,
104 flags|TDB_INCOMPATIBLE_HASH,
105 O_CREAT|O_RDWR|O_TRUNC, 0600, &log_ctx,
109 d.dptr = (void *)"Hello";
111 ok1(tdb_store(tdb, d, d, TDB_INSERT) == 0);
114 /* Should have marked rwlocks field. */
115 ok1(hdr_rwlocks("run-incompatible.tdb") == rwmagic);
117 /* Cannot open with old hash. */
119 tdb = tdb_open_ex("run-incompatible.tdb", 0, 0,
120 O_RDWR, 0600, &log_ctx, tdb_old_hash);
124 /* Can open with jenkins hash. */
126 tdb = tdb_open_ex("run-incompatible.tdb", 0, 0,
127 O_RDWR, 0600, &log_ctx, tdb_jenkins_hash);
130 ok1(tdb_fetch(tdb, d).dsize == 5);
131 ok1(tdb_check(tdb, NULL, NULL) == 0);
134 /* Can open by letting it figure it out itself. */
136 tdb = tdb_open_ex("run-incompatible.tdb", 0, 0,
137 O_RDWR, 0600, &log_ctx, NULL);
140 ok1(tdb_fetch(tdb, d).dsize == 5);
141 ok1(tdb_check(tdb, NULL, NULL) == 0);
144 /* We can also use incompatible hash with other hashes. */
146 tdb = tdb_open_ex("run-incompatible.tdb", 0,
147 flags|TDB_INCOMPATIBLE_HASH,
148 O_CREAT|O_RDWR|O_TRUNC, 0600, &log_ctx,
152 d.dptr = (void *)"Hello";
154 ok1(tdb_store(tdb, d, d, TDB_INSERT) == 0);
157 /* Should have marked rwlocks field. */
158 ok1(hdr_rwlocks("run-incompatible.tdb") == rwmagic);
160 /* It should not open if we don't specify. */
162 tdb = tdb_open_ex("run-incompatible.tdb", 0, 0, O_RDWR, 0,
167 /* Should reopen with correct hash. */
169 tdb = tdb_open_ex("run-incompatible.tdb", 0, 0, O_RDWR, 0,
170 &log_ctx, tdb_dumb_hash);
173 ok1(tdb_fetch(tdb, d).dsize == 5);
174 ok1(tdb_check(tdb, NULL, NULL) == 0);
178 return exit_status();