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