]> git.ipfire.org Git - thirdparty/systemd.git/blob - src/test/test-util.c
test-path-util,test-sched-prio: uninitialize manager to appease valgrind
[thirdparty/systemd.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
29 #include "util.h"
30
31 static void test_streq_ptr(void) {
32 assert_se(streq_ptr(NULL, NULL));
33 assert_se(!streq_ptr("abc", "cdef"));
34 }
35
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"));
44
45 assert_se(!first_word("Hello", "Hellooo"));
46 assert_se(!first_word("Hello", "xxxxx"));
47 assert_se(!first_word("Hellooo", "Hello"));
48 }
49
50 static 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
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);
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);
96 }
97
98 static 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
126 static 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
135 static 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
147 static void test_safe_atod(void) {
148 int r;
149 double d;
150 char *e;
151
152 r = safe_atod("junk", &d);
153 assert_se(r == -EINVAL);
154
155 r = safe_atod("0.2244", &d);
156 assert_se(r == 0);
157 assert_se(abs(d - 0.2244) < 0.000001);
158
159 r = safe_atod("0,5", &d);
160 assert_se(r == -EINVAL);
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 == ',');
192 }
193
194 static 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
210 static 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
219 static 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
227 static void test_in_charset(void) {
228 assert_se(in_charset("dddaaabbbcccc", "abcd"));
229 assert_se(!in_charset("dddaaabbbcccc", "abc f"));
230 }
231
232 static void test_hexchar(void) {
233 assert_se(hexchar(0xa) == 'a');
234 assert_se(hexchar(0x0) == '0');
235 }
236
237 static void test_unhexchar(void) {
238 assert_se(unhexchar('a') == 0xA);
239 assert_se(unhexchar('A') == 0xA);
240 assert_se(unhexchar('0') == 0x0);
241 }
242
243 static void test_octchar(void) {
244 assert_se(octchar(00) == '0');
245 assert_se(octchar(07) == '7');
246 }
247
248 static void test_unoctchar(void) {
249 assert_se(unoctchar('0') == 00);
250 assert_se(unoctchar('7') == 07);
251 }
252
253 static void test_decchar(void) {
254 assert_se(decchar(0) == '0');
255 assert_se(decchar(9) == '9');
256 }
257
258 static void test_undecchar(void) {
259 assert_se(undecchar('0') == 0);
260 assert_se(undecchar('9') == 9);
261 }
262
263 static void test_foreach_word(void) {
264 char *w, *state;
265 size_t l;
266 int i = 0;
267 const char test[] = "test abc d\te f ";
268 const char * const expected[] = {
269 "test",
270 "abc",
271 "d",
272 "e",
273 "f",
274 "",
275 NULL
276 };
277
278 FOREACH_WORD(w, l, test, state) {
279 assert_se(strneq(expected[i++], w, l));
280 }
281 }
282
283 static void test_foreach_word_quoted(void) {
284 char *w, *state;
285 size_t l;
286 int i = 0;
287 const char test[] = "test a b c 'd' e '' '' hhh '' '' \"a b c\"";
288 const char * const expected[] = {
289 "test",
290 "a",
291 "b",
292 "c",
293 "d",
294 "e",
295 "",
296 "",
297 "hhh",
298 "",
299 "",
300 "a b c",
301 NULL
302 };
303
304 printf("<%s>\n", test);
305 FOREACH_WORD_QUOTED(w, l, test, state) {
306 _cleanup_free_ char *t = NULL;
307
308 assert_se(t = strndup(w, l));
309 assert_se(strneq(expected[i++], w, l));
310 printf("<%s>\n", t);
311 }
312 }
313
314 static void test_default_term_for_tty(void) {
315 puts(default_term_for_tty("/dev/tty23"));
316 puts(default_term_for_tty("/dev/ttyS23"));
317 puts(default_term_for_tty("/dev/tty0"));
318 puts(default_term_for_tty("/dev/pty0"));
319 puts(default_term_for_tty("/dev/pts/0"));
320 puts(default_term_for_tty("/dev/console"));
321 puts(default_term_for_tty("tty23"));
322 puts(default_term_for_tty("ttyS23"));
323 puts(default_term_for_tty("tty0"));
324 puts(default_term_for_tty("pty0"));
325 puts(default_term_for_tty("pts/0"));
326 puts(default_term_for_tty("console"));
327 }
328
329 static void test_memdup_multiply(void) {
330 int org[] = {1, 2, 3};
331 int *dup;
332
333 dup = (int*)memdup_multiply(org, sizeof(int), 3);
334
335 assert_se(dup);
336 assert_se(dup[0] == 1);
337 assert_se(dup[1] == 2);
338 assert_se(dup[2] == 3);
339 free(dup);
340 }
341
342 static void test_bus_path_escape_one(const char *a, const char *b) {
343 _cleanup_free_ char *t = NULL, *x = NULL, *y = NULL;
344
345 assert_se(t = bus_path_escape(a));
346 assert_se(streq(t, b));
347
348 assert_se(x = bus_path_unescape(t));
349 assert_se(streq(a, x));
350
351 assert_se(y = bus_path_unescape(b));
352 assert_se(streq(a, y));
353 }
354
355 static void test_bus_path_escape(void) {
356 test_bus_path_escape_one("foo123bar", "foo123bar");
357 test_bus_path_escape_one("foo.bar", "foo_2ebar");
358 test_bus_path_escape_one("foo_2ebar", "foo_5f2ebar");
359 test_bus_path_escape_one("", "_");
360 test_bus_path_escape_one("_", "_5f");
361 test_bus_path_escape_one("1", "_31");
362 test_bus_path_escape_one(":1", "_3a1");
363 }
364
365 static void test_hostname_is_valid(void) {
366 assert(hostname_is_valid("foobar"));
367 assert(hostname_is_valid("foobar.com"));
368 assert(!hostname_is_valid("fööbar"));
369 assert(!hostname_is_valid(""));
370 assert(!hostname_is_valid("."));
371 assert(!hostname_is_valid(".."));
372 assert(!hostname_is_valid("foobar."));
373 assert(!hostname_is_valid(".foobar"));
374 assert(!hostname_is_valid("foo..bar"));
375 assert(!hostname_is_valid("xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"));
376 }
377
378 static void test_u64log2(void) {
379 assert(u64log2(0) == 0);
380 assert(u64log2(8) == 3);
381 assert(u64log2(9) == 3);
382 assert(u64log2(15) == 3);
383 assert(u64log2(16) == 4);
384 assert(u64log2(1024*1024) == 20);
385 assert(u64log2(1024*1024+5) == 20);
386 }
387
388 static void test_get_process_comm(void) {
389 _cleanup_free_ char *a = NULL, *c = NULL, *d = NULL, *f = NULL, *i = NULL;
390 unsigned long long b;
391 pid_t e;
392 uid_t u;
393 gid_t g;
394 dev_t h;
395 int r;
396
397 assert_se(get_process_comm(1, &a) >= 0);
398 log_info("pid1 comm: '%s'", a);
399
400 assert_se(get_starttime_of_pid(1, &b) >= 0);
401 log_info("pid1 starttime: '%llu'", b);
402
403 assert_se(get_process_cmdline(1, 0, true, &c) >= 0);
404 log_info("pid1 cmdline: '%s'", c);
405
406 assert_se(get_process_cmdline(1, 8, false, &d) >= 0);
407 log_info("pid1 cmdline truncated: '%s'", d);
408
409 assert_se(get_parent_of_pid(1, &e) >= 0);
410 log_info("pid1 ppid: '%llu'", (unsigned long long) e);
411 assert_se(e == 0);
412
413 assert_se(is_kernel_thread(1) == 0);
414
415 r = get_process_exe(1, &f);
416 assert_se(r >= 0 || r == -EACCES);
417 log_info("pid1 exe: '%s'", strna(f));
418
419 assert_se(get_process_uid(1, &u) == 0);
420 log_info("pid1 uid: '%llu'", (unsigned long long) u);
421 assert_se(u == 0);
422
423 assert_se(get_process_gid(1, &g) == 0);
424 log_info("pid1 gid: '%llu'", (unsigned long long) g);
425 assert_se(g == 0);
426
427 assert(get_ctty_devnr(1, &h) == -ENOENT);
428
429 getenv_for_pid(1, "PATH", &i);
430 log_info("pid1 $PATH: '%s'", strna(i));
431 }
432
433 static void test_protect_errno(void) {
434 errno = 12;
435 {
436 PROTECT_ERRNO;
437 errno = 11;
438 }
439 assert(errno == 12);
440 }
441
442 static void test_parse_bytes(void) {
443 off_t bytes;
444
445 assert_se(parse_bytes("111", &bytes) == 0);
446 assert_se(bytes == 111);
447
448 assert_se(parse_bytes(" 112 B", &bytes) == 0);
449 assert_se(bytes == 112);
450
451 assert_se(parse_bytes("3 K", &bytes) == 0);
452 assert_se(bytes == 3*1024);
453
454 assert_se(parse_bytes(" 4 M 11K", &bytes) == 0);
455 assert_se(bytes == 4*1024*1024 + 11 * 1024);
456
457 assert_se(parse_bytes("3B3G", &bytes) == 0);
458 assert_se(bytes == 3ULL*1024*1024*1024 + 3);
459
460 assert_se(parse_bytes("3B3G4T", &bytes) == 0);
461 assert_se(bytes == (4ULL*1024 + 3)*1024*1024*1024 + 3);
462
463 assert_se(parse_bytes("12P", &bytes) == 0);
464 assert_se(bytes == 12ULL * 1024*1024*1024*1024*1024);
465
466 assert_se(parse_bytes("3E 2P", &bytes) == 0);
467 assert_se(bytes == (3 * 1024 + 2ULL) * 1024*1024*1024*1024*1024);
468
469 assert_se(parse_bytes("12X", &bytes) == -EINVAL);
470
471 assert_se(parse_bytes("1024E", &bytes) == -ERANGE);
472 assert_se(parse_bytes("-1", &bytes) == -ERANGE);
473 assert_se(parse_bytes("-1024E", &bytes) == -ERANGE);
474
475 assert_se(parse_bytes("-1024P", &bytes) == -ERANGE);
476
477 assert_se(parse_bytes("-10B 20K", &bytes) == -ERANGE);
478 }
479
480 int main(int argc, char *argv[]) {
481 test_streq_ptr();
482 test_first_word();
483 test_close_many();
484 test_parse_boolean();
485 test_parse_pid();
486 test_parse_uid();
487 test_safe_atolli();
488 test_safe_atod();
489 test_strappend();
490 test_strstrip();
491 test_delete_chars();
492 test_in_charset();
493 test_hexchar();
494 test_unhexchar();
495 test_octchar();
496 test_unoctchar();
497 test_decchar();
498 test_undecchar();
499 test_foreach_word();
500 test_foreach_word_quoted();
501 test_default_term_for_tty();
502 test_memdup_multiply();
503 test_bus_path_escape();
504 test_hostname_is_valid();
505 test_u64log2();
506 test_get_process_comm();
507 test_protect_errno();
508 test_parse_bytes();
509
510 return 0;
511 }