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