]> git.ipfire.org Git - thirdparty/systemd.git/blob - src/test/test-set.c
4c1872d636d3e35465aeca3892acd2d55eb77793
[thirdparty/systemd.git] / src / test / test-set.c
1 /* SPDX-License-Identifier: LGPL-2.1-or-later */
2
3 #include <unistd.h>
4
5 #include "random-util.h"
6 #include "set.h"
7 #include "strv.h"
8 #include "tests.h"
9
10 TEST(set_steal_first) {
11 _cleanup_set_free_ Set *m = NULL;
12 int seen[3] = {};
13 char *val;
14
15 m = set_new(&string_hash_ops);
16 assert_se(m);
17
18 assert_se(set_put(m, (void*) "1") == 1);
19 assert_se(set_put(m, (void*) "22") == 1);
20 assert_se(set_put(m, (void*) "333") == 1);
21
22 while ((val = set_steal_first(m)))
23 seen[strlen(val) - 1]++;
24
25 assert_se(seen[0] == 1 && seen[1] == 1 && seen[2] == 1);
26
27 assert_se(set_isempty(m));
28 }
29
30 typedef struct Item {
31 int seen;
32 } Item;
33 static void item_seen(Item *item) {
34 item->seen++;
35 }
36
37 DEFINE_PRIVATE_HASH_OPS_WITH_VALUE_DESTRUCTOR(item_hash_ops, void, trivial_hash_func, trivial_compare_func, Item, item_seen);
38
39 TEST(set_free_with_hash_ops) {
40 Set *m;
41 struct Item items[4] = {};
42
43 assert_se(m = set_new(&item_hash_ops));
44 FOREACH_ARRAY(item, items, ELEMENTSOF(items) - 1)
45 assert_se(set_put(m, item) == 1);
46
47 m = set_free(m);
48 assert_se(items[0].seen == 1);
49 assert_se(items[1].seen == 1);
50 assert_se(items[2].seen == 1);
51 assert_se(items[3].seen == 0);
52 }
53
54 TEST(set_put) {
55 _cleanup_set_free_ Set *m = NULL;
56
57 m = set_new(&string_hash_ops);
58 assert_se(m);
59
60 assert_se(set_put(m, (void*) "1") == 1);
61 assert_se(set_put(m, (void*) "22") == 1);
62 assert_se(set_put(m, (void*) "333") == 1);
63 assert_se(set_put(m, (void*) "333") == 0);
64 assert_se(set_remove(m, (void*) "333"));
65 assert_se(set_put(m, (void*) "333") == 1);
66 assert_se(set_put(m, (void*) "333") == 0);
67 assert_se(set_put(m, (void*) "22") == 0);
68
69 _cleanup_free_ char **t = set_get_strv(m);
70 assert_se(strv_contains(t, "1"));
71 assert_se(strv_contains(t, "22"));
72 assert_se(strv_contains(t, "333"));
73 assert_se(strv_length(t) == 3);
74 }
75
76 TEST(set_put_strndup) {
77 _cleanup_set_free_ Set *m = NULL;
78
79 assert_se(set_put_strndup(&m, "12345", 0) == 1);
80 assert_se(set_put_strndup(&m, "12345", 1) == 1);
81 assert_se(set_put_strndup(&m, "12345", 2) == 1);
82 assert_se(set_put_strndup(&m, "12345", 3) == 1);
83 assert_se(set_put_strndup(&m, "12345", 4) == 1);
84 assert_se(set_put_strndup(&m, "12345", 5) == 1);
85 assert_se(set_put_strndup(&m, "12345", 6) == 0);
86
87 assert_se(set_contains(m, ""));
88 assert_se(set_contains(m, "1"));
89 assert_se(set_contains(m, "12"));
90 assert_se(set_contains(m, "123"));
91 assert_se(set_contains(m, "1234"));
92 assert_se(set_contains(m, "12345"));
93
94 assert_se(set_size(m) == 6);
95 }
96
97 TEST(set_put_strdup) {
98 _cleanup_set_free_ Set *m = NULL;
99
100 assert_se(set_put_strdup(&m, "aaa") == 1);
101 assert_se(set_put_strdup(&m, "aaa") == 0);
102 assert_se(set_put_strdup(&m, "bbb") == 1);
103 assert_se(set_put_strdup(&m, "bbb") == 0);
104 assert_se(set_put_strdup(&m, "aaa") == 0);
105
106 assert_se(set_contains(m, "aaa"));
107 assert_se(set_contains(m, "bbb"));
108
109 assert_se(set_size(m) == 2);
110 }
111
112 TEST(set_put_strdupv) {
113 _cleanup_set_free_ Set *m = NULL;
114
115 assert_se(set_put_strdupv(&m, STRV_MAKE("aaa", "aaa", "bbb", "bbb", "aaa")) == 2);
116 assert_se(set_put_strdupv(&m, STRV_MAKE("aaa", "aaa", "bbb", "bbb", "ccc")) == 1);
117
118 assert_se(set_contains(m, "aaa"));
119 assert_se(set_contains(m, "bbb"));
120 assert_se(set_contains(m, "ccc"));
121
122 assert_se(set_size(m) == 3);
123 }
124
125 TEST(set_ensure_allocated) {
126 _cleanup_set_free_ Set *m = NULL;
127
128 ASSERT_OK_POSITIVE(set_ensure_allocated(&m, &string_hash_ops));
129 ASSERT_OK_ZERO(set_ensure_allocated(&m, &string_hash_ops));
130 ASSERT_SIGNAL(set_ensure_allocated(&m, NULL), SIGABRT);
131 ASSERT_TRUE(set_isempty(m));
132 }
133
134 TEST(set_copy) {
135 _cleanup_set_free_ Set *s = NULL, *copy = NULL;
136 _cleanup_free_ char *key1 = NULL, *key2 = NULL, *key3 = NULL, *key4 = NULL;
137
138 key1 = strdup("key1");
139 assert_se(key1);
140 key2 = strdup("key2");
141 assert_se(key2);
142 key3 = strdup("key3");
143 assert_se(key3);
144 key4 = strdup("key4");
145 assert_se(key4);
146
147 s = set_new(&string_hash_ops);
148 assert_se(s);
149
150 assert_se(set_put(s, key1) >= 0);
151 assert_se(set_put(s, key2) >= 0);
152 assert_se(set_put(s, key3) >= 0);
153 assert_se(set_put(s, key4) >= 0);
154
155 copy = set_copy(s);
156 assert_se(copy);
157
158 assert_se(set_equal(s, copy));
159 }
160
161 TEST(set_ensure_put) {
162 _cleanup_set_free_ Set *m = NULL;
163
164 ASSERT_OK_POSITIVE(set_ensure_put(&m, &string_hash_ops, "a"));
165 ASSERT_OK_ZERO(set_ensure_put(&m, &string_hash_ops, "a"));
166 ASSERT_SIGNAL(set_ensure_put(&m, NULL, "a"), SIGABRT);
167 ASSERT_OK_POSITIVE(set_ensure_put(&m, &string_hash_ops, "b"));
168 ASSERT_OK_ZERO(set_ensure_put(&m, &string_hash_ops, "b"));
169 ASSERT_OK_ZERO(set_ensure_put(&m, &string_hash_ops, "a"));
170 ASSERT_EQ(set_size(m), 2u);
171 }
172
173 TEST(set_ensure_consume) {
174 _cleanup_set_free_ Set *m = NULL;
175 char *s, *t;
176
177 assert_se(s = strdup("a"));
178 assert_se(set_ensure_consume(&m, &string_hash_ops_free, s) == 1);
179
180 assert_se(t = strdup("a"));
181 assert_se(set_ensure_consume(&m, &string_hash_ops_free, t) == 0);
182
183 assert_se(t = strdup("a"));
184 assert_se(set_ensure_consume(&m, &string_hash_ops_free, t) == 0);
185
186 assert_se(t = strdup("b"));
187 assert_se(set_ensure_consume(&m, &string_hash_ops_free, t) == 1);
188
189 assert_se(t = strdup("b"));
190 assert_se(set_ensure_consume(&m, &string_hash_ops_free, t) == 0);
191
192 assert_se(set_size(m) == 2);
193 }
194
195 TEST(set_strjoin) {
196 _cleanup_set_free_ Set *m = NULL;
197 _cleanup_free_ char *joined = NULL;
198
199 /* Empty set */
200 assert_se(set_strjoin(m, NULL, false, &joined) >= 0);
201 assert_se(!joined);
202 assert_se(set_strjoin(m, "", false, &joined) >= 0);
203 assert_se(!joined);
204 assert_se(set_strjoin(m, " ", false, &joined) >= 0);
205 assert_se(!joined);
206 assert_se(set_strjoin(m, "xxx", false, &joined) >= 0);
207 assert_se(!joined);
208 assert_se(set_strjoin(m, NULL, true, &joined) >= 0);
209 assert_se(!joined);
210 assert_se(set_strjoin(m, "", true, &joined) >= 0);
211 assert_se(!joined);
212 assert_se(set_strjoin(m, " ", true, &joined) >= 0);
213 assert_se(!joined);
214 assert_se(set_strjoin(m, "xxx", true, &joined) >= 0);
215 assert_se(!joined);
216
217 /* Single entry */
218 assert_se(set_put_strdup(&m, "aaa") == 1);
219 assert_se(set_strjoin(m, NULL, false, &joined) >= 0);
220 ASSERT_STREQ(joined, "aaa");
221 joined = mfree(joined);
222 assert_se(set_strjoin(m, "", false, &joined) >= 0);
223 ASSERT_STREQ(joined, "aaa");
224 joined = mfree(joined);
225 assert_se(set_strjoin(m, " ", false, &joined) >= 0);
226 ASSERT_STREQ(joined, "aaa");
227 joined = mfree(joined);
228 assert_se(set_strjoin(m, "xxx", false, &joined) >= 0);
229 ASSERT_STREQ(joined, "aaa");
230 joined = mfree(joined);
231 assert_se(set_strjoin(m, NULL, true, &joined) >= 0);
232 ASSERT_STREQ(joined, "aaa");
233 joined = mfree(joined);
234 assert_se(set_strjoin(m, "", true, &joined) >= 0);
235 ASSERT_STREQ(joined, "aaa");
236 joined = mfree(joined);
237 assert_se(set_strjoin(m, " ", true, &joined) >= 0);
238 ASSERT_STREQ(joined, " aaa ");
239 joined = mfree(joined);
240 assert_se(set_strjoin(m, "xxx", true, &joined) >= 0);
241 ASSERT_STREQ(joined, "xxxaaaxxx");
242
243 /* Two entries */
244 assert_se(set_put_strdup(&m, "bbb") == 1);
245 assert_se(set_put_strdup(&m, "aaa") == 0);
246 joined = mfree(joined);
247 assert_se(set_strjoin(m, NULL, false, &joined) >= 0);
248 assert_se(STR_IN_SET(joined, "aaabbb", "bbbaaa"));
249 joined = mfree(joined);
250 assert_se(set_strjoin(m, "", false, &joined) >= 0);
251 assert_se(STR_IN_SET(joined, "aaabbb", "bbbaaa"));
252 joined = mfree(joined);
253 assert_se(set_strjoin(m, " ", false, &joined) >= 0);
254 assert_se(STR_IN_SET(joined, "aaa bbb", "bbb aaa"));
255 joined = mfree(joined);
256 assert_se(set_strjoin(m, "xxx", false, &joined) >= 0);
257 assert_se(STR_IN_SET(joined, "aaaxxxbbb", "bbbxxxaaa"));
258 joined = mfree(joined);
259 assert_se(set_strjoin(m, NULL, true, &joined) >= 0);
260 assert_se(STR_IN_SET(joined, "aaabbb", "bbbaaa"));
261 joined = mfree(joined);
262 assert_se(set_strjoin(m, "", true, &joined) >= 0);
263 assert_se(STR_IN_SET(joined, "aaabbb", "bbbaaa"));
264 joined = mfree(joined);
265 assert_se(set_strjoin(m, " ", true, &joined) >= 0);
266 assert_se(STR_IN_SET(joined, " aaa bbb ", " bbb aaa "));
267 joined = mfree(joined);
268 assert_se(set_strjoin(m, "xxx", true, &joined) >= 0);
269 assert_se(STR_IN_SET(joined, "xxxaaaxxxbbbxxx", "xxxbbbxxxaaaxxx"));
270 }
271
272 TEST(set_equal) {
273 _cleanup_set_free_ Set *a = NULL, *b = NULL;
274 void *p;
275 int r;
276
277 assert_se(a = set_new(NULL));
278 assert_se(b = set_new(NULL));
279
280 assert_se(set_equal(a, a));
281 assert_se(set_equal(b, b));
282 assert_se(set_equal(a, b));
283 assert_se(set_equal(b, a));
284 assert_se(set_equal(NULL, a));
285 assert_se(set_equal(NULL, b));
286 assert_se(set_equal(a, NULL));
287 assert_se(set_equal(b, NULL));
288 assert_se(set_equal(NULL, NULL));
289
290 for (unsigned i = 0; i < 333; i++) {
291 p = INT32_TO_PTR(1 + (random_u32() & 0xFFFU));
292
293 r = set_put(a, p);
294 assert_se(r >= 0 || r == -EEXIST);
295 }
296
297 assert_se(set_put(a, INT32_TO_PTR(0x1000U)) >= 0);
298
299 assert_se(set_size(a) >= 2);
300 assert_se(set_size(a) <= 334);
301
302 assert_se(!set_equal(a, b));
303 assert_se(!set_equal(b, a));
304 assert_se(!set_equal(a, NULL));
305
306 SET_FOREACH(p, a)
307 assert_se(set_put(b, p) >= 0);
308
309 assert_se(set_equal(a, b));
310 assert_se(set_equal(b, a));
311
312 assert_se(set_remove(a, INT32_TO_PTR(0x1000U)) == INT32_TO_PTR(0x1000U));
313
314 assert_se(!set_equal(a, b));
315 assert_se(!set_equal(b, a));
316
317 assert_se(set_remove(b, INT32_TO_PTR(0x1000U)) == INT32_TO_PTR(0x1000U));
318
319 assert_se(set_equal(a, b));
320 assert_se(set_equal(b, a));
321
322 assert_se(set_put(b, INT32_TO_PTR(0x1001U)) >= 0);
323
324 assert_se(!set_equal(a, b));
325 assert_se(!set_equal(b, a));
326
327 assert_se(set_put(a, INT32_TO_PTR(0x1001U)) >= 0);
328
329 assert_se(set_equal(a, b));
330 assert_se(set_equal(b, a));
331
332 set_clear(a);
333
334 assert_se(!set_equal(a, b));
335 assert_se(!set_equal(b, a));
336
337 set_clear(b);
338
339 assert_se(set_equal(a, b));
340 assert_se(set_equal(b, a));
341 }
342
343 TEST(set_fnmatch) {
344 _cleanup_set_free_ Set *match = NULL, *nomatch = NULL;
345
346 assert_se(set_put_strdup(&match, "aaa") >= 0);
347 assert_se(set_put_strdup(&match, "bbb*") >= 0);
348 assert_se(set_put_strdup(&match, "*ccc") >= 0);
349
350 assert_se(set_put_strdup(&nomatch, "a*") >= 0);
351 assert_se(set_put_strdup(&nomatch, "bbb") >= 0);
352 assert_se(set_put_strdup(&nomatch, "ccc*") >= 0);
353
354 assert_se(set_fnmatch(NULL, NULL, ""));
355 assert_se(set_fnmatch(NULL, NULL, "hoge"));
356
357 assert_se(set_fnmatch(match, NULL, "aaa"));
358 assert_se(set_fnmatch(match, NULL, "bbb"));
359 assert_se(set_fnmatch(match, NULL, "bbbXXX"));
360 assert_se(set_fnmatch(match, NULL, "ccc"));
361 assert_se(set_fnmatch(match, NULL, "XXXccc"));
362 assert_se(!set_fnmatch(match, NULL, ""));
363 assert_se(!set_fnmatch(match, NULL, "aaaa"));
364 assert_se(!set_fnmatch(match, NULL, "XXbbb"));
365 assert_se(!set_fnmatch(match, NULL, "cccXX"));
366
367 assert_se(set_fnmatch(NULL, nomatch, ""));
368 assert_se(set_fnmatch(NULL, nomatch, "Xa"));
369 assert_se(set_fnmatch(NULL, nomatch, "bbbb"));
370 assert_se(set_fnmatch(NULL, nomatch, "XXXccc"));
371 assert_se(!set_fnmatch(NULL, nomatch, "a"));
372 assert_se(!set_fnmatch(NULL, nomatch, "aXXXX"));
373 assert_se(!set_fnmatch(NULL, nomatch, "bbb"));
374 assert_se(!set_fnmatch(NULL, nomatch, "ccc"));
375 assert_se(!set_fnmatch(NULL, nomatch, "cccXXX"));
376
377 assert_se(set_fnmatch(match, nomatch, "bbbbb"));
378 assert_se(set_fnmatch(match, nomatch, "XXccc"));
379 assert_se(!set_fnmatch(match, nomatch, ""));
380 assert_se(!set_fnmatch(match, nomatch, "a"));
381 assert_se(!set_fnmatch(match, nomatch, "aaa"));
382 assert_se(!set_fnmatch(match, nomatch, "b"));
383 assert_se(!set_fnmatch(match, nomatch, "bbb"));
384 assert_se(!set_fnmatch(match, nomatch, "ccc"));
385 assert_se(!set_fnmatch(match, nomatch, "ccccc"));
386 assert_se(!set_fnmatch(match, nomatch, "cccXX"));
387 }
388
389 TEST(set_to_strv) {
390 _cleanup_set_free_ Set *set = NULL;
391 _cleanup_strv_free_ char **a = NULL;
392 _cleanup_free_ char **b = NULL;
393 char **v = STRV_MAKE("aaa", "bbb", "ccc");
394
395 ASSERT_NOT_NULL(a = set_to_strv(&set));
396 ASSERT_TRUE(strv_isempty(a));
397 ASSERT_NULL(set);
398 a = strv_free(a);
399
400 ASSERT_OK(set_put_strdupv(&set, v));
401 ASSERT_EQ(set_size(set), strv_length(v));
402
403 ASSERT_NOT_NULL(b = set_get_strv(set));
404 ASSERT_EQ(strv_length(b), strv_length(v));
405 ASSERT_TRUE(strv_equal_ignore_order(b, v));
406
407 ASSERT_NOT_NULL(a = set_to_strv(&set));
408 ASSERT_EQ(strv_length(a), strv_length(v));
409 ASSERT_TRUE(strv_equal_ignore_order(a, v));
410 ASSERT_NULL(set);
411 }
412
413 DEFINE_TEST_MAIN(LOG_INFO);