1 #include "tdb2-source.h"
2 #include <ccan/tap/tap.h>
6 static unsigned int tdb1_dumb_hash(TDB_DATA *key)
11 static void log_fn(struct tdb1_context *tdb, enum tdb_log_level level,
12 enum TDB_ERROR ecode, const char *message, void *priv)
14 unsigned int *count = priv;
15 if (strstr(message, "hash"))
19 static unsigned int hdr_rwlocks(const char *fname)
21 struct tdb1_header hdr;
23 int fd = open(fname, O_RDONLY);
27 if (read(fd, &hdr, sizeof(hdr)) != sizeof(hdr))
34 static unsigned int jenkins_hashfn(TDB_DATA *key)
36 return hashlittle(key->dptr, key->dsize);
39 static unsigned int old_hash(TDB_DATA *key)
41 return tdb1_old_hash(key);
44 int main(int argc, char *argv[])
46 struct tdb1_context *tdb;
47 unsigned int log_count, flags;
49 struct tdb1_logging_context log_ctx = { log_fn, &log_count };
53 for (flags = 0; flags <= TDB_CONVERT; flags += TDB_CONVERT) {
54 unsigned int rwmagic = TDB1_HASH_RWLOCK_MAGIC;
56 if (flags & TDB_CONVERT)
57 tdb1_convert(&rwmagic, sizeof(rwmagic));
59 /* Create an old-style hash. */
61 tdb = tdb1_open_ex("run-incompatible.tdb", 0, flags,
62 O_CREAT|O_RDWR|O_TRUNC, 0600, &log_ctx,
66 d.dptr = (void *)"Hello";
68 ok1(tdb1_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 hash. */
76 tdb = tdb1_open_ex("run-incompatible.tdb", 0,
78 O_RDWR, 0600, &log_ctx,
79 tdb1_incompatible_hash);
82 d = tdb1_fetch(tdb, d);
85 ok1(tdb1_check(tdb, NULL, NULL) == 0);
89 tdb = tdb1_open_ex("test/jenkins-le-hash.tdb1", 0, 0, O_RDONLY,
90 0, &log_ctx, jenkins_hashfn);
93 ok1(tdb1_check(tdb, NULL, NULL) == 0);
97 tdb = tdb1_open_ex("test/jenkins-be-hash.tdb1", 0, 0, O_RDONLY,
98 0, &log_ctx, jenkins_hashfn);
101 ok1(tdb1_check(tdb, NULL, NULL) == 0);
104 /* OK, now create with incompatible hash. */
106 tdb = tdb1_open_ex("run-incompatible.tdb", 0,
108 O_CREAT|O_RDWR|O_TRUNC, 0600, &log_ctx,
109 tdb1_incompatible_hash);
112 d.dptr = (void *)"Hello";
114 ok1(tdb1_store(tdb, d, d, TDB_INSERT) == 0);
117 /* Should have marked rwlocks field. */
118 ok1(hdr_rwlocks("run-incompatible.tdb") == rwmagic);
120 /* Cannot open with old hash. */
122 tdb = tdb1_open_ex("run-incompatible.tdb", 0, 0,
123 O_RDWR, 0600, &log_ctx, old_hash);
127 /* Can open with jenkins hash. */
129 tdb = tdb1_open_ex("run-incompatible.tdb", 0, 0,
130 O_RDWR, 0600, &log_ctx, jenkins_hashfn);
133 d = tdb1_fetch(tdb, d);
136 ok1(tdb1_check(tdb, NULL, NULL) == 0);
139 /* Can open by letting it figure it out itself. */
141 tdb = tdb1_open_ex("run-incompatible.tdb", 0, 0,
142 O_RDWR, 0600, &log_ctx, NULL);
145 d.dptr = (void *)"Hello";
147 d = tdb1_fetch(tdb, d);
150 ok1(tdb1_check(tdb, NULL, NULL) == 0);
153 /* FIXME: Not possible with TDB2 :( */
154 /* We can also use incompatible hash with other hashes. */
156 tdb = tdb1_open_ex("run-incompatible.tdb", 0,
158 O_CREAT|O_RDWR|O_TRUNC, 0600, &log_ctx,
162 d.dptr = (void *)"Hello";
164 ok1(tdb1_store(tdb, d, d, TDB_INSERT) == 0);
167 /* FIXME: Should have marked rwlocks field. */
168 ok1(hdr_rwlocks("run-incompatible.tdb") != rwmagic);
170 /* It should not open if we don't specify. */
172 tdb = tdb1_open_ex("run-incompatible.tdb", 0, 0, O_RDWR, 0,
177 /* Should reopen with correct hash. */
179 tdb = tdb1_open_ex("run-incompatible.tdb", 0, 0, O_RDWR, 0,
180 &log_ctx, tdb1_dumb_hash);
183 d = tdb1_fetch(tdb, d);
186 ok1(tdb1_check(tdb, NULL, NULL) == 0);
190 return exit_status();