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