1 /*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
4 This file is part of systemd.
6 Copyright 2010 Lennart Poettering
7 Copyright 2013 Thomas H.P. Andersen
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.
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.
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/>.
33 #include "conf-parser.h"
35 static void test_streq_ptr(void) {
36 assert_se(streq_ptr(NULL, NULL));
37 assert_se(!streq_ptr("abc", "cdef"));
40 static void test_align_power2(void) {
43 assert_se(ALIGN_POWER2(0) == 0);
44 assert_se(ALIGN_POWER2(1) == 1);
45 assert_se(ALIGN_POWER2(2) == 2);
46 assert_se(ALIGN_POWER2(3) == 4);
47 assert_se(ALIGN_POWER2(12) == 16);
49 assert_se(ALIGN_POWER2(ULONG_MAX) == 0);
50 assert_se(ALIGN_POWER2(ULONG_MAX - 1) == 0);
51 assert_se(ALIGN_POWER2(ULONG_MAX - 1024) == 0);
52 assert_se(ALIGN_POWER2(ULONG_MAX / 2) == ULONG_MAX / 2 + 1);
53 assert_se(ALIGN_POWER2(ULONG_MAX + 1) == 0);
55 for (i = 1; i < 131071; ++i) {
56 for (p2 = 1; p2 < i; p2 <<= 1)
59 assert_se(ALIGN_POWER2(i) == p2);
62 for (i = ULONG_MAX - 1024; i < ULONG_MAX; ++i) {
63 for (p2 = 1; p2 && p2 < i; p2 <<= 1)
66 assert_se(ALIGN_POWER2(i) == p2);
70 static void test_first_word(void) {
71 assert_se(first_word("Hello", ""));
72 assert_se(first_word("Hello", "Hello"));
73 assert_se(first_word("Hello world", "Hello"));
74 assert_se(first_word("Hello\tworld", "Hello"));
75 assert_se(first_word("Hello\nworld", "Hello"));
76 assert_se(first_word("Hello\rworld", "Hello"));
77 assert_se(first_word("Hello ", "Hello"));
79 assert_se(!first_word("Hello", "Hellooo"));
80 assert_se(!first_word("Hello", "xxxxx"));
81 assert_se(!first_word("Hellooo", "Hello"));
84 static void test_close_many(void) {
86 char name0[] = "/tmp/test-close-many.XXXXXX";
87 char name1[] = "/tmp/test-close-many.XXXXXX";
88 char name2[] = "/tmp/test-close-many.XXXXXX";
90 fds[0] = mkostemp_safe(name0, O_RDWR|O_CLOEXEC);
91 fds[1] = mkostemp_safe(name1, O_RDWR|O_CLOEXEC);
92 fds[2] = mkostemp_safe(name2, O_RDWR|O_CLOEXEC);
96 assert_se(fcntl(fds[0], F_GETFD) == -1);
97 assert_se(fcntl(fds[1], F_GETFD) == -1);
98 assert_se(fcntl(fds[2], F_GETFD) >= 0);
107 static void test_parse_boolean(void) {
108 assert_se(parse_boolean("1") == 1);
109 assert_se(parse_boolean("y") == 1);
110 assert_se(parse_boolean("Y") == 1);
111 assert_se(parse_boolean("yes") == 1);
112 assert_se(parse_boolean("YES") == 1);
113 assert_se(parse_boolean("true") == 1);
114 assert_se(parse_boolean("TRUE") == 1);
115 assert_se(parse_boolean("on") == 1);
116 assert_se(parse_boolean("ON") == 1);
118 assert_se(parse_boolean("0") == 0);
119 assert_se(parse_boolean("n") == 0);
120 assert_se(parse_boolean("N") == 0);
121 assert_se(parse_boolean("no") == 0);
122 assert_se(parse_boolean("NO") == 0);
123 assert_se(parse_boolean("false") == 0);
124 assert_se(parse_boolean("FALSE") == 0);
125 assert_se(parse_boolean("off") == 0);
126 assert_se(parse_boolean("OFF") == 0);
128 assert_se(parse_boolean("garbage") < 0);
129 assert_se(parse_boolean("") < 0);
132 static void test_parse_pid(void) {
136 r = parse_pid("100", &pid);
138 assert_se(pid == 100);
140 r = parse_pid("0x7FFFFFFF", &pid);
142 assert_se(pid == 2147483647);
144 pid = 65; /* pid is left unchanged on ERANGE. Set to known arbitrary value. */
145 r = parse_pid("0", &pid);
146 assert_se(r == -ERANGE);
147 assert_se(pid == 65);
149 pid = 65; /* pid is left unchanged on ERANGE. Set to known arbitrary value. */
150 r = parse_pid("-100", &pid);
151 assert_se(r == -ERANGE);
152 assert_se(pid == 65);
154 pid = 65; /* pid is left unchanged on ERANGE. Set to known arbitrary value. */
155 r = parse_pid("0xFFFFFFFFFFFFFFFFF", &pid);
156 assert(r == -ERANGE);
157 assert_se(pid == 65);
160 static void test_parse_uid(void) {
164 r = parse_uid("100", &uid);
166 assert_se(uid == 100);
169 static void test_safe_atolli(void) {
173 r = safe_atolli("12345", &l);
175 assert_se(l == 12345);
177 r = safe_atolli("junk", &l);
178 assert_se(r == -EINVAL);
181 static void test_safe_atod(void) {
186 r = safe_atod("junk", &d);
187 assert_se(r == -EINVAL);
189 r = safe_atod("0.2244", &d);
191 assert_se(abs(d - 0.2244) < 0.000001);
193 r = safe_atod("0,5", &d);
194 assert_se(r == -EINVAL);
198 assert_se(*e == ',');
200 /* Check if this really is locale independent */
201 setlocale(LC_NUMERIC, "de_DE.utf8");
203 r = safe_atod("0.2244", &d);
205 assert_se(abs(d - 0.2244) < 0.000001);
207 r = safe_atod("0,5", &d);
208 assert_se(r == -EINVAL);
211 assert_se(abs(strtod("0,5", &e) - 0.5) < 0.00001);
213 /* And check again, reset */
214 setlocale(LC_NUMERIC, "C");
216 r = safe_atod("0.2244", &d);
218 assert_se(abs(d - 0.2244) < 0.000001);
220 r = safe_atod("0,5", &d);
221 assert_se(r == -EINVAL);
225 assert_se(*e == ',');
228 static void test_strappend(void) {
229 _cleanup_free_ char *t1, *t2, *t3, *t4;
231 t1 = strappend(NULL, NULL);
232 assert_se(streq(t1, ""));
234 t2 = strappend(NULL, "suf");
235 assert_se(streq(t2, "suf"));
237 t3 = strappend("pre", NULL);
238 assert_se(streq(t3, "pre"));
240 t4 = strappend("pre", "suf");
241 assert_se(streq(t4, "presuf"));
244 static void test_strstrip(void) {
246 char input[] = " hello, waldo. ";
249 assert_se(streq(r, "hello, waldo."));
252 static void test_delete_chars(void) {
254 char input[] = " hello, waldo. abc";
256 r = delete_chars(input, WHITESPACE);
257 assert_se(streq(r, "hello,waldo.abc"));
260 static void test_in_charset(void) {
261 assert_se(in_charset("dddaaabbbcccc", "abcd"));
262 assert_se(!in_charset("dddaaabbbcccc", "abc f"));
265 static void test_hexchar(void) {
266 assert_se(hexchar(0xa) == 'a');
267 assert_se(hexchar(0x0) == '0');
270 static void test_unhexchar(void) {
271 assert_se(unhexchar('a') == 0xA);
272 assert_se(unhexchar('A') == 0xA);
273 assert_se(unhexchar('0') == 0x0);
276 static void test_octchar(void) {
277 assert_se(octchar(00) == '0');
278 assert_se(octchar(07) == '7');
281 static void test_unoctchar(void) {
282 assert_se(unoctchar('0') == 00);
283 assert_se(unoctchar('7') == 07);
286 static void test_decchar(void) {
287 assert_se(decchar(0) == '0');
288 assert_se(decchar(9) == '9');
291 static void test_undecchar(void) {
292 assert_se(undecchar('0') == 0);
293 assert_se(undecchar('9') == 9);
296 static void test_cescape(void) {
297 _cleanup_free_ char *escaped;
298 escaped = cescape("abc\\\"\b\f\n\r\t\v\003\177\234\313");
299 assert_se(streq(escaped, "abc\\\\\\\"\\b\\f\\n\\r\\t\\v\\003\\177\\234\\313"));
302 static void test_cunescape(void) {
303 _cleanup_free_ char *unescaped;
304 unescaped = cunescape("abc\\\\\\\"\\b\\f\\n\\r\\t\\v\\003\\177\\234\\313");
305 assert_se(streq(unescaped, "abc\\\"\b\f\n\r\t\v\003\177\234\313"));
308 static void test_foreach_word(void) {
312 const char test[] = "test abc d\te f ";
313 const char * const expected[] = {
323 FOREACH_WORD(w, l, test, state) {
324 assert_se(strneq(expected[i++], w, l));
328 static void test_foreach_word_quoted(void) {
332 const char test[] = "test a b c 'd' e '' '' hhh '' '' \"a b c\"";
333 const char * const expected[] = {
349 printf("<%s>\n", test);
350 FOREACH_WORD_QUOTED(w, l, test, state) {
351 _cleanup_free_ char *t = NULL;
353 assert_se(t = strndup(w, l));
354 assert_se(strneq(expected[i++], w, l));
359 static void test_default_term_for_tty(void) {
360 puts(default_term_for_tty("/dev/tty23"));
361 puts(default_term_for_tty("/dev/ttyS23"));
362 puts(default_term_for_tty("/dev/tty0"));
363 puts(default_term_for_tty("/dev/pty0"));
364 puts(default_term_for_tty("/dev/pts/0"));
365 puts(default_term_for_tty("/dev/console"));
366 puts(default_term_for_tty("tty23"));
367 puts(default_term_for_tty("ttyS23"));
368 puts(default_term_for_tty("tty0"));
369 puts(default_term_for_tty("pty0"));
370 puts(default_term_for_tty("pts/0"));
371 puts(default_term_for_tty("console"));
374 static void test_memdup_multiply(void) {
375 int org[] = {1, 2, 3};
378 dup = (int*)memdup_multiply(org, sizeof(int), 3);
381 assert_se(dup[0] == 1);
382 assert_se(dup[1] == 2);
383 assert_se(dup[2] == 3);
387 static void test_hostname_is_valid(void) {
388 assert(hostname_is_valid("foobar"));
389 assert(hostname_is_valid("foobar.com"));
390 assert(!hostname_is_valid("fööbar"));
391 assert(!hostname_is_valid(""));
392 assert(!hostname_is_valid("."));
393 assert(!hostname_is_valid(".."));
394 assert(!hostname_is_valid("foobar."));
395 assert(!hostname_is_valid(".foobar"));
396 assert(!hostname_is_valid("foo..bar"));
397 assert(!hostname_is_valid("xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"));
400 static void test_u64log2(void) {
401 assert(u64log2(0) == 0);
402 assert(u64log2(8) == 3);
403 assert(u64log2(9) == 3);
404 assert(u64log2(15) == 3);
405 assert(u64log2(16) == 4);
406 assert(u64log2(1024*1024) == 20);
407 assert(u64log2(1024*1024+5) == 20);
410 static void test_get_process_comm(void) {
412 _cleanup_free_ char *a = NULL, *c = NULL, *d = NULL, *f = NULL, *i = NULL;
413 unsigned long long b;
420 if (stat("/proc/1/comm", &st) == 0) {
421 assert_se(get_process_comm(1, &a) >= 0);
422 log_info("pid1 comm: '%s'", a);
424 log_warning("/proc/1/comm does not exist.");
427 assert_se(get_starttime_of_pid(1, &b) >= 0);
428 log_info("pid1 starttime: '%llu'", b);
430 assert_se(get_process_cmdline(1, 0, true, &c) >= 0);
431 log_info("pid1 cmdline: '%s'", c);
433 assert_se(get_process_cmdline(1, 8, false, &d) >= 0);
434 log_info("pid1 cmdline truncated: '%s'", d);
436 assert_se(get_parent_of_pid(1, &e) >= 0);
437 log_info("pid1 ppid: "PID_FMT, e);
440 assert_se(is_kernel_thread(1) == 0);
442 r = get_process_exe(1, &f);
443 assert_se(r >= 0 || r == -EACCES);
444 log_info("pid1 exe: '%s'", strna(f));
446 assert_se(get_process_uid(1, &u) == 0);
447 log_info("pid1 uid: "UID_FMT, u);
450 assert_se(get_process_gid(1, &g) == 0);
451 log_info("pid1 gid: "GID_FMT, g);
454 assert(get_ctty_devnr(1, &h) == -ENOENT);
456 getenv_for_pid(1, "PATH", &i);
457 log_info("pid1 $PATH: '%s'", strna(i));
460 static void test_protect_errno(void) {
469 static void test_parse_size(void) {
472 assert_se(parse_size("111", 1024, &bytes) == 0);
473 assert_se(bytes == 111);
475 assert_se(parse_size("111.4", 1024, &bytes) == 0);
476 assert_se(bytes == 111);
478 assert_se(parse_size(" 112 B", 1024, &bytes) == 0);
479 assert_se(bytes == 112);
481 assert_se(parse_size(" 112.6 B", 1024, &bytes) == 0);
482 assert_se(bytes == 112);
484 assert_se(parse_size("3.5 K", 1024, &bytes) == 0);
485 assert_se(bytes == 3*1024 + 512);
487 assert_se(parse_size("3. K", 1024, &bytes) == 0);
488 assert_se(bytes == 3*1024);
490 assert_se(parse_size("3.0 K", 1024, &bytes) == 0);
491 assert_se(bytes == 3*1024);
493 assert_se(parse_size("3. 0 K", 1024, &bytes) == -EINVAL);
495 assert_se(parse_size(" 4 M 11.5K", 1024, &bytes) == 0);
496 assert_se(bytes == 4*1024*1024 + 11 * 1024 + 512);
498 assert_se(parse_size("3B3.5G", 1024, &bytes) == -EINVAL);
500 assert_se(parse_size("3.5G3B", 1024, &bytes) == 0);
501 assert_se(bytes == 3ULL*1024*1024*1024 + 512*1024*1024 + 3);
503 assert_se(parse_size("3.5G 4B", 1024, &bytes) == 0);
504 assert_se(bytes == 3ULL*1024*1024*1024 + 512*1024*1024 + 4);
506 assert_se(parse_size("3B3G4T", 1024, &bytes) == -EINVAL);
508 assert_se(parse_size("4T3G3B", 1024, &bytes) == 0);
509 assert_se(bytes == (4ULL*1024 + 3)*1024*1024*1024 + 3);
511 assert_se(parse_size(" 4 T 3 G 3 B", 1024, &bytes) == 0);
512 assert_se(bytes == (4ULL*1024 + 3)*1024*1024*1024 + 3);
514 assert_se(parse_size("12P", 1024, &bytes) == 0);
515 assert_se(bytes == 12ULL * 1024*1024*1024*1024*1024);
517 assert_se(parse_size("12P12P", 1024, &bytes) == -EINVAL);
519 assert_se(parse_size("3E 2P", 1024, &bytes) == 0);
520 assert_se(bytes == (3 * 1024 + 2ULL) * 1024*1024*1024*1024*1024);
522 assert_se(parse_size("12X", 1024, &bytes) == -EINVAL);
524 assert_se(parse_size("12.5X", 1024, &bytes) == -EINVAL);
526 assert_se(parse_size("12.5e3", 1024, &bytes) == -EINVAL);
528 assert_se(parse_size("1024E", 1024, &bytes) == -ERANGE);
529 assert_se(parse_size("-1", 1024, &bytes) == -ERANGE);
530 assert_se(parse_size("-1024E", 1024, &bytes) == -ERANGE);
532 assert_se(parse_size("-1024P", 1024, &bytes) == -ERANGE);
534 assert_se(parse_size("-10B 20K", 1024, &bytes) == -ERANGE);
537 static void test_config_parse_iec_off(void) {
539 assert_se(config_parse_iec_off(NULL, "/this/file", 11, "Section", 22, "Size", 0, "4M", &offset, NULL) == 0);
540 assert_se(offset == 4 * 1024 * 1024);
542 assert_se(config_parse_iec_off(NULL, "/this/file", 11, "Section", 22, "Size", 0, "4.5M", &offset, NULL) == 0);
545 static void test_strextend(void) {
546 _cleanup_free_ char *str = strdup("0123");
547 strextend(&str, "456", "78", "9", NULL);
548 assert_se(streq(str, "0123456789"));
551 static void test_strrep(void) {
552 _cleanup_free_ char *one, *three, *zero;
553 one = strrep("waldo", 1);
554 three = strrep("waldo", 3);
555 zero = strrep("waldo", 0);
557 assert_se(streq(one, "waldo"));
558 assert_se(streq(three, "waldowaldowaldo"));
559 assert_se(streq(zero, ""));
562 static void test_split_pair(void) {
563 _cleanup_free_ char *a = NULL, *b = NULL;
565 assert_se(split_pair("", "", &a, &b) == -EINVAL);
566 assert_se(split_pair("foo=bar", "", &a, &b) == -EINVAL);
567 assert_se(split_pair("", "=", &a, &b) == -EINVAL);
568 assert_se(split_pair("foo=bar", "=", &a, &b) >= 0);
569 assert_se(streq(a, "foo"));
570 assert_se(streq(b, "bar"));
573 assert_se(split_pair("==", "==", &a, &b) >= 0);
574 assert_se(streq(a, ""));
575 assert_se(streq(b, ""));
579 assert_se(split_pair("===", "==", &a, &b) >= 0);
580 assert_se(streq(a, ""));
581 assert_se(streq(b, "="));
584 static void test_fstab_node_to_udev_node(void) {
587 n = fstab_node_to_udev_node("LABEL=applé/jack");
589 assert_se(streq(n, "/dev/disk/by-label/applé\\x2fjack"));
592 n = fstab_node_to_udev_node("PARTLABEL=pinkié pie");
594 assert_se(streq(n, "/dev/disk/by-partlabel/pinkié\\x20pie"));
597 n = fstab_node_to_udev_node("UUID=037b9d94-148e-4ee4-8d38-67bfe15bb535");
599 assert_se(streq(n, "/dev/disk/by-uuid/037b9d94-148e-4ee4-8d38-67bfe15bb535"));
602 n = fstab_node_to_udev_node("PARTUUID=037b9d94-148e-4ee4-8d38-67bfe15bb535");
604 assert_se(streq(n, "/dev/disk/by-partuuid/037b9d94-148e-4ee4-8d38-67bfe15bb535"));
607 n = fstab_node_to_udev_node("PONIES=awesome");
609 assert_se(streq(n, "PONIES=awesome"));
612 n = fstab_node_to_udev_node("/dev/xda1");
614 assert_se(streq(n, "/dev/xda1"));
618 static void test_get_files_in_directory(void) {
619 _cleanup_strv_free_ char **l = NULL, **t = NULL;
621 assert_se(get_files_in_directory("/tmp", &l) >= 0);
622 assert_se(get_files_in_directory(".", &t) >= 0);
623 assert_se(get_files_in_directory(".", NULL) >= 0);
626 static void test_in_set(void) {
627 assert_se(IN_SET(1, 1));
628 assert_se(IN_SET(1, 1, 2, 3, 4));
629 assert_se(IN_SET(2, 1, 2, 3, 4));
630 assert_se(IN_SET(3, 1, 2, 3, 4));
631 assert_se(IN_SET(4, 1, 2, 3, 4));
632 assert_se(!IN_SET(0, 1));
633 assert_se(!IN_SET(0, 1, 2, 3, 4));
636 static void test_writing_tmpfile(void) {
637 char name[] = "/tmp/test-systemd_writing_tmpfile.XXXXXX";
638 _cleanup_free_ char *contents = NULL;
643 IOVEC_SET_STRING(iov[0], "abc\n");
644 IOVEC_SET_STRING(iov[1], ALPHANUMERICAL "\n");
645 IOVEC_SET_STRING(iov[2], "");
647 fd = mkostemp_safe(name, O_RDWR|O_CLOEXEC);
648 printf("tmpfile: %s", name);
650 r = writev(fd, iov, 3);
653 r = read_full_file(name, &contents, &size);
655 printf("contents: %s", contents);
656 assert(streq(contents, "abc\n" ALPHANUMERICAL "\n"));
659 static void test_hexdump(void) {
663 hexdump(stdout, NULL, 0);
664 hexdump(stdout, "", 0);
665 hexdump(stdout, "", 1);
666 hexdump(stdout, "x", 1);
667 hexdump(stdout, "x", 2);
668 hexdump(stdout, "foobar", 7);
669 hexdump(stdout, "f\nobar", 7);
670 hexdump(stdout, "xxxxxxxxxxxxxxxxxxxxyz", 23);
672 for (i = 0; i < ELEMENTSOF(data); i++)
675 hexdump(stdout, data, sizeof(data));
678 static void test_log2i(void) {
679 assert_se(log2i(1) == 0);
680 assert_se(log2i(2) == 1);
681 assert_se(log2i(3) == 1);
682 assert_se(log2i(4) == 2);
683 assert_se(log2i(32) == 5);
684 assert_se(log2i(33) == 5);
685 assert_se(log2i(63) == 5);
686 assert_se(log2i(INT_MAX) == sizeof(int)*8-2);
689 static void test_foreach_string(void) {
690 const char * const t[] = {
699 FOREACH_STRING(x, "foo", "bar", "waldo")
700 assert_se(streq_ptr(t[i++], x));
704 FOREACH_STRING(x, "zzz")
705 assert_se(streq(x, "zzz"));
708 int main(int argc, char *argv[]) {
709 log_parse_environment();
716 test_parse_boolean();
734 test_foreach_word_quoted();
735 test_default_term_for_tty();
736 test_memdup_multiply();
737 test_hostname_is_valid();
739 test_get_process_comm();
740 test_protect_errno();
742 test_config_parse_iec_off();
746 test_fstab_node_to_udev_node();
747 test_get_files_in_directory();
749 test_writing_tmpfile();
752 test_foreach_string();