]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/test/test-util.c
libudev: fix hwdb validation to look for the *new* file
[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
TA
194static void test_strappend(void) {
195 _cleanup_free_ char *t1, *t2, *t3, *t4;
196
197 t1 = strappend(NULL, NULL);
198 assert_se(streq(t1, ""));
199
200 t2 = strappend(NULL, "suf");
201 assert_se(streq(t2, "suf"));
202
203 t3 = strappend("pre", NULL);
204 assert_se(streq(t3, "pre"));
205
206 t4 = strappend("pre", "suf");
207 assert_se(streq(t4, "presuf"));
208}
209
1ef04f0b
TA
210static void test_strstrip(void) {
211 char *r;
212 char input[] = " hello, waldo. ";
213
214 r = strstrip(input);
215 assert_se(streq(r, "hello, waldo."));
216
217}
218
219static void test_delete_chars(void) {
220 char *r;
221 char input[] = " hello, waldo. abc";
222
223 r = delete_chars(input, WHITESPACE);
224 assert_se(streq(r, "hello,waldo.abc"));
225}
226
227static void test_in_charset(void) {
228 assert_se(in_charset("dddaaabbbcccc", "abcd"));
229 assert_se(!in_charset("dddaaabbbcccc", "abc f"));
230}
231
44f4c86c
DB
232static void test_hexchar(void) {
233 assert_se(hexchar(0xa) == 'a');
234 assert_se(hexchar(0x0) == '0');
235}
236
237static void test_unhexchar(void) {
238 assert_se(unhexchar('a') == 0xA);
239 assert_se(unhexchar('A') == 0xA);
240 assert_se(unhexchar('0') == 0x0);
241}
242
243static void test_octchar(void) {
244 assert_se(octchar(00) == '0');
245 assert_se(octchar(07) == '7');
246}
247
248static void test_unoctchar(void) {
249 assert_se(unoctchar('0') == 00);
250 assert_se(unoctchar('7') == 07);
251}
252
253static void test_decchar(void) {
254 assert_se(decchar(0) == '0');
255 assert_se(decchar(9) == '9');
256}
257
258static void test_undecchar(void) {
259 assert_se(undecchar('0') == 0);
260 assert_se(undecchar('9') == 9);
261}
262
b4ecc959
TA
263static void test_cescape(void) {
264 _cleanup_free_ char *escaped;
265 escaped = cescape("abc\\\"\b\f\n\r\t\v\003\177\234\313");
266 assert_se(streq(escaped, "abc\\\\\\\"\\b\\f\\n\\r\\t\\v\\003\\177\\234\\313"));
267}
268
269static void test_cunescape(void) {
270 _cleanup_free_ char *unescaped;
271 unescaped = cunescape("abc\\\\\\\"\\b\\f\\n\\r\\t\\v\\003\\177\\234\\313");
272 assert_se(streq(unescaped, "abc\\\"\b\f\n\r\t\v\003\177\234\313"));
273}
274
1ef04f0b
TA
275static void test_foreach_word(void) {
276 char *w, *state;
277 size_t l;
278 int i = 0;
279 const char test[] = "test abc d\te f ";
280 const char * const expected[] = {
281 "test",
282 "abc",
283 "d",
284 "e",
285 "f",
286 "",
287 NULL
288 };
289
290 FOREACH_WORD(w, l, test, state) {
291 assert_se(strneq(expected[i++], w, l));
292 }
293}
294
539ad707
TA
295static void test_foreach_word_quoted(void) {
296 char *w, *state;
297 size_t l;
1ef04f0b
TA
298 int i = 0;
299 const char test[] = "test a b c 'd' e '' '' hhh '' '' \"a b c\"";
300 const char * const expected[] = {
301 "test",
302 "a",
303 "b",
304 "c",
305 "d",
306 "e",
307 "",
308 "",
309 "hhh",
310 "",
311 "",
312 "a b c",
313 NULL
314 };
315
539ad707
TA
316 printf("<%s>\n", test);
317 FOREACH_WORD_QUOTED(w, l, test, state) {
1ef04f0b 318 _cleanup_free_ char *t = NULL;
539ad707
TA
319
320 assert_se(t = strndup(w, l));
1ef04f0b 321 assert_se(strneq(expected[i++], w, l));
539ad707 322 printf("<%s>\n", t);
539ad707
TA
323 }
324}
325
326static void test_default_term_for_tty(void) {
327 puts(default_term_for_tty("/dev/tty23"));
328 puts(default_term_for_tty("/dev/ttyS23"));
329 puts(default_term_for_tty("/dev/tty0"));
330 puts(default_term_for_tty("/dev/pty0"));
331 puts(default_term_for_tty("/dev/pts/0"));
332 puts(default_term_for_tty("/dev/console"));
333 puts(default_term_for_tty("tty23"));
334 puts(default_term_for_tty("ttyS23"));
335 puts(default_term_for_tty("tty0"));
336 puts(default_term_for_tty("pty0"));
337 puts(default_term_for_tty("pts/0"));
338 puts(default_term_for_tty("console"));
339}
340
0d585d82
TA
341static void test_memdup_multiply(void) {
342 int org[] = {1, 2, 3};
343 int *dup;
344
345 dup = (int*)memdup_multiply(org, sizeof(int), 3);
346
347 assert_se(dup);
348 assert_se(dup[0] == 1);
349 assert_se(dup[1] == 2);
350 assert_se(dup[2] == 3);
351 free(dup);
352}
353
d47c78be
LP
354static void test_bus_path_escape_one(const char *a, const char *b) {
355 _cleanup_free_ char *t = NULL, *x = NULL, *y = NULL;
356
357 assert_se(t = bus_path_escape(a));
358 assert_se(streq(t, b));
359
360 assert_se(x = bus_path_unescape(t));
361 assert_se(streq(a, x));
362
363 assert_se(y = bus_path_unescape(b));
364 assert_se(streq(a, y));
365}
366
367static void test_bus_path_escape(void) {
368 test_bus_path_escape_one("foo123bar", "foo123bar");
369 test_bus_path_escape_one("foo.bar", "foo_2ebar");
370 test_bus_path_escape_one("foo_2ebar", "foo_5f2ebar");
371 test_bus_path_escape_one("", "_");
372 test_bus_path_escape_one("_", "_5f");
373 test_bus_path_escape_one("1", "_31");
374 test_bus_path_escape_one(":1", "_3a1");
375}
376
aa3c5cf8
LP
377static void test_hostname_is_valid(void) {
378 assert(hostname_is_valid("foobar"));
379 assert(hostname_is_valid("foobar.com"));
380 assert(!hostname_is_valid("fööbar"));
381 assert(!hostname_is_valid(""));
382 assert(!hostname_is_valid("."));
383 assert(!hostname_is_valid(".."));
384 assert(!hostname_is_valid("foobar."));
385 assert(!hostname_is_valid(".foobar"));
386 assert(!hostname_is_valid("foo..bar"));
387 assert(!hostname_is_valid("xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"));
388}
389
144e51ec
CR
390static void test_u64log2(void) {
391 assert(u64log2(0) == 0);
392 assert(u64log2(8) == 3);
393 assert(u64log2(9) == 3);
394 assert(u64log2(15) == 3);
395 assert(u64log2(16) == 4);
396 assert(u64log2(1024*1024) == 20);
397 assert(u64log2(1024*1024+5) == 20);
398}
399
49aa47c7
LP
400static 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;
403 pid_t e;
404 uid_t u;
405 gid_t g;
406 dev_t h;
407 int r;
408
409 assert_se(get_process_comm(1, &a) >= 0);
410 log_info("pid1 comm: '%s'", a);
411
412 assert_se(get_starttime_of_pid(1, &b) >= 0);
413 log_info("pid1 starttime: '%llu'", b);
414
415 assert_se(get_process_cmdline(1, 0, true, &c) >= 0);
416 log_info("pid1 cmdline: '%s'", c);
417
418 assert_se(get_process_cmdline(1, 8, false, &d) >= 0);
419 log_info("pid1 cmdline truncated: '%s'", d);
420
421 assert_se(get_parent_of_pid(1, &e) >= 0);
422 log_info("pid1 ppid: '%llu'", (unsigned long long) e);
423 assert_se(e == 0);
424
425 assert_se(is_kernel_thread(1) == 0);
426
427 r = get_process_exe(1, &f);
428 assert_se(r >= 0 || r == -EACCES);
429 log_info("pid1 exe: '%s'", strna(f));
430
431 assert_se(get_process_uid(1, &u) == 0);
432 log_info("pid1 uid: '%llu'", (unsigned long long) u);
433 assert_se(u == 0);
434
435 assert_se(get_process_gid(1, &g) == 0);
436 log_info("pid1 gid: '%llu'", (unsigned long long) g);
437 assert_se(g == 0);
438
439 assert(get_ctty_devnr(1, &h) == -ENOENT);
440
441 getenv_for_pid(1, "PATH", &i);
442 log_info("pid1 $PATH: '%s'", strna(i));
443}
444
2a371001
ZJS
445static void test_protect_errno(void) {
446 errno = 12;
447 {
448 PROTECT_ERRNO;
449 errno = 11;
450 }
451 assert(errno == 12);
452}
453
b32ff512
ZJS
454static void test_parse_bytes(void) {
455 off_t bytes;
456
457 assert_se(parse_bytes("111", &bytes) == 0);
458 assert_se(bytes == 111);
459
460 assert_se(parse_bytes(" 112 B", &bytes) == 0);
461 assert_se(bytes == 112);
462
463 assert_se(parse_bytes("3 K", &bytes) == 0);
464 assert_se(bytes == 3*1024);
465
466 assert_se(parse_bytes(" 4 M 11K", &bytes) == 0);
467 assert_se(bytes == 4*1024*1024 + 11 * 1024);
468
469 assert_se(parse_bytes("3B3G", &bytes) == 0);
470 assert_se(bytes == 3ULL*1024*1024*1024 + 3);
471
472 assert_se(parse_bytes("3B3G4T", &bytes) == 0);
473 assert_se(bytes == (4ULL*1024 + 3)*1024*1024*1024 + 3);
474
475 assert_se(parse_bytes("12P", &bytes) == 0);
476 assert_se(bytes == 12ULL * 1024*1024*1024*1024*1024);
477
478 assert_se(parse_bytes("3E 2P", &bytes) == 0);
479 assert_se(bytes == (3 * 1024 + 2ULL) * 1024*1024*1024*1024*1024);
480
481 assert_se(parse_bytes("12X", &bytes) == -EINVAL);
482
483 assert_se(parse_bytes("1024E", &bytes) == -ERANGE);
484 assert_se(parse_bytes("-1", &bytes) == -ERANGE);
485 assert_se(parse_bytes("-1024E", &bytes) == -ERANGE);
486
487 assert_se(parse_bytes("-1024P", &bytes) == -ERANGE);
488
489 assert_se(parse_bytes("-10B 20K", &bytes) == -ERANGE);
490}
491
b4ecc959
TA
492static void test_strextend(void) {
493 _cleanup_free_ char *str = strdup("0123");
494 strextend(&str, "456", "78", "9", NULL);
495 assert_se(streq(str, "0123456789"));
496}
497
498static void test_strrep(void) {
499 _cleanup_free_ char *one, *three, *zero;
500 one = strrep("waldo", 1);
501 three = strrep("waldo", 3);
502 zero = strrep("waldo", 0);
503
504 assert_se(streq(one, "waldo"));
505 assert_se(streq(three, "waldowaldowaldo"));
506 assert_se(streq(zero, ""));
507}
508
509static void test_parse_user_at_host(void) {
510 _cleanup_free_ char *both = strdup("waldo@waldoscomputer");
511 _cleanup_free_ char *onlyhost = strdup("mikescomputer");
512 char *user = NULL, *host = NULL;
513
514 parse_user_at_host(both, &user, &host);
515 assert_se(streq(user, "waldo"));
516 assert_se(streq(host, "waldoscomputer"));
517
518 user = host = NULL;
519 parse_user_at_host(onlyhost, &user, &host);
520 assert_se(user == NULL);
521 assert_se(streq(host, "mikescomputer"));
522}
523
d4ac85c6
LP
524static void test_split_pair(void) {
525 _cleanup_free_ char *a = NULL, *b = NULL;
526
527 assert_se(split_pair("", "", &a, &b) == -EINVAL);
528 assert_se(split_pair("foo=bar", "", &a, &b) == -EINVAL);
529 assert_se(split_pair("", "=", &a, &b) == -EINVAL);
530 assert_se(split_pair("foo=bar", "=", &a, &b) >= 0);
531 assert_se(streq(a, "foo"));
532 assert_se(streq(b, "bar"));
533 free(a);
534 free(b);
535 assert_se(split_pair("==", "==", &a, &b) >= 0);
536 assert_se(streq(a, ""));
537 assert_se(streq(b, ""));
538 free(a);
539 free(b);
540
541 assert_se(split_pair("===", "==", &a, &b) >= 0);
542 assert_se(streq(a, ""));
543 assert_se(streq(b, "="));
544}
545
539ad707
TA
546int main(int argc, char *argv[]) {
547 test_streq_ptr();
548 test_first_word();
dbd73f9e 549 test_close_many();
8354c34e 550 test_parse_boolean();
8d99e5f5
TA
551 test_parse_pid();
552 test_parse_uid();
553 test_safe_atolli();
554 test_safe_atod();
dbd73f9e 555 test_strappend();
1ef04f0b
TA
556 test_strstrip();
557 test_delete_chars();
558 test_in_charset();
44f4c86c
DB
559 test_hexchar();
560 test_unhexchar();
561 test_octchar();
562 test_unoctchar();
563 test_decchar();
564 test_undecchar();
b4ecc959
TA
565 test_cescape();
566 test_cunescape();
1ef04f0b 567 test_foreach_word();
539ad707 568 test_foreach_word_quoted();
1ef04f0b 569 test_default_term_for_tty();
0d585d82 570 test_memdup_multiply();
d47c78be 571 test_bus_path_escape();
aa3c5cf8 572 test_hostname_is_valid();
144e51ec 573 test_u64log2();
49aa47c7 574 test_get_process_comm();
2a371001 575 test_protect_errno();
b32ff512 576 test_parse_bytes();
b4ecc959
TA
577 test_strextend();
578 test_strrep();
579 test_parse_user_at_host();
d4ac85c6 580 test_split_pair();
539ad707
TA
581
582 return 0;
583}