ccan/ntdb: demote to junkcode.
[ccan] / junkcode / rusty@rustcorp.com.au-ntdb / test / api-82-lockattr.c
1 #include "../private.h" // for ntdb_fcntl_unlock
2 #include "../ntdb.h"
3 #include "tap-interface.h"
4 #include <errno.h>
5 #include "logging.h"
6 #include "helpapi-external-agent.h"
7
8 static int mylock(int fd, int rw, off_t off, off_t len, bool waitflag,
9                   void *_err)
10 {
11         int *lock_err = _err;
12         struct flock fl;
13         int ret;
14
15         if (*lock_err) {
16                 errno = *lock_err;
17                 return -1;
18         }
19
20         do {
21                 fl.l_type = rw;
22                 fl.l_whence = SEEK_SET;
23                 fl.l_start = off;
24                 fl.l_len = len;
25
26                 if (waitflag)
27                         ret = fcntl(fd, F_SETLKW, &fl);
28                 else
29                         ret = fcntl(fd, F_SETLK, &fl);
30         } while (ret != 0 && errno == EINTR);
31
32         return ret;
33 }
34
35 static int trav_err;
36 static int trav(struct ntdb_context *ntdb, NTDB_DATA k, NTDB_DATA d, int *terr)
37 {
38         *terr = trav_err;
39         return 0;
40 }
41
42 int main(int argc, char *argv[])
43 {
44         unsigned int i;
45         struct ntdb_context *ntdb;
46         int flags[] = { NTDB_DEFAULT, NTDB_NOMMAP,
47                         NTDB_CONVERT, NTDB_NOMMAP|NTDB_CONVERT };
48         union ntdb_attribute lock_attr;
49         NTDB_DATA key = ntdb_mkdata("key", 3);
50         NTDB_DATA data = ntdb_mkdata("data", 4);
51         int lock_err;
52
53         lock_attr.base.attr = NTDB_ATTRIBUTE_FLOCK;
54         lock_attr.base.next = &tap_log_attr;
55         lock_attr.flock.lock = mylock;
56         lock_attr.flock.unlock = ntdb_fcntl_unlock;
57         lock_attr.flock.data = &lock_err;
58
59         plan_tests(sizeof(flags) / sizeof(flags[0]) * 81);
60
61         for (i = 0; i < sizeof(flags) / sizeof(flags[0]); i++) {
62                 NTDB_DATA d;
63
64                 /* Nonblocking open; expect no error message. */
65                 lock_err = EAGAIN;
66                 ntdb = ntdb_open("run-82-lockattr.ntdb", flags[i]|MAYBE_NOSYNC,
67                                  O_RDWR|O_CREAT|O_TRUNC, 0600, &lock_attr);
68                 ok(errno == lock_err, "Errno is %u", errno);
69                 ok1(!ntdb);
70                 ok1(tap_log_messages == 0);
71
72                 lock_err = EINTR;
73                 ntdb = ntdb_open("run-82-lockattr.ntdb", flags[i]|MAYBE_NOSYNC,
74                                  O_RDWR|O_CREAT|O_TRUNC, 0600, &lock_attr);
75                 ok(errno == lock_err, "Errno is %u", errno);
76                 ok1(!ntdb);
77                 ok1(tap_log_messages == 0);
78
79                 /* Forced fail open. */
80                 lock_err = ENOMEM;
81                 ntdb = ntdb_open("run-82-lockattr.ntdb", flags[i]|MAYBE_NOSYNC,
82                                  O_RDWR|O_CREAT|O_TRUNC, 0600, &lock_attr);
83                 ok1(errno == lock_err);
84                 ok1(!ntdb);
85                 ok1(tap_log_messages == 1);
86                 tap_log_messages = 0;
87
88                 lock_err = 0;
89                 ntdb = ntdb_open("run-82-lockattr.ntdb", flags[i]|MAYBE_NOSYNC,
90                                  O_RDWR|O_CREAT|O_TRUNC, 0600, &lock_attr);
91                 if (!ok1(ntdb))
92                         continue;
93                 ok1(tap_log_messages == 0);
94
95                 /* Nonblocking store. */
96                 lock_err = EAGAIN;
97                 ok1(ntdb_store(ntdb, key, data, NTDB_REPLACE) == NTDB_ERR_LOCK);
98                 ok1(tap_log_messages == 0);
99                 lock_err = EINTR;
100                 ok1(ntdb_store(ntdb, key, data, NTDB_REPLACE) == NTDB_ERR_LOCK);
101                 ok1(tap_log_messages == 0);
102                 lock_err = ENOMEM;
103                 ok1(ntdb_store(ntdb, key, data, NTDB_REPLACE) == NTDB_ERR_LOCK);
104                 ok1(tap_log_messages == 1);
105                 tap_log_messages = 0;
106
107                 /* Nonblocking fetch. */
108                 lock_err = EAGAIN;
109                 ok1(!ntdb_exists(ntdb, key));
110                 ok1(tap_log_messages == 0);
111                 lock_err = EINTR;
112                 ok1(!ntdb_exists(ntdb, key));
113                 ok1(tap_log_messages == 0);
114                 lock_err = ENOMEM;
115                 ok1(!ntdb_exists(ntdb, key));
116                 ok1(tap_log_messages == 1);
117                 tap_log_messages = 0;
118
119                 lock_err = EAGAIN;
120                 ok1(ntdb_fetch(ntdb, key, &d) == NTDB_ERR_LOCK);
121                 ok1(tap_log_messages == 0);
122                 lock_err = EINTR;
123                 ok1(ntdb_fetch(ntdb, key, &d) == NTDB_ERR_LOCK);
124                 ok1(tap_log_messages == 0);
125                 lock_err = ENOMEM;
126                 ok1(ntdb_fetch(ntdb, key, &d) == NTDB_ERR_LOCK);
127                 ok1(tap_log_messages == 1);
128                 tap_log_messages = 0;
129
130                 /* Nonblocking delete. */
131                 lock_err = EAGAIN;
132                 ok1(ntdb_delete(ntdb, key) == NTDB_ERR_LOCK);
133                 ok1(tap_log_messages == 0);
134                 lock_err = EINTR;
135                 ok1(ntdb_delete(ntdb, key) == NTDB_ERR_LOCK);
136                 ok1(tap_log_messages == 0);
137                 lock_err = ENOMEM;
138                 ok1(ntdb_delete(ntdb, key) == NTDB_ERR_LOCK);
139                 ok1(tap_log_messages == 1);
140                 tap_log_messages = 0;
141
142                 /* Nonblocking locks. */
143                 lock_err = EAGAIN;
144                 ok1(ntdb_chainlock(ntdb, key) == NTDB_ERR_LOCK);
145                 ok1(tap_log_messages == 0);
146                 lock_err = EINTR;
147                 ok1(ntdb_chainlock(ntdb, key) == NTDB_ERR_LOCK);
148                 ok1(tap_log_messages == 0);
149                 lock_err = ENOMEM;
150                 ok1(ntdb_chainlock(ntdb, key) == NTDB_ERR_LOCK);
151                 ok1(tap_log_messages == 1);
152                 tap_log_messages = 0;
153
154                 lock_err = EAGAIN;
155                 ok1(ntdb_chainlock_read(ntdb, key) == NTDB_ERR_LOCK);
156                 ok1(tap_log_messages == 0);
157                 lock_err = EINTR;
158                 ok1(ntdb_chainlock_read(ntdb, key) == NTDB_ERR_LOCK);
159                 ok1(tap_log_messages == 0);
160                 lock_err = ENOMEM;
161                 ok1(ntdb_chainlock_read(ntdb, key) == NTDB_ERR_LOCK);
162                 ok1(tap_log_messages == 1);
163                 tap_log_messages = 0;
164
165                 lock_err = EAGAIN;
166                 ok1(ntdb_lockall(ntdb) == NTDB_ERR_LOCK);
167                 ok1(tap_log_messages == 0);
168                 lock_err = EINTR;
169                 ok1(ntdb_lockall(ntdb) == NTDB_ERR_LOCK);
170                 ok1(tap_log_messages == 0);
171                 lock_err = ENOMEM;
172                 ok1(ntdb_lockall(ntdb) == NTDB_ERR_LOCK);
173                 /* This actually does divide and conquer. */
174                 ok1(tap_log_messages > 0);
175                 tap_log_messages = 0;
176
177                 lock_err = EAGAIN;
178                 ok1(ntdb_lockall_read(ntdb) == NTDB_ERR_LOCK);
179                 ok1(tap_log_messages == 0);
180                 lock_err = EINTR;
181                 ok1(ntdb_lockall_read(ntdb) == NTDB_ERR_LOCK);
182                 ok1(tap_log_messages == 0);
183                 lock_err = ENOMEM;
184                 ok1(ntdb_lockall_read(ntdb) == NTDB_ERR_LOCK);
185                 ok1(tap_log_messages > 0);
186                 tap_log_messages = 0;
187
188                 /* Nonblocking traverse; go nonblock partway through. */
189                 lock_err = 0;
190                 ok1(ntdb_store(ntdb, key, data, NTDB_REPLACE) == 0);
191                 /* Need two entries to ensure two lock attempts! */
192                 ok1(ntdb_store(ntdb, ntdb_mkdata("key2", 4), data,
193                                NTDB_REPLACE) == 0);
194                 trav_err = EAGAIN;
195                 ok1(ntdb_traverse(ntdb, trav, &lock_err) == NTDB_ERR_LOCK);
196                 ok1(tap_log_messages == 0);
197                 trav_err = EINTR;
198                 lock_err = 0;
199                 ok1(ntdb_traverse(ntdb, trav, &lock_err) == NTDB_ERR_LOCK);
200                 ok1(tap_log_messages == 0);
201                 trav_err = ENOMEM;
202                 lock_err = 0;
203                 ok1(ntdb_traverse(ntdb, trav, &lock_err) == NTDB_ERR_LOCK);
204                 ok1(tap_log_messages == 1);
205                 tap_log_messages = 0;
206
207                 /* Nonblocking transactions. */
208                 lock_err = EAGAIN;
209                 ok1(ntdb_transaction_start(ntdb) == NTDB_ERR_LOCK);
210                 ok1(tap_log_messages == 0);
211                 lock_err = EINTR;
212                 ok1(ntdb_transaction_start(ntdb) == NTDB_ERR_LOCK);
213                 ok1(tap_log_messages == 0);
214                 lock_err = ENOMEM;
215                 ok1(ntdb_transaction_start(ntdb) == NTDB_ERR_LOCK);
216                 ok1(tap_log_messages == 1);
217                 tap_log_messages = 0;
218
219                 /* Nonblocking transaction prepare. */
220                 lock_err = 0;
221                 ok1(ntdb_transaction_start(ntdb) == 0);
222                 ok1(ntdb_delete(ntdb, key) == 0);
223
224                 lock_err = EAGAIN;
225                 ok1(ntdb_transaction_prepare_commit(ntdb) == NTDB_ERR_LOCK);
226                 ok1(tap_log_messages == 0);
227
228                 lock_err = 0;
229                 ok1(ntdb_transaction_prepare_commit(ntdb) == 0);
230                 ok1(ntdb_transaction_commit(ntdb) == 0);
231
232                 /* And the transaction was committed, right? */
233                 ok1(!ntdb_exists(ntdb, key));
234                 ntdb_close(ntdb);
235                 ok1(tap_log_messages == 0);
236         }
237         return exit_status();
238 }