chiark / gitweb /
macro: add CONST_MAX() macro
[elogind.git] / src / test / test-util.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 #include <unistd.h>
25 #include <fcntl.h>
26 #include <locale.h>
27 #include <errno.h>
28 #include <signal.h>
29 #include <math.h>
30
31 #include "util.h"
32 #include "mkdir.h"
33 #include "strv.h"
34 #include "def.h"
35 #include "fileio.h"
36 #include "conf-parser.h"
37
38 static void test_streq_ptr(void) {
39         assert_se(streq_ptr(NULL, NULL));
40         assert_se(!streq_ptr("abc", "cdef"));
41 }
42
43 static void test_align_power2(void) {
44         unsigned long i, p2;
45
46         assert_se(ALIGN_POWER2(0) == 0);
47         assert_se(ALIGN_POWER2(1) == 1);
48         assert_se(ALIGN_POWER2(2) == 2);
49         assert_se(ALIGN_POWER2(3) == 4);
50         assert_se(ALIGN_POWER2(12) == 16);
51
52         assert_se(ALIGN_POWER2(ULONG_MAX) == 0);
53         assert_se(ALIGN_POWER2(ULONG_MAX - 1) == 0);
54         assert_se(ALIGN_POWER2(ULONG_MAX - 1024) == 0);
55         assert_se(ALIGN_POWER2(ULONG_MAX / 2) == ULONG_MAX / 2 + 1);
56         assert_se(ALIGN_POWER2(ULONG_MAX + 1) == 0);
57
58         for (i = 1; i < 131071; ++i) {
59                 for (p2 = 1; p2 < i; p2 <<= 1)
60                         /* empty */ ;
61
62                 assert_se(ALIGN_POWER2(i) == p2);
63         }
64
65         for (i = ULONG_MAX - 1024; i < ULONG_MAX; ++i) {
66                 for (p2 = 1; p2 && p2 < i; p2 <<= 1)
67                         /* empty */ ;
68
69                 assert_se(ALIGN_POWER2(i) == p2);
70         }
71 }
72
73 static void test_max(void) {
74         static const struct {
75                 int a;
76                 int b[CONST_MAX(10, 100)];
77         } val1 = {
78                 .a = CONST_MAX(10, 100),
79         };
80         int d = 0;
81
82         assert_cc(sizeof(val1.b) == sizeof(int) * 100);
83
84         /* CONST_MAX returns (void) instead of a value if the passed arguments
85          * are not of the same type or not constant expressions. */
86         assert_cc(__builtin_types_compatible_p(typeof(CONST_MAX(1, 10)), int));
87         assert_cc(__builtin_types_compatible_p(typeof(CONST_MAX(d, 10)), void));
88         assert_cc(__builtin_types_compatible_p(typeof(CONST_MAX(1, 1U)), void));
89
90         assert_se(val1.a == 100);
91         assert_se(MAX(++d, 0) == 1);
92         assert_se(d == 1);
93 }
94
95 static void test_first_word(void) {
96         assert_se(first_word("Hello", ""));
97         assert_se(first_word("Hello", "Hello"));
98         assert_se(first_word("Hello world", "Hello"));
99         assert_se(first_word("Hello\tworld", "Hello"));
100         assert_se(first_word("Hello\nworld", "Hello"));
101         assert_se(first_word("Hello\rworld", "Hello"));
102         assert_se(first_word("Hello ", "Hello"));
103
104         assert_se(!first_word("Hello", "Hellooo"));
105         assert_se(!first_word("Hello", "xxxxx"));
106         assert_se(!first_word("Hellooo", "Hello"));
107 }
108
109 static void test_close_many(void) {
110         int fds[3];
111         char name0[] = "/tmp/test-close-many.XXXXXX";
112         char name1[] = "/tmp/test-close-many.XXXXXX";
113         char name2[] = "/tmp/test-close-many.XXXXXX";
114
115         fds[0] = mkostemp_safe(name0, O_RDWR|O_CLOEXEC);
116         fds[1] = mkostemp_safe(name1, O_RDWR|O_CLOEXEC);
117         fds[2] = mkostemp_safe(name2, O_RDWR|O_CLOEXEC);
118
119         close_many(fds, 2);
120
121         assert_se(fcntl(fds[0], F_GETFD) == -1);
122         assert_se(fcntl(fds[1], F_GETFD) == -1);
123         assert_se(fcntl(fds[2], F_GETFD) >= 0);
124
125         safe_close(fds[2]);
126
127         unlink(name0);
128         unlink(name1);
129         unlink(name2);
130 }
131
132 static void test_parse_boolean(void) {
133         assert_se(parse_boolean("1") == 1);
134         assert_se(parse_boolean("y") == 1);
135         assert_se(parse_boolean("Y") == 1);
136         assert_se(parse_boolean("yes") == 1);
137         assert_se(parse_boolean("YES") == 1);
138         assert_se(parse_boolean("true") == 1);
139         assert_se(parse_boolean("TRUE") == 1);
140         assert_se(parse_boolean("on") == 1);
141         assert_se(parse_boolean("ON") == 1);
142
143         assert_se(parse_boolean("0") == 0);
144         assert_se(parse_boolean("n") == 0);
145         assert_se(parse_boolean("N") == 0);
146         assert_se(parse_boolean("no") == 0);
147         assert_se(parse_boolean("NO") == 0);
148         assert_se(parse_boolean("false") == 0);
149         assert_se(parse_boolean("FALSE") == 0);
150         assert_se(parse_boolean("off") == 0);
151         assert_se(parse_boolean("OFF") == 0);
152
153         assert_se(parse_boolean("garbage") < 0);
154         assert_se(parse_boolean("") < 0);
155         assert_se(parse_boolean("full") < 0);
156 }
157
158 static void test_parse_pid(void) {
159         int r;
160         pid_t pid;
161
162         r = parse_pid("100", &pid);
163         assert_se(r == 0);
164         assert_se(pid == 100);
165
166         r = parse_pid("0x7FFFFFFF", &pid);
167         assert_se(r == 0);
168         assert_se(pid == 2147483647);
169
170         pid = 65; /* pid is left unchanged on ERANGE. Set to known arbitrary value. */
171         r = parse_pid("0", &pid);
172         assert_se(r == -ERANGE);
173         assert_se(pid == 65);
174
175         pid = 65; /* pid is left unchanged on ERANGE. Set to known arbitrary value. */
176         r = parse_pid("-100", &pid);
177         assert_se(r == -ERANGE);
178         assert_se(pid == 65);
179
180         pid = 65; /* pid is left unchanged on ERANGE. Set to known arbitrary value. */
181         r = parse_pid("0xFFFFFFFFFFFFFFFFF", &pid);
182         assert(r == -ERANGE);
183         assert_se(pid == 65);
184 }
185
186 static void test_parse_uid(void) {
187         int r;
188         uid_t uid;
189
190         r = parse_uid("100", &uid);
191         assert_se(r == 0);
192         assert_se(uid == 100);
193 }
194
195 static void test_safe_atolli(void) {
196         int r;
197         long long l;
198
199         r = safe_atolli("12345", &l);
200         assert_se(r == 0);
201         assert_se(l == 12345);
202
203         r = safe_atolli("junk", &l);
204         assert_se(r == -EINVAL);
205 }
206
207 static void test_safe_atod(void) {
208         int r;
209         double d;
210         char *e;
211
212         r = safe_atod("junk", &d);
213         assert_se(r == -EINVAL);
214
215         r = safe_atod("0.2244", &d);
216         assert_se(r == 0);
217         assert_se(fabs(d - 0.2244) < 0.000001);
218
219         r = safe_atod("0,5", &d);
220         assert_se(r == -EINVAL);
221
222         errno = 0;
223         strtod("0,5", &e);
224         assert_se(*e == ',');
225
226         /* Check if this really is locale independent */
227         if (setlocale(LC_NUMERIC, "de_DE.utf8")) {
228
229                 r = safe_atod("0.2244", &d);
230                 assert_se(r == 0);
231                 assert_se(fabs(d - 0.2244) < 0.000001);
232
233                 r = safe_atod("0,5", &d);
234                 assert_se(r == -EINVAL);
235
236                 errno = 0;
237                 assert_se(fabs(strtod("0,5", &e) - 0.5) < 0.00001);
238         }
239
240         /* And check again, reset */
241         assert_se(setlocale(LC_NUMERIC, "C"));
242
243         r = safe_atod("0.2244", &d);
244         assert_se(r == 0);
245         assert_se(fabs(d - 0.2244) < 0.000001);
246
247         r = safe_atod("0,5", &d);
248         assert_se(r == -EINVAL);
249
250         errno = 0;
251         strtod("0,5", &e);
252         assert_se(*e == ',');
253 }
254
255 static void test_strappend(void) {
256         _cleanup_free_ char *t1, *t2, *t3, *t4;
257
258         t1 = strappend(NULL, NULL);
259         assert_se(streq(t1, ""));
260
261         t2 = strappend(NULL, "suf");
262         assert_se(streq(t2, "suf"));
263
264         t3 = strappend("pre", NULL);
265         assert_se(streq(t3, "pre"));
266
267         t4 = strappend("pre", "suf");
268         assert_se(streq(t4, "presuf"));
269 }
270
271 static void test_strstrip(void) {
272         char *r;
273         char input[] = "   hello, waldo.   ";
274
275         r = strstrip(input);
276         assert_se(streq(r, "hello, waldo."));
277 }
278
279 static void test_delete_chars(void) {
280         char *r;
281         char input[] = "   hello, waldo.   abc";
282
283         r = delete_chars(input, WHITESPACE);
284         assert_se(streq(r, "hello,waldo.abc"));
285 }
286
287 static void test_in_charset(void) {
288         assert_se(in_charset("dddaaabbbcccc", "abcd"));
289         assert_se(!in_charset("dddaaabbbcccc", "abc f"));
290 }
291
292 static void test_hexchar(void) {
293         assert_se(hexchar(0xa) == 'a');
294         assert_se(hexchar(0x0) == '0');
295 }
296
297 static void test_unhexchar(void) {
298         assert_se(unhexchar('a') == 0xA);
299         assert_se(unhexchar('A') == 0xA);
300         assert_se(unhexchar('0') == 0x0);
301 }
302
303 static void test_octchar(void) {
304         assert_se(octchar(00) == '0');
305         assert_se(octchar(07) == '7');
306 }
307
308 static void test_unoctchar(void) {
309         assert_se(unoctchar('0') == 00);
310         assert_se(unoctchar('7') == 07);
311 }
312
313 static void test_decchar(void) {
314         assert_se(decchar(0) == '0');
315         assert_se(decchar(9) == '9');
316 }
317
318 static void test_undecchar(void) {
319         assert_se(undecchar('0') == 0);
320         assert_se(undecchar('9') == 9);
321 }
322
323 static void test_cescape(void) {
324         _cleanup_free_ char *escaped;
325
326         assert_se(escaped = cescape("abc\\\"\b\f\n\r\t\v\a\003\177\234\313"));
327         assert_se(streq(escaped, "abc\\\\\\\"\\b\\f\\n\\r\\t\\v\\a\\003\\177\\234\\313"));
328 }
329
330 static void test_cunescape(void) {
331         _cleanup_free_ char *unescaped;
332
333         assert_se(unescaped = cunescape("abc\\\\\\\"\\b\\f\\a\\n\\r\\t\\v\\003\\177\\234\\313\\000\\x00"));
334         assert_se(streq(unescaped, "abc\\\"\b\f\a\n\r\t\v\003\177\234\313\\000\\x00"));
335 }
336
337 static void test_foreach_word(void) {
338         const char *word, *state;
339         size_t l;
340         int i = 0;
341         const char test[] = "test abc d\te   f   ";
342         const char * const expected[] = {
343                 "test",
344                 "abc",
345                 "d",
346                 "e",
347                 "f",
348                 "",
349                 NULL
350         };
351
352         FOREACH_WORD(word, l, test, state)
353                 assert_se(strneq(expected[i++], word, l));
354 }
355
356 static void test_foreach_word_quoted(void) {
357         const char *word, *state;
358         size_t l;
359         int i = 0;
360         const char test[] = "test a b c 'd' e '' '' hhh '' '' \"a b c\"";
361         const char * const expected[] = {
362                 "test",
363                 "a",
364                 "b",
365                 "c",
366                 "d",
367                 "e",
368                 "",
369                 "",
370                 "hhh",
371                 "",
372                 "",
373                 "a b c",
374                 NULL
375         };
376
377         printf("<%s>\n", test);
378         FOREACH_WORD_QUOTED(word, l, test, state) {
379                 _cleanup_free_ char *t = NULL;
380
381                 assert_se(t = strndup(word, l));
382                 assert_se(strneq(expected[i++], word, l));
383                 printf("<%s>\n", t);
384         }
385         assert(isempty(state));
386 }
387
388 static void test_default_term_for_tty(void) {
389         puts(default_term_for_tty("/dev/tty23"));
390         puts(default_term_for_tty("/dev/ttyS23"));
391         puts(default_term_for_tty("/dev/tty0"));
392         puts(default_term_for_tty("/dev/pty0"));
393         puts(default_term_for_tty("/dev/pts/0"));
394         puts(default_term_for_tty("/dev/console"));
395         puts(default_term_for_tty("tty23"));
396         puts(default_term_for_tty("ttyS23"));
397         puts(default_term_for_tty("tty0"));
398         puts(default_term_for_tty("pty0"));
399         puts(default_term_for_tty("pts/0"));
400         puts(default_term_for_tty("console"));
401 }
402
403 static void test_memdup_multiply(void) {
404         int org[] = {1, 2, 3};
405         int *dup;
406
407         dup = (int*)memdup_multiply(org, sizeof(int), 3);
408
409         assert_se(dup);
410         assert_se(dup[0] == 1);
411         assert_se(dup[1] == 2);
412         assert_se(dup[2] == 3);
413         free(dup);
414 }
415
416 static void test_hostname_is_valid(void) {
417         assert(hostname_is_valid("foobar"));
418         assert(hostname_is_valid("foobar.com"));
419         assert(!hostname_is_valid("fööbar"));
420         assert(!hostname_is_valid(""));
421         assert(!hostname_is_valid("."));
422         assert(!hostname_is_valid(".."));
423         assert(!hostname_is_valid("foobar."));
424         assert(!hostname_is_valid(".foobar"));
425         assert(!hostname_is_valid("foo..bar"));
426         assert(!hostname_is_valid("xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"));
427 }
428
429 static void test_u64log2(void) {
430         assert(u64log2(0) == 0);
431         assert(u64log2(8) == 3);
432         assert(u64log2(9) == 3);
433         assert(u64log2(15) == 3);
434         assert(u64log2(16) == 4);
435         assert(u64log2(1024*1024) == 20);
436         assert(u64log2(1024*1024+5) == 20);
437 }
438
439 static void test_get_process_comm(void) {
440         struct stat st;
441         _cleanup_free_ char *a = NULL, *c = NULL, *d = NULL, *f = NULL, *i = NULL;
442         unsigned long long b;
443         pid_t e;
444         uid_t u;
445         gid_t g;
446         dev_t h;
447         int r;
448
449         if (stat("/proc/1/comm", &st) == 0) {
450                 assert_se(get_process_comm(1, &a) >= 0);
451                 log_info("pid1 comm: '%s'", a);
452         } else {
453                 log_warning("/proc/1/comm does not exist.");
454         }
455
456         assert_se(get_starttime_of_pid(1, &b) >= 0);
457         log_info("pid1 starttime: '%llu'", b);
458
459         assert_se(get_process_cmdline(1, 0, true, &c) >= 0);
460         log_info("pid1 cmdline: '%s'", c);
461
462         assert_se(get_process_cmdline(1, 8, false, &d) >= 0);
463         log_info("pid1 cmdline truncated: '%s'", d);
464
465         assert_se(get_parent_of_pid(1, &e) >= 0);
466         log_info("pid1 ppid: "PID_FMT, e);
467         assert_se(e == 0);
468
469         assert_se(is_kernel_thread(1) == 0);
470
471         r = get_process_exe(1, &f);
472         assert_se(r >= 0 || r == -EACCES);
473         log_info("pid1 exe: '%s'", strna(f));
474
475         assert_se(get_process_uid(1, &u) == 0);
476         log_info("pid1 uid: "UID_FMT, u);
477         assert_se(u == 0);
478
479         assert_se(get_process_gid(1, &g) == 0);
480         log_info("pid1 gid: "GID_FMT, g);
481         assert_se(g == 0);
482
483         assert(get_ctty_devnr(1, &h) == -ENOENT);
484
485         getenv_for_pid(1, "PATH", &i);
486         log_info("pid1 $PATH: '%s'", strna(i));
487 }
488
489 static void test_protect_errno(void) {
490         errno = 12;
491         {
492                 PROTECT_ERRNO;
493                 errno = 11;
494         }
495         assert(errno == 12);
496 }
497
498 static void test_parse_size(void) {
499         off_t bytes;
500
501         assert_se(parse_size("111", 1024, &bytes) == 0);
502         assert_se(bytes == 111);
503
504         assert_se(parse_size("111.4", 1024, &bytes) == 0);
505         assert_se(bytes == 111);
506
507         assert_se(parse_size(" 112 B", 1024, &bytes) == 0);
508         assert_se(bytes == 112);
509
510         assert_se(parse_size(" 112.6 B", 1024, &bytes) == 0);
511         assert_se(bytes == 112);
512
513         assert_se(parse_size("3.5 K", 1024, &bytes) == 0);
514         assert_se(bytes == 3*1024 + 512);
515
516         assert_se(parse_size("3. K", 1024, &bytes) == 0);
517         assert_se(bytes == 3*1024);
518
519         assert_se(parse_size("3.0 K", 1024, &bytes) == 0);
520         assert_se(bytes == 3*1024);
521
522         assert_se(parse_size("3. 0 K", 1024, &bytes) == -EINVAL);
523
524         assert_se(parse_size(" 4 M 11.5K", 1024, &bytes) == 0);
525         assert_se(bytes == 4*1024*1024 + 11 * 1024 + 512);
526
527         assert_se(parse_size("3B3.5G", 1024, &bytes) == -EINVAL);
528
529         assert_se(parse_size("3.5G3B", 1024, &bytes) == 0);
530         assert_se(bytes == 3ULL*1024*1024*1024 + 512*1024*1024 + 3);
531
532         assert_se(parse_size("3.5G 4B", 1024, &bytes) == 0);
533         assert_se(bytes == 3ULL*1024*1024*1024 + 512*1024*1024 + 4);
534
535         assert_se(parse_size("3B3G4T", 1024, &bytes) == -EINVAL);
536
537         assert_se(parse_size("4T3G3B", 1024, &bytes) == 0);
538         assert_se(bytes == (4ULL*1024 + 3)*1024*1024*1024 + 3);
539
540         assert_se(parse_size(" 4 T 3 G 3 B", 1024, &bytes) == 0);
541         assert_se(bytes == (4ULL*1024 + 3)*1024*1024*1024 + 3);
542
543         assert_se(parse_size("12P", 1024, &bytes) == 0);
544         assert_se(bytes == 12ULL * 1024*1024*1024*1024*1024);
545
546         assert_se(parse_size("12P12P", 1024, &bytes) == -EINVAL);
547
548         assert_se(parse_size("3E 2P", 1024, &bytes) == 0);
549         assert_se(bytes == (3 * 1024 + 2ULL) * 1024*1024*1024*1024*1024);
550
551         assert_se(parse_size("12X", 1024, &bytes) == -EINVAL);
552
553         assert_se(parse_size("12.5X", 1024, &bytes) == -EINVAL);
554
555         assert_se(parse_size("12.5e3", 1024, &bytes) == -EINVAL);
556
557         assert_se(parse_size("1024E", 1024, &bytes) == -ERANGE);
558         assert_se(parse_size("-1", 1024, &bytes) == -ERANGE);
559         assert_se(parse_size("-1024E", 1024, &bytes) == -ERANGE);
560
561         assert_se(parse_size("-1024P", 1024, &bytes) == -ERANGE);
562
563         assert_se(parse_size("-10B 20K", 1024, &bytes) == -ERANGE);
564 }
565
566 static void test_config_parse_iec_off(void) {
567         off_t offset = 0;
568         assert_se(config_parse_iec_off(NULL, "/this/file", 11, "Section", 22, "Size", 0, "4M", &offset, NULL) == 0);
569         assert_se(offset == 4 * 1024 * 1024);
570
571         assert_se(config_parse_iec_off(NULL, "/this/file", 11, "Section", 22, "Size", 0, "4.5M", &offset, NULL) == 0);
572 }
573
574 static void test_strextend(void) {
575         _cleanup_free_ char *str = strdup("0123");
576         strextend(&str, "456", "78", "9", NULL);
577         assert_se(streq(str, "0123456789"));
578 }
579
580 static void test_strrep(void) {
581         _cleanup_free_ char *one, *three, *zero;
582         one = strrep("waldo", 1);
583         three = strrep("waldo", 3);
584         zero = strrep("waldo", 0);
585
586         assert_se(streq(one, "waldo"));
587         assert_se(streq(three, "waldowaldowaldo"));
588         assert_se(streq(zero, ""));
589 }
590
591 static void test_split_pair(void) {
592         _cleanup_free_ char *a = NULL, *b = NULL;
593
594         assert_se(split_pair("", "", &a, &b) == -EINVAL);
595         assert_se(split_pair("foo=bar", "", &a, &b) == -EINVAL);
596         assert_se(split_pair("", "=", &a, &b) == -EINVAL);
597         assert_se(split_pair("foo=bar", "=", &a, &b) >= 0);
598         assert_se(streq(a, "foo"));
599         assert_se(streq(b, "bar"));
600         free(a);
601         free(b);
602         assert_se(split_pair("==", "==", &a, &b) >= 0);
603         assert_se(streq(a, ""));
604         assert_se(streq(b, ""));
605         free(a);
606         free(b);
607
608         assert_se(split_pair("===", "==", &a, &b) >= 0);
609         assert_se(streq(a, ""));
610         assert_se(streq(b, "="));
611 }
612
613 static void test_fstab_node_to_udev_node(void) {
614         char *n;
615
616         n = fstab_node_to_udev_node("LABEL=applé/jack");
617         puts(n);
618         assert_se(streq(n, "/dev/disk/by-label/applé\\x2fjack"));
619         free(n);
620
621         n = fstab_node_to_udev_node("PARTLABEL=pinkié pie");
622         puts(n);
623         assert_se(streq(n, "/dev/disk/by-partlabel/pinkié\\x20pie"));
624         free(n);
625
626         n = fstab_node_to_udev_node("UUID=037b9d94-148e-4ee4-8d38-67bfe15bb535");
627         puts(n);
628         assert_se(streq(n, "/dev/disk/by-uuid/037b9d94-148e-4ee4-8d38-67bfe15bb535"));
629         free(n);
630
631         n = fstab_node_to_udev_node("PARTUUID=037b9d94-148e-4ee4-8d38-67bfe15bb535");
632         puts(n);
633         assert_se(streq(n, "/dev/disk/by-partuuid/037b9d94-148e-4ee4-8d38-67bfe15bb535"));
634         free(n);
635
636         n = fstab_node_to_udev_node("PONIES=awesome");
637         puts(n);
638         assert_se(streq(n, "PONIES=awesome"));
639         free(n);
640
641         n = fstab_node_to_udev_node("/dev/xda1");
642         puts(n);
643         assert_se(streq(n, "/dev/xda1"));
644         free(n);
645 }
646
647 static void test_get_files_in_directory(void) {
648         _cleanup_strv_free_ char **l = NULL, **t = NULL;
649
650         assert_se(get_files_in_directory("/tmp", &l) >= 0);
651         assert_se(get_files_in_directory(".", &t) >= 0);
652         assert_se(get_files_in_directory(".", NULL) >= 0);
653 }
654
655 static void test_in_set(void) {
656         assert_se(IN_SET(1, 1));
657         assert_se(IN_SET(1, 1, 2, 3, 4));
658         assert_se(IN_SET(2, 1, 2, 3, 4));
659         assert_se(IN_SET(3, 1, 2, 3, 4));
660         assert_se(IN_SET(4, 1, 2, 3, 4));
661         assert_se(!IN_SET(0, 1));
662         assert_se(!IN_SET(0, 1, 2, 3, 4));
663 }
664
665 static void test_writing_tmpfile(void) {
666         char name[] = "/tmp/test-systemd_writing_tmpfile.XXXXXX";
667         _cleanup_free_ char *contents = NULL;
668         size_t size;
669         int fd, r;
670         struct iovec iov[3];
671
672         IOVEC_SET_STRING(iov[0], "abc\n");
673         IOVEC_SET_STRING(iov[1], ALPHANUMERICAL "\n");
674         IOVEC_SET_STRING(iov[2], "");
675
676         fd = mkostemp_safe(name, O_RDWR|O_CLOEXEC);
677         printf("tmpfile: %s", name);
678
679         r = writev(fd, iov, 3);
680         assert(r >= 0);
681
682         r = read_full_file(name, &contents, &size);
683         assert(r == 0);
684         printf("contents: %s", contents);
685         assert(streq(contents, "abc\n" ALPHANUMERICAL "\n"));
686
687         unlink(name);
688 }
689
690 static void test_hexdump(void) {
691         uint8_t data[146];
692         unsigned i;
693
694         hexdump(stdout, NULL, 0);
695         hexdump(stdout, "", 0);
696         hexdump(stdout, "", 1);
697         hexdump(stdout, "x", 1);
698         hexdump(stdout, "x", 2);
699         hexdump(stdout, "foobar", 7);
700         hexdump(stdout, "f\nobar", 7);
701         hexdump(stdout, "xxxxxxxxxxxxxxxxxxxxyz", 23);
702
703         for (i = 0; i < ELEMENTSOF(data); i++)
704                 data[i] = i*2;
705
706         hexdump(stdout, data, sizeof(data));
707 }
708
709 static void test_log2i(void) {
710         assert_se(log2i(1) == 0);
711         assert_se(log2i(2) == 1);
712         assert_se(log2i(3) == 1);
713         assert_se(log2i(4) == 2);
714         assert_se(log2i(32) == 5);
715         assert_se(log2i(33) == 5);
716         assert_se(log2i(63) == 5);
717         assert_se(log2i(INT_MAX) == sizeof(int)*8-2);
718 }
719
720 static void test_foreach_string(void) {
721         const char * const t[] = {
722                 "foo",
723                 "bar",
724                 "waldo",
725                 NULL
726         };
727         const char *x;
728         unsigned i = 0;
729
730         FOREACH_STRING(x, "foo", "bar", "waldo")
731                 assert_se(streq_ptr(t[i++], x));
732
733         assert_se(i == 3);
734
735         FOREACH_STRING(x, "zzz")
736                 assert_se(streq(x, "zzz"));
737 }
738
739 static void test_filename_is_safe(void) {
740         char foo[FILENAME_MAX+2];
741         int i;
742
743         assert_se(!filename_is_safe(""));
744         assert_se(!filename_is_safe("/bar/foo"));
745         assert_se(!filename_is_safe("/"));
746         assert_se(!filename_is_safe("."));
747         assert_se(!filename_is_safe(".."));
748
749         for (i=0; i<FILENAME_MAX+1; i++)
750                 foo[i] = 'a';
751         foo[FILENAME_MAX+1] = '\0';
752
753         assert_se(!filename_is_safe(foo));
754
755         assert_se(filename_is_safe("foo_bar-333"));
756         assert_se(filename_is_safe("o.o"));
757 }
758
759 static void test_string_has_cc(void) {
760         assert_se(string_has_cc("abc\1", NULL));
761         assert_se(string_has_cc("abc\x7f", NULL));
762         assert_se(string_has_cc("abc\x7f", NULL));
763         assert_se(string_has_cc("abc\t\x7f", "\t"));
764         assert_se(string_has_cc("abc\t\x7f", "\t"));
765         assert_se(string_has_cc("\x7f", "\t"));
766         assert_se(string_has_cc("\x7f", "\t\a"));
767
768         assert_se(!string_has_cc("abc\t\t", "\t"));
769         assert_se(!string_has_cc("abc\t\t\a", "\t\a"));
770         assert_se(!string_has_cc("a\ab\tc", "\t\a"));
771 }
772
773 static void test_ascii_strlower(void) {
774         char a[] = "AabBcC Jk Ii Od LKJJJ kkd LK";
775         assert_se(streq(ascii_strlower(a), "aabbcc jk ii od lkjjj kkd lk"));
776 }
777
778 static void test_files_same(void) {
779         _cleanup_close_ int fd = -1;
780         char name[] = "/tmp/test-files_same.XXXXXX";
781         char name_alias[] = "/tmp/test-files_same.alias";
782
783         fd = mkostemp_safe(name, O_RDWR|O_CLOEXEC);
784         assert_se(fd >= 0);
785         assert_se(symlink(name, name_alias) >= 0);
786
787         assert_se(files_same(name, name));
788         assert_se(files_same(name, name_alias));
789
790         unlink(name);
791         unlink(name_alias);
792 }
793
794 static void test_is_valid_documentation_url(void) {
795         assert_se(is_valid_documentation_url("http://www.freedesktop.org/wiki/Software/systemd"));
796         assert_se(is_valid_documentation_url("https://www.kernel.org/doc/Documentation/binfmt_misc.txt"));
797         assert_se(is_valid_documentation_url("file:foo"));
798         assert_se(is_valid_documentation_url("man:systemd.special(7)"));
799         assert_se(is_valid_documentation_url("info:bar"));
800
801         assert_se(!is_valid_documentation_url("foo:"));
802         assert_se(!is_valid_documentation_url("info:"));
803         assert_se(!is_valid_documentation_url(""));
804 }
805
806 static void test_file_in_same_dir(void) {
807         assert_se(streq(file_in_same_dir("/", "a"), "/a"));
808         assert_se(streq(file_in_same_dir("/", "/a"), "/a"));
809         assert_se(streq(file_in_same_dir("", "a"), "a"));
810         assert_se(streq(file_in_same_dir("a/", "a"), "a/a"));
811         assert_se(streq(file_in_same_dir("bar/foo", "bar"), "bar/bar"));
812 }
813
814 static void test_endswith(void) {
815         assert_se(endswith("foobar", "bar"));
816         assert_se(endswith("foobar", ""));
817         assert_se(endswith("foobar", "foobar"));
818         assert_se(endswith("", ""));
819
820         assert_se(!endswith("foobar", "foo"));
821         assert_se(!endswith("foobar", "foobarfoofoo"));
822 }
823
824 static void test_close_nointr(void) {
825         char name[] = "/tmp/test-test-close_nointr.XXXXXX";
826         int fd;
827
828         fd = mkostemp_safe(name, O_RDWR|O_CLOEXEC);
829         assert_se(fd >= 0);
830         assert_se(close_nointr(fd) >= 0);
831         assert_se(close_nointr(fd) < 0);
832
833         unlink(name);
834 }
835
836
837 static void test_unlink_noerrno(void) {
838         char name[] = "/tmp/test-close_nointr.XXXXXX";
839         int fd;
840
841         fd = mkostemp_safe(name, O_RDWR|O_CLOEXEC);
842         assert_se(fd >= 0);
843         assert_se(close_nointr(fd) >= 0);
844
845         {
846                 PROTECT_ERRNO;
847                 errno = -42;
848                 assert_se(unlink_noerrno(name) >= 0);
849                 assert_se(errno == -42);
850                 assert_se(unlink_noerrno(name) < 0);
851                 assert_se(errno == -42);
852         }
853 }
854
855 static void test_readlink_and_make_absolute(void) {
856         char tempdir[] = "/tmp/test-readlink_and_make_absolute";
857         char name[] = "/tmp/test-readlink_and_make_absolute/original";
858         char name2[] = "test-readlink_and_make_absolute/original";
859         char name_alias[] = "/tmp/test-readlink_and_make_absolute-alias";
860         char *r = NULL;
861
862         assert(mkdir_safe(tempdir, 0755, getuid(), getgid()) >= 0);
863         assert_se(touch(name) >= 0);
864
865         assert_se(symlink(name, name_alias) >= 0);
866         assert_se(readlink_and_make_absolute(name_alias, &r) >= 0);
867         assert_se(streq(r, name));
868         free(r);
869         assert_se(unlink(name_alias) >= 0);
870
871         assert_se(chdir(tempdir) >= 0);
872         assert_se(symlink(name2, name_alias) >= 0);
873         assert_se(readlink_and_make_absolute(name_alias, &r) >= 0);
874         assert_se(streq(r, name));
875         free(r);
876         assert_se(unlink(name_alias) >= 0);
877
878         assert_se(rm_rf_dangerous(tempdir, false, true, false) >= 0);
879 }
880
881 static void test_read_one_char(void) {
882         char r;
883         bool need_nl;
884         char name[] = "/tmp/test-read_one_char.XXXXXX";
885         _cleanup_close_ int fd = -1;
886         FILE *file;
887
888         fd = mkostemp_safe(name, O_RDWR|O_CLOEXEC);
889         assert_se(fd >= 0);
890         file = fdopen(fd, "r+");
891         assert_se(file);
892         assert_se(fputs("c\n", file) >= 0);
893         rewind(file);
894
895         assert_se(read_one_char(file, &r, 1000000, &need_nl) >= 0);
896         assert_se(!need_nl);
897         assert_se(r == 'c');
898         assert_se(read_one_char(file, &r, 1000000, &need_nl) < 0);
899
900         rewind(file);
901         assert_se(fputs("foobar\n", file) >= 0);
902         rewind(file);
903         assert_se(read_one_char(file, &r, 1000000, &need_nl) < 0);
904
905         rewind(file);
906         assert_se(fputs("\n", file) >= 0);
907         rewind(file);
908         assert_se(read_one_char(file, &r, 1000000, &need_nl) < 0);
909
910         unlink(name);
911 }
912
913 static void test_ignore_signals(void) {
914         assert_se(ignore_signals(SIGINT, -1) >= 0);
915         assert_se(kill(getpid(), SIGINT) >= 0);
916         assert_se(ignore_signals(SIGUSR1, SIGUSR2, SIGTERM, SIGPIPE, -1) >= 0);
917         assert_se(kill(getpid(), SIGUSR1) >= 0);
918         assert_se(kill(getpid(), SIGUSR2) >= 0);
919         assert_se(kill(getpid(), SIGTERM) >= 0);
920         assert_se(kill(getpid(), SIGPIPE) >= 0);
921         assert_se(default_signals(SIGINT, SIGUSR1, SIGUSR2, SIGTERM, SIGPIPE, -1) >= 0);
922 }
923
924 static void test_strshorten(void) {
925         char s[] = "foobar";
926
927         assert_se(strlen(strshorten(s, 6)) == 6);
928         assert_se(strlen(strshorten(s, 12)) == 6);
929         assert_se(strlen(strshorten(s, 2)) == 2);
930         assert_se(strlen(strshorten(s, 0)) == 0);
931 }
932
933 static void test_strappenda(void) {
934         char *actual;
935
936         actual = strappenda("", "foo", "bar");
937         assert_se(streq(actual, "foobar"));
938
939         actual = strappenda("foo", "bar", "baz");
940         assert_se(streq(actual, "foobarbaz"));
941
942         actual = strappenda("foo", "", "bar", "baz");
943         assert_se(streq(actual, "foobarbaz"));
944 }
945
946 int main(int argc, char *argv[]) {
947         log_parse_environment();
948         log_open();
949
950         test_streq_ptr();
951         test_align_power2();
952         test_max();
953         test_first_word();
954         test_close_many();
955         test_parse_boolean();
956         test_parse_pid();
957         test_parse_uid();
958         test_safe_atolli();
959         test_safe_atod();
960         test_strappend();
961         test_strstrip();
962         test_delete_chars();
963         test_in_charset();
964         test_hexchar();
965         test_unhexchar();
966         test_octchar();
967         test_unoctchar();
968         test_decchar();
969         test_undecchar();
970         test_cescape();
971         test_cunescape();
972         test_foreach_word();
973         test_foreach_word_quoted();
974         test_default_term_for_tty();
975         test_memdup_multiply();
976         test_hostname_is_valid();
977         test_u64log2();
978         test_get_process_comm();
979         test_protect_errno();
980         test_parse_size();
981         test_config_parse_iec_off();
982         test_strextend();
983         test_strrep();
984         test_split_pair();
985         test_fstab_node_to_udev_node();
986         test_get_files_in_directory();
987         test_in_set();
988         test_writing_tmpfile();
989         test_hexdump();
990         test_log2i();
991         test_foreach_string();
992         test_filename_is_safe();
993         test_string_has_cc();
994         test_ascii_strlower();
995         test_files_same();
996         test_is_valid_documentation_url();
997         test_file_in_same_dir();
998         test_endswith();
999         test_close_nointr();
1000         test_unlink_noerrno();
1001         test_readlink_and_make_absolute();
1002         test_read_one_char();
1003         test_ignore_signals();
1004         test_strshorten();
1005         test_strappenda();
1006
1007         return 0;
1008 }