tdb2: use ccan/err instead of err.h
[ddiss/samba.git] / lib / tdb2 / test / run-tdb1-no-lock-during-traverse.c
1 #include "private.h"
2 #include <unistd.h>
3 #include "tdb1-lock-tracking.h"
4
5 #define fcntl fcntl_with_lockcheck1
6
7 #include "tdb2-source.h"
8 #include "tap-interface.h"
9 #include <stdlib.h>
10 #include "logging.h"
11
12 #undef fcntl
13
14 #define NUM_ENTRIES 10
15
16 static bool prepare_entries(struct tdb_context *tdb)
17 {
18         unsigned int i;
19         TDB_DATA key, data;
20
21         for (i = 0; i < NUM_ENTRIES; i++) {
22                 key.dsize = sizeof(i);
23                 key.dptr = (void *)&i;
24                 data = tdb_mkdata("world", strlen("world"));
25
26                 if (tdb_store(tdb, key, data, 0) != TDB_SUCCESS)
27                         return false;
28         }
29         return true;
30 }
31
32 static void delete_entries(struct tdb_context *tdb)
33 {
34         unsigned int i;
35         TDB_DATA key;
36
37         for (i = 0; i < NUM_ENTRIES; i++) {
38                 key.dsize = sizeof(i);
39                 key.dptr = (void *)&i;
40
41                 ok1(tdb_delete(tdb, key) == TDB_SUCCESS);
42         }
43 }
44
45 /* We don't know how many times this will run. */
46 static int delete_other(struct tdb_context *tdb, TDB_DATA key, TDB_DATA data,
47                         void *private_data)
48 {
49         unsigned int i;
50         memcpy(&i, key.dptr, 4);
51         i = (i + 1) % NUM_ENTRIES;
52         key.dptr = (void *)&i;
53         if (tdb_delete(tdb, key) != TDB_SUCCESS)
54                 (*(int *)private_data)++;
55         return 0;
56 }
57
58 static int delete_self(struct tdb_context *tdb, TDB_DATA key, TDB_DATA data,
59                         void *private_data)
60 {
61         ok1(tdb_delete(tdb, key) == TDB_SUCCESS);
62         return 0;
63 }
64
65 int main(int argc, char *argv[])
66 {
67         struct tdb_context *tdb;
68         int errors = 0;
69         union tdb_attribute hsize;
70
71         hsize.base.attr = TDB_ATTRIBUTE_TDB1_HASHSIZE;
72         hsize.base.next = &tap_log_attr;
73         hsize.tdb1_hashsize.hsize = 1024;
74
75         plan_tests(40);
76         tdb = tdb_open("run-no-lock-during-traverse.tdb1",
77                        TDB_VERSION1, O_CREAT|O_TRUNC|O_RDWR,
78                        0600, &hsize);
79
80         ok1(tdb);
81         ok1(prepare_entries(tdb));
82         ok1(locking_errors1 == 0);
83         ok1(tdb_lockall(tdb) == 0);
84         ok1(locking_errors1 == 0);
85         ok1(tdb_traverse(tdb, delete_other, &errors) >= 0);
86         ok1(errors == 0);
87         ok1(locking_errors1 == 0);
88         tdb_unlockall(tdb);
89
90         ok1(prepare_entries(tdb));
91         ok1(locking_errors1 == 0);
92         ok1(tdb_lockall(tdb) == 0);
93         ok1(locking_errors1 == 0);
94         ok1(tdb_traverse(tdb, delete_self, NULL) == NUM_ENTRIES);
95         ok1(locking_errors1 == 0);
96         tdb_unlockall(tdb);
97
98         ok1(prepare_entries(tdb));
99         ok1(locking_errors1 == 0);
100         ok1(tdb_lockall(tdb) == 0);
101         ok1(locking_errors1 == 0);
102         delete_entries(tdb);
103         ok1(locking_errors1 == 0);
104         tdb_unlockall(tdb);
105
106         ok1(tdb_close(tdb) == 0);
107
108         return exit_status();
109 }