1 #include "tdb2-source.h"
2 #include <ccan/tap/tap.h>
6 static uint64_t tdb1_dumb_hash(const void *key
, size_t len
, uint64_t seed
,
12 static void log_fn(struct tdb_context
*tdb
, enum tdb_log_level level
,
13 enum TDB_ERROR ecode
, const char *message
, void *priv
)
15 unsigned int *count
= priv
;
16 if (strstr(message
, "hash"))
20 static unsigned int hdr_rwlocks(const char *fname
)
22 struct tdb1_header hdr
;
24 int fd
= open(fname
, O_RDONLY
);
28 if (read(fd
, &hdr
, sizeof(hdr
)) != sizeof(hdr
))
35 static uint64_t jenkins_hashfn(const void *key
, size_t len
, uint64_t seed
,
38 return hashlittle(key
, len
);
41 static uint64_t old_hash(const void *key
, size_t len
, uint64_t seed
,
44 return tdb1_old_hash(key
, len
, seed
, unused
);
47 int main(int argc
, char *argv
[])
49 struct tdb_context
*tdb
;
50 unsigned int log_count
, flags
;
52 union tdb_attribute log_attr
, jhash_attr
, ohash_attr
,
53 incompat_hash_attr
, dumbhash_attr
;
55 log_attr
.base
.attr
= TDB_ATTRIBUTE_LOG
;
56 log_attr
.base
.next
= NULL
;
57 log_attr
.log
.fn
= log_fn
;
58 log_attr
.log
.data
= &log_count
;
60 jhash_attr
.base
.attr
= TDB_ATTRIBUTE_HASH
;
61 jhash_attr
.base
.next
= &log_attr
;
62 jhash_attr
.hash
.fn
= jenkins_hashfn
;
64 ohash_attr
.base
.attr
= TDB_ATTRIBUTE_HASH
;
65 ohash_attr
.base
.next
= &log_attr
;
66 ohash_attr
.hash
.fn
= old_hash
;
68 incompat_hash_attr
.base
.attr
= TDB_ATTRIBUTE_HASH
;
69 incompat_hash_attr
.base
.next
= &log_attr
;
70 incompat_hash_attr
.hash
.fn
= tdb1_incompatible_hash
;
72 dumbhash_attr
.base
.attr
= TDB_ATTRIBUTE_HASH
;
73 dumbhash_attr
.base
.next
= &log_attr
;
74 dumbhash_attr
.hash
.fn
= tdb1_dumb_hash
;
78 for (flags
= 0; flags
<= TDB_CONVERT
; flags
+= TDB_CONVERT
) {
79 unsigned int rwmagic
= TDB1_HASH_RWLOCK_MAGIC
;
81 if (flags
& TDB_CONVERT
)
82 tdb1_convert(&rwmagic
, sizeof(rwmagic
));
84 /* Create an old-style hash. */
86 tdb
= tdb_open("run-incompatible.tdb1", flags
|TDB_VERSION1
,
87 O_CREAT
|O_RDWR
|O_TRUNC
, 0600, &log_attr
);
90 d
.dptr
= (void *)"Hello";
92 ok1(tdb_store(tdb
, d
, d
, TDB_INSERT
) == TDB_SUCCESS
);
95 /* Should not have marked rwlocks field. */
96 ok1(hdr_rwlocks("run-incompatible.tdb1") == 0);
98 /* We can still open any old-style with incompat hash. */
100 tdb
= tdb_open("run-incompatible.tdb1",
102 O_RDWR
, 0600, &incompat_hash_attr
);
105 ok1(tdb_fetch(tdb
, d
, &d
) == TDB_SUCCESS
);
108 ok1(tdb_check(tdb
, NULL
, NULL
) == TDB_SUCCESS
);
112 tdb
= tdb_open("test/jenkins-le-hash.tdb1",
113 TDB_VERSION1
, O_RDONLY
, 0, &jhash_attr
);
116 ok1(tdb_check(tdb
, NULL
, NULL
) == TDB_SUCCESS
);
120 tdb
= tdb_open("test/jenkins-be-hash.tdb1",
121 TDB_VERSION1
, O_RDONLY
, 0, &jhash_attr
);
124 ok1(tdb_check(tdb
, NULL
, NULL
) == TDB_SUCCESS
);
127 /* OK, now create with incompatible hash. */
129 tdb
= tdb_open("run-incompatible.tdb1",
131 O_CREAT
|O_RDWR
|O_TRUNC
, 0600,
132 &incompat_hash_attr
);
135 d
.dptr
= (void *)"Hello";
137 ok1(tdb_store(tdb
, d
, d
, TDB_INSERT
) == TDB_SUCCESS
);
140 /* Should have marked rwlocks field. */
141 ok1(hdr_rwlocks("run-incompatible.tdb1") == rwmagic
);
143 /* Cannot open with old hash. */
145 tdb
= tdb_open("run-incompatible.tdb1", TDB_VERSION1
,
146 O_RDWR
, 0600, &ohash_attr
);
150 /* Can open with jenkins hash. */
152 tdb
= tdb_open("run-incompatible.tdb1", TDB_VERSION1
,
153 O_RDWR
, 0600, &jhash_attr
);
156 ok1(tdb_fetch(tdb
, d
, &d
) == TDB_SUCCESS
);
159 ok1(tdb_check(tdb
, NULL
, NULL
) == TDB_SUCCESS
);
162 /* Can open by letting it figure it out itself. */
164 tdb
= tdb_open("run-incompatible.tdb1", TDB_VERSION1
,
165 O_RDWR
, 0600, &log_attr
);
168 d
.dptr
= (void *)"Hello";
170 ok1(tdb_fetch(tdb
, d
, &d
) == TDB_SUCCESS
);
173 ok1(tdb_check(tdb
, NULL
, NULL
) == TDB_SUCCESS
);
176 /* FIXME: Not possible with TDB2 :( */
177 /* We can also use incompatible hash with other hashes. */
179 tdb
= tdb_open("run-incompatible.tdb1",
181 O_CREAT
|O_RDWR
|O_TRUNC
, 0600, &dumbhash_attr
);
184 d
.dptr
= (void *)"Hello";
186 ok1(tdb_store(tdb
, d
, d
, TDB_INSERT
) == TDB_SUCCESS
);
189 /* FIXME: Should have marked rwlocks field. */
190 ok1(hdr_rwlocks("run-incompatible.tdb1") != rwmagic
);
192 /* It should not open if we don't specify. */
194 tdb
= tdb_open("run-incompatible.tdb1", TDB_VERSION1
, O_RDWR
, 0,
199 /* Should reopen with correct hash. */
201 tdb
= tdb_open("run-incompatible.tdb1", TDB_VERSION1
, O_RDWR
, 0,
205 ok1(tdb_fetch(tdb
, d
, &d
) == TDB_SUCCESS
);
208 ok1(tdb_check(tdb
, NULL
, NULL
) == TDB_SUCCESS
);
212 return exit_status();