b94bc01bffe4a9b19740b3cee2d95936a174930a
[metze/samba/wip.git] / lib / ntdb / test / run-30-exhaust-before-expand.c
1 #include "ntdb-source.h"
2 #include "tap-interface.h"
3 #include "logging.h"
4
5 static bool empty_freetable(struct ntdb_context *ntdb)
6 {
7         struct ntdb_freetable ftab;
8         unsigned int i;
9
10         /* Now, free table should be completely exhausted in zone 0 */
11         if (ntdb_read_convert(ntdb, ntdb->ftable_off, &ftab, sizeof(ftab)) != 0)
12                 abort();
13
14         for (i = 0; i < sizeof(ftab.buckets)/sizeof(ftab.buckets[0]); i++) {
15                 if (ftab.buckets[i])
16                         return false;
17         }
18         return true;
19 }
20
21
22 int main(int argc, char *argv[])
23 {
24         unsigned int i, j;
25         struct ntdb_context *ntdb;
26         int flags[] = { NTDB_INTERNAL, NTDB_DEFAULT, NTDB_NOMMAP,
27                         NTDB_INTERNAL|NTDB_CONVERT, NTDB_CONVERT,
28                         NTDB_NOMMAP|NTDB_CONVERT };
29
30         plan_tests(sizeof(flags) / sizeof(flags[0]) * 9 + 1);
31
32         for (i = 0; i < sizeof(flags) / sizeof(flags[0]); i++) {
33                 NTDB_DATA k;
34                 uint64_t size;
35                 bool was_empty = false;
36
37                 k.dptr = (void *)&j;
38                 k.dsize = sizeof(j);
39
40                 ntdb = ntdb_open("run-30-exhaust-before-expand.ntdb", flags[i],
41                                O_RDWR|O_CREAT|O_TRUNC, 0600, &tap_log_attr);
42                 ok1(ntdb);
43                 if (!ntdb)
44                         continue;
45
46                 ok1(empty_freetable(ntdb));
47                 /* Need some hash lock for expand. */
48                 ok1(ntdb_lock_hashes(ntdb, 0, 1, F_WRLCK, NTDB_LOCK_WAIT) == 0);
49                 /* Create some free space. */
50                 ok1(ntdb_expand(ntdb, 1) == 0);
51                 ok1(ntdb_unlock_hashes(ntdb, 0, 1, F_WRLCK) == 0);
52                 ok1(ntdb_check(ntdb, NULL, NULL) == 0);
53                 ok1(!empty_freetable(ntdb));
54
55                 size = ntdb->file->map_size;
56                 /* Insert minimal-length records until we expand. */
57                 for (j = 0; ntdb->file->map_size == size; j++) {
58                         was_empty = empty_freetable(ntdb);
59                         if (ntdb_store(ntdb, k, k, NTDB_INSERT) != 0)
60                                 err(1, "Failed to store record %i", j);
61                 }
62
63                 /* Would have been empty before expansion, but no longer. */
64                 ok1(was_empty);
65                 ok1(!empty_freetable(ntdb));
66                 ntdb_close(ntdb);
67         }
68
69         ok1(tap_log_messages == 0);
70         return exit_status();
71 }