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/>.
31 static void test_streq_ptr(void) {
32 assert_se(streq_ptr(NULL, NULL));
33 assert_se(!streq_ptr("abc", "cdef"));
36 static void test_first_word(void) {
37 assert_se(first_word("Hello", ""));
38 assert_se(first_word("Hello", "Hello"));
39 assert_se(first_word("Hello world", "Hello"));
40 assert_se(first_word("Hello\tworld", "Hello"));
41 assert_se(first_word("Hello\nworld", "Hello"));
42 assert_se(first_word("Hello\rworld", "Hello"));
43 assert_se(first_word("Hello ", "Hello"));
45 assert_se(!first_word("Hello", "Hellooo"));
46 assert_se(!first_word("Hello", "xxxxx"));
47 assert_se(!first_word("Hellooo", "Hello"));
50 static void test_close_many(void) {
52 char name0[] = "/tmp/test-close-many.XXXXXX";
53 char name1[] = "/tmp/test-close-many.XXXXXX";
54 char name2[] = "/tmp/test-close-many.XXXXXX";
56 fds[0] = mkstemp(name0);
57 fds[1] = mkstemp(name1);
58 fds[2] = mkstemp(name2);
62 assert_se(fcntl(fds[0], F_GETFD) == -1);
63 assert_se(fcntl(fds[1], F_GETFD) == -1);
64 assert_se(fcntl(fds[2], F_GETFD) >= 0);
66 close_nointr_nofail(fds[2]);
73 static void test_parse_boolean(void) {
74 assert_se(parse_boolean("1") == 1);
75 assert_se(parse_boolean("y") == 1);
76 assert_se(parse_boolean("Y") == 1);
77 assert_se(parse_boolean("yes") == 1);
78 assert_se(parse_boolean("YES") == 1);
79 assert_se(parse_boolean("true") == 1);
80 assert_se(parse_boolean("TRUE") == 1);
81 assert_se(parse_boolean("on") == 1);
82 assert_se(parse_boolean("ON") == 1);
84 assert_se(parse_boolean("0") == 0);
85 assert_se(parse_boolean("n") == 0);
86 assert_se(parse_boolean("N") == 0);
87 assert_se(parse_boolean("no") == 0);
88 assert_se(parse_boolean("NO") == 0);
89 assert_se(parse_boolean("false") == 0);
90 assert_se(parse_boolean("FALSE") == 0);
91 assert_se(parse_boolean("off") == 0);
92 assert_se(parse_boolean("OFF") == 0);
94 assert_se(parse_boolean("garbage") < 0);
95 assert_se(parse_boolean("") < 0);
98 static void test_parse_pid(void) {
102 r = parse_pid("100", &pid);
104 assert_se(pid == 100);
106 r = parse_pid("0x7FFFFFFF", &pid);
108 assert_se(pid == 2147483647);
110 pid = 65; /* pid is left unchanged on ERANGE. Set to known arbitrary value. */
111 r = parse_pid("0", &pid);
112 assert_se(r == -ERANGE);
113 assert_se(pid == 65);
115 pid = 65; /* pid is left unchanged on ERANGE. Set to known arbitrary value. */
116 r = parse_pid("-100", &pid);
117 assert_se(r == -ERANGE);
118 assert_se(pid == 65);
120 pid = 65; /* pid is left unchanged on ERANGE. Set to known arbitrary value. */
121 r = parse_pid("0xFFFFFFFFFFFFFFFFF", &pid);
122 assert(r == -ERANGE);
123 assert_se(pid == 65);
126 static void test_parse_uid(void) {
130 r = parse_uid("100", &uid);
132 assert_se(uid == 100);
135 static void test_safe_atolli(void) {
139 r = safe_atolli("12345", &l);
141 assert_se(l == 12345);
143 r = safe_atolli("junk", &l);
144 assert_se(r == -EINVAL);
147 static void test_safe_atod(void) {
152 r = safe_atod("junk", &d);
153 assert_se(r == -EINVAL);
155 r = safe_atod("0.2244", &d);
157 assert_se(abs(d - 0.2244) < 0.000001);
159 r = safe_atod("0,5", &d);
160 assert_se(r == -EINVAL);
164 assert_se(*e == ',');
166 /* Check if this really is locale independent */
167 setlocale(LC_NUMERIC, "de_DE.utf8");
169 r = safe_atod("0.2244", &d);
171 assert_se(abs(d - 0.2244) < 0.000001);
173 r = safe_atod("0,5", &d);
174 assert_se(r == -EINVAL);
177 assert_se(abs(strtod("0,5", &e) - 0.5) < 0.00001);
179 /* And check again, reset */
180 setlocale(LC_NUMERIC, "C");
182 r = safe_atod("0.2244", &d);
184 assert_se(abs(d - 0.2244) < 0.000001);
186 r = safe_atod("0,5", &d);
187 assert_se(r == -EINVAL);
191 assert_se(*e == ',');
194 static void test_strappend(void) {
195 _cleanup_free_ char *t1, *t2, *t3, *t4;
197 t1 = strappend(NULL, NULL);
198 assert_se(streq(t1, ""));
200 t2 = strappend(NULL, "suf");
201 assert_se(streq(t2, "suf"));
203 t3 = strappend("pre", NULL);
204 assert_se(streq(t3, "pre"));
206 t4 = strappend("pre", "suf");
207 assert_se(streq(t4, "presuf"));
210 static void test_strstrip(void) {
212 char input[] = " hello, waldo. ";
215 assert_se(streq(r, "hello, waldo."));
218 static void test_delete_chars(void) {
220 char input[] = " hello, waldo. abc";
222 r = delete_chars(input, WHITESPACE);
223 assert_se(streq(r, "hello,waldo.abc"));
226 static void test_in_charset(void) {
227 assert_se(in_charset("dddaaabbbcccc", "abcd"));
228 assert_se(!in_charset("dddaaabbbcccc", "abc f"));
231 static void test_hexchar(void) {
232 assert_se(hexchar(0xa) == 'a');
233 assert_se(hexchar(0x0) == '0');
236 static void test_unhexchar(void) {
237 assert_se(unhexchar('a') == 0xA);
238 assert_se(unhexchar('A') == 0xA);
239 assert_se(unhexchar('0') == 0x0);
242 static void test_octchar(void) {
243 assert_se(octchar(00) == '0');
244 assert_se(octchar(07) == '7');
247 static void test_unoctchar(void) {
248 assert_se(unoctchar('0') == 00);
249 assert_se(unoctchar('7') == 07);
252 static void test_decchar(void) {
253 assert_se(decchar(0) == '0');
254 assert_se(decchar(9) == '9');
257 static void test_undecchar(void) {
258 assert_se(undecchar('0') == 0);
259 assert_se(undecchar('9') == 9);
262 static void test_cescape(void) {
263 _cleanup_free_ char *escaped;
264 escaped = cescape("abc\\\"\b\f\n\r\t\v\003\177\234\313");
265 assert_se(streq(escaped, "abc\\\\\\\"\\b\\f\\n\\r\\t\\v\\003\\177\\234\\313"));
268 static void test_cunescape(void) {
269 _cleanup_free_ char *unescaped;
270 unescaped = cunescape("abc\\\\\\\"\\b\\f\\n\\r\\t\\v\\003\\177\\234\\313");
271 assert_se(streq(unescaped, "abc\\\"\b\f\n\r\t\v\003\177\234\313"));
274 static void test_foreach_word(void) {
278 const char test[] = "test abc d\te f ";
279 const char * const expected[] = {
289 FOREACH_WORD(w, l, test, state) {
290 assert_se(strneq(expected[i++], w, l));
294 static void test_foreach_word_quoted(void) {
298 const char test[] = "test a b c 'd' e '' '' hhh '' '' \"a b c\"";
299 const char * const expected[] = {
315 printf("<%s>\n", test);
316 FOREACH_WORD_QUOTED(w, l, test, state) {
317 _cleanup_free_ char *t = NULL;
319 assert_se(t = strndup(w, l));
320 assert_se(strneq(expected[i++], w, l));
325 static void test_default_term_for_tty(void) {
326 puts(default_term_for_tty("/dev/tty23"));
327 puts(default_term_for_tty("/dev/ttyS23"));
328 puts(default_term_for_tty("/dev/tty0"));
329 puts(default_term_for_tty("/dev/pty0"));
330 puts(default_term_for_tty("/dev/pts/0"));
331 puts(default_term_for_tty("/dev/console"));
332 puts(default_term_for_tty("tty23"));
333 puts(default_term_for_tty("ttyS23"));
334 puts(default_term_for_tty("tty0"));
335 puts(default_term_for_tty("pty0"));
336 puts(default_term_for_tty("pts/0"));
337 puts(default_term_for_tty("console"));
340 static void test_memdup_multiply(void) {
341 int org[] = {1, 2, 3};
344 dup = (int*)memdup_multiply(org, sizeof(int), 3);
347 assert_se(dup[0] == 1);
348 assert_se(dup[1] == 2);
349 assert_se(dup[2] == 3);
353 static void test_bus_path_escape_one(const char *a, const char *b) {
354 _cleanup_free_ char *t = NULL, *x = NULL, *y = NULL;
356 assert_se(t = bus_path_escape(a));
357 assert_se(streq(t, b));
359 assert_se(x = bus_path_unescape(t));
360 assert_se(streq(a, x));
362 assert_se(y = bus_path_unescape(b));
363 assert_se(streq(a, y));
366 static void test_bus_path_escape(void) {
367 test_bus_path_escape_one("foo123bar", "foo123bar");
368 test_bus_path_escape_one("foo.bar", "foo_2ebar");
369 test_bus_path_escape_one("foo_2ebar", "foo_5f2ebar");
370 test_bus_path_escape_one("", "_");
371 test_bus_path_escape_one("_", "_5f");
372 test_bus_path_escape_one("1", "_31");
373 test_bus_path_escape_one(":1", "_3a1");
376 static void test_hostname_is_valid(void) {
377 assert(hostname_is_valid("foobar"));
378 assert(hostname_is_valid("foobar.com"));
379 assert(!hostname_is_valid("fööbar"));
380 assert(!hostname_is_valid(""));
381 assert(!hostname_is_valid("."));
382 assert(!hostname_is_valid(".."));
383 assert(!hostname_is_valid("foobar."));
384 assert(!hostname_is_valid(".foobar"));
385 assert(!hostname_is_valid("foo..bar"));
386 assert(!hostname_is_valid("xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"));
389 static void test_u64log2(void) {
390 assert(u64log2(0) == 0);
391 assert(u64log2(8) == 3);
392 assert(u64log2(9) == 3);
393 assert(u64log2(15) == 3);
394 assert(u64log2(16) == 4);
395 assert(u64log2(1024*1024) == 20);
396 assert(u64log2(1024*1024+5) == 20);
399 static void test_get_process_comm(void) {
401 _cleanup_free_ char *a = NULL, *c = NULL, *d = NULL, *f = NULL, *i = NULL;
402 unsigned long long b;
409 if (stat("/proc/1/comm", &st) == 0) {
410 assert_se(get_process_comm(1, &a) >= 0);
411 log_info("pid1 comm: '%s'", a);
413 log_warning("/proc/1/comm does not exist.");
416 assert_se(get_starttime_of_pid(1, &b) >= 0);
417 log_info("pid1 starttime: '%llu'", b);
419 assert_se(get_process_cmdline(1, 0, true, &c) >= 0);
420 log_info("pid1 cmdline: '%s'", c);
422 assert_se(get_process_cmdline(1, 8, false, &d) >= 0);
423 log_info("pid1 cmdline truncated: '%s'", d);
425 assert_se(get_parent_of_pid(1, &e) >= 0);
426 log_info("pid1 ppid: '%llu'", (unsigned long long) e);
429 assert_se(is_kernel_thread(1) == 0);
431 r = get_process_exe(1, &f);
432 assert_se(r >= 0 || r == -EACCES);
433 log_info("pid1 exe: '%s'", strna(f));
435 assert_se(get_process_uid(1, &u) == 0);
436 log_info("pid1 uid: '%llu'", (unsigned long long) u);
439 assert_se(get_process_gid(1, &g) == 0);
440 log_info("pid1 gid: '%llu'", (unsigned long long) g);
443 assert(get_ctty_devnr(1, &h) == -ENOENT);
445 getenv_for_pid(1, "PATH", &i);
446 log_info("pid1 $PATH: '%s'", strna(i));
449 static void test_protect_errno(void) {
458 static void test_parse_bytes(void) {
461 assert_se(parse_bytes("111", &bytes) == 0);
462 assert_se(bytes == 111);
464 assert_se(parse_bytes(" 112 B", &bytes) == 0);
465 assert_se(bytes == 112);
467 assert_se(parse_bytes("3 K", &bytes) == 0);
468 assert_se(bytes == 3*1024);
470 assert_se(parse_bytes(" 4 M 11K", &bytes) == 0);
471 assert_se(bytes == 4*1024*1024 + 11 * 1024);
473 assert_se(parse_bytes("3B3G", &bytes) == 0);
474 assert_se(bytes == 3ULL*1024*1024*1024 + 3);
476 assert_se(parse_bytes("3B3G4T", &bytes) == 0);
477 assert_se(bytes == (4ULL*1024 + 3)*1024*1024*1024 + 3);
479 assert_se(parse_bytes("12P", &bytes) == 0);
480 assert_se(bytes == 12ULL * 1024*1024*1024*1024*1024);
482 assert_se(parse_bytes("3E 2P", &bytes) == 0);
483 assert_se(bytes == (3 * 1024 + 2ULL) * 1024*1024*1024*1024*1024);
485 assert_se(parse_bytes("12X", &bytes) == -EINVAL);
487 assert_se(parse_bytes("1024E", &bytes) == -ERANGE);
488 assert_se(parse_bytes("-1", &bytes) == -ERANGE);
489 assert_se(parse_bytes("-1024E", &bytes) == -ERANGE);
491 assert_se(parse_bytes("-1024P", &bytes) == -ERANGE);
493 assert_se(parse_bytes("-10B 20K", &bytes) == -ERANGE);
496 static void test_strextend(void) {
497 _cleanup_free_ char *str = strdup("0123");
498 strextend(&str, "456", "78", "9", NULL);
499 assert_se(streq(str, "0123456789"));
502 static void test_strrep(void) {
503 _cleanup_free_ char *one, *three, *zero;
504 one = strrep("waldo", 1);
505 three = strrep("waldo", 3);
506 zero = strrep("waldo", 0);
508 assert_se(streq(one, "waldo"));
509 assert_se(streq(three, "waldowaldowaldo"));
510 assert_se(streq(zero, ""));
513 static void test_parse_user_at_host(void) {
514 _cleanup_free_ char *both = strdup("waldo@waldoscomputer");
515 _cleanup_free_ char *onlyhost = strdup("mikescomputer");
516 char *user = NULL, *host = NULL;
518 parse_user_at_host(both, &user, &host);
519 assert_se(streq(user, "waldo"));
520 assert_se(streq(host, "waldoscomputer"));
523 parse_user_at_host(onlyhost, &user, &host);
524 assert_se(user == NULL);
525 assert_se(streq(host, "mikescomputer"));
528 static void test_split_pair(void) {
529 _cleanup_free_ char *a = NULL, *b = NULL;
531 assert_se(split_pair("", "", &a, &b) == -EINVAL);
532 assert_se(split_pair("foo=bar", "", &a, &b) == -EINVAL);
533 assert_se(split_pair("", "=", &a, &b) == -EINVAL);
534 assert_se(split_pair("foo=bar", "=", &a, &b) >= 0);
535 assert_se(streq(a, "foo"));
536 assert_se(streq(b, "bar"));
539 assert_se(split_pair("==", "==", &a, &b) >= 0);
540 assert_se(streq(a, ""));
541 assert_se(streq(b, ""));
545 assert_se(split_pair("===", "==", &a, &b) >= 0);
546 assert_se(streq(a, ""));
547 assert_se(streq(b, "="));
550 int main(int argc, char *argv[]) {
554 test_parse_boolean();
572 test_foreach_word_quoted();
573 test_default_term_for_tty();
574 test_memdup_multiply();
575 test_bus_path_escape();
576 test_hostname_is_valid();
578 test_get_process_comm();
579 test_protect_errno();
583 test_parse_user_at_host();