tdb2: allow multiple chain locks.
[ccan] / ccan / tdb2 / test / run-lockall.c
1 #include "config.h"
2 #include <unistd.h>
3 #include "lock-tracking.h"
4
5 #define fcntl fcntl_with_lockcheck
6
7 #include <ccan/tdb2/tdb.c>
8 #include <ccan/tdb2/open.c>
9 #include <ccan/tdb2/free.c>
10 #include <ccan/tdb2/lock.c>
11 #include <ccan/tdb2/io.c>
12 #include <ccan/tdb2/hash.c>
13 #include <ccan/tdb2/check.c>
14 #include <ccan/tdb2/transaction.c>
15 #include <ccan/tap/tap.h>
16 #include <stdlib.h>
17 #include <stdbool.h>
18 #include <stdarg.h>
19 #include <err.h>
20 #include "external-agent.h"
21 #include "logging.h"
22
23 #define TEST_DBNAME "run-lockall.tdb"
24
25 #undef fcntl
26
27 int main(int argc, char *argv[])
28 {
29         struct agent *agent;
30         const int flags[] = { TDB_DEFAULT,
31                               TDB_NOMMAP,
32                               TDB_CONVERT,
33                               TDB_CONVERT | TDB_NOMMAP };
34         int i;
35
36         plan_tests(13 * sizeof(flags)/sizeof(flags[0]) + 1);
37         agent = prepare_external_agent();
38         if (!agent)
39                 err(1, "preparing agent");
40
41         for (i = 0; i < sizeof(flags)/sizeof(flags[0]); i++) {
42                 enum agent_return ret;
43                 struct tdb_context *tdb;
44
45                 tdb = tdb_open(TEST_DBNAME, flags[i],
46                                O_RDWR|O_CREAT|O_TRUNC, 0600, &tap_log_attr);
47                 ok1(tdb);
48
49                 ret = external_agent_operation(agent, OPEN, TEST_DBNAME);
50                 ok1(ret == SUCCESS);
51
52                 ok1(tdb_lockall(tdb) == TDB_SUCCESS);
53                 ok1(external_agent_operation(agent, STORE, "key")
54                     == WOULD_HAVE_BLOCKED);
55                 ok1(external_agent_operation(agent, FETCH, "key")
56                     == WOULD_HAVE_BLOCKED);
57                 /* Test nesting. */
58                 ok1(tdb_lockall(tdb) == TDB_SUCCESS);
59                 tdb_unlockall(tdb);
60                 tdb_unlockall(tdb);
61
62                 ok1(external_agent_operation(agent, STORE, "key") == SUCCESS);
63
64                 ok1(tdb_lockall_read(tdb) == TDB_SUCCESS);
65                 ok1(external_agent_operation(agent, STORE, "key")
66                     == WOULD_HAVE_BLOCKED);
67                 ok1(external_agent_operation(agent, FETCH, "key") == SUCCESS);
68                 ok1(tdb_lockall_read(tdb) == TDB_SUCCESS);
69                 tdb_unlockall_read(tdb);
70                 tdb_unlockall_read(tdb);
71
72                 ok1(external_agent_operation(agent, STORE, "key") == SUCCESS);
73                 ok1(external_agent_operation(agent, CLOSE, NULL) == SUCCESS);
74                 tdb_close(tdb);
75         }
76
77         free_external_agent(agent);
78         ok1(tap_log_messages == 0);
79         return exit_status();
80 }