]> git.ipfire.org Git - thirdparty/systemd.git/blob - src/test/test-condition.c
nulstr-util: Declare NULSTR_FOREACH() iterator inline
[thirdparty/systemd.git] / src / test / test-condition.c
1 /* SPDX-License-Identifier: LGPL-2.1-or-later */
2
3 #include <stdio.h>
4 #include <sys/types.h>
5 #include <sys/utsname.h>
6 #include <unistd.h>
7
8 #include "sd-id128.h"
9
10 #include "alloc-util.h"
11 #include "apparmor-util.h"
12 #include "architecture.h"
13 #include "audit-util.h"
14 #include "cgroup-util.h"
15 #include "condition.h"
16 #include "cpu-set-util.h"
17 #include "efi-loader.h"
18 #include "env-util.h"
19 #include "errno-util.h"
20 #include "fileio.h"
21 #include "fs-util.h"
22 #include "hostname-util.h"
23 #include "id128-util.h"
24 #include "ima-util.h"
25 #include "limits-util.h"
26 #include "log.h"
27 #include "macro.h"
28 #include "nulstr-util.h"
29 #include "os-util.h"
30 #include "path-util.h"
31 #include "process-util.h"
32 #include "psi-util.h"
33 #include "rm-rf.h"
34 #include "selinux-util.h"
35 #include "set.h"
36 #include "smack-util.h"
37 #include "string-util.h"
38 #include "strv.h"
39 #include "tests.h"
40 #include "tmpfile-util.h"
41 #include "tomoyo-util.h"
42 #include "udev-util.h"
43 #include "uid-alloc-range.h"
44 #include "user-util.h"
45 #include "virt.h"
46
47 TEST(condition_test_path) {
48 Condition *condition;
49
50 condition = condition_new(CONDITION_PATH_EXISTS, "/bin/sh", false, false);
51 assert_se(condition);
52 assert_se(condition_test(condition, environ) > 0);
53 condition_free(condition);
54
55 condition = condition_new(CONDITION_PATH_EXISTS, "/bin/s?", false, false);
56 assert_se(condition);
57 assert_se(condition_test(condition, environ) == 0);
58 condition_free(condition);
59
60 condition = condition_new(CONDITION_PATH_EXISTS_GLOB, "/bin/s?", false, false);
61 assert_se(condition);
62 assert_se(condition_test(condition, environ) > 0);
63 condition_free(condition);
64
65 condition = condition_new(CONDITION_PATH_EXISTS_GLOB, "/bin/s?", false, true);
66 assert_se(condition);
67 assert_se(condition_test(condition, environ) == 0);
68 condition_free(condition);
69
70 condition = condition_new(CONDITION_PATH_EXISTS, "/thiscertainlywontexist", false, false);
71 assert_se(condition);
72 assert_se(condition_test(condition, environ) == 0);
73 condition_free(condition);
74
75 condition = condition_new(CONDITION_PATH_EXISTS, "/thiscertainlywontexist", false, true);
76 assert_se(condition);
77 assert_se(condition_test(condition, environ) > 0);
78 condition_free(condition);
79
80 condition = condition_new(CONDITION_PATH_IS_DIRECTORY, "/bin", false, false);
81 assert_se(condition);
82 assert_se(condition_test(condition, environ) > 0);
83 condition_free(condition);
84
85 condition = condition_new(CONDITION_DIRECTORY_NOT_EMPTY, "/bin", false, false);
86 assert_se(condition);
87 assert_se(condition_test(condition, environ) > 0);
88 condition_free(condition);
89
90 condition = condition_new(CONDITION_FILE_NOT_EMPTY, "/bin/sh", false, false);
91 assert_se(condition);
92 assert_se(condition_test(condition, environ) > 0);
93 condition_free(condition);
94
95 condition = condition_new(CONDITION_FILE_IS_EXECUTABLE, "/bin/sh", false, false);
96 assert_se(condition);
97 assert_se(condition_test(condition, environ) > 0);
98 condition_free(condition);
99
100 condition = condition_new(CONDITION_FILE_IS_EXECUTABLE, "/etc/passwd", false, false);
101 assert_se(condition);
102 assert_se(condition_test(condition, environ) == 0);
103 condition_free(condition);
104
105 condition = condition_new(CONDITION_PATH_IS_MOUNT_POINT, "/proc", false, false);
106 assert_se(condition);
107 assert_se(condition_test(condition, environ) > 0);
108 condition_free(condition);
109
110 condition = condition_new(CONDITION_PATH_IS_MOUNT_POINT, "/", false, false);
111 assert_se(condition);
112 assert_se(condition_test(condition, environ) > 0);
113 condition_free(condition);
114
115 condition = condition_new(CONDITION_PATH_IS_MOUNT_POINT, "/bin", false, false);
116 assert_se(condition);
117 assert_se(condition_test(condition, environ) == 0);
118 condition_free(condition);
119
120 condition = condition_new(CONDITION_PATH_IS_READ_WRITE, "/tmp", false, false);
121 assert_se(condition);
122 assert_se(condition_test(condition, environ) > 0);
123 condition_free(condition);
124
125 condition = condition_new(CONDITION_PATH_IS_ENCRYPTED, "/sys", false, false);
126 assert_se(condition);
127 assert_se(condition_test(condition, environ) == 0);
128 condition_free(condition);
129
130 condition = condition_new(CONDITION_PATH_IS_SYMBOLIC_LINK, "/dev/stdout", false, false);
131 assert_se(condition);
132 assert_se(condition_test(condition, environ) > 0);
133 condition_free(condition);
134 }
135
136 TEST(condition_test_control_group_hierarchy) {
137 Condition *condition;
138 int r;
139
140 r = cg_unified();
141 if (r == -ENOMEDIUM) {
142 log_tests_skipped("cgroup not mounted");
143 return;
144 }
145 assert_se(r >= 0);
146
147 condition = condition_new(CONDITION_CONTROL_GROUP_CONTROLLER, "v1", false, false);
148 assert_se(condition);
149 assert_se(condition_test(condition, environ) == (r < CGROUP_UNIFIED_ALL));
150 condition_free(condition);
151
152 condition = condition_new(CONDITION_CONTROL_GROUP_CONTROLLER, "v2", false, false);
153 assert_se(condition);
154 assert_se(condition_test(condition, environ) == (r >= CGROUP_UNIFIED_ALL));
155 condition_free(condition);
156 }
157
158 TEST(condition_test_control_group_controller) {
159 Condition *condition;
160 CGroupMask system_mask;
161 _cleanup_free_ char *controller_name = NULL;
162 int r;
163
164 r = cg_unified();
165 if (r == -ENOMEDIUM) {
166 log_tests_skipped("cgroup not mounted");
167 return;
168 }
169 assert_se(r >= 0);
170
171 /* Invalid controllers are ignored */
172 condition = condition_new(CONDITION_CONTROL_GROUP_CONTROLLER, "thisisnotarealcontroller", false, false);
173 assert_se(condition);
174 assert_se(condition_test(condition, environ) > 0);
175 condition_free(condition);
176
177 condition = condition_new(CONDITION_CONTROL_GROUP_CONTROLLER, "thisisnotarealcontroller", false, true);
178 assert_se(condition);
179 assert_se(condition_test(condition, environ) == 0);
180 condition_free(condition);
181
182 assert_se(cg_mask_supported(&system_mask) >= 0);
183
184 /* Individual valid controllers one by one */
185 for (CGroupController controller = 0; controller < _CGROUP_CONTROLLER_MAX; controller++) {
186 const char *local_controller_name = cgroup_controller_to_string(controller);
187 log_info("chosen controller is '%s'", local_controller_name);
188 if (system_mask & CGROUP_CONTROLLER_TO_MASK(controller)) {
189 log_info("this controller is available");
190 condition = condition_new(CONDITION_CONTROL_GROUP_CONTROLLER, local_controller_name, false, false);
191 assert_se(condition);
192 assert_se(condition_test(condition, environ) > 0);
193 condition_free(condition);
194
195 condition = condition_new(CONDITION_CONTROL_GROUP_CONTROLLER, local_controller_name, false, true);
196 assert_se(condition);
197 assert_se(condition_test(condition, environ) == 0);
198 condition_free(condition);
199 } else {
200 log_info("this controller is unavailable");
201 condition = condition_new(CONDITION_CONTROL_GROUP_CONTROLLER, local_controller_name, false, false);
202 assert_se(condition);
203 assert_se(condition_test(condition, environ) == 0);
204 condition_free(condition);
205
206 condition = condition_new(CONDITION_CONTROL_GROUP_CONTROLLER, local_controller_name, false, true);
207 assert_se(condition);
208 assert_se(condition_test(condition, environ) > 0);
209 condition_free(condition);
210 }
211 }
212
213 /* Multiple valid controllers at the same time */
214 assert_se(cg_mask_to_string(system_mask, &controller_name) >= 0);
215
216 condition = condition_new(CONDITION_CONTROL_GROUP_CONTROLLER, strempty(controller_name), false, false);
217 assert_se(condition);
218 assert_se(condition_test(condition, environ) > 0);
219 condition_free(condition);
220
221 condition = condition_new(CONDITION_CONTROL_GROUP_CONTROLLER, strempty(controller_name), false, true);
222 assert_se(condition);
223 assert_se(condition_test(condition, environ) == 0);
224 condition_free(condition);
225 }
226
227 TEST(condition_test_ac_power) {
228 Condition *condition;
229
230 condition = condition_new(CONDITION_AC_POWER, "true", false, false);
231 assert_se(condition);
232 assert_se(condition_test(condition, environ) == on_ac_power());
233 condition_free(condition);
234
235 condition = condition_new(CONDITION_AC_POWER, "false", false, false);
236 assert_se(condition);
237 assert_se(condition_test(condition, environ) != on_ac_power());
238 condition_free(condition);
239
240 condition = condition_new(CONDITION_AC_POWER, "false", false, true);
241 assert_se(condition);
242 assert_se(condition_test(condition, environ) == on_ac_power());
243 condition_free(condition);
244 }
245
246 TEST(condition_test_host) {
247 _cleanup_free_ char *hostname = NULL;
248 Condition *condition;
249 sd_id128_t id;
250 int r;
251
252 r = sd_id128_get_machine(&id);
253 if (IN_SET(r, -ENOENT, -ENOMEDIUM))
254 return (void) log_tests_skipped("/etc/machine-id missing");
255 assert_se(r >= 0);
256
257 condition = condition_new(CONDITION_HOST, SD_ID128_TO_STRING(id), false, false);
258 assert_se(condition);
259 assert_se(condition_test(condition, environ) > 0);
260 condition_free(condition);
261
262 condition = condition_new(CONDITION_HOST, "garbage value jjjjjjjjjjjjjj", false, false);
263 assert_se(condition);
264 assert_se(condition_test(condition, environ) == 0);
265 condition_free(condition);
266
267 condition = condition_new(CONDITION_HOST, SD_ID128_TO_STRING(id), false, true);
268 assert_se(condition);
269 assert_se(condition_test(condition, environ) == 0);
270 condition_free(condition);
271
272 hostname = gethostname_malloc();
273 assert_se(hostname);
274
275 /* if hostname looks like an id128 then skip testing it */
276 if (id128_is_valid(hostname))
277 log_notice("hostname is an id128, skipping test");
278 else {
279 condition = condition_new(CONDITION_HOST, hostname, false, false);
280 assert_se(condition);
281 assert_se(condition_test(condition, environ) > 0);
282 condition_free(condition);
283 }
284 }
285
286 TEST(condition_test_architecture) {
287 Condition *condition;
288 const char *sa;
289 Architecture a;
290
291 a = uname_architecture();
292 assert_se(a >= 0);
293
294 sa = architecture_to_string(a);
295 assert_se(sa);
296
297 condition = condition_new(CONDITION_ARCHITECTURE, sa, false, false);
298 assert_se(condition);
299 assert_se(condition_test(condition, environ) > 0);
300 condition_free(condition);
301
302 condition = condition_new(CONDITION_ARCHITECTURE, "garbage value", false, false);
303 assert_se(condition);
304 assert_se(condition_test(condition, environ) == 0);
305 condition_free(condition);
306
307 condition = condition_new(CONDITION_ARCHITECTURE, sa, false, true);
308 assert_se(condition);
309 assert_se(condition_test(condition, environ) == 0);
310 condition_free(condition);
311 }
312
313 TEST(condition_test_firmware) {
314 Condition *condition;
315
316 /* Empty parameter */
317 condition = condition_new(CONDITION_FIRMWARE, "", false, false);
318 assert_se(condition);
319 assert_se(condition_test(condition, environ) == 0);
320 condition_free(condition);
321
322 /* uefi parameter */
323 condition = condition_new(CONDITION_FIRMWARE, "uefi", false, false);
324 assert_se(condition);
325 assert_se(condition_test(condition, environ) == is_efi_boot());
326 condition_free(condition);
327 }
328
329 TEST(condition_test_firmware_device_tree) {
330 Condition *condition;
331 bool is_device_tree_system;
332
333 /* device-tree parameter */
334 is_device_tree_system = (access("/sys/firmware/devicetree/", F_OK) == 0);
335
336 condition = condition_new(CONDITION_FIRMWARE, "device-tree", false, false);
337 assert_se(condition);
338 assert_se(condition_test(condition, environ) == is_device_tree_system);
339 condition_free(condition);
340
341 /* device-tree-compatible parameter */
342 if (!is_device_tree_system) {
343 condition = condition_new(CONDITION_FIRMWARE, "device-tree-compatible()", false, false);
344 assert_se(condition);
345 assert_se(condition_test(condition, environ) == 0);
346 condition_free(condition);
347 } else {
348 _cleanup_free_ char *dtcompat = NULL;
349 _cleanup_strv_free_ char **dtcompatlist = NULL;
350 size_t dtcompat_size;
351 int r;
352
353 r = read_full_virtual_file("/proc/device-tree/compatible", &dtcompat, &dtcompat_size);
354 if (r < 0) {
355 condition = condition_new(CONDITION_FIRMWARE, "device-tree-compatible()", false, false);
356 assert_se(condition);
357 if (r == -ENOENT)
358 assert_se(condition_test(condition, environ) == 0);
359 else
360 assert_se(condition_test(condition, environ) < 0);
361 condition_free(condition);
362 return;
363 }
364
365 dtcompatlist = strv_parse_nulstr(dtcompat, dtcompat_size);
366
367 STRV_FOREACH(c, dtcompatlist) {
368 _cleanup_free_ char *expression = NULL;
369
370 assert_se(expression = strjoin("device-tree-compatible(", *c, ")"));
371 condition = condition_new(CONDITION_FIRMWARE, expression, false, false);
372 assert_se(condition);
373 assert_se(condition_test(condition, environ) > 0);
374 condition_free(condition);
375 }
376 }
377 }
378
379 TEST(condition_test_firmware_smbios) {
380 Condition *condition;
381 _cleanup_free_ char *bios_vendor = NULL, *bios_version = NULL;
382 const char *expression;
383
384 /* smbios-field parameter */
385 /* Test some malformed smbios-field arguments */
386 condition = condition_new(CONDITION_FIRMWARE, "smbios-field()", false, false);
387 assert_se(condition);
388 assert_se(condition_test(condition, environ) == -EINVAL);
389 condition_free(condition);
390
391 condition = condition_new(CONDITION_FIRMWARE, "smbios-field(malformed)", false, false);
392 assert_se(condition);
393 assert_se(condition_test(condition, environ) == -EINVAL);
394 condition_free(condition);
395
396 condition = condition_new(CONDITION_FIRMWARE, "smbios-field(malformed", false, false);
397 assert_se(condition);
398 assert_se(condition_test(condition, environ) == -EINVAL);
399 condition_free(condition);
400
401 condition = condition_new(CONDITION_FIRMWARE, "smbios-field(malformed=)", false, false);
402 assert_se(condition);
403 assert_se(condition_test(condition, environ) == -EINVAL);
404 condition_free(condition);
405
406 condition = condition_new(CONDITION_FIRMWARE, "smbios-field(malformed=)", false, false);
407 assert_se(condition);
408 assert_se(condition_test(condition, environ) == -EINVAL);
409 condition_free(condition);
410
411 condition = condition_new(CONDITION_FIRMWARE, "smbios-field(not_existing=nothing garbage)", false, false);
412 assert_se(condition);
413 assert_se(condition_test(condition, environ) == -EINVAL);
414 condition_free(condition);
415
416 /* Test not existing SMBIOS field */
417 condition = condition_new(CONDITION_FIRMWARE, "smbios-field(not_existing=nothing)", false, false);
418 assert_se(condition);
419 assert_se(condition_test(condition, environ) == 0);
420 condition_free(condition);
421
422 /* Test with bios_vendor, if available */
423 if (read_virtual_file("/sys/class/dmi/id/bios_vendor", SIZE_MAX, &bios_vendor, NULL) <= 0)
424 return;
425
426 /* remove trailing newline */
427 strstrip(bios_vendor);
428
429 /* Check if the bios_vendor contains any spaces we should quote */
430 const char *quote = strchr(bios_vendor, ' ') ? "\"" : "";
431
432 /* Test equality / inequality using fnmatch() */
433 expression = strjoina("smbios-field(bios_vendor $= ", quote, bios_vendor, quote, ")");
434 condition = condition_new(CONDITION_FIRMWARE, expression, false, false);
435 assert_se(condition);
436 assert_se(condition_test(condition, environ) > 0);
437 condition_free(condition);
438
439 expression = strjoina("smbios-field(bios_vendor$=", quote, bios_vendor, quote, ")");
440 condition = condition_new(CONDITION_FIRMWARE, expression, false, false);
441 assert_se(condition);
442 assert_se(condition_test(condition, environ) > 0);
443 condition_free(condition);
444
445 expression = strjoina("smbios-field(bios_vendor !$= ", quote, bios_vendor, quote, ")");
446 condition = condition_new(CONDITION_FIRMWARE, expression, false, false);
447 assert_se(condition);
448 assert_se(condition_test(condition, environ) == 0);
449 condition_free(condition);
450
451 expression = strjoina("smbios-field(bios_vendor!$=", quote, bios_vendor, quote, ")");
452 condition = condition_new(CONDITION_FIRMWARE, expression, false, false);
453 assert_se(condition);
454 assert_se(condition_test(condition, environ) == 0);
455 condition_free(condition);
456
457 expression = strjoina("smbios-field(bios_vendor $= ", quote, bios_vendor, "*", quote, ")");
458 condition = condition_new(CONDITION_FIRMWARE, expression, false, false);
459 assert_se(condition);
460 assert_se(condition_test(condition, environ) > 0);
461 condition_free(condition);
462
463 /* Test version comparison with bios_version, if available */
464 if (read_virtual_file("/sys/class/dmi/id/bios_version", SIZE_MAX, &bios_version, NULL) <= 0)
465 return;
466
467 /* remove trailing newline */
468 strstrip(bios_version);
469
470 /* Check if the bios_version contains any spaces we should quote */
471 quote = strchr(bios_version, ' ') ? "\"" : "";
472
473 expression = strjoina("smbios-field(bios_version = ", quote, bios_version, quote, ")");
474 condition = condition_new(CONDITION_FIRMWARE, expression, false, false);
475 assert_se(condition);
476 assert_se(condition_test(condition, environ) > 0);
477 condition_free(condition);
478
479 expression = strjoina("smbios-field(bios_version != ", quote, bios_version, quote, ")");
480 condition = condition_new(CONDITION_FIRMWARE, expression, false, false);
481 assert_se(condition);
482 assert_se(condition_test(condition, environ) == 0);
483 condition_free(condition);
484
485 expression = strjoina("smbios-field(bios_version <= ", quote, bios_version, quote, ")");
486 condition = condition_new(CONDITION_FIRMWARE, expression, false, false);
487 assert_se(condition);
488 assert_se(condition_test(condition, environ) > 0);
489 condition_free(condition);
490
491 expression = strjoina("smbios-field(bios_version >= ", quote, bios_version, quote, ")");
492 condition = condition_new(CONDITION_FIRMWARE, expression, false, false);
493 assert_se(condition);
494 assert_se(condition_test(condition, environ) > 0);
495 condition_free(condition);
496
497 expression = strjoina("smbios-field(bios_version < ", quote, bios_version, ".1", quote, ")");
498 condition = condition_new(CONDITION_FIRMWARE, expression, false, false);
499 assert_se(condition);
500 assert_se(condition_test(condition, environ) > 0);
501 condition_free(condition);
502
503 expression = strjoina("smbios-field(bios_version > ", quote, bios_version, ".1", quote, ")");
504 condition = condition_new(CONDITION_FIRMWARE, expression, false, false);
505 assert_se(condition);
506 assert_se(condition_test(condition, environ) == 0);
507 condition_free(condition);
508 }
509
510 TEST(condition_test_kernel_command_line) {
511 Condition *condition;
512 int r;
513
514 condition = condition_new(CONDITION_KERNEL_COMMAND_LINE, "thisreallyshouldntbeonthekernelcommandline", false, false);
515 assert_se(condition);
516 r = condition_test(condition, environ);
517 if (ERRNO_IS_PRIVILEGE(r))
518 return;
519 assert_se(r == 0);
520 condition_free(condition);
521
522 condition = condition_new(CONDITION_KERNEL_COMMAND_LINE, "andthis=neither", false, false);
523 assert_se(condition);
524 assert_se(condition_test(condition, environ) == 0);
525 condition_free(condition);
526 }
527
528 TEST(condition_test_kernel_version) {
529 Condition *condition;
530 struct utsname u;
531 const char *v;
532
533 condition = condition_new(CONDITION_KERNEL_VERSION, "*thisreallyshouldntbeinthekernelversion*", false, false);
534 assert_se(condition);
535 assert_se(condition_test(condition, environ) == 0);
536 condition_free(condition);
537
538 condition = condition_new(CONDITION_KERNEL_VERSION, "*", false, false);
539 assert_se(condition);
540 assert_se(condition_test(condition, environ) > 0);
541 condition_free(condition);
542
543 /* An artificially empty condition. It evaluates to true, but normally
544 * such condition cannot be created, because the condition list is reset instead. */
545 condition = condition_new(CONDITION_KERNEL_VERSION, "", false, false);
546 assert_se(condition);
547 assert_se(condition_test(condition, environ) > 0);
548 condition_free(condition);
549
550 assert_se(uname(&u) >= 0);
551
552 condition = condition_new(CONDITION_KERNEL_VERSION, u.release, false, false);
553 assert_se(condition);
554 assert_se(condition_test(condition, environ) > 0);
555 condition_free(condition);
556
557 strshorten(u.release, 4);
558 strcpy(strchr(u.release, 0), "*");
559
560 condition = condition_new(CONDITION_KERNEL_VERSION, u.release, false, false);
561 assert_se(condition);
562 assert_se(condition_test(condition, environ) > 0);
563 condition_free(condition);
564
565 /* 0.1.2 would be a very very very old kernel */
566 condition = condition_new(CONDITION_KERNEL_VERSION, "> 0.1.2", false, false);
567 assert_se(condition);
568 assert_se(condition_test(condition, environ) > 0);
569 condition_free(condition);
570
571 condition = condition_new(CONDITION_KERNEL_VERSION, ">0.1.2", false, false);
572 assert_se(condition);
573 assert_se(condition_test(condition, environ) > 0);
574 condition_free(condition);
575
576 condition = condition_new(CONDITION_KERNEL_VERSION, "'>0.1.2' '<9.0.0'", false, false);
577 assert_se(condition);
578 assert_se(condition_test(condition, environ) > 0);
579 condition_free(condition);
580
581 condition = condition_new(CONDITION_KERNEL_VERSION, "> 0.1.2 < 9.0.0", false, false);
582 assert_se(condition);
583 assert_se(condition_test(condition, environ) == -EINVAL);
584 condition_free(condition);
585
586 condition = condition_new(CONDITION_KERNEL_VERSION, ">", false, false);
587 assert_se(condition);
588 assert_se(condition_test(condition, environ) == -EINVAL);
589 condition_free(condition);
590
591 condition = condition_new(CONDITION_KERNEL_VERSION, ">= 0.1.2", false, false);
592 assert_se(condition);
593 assert_se(condition_test(condition, environ) > 0);
594 condition_free(condition);
595
596 condition = condition_new(CONDITION_KERNEL_VERSION, "< 0.1.2", false, false);
597 assert_se(condition);
598 assert_se(condition_test(condition, environ) == 0);
599 condition_free(condition);
600
601 condition = condition_new(CONDITION_KERNEL_VERSION, "<= 0.1.2", false, false);
602 assert_se(condition);
603 assert_se(condition_test(condition, environ) == 0);
604 condition_free(condition);
605
606 condition = condition_new(CONDITION_KERNEL_VERSION, "= 0.1.2", false, false);
607 assert_se(condition);
608 assert_se(condition_test(condition, environ) == 0);
609 condition_free(condition);
610
611 /* 4711.8.15 is a very very very future kernel */
612 condition = condition_new(CONDITION_KERNEL_VERSION, "< 4711.8.15", false, false);
613 assert_se(condition);
614 assert_se(condition_test(condition, environ) > 0);
615 condition_free(condition);
616
617 condition = condition_new(CONDITION_KERNEL_VERSION, "<= 4711.8.15", false, false);
618 assert_se(condition);
619 assert_se(condition_test(condition, environ) > 0);
620 condition_free(condition);
621
622 condition = condition_new(CONDITION_KERNEL_VERSION, "= 4711.8.15", false, false);
623 assert_se(condition);
624 assert_se(condition_test(condition, environ) == 0);
625 condition_free(condition);
626
627 condition = condition_new(CONDITION_KERNEL_VERSION, "> 4711.8.15", false, false);
628 assert_se(condition);
629 assert_se(condition_test(condition, environ) == 0);
630 condition_free(condition);
631
632 condition = condition_new(CONDITION_KERNEL_VERSION, " >= 4711.8.15", false, false);
633 assert_se(condition);
634 assert_se(condition_test(condition, environ) == 0);
635 condition_free(condition);
636
637 assert_se(uname(&u) >= 0);
638
639 v = strjoina(">=", u.release);
640 condition = condition_new(CONDITION_KERNEL_VERSION, v, false, false);
641 assert_se(condition);
642 assert_se(condition_test(condition, environ) > 0);
643 condition_free(condition);
644
645 v = strjoina("= ", u.release);
646 condition = condition_new(CONDITION_KERNEL_VERSION, v, false, false);
647 assert_se(condition);
648 assert_se(condition_test(condition, environ) > 0);
649 condition_free(condition);
650
651 v = strjoina("<=", u.release);
652 condition = condition_new(CONDITION_KERNEL_VERSION, v, false, false);
653 assert_se(condition);
654 assert_se(condition_test(condition, environ) > 0);
655 condition_free(condition);
656
657 v = strjoina("> ", u.release);
658 condition = condition_new(CONDITION_KERNEL_VERSION, v, false, false);
659 assert_se(condition);
660 assert_se(condition_test(condition, environ) == 0);
661 condition_free(condition);
662
663 v = strjoina("< ", u.release);
664 condition = condition_new(CONDITION_KERNEL_VERSION, v, false, false);
665 assert_se(condition);
666 assert_se(condition_test(condition, environ) == 0);
667 condition_free(condition);
668 }
669
670 TEST(condition_test_credential) {
671 _cleanup_(rm_rf_physical_and_freep) char *n1 = NULL, *n2 = NULL;
672 _cleanup_free_ char *d1 = NULL, *d2 = NULL, *j = NULL;
673 Condition *condition;
674
675 assert_se(free_and_strdup(&d1, getenv("CREDENTIALS_DIRECTORY")) >= 0);
676 assert_se(free_and_strdup(&d2, getenv("ENCRYPTED_CREDENTIALS_DIRECTORY")) >= 0);
677
678 assert_se(unsetenv("CREDENTIALS_DIRECTORY") >= 0);
679 assert_se(unsetenv("ENCRYPTED_CREDENTIALS_DIRECTORY") >= 0);
680
681 condition = condition_new(CONDITION_CREDENTIAL, "definitelymissing", /* trigger= */ false, /* negate= */ false);
682 assert_se(condition);
683 assert_se(condition_test(condition, environ) == 0);
684 condition_free(condition);
685
686 /* invalid */
687 condition = condition_new(CONDITION_CREDENTIAL, "..", /* trigger= */ false, /* negate= */ false);
688 assert_se(condition);
689 assert_se(condition_test(condition, environ) == 0);
690 condition_free(condition);
691
692 assert_se(mkdtemp_malloc(NULL, &n1) >= 0);
693 assert_se(mkdtemp_malloc(NULL, &n2) >= 0);
694
695 assert_se(setenv("CREDENTIALS_DIRECTORY", n1, /* overwrite= */ true) >= 0);
696 assert_se(setenv("ENCRYPTED_CREDENTIALS_DIRECTORY", n2, /* overwrite= */ true) >= 0);
697
698 condition = condition_new(CONDITION_CREDENTIAL, "stillmissing", /* trigger= */ false, /* negate= */ false);
699 assert_se(condition);
700 assert_se(condition_test(condition, environ) == 0);
701 condition_free(condition);
702
703 assert_se(j = path_join(n1, "existing"));
704 assert_se(touch(j) >= 0);
705 assert_se(j);
706 condition = condition_new(CONDITION_CREDENTIAL, "existing", /* trigger= */ false, /* negate= */ false);
707 assert_se(condition);
708 assert_se(condition_test(condition, environ) > 0);
709 condition_free(condition);
710 free(j);
711
712 assert_se(j = path_join(n2, "existing-encrypted"));
713 assert_se(touch(j) >= 0);
714 assert_se(j);
715 condition = condition_new(CONDITION_CREDENTIAL, "existing-encrypted", /* trigger= */ false, /* negate= */ false);
716 assert_se(condition);
717 assert_se(condition_test(condition, environ) > 0);
718 condition_free(condition);
719
720 assert_se(set_unset_env("CREDENTIALS_DIRECTORY", d1, /* overwrite= */ true) >= 0);
721 assert_se(set_unset_env("ENCRYPTED_CREDENTIALS_DIRECTORY", d2, /* overwrite= */ true) >= 0);
722 }
723
724 #if defined(__i386__) || defined(__x86_64__)
725 TEST(condition_test_cpufeature) {
726 Condition *condition;
727
728 condition = condition_new(CONDITION_CPU_FEATURE, "fpu", false, false);
729 assert_se(condition);
730 assert_se(condition_test(condition, environ) > 0);
731 condition_free(condition);
732
733 condition = condition_new(CONDITION_CPU_FEATURE, "somecpufeaturethatreallydoesntmakesense", false, false);
734 assert_se(condition);
735 assert_se(condition_test(condition, environ) == 0);
736 condition_free(condition);
737
738 condition = condition_new(CONDITION_CPU_FEATURE, "a", false, false);
739 assert_se(condition);
740 assert_se(condition_test(condition, environ) == 0);
741 condition_free(condition);
742 }
743 #endif
744
745 TEST(condition_test_security) {
746 Condition *condition;
747
748 condition = condition_new(CONDITION_SECURITY, "garbage oifdsjfoidsjoj", false, false);
749 assert_se(condition);
750 assert_se(condition_test(condition, environ) == 0);
751 condition_free(condition);
752
753 condition = condition_new(CONDITION_SECURITY, "selinux", false, true);
754 assert_se(condition);
755 assert_se(condition_test(condition, environ) != mac_selinux_use());
756 condition_free(condition);
757
758 condition = condition_new(CONDITION_SECURITY, "apparmor", false, false);
759 assert_se(condition);
760 assert_se(condition_test(condition, environ) == mac_apparmor_use());
761 condition_free(condition);
762
763 condition = condition_new(CONDITION_SECURITY, "tomoyo", false, false);
764 assert_se(condition);
765 assert_se(condition_test(condition, environ) == mac_tomoyo_use());
766 condition_free(condition);
767
768 condition = condition_new(CONDITION_SECURITY, "ima", false, false);
769 assert_se(condition);
770 assert_se(condition_test(condition, environ) == use_ima());
771 condition_free(condition);
772
773 condition = condition_new(CONDITION_SECURITY, "smack", false, false);
774 assert_se(condition);
775 assert_se(condition_test(condition, environ) == mac_smack_use());
776 condition_free(condition);
777
778 condition = condition_new(CONDITION_SECURITY, "audit", false, false);
779 assert_se(condition);
780 assert_se(condition_test(condition, environ) == use_audit());
781 condition_free(condition);
782
783 condition = condition_new(CONDITION_SECURITY, "uefi-secureboot", false, false);
784 assert_se(condition);
785 assert_se(condition_test(condition, environ) == is_efi_secure_boot());
786 condition_free(condition);
787 }
788
789 TEST(print_securities) {
790 log_info("------ enabled security technologies ------");
791 log_info("SELinux: %s", yes_no(mac_selinux_use()));
792 log_info("AppArmor: %s", yes_no(mac_apparmor_use()));
793 log_info("Tomoyo: %s", yes_no(mac_tomoyo_use()));
794 log_info("IMA: %s", yes_no(use_ima()));
795 log_info("SMACK: %s", yes_no(mac_smack_use()));
796 log_info("Audit: %s", yes_no(use_audit()));
797 log_info("UEFI secure boot: %s", yes_no(is_efi_secure_boot()));
798 log_info("-------------------------------------------");
799 }
800
801 TEST(condition_test_virtualization) {
802 Condition *condition;
803 int r;
804
805 condition = condition_new(CONDITION_VIRTUALIZATION, "garbage oifdsjfoidsjoj", false, false);
806 assert_se(condition);
807 r = condition_test(condition, environ);
808 if (ERRNO_IS_PRIVILEGE(r))
809 return;
810 log_info("ConditionVirtualization=garbage → %i", r);
811 assert_se(r == 0);
812 condition_free(condition);
813
814 condition = condition_new(CONDITION_VIRTUALIZATION, "container", false, false);
815 assert_se(condition);
816 r = condition_test(condition, environ);
817 log_info("ConditionVirtualization=container → %i", r);
818 assert_se(r == !!detect_container());
819 condition_free(condition);
820
821 condition = condition_new(CONDITION_VIRTUALIZATION, "vm", false, false);
822 assert_se(condition);
823 r = condition_test(condition, environ);
824 log_info("ConditionVirtualization=vm → %i", r);
825 assert_se(r == (detect_vm() && !detect_container()));
826 condition_free(condition);
827
828 condition = condition_new(CONDITION_VIRTUALIZATION, "private-users", false, false);
829 assert_se(condition);
830 r = condition_test(condition, environ);
831 log_info("ConditionVirtualization=private-users → %i", r);
832 assert_se(r == !!running_in_userns());
833 condition_free(condition);
834
835 NULSTR_FOREACH(virt,
836 "kvm\0"
837 "amazon\0"
838 "qemu\0"
839 "bochs\0"
840 "xen\0"
841 "uml\0"
842 "vmware\0"
843 "oracle\0"
844 "microsoft\0"
845 "zvm\0"
846 "parallels\0"
847 "bhyve\0"
848 "vm_other\0") {
849
850 condition = condition_new(CONDITION_VIRTUALIZATION, virt, false, false);
851 assert_se(condition);
852 r = condition_test(condition, environ);
853 log_info("ConditionVirtualization=%s → %i", virt, r);
854 assert_se(r >= 0);
855 condition_free(condition);
856 }
857 }
858
859 TEST(condition_test_user) {
860 Condition *condition;
861 char* uid;
862 char* username;
863 int r;
864
865 condition = condition_new(CONDITION_USER, "garbage oifdsjfoidsjoj", false, false);
866 assert_se(condition);
867 r = condition_test(condition, environ);
868 log_info("ConditionUser=garbage → %i", r);
869 assert_se(r == 0);
870 condition_free(condition);
871
872 assert_se(asprintf(&uid, "%"PRIu32, UINT32_C(0xFFFF)) > 0);
873 condition = condition_new(CONDITION_USER, uid, false, false);
874 assert_se(condition);
875 r = condition_test(condition, environ);
876 log_info("ConditionUser=%s → %i", uid, r);
877 assert_se(r == 0);
878 condition_free(condition);
879 free(uid);
880
881 assert_se(asprintf(&uid, "%u", (unsigned)getuid()) > 0);
882 condition = condition_new(CONDITION_USER, uid, false, false);
883 assert_se(condition);
884 r = condition_test(condition, environ);
885 log_info("ConditionUser=%s → %i", uid, r);
886 assert_se(r > 0);
887 condition_free(condition);
888 free(uid);
889
890 assert_se(asprintf(&uid, "%u", (unsigned)getuid()+1) > 0);
891 condition = condition_new(CONDITION_USER, uid, false, false);
892 assert_se(condition);
893 r = condition_test(condition, environ);
894 log_info("ConditionUser=%s → %i", uid, r);
895 assert_se(r == 0);
896 condition_free(condition);
897 free(uid);
898
899 username = getusername_malloc();
900 assert_se(username);
901 condition = condition_new(CONDITION_USER, username, false, false);
902 assert_se(condition);
903 r = condition_test(condition, environ);
904 log_info("ConditionUser=%s → %i", username, r);
905 assert_se(r > 0);
906 condition_free(condition);
907 free(username);
908
909 username = (char*)(geteuid() == 0 ? NOBODY_USER_NAME : "root");
910 condition = condition_new(CONDITION_USER, username, false, false);
911 assert_se(condition);
912 r = condition_test(condition, environ);
913 log_info("ConditionUser=%s → %i", username, r);
914 assert_se(r == 0);
915 condition_free(condition);
916
917 condition = condition_new(CONDITION_USER, "@system", false, false);
918 assert_se(condition);
919 r = condition_test(condition, environ);
920 log_info("ConditionUser=@system → %i", r);
921 if (uid_is_system(getuid()) || uid_is_system(geteuid()))
922 assert_se(r > 0);
923 else
924 assert_se(r == 0);
925 condition_free(condition);
926 }
927
928 TEST(condition_test_group) {
929 Condition *condition;
930 char* gid;
931 char* groupname;
932 gid_t *gids, max_gid;
933 int ngroups_max, ngroups, r, i;
934
935 assert_se(0 < asprintf(&gid, "%u", UINT32_C(0xFFFF)));
936 condition = condition_new(CONDITION_GROUP, gid, false, false);
937 assert_se(condition);
938 r = condition_test(condition, environ);
939 log_info("ConditionGroup=%s → %i", gid, r);
940 assert_se(r == 0);
941 condition_free(condition);
942 free(gid);
943
944 assert_se(0 < asprintf(&gid, "%u", getgid()));
945 condition = condition_new(CONDITION_GROUP, gid, false, false);
946 assert_se(condition);
947 r = condition_test(condition, environ);
948 log_info("ConditionGroup=%s → %i", gid, r);
949 assert_se(r > 0);
950 condition_free(condition);
951 free(gid);
952
953 ngroups_max = sysconf(_SC_NGROUPS_MAX);
954 assert_se(ngroups_max > 0);
955
956 gids = newa(gid_t, ngroups_max);
957
958 ngroups = getgroups(ngroups_max, gids);
959 assert_se(ngroups >= 0);
960
961 max_gid = getgid();
962 for (i = 0; i < ngroups; i++) {
963 assert_se(0 < asprintf(&gid, "%u", gids[i]));
964 condition = condition_new(CONDITION_GROUP, gid, false, false);
965 assert_se(condition);
966 r = condition_test(condition, environ);
967 log_info("ConditionGroup=%s → %i", gid, r);
968 assert_se(r > 0);
969 condition_free(condition);
970 free(gid);
971 max_gid = gids[i] > max_gid ? gids[i] : max_gid;
972
973 groupname = gid_to_name(gids[i]);
974 assert_se(groupname);
975 condition = condition_new(CONDITION_GROUP, groupname, false, false);
976 assert_se(condition);
977 r = condition_test(condition, environ);
978 log_info("ConditionGroup=%s → %i", groupname, r);
979 assert_se(r > 0);
980 condition_free(condition);
981 free(groupname);
982 max_gid = gids[i] > max_gid ? gids[i] : max_gid;
983 }
984
985 assert_se(0 < asprintf(&gid, "%u", max_gid+1));
986 condition = condition_new(CONDITION_GROUP, gid, false, false);
987 assert_se(condition);
988 r = condition_test(condition, environ);
989 log_info("ConditionGroup=%s → %i", gid, r);
990 assert_se(r == 0);
991 condition_free(condition);
992 free(gid);
993
994 groupname = (char*)(getegid() == 0 ? NOBODY_GROUP_NAME : "root");
995 condition = condition_new(CONDITION_GROUP, groupname, false, false);
996 assert_se(condition);
997 r = condition_test(condition, environ);
998 log_info("ConditionGroup=%s → %i", groupname, r);
999 assert_se(r == 0);
1000 condition_free(condition);
1001 }
1002
1003 static void test_condition_test_cpus_one(const char *s, bool result) {
1004 Condition *condition;
1005 int r;
1006
1007 log_debug("%s=%s", condition_type_to_string(CONDITION_CPUS), s);
1008
1009 condition = condition_new(CONDITION_CPUS, s, false, false);
1010 assert_se(condition);
1011
1012 r = condition_test(condition, environ);
1013 assert_se(r >= 0);
1014 assert_se(r == result);
1015 condition_free(condition);
1016 }
1017
1018 TEST(condition_test_cpus) {
1019 _cleanup_free_ char *t = NULL;
1020 int cpus;
1021
1022 cpus = cpus_in_affinity_mask();
1023 assert_se(cpus >= 0);
1024
1025 test_condition_test_cpus_one("> 0", true);
1026 test_condition_test_cpus_one(">= 0", true);
1027 test_condition_test_cpus_one("!= 0", true);
1028 test_condition_test_cpus_one("<= 0", false);
1029 test_condition_test_cpus_one("< 0", false);
1030 test_condition_test_cpus_one("= 0", false);
1031
1032 test_condition_test_cpus_one("> 100000", false);
1033 test_condition_test_cpus_one("= 100000", false);
1034 test_condition_test_cpus_one(">= 100000", false);
1035 test_condition_test_cpus_one("< 100000", true);
1036 test_condition_test_cpus_one("!= 100000", true);
1037 test_condition_test_cpus_one("<= 100000", true);
1038
1039 assert_se(asprintf(&t, "= %i", cpus) >= 0);
1040 test_condition_test_cpus_one(t, true);
1041 t = mfree(t);
1042
1043 assert_se(asprintf(&t, "<= %i", cpus) >= 0);
1044 test_condition_test_cpus_one(t, true);
1045 t = mfree(t);
1046
1047 assert_se(asprintf(&t, ">= %i", cpus) >= 0);
1048 test_condition_test_cpus_one(t, true);
1049 t = mfree(t);
1050
1051 assert_se(asprintf(&t, "!= %i", cpus) >= 0);
1052 test_condition_test_cpus_one(t, false);
1053 t = mfree(t);
1054
1055 assert_se(asprintf(&t, "< %i", cpus) >= 0);
1056 test_condition_test_cpus_one(t, false);
1057 t = mfree(t);
1058
1059 assert_se(asprintf(&t, "> %i", cpus) >= 0);
1060 test_condition_test_cpus_one(t, false);
1061 t = mfree(t);
1062 }
1063
1064 static void test_condition_test_memory_one(const char *s, bool result) {
1065 Condition *condition;
1066 int r;
1067
1068 log_debug("%s=%s", condition_type_to_string(CONDITION_MEMORY), s);
1069
1070 condition = condition_new(CONDITION_MEMORY, s, false, false);
1071 assert_se(condition);
1072
1073 r = condition_test(condition, environ);
1074 assert_se(r >= 0);
1075 assert_se(r == result);
1076 condition_free(condition);
1077 }
1078
1079 TEST(condition_test_memory) {
1080 _cleanup_free_ char *t = NULL;
1081 uint64_t memory;
1082
1083 memory = physical_memory();
1084
1085 test_condition_test_memory_one("> 0", true);
1086 test_condition_test_memory_one(">= 0", true);
1087 test_condition_test_memory_one("!= 0", true);
1088 test_condition_test_memory_one("<= 0", false);
1089 test_condition_test_memory_one("< 0", false);
1090 test_condition_test_memory_one("= 0", false);
1091
1092 test_condition_test_memory_one("> 18446744073709547520", false);
1093 test_condition_test_memory_one("= 18446744073709547520", false);
1094 test_condition_test_memory_one(">= 18446744073709547520", false);
1095 test_condition_test_memory_one("< 18446744073709547520", true);
1096 test_condition_test_memory_one("!= 18446744073709547520", true);
1097 test_condition_test_memory_one("<= 18446744073709547520", true);
1098
1099 test_condition_test_memory_one("> 100T", false);
1100 test_condition_test_memory_one("= 100T", false);
1101 test_condition_test_memory_one(">= 100T", false);
1102 test_condition_test_memory_one("< 100T", true);
1103 test_condition_test_memory_one("!= 100T", true);
1104 test_condition_test_memory_one("<= 100T", true);
1105
1106 test_condition_test_memory_one("> 100 T", false);
1107 test_condition_test_memory_one("= 100 T", false);
1108 test_condition_test_memory_one(">= 100 T", false);
1109 test_condition_test_memory_one("< 100 T", true);
1110 test_condition_test_memory_one("!= 100 T", true);
1111 test_condition_test_memory_one("<= 100 T", true);
1112
1113 test_condition_test_memory_one("> 100 T 1 G", false);
1114 test_condition_test_memory_one("= 100 T 1 G", false);
1115 test_condition_test_memory_one(">= 100 T 1 G", false);
1116 test_condition_test_memory_one("< 100 T 1 G", true);
1117 test_condition_test_memory_one("!= 100 T 1 G", true);
1118 test_condition_test_memory_one("<= 100 T 1 G", true);
1119
1120 assert_se(asprintf(&t, "= %" PRIu64, memory) >= 0);
1121 test_condition_test_memory_one(t, true);
1122 t = mfree(t);
1123
1124 assert_se(asprintf(&t, "<= %" PRIu64, memory) >= 0);
1125 test_condition_test_memory_one(t, true);
1126 t = mfree(t);
1127
1128 assert_se(asprintf(&t, ">= %" PRIu64, memory) >= 0);
1129 test_condition_test_memory_one(t, true);
1130 t = mfree(t);
1131
1132 assert_se(asprintf(&t, "!= %" PRIu64, memory) >= 0);
1133 test_condition_test_memory_one(t, false);
1134 t = mfree(t);
1135
1136 assert_se(asprintf(&t, "< %" PRIu64, memory) >= 0);
1137 test_condition_test_memory_one(t, false);
1138 t = mfree(t);
1139
1140 assert_se(asprintf(&t, "> %" PRIu64, memory) >= 0);
1141 test_condition_test_memory_one(t, false);
1142 t = mfree(t);
1143 }
1144
1145 static void test_condition_test_environment_one(const char *s, bool result) {
1146 Condition *condition;
1147 int r;
1148
1149 log_debug("%s=%s", condition_type_to_string(CONDITION_ENVIRONMENT), s);
1150
1151 condition = condition_new(CONDITION_ENVIRONMENT, s, false, false);
1152 assert_se(condition);
1153
1154 r = condition_test(condition, environ);
1155 assert_se(r >= 0);
1156 assert_se(r == result);
1157 condition_free(condition);
1158 }
1159
1160 TEST(condition_test_environment) {
1161 assert_se(setenv("EXISTINGENVVAR", "foo", false) >= 0);
1162
1163 test_condition_test_environment_one("MISSINGENVVAR", false);
1164 test_condition_test_environment_one("MISSINGENVVAR=foo", false);
1165 test_condition_test_environment_one("MISSINGENVVAR=", false);
1166
1167 test_condition_test_environment_one("EXISTINGENVVAR", true);
1168 test_condition_test_environment_one("EXISTINGENVVAR=foo", true);
1169 test_condition_test_environment_one("EXISTINGENVVAR=bar", false);
1170 test_condition_test_environment_one("EXISTINGENVVAR=", false);
1171 }
1172
1173 TEST(condition_test_os_release) {
1174 _cleanup_strv_free_ char **os_release_pairs = NULL;
1175 _cleanup_free_ char *version_id = NULL;
1176 const char *key_value_pair;
1177 Condition *condition;
1178
1179 /* Should not happen, but it's a test so we don't know the environment. */
1180 if (load_os_release_pairs(NULL, &os_release_pairs) < 0)
1181 return;
1182 if (strv_length(os_release_pairs) < 2)
1183 return;
1184
1185 condition = condition_new(CONDITION_OS_RELEASE, "_THISHOPEFULLYWONTEXIST=01234 56789", false, false);
1186 assert_se(condition);
1187 assert_se(condition_test(condition, environ) == 0);
1188 condition_free(condition);
1189
1190 condition = condition_new(CONDITION_OS_RELEASE, "WRONG FORMAT", false, false);
1191 assert_se(condition);
1192 assert_se(condition_test(condition, environ) == -EINVAL);
1193 condition_free(condition);
1194
1195 condition = condition_new(CONDITION_OS_RELEASE, "WRONG!<>=FORMAT", false, false);
1196 assert_se(condition);
1197 assert_se(condition_test(condition, environ) == -EINVAL);
1198 condition_free(condition);
1199
1200 condition = condition_new(CONDITION_OS_RELEASE, "WRONG FORMAT=", false, false);
1201 assert_se(condition);
1202 assert_se(condition_test(condition, environ) == -EINVAL);
1203 condition_free(condition);
1204
1205 condition = condition_new(CONDITION_OS_RELEASE, "WRONG =FORMAT", false, false);
1206 assert_se(condition);
1207 assert_se(condition_test(condition, environ) == -EINVAL);
1208 condition_free(condition);
1209
1210 condition = condition_new(CONDITION_OS_RELEASE, "WRONG = FORMAT", false, false);
1211 assert_se(condition);
1212 assert_se(condition_test(condition, environ) == -EINVAL);
1213 condition_free(condition);
1214
1215 condition = condition_new(CONDITION_OS_RELEASE, "WRONGFORMAT= ", false, false);
1216 assert_se(condition);
1217 assert_se(condition_test(condition, environ) == -EINVAL);
1218 condition_free(condition);
1219
1220 condition = condition_new(CONDITION_OS_RELEASE, "WRO NG=FORMAT", false, false);
1221 assert_se(condition);
1222 assert_se(condition_test(condition, environ) == -EINVAL);
1223 condition_free(condition);
1224
1225 condition = condition_new(CONDITION_OS_RELEASE, "", false, false);
1226 assert_se(condition);
1227 assert_se(condition_test(condition, environ) > 0);
1228 condition_free(condition);
1229
1230 /* load_os_release_pairs() removes quotes, we have to add them back,
1231 * otherwise we get a string: "PRETTY_NAME=Debian GNU/Linux 10 (buster)"
1232 * which is wrong, as the value is not quoted anymore. */
1233 const char *quote = strchr(os_release_pairs[1], ' ') ? "\"" : "";
1234 key_value_pair = strjoina(os_release_pairs[0], "=", quote, os_release_pairs[1], quote);
1235 condition = condition_new(CONDITION_OS_RELEASE, key_value_pair, false, false);
1236 assert_se(condition);
1237 assert_se(condition_test(condition, environ) > 0);
1238 condition_free(condition);
1239
1240 key_value_pair = strjoina(os_release_pairs[0], "!=", quote, os_release_pairs[1], quote);
1241 condition = condition_new(CONDITION_OS_RELEASE, key_value_pair, false, false);
1242 assert_se(condition);
1243 assert_se(condition_test(condition, environ) == 0);
1244 condition_free(condition);
1245
1246 /* Test fnmatch() operators */
1247 key_value_pair = strjoina(os_release_pairs[0], "$=", quote, os_release_pairs[1], quote);
1248 condition = condition_new(CONDITION_OS_RELEASE, key_value_pair, false, false);
1249 assert_se(condition);
1250 assert_se(condition_test(condition, environ) > 0);
1251 condition_free(condition);
1252
1253 key_value_pair = strjoina(os_release_pairs[0], "!$=", quote, os_release_pairs[1], quote);
1254 condition = condition_new(CONDITION_OS_RELEASE, key_value_pair, false, false);
1255 assert_se(condition);
1256 assert_se(condition_test(condition, environ) == 0);
1257 condition_free(condition);
1258
1259 /* Some distros (eg: Arch) do not set VERSION_ID */
1260 if (parse_os_release(NULL, "VERSION_ID", &version_id) <= 0)
1261 return;
1262
1263 key_value_pair = strjoina("VERSION_ID", "=", version_id);
1264 condition = condition_new(CONDITION_OS_RELEASE, key_value_pair, false, false);
1265 assert_se(condition);
1266 assert_se(condition_test(condition, environ) > 0);
1267 condition_free(condition);
1268
1269 key_value_pair = strjoina("VERSION_ID", "!=", version_id);
1270 condition = condition_new(CONDITION_OS_RELEASE, key_value_pair, false, false);
1271 assert_se(condition);
1272 assert_se(condition_test(condition, environ) == 0);
1273 condition_free(condition);
1274
1275 key_value_pair = strjoina("VERSION_ID", "<=", version_id);
1276 condition = condition_new(CONDITION_OS_RELEASE, key_value_pair, false, false);
1277 assert_se(condition);
1278 assert_se(condition_test(condition, environ) > 0);
1279 condition_free(condition);
1280
1281 key_value_pair = strjoina("VERSION_ID", ">=", version_id);
1282 condition = condition_new(CONDITION_OS_RELEASE, key_value_pair, false, false);
1283 assert_se(condition);
1284 assert_se(condition_test(condition, environ) > 0);
1285 condition_free(condition);
1286
1287 key_value_pair = strjoina("VERSION_ID", "<", version_id, ".1");
1288 condition = condition_new(CONDITION_OS_RELEASE, key_value_pair, false, false);
1289 assert_se(condition);
1290 assert_se(condition_test(condition, environ) > 0);
1291 condition_free(condition);
1292
1293 key_value_pair = strjoina("VERSION_ID", ">", version_id, ".1");
1294 condition = condition_new(CONDITION_OS_RELEASE, key_value_pair, false, false);
1295 assert_se(condition);
1296 assert_se(condition_test(condition, environ) == 0);
1297 condition_free(condition);
1298
1299 key_value_pair = strjoina("VERSION_ID", "=", version_id, " ", os_release_pairs[0], "=", quote, os_release_pairs[1], quote);
1300 condition = condition_new(CONDITION_OS_RELEASE, key_value_pair, false, false);
1301 assert_se(condition);
1302 assert_se(condition_test(condition, environ) > 0);
1303 condition_free(condition);
1304
1305 key_value_pair = strjoina("VERSION_ID", "!=", version_id, " ", os_release_pairs[0], "=", quote, os_release_pairs[1], quote);
1306 condition = condition_new(CONDITION_OS_RELEASE, key_value_pair, false, false);
1307 assert_se(condition);
1308 assert_se(condition_test(condition, environ) == 0);
1309 condition_free(condition);
1310
1311 key_value_pair = strjoina("VERSION_ID", "=", version_id, " ", os_release_pairs[0], "!=", quote, os_release_pairs[1], quote);
1312 condition = condition_new(CONDITION_OS_RELEASE, key_value_pair, false, false);
1313 assert_se(condition);
1314 assert_se(condition_test(condition, environ) == 0);
1315 condition_free(condition);
1316
1317 key_value_pair = strjoina("VERSION_ID", "!=", version_id, " ", os_release_pairs[0], "!=", quote, os_release_pairs[1], quote);
1318 condition = condition_new(CONDITION_OS_RELEASE, key_value_pair, false, false);
1319 assert_se(condition);
1320 assert_se(condition_test(condition, environ) == 0);
1321 condition_free(condition);
1322
1323 key_value_pair = strjoina("VERSION_ID", "<", version_id, ".1", " ", os_release_pairs[0], "=", quote, os_release_pairs[1], quote);
1324 condition = condition_new(CONDITION_OS_RELEASE, key_value_pair, false, false);
1325 assert_se(condition);
1326 assert_se(condition_test(condition, environ) > 0);
1327 condition_free(condition);
1328 }
1329
1330 TEST(condition_test_psi) {
1331 Condition *condition;
1332 CGroupMask mask;
1333 int r;
1334
1335 if (!is_pressure_supported())
1336 return (void) log_notice("Pressure Stall Information (PSI) is not supported, skipping %s", __func__);
1337
1338 condition = condition_new(CONDITION_MEMORY_PRESSURE, "", false, false);
1339 assert_se(condition);
1340 assert_se(condition_test(condition, environ) < 0);
1341 condition_free(condition);
1342
1343 condition = condition_new(CONDITION_CPU_PRESSURE, "sbarabau", false, false);
1344 assert_se(condition);
1345 assert_se(condition_test(condition, environ) < 0);
1346 condition_free(condition);
1347
1348 condition = condition_new(CONDITION_MEMORY_PRESSURE, "10%sbarabau", false, false);
1349 assert_se(condition);
1350 assert_se(condition_test(condition, environ) < 0);
1351 condition_free(condition);
1352
1353 condition = condition_new(CONDITION_CPU_PRESSURE, "10% sbarabau", false, false);
1354 assert_se(condition);
1355 assert_se(condition_test(condition, environ) < 0);
1356 condition_free(condition);
1357
1358 condition = condition_new(CONDITION_CPU_PRESSURE, "-10", false, false);
1359 assert_se(condition);
1360 assert_se(condition_test(condition, environ) < 0);
1361 condition_free(condition);
1362
1363 condition = condition_new(CONDITION_CPU_PRESSURE, "10%/10min", false, false);
1364 assert_se(condition);
1365 assert_se(condition_test(condition, environ) < 0);
1366 condition_free(condition);
1367
1368 condition = condition_new(CONDITION_CPU_PRESSURE, "10min/10%", false, false);
1369 assert_se(condition);
1370 assert_se(condition_test(condition, environ) < 0);
1371 condition_free(condition);
1372
1373 condition = condition_new(CONDITION_CPU_PRESSURE, "10% 5min", false, false);
1374 assert_se(condition);
1375 assert_se(condition_test(condition, environ) < 0);
1376 condition_free(condition);
1377
1378 condition = condition_new(CONDITION_CPU_PRESSURE, "/5min", false, false);
1379 assert_se(condition);
1380 assert_se(condition_test(condition, environ) < 0);
1381 condition_free(condition);
1382
1383 condition = condition_new(CONDITION_IO_PRESSURE, "10s / ", false, false);
1384 assert_se(condition);
1385 assert_se(condition_test(condition, environ) < 0);
1386 condition_free(condition);
1387
1388 condition = condition_new(CONDITION_MEMORY_PRESSURE, "100%", false, false);
1389 assert_se(condition);
1390 assert_se(condition_test(condition, environ) >= 0);
1391 condition_free(condition);
1392
1393 condition = condition_new(CONDITION_MEMORY_PRESSURE, "0%", false, false);
1394 assert_se(condition);
1395 assert_se(condition_test(condition, environ) >= 0);
1396 condition_free(condition);
1397
1398 condition = condition_new(CONDITION_MEMORY_PRESSURE, "0.0%", false, false);
1399 assert_se(condition);
1400 assert_se(condition_test(condition, environ) >= 0);
1401 condition_free(condition);
1402
1403 condition = condition_new(CONDITION_CPU_PRESSURE, "100%", false, false);
1404 assert_se(condition);
1405 assert_se(condition_test(condition, environ) >= 0);
1406 condition_free(condition);
1407
1408 condition = condition_new(CONDITION_CPU_PRESSURE, "0%", false, false);
1409 assert_se(condition);
1410 assert_se(condition_test(condition, environ) >= 0);
1411 condition_free(condition);
1412
1413 condition = condition_new(CONDITION_CPU_PRESSURE, "0.0%", false, false);
1414 assert_se(condition);
1415 assert_se(condition_test(condition, environ) >= 0);
1416 condition_free(condition);
1417
1418 condition = condition_new(CONDITION_CPU_PRESSURE, "0.01%", false, false);
1419 assert_se(condition);
1420 assert_se(condition_test(condition, environ) >= 0);
1421 condition_free(condition);
1422
1423 condition = condition_new(CONDITION_CPU_PRESSURE, "0.0%/10sec", false, false);
1424 assert_se(condition);
1425 assert_se(condition_test(condition, environ) >= 0);
1426 condition_free(condition);
1427
1428 condition = condition_new(CONDITION_CPU_PRESSURE, "100.0% / 1min", false, false);
1429 assert_se(condition);
1430 assert_se(condition_test(condition, environ) >= 0);
1431 condition_free(condition);
1432
1433 condition = condition_new(CONDITION_IO_PRESSURE, "50.0% / 1min", false, false);
1434 assert_se(condition);
1435 assert_se(condition_test(condition, environ) >= 0);
1436 condition_free(condition);
1437
1438 r = cg_all_unified();
1439 if (r < 0)
1440 return (void) log_notice("Failed to determine whether the unified cgroups hierarchy is used, skipping %s", __func__);
1441 if (r == 0)
1442 return (void) log_notice("Requires the unified cgroups hierarchy, skipping %s", __func__);
1443
1444 if (cg_mask_supported(&mask) < 0)
1445 return (void) log_notice("Failed to get supported cgroup controllers, skipping %s", __func__);
1446
1447 if (!FLAGS_SET(mask, CGROUP_MASK_MEMORY))
1448 return (void) log_notice("Requires the cgroup memory controller, skipping %s", __func__);
1449
1450 if (!FLAGS_SET(mask, CGROUP_MASK_CPU))
1451 return (void) log_notice("Requires the cgroup CPU controller, skipping %s", __func__);
1452
1453 condition = condition_new(CONDITION_MEMORY_PRESSURE, " : / ", false, false);
1454 assert_se(condition);
1455 assert_se(condition_test(condition, environ) < 0);
1456 condition_free(condition);
1457
1458 condition = condition_new(CONDITION_CPU_PRESSURE, "hopefullythisisnotarealone.slice:100% / 10sec", false, false);
1459 assert_se(condition);
1460 assert_se(condition_test(condition, environ) > 0);
1461 condition_free(condition);
1462
1463 condition = condition_new(CONDITION_CPU_PRESSURE, "-.slice:100.0% / 1min", false, false);
1464 assert_se(condition);
1465 assert_se(condition_test(condition, environ) >= 0);
1466 condition_free(condition);
1467
1468 condition = condition_new(CONDITION_MEMORY_PRESSURE, "-.slice:0.0%/5min", false, false);
1469 assert_se(condition);
1470 assert_se(condition_test(condition, environ) >= 0);
1471 condition_free(condition);
1472
1473 condition = condition_new(CONDITION_MEMORY_PRESSURE, "-.slice:100.0%", false, false);
1474 assert_se(condition);
1475 assert_se(condition_test(condition, environ) >= 0);
1476 condition_free(condition);
1477
1478 condition = condition_new(CONDITION_IO_PRESSURE, "-.slice:0.0%", false, false);
1479 assert_se(condition);
1480 assert_se(condition_test(condition, environ) >= 0);
1481 condition_free(condition);
1482 }
1483
1484 DEFINE_TEST_MAIN(LOG_DEBUG);