]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/test/test-util.c
test: Make testing work on systems without or old systemd
[thirdparty/systemd.git] / src / test / test-util.c
CommitLineData
539ad707
TA
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>
dbd73f9e
TA
24#include <unistd.h>
25#include <fcntl.h>
d6dd604b 26#include <locale.h>
2a371001 27#include <errno.h>
539ad707
TA
28
29#include "util.h"
30
31static void test_streq_ptr(void) {
8354c34e
TA
32 assert_se(streq_ptr(NULL, NULL));
33 assert_se(!streq_ptr("abc", "cdef"));
539ad707
TA
34}
35
36static void test_first_word(void) {
8354c34e
TA
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"));
44
45 assert_se(!first_word("Hello", "Hellooo"));
46 assert_se(!first_word("Hello", "xxxxx"));
47 assert_se(!first_word("Hellooo", "Hello"));
48}
49
dbd73f9e
TA
50static void test_close_many(void) {
51 int fds[3];
52 char name0[] = "/tmp/test-close-many.XXXXXX";
53 char name1[] = "/tmp/test-close-many.XXXXXX";
54 char name2[] = "/tmp/test-close-many.XXXXXX";
55
56 fds[0] = mkstemp(name0);
57 fds[1] = mkstemp(name1);
58 fds[2] = mkstemp(name2);
59
60 close_many(fds, 2);
61
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);
65
66 close_nointr_nofail(fds[2]);
67
68 unlink(name0);
69 unlink(name1);
70 unlink(name2);
71}
72
8354c34e
TA
73static 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);
83
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);
93
94 assert_se(parse_boolean("garbage") < 0);
95 assert_se(parse_boolean("") < 0);
539ad707
TA
96}
97
8d99e5f5
TA
98static void test_parse_pid(void) {
99 int r;
100 pid_t pid;
101
102 r = parse_pid("100", &pid);
103 assert_se(r == 0);
104 assert_se(pid == 100);
105
106 r = parse_pid("0x7FFFFFFF", &pid);
107 assert_se(r == 0);
108 assert_se(pid == 2147483647);
109
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);
114
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);
119
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);
124}
125
126static void test_parse_uid(void) {
127 int r;
128 uid_t uid;
129
130 r = parse_uid("100", &uid);
131 assert_se(r == 0);
132 assert_se(uid == 100);
133}
134
135static void test_safe_atolli(void) {
136 int r;
137 long long l;
138
139 r = safe_atolli("12345", &l);
140 assert_se(r == 0);
141 assert_se(l == 12345);
142
143 r = safe_atolli("junk", &l);
144 assert_se(r == -EINVAL);
145}
146
147static void test_safe_atod(void) {
148 int r;
149 double d;
d6dd604b
LP
150 char *e;
151
152 r = safe_atod("junk", &d);
153 assert_se(r == -EINVAL);
8d99e5f5
TA
154
155 r = safe_atod("0.2244", &d);
156 assert_se(r == 0);
157 assert_se(abs(d - 0.2244) < 0.000001);
158
d6dd604b 159 r = safe_atod("0,5", &d);
8d99e5f5 160 assert_se(r == -EINVAL);
d6dd604b
LP
161
162 errno = 0;
163 strtod("0,5", &e);
164 assert_se(*e == ',');
165
166 /* Check if this really is locale independent */
167 setlocale(LC_NUMERIC, "de_DE.utf8");
168
169 r = safe_atod("0.2244", &d);
170 assert_se(r == 0);
171 assert_se(abs(d - 0.2244) < 0.000001);
172
173 r = safe_atod("0,5", &d);
174 assert_se(r == -EINVAL);
175
176 errno = 0;
177 assert_se(abs(strtod("0,5", &e) - 0.5) < 0.00001);
178
179 /* And check again, reset */
180 setlocale(LC_NUMERIC, "C");
181
182 r = safe_atod("0.2244", &d);
183 assert_se(r == 0);
184 assert_se(abs(d - 0.2244) < 0.000001);
185
186 r = safe_atod("0,5", &d);
187 assert_se(r == -EINVAL);
188
189 errno = 0;
190 strtod("0,5", &e);
191 assert_se(*e == ',');
8d99e5f5
TA
192}
193
dbd73f9e 194static void test_strappend(void) {
998b087f 195 _cleanup_free_ char *t1, *t2, *t3, *t4;
dbd73f9e 196
998b087f
TA
197 t1 = strappend(NULL, NULL);
198 assert_se(streq(t1, ""));
dbd73f9e 199
998b087f
TA
200 t2 = strappend(NULL, "suf");
201 assert_se(streq(t2, "suf"));
dbd73f9e 202
998b087f
TA
203 t3 = strappend("pre", NULL);
204 assert_se(streq(t3, "pre"));
dbd73f9e 205
998b087f
TA
206 t4 = strappend("pre", "suf");
207 assert_se(streq(t4, "presuf"));
dbd73f9e
TA
208}
209
1ef04f0b 210static void test_strstrip(void) {
998b087f
TA
211 char *r;
212 char input[] = " hello, waldo. ";
1ef04f0b 213
998b087f
TA
214 r = strstrip(input);
215 assert_se(streq(r, "hello, waldo."));
1ef04f0b
TA
216}
217
218static void test_delete_chars(void) {
998b087f
TA
219 char *r;
220 char input[] = " hello, waldo. abc";
1ef04f0b 221
998b087f
TA
222 r = delete_chars(input, WHITESPACE);
223 assert_se(streq(r, "hello,waldo.abc"));
1ef04f0b
TA
224}
225
226static void test_in_charset(void) {
998b087f
TA
227 assert_se(in_charset("dddaaabbbcccc", "abcd"));
228 assert_se(!in_charset("dddaaabbbcccc", "abc f"));
1ef04f0b
TA
229}
230
44f4c86c
DB
231static void test_hexchar(void) {
232 assert_se(hexchar(0xa) == 'a');
233 assert_se(hexchar(0x0) == '0');
234}
235
236static void test_unhexchar(void) {
237 assert_se(unhexchar('a') == 0xA);
238 assert_se(unhexchar('A') == 0xA);
239 assert_se(unhexchar('0') == 0x0);
240}
241
242static void test_octchar(void) {
243 assert_se(octchar(00) == '0');
244 assert_se(octchar(07) == '7');
245}
246
247static void test_unoctchar(void) {
248 assert_se(unoctchar('0') == 00);
249 assert_se(unoctchar('7') == 07);
250}
251
252static void test_decchar(void) {
253 assert_se(decchar(0) == '0');
254 assert_se(decchar(9) == '9');
255}
256
257static void test_undecchar(void) {
258 assert_se(undecchar('0') == 0);
259 assert_se(undecchar('9') == 9);
260}
261
b4ecc959
TA
262static 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"));
266}
267
268static 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"));
272}
273
1ef04f0b
TA
274static void test_foreach_word(void) {
275 char *w, *state;
276 size_t l;
277 int i = 0;
278 const char test[] = "test abc d\te f ";
279 const char * const expected[] = {
280 "test",
281 "abc",
282 "d",
283 "e",
284 "f",
285 "",
286 NULL
287 };
288
289 FOREACH_WORD(w, l, test, state) {
290 assert_se(strneq(expected[i++], w, l));
291 }
292}
293
539ad707
TA
294static void test_foreach_word_quoted(void) {
295 char *w, *state;
296 size_t l;
1ef04f0b
TA
297 int i = 0;
298 const char test[] = "test a b c 'd' e '' '' hhh '' '' \"a b c\"";
299 const char * const expected[] = {
300 "test",
301 "a",
302 "b",
303 "c",
304 "d",
305 "e",
306 "",
307 "",
308 "hhh",
309 "",
310 "",
311 "a b c",
312 NULL
313 };
314
539ad707
TA
315 printf("<%s>\n", test);
316 FOREACH_WORD_QUOTED(w, l, test, state) {
1ef04f0b 317 _cleanup_free_ char *t = NULL;
539ad707
TA
318
319 assert_se(t = strndup(w, l));
1ef04f0b 320 assert_se(strneq(expected[i++], w, l));
539ad707 321 printf("<%s>\n", t);
539ad707
TA
322 }
323}
324
325static 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"));
338}
339
0d585d82
TA
340static void test_memdup_multiply(void) {
341 int org[] = {1, 2, 3};
342 int *dup;
343
344 dup = (int*)memdup_multiply(org, sizeof(int), 3);
345
346 assert_se(dup);
347 assert_se(dup[0] == 1);
348 assert_se(dup[1] == 2);
349 assert_se(dup[2] == 3);
350 free(dup);
351}
352
d47c78be
LP
353static void test_bus_path_escape_one(const char *a, const char *b) {
354 _cleanup_free_ char *t = NULL, *x = NULL, *y = NULL;
355
356 assert_se(t = bus_path_escape(a));
357 assert_se(streq(t, b));
358
359 assert_se(x = bus_path_unescape(t));
360 assert_se(streq(a, x));
361
362 assert_se(y = bus_path_unescape(b));
363 assert_se(streq(a, y));
364}
365
366static 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");
374}
375
aa3c5cf8
LP
376static 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"));
387}
388
144e51ec
CR
389static 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);
397}
398
49aa47c7 399static void test_get_process_comm(void) {
143bfdaf 400 struct stat st;
49aa47c7
LP
401 _cleanup_free_ char *a = NULL, *c = NULL, *d = NULL, *f = NULL, *i = NULL;
402 unsigned long long b;
403 pid_t e;
404 uid_t u;
405 gid_t g;
406 dev_t h;
407 int r;
408
143bfdaf
HHPF
409 if (stat("/proc/1/comm", &st) == 0) {
410 assert_se(get_process_comm(1, &a) >= 0);
411 log_info("pid1 comm: '%s'", a);
412 } else {
413 log_warning("/proc/1/comm does not exist.");
414 }
49aa47c7
LP
415
416 assert_se(get_starttime_of_pid(1, &b) >= 0);
417 log_info("pid1 starttime: '%llu'", b);
418
419 assert_se(get_process_cmdline(1, 0, true, &c) >= 0);
420 log_info("pid1 cmdline: '%s'", c);
421
422 assert_se(get_process_cmdline(1, 8, false, &d) >= 0);
423 log_info("pid1 cmdline truncated: '%s'", d);
424
425 assert_se(get_parent_of_pid(1, &e) >= 0);
426 log_info("pid1 ppid: '%llu'", (unsigned long long) e);
427 assert_se(e == 0);
428
429 assert_se(is_kernel_thread(1) == 0);
430
431 r = get_process_exe(1, &f);
432 assert_se(r >= 0 || r == -EACCES);
433 log_info("pid1 exe: '%s'", strna(f));
434
435 assert_se(get_process_uid(1, &u) == 0);
436 log_info("pid1 uid: '%llu'", (unsigned long long) u);
437 assert_se(u == 0);
438
439 assert_se(get_process_gid(1, &g) == 0);
440 log_info("pid1 gid: '%llu'", (unsigned long long) g);
441 assert_se(g == 0);
442
443 assert(get_ctty_devnr(1, &h) == -ENOENT);
444
445 getenv_for_pid(1, "PATH", &i);
446 log_info("pid1 $PATH: '%s'", strna(i));
447}
448
2a371001
ZJS
449static void test_protect_errno(void) {
450 errno = 12;
451 {
452 PROTECT_ERRNO;
453 errno = 11;
454 }
455 assert(errno == 12);
456}
457
b32ff512
ZJS
458static void test_parse_bytes(void) {
459 off_t bytes;
460
461 assert_se(parse_bytes("111", &bytes) == 0);
462 assert_se(bytes == 111);
463
464 assert_se(parse_bytes(" 112 B", &bytes) == 0);
465 assert_se(bytes == 112);
466
467 assert_se(parse_bytes("3 K", &bytes) == 0);
468 assert_se(bytes == 3*1024);
469
470 assert_se(parse_bytes(" 4 M 11K", &bytes) == 0);
471 assert_se(bytes == 4*1024*1024 + 11 * 1024);
472
473 assert_se(parse_bytes("3B3G", &bytes) == 0);
474 assert_se(bytes == 3ULL*1024*1024*1024 + 3);
475
476 assert_se(parse_bytes("3B3G4T", &bytes) == 0);
477 assert_se(bytes == (4ULL*1024 + 3)*1024*1024*1024 + 3);
478
479 assert_se(parse_bytes("12P", &bytes) == 0);
480 assert_se(bytes == 12ULL * 1024*1024*1024*1024*1024);
481
482 assert_se(parse_bytes("3E 2P", &bytes) == 0);
483 assert_se(bytes == (3 * 1024 + 2ULL) * 1024*1024*1024*1024*1024);
484
485 assert_se(parse_bytes("12X", &bytes) == -EINVAL);
486
487 assert_se(parse_bytes("1024E", &bytes) == -ERANGE);
488 assert_se(parse_bytes("-1", &bytes) == -ERANGE);
489 assert_se(parse_bytes("-1024E", &bytes) == -ERANGE);
490
491 assert_se(parse_bytes("-1024P", &bytes) == -ERANGE);
492
493 assert_se(parse_bytes("-10B 20K", &bytes) == -ERANGE);
494}
495
b4ecc959
TA
496static void test_strextend(void) {
497 _cleanup_free_ char *str = strdup("0123");
498 strextend(&str, "456", "78", "9", NULL);
499 assert_se(streq(str, "0123456789"));
500}
501
502static 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);
507
508 assert_se(streq(one, "waldo"));
509 assert_se(streq(three, "waldowaldowaldo"));
510 assert_se(streq(zero, ""));
511}
512
513static 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;
517
518 parse_user_at_host(both, &user, &host);
519 assert_se(streq(user, "waldo"));
520 assert_se(streq(host, "waldoscomputer"));
521
522 user = host = NULL;
523 parse_user_at_host(onlyhost, &user, &host);
524 assert_se(user == NULL);
525 assert_se(streq(host, "mikescomputer"));
526}
527
d4ac85c6
LP
528static void test_split_pair(void) {
529 _cleanup_free_ char *a = NULL, *b = NULL;
530
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"));
537 free(a);
538 free(b);
539 assert_se(split_pair("==", "==", &a, &b) >= 0);
540 assert_se(streq(a, ""));
541 assert_se(streq(b, ""));
542 free(a);
543 free(b);
544
545 assert_se(split_pair("===", "==", &a, &b) >= 0);
546 assert_se(streq(a, ""));
547 assert_se(streq(b, "="));
548}
549
539ad707
TA
550int main(int argc, char *argv[]) {
551 test_streq_ptr();
552 test_first_word();
dbd73f9e 553 test_close_many();
8354c34e 554 test_parse_boolean();
8d99e5f5
TA
555 test_parse_pid();
556 test_parse_uid();
557 test_safe_atolli();
558 test_safe_atod();
dbd73f9e 559 test_strappend();
1ef04f0b
TA
560 test_strstrip();
561 test_delete_chars();
562 test_in_charset();
44f4c86c
DB
563 test_hexchar();
564 test_unhexchar();
565 test_octchar();
566 test_unoctchar();
567 test_decchar();
568 test_undecchar();
b4ecc959
TA
569 test_cescape();
570 test_cunescape();
1ef04f0b 571 test_foreach_word();
539ad707 572 test_foreach_word_quoted();
1ef04f0b 573 test_default_term_for_tty();
0d585d82 574 test_memdup_multiply();
d47c78be 575 test_bus_path_escape();
aa3c5cf8 576 test_hostname_is_valid();
144e51ec 577 test_u64log2();
49aa47c7 578 test_get_process_comm();
2a371001 579 test_protect_errno();
b32ff512 580 test_parse_bytes();
b4ecc959
TA
581 test_strextend();
582 test_strrep();
583 test_parse_user_at_host();
d4ac85c6 584 test_split_pair();
539ad707
TA
585
586 return 0;
587}