chiark / gitweb /
Prep v233.3: Add all possible coverage tests for elogind
[elogind.git] / src / test / test-parse-util.c
1 /***
2   This file is part of systemd.
3
4   Copyright 2010 Lennart Poettering
5   Copyright 2013 Thomas H.P. Andersen
6
7   systemd is free software; you can redistribute it and/or modify it
8   under the terms of the GNU Lesser General Public License as published by
9   the Free Software Foundation; either version 2.1 of the License, or
10   (at your option) any later version.
11
12   systemd is distributed in the hope that it will be useful, but
13   WITHOUT ANY WARRANTY; without even the implied warranty of
14   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15   Lesser General Public License for more details.
16
17   You should have received a copy of the GNU Lesser General Public License
18   along with systemd; If not, see <http://www.gnu.org/licenses/>.
19 ***/
20
21 #include <locale.h>
22 #include <math.h>
23
24 #include "log.h"
25 #include "parse-util.h"
26
27 static void test_parse_boolean(void) {
28         assert_se(parse_boolean("1") == 1);
29         assert_se(parse_boolean("y") == 1);
30         assert_se(parse_boolean("Y") == 1);
31         assert_se(parse_boolean("yes") == 1);
32         assert_se(parse_boolean("YES") == 1);
33         assert_se(parse_boolean("true") == 1);
34         assert_se(parse_boolean("TRUE") == 1);
35         assert_se(parse_boolean("on") == 1);
36         assert_se(parse_boolean("ON") == 1);
37
38         assert_se(parse_boolean("0") == 0);
39         assert_se(parse_boolean("n") == 0);
40         assert_se(parse_boolean("N") == 0);
41         assert_se(parse_boolean("no") == 0);
42         assert_se(parse_boolean("NO") == 0);
43         assert_se(parse_boolean("false") == 0);
44         assert_se(parse_boolean("FALSE") == 0);
45         assert_se(parse_boolean("off") == 0);
46         assert_se(parse_boolean("OFF") == 0);
47
48         assert_se(parse_boolean("garbage") < 0);
49         assert_se(parse_boolean("") < 0);
50         assert_se(parse_boolean("full") < 0);
51 }
52
53 static void test_parse_pid(void) {
54         int r;
55         pid_t pid;
56
57         r = parse_pid("100", &pid);
58         assert_se(r == 0);
59         assert_se(pid == 100);
60
61         r = parse_pid("0x7FFFFFFF", &pid);
62         assert_se(r == 0);
63         assert_se(pid == 2147483647);
64
65         pid = 65; /* pid is left unchanged on ERANGE. Set to known arbitrary value. */
66         r = parse_pid("0", &pid);
67         assert_se(r == -ERANGE);
68         assert_se(pid == 65);
69
70         pid = 65; /* pid is left unchanged on ERANGE. Set to known arbitrary value. */
71         r = parse_pid("-100", &pid);
72         assert_se(r == -ERANGE);
73         assert_se(pid == 65);
74
75         pid = 65; /* pid is left unchanged on ERANGE. Set to known arbitrary value. */
76         r = parse_pid("0xFFFFFFFFFFFFFFFFF", &pid);
77         assert_se(r == -ERANGE);
78         assert_se(pid == 65);
79
80         r = parse_pid("junk", &pid);
81         assert_se(r == -EINVAL);
82 }
83
84 static void test_parse_mode(void) {
85         mode_t m;
86
87         assert_se(parse_mode("-1", &m) < 0);
88         assert_se(parse_mode("", &m) < 0);
89         assert_se(parse_mode("888", &m) < 0);
90         assert_se(parse_mode("77777", &m) < 0);
91
92         assert_se(parse_mode("544", &m) >= 0 && m == 0544);
93         assert_se(parse_mode("777", &m) >= 0 && m == 0777);
94         assert_se(parse_mode("7777", &m) >= 0 && m == 07777);
95         assert_se(parse_mode("0", &m) >= 0 && m == 0);
96 }
97
98 static void test_parse_size(void) {
99         uint64_t bytes;
100
101         assert_se(parse_size("111", 1024, &bytes) == 0);
102         assert_se(bytes == 111);
103
104         assert_se(parse_size("111.4", 1024, &bytes) == 0);
105         assert_se(bytes == 111);
106
107         assert_se(parse_size(" 112 B", 1024, &bytes) == 0);
108         assert_se(bytes == 112);
109
110         assert_se(parse_size(" 112.6 B", 1024, &bytes) == 0);
111         assert_se(bytes == 112);
112
113         assert_se(parse_size("3.5 K", 1024, &bytes) == 0);
114         assert_se(bytes == 3*1024 + 512);
115
116         assert_se(parse_size("3. K", 1024, &bytes) == 0);
117         assert_se(bytes == 3*1024);
118
119         assert_se(parse_size("3.0 K", 1024, &bytes) == 0);
120         assert_se(bytes == 3*1024);
121
122         assert_se(parse_size("3. 0 K", 1024, &bytes) == -EINVAL);
123
124         assert_se(parse_size(" 4 M 11.5K", 1024, &bytes) == 0);
125         assert_se(bytes == 4*1024*1024 + 11 * 1024 + 512);
126
127         assert_se(parse_size("3B3.5G", 1024, &bytes) == -EINVAL);
128
129         assert_se(parse_size("3.5G3B", 1024, &bytes) == 0);
130         assert_se(bytes == 3ULL*1024*1024*1024 + 512*1024*1024 + 3);
131
132         assert_se(parse_size("3.5G 4B", 1024, &bytes) == 0);
133         assert_se(bytes == 3ULL*1024*1024*1024 + 512*1024*1024 + 4);
134
135         assert_se(parse_size("3B3G4T", 1024, &bytes) == -EINVAL);
136
137         assert_se(parse_size("4T3G3B", 1024, &bytes) == 0);
138         assert_se(bytes == (4ULL*1024 + 3)*1024*1024*1024 + 3);
139
140         assert_se(parse_size(" 4 T 3 G 3 B", 1024, &bytes) == 0);
141         assert_se(bytes == (4ULL*1024 + 3)*1024*1024*1024 + 3);
142
143         assert_se(parse_size("12P", 1024, &bytes) == 0);
144         assert_se(bytes == 12ULL * 1024*1024*1024*1024*1024);
145
146         assert_se(parse_size("12P12P", 1024, &bytes) == -EINVAL);
147
148         assert_se(parse_size("3E 2P", 1024, &bytes) == 0);
149         assert_se(bytes == (3 * 1024 + 2ULL) * 1024*1024*1024*1024*1024);
150
151         assert_se(parse_size("12X", 1024, &bytes) == -EINVAL);
152
153         assert_se(parse_size("12.5X", 1024, &bytes) == -EINVAL);
154
155         assert_se(parse_size("12.5e3", 1024, &bytes) == -EINVAL);
156
157         assert_se(parse_size("1024E", 1024, &bytes) == -ERANGE);
158         assert_se(parse_size("-1", 1024, &bytes) == -ERANGE);
159         assert_se(parse_size("-1024E", 1024, &bytes) == -ERANGE);
160
161         assert_se(parse_size("-1024P", 1024, &bytes) == -ERANGE);
162
163         assert_se(parse_size("-10B 20K", 1024, &bytes) == -ERANGE);
164 }
165
166 #if 0 /// UNNEEDED by elogind
167 static void test_parse_range(void) {
168         unsigned lower, upper;
169
170         /* Successful cases */
171         assert_se(parse_range("111", &lower, &upper) == 0);
172         assert_se(lower == 111);
173         assert_se(upper == 111);
174
175         assert_se(parse_range("111-123", &lower, &upper) == 0);
176         assert_se(lower == 111);
177         assert_se(upper == 123);
178
179         assert_se(parse_range("123-111", &lower, &upper) == 0);
180         assert_se(lower == 123);
181         assert_se(upper == 111);
182
183         assert_se(parse_range("123-123", &lower, &upper) == 0);
184         assert_se(lower == 123);
185         assert_se(upper == 123);
186
187         assert_se(parse_range("0", &lower, &upper) == 0);
188         assert_se(lower == 0);
189         assert_se(upper == 0);
190
191         assert_se(parse_range("0-15", &lower, &upper) == 0);
192         assert_se(lower == 0);
193         assert_se(upper == 15);
194
195         assert_se(parse_range("15-0", &lower, &upper) == 0);
196         assert_se(lower == 15);
197         assert_se(upper == 0);
198
199         assert_se(parse_range("128-65535", &lower, &upper) == 0);
200         assert_se(lower == 128);
201         assert_se(upper == 65535);
202
203         assert_se(parse_range("1024-4294967295", &lower, &upper) == 0);
204         assert_se(lower == 1024);
205         assert_se(upper == 4294967295);
206
207         /* Leading whitespace is acceptable */
208         assert_se(parse_range(" 111", &lower, &upper) == 0);
209         assert_se(lower == 111);
210         assert_se(upper == 111);
211
212         assert_se(parse_range(" 111-123", &lower, &upper) == 0);
213         assert_se(lower == 111);
214         assert_se(upper == 123);
215
216         assert_se(parse_range("111- 123", &lower, &upper) == 0);
217         assert_se(lower == 111);
218         assert_se(upper == 123);
219
220         assert_se(parse_range("\t111-\t123", &lower, &upper) == 0);
221         assert_se(lower == 111);
222         assert_se(upper == 123);
223
224         assert_se(parse_range(" \t 111- \t 123", &lower, &upper) == 0);
225         assert_se(lower == 111);
226         assert_se(upper == 123);
227
228         /* Error cases, make sure they fail as expected */
229         lower = upper = 9999;
230         assert_se(parse_range("111garbage", &lower, &upper) == -EINVAL);
231         assert_se(lower == 9999);
232         assert_se(upper == 9999);
233
234         assert_se(parse_range("garbage111", &lower, &upper) == -EINVAL);
235         assert_se(lower == 9999);
236         assert_se(upper == 9999);
237
238         assert_se(parse_range("garbage", &lower, &upper) == -EINVAL);
239         assert_se(lower == 9999);
240         assert_se(upper == 9999);
241
242         assert_se(parse_range("111-123garbage", &lower, &upper) == -EINVAL);
243         assert_se(lower == 9999);
244         assert_se(upper == 9999);
245
246         assert_se(parse_range("111garbage-123", &lower, &upper) == -EINVAL);
247         assert_se(lower == 9999);
248         assert_se(upper == 9999);
249
250         /* Empty string */
251         lower = upper = 9999;
252         assert_se(parse_range("", &lower, &upper) == -EINVAL);
253         assert_se(lower == 9999);
254         assert_se(upper == 9999);
255
256         /* 111--123 will pass -123 to safe_atou which returns -ERANGE for negative */
257         assert_se(parse_range("111--123", &lower, &upper) == -ERANGE);
258         assert_se(lower == 9999);
259         assert_se(upper == 9999);
260
261         assert_se(parse_range("-111-123", &lower, &upper) == -EINVAL);
262         assert_se(lower == 9999);
263         assert_se(upper == 9999);
264
265         assert_se(parse_range("111-123-", &lower, &upper) == -EINVAL);
266         assert_se(lower == 9999);
267         assert_se(upper == 9999);
268
269         assert_se(parse_range("111.4-123", &lower, &upper) == -EINVAL);
270         assert_se(lower == 9999);
271         assert_se(upper == 9999);
272
273         assert_se(parse_range("111-123.4", &lower, &upper) == -EINVAL);
274         assert_se(lower == 9999);
275         assert_se(upper == 9999);
276
277         assert_se(parse_range("111,4-123", &lower, &upper) == -EINVAL);
278         assert_se(lower == 9999);
279         assert_se(upper == 9999);
280
281         assert_se(parse_range("111-123,4", &lower, &upper) == -EINVAL);
282         assert_se(lower == 9999);
283         assert_se(upper == 9999);
284
285         /* Error on trailing dash */
286         assert_se(parse_range("111-", &lower, &upper) == -EINVAL);
287         assert_se(lower == 9999);
288         assert_se(upper == 9999);
289
290         assert_se(parse_range("111-123-", &lower, &upper) == -EINVAL);
291         assert_se(lower == 9999);
292         assert_se(upper == 9999);
293
294         assert_se(parse_range("111--", &lower, &upper) == -EINVAL);
295         assert_se(lower == 9999);
296         assert_se(upper == 9999);
297
298         assert_se(parse_range("111- ", &lower, &upper) == -EINVAL);
299         assert_se(lower == 9999);
300         assert_se(upper == 9999);
301
302         /* Whitespace is not a separator */
303         assert_se(parse_range("111 123", &lower, &upper) == -EINVAL);
304         assert_se(lower == 9999);
305         assert_se(upper == 9999);
306
307         assert_se(parse_range("111\t123", &lower, &upper) == -EINVAL);
308         assert_se(lower == 9999);
309         assert_se(upper == 9999);
310
311         assert_se(parse_range("111 \t 123", &lower, &upper) == -EINVAL);
312         assert_se(lower == 9999);
313         assert_se(upper == 9999);
314
315         /* Trailing whitespace is invalid (from safe_atou) */
316         assert_se(parse_range("111 ", &lower, &upper) == -EINVAL);
317         assert_se(lower == 9999);
318         assert_se(upper == 9999);
319
320         assert_se(parse_range("111-123 ", &lower, &upper) == -EINVAL);
321         assert_se(lower == 9999);
322         assert_se(upper == 9999);
323
324         assert_se(parse_range("111 -123", &lower, &upper) == -EINVAL);
325         assert_se(lower == 9999);
326         assert_se(upper == 9999);
327
328         assert_se(parse_range("111 -123 ", &lower, &upper) == -EINVAL);
329         assert_se(lower == 9999);
330         assert_se(upper == 9999);
331
332         assert_se(parse_range("111\t-123\t", &lower, &upper) == -EINVAL);
333         assert_se(lower == 9999);
334         assert_se(upper == 9999);
335
336         assert_se(parse_range("111 \t -123 \t ", &lower, &upper) == -EINVAL);
337         assert_se(lower == 9999);
338         assert_se(upper == 9999);
339
340         /* Out of the "unsigned" range, this is 1<<64 */
341         assert_se(parse_range("0-18446744073709551616", &lower, &upper) == -ERANGE);
342         assert_se(lower == 9999);
343         assert_se(upper == 9999);
344 }
345 #endif // 0
346
347 static void test_safe_atolli(void) {
348         int r;
349         long long l;
350
351         r = safe_atolli("12345", &l);
352         assert_se(r == 0);
353         assert_se(l == 12345);
354
355         r = safe_atolli("  12345", &l);
356         assert_se(r == 0);
357         assert_se(l == 12345);
358
359         r = safe_atolli("-12345", &l);
360         assert_se(r == 0);
361         assert_se(l == -12345);
362
363         r = safe_atolli("  -12345", &l);
364         assert_se(r == 0);
365         assert_se(l == -12345);
366
367         r = safe_atolli("12345678901234567890", &l);
368         assert_se(r == -ERANGE);
369
370         r = safe_atolli("-12345678901234567890", &l);
371         assert_se(r == -ERANGE);
372
373         r = safe_atolli("junk", &l);
374         assert_se(r == -EINVAL);
375 }
376
377 static void test_safe_atou16(void) {
378         int r;
379         uint16_t l;
380
381         r = safe_atou16("12345", &l);
382         assert_se(r == 0);
383         assert_se(l == 12345);
384
385         r = safe_atou16("  12345", &l);
386         assert_se(r == 0);
387         assert_se(l == 12345);
388
389         r = safe_atou16("123456", &l);
390         assert_se(r == -ERANGE);
391
392         r = safe_atou16("-1", &l);
393         assert_se(r == -ERANGE);
394
395         r = safe_atou16("  -1", &l);
396         assert_se(r == -ERANGE);
397
398         r = safe_atou16("junk", &l);
399         assert_se(r == -EINVAL);
400 }
401
402 static void test_safe_atoi16(void) {
403         int r;
404         int16_t l;
405
406         r = safe_atoi16("-12345", &l);
407         assert_se(r == 0);
408         assert_se(l == -12345);
409
410         r = safe_atoi16("  -12345", &l);
411         assert_se(r == 0);
412         assert_se(l == -12345);
413
414         r = safe_atoi16("32767", &l);
415         assert_se(r == 0);
416         assert_se(l == 32767);
417
418         r = safe_atoi16("  32767", &l);
419         assert_se(r == 0);
420         assert_se(l == 32767);
421
422         r = safe_atoi16("36536", &l);
423         assert_se(r == -ERANGE);
424
425         r = safe_atoi16("-32769", &l);
426         assert_se(r == -ERANGE);
427
428         r = safe_atoi16("junk", &l);
429         assert_se(r == -EINVAL);
430 }
431
432 static void test_safe_atod(void) {
433         int r;
434         double d;
435         char *e;
436
437         r = safe_atod("junk", &d);
438         assert_se(r == -EINVAL);
439
440         r = safe_atod("0.2244", &d);
441         assert_se(r == 0);
442         assert_se(fabs(d - 0.2244) < 0.000001);
443
444         r = safe_atod("0,5", &d);
445         assert_se(r == -EINVAL);
446
447         errno = 0;
448         strtod("0,5", &e);
449         assert_se(*e == ',');
450
451         /* Check if this really is locale independent */
452         if (setlocale(LC_NUMERIC, "de_DE.utf8")) {
453
454                 r = safe_atod("0.2244", &d);
455                 assert_se(r == 0);
456                 assert_se(fabs(d - 0.2244) < 0.000001);
457
458                 r = safe_atod("0,5", &d);
459                 assert_se(r == -EINVAL);
460
461                 errno = 0;
462                 assert_se(fabs(strtod("0,5", &e) - 0.5) < 0.00001);
463         }
464
465         /* And check again, reset */
466         assert_se(setlocale(LC_NUMERIC, "C"));
467
468         r = safe_atod("0.2244", &d);
469         assert_se(r == 0);
470         assert_se(fabs(d - 0.2244) < 0.000001);
471
472         r = safe_atod("0,5", &d);
473         assert_se(r == -EINVAL);
474
475         errno = 0;
476         strtod("0,5", &e);
477         assert_se(*e == ',');
478 }
479
480 static void test_parse_percent(void) {
481         assert_se(parse_percent("") == -EINVAL);
482         assert_se(parse_percent("foo") == -EINVAL);
483         assert_se(parse_percent("0") == -EINVAL);
484         assert_se(parse_percent("50") == -EINVAL);
485         assert_se(parse_percent("100") == -EINVAL);
486         assert_se(parse_percent("-1") == -EINVAL);
487         assert_se(parse_percent("0%") == 0);
488         assert_se(parse_percent("55%") == 55);
489         assert_se(parse_percent("100%") == 100);
490         assert_se(parse_percent("-7%") == -ERANGE);
491         assert_se(parse_percent("107%") == -ERANGE);
492         assert_se(parse_percent("%") == -EINVAL);
493         assert_se(parse_percent("%%") == -EINVAL);
494         assert_se(parse_percent("%1") == -EINVAL);
495         assert_se(parse_percent("1%%") == -EINVAL);
496 }
497
498 static void test_parse_percent_unbounded(void) {
499         assert_se(parse_percent_unbounded("101%") == 101);
500         assert_se(parse_percent_unbounded("400%") == 400);
501 }
502
503 #if 0 /// UNNEEDED by elogind
504 static void test_parse_nice(void) {
505         int n;
506
507         assert_se(parse_nice("0", &n) >= 0 && n == 0);
508         assert_se(parse_nice("+0", &n) >= 0 && n == 0);
509         assert_se(parse_nice("-1", &n) >= 0 && n == -1);
510         assert_se(parse_nice("-2", &n) >= 0 && n == -2);
511         assert_se(parse_nice("1", &n) >= 0 && n == 1);
512         assert_se(parse_nice("2", &n) >= 0 && n == 2);
513         assert_se(parse_nice("+1", &n) >= 0 && n == 1);
514         assert_se(parse_nice("+2", &n) >= 0 && n == 2);
515         assert_se(parse_nice("-20", &n) >= 0 && n == -20);
516         assert_se(parse_nice("19", &n) >= 0 && n == 19);
517         assert_se(parse_nice("+19", &n) >= 0 && n == 19);
518
519
520         assert_se(parse_nice("", &n) == -EINVAL);
521         assert_se(parse_nice("-", &n) == -EINVAL);
522         assert_se(parse_nice("+", &n) == -EINVAL);
523         assert_se(parse_nice("xx", &n) == -EINVAL);
524         assert_se(parse_nice("-50", &n) == -ERANGE);
525         assert_se(parse_nice("50", &n) == -ERANGE);
526         assert_se(parse_nice("+50", &n) == -ERANGE);
527         assert_se(parse_nice("-21", &n) == -ERANGE);
528         assert_se(parse_nice("20", &n) == -ERANGE);
529         assert_se(parse_nice("+20", &n) == -ERANGE);
530 }
531 #endif // 0
532
533 int main(int argc, char *argv[]) {
534         log_parse_environment();
535         log_open();
536
537         test_parse_boolean();
538         test_parse_pid();
539         test_parse_mode();
540         test_parse_size();
541 #if 0 /// UNNEEDED by elogind
542         test_parse_range();
543 #endif // 0
544         test_safe_atolli();
545         test_safe_atou16();
546         test_safe_atoi16();
547         test_safe_atod();
548         test_parse_percent();
549         test_parse_percent_unbounded();
550 #if 0 /// UNNEEDED by elogind
551         test_parse_nice();
552 #endif // 0
553
554         return 0;
555 }