]>
Commit | Line | Data |
---|---|---|
db9ecf05 | 1 | /* SPDX-License-Identifier: LGPL-2.1-or-later */ |
647f6824 | 2 | |
4f18ff2e YW |
3 | #include <unistd.h> |
4 | ||
e4304fb8 | 5 | #include "random-util.h" |
647f6824 | 6 | #include "set.h" |
ef79eae0 | 7 | #include "strv.h" |
4f7452a8 | 8 | #include "tests.h" |
647f6824 | 9 | |
4f7452a8 | 10 | TEST(set_steal_first) { |
647f6824 ZJS |
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 | ||
bdf7026e | 25 | assert_se(seen[0] == 1 && seen[1] == 1 && seen[2] == 1); |
647f6824 ZJS |
26 | |
27 | assert_se(set_isempty(m)); | |
28 | } | |
29 | ||
224b0e7a ZJS |
30 | typedef struct Item { |
31 | int seen; | |
32 | } Item; | |
33 | static void item_seen(Item *item) { | |
34 | item->seen++; | |
35 | } | |
36 | ||
98233ee5 YW |
37 | DEFINE_PRIVATE_HASH_OPS_WITH_VALUE_DESTRUCTOR(item_hash_ops, void, trivial_hash_func, trivial_compare_func, Item, item_seen); |
38 | ||
4f7452a8 | 39 | TEST(set_free_with_hash_ops) { |
98233ee5 YW |
40 | Set *m; |
41 | struct Item items[4] = {}; | |
98233ee5 YW |
42 | |
43 | assert_se(m = set_new(&item_hash_ops)); | |
ddb8a639 I |
44 | FOREACH_ARRAY(item, items, ELEMENTSOF(items) - 1) |
45 | assert_se(set_put(m, item) == 1); | |
98233ee5 YW |
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 | ||
4f7452a8 | 54 | TEST(set_put) { |
756c09e6 RC |
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); | |
ef79eae0 ZJS |
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); | |
756c09e6 RC |
74 | } |
75 | ||
cb649d12 YW |
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 | ||
4f7452a8 | 97 | TEST(set_put_strdup) { |
de747a00 ZJS |
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); | |
cb649d12 YW |
105 | |
106 | assert_se(set_contains(m, "aaa")); | |
107 | assert_se(set_contains(m, "bbb")); | |
108 | ||
de747a00 ZJS |
109 | assert_se(set_size(m) == 2); |
110 | } | |
111 | ||
4f7452a8 | 112 | TEST(set_put_strdupv) { |
de747a00 ZJS |
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); | |
cb649d12 YW |
117 | |
118 | assert_se(set_contains(m, "aaa")); | |
119 | assert_se(set_contains(m, "bbb")); | |
120 | assert_se(set_contains(m, "ccc")); | |
121 | ||
de747a00 ZJS |
122 | assert_se(set_size(m) == 3); |
123 | } | |
124 | ||
4f7452a8 | 125 | TEST(set_ensure_allocated) { |
0f9ccd95 ZJS |
126 | _cleanup_set_free_ Set *m = NULL; |
127 | ||
bc169c4f YW |
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)); | |
0f9ccd95 ZJS |
132 | } |
133 | ||
4f7452a8 | 134 | TEST(set_copy) { |
828513ee YW |
135 | _cleanup_set_free_ Set *s = NULL, *copy = NULL; |
136 | _cleanup_free_ char *key1 = NULL, *key2 = NULL, *key3 = NULL, *key4 = NULL; | |
5ef8b072 | 137 | |
5ef8b072 MG |
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 | ||
f21b863e | 158 | assert_se(set_equal(s, copy)); |
5ef8b072 MG |
159 | } |
160 | ||
4f7452a8 | 161 | TEST(set_ensure_put) { |
0f9ccd95 ZJS |
162 | _cleanup_set_free_ Set *m = NULL; |
163 | ||
bc169c4f YW |
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); | |
0f9ccd95 ZJS |
171 | } |
172 | ||
4f7452a8 | 173 | TEST(set_ensure_consume) { |
fcc1d031 ZJS |
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 | ||
4f7452a8 | 195 | TEST(set_strjoin) { |
4dbce717 YW |
196 | _cleanup_set_free_ Set *m = NULL; |
197 | _cleanup_free_ char *joined = NULL; | |
198 | ||
8d80f275 YW |
199 | /* Empty set */ |
200 | assert_se(set_strjoin(m, NULL, false, &joined) >= 0); | |
4dbce717 | 201 | assert_se(!joined); |
8d80f275 | 202 | assert_se(set_strjoin(m, "", false, &joined) >= 0); |
4dbce717 | 203 | assert_se(!joined); |
8d80f275 | 204 | assert_se(set_strjoin(m, " ", false, &joined) >= 0); |
4dbce717 | 205 | assert_se(!joined); |
8d80f275 YW |
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); | |
4dbce717 YW |
215 | assert_se(!joined); |
216 | ||
8d80f275 | 217 | /* Single entry */ |
4dbce717 | 218 | assert_se(set_put_strdup(&m, "aaa") == 1); |
8d80f275 | 219 | assert_se(set_strjoin(m, NULL, false, &joined) >= 0); |
c79e88b3 | 220 | ASSERT_STREQ(joined, "aaa"); |
4dbce717 | 221 | joined = mfree(joined); |
8d80f275 | 222 | assert_se(set_strjoin(m, "", false, &joined) >= 0); |
c79e88b3 | 223 | ASSERT_STREQ(joined, "aaa"); |
4dbce717 | 224 | joined = mfree(joined); |
8d80f275 | 225 | assert_se(set_strjoin(m, " ", false, &joined) >= 0); |
c79e88b3 | 226 | ASSERT_STREQ(joined, "aaa"); |
8d80f275 YW |
227 | joined = mfree(joined); |
228 | assert_se(set_strjoin(m, "xxx", false, &joined) >= 0); | |
c79e88b3 | 229 | ASSERT_STREQ(joined, "aaa"); |
8d80f275 YW |
230 | joined = mfree(joined); |
231 | assert_se(set_strjoin(m, NULL, true, &joined) >= 0); | |
c79e88b3 | 232 | ASSERT_STREQ(joined, "aaa"); |
4dbce717 | 233 | joined = mfree(joined); |
8d80f275 | 234 | assert_se(set_strjoin(m, "", true, &joined) >= 0); |
c79e88b3 | 235 | ASSERT_STREQ(joined, "aaa"); |
8d80f275 YW |
236 | joined = mfree(joined); |
237 | assert_se(set_strjoin(m, " ", true, &joined) >= 0); | |
c79e88b3 | 238 | ASSERT_STREQ(joined, " aaa "); |
8d80f275 YW |
239 | joined = mfree(joined); |
240 | assert_se(set_strjoin(m, "xxx", true, &joined) >= 0); | |
c79e88b3 | 241 | ASSERT_STREQ(joined, "xxxaaaxxx"); |
4dbce717 | 242 | |
8d80f275 | 243 | /* Two entries */ |
4dbce717 YW |
244 | assert_se(set_put_strdup(&m, "bbb") == 1); |
245 | assert_se(set_put_strdup(&m, "aaa") == 0); | |
4dbce717 | 246 | joined = mfree(joined); |
8d80f275 | 247 | assert_se(set_strjoin(m, NULL, false, &joined) >= 0); |
4dbce717 | 248 | assert_se(STR_IN_SET(joined, "aaabbb", "bbbaaa")); |
4dbce717 | 249 | joined = mfree(joined); |
8d80f275 | 250 | assert_se(set_strjoin(m, "", false, &joined) >= 0); |
4dbce717 | 251 | assert_se(STR_IN_SET(joined, "aaabbb", "bbbaaa")); |
4dbce717 | 252 | joined = mfree(joined); |
8d80f275 | 253 | assert_se(set_strjoin(m, " ", false, &joined) >= 0); |
4dbce717 | 254 | assert_se(STR_IN_SET(joined, "aaa bbb", "bbb aaa")); |
4dbce717 | 255 | joined = mfree(joined); |
8d80f275 | 256 | assert_se(set_strjoin(m, "xxx", false, &joined) >= 0); |
4dbce717 | 257 | assert_se(STR_IN_SET(joined, "aaaxxxbbb", "bbbxxxaaa")); |
8d80f275 YW |
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")); | |
4dbce717 YW |
270 | } |
271 | ||
4f7452a8 | 272 | TEST(set_equal) { |
e4304fb8 LP |
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 | ||
d25d4f18 YW |
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 | ||
24655047 YW |
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 | ||
4f7452a8 | 413 | DEFINE_TEST_MAIN(LOG_INFO); |