tdb: don't use err.h in tests.
[samba.git] / lib / tdb / test / run-incompatible.c
1 #include "../common/tdb_private.h"
2 #include "../common/io.c"
3 #include "../common/tdb.c"
4 #include "../common/lock.c"
5 #include "../common/freelist.c"
6 #include "../common/traverse.c"
7 #include "../common/transaction.c"
8 #include "../common/error.c"
9 #include "../common/open.c"
10 #include "../common/check.c"
11 #include "../common/hash.c"
12 #include "tap-interface.h"
13 #include <stdlib.h>
14
15 static unsigned int tdb_dumb_hash(TDB_DATA *key)
16 {
17         return key->dsize;
18 }
19
20 static void log_fn(struct tdb_context *tdb, enum tdb_debug_level level, const char *fmt, ...)
21 {
22         unsigned int *count = tdb_get_logging_private(tdb);
23         if (strstr(fmt, "hash"))
24                 (*count)++;
25 }
26
27 static unsigned int hdr_rwlocks(const char *fname)
28 {
29         struct tdb_header hdr;
30
31         int fd = open(fname, O_RDONLY);
32         if (fd == -1)
33                 return -1;
34
35         if (read(fd, &hdr, sizeof(hdr)) != sizeof(hdr))
36                 return -1;
37
38         close(fd);
39         return hdr.rwlocks;
40 }
41
42 int main(int argc, char *argv[])
43 {
44         struct tdb_context *tdb;
45         unsigned int log_count, flags;
46         TDB_DATA d, r;
47         struct tdb_logging_context log_ctx = { log_fn, &log_count };
48
49         plan_tests(38 * 2);
50
51         for (flags = 0; flags <= TDB_CONVERT; flags += TDB_CONVERT) {
52                 unsigned int rwmagic = TDB_HASH_RWLOCK_MAGIC;
53
54                 if (flags & TDB_CONVERT)
55                         tdb_convert(&rwmagic, sizeof(rwmagic));
56
57                 /* Create an old-style hash. */
58                 log_count = 0;
59                 tdb = tdb_open_ex("run-incompatible.tdb", 0, flags,
60                                   O_CREAT|O_RDWR|O_TRUNC, 0600, &log_ctx,
61                                   NULL);
62                 ok1(tdb);
63                 ok1(log_count == 0);
64                 d.dptr = (void *)"Hello";
65                 d.dsize = 5;
66                 ok1(tdb_store(tdb, d, d, TDB_INSERT) == 0);
67                 tdb_close(tdb);
68
69                 /* Should not have marked rwlocks field. */
70                 ok1(hdr_rwlocks("run-incompatible.tdb") == 0);
71
72                 /* We can still open any old-style with incompat flag. */
73                 log_count = 0;
74                 tdb = tdb_open_ex("run-incompatible.tdb", 0,
75                                   TDB_INCOMPATIBLE_HASH,
76                                   O_RDWR, 0600, &log_ctx, NULL);
77                 ok1(tdb);
78                 ok1(log_count == 0);
79                 r = tdb_fetch(tdb, d);
80                 ok1(r.dsize == 5);
81                 free(r.dptr);
82                 ok1(tdb_check(tdb, NULL, NULL) == 0);
83                 tdb_close(tdb);
84
85                 log_count = 0;
86                 tdb = tdb_open_ex("test/jenkins-le-hash.tdb", 0, 0, O_RDONLY,
87                                   0, &log_ctx, tdb_jenkins_hash);
88                 ok1(tdb);
89                 ok1(log_count == 0);
90                 ok1(tdb_check(tdb, NULL, NULL) == 0);
91                 tdb_close(tdb);
92
93                 log_count = 0;
94                 tdb = tdb_open_ex("test/jenkins-be-hash.tdb", 0, 0, O_RDONLY,
95                                   0, &log_ctx, tdb_jenkins_hash);
96                 ok1(tdb);
97                 ok1(log_count == 0);
98                 ok1(tdb_check(tdb, NULL, NULL) == 0);
99                 tdb_close(tdb);
100
101                 /* OK, now create with incompatible flag, default hash. */
102                 log_count = 0;
103                 tdb = tdb_open_ex("run-incompatible.tdb", 0,
104                                   flags|TDB_INCOMPATIBLE_HASH,
105                                   O_CREAT|O_RDWR|O_TRUNC, 0600, &log_ctx,
106                                   NULL);
107                 ok1(tdb);
108                 ok1(log_count == 0);
109                 d.dptr = (void *)"Hello";
110                 d.dsize = 5;
111                 ok1(tdb_store(tdb, d, d, TDB_INSERT) == 0);
112                 tdb_close(tdb);
113
114                 /* Should have marked rwlocks field. */
115                 ok1(hdr_rwlocks("run-incompatible.tdb") == rwmagic);
116
117                 /* Cannot open with old hash. */
118                 log_count = 0;
119                 tdb = tdb_open_ex("run-incompatible.tdb", 0, 0,
120                                   O_RDWR, 0600, &log_ctx, tdb_old_hash);
121                 ok1(!tdb);
122                 ok1(log_count == 1);
123
124                 /* Can open with jenkins hash. */
125                 log_count = 0;
126                 tdb = tdb_open_ex("run-incompatible.tdb", 0, 0,
127                                   O_RDWR, 0600, &log_ctx, tdb_jenkins_hash);
128                 ok1(tdb);
129                 ok1(log_count == 0);
130                 r = tdb_fetch(tdb, d);
131                 ok1(r.dsize == 5);
132                 free(r.dptr);
133                 ok1(tdb_check(tdb, NULL, NULL) == 0);
134                 tdb_close(tdb);
135
136                 /* Can open by letting it figure it out itself. */
137                 log_count = 0;
138                 tdb = tdb_open_ex("run-incompatible.tdb", 0, 0,
139                                   O_RDWR, 0600, &log_ctx, NULL);
140                 ok1(tdb);
141                 ok1(log_count == 0);
142                 r = tdb_fetch(tdb, d);
143                 ok1(r.dsize == 5);
144                 free(r.dptr);
145                 ok1(tdb_check(tdb, NULL, NULL) == 0);
146                 tdb_close(tdb);
147
148                 /* We can also use incompatible hash with other hashes. */
149                 log_count = 0;
150                 tdb = tdb_open_ex("run-incompatible.tdb", 0,
151                                   flags|TDB_INCOMPATIBLE_HASH,
152                                   O_CREAT|O_RDWR|O_TRUNC, 0600, &log_ctx,
153                                   tdb_dumb_hash);
154                 ok1(tdb);
155                 ok1(log_count == 0);
156                 d.dptr = (void *)"Hello";
157                 d.dsize = 5;
158                 ok1(tdb_store(tdb, d, d, TDB_INSERT) == 0);
159                 tdb_close(tdb);
160
161                 /* Should have marked rwlocks field. */
162                 ok1(hdr_rwlocks("run-incompatible.tdb") == rwmagic);
163
164                 /* It should not open if we don't specify. */
165                 log_count = 0;
166                 tdb = tdb_open_ex("run-incompatible.tdb", 0, 0, O_RDWR, 0,
167                                   &log_ctx, NULL);
168                 ok1(!tdb);
169                 ok1(log_count == 1);
170
171                 /* Should reopen with correct hash. */
172                 log_count = 0;
173                 tdb = tdb_open_ex("run-incompatible.tdb", 0, 0, O_RDWR, 0,
174                                   &log_ctx, tdb_dumb_hash);
175                 ok1(tdb);
176                 ok1(log_count == 0);
177                 r = tdb_fetch(tdb, d);
178                 ok1(r.dsize == 5);
179                 free(r.dptr);
180                 ok1(tdb_check(tdb, NULL, NULL) == 0);
181                 tdb_close(tdb);
182         }
183
184         return exit_status();
185 }