chiark / gitweb /
test: fix "make check"
[elogind.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
145         p = strv_join_quoted((char **)split);
146         assert_se(p);
147         printf("-%s- --- -%s-\n", p, quoted); /* fprintf deals with NULL, puts does not */
148         assert_se(p);
149         assert_se(streq(p, quoted));
150
151         s = strv_split_quoted(quoted);
152         assert_se(s);
153         STRV_FOREACH(t, s) {
154                 assert_se(*t);
155                 assert_se(streq(*t, *split));
156                 split++;
157         }
158 }
159
160 static void test_strv_quote_unquote2(const char *quoted, const char ** list) {
161         _cleanup_strv_free_ char **s;
162         unsigned i = 0;
163         char **t;
164
165         s = strv_split_quoted(quoted);
166         assert_se(s);
167
168         STRV_FOREACH(t, s)
169                 assert_se(streq(list[i++], *t));
170
171         assert_se(list[i] == NULL);
172 }
173
174 static void test_strv_split(void) {
175         char **s;
176         unsigned i = 0;
177         _cleanup_strv_free_ char **l = NULL;
178         const char str[] = "one,two,three";
179
180         l = strv_split(str, ",");
181
182         assert(l);
183
184         STRV_FOREACH(s, l) {
185                 assert_se(streq(*s, input_table_multiple[i++]));
186         }
187 }
188
189 static void test_strv_split_newlines(void) {
190         unsigned i = 0;
191         char **s;
192         _cleanup_strv_free_ char **l = NULL;
193         const char str[] = "one\ntwo\nthree";
194
195         l = strv_split_newlines(str);
196
197         assert(l);
198
199         STRV_FOREACH(s, l) {
200                 assert_se(streq(*s, input_table_multiple[i++]));
201         }
202 }
203
204 static void test_strv_split_nulstr(void) {
205         _cleanup_strv_free_ char **l = NULL;
206         const char nulstr[] = "str0\0str1\0str2\0str3\0";
207
208         l = strv_split_nulstr (nulstr);
209         assert_se(l);
210
211         assert_se(streq(l[0], "str0"));
212         assert_se(streq(l[1], "str1"));
213         assert_se(streq(l[2], "str2"));
214         assert_se(streq(l[3], "str3"));
215 }
216
217 static void test_strv_parse_nulstr(void) {
218         _cleanup_strv_free_ char **l = NULL;
219         const char nulstr[] = "fuck\0fuck2\0fuck3\0\0fuck5\0\0xxx";
220
221         l = strv_parse_nulstr(nulstr, sizeof(nulstr)-1);
222         assert_se(l);
223         puts("Parse nulstr:");
224         strv_print(l);
225
226         assert_se(streq(l[0], "fuck"));
227         assert_se(streq(l[1], "fuck2"));
228         assert_se(streq(l[2], "fuck3"));
229         assert_se(streq(l[3], ""));
230         assert_se(streq(l[4], "fuck5"));
231         assert_se(streq(l[5], ""));
232         assert_se(streq(l[6], "xxx"));
233 }
234
235 static void test_strv_overlap(void) {
236         const char * const input_table[] = {
237                 "one",
238                 "two",
239                 "three",
240                 NULL
241         };
242         const char * const input_table_overlap[] = {
243                 "two",
244                 NULL
245         };
246         const char * const input_table_unique[] = {
247                 "four",
248                 "five",
249                 "six",
250                 NULL
251         };
252
253         assert_se(strv_overlap((char **)input_table, (char**)input_table_overlap));
254         assert_se(!strv_overlap((char **)input_table, (char**)input_table_unique));
255 }
256
257 static void test_strv_sort(void) {
258         const char* input_table[] = {
259                 "durian",
260                 "apple",
261                 "citrus",
262                  "CAPITAL LETTERS FIRST",
263                 "banana",
264                 NULL
265         };
266
267         strv_sort((char **)input_table);
268
269         assert_se(streq(input_table[0], "CAPITAL LETTERS FIRST"));
270         assert_se(streq(input_table[1], "apple"));
271         assert_se(streq(input_table[2], "banana"));
272         assert_se(streq(input_table[3], "citrus"));
273         assert_se(streq(input_table[4], "durian"));
274 }
275
276 static void test_strv_extend_strv_concat(void) {
277          _cleanup_strv_free_ char **a = NULL, **b = NULL;
278
279         a = strv_new("without", "suffix", NULL);
280         b = strv_new("with", "suffix", NULL);
281         assert_se(a);
282         assert_se(b);
283
284         assert_se(strv_extend_strv_concat(&a, b, "_suffix") >= 0);
285
286         assert_se(streq(a[0], "without"));
287         assert_se(streq(a[1], "suffix"));
288         assert_se(streq(a[2], "with_suffix"));
289         assert_se(streq(a[3], "suffix_suffix"));
290 }
291
292 static void test_strv_extend_strv(void) {
293          _cleanup_strv_free_ char **a = NULL, **b = NULL;
294
295         a = strv_new("abc", "def", "ghi", NULL);
296         b = strv_new("jkl", "mno", "pqr", NULL);
297         assert_se(a);
298         assert_se(b);
299
300         assert_se(strv_extend_strv(&a, b) >= 0);
301
302         assert_se(streq(a[0], "abc"));
303         assert_se(streq(a[1], "def"));
304         assert_se(streq(a[2], "ghi"));
305         assert_se(streq(a[3], "jkl"));
306         assert_se(streq(a[4], "mno"));
307         assert_se(streq(a[5], "pqr"));
308
309         assert_se(strv_length(a) == 6);
310 }
311
312 static void test_strv_extend(void) {
313         _cleanup_strv_free_ char **a = NULL, **b = NULL;
314
315         a = strv_new("test", "test1", NULL);
316         assert_se(a);
317         assert_se(strv_extend(&a, "test2") >= 0);
318         assert_se(strv_extend(&b, "test3") >= 0);
319
320         assert_se(streq(a[0], "test"));
321         assert_se(streq(a[1], "test1"));
322         assert_se(streq(a[2], "test2"));
323         assert_se(streq(b[0], "test3"));
324 }
325
326 static void test_strv_foreach(void) {
327         _cleanup_strv_free_ char **a;
328         unsigned i = 0;
329         char **check;
330
331         a = strv_new("one", "two", "three", NULL);
332
333         assert_se(a);
334
335         STRV_FOREACH(check, a) {
336                 assert_se(streq(*check, input_table_multiple[i++]));
337         }
338 }
339
340 static void test_strv_foreach_backwards(void) {
341         _cleanup_strv_free_ char **a;
342         unsigned i = 2;
343         char **check;
344
345         a = strv_new("one", "two", "three", NULL);
346
347         assert_se(a);
348
349         STRV_FOREACH_BACKWARDS(check, a) {
350                 assert_se(streq_ptr(*check, input_table_multiple[i--]));
351         }
352 }
353
354 static void test_strv_foreach_pair(void) {
355         _cleanup_strv_free_ char **a = NULL;
356         char **x, **y;
357
358         a = strv_new("pair_one",   "pair_one",
359                      "pair_two",   "pair_two",
360                      "pair_three", "pair_three",
361                      NULL);
362
363         STRV_FOREACH_PAIR(x, y, a) {
364                 assert_se(streq(*x, *y));
365         }
366 }
367
368 static void test_strv_from_stdarg_alloca_one(char **l, const char *first, ...) {
369         char **j;
370         unsigned i;
371
372         j = strv_from_stdarg_alloca(first);
373
374         for (i = 0;; i++) {
375                 assert_se(streq_ptr(l[i], j[i]));
376
377                 if (!l[i])
378                         break;
379         }
380 }
381
382 static void test_strv_from_stdarg_alloca(void) {
383         test_strv_from_stdarg_alloca_one(STRV_MAKE("foo", "bar"), "foo", "bar", NULL);
384         test_strv_from_stdarg_alloca_one(STRV_MAKE("foo"), "foo", NULL);
385         test_strv_from_stdarg_alloca_one(STRV_MAKE_EMPTY, NULL);
386 }
387
388 int main(int argc, char *argv[]) {
389         test_specifier_printf();
390         test_strv_foreach();
391         test_strv_foreach_backwards();
392         test_strv_foreach_pair();
393         test_strv_find();
394         test_strv_find_prefix();
395         test_strv_join();
396
397         test_strv_quote_unquote(input_table_multiple, "\"one\" \"two\" \"three\"");
398         test_strv_quote_unquote(input_table_one, "\"one\"");
399         test_strv_quote_unquote(input_table_none, "");
400         test_strv_quote_unquote(input_table_quotes, QUOTES_STRING);
401         test_strv_quote_unquote(input_table_spaces, SPACES_STRING);
402
403         test_strv_quote_unquote2("    foo=bar     \"waldo\"    zzz    ", (const char*[]) { "foo=bar", "waldo", "zzz", NULL });
404         test_strv_quote_unquote2("", (const char*[]) { NULL });
405         test_strv_quote_unquote2(" ", (const char*[]) { NULL });
406         test_strv_quote_unquote2("   ", (const char*[]) { NULL });
407         test_strv_quote_unquote2("   x", (const char*[]) { "x", NULL });
408         test_strv_quote_unquote2("x   ", (const char*[]) { "x", NULL });
409         test_strv_quote_unquote2("  x   ", (const char*[]) { "x", NULL });
410         test_strv_quote_unquote2("  \"x\"   ", (const char*[]) { "x", NULL });
411         test_strv_quote_unquote2("  \'x\'   ", (const char*[]) { "x", NULL });
412         test_strv_quote_unquote2("  \'x\"\'   ", (const char*[]) { "x\"", NULL });
413         test_strv_quote_unquote2("  \"x\'\"   ", (const char*[]) { "x\'", NULL });
414
415         test_strv_split();
416         test_strv_split_newlines();
417         test_strv_split_nulstr();
418         test_strv_parse_nulstr();
419         test_strv_overlap();
420         test_strv_sort();
421         test_strv_extend_strv();
422         test_strv_extend_strv_concat();
423         test_strv_extend();
424         test_strv_from_stdarg_alloca();
425
426         return 0;
427 }