]> git.ozlabs.org Git - ccan/blob - ccan/tdb2/test/run-capabilities.c
htable: fix bug where first entry has hash of 0 or 1.
[ccan] / ccan / tdb2 / test / run-capabilities.c
1 #include <ccan/failtest/failtest_override.h>
2 #include "tdb2-source.h"
3 #include <ccan/tap/tap.h>
4 #include "logging.h"
5 #include "layout.h"
6 #include "failtest_helper.h"
7 #include <stdarg.h>
8 #include <err.h>
9
10 static size_t len_of(bool breaks_check, bool breaks_write, bool breaks_open)
11 {
12         size_t len = 0;
13         if (breaks_check)
14                 len += 8;
15         if (breaks_write)
16                 len += 16;
17         if (breaks_open)
18                 len += 32;
19         return len;
20 }
21
22 /* Creates a TDB with various capabilities. */
23 static void create_tdb(const char *name,
24                        unsigned int cap,
25                        bool breaks_check,
26                        bool breaks_write,
27                        bool breaks_open, ...)
28 {
29         TDB_DATA key, data;
30         va_list ap;
31         struct tdb_layout *layout;
32         struct tdb_context *tdb;
33         int fd;
34
35         key = tdb_mkdata("Hello", 5);
36         data = tdb_mkdata("world", 5);
37
38         /* Create a TDB with some data, and some capabilities */
39         layout = new_tdb_layout();
40         tdb_layout_add_freetable(layout);
41         tdb_layout_add_used(layout, key, data, 6);
42         tdb_layout_add_free(layout, 80, 0);
43         tdb_layout_add_capability(layout, cap,
44                                   breaks_write, breaks_check, breaks_open,
45                                   len_of(breaks_check, breaks_write, breaks_open));
46
47         va_start(ap, breaks_open);
48         while ((cap = va_arg(ap, int)) != 0) {
49                 breaks_check = va_arg(ap, int);
50                 breaks_write = va_arg(ap, int);
51                 breaks_open = va_arg(ap, int);
52
53                 key.dsize--;
54                 tdb_layout_add_used(layout, key, data, 11 - key.dsize);
55                 tdb_layout_add_free(layout, 80, 0);
56                 tdb_layout_add_capability(layout, cap,
57                                           breaks_write, breaks_check,
58                                           breaks_open,
59                                           len_of(breaks_check, breaks_write,
60                                                  breaks_open));
61         }
62         va_end(ap);
63
64         /* We open-code this, because we need to use the failtest write. */
65         tdb = tdb_layout_get(layout, failtest_free, &tap_log_attr);
66
67         fd = open(name, O_RDWR|O_TRUNC|O_CREAT, 0600);
68         if (fd < 0)
69                 err(1, "opening %s for writing", name);
70         if (write(fd, tdb->file->map_ptr, tdb->file->map_size)
71             != tdb->file->map_size)
72                 err(1, "writing %s", name);
73         close(fd);
74         tdb_close(tdb);
75         tdb_layout_free(layout);
76 }
77
78 /* Note all the "goto out" early exits: they're to shorten failtest time. */
79 int main(int argc, char *argv[])
80 {
81         struct tdb_context *tdb;
82         char *summary;
83
84         failtest_init(argc, argv);
85         failtest_hook = block_repeat_failures;
86         failtest_exit_check = exit_check_log;
87         plan_tests(60);
88
89         failtest_suppress = true;
90         /* Capability says you can ignore it? */
91         create_tdb("run-capabilities.tdb", 1, false, false, false, 0);
92
93         failtest_suppress = false;
94         tdb = tdb_open("run-capabilities.tdb", TDB_DEFAULT, O_RDWR, 0,
95                        &tap_log_attr);
96         failtest_suppress = true;
97         if (!ok1(tdb))
98                 goto out;
99         ok1(tap_log_messages == 0);
100         ok1(tdb_check(tdb, NULL, NULL) == TDB_SUCCESS);
101         ok1(tap_log_messages == 0);
102         tdb_close(tdb);
103
104         /* Two capabilitues say you can ignore them? */
105         create_tdb("run-capabilities.tdb",
106                    1, false, false, false,
107                    2, false, false, false, 0);
108
109         failtest_suppress = false;
110         tdb = tdb_open("run-capabilities.tdb", TDB_DEFAULT, O_RDWR, 0,
111                        &tap_log_attr);
112         failtest_suppress = true;
113         if (!ok1(tdb))
114                 goto out;
115         ok1(tap_log_messages == 0);
116         ok1(tdb_check(tdb, NULL, NULL) == TDB_SUCCESS);
117         ok1(tap_log_messages == 0);
118         ok1(tdb_summary(tdb, 0, &summary) == TDB_SUCCESS);
119         ok1(strstr(summary, "Capability 1\n"));
120         free(summary);
121         tdb_close(tdb);
122
123         /* Capability says you can't check. */
124         create_tdb("run-capabilities.tdb",
125                    1, false, false, false,
126                    2, true, false, false, 0);
127
128         failtest_suppress = false;
129         tdb = tdb_open("run-capabilities.tdb", TDB_DEFAULT, O_RDWR, 0,
130                        &tap_log_attr);
131         failtest_suppress = true;
132         if (!ok1(tdb))
133                 goto out;
134         ok1(tap_log_messages == 0);
135         ok1(tdb_get_flags(tdb) & TDB_CANT_CHECK);
136         ok1(tdb_check(tdb, NULL, NULL) == TDB_SUCCESS);
137         /* We expect a warning! */
138         ok1(tap_log_messages == 1);
139         ok1(strstr(log_last, "capabilit"));
140         ok1(tdb_summary(tdb, 0, &summary) == TDB_SUCCESS);
141         ok1(strstr(summary, "Capability 1\n"));
142         ok1(strstr(summary, "Capability 2 (uncheckable)\n"));
143         free(summary);
144         tdb_close(tdb);
145
146         /* Capability says you can't write. */
147         create_tdb("run-capabilities.tdb",
148                    1, false, false, false,
149                    2, false, true, false, 0);
150
151         failtest_suppress = false;
152         tdb = tdb_open("run-capabilities.tdb", TDB_DEFAULT, O_RDWR, 0,
153                        &tap_log_attr);
154         failtest_suppress = true;
155         /* We expect a message. */
156         ok1(!tdb);
157         if (!ok1(tap_log_messages == 2))
158                 goto out;
159         if (!ok1(strstr(log_last, "unknown")))
160                 goto out;
161         ok1(strstr(log_last, "write"));
162
163         /* We can open it read-only though! */
164         failtest_suppress = false;
165         tdb = tdb_open("run-capabilities.tdb", TDB_DEFAULT, O_RDONLY, 0,
166                        &tap_log_attr);
167         failtest_suppress = true;
168         if (!ok1(tdb))
169                 goto out;
170         ok1(tap_log_messages == 2);
171         ok1(tdb_check(tdb, NULL, NULL) == TDB_SUCCESS);
172         ok1(tap_log_messages == 2);
173         ok1(tdb_summary(tdb, 0, &summary) == TDB_SUCCESS);
174         ok1(strstr(summary, "Capability 1\n"));
175         ok1(strstr(summary, "Capability 2 (read-only)\n"));
176         free(summary);
177         tdb_close(tdb);
178
179         /* Capability says you can't open. */
180         create_tdb("run-capabilities.tdb",
181                    1, false, false, false,
182                    2, false, false, true, 0);
183
184         failtest_suppress = false;
185         tdb = tdb_open("run-capabilities.tdb", TDB_DEFAULT, O_RDWR, 0,
186                        &tap_log_attr);
187         failtest_suppress = true;
188         /* We expect a message. */
189         ok1(!tdb);
190         if (!ok1(tap_log_messages == 3))
191                 goto out;
192         if (!ok1(strstr(log_last, "unknown")))
193                 goto out;
194
195         /* Combine capabilities correctly. */
196         create_tdb("run-capabilities.tdb",
197                    1, false, false, false,
198                    2, true, false, false,
199                    3, false, true, false, 0);
200
201         failtest_suppress = false;
202         tdb = tdb_open("run-capabilities.tdb", TDB_DEFAULT, O_RDWR, 0,
203                        &tap_log_attr);
204         failtest_suppress = true;
205         /* We expect a message. */
206         ok1(!tdb);
207         if (!ok1(tap_log_messages == 4))
208                 goto out;
209         if (!ok1(strstr(log_last, "unknown")))
210                 goto out;
211         ok1(strstr(log_last, "write"));
212
213         /* We can open it read-only though! */
214         failtest_suppress = false;
215         tdb = tdb_open("run-capabilities.tdb", TDB_DEFAULT, O_RDONLY, 0,
216                        &tap_log_attr);
217         failtest_suppress = true;
218         if (!ok1(tdb))
219                 goto out;
220         ok1(tap_log_messages == 4);
221         ok1(tdb_get_flags(tdb) & TDB_CANT_CHECK);
222         ok1(tdb_check(tdb, NULL, NULL) == TDB_SUCCESS);
223         /* We expect a warning! */
224         ok1(tap_log_messages == 5);
225         ok1(strstr(log_last, "unknown"));
226         ok1(tdb_summary(tdb, 0, &summary) == TDB_SUCCESS);
227         ok1(strstr(summary, "Capability 1\n"));
228         ok1(strstr(summary, "Capability 2 (uncheckable)\n"));
229         ok1(strstr(summary, "Capability 3 (read-only)\n"));
230         free(summary);
231         tdb_close(tdb);
232
233         /* Two capability flags in one. */
234         create_tdb("run-capabilities.tdb",
235                    1, false, false, false,
236                    2, true, true, false,
237                    0);
238
239         failtest_suppress = false;
240         tdb = tdb_open("run-capabilities.tdb", TDB_DEFAULT, O_RDWR, 0,
241                        &tap_log_attr);
242         failtest_suppress = true;
243         /* We expect a message. */
244         ok1(!tdb);
245         if (!ok1(tap_log_messages == 6))
246                 goto out;
247         if (!ok1(strstr(log_last, "unknown")))
248                 goto out;
249         ok1(strstr(log_last, "write"));
250
251         /* We can open it read-only though! */
252         failtest_suppress = false;
253         tdb = tdb_open("run-capabilities.tdb", TDB_DEFAULT, O_RDONLY, 0,
254                        &tap_log_attr);
255         failtest_suppress = true;
256         if (!ok1(tdb))
257                 goto out;
258         ok1(tap_log_messages == 6);
259         ok1(tdb_get_flags(tdb) & TDB_CANT_CHECK);
260         ok1(tdb_check(tdb, NULL, NULL) == TDB_SUCCESS);
261         /* We expect a warning! */
262         ok1(tap_log_messages == 7);
263         ok1(strstr(log_last, "unknown"));
264         ok1(tdb_summary(tdb, 0, &summary) == TDB_SUCCESS);
265         ok1(strstr(summary, "Capability 1\n"));
266         ok1(strstr(summary, "Capability 2 (uncheckable,read-only)\n"));
267         free(summary);
268         tdb_close(tdb);
269
270 out:
271         failtest_exit(exit_status());
272 }