]> git.ipfire.org Git - thirdparty/systemd.git/blob - src/test/test-condition.c
4cd23d8e2135bba4ec65f986a66894bd5aa9f9ab
[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 const char *virt;
804 int r;
805
806 condition = condition_new(CONDITION_VIRTUALIZATION, "garbage oifdsjfoidsjoj", false, false);
807 assert_se(condition);
808 r = condition_test(condition, environ);
809 if (ERRNO_IS_PRIVILEGE(r))
810 return;
811 log_info("ConditionVirtualization=garbage → %i", r);
812 assert_se(r == 0);
813 condition_free(condition);
814
815 condition = condition_new(CONDITION_VIRTUALIZATION, "container", false, false);
816 assert_se(condition);
817 r = condition_test(condition, environ);
818 log_info("ConditionVirtualization=container → %i", r);
819 assert_se(r == !!detect_container());
820 condition_free(condition);
821
822 condition = condition_new(CONDITION_VIRTUALIZATION, "vm", false, false);
823 assert_se(condition);
824 r = condition_test(condition, environ);
825 log_info("ConditionVirtualization=vm → %i", r);
826 assert_se(r == (detect_vm() && !detect_container()));
827 condition_free(condition);
828
829 condition = condition_new(CONDITION_VIRTUALIZATION, "private-users", false, false);
830 assert_se(condition);
831 r = condition_test(condition, environ);
832 log_info("ConditionVirtualization=private-users → %i", r);
833 assert_se(r == !!running_in_userns());
834 condition_free(condition);
835
836 NULSTR_FOREACH(virt,
837 "kvm\0"
838 "amazon\0"
839 "qemu\0"
840 "bochs\0"
841 "xen\0"
842 "uml\0"
843 "vmware\0"
844 "oracle\0"
845 "microsoft\0"
846 "zvm\0"
847 "parallels\0"
848 "bhyve\0"
849 "vm_other\0") {
850
851 condition = condition_new(CONDITION_VIRTUALIZATION, virt, false, false);
852 assert_se(condition);
853 r = condition_test(condition, environ);
854 log_info("ConditionVirtualization=%s → %i", virt, r);
855 assert_se(r >= 0);
856 condition_free(condition);
857 }
858 }
859
860 TEST(condition_test_user) {
861 Condition *condition;
862 char* uid;
863 char* username;
864 int r;
865
866 condition = condition_new(CONDITION_USER, "garbage oifdsjfoidsjoj", false, false);
867 assert_se(condition);
868 r = condition_test(condition, environ);
869 log_info("ConditionUser=garbage → %i", r);
870 assert_se(r == 0);
871 condition_free(condition);
872
873 assert_se(asprintf(&uid, "%"PRIu32, UINT32_C(0xFFFF)) > 0);
874 condition = condition_new(CONDITION_USER, uid, false, false);
875 assert_se(condition);
876 r = condition_test(condition, environ);
877 log_info("ConditionUser=%s → %i", uid, r);
878 assert_se(r == 0);
879 condition_free(condition);
880 free(uid);
881
882 assert_se(asprintf(&uid, "%u", (unsigned)getuid()) > 0);
883 condition = condition_new(CONDITION_USER, uid, false, false);
884 assert_se(condition);
885 r = condition_test(condition, environ);
886 log_info("ConditionUser=%s → %i", uid, r);
887 assert_se(r > 0);
888 condition_free(condition);
889 free(uid);
890
891 assert_se(asprintf(&uid, "%u", (unsigned)getuid()+1) > 0);
892 condition = condition_new(CONDITION_USER, uid, false, false);
893 assert_se(condition);
894 r = condition_test(condition, environ);
895 log_info("ConditionUser=%s → %i", uid, r);
896 assert_se(r == 0);
897 condition_free(condition);
898 free(uid);
899
900 username = getusername_malloc();
901 assert_se(username);
902 condition = condition_new(CONDITION_USER, username, false, false);
903 assert_se(condition);
904 r = condition_test(condition, environ);
905 log_info("ConditionUser=%s → %i", username, r);
906 assert_se(r > 0);
907 condition_free(condition);
908 free(username);
909
910 username = (char*)(geteuid() == 0 ? NOBODY_USER_NAME : "root");
911 condition = condition_new(CONDITION_USER, username, false, false);
912 assert_se(condition);
913 r = condition_test(condition, environ);
914 log_info("ConditionUser=%s → %i", username, r);
915 assert_se(r == 0);
916 condition_free(condition);
917
918 condition = condition_new(CONDITION_USER, "@system", false, false);
919 assert_se(condition);
920 r = condition_test(condition, environ);
921 log_info("ConditionUser=@system → %i", r);
922 if (uid_is_system(getuid()) || uid_is_system(geteuid()))
923 assert_se(r > 0);
924 else
925 assert_se(r == 0);
926 condition_free(condition);
927 }
928
929 TEST(condition_test_group) {
930 Condition *condition;
931 char* gid;
932 char* groupname;
933 gid_t *gids, max_gid;
934 int ngroups_max, ngroups, r, i;
935
936 assert_se(0 < asprintf(&gid, "%u", UINT32_C(0xFFFF)));
937 condition = condition_new(CONDITION_GROUP, gid, false, false);
938 assert_se(condition);
939 r = condition_test(condition, environ);
940 log_info("ConditionGroup=%s → %i", gid, r);
941 assert_se(r == 0);
942 condition_free(condition);
943 free(gid);
944
945 assert_se(0 < asprintf(&gid, "%u", getgid()));
946 condition = condition_new(CONDITION_GROUP, gid, false, false);
947 assert_se(condition);
948 r = condition_test(condition, environ);
949 log_info("ConditionGroup=%s → %i", gid, r);
950 assert_se(r > 0);
951 condition_free(condition);
952 free(gid);
953
954 ngroups_max = sysconf(_SC_NGROUPS_MAX);
955 assert_se(ngroups_max > 0);
956
957 gids = newa(gid_t, ngroups_max);
958
959 ngroups = getgroups(ngroups_max, gids);
960 assert_se(ngroups >= 0);
961
962 max_gid = getgid();
963 for (i = 0; i < ngroups; i++) {
964 assert_se(0 < asprintf(&gid, "%u", gids[i]));
965 condition = condition_new(CONDITION_GROUP, gid, false, false);
966 assert_se(condition);
967 r = condition_test(condition, environ);
968 log_info("ConditionGroup=%s → %i", gid, r);
969 assert_se(r > 0);
970 condition_free(condition);
971 free(gid);
972 max_gid = gids[i] > max_gid ? gids[i] : max_gid;
973
974 groupname = gid_to_name(gids[i]);
975 assert_se(groupname);
976 condition = condition_new(CONDITION_GROUP, groupname, false, false);
977 assert_se(condition);
978 r = condition_test(condition, environ);
979 log_info("ConditionGroup=%s → %i", groupname, r);
980 assert_se(r > 0);
981 condition_free(condition);
982 free(groupname);
983 max_gid = gids[i] > max_gid ? gids[i] : max_gid;
984 }
985
986 assert_se(0 < asprintf(&gid, "%u", max_gid+1));
987 condition = condition_new(CONDITION_GROUP, gid, false, false);
988 assert_se(condition);
989 r = condition_test(condition, environ);
990 log_info("ConditionGroup=%s → %i", gid, r);
991 assert_se(r == 0);
992 condition_free(condition);
993 free(gid);
994
995 groupname = (char*)(getegid() == 0 ? NOBODY_GROUP_NAME : "root");
996 condition = condition_new(CONDITION_GROUP, groupname, false, false);
997 assert_se(condition);
998 r = condition_test(condition, environ);
999 log_info("ConditionGroup=%s → %i", groupname, r);
1000 assert_se(r == 0);
1001 condition_free(condition);
1002 }
1003
1004 static void test_condition_test_cpus_one(const char *s, bool result) {
1005 Condition *condition;
1006 int r;
1007
1008 log_debug("%s=%s", condition_type_to_string(CONDITION_CPUS), s);
1009
1010 condition = condition_new(CONDITION_CPUS, s, false, false);
1011 assert_se(condition);
1012
1013 r = condition_test(condition, environ);
1014 assert_se(r >= 0);
1015 assert_se(r == result);
1016 condition_free(condition);
1017 }
1018
1019 TEST(condition_test_cpus) {
1020 _cleanup_free_ char *t = NULL;
1021 int cpus;
1022
1023 cpus = cpus_in_affinity_mask();
1024 assert_se(cpus >= 0);
1025
1026 test_condition_test_cpus_one("> 0", true);
1027 test_condition_test_cpus_one(">= 0", true);
1028 test_condition_test_cpus_one("!= 0", true);
1029 test_condition_test_cpus_one("<= 0", false);
1030 test_condition_test_cpus_one("< 0", false);
1031 test_condition_test_cpus_one("= 0", false);
1032
1033 test_condition_test_cpus_one("> 100000", false);
1034 test_condition_test_cpus_one("= 100000", false);
1035 test_condition_test_cpus_one(">= 100000", false);
1036 test_condition_test_cpus_one("< 100000", true);
1037 test_condition_test_cpus_one("!= 100000", true);
1038 test_condition_test_cpus_one("<= 100000", true);
1039
1040 assert_se(asprintf(&t, "= %i", cpus) >= 0);
1041 test_condition_test_cpus_one(t, true);
1042 t = mfree(t);
1043
1044 assert_se(asprintf(&t, "<= %i", cpus) >= 0);
1045 test_condition_test_cpus_one(t, true);
1046 t = mfree(t);
1047
1048 assert_se(asprintf(&t, ">= %i", cpus) >= 0);
1049 test_condition_test_cpus_one(t, true);
1050 t = mfree(t);
1051
1052 assert_se(asprintf(&t, "!= %i", cpus) >= 0);
1053 test_condition_test_cpus_one(t, false);
1054 t = mfree(t);
1055
1056 assert_se(asprintf(&t, "< %i", cpus) >= 0);
1057 test_condition_test_cpus_one(t, false);
1058 t = mfree(t);
1059
1060 assert_se(asprintf(&t, "> %i", cpus) >= 0);
1061 test_condition_test_cpus_one(t, false);
1062 t = mfree(t);
1063 }
1064
1065 static void test_condition_test_memory_one(const char *s, bool result) {
1066 Condition *condition;
1067 int r;
1068
1069 log_debug("%s=%s", condition_type_to_string(CONDITION_MEMORY), s);
1070
1071 condition = condition_new(CONDITION_MEMORY, s, false, false);
1072 assert_se(condition);
1073
1074 r = condition_test(condition, environ);
1075 assert_se(r >= 0);
1076 assert_se(r == result);
1077 condition_free(condition);
1078 }
1079
1080 TEST(condition_test_memory) {
1081 _cleanup_free_ char *t = NULL;
1082 uint64_t memory;
1083
1084 memory = physical_memory();
1085
1086 test_condition_test_memory_one("> 0", true);
1087 test_condition_test_memory_one(">= 0", true);
1088 test_condition_test_memory_one("!= 0", true);
1089 test_condition_test_memory_one("<= 0", false);
1090 test_condition_test_memory_one("< 0", false);
1091 test_condition_test_memory_one("= 0", false);
1092
1093 test_condition_test_memory_one("> 18446744073709547520", false);
1094 test_condition_test_memory_one("= 18446744073709547520", false);
1095 test_condition_test_memory_one(">= 18446744073709547520", false);
1096 test_condition_test_memory_one("< 18446744073709547520", true);
1097 test_condition_test_memory_one("!= 18446744073709547520", true);
1098 test_condition_test_memory_one("<= 18446744073709547520", true);
1099
1100 test_condition_test_memory_one("> 100T", false);
1101 test_condition_test_memory_one("= 100T", false);
1102 test_condition_test_memory_one(">= 100T", false);
1103 test_condition_test_memory_one("< 100T", true);
1104 test_condition_test_memory_one("!= 100T", true);
1105 test_condition_test_memory_one("<= 100T", true);
1106
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", false);
1110 test_condition_test_memory_one("< 100 T", true);
1111 test_condition_test_memory_one("!= 100 T", true);
1112 test_condition_test_memory_one("<= 100 T", true);
1113
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", false);
1117 test_condition_test_memory_one("< 100 T 1 G", true);
1118 test_condition_test_memory_one("!= 100 T 1 G", true);
1119 test_condition_test_memory_one("<= 100 T 1 G", true);
1120
1121 assert_se(asprintf(&t, "= %" PRIu64, memory) >= 0);
1122 test_condition_test_memory_one(t, true);
1123 t = mfree(t);
1124
1125 assert_se(asprintf(&t, "<= %" PRIu64, memory) >= 0);
1126 test_condition_test_memory_one(t, true);
1127 t = mfree(t);
1128
1129 assert_se(asprintf(&t, ">= %" PRIu64, memory) >= 0);
1130 test_condition_test_memory_one(t, true);
1131 t = mfree(t);
1132
1133 assert_se(asprintf(&t, "!= %" PRIu64, memory) >= 0);
1134 test_condition_test_memory_one(t, false);
1135 t = mfree(t);
1136
1137 assert_se(asprintf(&t, "< %" PRIu64, memory) >= 0);
1138 test_condition_test_memory_one(t, false);
1139 t = mfree(t);
1140
1141 assert_se(asprintf(&t, "> %" PRIu64, memory) >= 0);
1142 test_condition_test_memory_one(t, false);
1143 t = mfree(t);
1144 }
1145
1146 static void test_condition_test_environment_one(const char *s, bool result) {
1147 Condition *condition;
1148 int r;
1149
1150 log_debug("%s=%s", condition_type_to_string(CONDITION_ENVIRONMENT), s);
1151
1152 condition = condition_new(CONDITION_ENVIRONMENT, s, false, false);
1153 assert_se(condition);
1154
1155 r = condition_test(condition, environ);
1156 assert_se(r >= 0);
1157 assert_se(r == result);
1158 condition_free(condition);
1159 }
1160
1161 TEST(condition_test_environment) {
1162 assert_se(setenv("EXISTINGENVVAR", "foo", false) >= 0);
1163
1164 test_condition_test_environment_one("MISSINGENVVAR", false);
1165 test_condition_test_environment_one("MISSINGENVVAR=foo", false);
1166 test_condition_test_environment_one("MISSINGENVVAR=", false);
1167
1168 test_condition_test_environment_one("EXISTINGENVVAR", true);
1169 test_condition_test_environment_one("EXISTINGENVVAR=foo", true);
1170 test_condition_test_environment_one("EXISTINGENVVAR=bar", false);
1171 test_condition_test_environment_one("EXISTINGENVVAR=", false);
1172 }
1173
1174 TEST(condition_test_os_release) {
1175 _cleanup_strv_free_ char **os_release_pairs = NULL;
1176 _cleanup_free_ char *version_id = NULL;
1177 const char *key_value_pair;
1178 Condition *condition;
1179
1180 /* Should not happen, but it's a test so we don't know the environment. */
1181 if (load_os_release_pairs(NULL, &os_release_pairs) < 0)
1182 return;
1183 if (strv_length(os_release_pairs) < 2)
1184 return;
1185
1186 condition = condition_new(CONDITION_OS_RELEASE, "_THISHOPEFULLYWONTEXIST=01234 56789", false, false);
1187 assert_se(condition);
1188 assert_se(condition_test(condition, environ) == 0);
1189 condition_free(condition);
1190
1191 condition = condition_new(CONDITION_OS_RELEASE, "WRONG FORMAT", false, false);
1192 assert_se(condition);
1193 assert_se(condition_test(condition, environ) == -EINVAL);
1194 condition_free(condition);
1195
1196 condition = condition_new(CONDITION_OS_RELEASE, "WRONG!<>=FORMAT", false, false);
1197 assert_se(condition);
1198 assert_se(condition_test(condition, environ) == -EINVAL);
1199 condition_free(condition);
1200
1201 condition = condition_new(CONDITION_OS_RELEASE, "WRONG FORMAT=", false, false);
1202 assert_se(condition);
1203 assert_se(condition_test(condition, environ) == -EINVAL);
1204 condition_free(condition);
1205
1206 condition = condition_new(CONDITION_OS_RELEASE, "WRONG =FORMAT", false, false);
1207 assert_se(condition);
1208 assert_se(condition_test(condition, environ) == -EINVAL);
1209 condition_free(condition);
1210
1211 condition = condition_new(CONDITION_OS_RELEASE, "WRONG = FORMAT", false, false);
1212 assert_se(condition);
1213 assert_se(condition_test(condition, environ) == -EINVAL);
1214 condition_free(condition);
1215
1216 condition = condition_new(CONDITION_OS_RELEASE, "WRONGFORMAT= ", false, false);
1217 assert_se(condition);
1218 assert_se(condition_test(condition, environ) == -EINVAL);
1219 condition_free(condition);
1220
1221 condition = condition_new(CONDITION_OS_RELEASE, "WRO NG=FORMAT", false, false);
1222 assert_se(condition);
1223 assert_se(condition_test(condition, environ) == -EINVAL);
1224 condition_free(condition);
1225
1226 condition = condition_new(CONDITION_OS_RELEASE, "", false, false);
1227 assert_se(condition);
1228 assert_se(condition_test(condition, environ) > 0);
1229 condition_free(condition);
1230
1231 /* load_os_release_pairs() removes quotes, we have to add them back,
1232 * otherwise we get a string: "PRETTY_NAME=Debian GNU/Linux 10 (buster)"
1233 * which is wrong, as the value is not quoted anymore. */
1234 const char *quote = strchr(os_release_pairs[1], ' ') ? "\"" : "";
1235 key_value_pair = strjoina(os_release_pairs[0], "=", quote, os_release_pairs[1], quote);
1236 condition = condition_new(CONDITION_OS_RELEASE, key_value_pair, false, false);
1237 assert_se(condition);
1238 assert_se(condition_test(condition, environ) > 0);
1239 condition_free(condition);
1240
1241 key_value_pair = strjoina(os_release_pairs[0], "!=", quote, os_release_pairs[1], quote);
1242 condition = condition_new(CONDITION_OS_RELEASE, key_value_pair, false, false);
1243 assert_se(condition);
1244 assert_se(condition_test(condition, environ) == 0);
1245 condition_free(condition);
1246
1247 /* Test fnmatch() operators */
1248 key_value_pair = strjoina(os_release_pairs[0], "$=", quote, os_release_pairs[1], quote);
1249 condition = condition_new(CONDITION_OS_RELEASE, key_value_pair, false, false);
1250 assert_se(condition);
1251 assert_se(condition_test(condition, environ) > 0);
1252 condition_free(condition);
1253
1254 key_value_pair = strjoina(os_release_pairs[0], "!$=", quote, os_release_pairs[1], quote);
1255 condition = condition_new(CONDITION_OS_RELEASE, key_value_pair, false, false);
1256 assert_se(condition);
1257 assert_se(condition_test(condition, environ) == 0);
1258 condition_free(condition);
1259
1260 /* Some distros (eg: Arch) do not set VERSION_ID */
1261 if (parse_os_release(NULL, "VERSION_ID", &version_id) <= 0)
1262 return;
1263
1264 key_value_pair = strjoina("VERSION_ID", "=", version_id);
1265 condition = condition_new(CONDITION_OS_RELEASE, key_value_pair, false, false);
1266 assert_se(condition);
1267 assert_se(condition_test(condition, environ) > 0);
1268 condition_free(condition);
1269
1270 key_value_pair = strjoina("VERSION_ID", "!=", version_id);
1271 condition = condition_new(CONDITION_OS_RELEASE, key_value_pair, false, false);
1272 assert_se(condition);
1273 assert_se(condition_test(condition, environ) == 0);
1274 condition_free(condition);
1275
1276 key_value_pair = strjoina("VERSION_ID", "<=", version_id);
1277 condition = condition_new(CONDITION_OS_RELEASE, key_value_pair, false, false);
1278 assert_se(condition);
1279 assert_se(condition_test(condition, environ) > 0);
1280 condition_free(condition);
1281
1282 key_value_pair = strjoina("VERSION_ID", ">=", version_id);
1283 condition = condition_new(CONDITION_OS_RELEASE, key_value_pair, false, false);
1284 assert_se(condition);
1285 assert_se(condition_test(condition, environ) > 0);
1286 condition_free(condition);
1287
1288 key_value_pair = strjoina("VERSION_ID", "<", version_id, ".1");
1289 condition = condition_new(CONDITION_OS_RELEASE, key_value_pair, false, false);
1290 assert_se(condition);
1291 assert_se(condition_test(condition, environ) > 0);
1292 condition_free(condition);
1293
1294 key_value_pair = strjoina("VERSION_ID", ">", version_id, ".1");
1295 condition = condition_new(CONDITION_OS_RELEASE, key_value_pair, false, false);
1296 assert_se(condition);
1297 assert_se(condition_test(condition, environ) == 0);
1298 condition_free(condition);
1299
1300 key_value_pair = strjoina("VERSION_ID", "=", version_id, " ", os_release_pairs[0], "=", quote, os_release_pairs[1], quote);
1301 condition = condition_new(CONDITION_OS_RELEASE, key_value_pair, false, false);
1302 assert_se(condition);
1303 assert_se(condition_test(condition, environ) > 0);
1304 condition_free(condition);
1305
1306 key_value_pair = strjoina("VERSION_ID", "!=", version_id, " ", os_release_pairs[0], "=", quote, os_release_pairs[1], quote);
1307 condition = condition_new(CONDITION_OS_RELEASE, key_value_pair, false, false);
1308 assert_se(condition);
1309 assert_se(condition_test(condition, environ) == 0);
1310 condition_free(condition);
1311
1312 key_value_pair = strjoina("VERSION_ID", "=", version_id, " ", os_release_pairs[0], "!=", quote, os_release_pairs[1], quote);
1313 condition = condition_new(CONDITION_OS_RELEASE, key_value_pair, false, false);
1314 assert_se(condition);
1315 assert_se(condition_test(condition, environ) == 0);
1316 condition_free(condition);
1317
1318 key_value_pair = strjoina("VERSION_ID", "!=", version_id, " ", os_release_pairs[0], "!=", quote, os_release_pairs[1], quote);
1319 condition = condition_new(CONDITION_OS_RELEASE, key_value_pair, false, false);
1320 assert_se(condition);
1321 assert_se(condition_test(condition, environ) == 0);
1322 condition_free(condition);
1323
1324 key_value_pair = strjoina("VERSION_ID", "<", version_id, ".1", " ", os_release_pairs[0], "=", quote, os_release_pairs[1], quote);
1325 condition = condition_new(CONDITION_OS_RELEASE, key_value_pair, false, false);
1326 assert_se(condition);
1327 assert_se(condition_test(condition, environ) > 0);
1328 condition_free(condition);
1329 }
1330
1331 TEST(condition_test_psi) {
1332 Condition *condition;
1333 CGroupMask mask;
1334 int r;
1335
1336 if (!is_pressure_supported())
1337 return (void) log_notice("Pressure Stall Information (PSI) is not supported, skipping %s", __func__);
1338
1339 condition = condition_new(CONDITION_MEMORY_PRESSURE, "", false, false);
1340 assert_se(condition);
1341 assert_se(condition_test(condition, environ) < 0);
1342 condition_free(condition);
1343
1344 condition = condition_new(CONDITION_CPU_PRESSURE, "sbarabau", false, false);
1345 assert_se(condition);
1346 assert_se(condition_test(condition, environ) < 0);
1347 condition_free(condition);
1348
1349 condition = condition_new(CONDITION_MEMORY_PRESSURE, "10%sbarabau", false, false);
1350 assert_se(condition);
1351 assert_se(condition_test(condition, environ) < 0);
1352 condition_free(condition);
1353
1354 condition = condition_new(CONDITION_CPU_PRESSURE, "10% sbarabau", false, false);
1355 assert_se(condition);
1356 assert_se(condition_test(condition, environ) < 0);
1357 condition_free(condition);
1358
1359 condition = condition_new(CONDITION_CPU_PRESSURE, "-10", false, false);
1360 assert_se(condition);
1361 assert_se(condition_test(condition, environ) < 0);
1362 condition_free(condition);
1363
1364 condition = condition_new(CONDITION_CPU_PRESSURE, "10%/10min", false, false);
1365 assert_se(condition);
1366 assert_se(condition_test(condition, environ) < 0);
1367 condition_free(condition);
1368
1369 condition = condition_new(CONDITION_CPU_PRESSURE, "10min/10%", false, false);
1370 assert_se(condition);
1371 assert_se(condition_test(condition, environ) < 0);
1372 condition_free(condition);
1373
1374 condition = condition_new(CONDITION_CPU_PRESSURE, "10% 5min", false, false);
1375 assert_se(condition);
1376 assert_se(condition_test(condition, environ) < 0);
1377 condition_free(condition);
1378
1379 condition = condition_new(CONDITION_CPU_PRESSURE, "/5min", false, false);
1380 assert_se(condition);
1381 assert_se(condition_test(condition, environ) < 0);
1382 condition_free(condition);
1383
1384 condition = condition_new(CONDITION_IO_PRESSURE, "10s / ", false, false);
1385 assert_se(condition);
1386 assert_se(condition_test(condition, environ) < 0);
1387 condition_free(condition);
1388
1389 condition = condition_new(CONDITION_MEMORY_PRESSURE, "100%", false, false);
1390 assert_se(condition);
1391 assert_se(condition_test(condition, environ) >= 0);
1392 condition_free(condition);
1393
1394 condition = condition_new(CONDITION_MEMORY_PRESSURE, "0%", false, false);
1395 assert_se(condition);
1396 assert_se(condition_test(condition, environ) >= 0);
1397 condition_free(condition);
1398
1399 condition = condition_new(CONDITION_MEMORY_PRESSURE, "0.0%", false, false);
1400 assert_se(condition);
1401 assert_se(condition_test(condition, environ) >= 0);
1402 condition_free(condition);
1403
1404 condition = condition_new(CONDITION_CPU_PRESSURE, "100%", false, false);
1405 assert_se(condition);
1406 assert_se(condition_test(condition, environ) >= 0);
1407 condition_free(condition);
1408
1409 condition = condition_new(CONDITION_CPU_PRESSURE, "0%", false, false);
1410 assert_se(condition);
1411 assert_se(condition_test(condition, environ) >= 0);
1412 condition_free(condition);
1413
1414 condition = condition_new(CONDITION_CPU_PRESSURE, "0.0%", false, false);
1415 assert_se(condition);
1416 assert_se(condition_test(condition, environ) >= 0);
1417 condition_free(condition);
1418
1419 condition = condition_new(CONDITION_CPU_PRESSURE, "0.01%", false, false);
1420 assert_se(condition);
1421 assert_se(condition_test(condition, environ) >= 0);
1422 condition_free(condition);
1423
1424 condition = condition_new(CONDITION_CPU_PRESSURE, "0.0%/10sec", false, false);
1425 assert_se(condition);
1426 assert_se(condition_test(condition, environ) >= 0);
1427 condition_free(condition);
1428
1429 condition = condition_new(CONDITION_CPU_PRESSURE, "100.0% / 1min", false, false);
1430 assert_se(condition);
1431 assert_se(condition_test(condition, environ) >= 0);
1432 condition_free(condition);
1433
1434 condition = condition_new(CONDITION_IO_PRESSURE, "50.0% / 1min", false, false);
1435 assert_se(condition);
1436 assert_se(condition_test(condition, environ) >= 0);
1437 condition_free(condition);
1438
1439 r = cg_all_unified();
1440 if (r < 0)
1441 return (void) log_notice("Failed to determine whether the unified cgroups hierarchy is used, skipping %s", __func__);
1442 if (r == 0)
1443 return (void) log_notice("Requires the unified cgroups hierarchy, skipping %s", __func__);
1444
1445 if (cg_mask_supported(&mask) < 0)
1446 return (void) log_notice("Failed to get supported cgroup controllers, skipping %s", __func__);
1447
1448 if (!FLAGS_SET(mask, CGROUP_MASK_MEMORY))
1449 return (void) log_notice("Requires the cgroup memory controller, skipping %s", __func__);
1450
1451 if (!FLAGS_SET(mask, CGROUP_MASK_CPU))
1452 return (void) log_notice("Requires the cgroup CPU controller, skipping %s", __func__);
1453
1454 condition = condition_new(CONDITION_MEMORY_PRESSURE, " : / ", false, false);
1455 assert_se(condition);
1456 assert_se(condition_test(condition, environ) < 0);
1457 condition_free(condition);
1458
1459 condition = condition_new(CONDITION_CPU_PRESSURE, "hopefullythisisnotarealone.slice:100% / 10sec", false, false);
1460 assert_se(condition);
1461 assert_se(condition_test(condition, environ) > 0);
1462 condition_free(condition);
1463
1464 condition = condition_new(CONDITION_CPU_PRESSURE, "-.slice:100.0% / 1min", false, false);
1465 assert_se(condition);
1466 assert_se(condition_test(condition, environ) >= 0);
1467 condition_free(condition);
1468
1469 condition = condition_new(CONDITION_MEMORY_PRESSURE, "-.slice:0.0%/5min", false, false);
1470 assert_se(condition);
1471 assert_se(condition_test(condition, environ) >= 0);
1472 condition_free(condition);
1473
1474 condition = condition_new(CONDITION_MEMORY_PRESSURE, "-.slice:100.0%", false, false);
1475 assert_se(condition);
1476 assert_se(condition_test(condition, environ) >= 0);
1477 condition_free(condition);
1478
1479 condition = condition_new(CONDITION_IO_PRESSURE, "-.slice:0.0%", false, false);
1480 assert_se(condition);
1481 assert_se(condition_test(condition, environ) >= 0);
1482 condition_free(condition);
1483 }
1484
1485 DEFINE_TEST_MAIN(LOG_DEBUG);