]> git.ipfire.org Git - thirdparty/systemd.git/blob - src/test/test-strv.c
test: only use assert_se
[thirdparty/systemd.git] / src / test / test-strv.c
1 /*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
2
3 /***
4 This file is part of systemd.
5
6 Copyright 2010 Lennart Poettering
7 Copyright 2013 Thomas H.P. Andersen
8
9 systemd is free software; you can redistribute it and/or modify it
10 under the terms of the GNU Lesser General Public License as published by
11 the Free Software Foundation; either version 2.1 of the License, or
12 (at your option) any later version.
13
14 systemd is distributed in the hope that it will be useful, but
15 WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 Lesser General Public License for more details.
18
19 You should have received a copy of the GNU Lesser General Public License
20 along with systemd; If not, see <http://www.gnu.org/licenses/>.
21 ***/
22
23 #include <string.h>
24
25 #include "util.h"
26 #include "specifier.h"
27 #include "strv.h"
28
29 static void test_specifier_printf(void) {
30 static const Specifier table[] = {
31 { 'a', specifier_string, (char*) "AAAA" },
32 { 'b', specifier_string, (char*) "BBBB" },
33 { 'm', specifier_machine_id, NULL },
34 { 'B', specifier_boot_id, NULL },
35 { 'H', specifier_host_name, NULL },
36 { 'v', specifier_kernel_release, NULL },
37 {}
38 };
39
40 _cleanup_free_ char *w = NULL;
41 int r;
42
43 r = specifier_printf("xxx a=%a b=%b yyy", table, NULL, &w);
44 assert_se(r >= 0);
45 assert_se(w);
46
47 puts(w);
48 assert_se(streq(w, "xxx a=AAAA b=BBBB yyy"));
49
50 free(w);
51 r = specifier_printf("machine=%m, boot=%B, host=%H, version=%v", table, NULL, &w);
52 assert_se(r >= 0);
53 assert_se(w);
54 puts(w);
55 }
56
57 static const char* const input_table_multiple[] = {
58 "one",
59 "two",
60 "three",
61 NULL,
62 };
63
64 static const char* const input_table_one[] = {
65 "one",
66 NULL,
67 };
68
69 static const char* const input_table_none[] = {
70 NULL,
71 };
72
73 static const char* const input_table_quotes[] = {
74 "\"",
75 "'",
76 "\"\"",
77 "\\",
78 "\\\\",
79 NULL,
80 };
81 #define QUOTES_STRING \
82 "\"\\\"\" " \
83 "\"\\\'\" " \
84 "\"\\\"\\\"\" " \
85 "\"\\\\\" " \
86 "\"\\\\\\\\\""
87
88 static const char * const input_table_spaces[] = {
89 " ",
90 "' '",
91 "\" ",
92 " \"",
93 " \\\\ ",
94 NULL,
95 };
96 #define SPACES_STRING \
97 "\" \" " \
98 "\"\\' \\'\" " \
99 "\"\\\" \" " \
100 "\" \\\"\" " \
101 "\" \\\\\\\\ \""
102
103 static void test_strv_find(void) {
104 assert_se(strv_find((char **)input_table_multiple, "three"));
105 assert_se(!strv_find((char **)input_table_multiple, "four"));
106 }
107
108 static void test_strv_find_prefix(void) {
109 assert_se(strv_find_prefix((char **)input_table_multiple, "o"));
110 assert_se(strv_find_prefix((char **)input_table_multiple, "one"));
111 assert_se(strv_find_prefix((char **)input_table_multiple, ""));
112 assert_se(!strv_find_prefix((char **)input_table_multiple, "xxx"));
113 assert_se(!strv_find_prefix((char **)input_table_multiple, "onee"));
114 }
115
116 static void test_strv_join(void) {
117 _cleanup_free_ char *p = NULL, *q = NULL, *r = NULL, *s = NULL, *t = NULL;
118
119 p = strv_join((char **)input_table_multiple, ", ");
120 assert_se(p);
121 assert_se(streq(p, "one, two, three"));
122
123 q = strv_join((char **)input_table_multiple, ";");
124 assert_se(q);
125 assert_se(streq(q, "one;two;three"));
126
127 r = strv_join((char **)input_table_multiple, NULL);
128 assert_se(r);
129 assert_se(streq(r, "one two three"));
130
131 s = strv_join((char **)input_table_one, ", ");
132 assert_se(s);
133 assert_se(streq(s, "one"));
134
135 t = strv_join((char **)input_table_none, ", ");
136 assert_se(t);
137 assert_se(streq(t, ""));
138 }
139
140 static void test_strv_quote_unquote(const char* const *split, const char *quoted) {
141 _cleanup_free_ char *p;
142 _cleanup_strv_free_ char **s;
143 char **t;
144 int r;
145
146 p = strv_join_quoted((char **)split);
147 assert_se(p);
148 printf("-%s- --- -%s-\n", p, quoted); /* fprintf deals with NULL, puts does not */
149 assert_se(p);
150 assert_se(streq(p, quoted));
151
152 r = strv_split_quoted(&s, quoted);
153 assert_se(r == 0);
154 assert_se(s);
155 STRV_FOREACH(t, s) {
156 assert_se(*t);
157 assert_se(streq(*t, *split));
158 split++;
159 }
160 }
161
162 static void test_strv_unquote(const char *quoted, const char **list) {
163 _cleanup_strv_free_ char **s;
164 _cleanup_free_ char *j;
165 unsigned i = 0;
166 char **t;
167 int r;
168
169 r = strv_split_quoted(&s, quoted);
170 assert_se(r == 0);
171 assert_se(s);
172 j = strv_join(s, " | ");
173 assert_se(j);
174 puts(j);
175
176 STRV_FOREACH(t, s)
177 assert_se(streq(list[i++], *t));
178
179 assert_se(list[i] == NULL);
180 }
181
182 static void test_invalid_unquote(const char *quoted) {
183 char **s = NULL;
184 int r;
185
186 r = strv_split_quoted(&s, quoted);
187 assert_se(s == NULL);
188 assert_se(r == -EINVAL);
189 }
190
191 static void test_strv_split(void) {
192 char **s;
193 unsigned i = 0;
194 _cleanup_strv_free_ char **l = NULL;
195 const char str[] = "one,two,three";
196
197 l = strv_split(str, ",");
198
199 assert_se(l);
200
201 STRV_FOREACH(s, l) {
202 assert_se(streq(*s, input_table_multiple[i++]));
203 }
204 }
205
206 static void test_strv_split_newlines(void) {
207 unsigned i = 0;
208 char **s;
209 _cleanup_strv_free_ char **l = NULL;
210 const char str[] = "one\ntwo\nthree";
211
212 l = strv_split_newlines(str);
213
214 assert_se(l);
215
216 STRV_FOREACH(s, l) {
217 assert_se(streq(*s, input_table_multiple[i++]));
218 }
219 }
220
221 static void test_strv_split_nulstr(void) {
222 _cleanup_strv_free_ char **l = NULL;
223 const char nulstr[] = "str0\0str1\0str2\0str3\0";
224
225 l = strv_split_nulstr (nulstr);
226 assert_se(l);
227
228 assert_se(streq(l[0], "str0"));
229 assert_se(streq(l[1], "str1"));
230 assert_se(streq(l[2], "str2"));
231 assert_se(streq(l[3], "str3"));
232 }
233
234 static void test_strv_parse_nulstr(void) {
235 _cleanup_strv_free_ char **l = NULL;
236 const char nulstr[] = "fuck\0fuck2\0fuck3\0\0fuck5\0\0xxx";
237
238 l = strv_parse_nulstr(nulstr, sizeof(nulstr)-1);
239 assert_se(l);
240 puts("Parse nulstr:");
241 strv_print(l);
242
243 assert_se(streq(l[0], "fuck"));
244 assert_se(streq(l[1], "fuck2"));
245 assert_se(streq(l[2], "fuck3"));
246 assert_se(streq(l[3], ""));
247 assert_se(streq(l[4], "fuck5"));
248 assert_se(streq(l[5], ""));
249 assert_se(streq(l[6], "xxx"));
250 }
251
252 static void test_strv_overlap(void) {
253 const char * const input_table[] = {
254 "one",
255 "two",
256 "three",
257 NULL
258 };
259 const char * const input_table_overlap[] = {
260 "two",
261 NULL
262 };
263 const char * const input_table_unique[] = {
264 "four",
265 "five",
266 "six",
267 NULL
268 };
269
270 assert_se(strv_overlap((char **)input_table, (char**)input_table_overlap));
271 assert_se(!strv_overlap((char **)input_table, (char**)input_table_unique));
272 }
273
274 static void test_strv_sort(void) {
275 const char* input_table[] = {
276 "durian",
277 "apple",
278 "citrus",
279 "CAPITAL LETTERS FIRST",
280 "banana",
281 NULL
282 };
283
284 strv_sort((char **)input_table);
285
286 assert_se(streq(input_table[0], "CAPITAL LETTERS FIRST"));
287 assert_se(streq(input_table[1], "apple"));
288 assert_se(streq(input_table[2], "banana"));
289 assert_se(streq(input_table[3], "citrus"));
290 assert_se(streq(input_table[4], "durian"));
291 }
292
293 static void test_strv_extend_strv_concat(void) {
294 _cleanup_strv_free_ char **a = NULL, **b = NULL;
295
296 a = strv_new("without", "suffix", NULL);
297 b = strv_new("with", "suffix", NULL);
298 assert_se(a);
299 assert_se(b);
300
301 assert_se(strv_extend_strv_concat(&a, b, "_suffix") >= 0);
302
303 assert_se(streq(a[0], "without"));
304 assert_se(streq(a[1], "suffix"));
305 assert_se(streq(a[2], "with_suffix"));
306 assert_se(streq(a[3], "suffix_suffix"));
307 }
308
309 static void test_strv_extend_strv(void) {
310 _cleanup_strv_free_ char **a = NULL, **b = NULL;
311
312 a = strv_new("abc", "def", "ghi", NULL);
313 b = strv_new("jkl", "mno", "pqr", NULL);
314 assert_se(a);
315 assert_se(b);
316
317 assert_se(strv_extend_strv(&a, b) >= 0);
318
319 assert_se(streq(a[0], "abc"));
320 assert_se(streq(a[1], "def"));
321 assert_se(streq(a[2], "ghi"));
322 assert_se(streq(a[3], "jkl"));
323 assert_se(streq(a[4], "mno"));
324 assert_se(streq(a[5], "pqr"));
325
326 assert_se(strv_length(a) == 6);
327 }
328
329 static void test_strv_extend(void) {
330 _cleanup_strv_free_ char **a = NULL, **b = NULL;
331
332 a = strv_new("test", "test1", NULL);
333 assert_se(a);
334 assert_se(strv_extend(&a, "test2") >= 0);
335 assert_se(strv_extend(&b, "test3") >= 0);
336
337 assert_se(streq(a[0], "test"));
338 assert_se(streq(a[1], "test1"));
339 assert_se(streq(a[2], "test2"));
340 assert_se(streq(b[0], "test3"));
341 }
342
343 static void test_strv_extendf(void) {
344 _cleanup_strv_free_ char **a = NULL, **b = NULL;
345
346 a = strv_new("test", "test1", NULL);
347 assert_se(a);
348 assert_se(strv_extendf(&a, "test2 %s %d %s", "foo", 128, "bar") >= 0);
349 assert_se(strv_extendf(&b, "test3 %s %s %d", "bar", "foo", 128) >= 0);
350
351 assert_se(streq(a[0], "test"));
352 assert_se(streq(a[1], "test1"));
353 assert_se(streq(a[2], "test2 foo 128 bar"));
354 assert_se(streq(b[0], "test3 bar foo 128"));
355 }
356
357 static void test_strv_foreach(void) {
358 _cleanup_strv_free_ char **a;
359 unsigned i = 0;
360 char **check;
361
362 a = strv_new("one", "two", "three", NULL);
363
364 assert_se(a);
365
366 STRV_FOREACH(check, a) {
367 assert_se(streq(*check, input_table_multiple[i++]));
368 }
369 }
370
371 static void test_strv_foreach_backwards(void) {
372 _cleanup_strv_free_ char **a;
373 unsigned i = 2;
374 char **check;
375
376 a = strv_new("one", "two", "three", NULL);
377
378 assert_se(a);
379
380 STRV_FOREACH_BACKWARDS(check, a) {
381 assert_se(streq_ptr(*check, input_table_multiple[i--]));
382 }
383 }
384
385 static void test_strv_foreach_pair(void) {
386 _cleanup_strv_free_ char **a = NULL;
387 char **x, **y;
388
389 a = strv_new("pair_one", "pair_one",
390 "pair_two", "pair_two",
391 "pair_three", "pair_three",
392 NULL);
393
394 STRV_FOREACH_PAIR(x, y, a) {
395 assert_se(streq(*x, *y));
396 }
397 }
398
399 static void test_strv_from_stdarg_alloca_one(char **l, const char *first, ...) {
400 char **j;
401 unsigned i;
402
403 j = strv_from_stdarg_alloca(first);
404
405 for (i = 0;; i++) {
406 assert_se(streq_ptr(l[i], j[i]));
407
408 if (!l[i])
409 break;
410 }
411 }
412
413 static void test_strv_from_stdarg_alloca(void) {
414 test_strv_from_stdarg_alloca_one(STRV_MAKE("foo", "bar"), "foo", "bar", NULL);
415 test_strv_from_stdarg_alloca_one(STRV_MAKE("foo"), "foo", NULL);
416 test_strv_from_stdarg_alloca_one(STRV_MAKE_EMPTY, NULL);
417 }
418
419 int main(int argc, char *argv[]) {
420 test_specifier_printf();
421 test_strv_foreach();
422 test_strv_foreach_backwards();
423 test_strv_foreach_pair();
424 test_strv_find();
425 test_strv_find_prefix();
426 test_strv_join();
427
428 test_strv_quote_unquote(input_table_multiple, "\"one\" \"two\" \"three\"");
429 test_strv_quote_unquote(input_table_one, "\"one\"");
430 test_strv_quote_unquote(input_table_none, "");
431 test_strv_quote_unquote(input_table_quotes, QUOTES_STRING);
432 test_strv_quote_unquote(input_table_spaces, SPACES_STRING);
433
434 test_strv_unquote(" foo=bar \"waldo\" zzz ", (const char*[]) { "foo=bar", "waldo", "zzz", NULL });
435 test_strv_unquote("", (const char*[]) { NULL });
436 test_strv_unquote(" ", (const char*[]) { NULL });
437 test_strv_unquote(" ", (const char*[]) { NULL });
438 test_strv_unquote(" x", (const char*[]) { "x", NULL });
439 test_strv_unquote("x ", (const char*[]) { "x", NULL });
440 test_strv_unquote(" x ", (const char*[]) { "x", NULL });
441 test_strv_unquote(" \"x\" ", (const char*[]) { "x", NULL });
442 test_strv_unquote(" 'x' ", (const char*[]) { "x", NULL });
443 test_strv_unquote(" 'x\"' ", (const char*[]) { "x\"", NULL });
444 test_strv_unquote(" \"x'\" ", (const char*[]) { "x'", NULL });
445 test_strv_unquote("a '--b=c \"d e\"'", (const char*[]) { "a", "--b=c \"d e\"", NULL });
446
447 test_invalid_unquote("a --b='c \"d e\"'");
448 test_invalid_unquote("a --b='c \"d e\" '");
449 test_invalid_unquote("a --b='c \"d e\"garbage");
450 test_invalid_unquote("'");
451 test_invalid_unquote("\"");
452 test_invalid_unquote("'x'y");
453
454 test_strv_split();
455 test_strv_split_newlines();
456 test_strv_split_nulstr();
457 test_strv_parse_nulstr();
458 test_strv_overlap();
459 test_strv_sort();
460 test_strv_extend_strv();
461 test_strv_extend_strv_concat();
462 test_strv_extend();
463 test_strv_extendf();
464 test_strv_from_stdarg_alloca();
465
466 return 0;
467 }