]> git.ozlabs.org Git - ccan/blob - ccan/tdb2/test/run-capabilities.c
e302656108c7dc3c47254619bdf0ea0b9de96290
[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
83         failtest_init(argc, argv);
84         failtest_hook = block_repeat_failures;
85         failtest_exit_check = exit_check_log;
86         plan_tests(35);
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         tdb_close(tdb);
118
119         /* Capability says you can't check. */
120         create_tdb("run-capabilities.tdb",
121                    1, false, false, false,
122                    2, true, false, false, 0);
123
124         failtest_suppress = false;
125         tdb = tdb_open("run-capabilities.tdb", TDB_DEFAULT, O_RDWR, 0,
126                        &tap_log_attr);
127         failtest_suppress = true;
128         if (!ok1(tdb))
129                 goto out;
130         ok1(tap_log_messages == 0);
131         ok1(tdb_get_flags(tdb) & TDB_CANT_CHECK);
132         ok1(tdb_check(tdb, NULL, NULL) == TDB_SUCCESS);
133         /* We expect a warning! */
134         ok1(tap_log_messages == 1);
135         ok1(strstr(log_last, "capabilit"));
136         tdb_close(tdb);
137
138         /* Capability says you can't write. */
139         create_tdb("run-capabilities.tdb",
140                    1, false, false, false,
141                    2, false, true, false, 0);
142
143         failtest_suppress = false;
144         tdb = tdb_open("run-capabilities.tdb", TDB_DEFAULT, O_RDWR, 0,
145                        &tap_log_attr);
146         failtest_suppress = true;
147         /* We expect a message. */
148         ok1(!tdb);
149         if (!ok1(tap_log_messages == 2))
150                 goto out;
151         if (!ok1(strstr(log_last, "unknown")))
152                 goto out;
153         ok1(strstr(log_last, "write"));
154
155         /* We can open it read-only though! */
156         failtest_suppress = false;
157         tdb = tdb_open("run-capabilities.tdb", TDB_DEFAULT, O_RDONLY, 0,
158                        &tap_log_attr);
159         failtest_suppress = true;
160         if (!ok1(tdb))
161                 goto out;
162         ok1(tap_log_messages == 2);
163         ok1(tdb_check(tdb, NULL, NULL) == TDB_SUCCESS);
164         ok1(tap_log_messages == 2);
165         tdb_close(tdb);
166
167         /* Capability says you can't open. */
168         create_tdb("run-capabilities.tdb",
169                    1, false, false, false,
170                    2, false, false, true, 0);
171
172         failtest_suppress = false;
173         tdb = tdb_open("run-capabilities.tdb", TDB_DEFAULT, O_RDWR, 0,
174                        &tap_log_attr);
175         failtest_suppress = true;
176         /* We expect a message. */
177         ok1(!tdb);
178         if (!ok1(tap_log_messages == 3))
179                 goto out;
180         if (!ok1(strstr(log_last, "unknown")))
181                 goto out;
182
183         /* Combine capabilities correctly. */
184         create_tdb("run-capabilities.tdb",
185                    1, false, false, false,
186                    2, true, false, false,
187                    3, false, true, false, 0);
188
189         failtest_suppress = false;
190         tdb = tdb_open("run-capabilities.tdb", TDB_DEFAULT, O_RDWR, 0,
191                        &tap_log_attr);
192         failtest_suppress = true;
193         /* We expect a message. */
194         ok1(!tdb);
195         if (!ok1(tap_log_messages == 4))
196                 goto out;
197         if (!ok1(strstr(log_last, "unknown")))
198                 goto out;
199         ok1(strstr(log_last, "write"));
200
201         /* We can open it read-only though! */
202         failtest_suppress = false;
203         tdb = tdb_open("run-capabilities.tdb", TDB_DEFAULT, O_RDONLY, 0,
204                        &tap_log_attr);
205         failtest_suppress = true;
206         if (!ok1(tdb))
207                 goto out;
208         ok1(tap_log_messages == 4);
209         ok1(tdb_get_flags(tdb) & TDB_CANT_CHECK);
210         ok1(tdb_check(tdb, NULL, NULL) == TDB_SUCCESS);
211         /* We expect a warning! */
212         ok1(tap_log_messages == 5);
213         ok1(strstr(log_last, "unknown"));
214         tdb_close(tdb);
215
216 out:
217         failtest_exit(exit_status());
218 }