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