]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/test/test-condition.c
nulstr-util: Declare NULSTR_FOREACH() iterator inline
[thirdparty/systemd.git] / src / test / test-condition.c
CommitLineData
db9ecf05 1/* SPDX-License-Identifier: LGPL-2.1-or-later */
b08f2be6 2
c465a29f
FS
3#include <stdio.h>
4#include <sys/types.h>
5022f08a 5#include <sys/utsname.h>
c465a29f
FS
6#include <unistd.h>
7
d1bddcec 8#include "sd-id128.h"
07630cea 9
b5efdb8a 10#include "alloc-util.h"
07630cea
LP
11#include "apparmor-util.h"
12#include "architecture.h"
430f0182 13#include "audit-util.h"
e16647c3 14#include "cgroup-util.h"
2767027b 15#include "condition.h"
f44b3035 16#include "cpu-set-util.h"
0bb2f0f1 17#include "efi-loader.h"
4f80cfca 18#include "env-util.h"
3c14dc61 19#include "errno-util.h"
bf07a125 20#include "fileio.h"
4f80cfca 21#include "fs-util.h"
07630cea 22#include "hostname-util.h"
40a23924 23#include "id128-util.h"
015df1f7 24#include "ima-util.h"
a70984c0 25#include "limits-util.h"
07630cea
LP
26#include "log.h"
27#include "macro.h"
d8b4d14d 28#include "nulstr-util.h"
1e26f8a6 29#include "os-util.h"
4f80cfca 30#include "path-util.h"
a70984c0 31#include "process-util.h"
81513b38 32#include "psi-util.h"
4f80cfca 33#include "rm-rf.h"
07630cea 34#include "selinux-util.h"
e16647c3 35#include "set.h"
015df1f7 36#include "smack-util.h"
5022f08a 37#include "string-util.h"
239a5707 38#include "strv.h"
d8b4d14d 39#include "tests.h"
4f80cfca 40#include "tmpfile-util.h"
fc65dabd 41#include "tomoyo-util.h"
06795b02 42#include "udev-util.h"
b085d224 43#include "uid-alloc-range.h"
c465a29f 44#include "user-util.h"
5022f08a 45#include "virt.h"
d1bddcec 46
4f7452a8 47TEST(condition_test_path) {
d1bddcec
LP
48 Condition *condition;
49
50 condition = condition_new(CONDITION_PATH_EXISTS, "/bin/sh", false, false);
4d548a7d 51 assert_se(condition);
18f806b8 52 assert_se(condition_test(condition, environ) > 0);
d1bddcec
LP
53 condition_free(condition);
54
b80ba1da 55 condition = condition_new(CONDITION_PATH_EXISTS, "/bin/s?", false, false);
4d548a7d 56 assert_se(condition);
a0b191b7 57 assert_se(condition_test(condition, environ) == 0);
b80ba1da
LP
58 condition_free(condition);
59
60 condition = condition_new(CONDITION_PATH_EXISTS_GLOB, "/bin/s?", false, false);
4d548a7d 61 assert_se(condition);
a0b191b7 62 assert_se(condition_test(condition, environ) > 0);
b80ba1da
LP
63 condition_free(condition);
64
65 condition = condition_new(CONDITION_PATH_EXISTS_GLOB, "/bin/s?", false, true);
4d548a7d 66 assert_se(condition);
a0b191b7 67 assert_se(condition_test(condition, environ) == 0);
b80ba1da
LP
68 condition_free(condition);
69
d1bddcec 70 condition = condition_new(CONDITION_PATH_EXISTS, "/thiscertainlywontexist", false, false);
4d548a7d 71 assert_se(condition);
a0b191b7 72 assert_se(condition_test(condition, environ) == 0);
d1bddcec
LP
73 condition_free(condition);
74
75 condition = condition_new(CONDITION_PATH_EXISTS, "/thiscertainlywontexist", false, true);
4d548a7d 76 assert_se(condition);
a0b191b7 77 assert_se(condition_test(condition, environ) > 0);
d1bddcec 78 condition_free(condition);
b80ba1da
LP
79
80 condition = condition_new(CONDITION_PATH_IS_DIRECTORY, "/bin", false, false);
4d548a7d 81 assert_se(condition);
a0b191b7 82 assert_se(condition_test(condition, environ) > 0);
b80ba1da
LP
83 condition_free(condition);
84
85 condition = condition_new(CONDITION_DIRECTORY_NOT_EMPTY, "/bin", false, false);
4d548a7d 86 assert_se(condition);
a0b191b7 87 assert_se(condition_test(condition, environ) > 0);
b80ba1da
LP
88 condition_free(condition);
89
90 condition = condition_new(CONDITION_FILE_NOT_EMPTY, "/bin/sh", false, false);
4d548a7d 91 assert_se(condition);
a0b191b7 92 assert_se(condition_test(condition, environ) > 0);
b80ba1da
LP
93 condition_free(condition);
94
95 condition = condition_new(CONDITION_FILE_IS_EXECUTABLE, "/bin/sh", false, false);
4d548a7d 96 assert_se(condition);
a0b191b7 97 assert_se(condition_test(condition, environ) > 0);
b80ba1da
LP
98 condition_free(condition);
99
100 condition = condition_new(CONDITION_FILE_IS_EXECUTABLE, "/etc/passwd", false, false);
4d548a7d 101 assert_se(condition);
a0b191b7 102 assert_se(condition_test(condition, environ) == 0);
b80ba1da
LP
103 condition_free(condition);
104
105 condition = condition_new(CONDITION_PATH_IS_MOUNT_POINT, "/proc", false, false);
4d548a7d 106 assert_se(condition);
a0b191b7 107 assert_se(condition_test(condition, environ) > 0);
b80ba1da
LP
108 condition_free(condition);
109
110 condition = condition_new(CONDITION_PATH_IS_MOUNT_POINT, "/", false, false);
4d548a7d 111 assert_se(condition);
a0b191b7 112 assert_se(condition_test(condition, environ) > 0);
b80ba1da
LP
113 condition_free(condition);
114
115 condition = condition_new(CONDITION_PATH_IS_MOUNT_POINT, "/bin", false, false);
4d548a7d 116 assert_se(condition);
a0b191b7 117 assert_se(condition_test(condition, environ) == 0);
b80ba1da 118 condition_free(condition);
015df1f7
RC
119
120 condition = condition_new(CONDITION_PATH_IS_READ_WRITE, "/tmp", false, false);
4d548a7d 121 assert_se(condition);
a0b191b7 122 assert_se(condition_test(condition, environ) > 0);
015df1f7
RC
123 condition_free(condition);
124
7f19247b
LP
125 condition = condition_new(CONDITION_PATH_IS_ENCRYPTED, "/sys", false, false);
126 assert_se(condition);
a0b191b7 127 assert_se(condition_test(condition, environ) == 0);
7f19247b
LP
128 condition_free(condition);
129
015df1f7 130 condition = condition_new(CONDITION_PATH_IS_SYMBOLIC_LINK, "/dev/stdout", false, false);
4d548a7d 131 assert_se(condition);
a0b191b7 132 assert_se(condition_test(condition, environ) > 0);
015df1f7 133 condition_free(condition);
d1bddcec 134}
b08f2be6 135
4f7452a8 136TEST(condition_test_control_group_hierarchy) {
8ebfd50a
ZJS
137 Condition *condition;
138 int r;
139
140 r = cg_unified();
b66789a9
DS
141 if (r == -ENOMEDIUM) {
142 log_tests_skipped("cgroup not mounted");
143 return;
144 }
145 assert_se(r >= 0);
8ebfd50a
ZJS
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
4f7452a8 158TEST(condition_test_control_group_controller) {
e16647c3
CD
159 Condition *condition;
160 CGroupMask system_mask;
e16647c3
CD
161 _cleanup_free_ char *controller_name = NULL;
162 int r;
163
d4d99bc6 164 r = cg_unified();
b66789a9
DS
165 if (r == -ENOMEDIUM) {
166 log_tests_skipped("cgroup not mounted");
8b81c382 167 return;
e16647c3 168 }
b66789a9 169 assert_se(r >= 0);
e16647c3
CD
170
171 /* Invalid controllers are ignored */
172 condition = condition_new(CONDITION_CONTROL_GROUP_CONTROLLER, "thisisnotarealcontroller", false, false);
173 assert_se(condition);
a0b191b7 174 assert_se(condition_test(condition, environ) > 0);
e16647c3
CD
175 condition_free(condition);
176
177 condition = condition_new(CONDITION_CONTROL_GROUP_CONTROLLER, "thisisnotarealcontroller", false, true);
178 assert_se(condition);
a0b191b7 179 assert_se(condition_test(condition, environ) == 0);
e16647c3
CD
180 condition_free(condition);
181
182 assert_se(cg_mask_supported(&system_mask) >= 0);
183
184 /* Individual valid controllers one by one */
8ebfd50a 185 for (CGroupController controller = 0; controller < _CGROUP_CONTROLLER_MAX; controller++) {
e16647c3
CD
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);
a0b191b7 192 assert_se(condition_test(condition, environ) > 0);
e16647c3
CD
193 condition_free(condition);
194
195 condition = condition_new(CONDITION_CONTROL_GROUP_CONTROLLER, local_controller_name, false, true);
196 assert_se(condition);
a0b191b7 197 assert_se(condition_test(condition, environ) == 0);
e16647c3
CD
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);
a0b191b7 203 assert_se(condition_test(condition, environ) == 0);
e16647c3
CD
204 condition_free(condition);
205
206 condition = condition_new(CONDITION_CONTROL_GROUP_CONTROLLER, local_controller_name, false, true);
207 assert_se(condition);
a0b191b7 208 assert_se(condition_test(condition, environ) > 0);
e16647c3
CD
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
2767027b 216 condition = condition_new(CONDITION_CONTROL_GROUP_CONTROLLER, strempty(controller_name), false, false);
e16647c3 217 assert_se(condition);
a0b191b7 218 assert_se(condition_test(condition, environ) > 0);
e16647c3
CD
219 condition_free(condition);
220
2767027b 221 condition = condition_new(CONDITION_CONTROL_GROUP_CONTROLLER, strempty(controller_name), false, true);
e16647c3 222 assert_se(condition);
a0b191b7 223 assert_se(condition_test(condition, environ) == 0);
e16647c3 224 condition_free(condition);
e16647c3
CD
225}
226
4f7452a8 227TEST(condition_test_ac_power) {
b08f2be6
RC
228 Condition *condition;
229
230 condition = condition_new(CONDITION_AC_POWER, "true", false, false);
4d548a7d 231 assert_se(condition);
a0b191b7 232 assert_se(condition_test(condition, environ) == on_ac_power());
b08f2be6
RC
233 condition_free(condition);
234
235 condition = condition_new(CONDITION_AC_POWER, "false", false, false);
4d548a7d 236 assert_se(condition);
a0b191b7 237 assert_se(condition_test(condition, environ) != on_ac_power());
b08f2be6
RC
238 condition_free(condition);
239
240 condition = condition_new(CONDITION_AC_POWER, "false", false, true);
4d548a7d 241 assert_se(condition);
a0b191b7 242 assert_se(condition_test(condition, environ) == on_ac_power());
b08f2be6
RC
243 condition_free(condition);
244}
245
4f7452a8 246TEST(condition_test_host) {
4d548a7d 247 _cleanup_free_ char *hostname = NULL;
b08f2be6
RC
248 Condition *condition;
249 sd_id128_t id;
b7af9b43 250 int r;
b08f2be6 251
b7af9b43
LB
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);
b08f2be6 256
85b55869 257 condition = condition_new(CONDITION_HOST, SD_ID128_TO_STRING(id), false, false);
4d548a7d 258 assert_se(condition);
a0b191b7 259 assert_se(condition_test(condition, environ) > 0);
b08f2be6
RC
260 condition_free(condition);
261
262 condition = condition_new(CONDITION_HOST, "garbage value jjjjjjjjjjjjjj", false, false);
4d548a7d 263 assert_se(condition);
a0b191b7 264 assert_se(condition_test(condition, environ) == 0);
b08f2be6
RC
265 condition_free(condition);
266
85b55869 267 condition = condition_new(CONDITION_HOST, SD_ID128_TO_STRING(id), false, true);
4d548a7d 268 assert_se(condition);
a0b191b7 269 assert_se(condition_test(condition, environ) == 0);
b08f2be6
RC
270 condition_free(condition);
271
272 hostname = gethostname_malloc();
273 assert_se(hostname);
274
40a23924 275 /* if hostname looks like an id128 then skip testing it */
ce5fcc69 276 if (id128_is_valid(hostname))
40a23924 277 log_notice("hostname is an id128, skipping test");
ce5fcc69 278 else {
40a23924 279 condition = condition_new(CONDITION_HOST, hostname, false, false);
4d548a7d 280 assert_se(condition);
a0b191b7 281 assert_se(condition_test(condition, environ) > 0);
40a23924
SM
282 condition_free(condition);
283 }
b08f2be6
RC
284}
285
4f7452a8 286TEST(condition_test_architecture) {
b08f2be6 287 Condition *condition;
b08f2be6 288 const char *sa;
6b41a7b2 289 Architecture a;
b08f2be6
RC
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);
4d548a7d 298 assert_se(condition);
a0b191b7 299 assert_se(condition_test(condition, environ) > 0);
b08f2be6
RC
300 condition_free(condition);
301
302 condition = condition_new(CONDITION_ARCHITECTURE, "garbage value", false, false);
4d548a7d 303 assert_se(condition);
a0b191b7 304 assert_se(condition_test(condition, environ) == 0);
b08f2be6
RC
305 condition_free(condition);
306
307 condition = condition_new(CONDITION_ARCHITECTURE, sa, false, true);
4d548a7d 308 assert_se(condition);
a0b191b7 309 assert_se(condition_test(condition, environ) == 0);
b08f2be6
RC
310 condition_free(condition);
311}
312
d8d2039c
DB
313TEST(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
329TEST(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
379TEST(condition_test_firmware_smbios) {
380 Condition *condition;
bf07a125
DB
381 _cleanup_free_ char *bios_vendor = NULL, *bios_version = NULL;
382 const char *expression;
bf07a125 383
d8d2039c 384 /* smbios-field parameter */
bf07a125
DB
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() */
71a3ff03 433 expression = strjoina("smbios-field(bios_vendor $= ", quote, bios_vendor, quote, ")");
bf07a125
DB
434 condition = condition_new(CONDITION_FIRMWARE, expression, false, false);
435 assert_se(condition);
acd3c866 436 assert_se(condition_test(condition, environ) > 0);
bf07a125
DB
437 condition_free(condition);
438
71a3ff03 439 expression = strjoina("smbios-field(bios_vendor$=", quote, bios_vendor, quote, ")");
bf07a125
DB
440 condition = condition_new(CONDITION_FIRMWARE, expression, false, false);
441 assert_se(condition);
acd3c866 442 assert_se(condition_test(condition, environ) > 0);
bf07a125
DB
443 condition_free(condition);
444
71a3ff03 445 expression = strjoina("smbios-field(bios_vendor !$= ", quote, bios_vendor, quote, ")");
bf07a125
DB
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
71a3ff03 451 expression = strjoina("smbios-field(bios_vendor!$=", quote, bios_vendor, quote, ")");
bf07a125
DB
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
71a3ff03 457 expression = strjoina("smbios-field(bios_vendor $= ", quote, bios_vendor, "*", quote, ")");
bf07a125
DB
458 condition = condition_new(CONDITION_FIRMWARE, expression, false, false);
459 assert_se(condition);
acd3c866 460 assert_se(condition_test(condition, environ) > 0);
bf07a125
DB
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);
acd3c866 476 assert_se(condition_test(condition, environ) > 0);
bf07a125
DB
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);
acd3c866 488 assert_se(condition_test(condition, environ) > 0);
bf07a125
DB
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);
acd3c866 494 assert_se(condition_test(condition, environ) > 0);
bf07a125
DB
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);
acd3c866 500 assert_se(condition_test(condition, environ) > 0);
bf07a125
DB
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
4f7452a8 510TEST(condition_test_kernel_command_line) {
07318c29 511 Condition *condition;
3c14dc61 512 int r;
07318c29
LP
513
514 condition = condition_new(CONDITION_KERNEL_COMMAND_LINE, "thisreallyshouldntbeonthekernelcommandline", false, false);
4d548a7d 515 assert_se(condition);
a0b191b7 516 r = condition_test(condition, environ);
3c14dc61
TM
517 if (ERRNO_IS_PRIVILEGE(r))
518 return;
519 assert_se(r == 0);
07318c29
LP
520 condition_free(condition);
521
522 condition = condition_new(CONDITION_KERNEL_COMMAND_LINE, "andthis=neither", false, false);
4d548a7d 523 assert_se(condition);
a0b191b7 524 assert_se(condition_test(condition, environ) == 0);
07318c29
LP
525 condition_free(condition);
526}
527
4f7452a8 528TEST(condition_test_kernel_version) {
5022f08a
LP
529 Condition *condition;
530 struct utsname u;
68c58c67 531 const char *v;
5022f08a
LP
532
533 condition = condition_new(CONDITION_KERNEL_VERSION, "*thisreallyshouldntbeinthekernelversion*", false, false);
534 assert_se(condition);
a0b191b7 535 assert_se(condition_test(condition, environ) == 0);
5022f08a
LP
536 condition_free(condition);
537
538 condition = condition_new(CONDITION_KERNEL_VERSION, "*", false, false);
539 assert_se(condition);
a0b191b7 540 assert_se(condition_test(condition, environ) > 0);
5022f08a
LP
541 condition_free(condition);
542
910c6d09
ZJS
543 /* An artificially empty condition. It evaluates to true, but normally
544 * such condition cannot be created, because the condition list is reset instead. */
5022f08a
LP
545 condition = condition_new(CONDITION_KERNEL_VERSION, "", false, false);
546 assert_se(condition);
a0b191b7 547 assert_se(condition_test(condition, environ) > 0);
5022f08a
LP
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);
a0b191b7 554 assert_se(condition_test(condition, environ) > 0);
5022f08a
LP
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);
a0b191b7 562 assert_se(condition_test(condition, environ) > 0);
5022f08a 563 condition_free(condition);
68c58c67
LP
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);
a0b191b7 568 assert_se(condition_test(condition, environ) > 0);
68c58c67
LP
569 condition_free(condition);
570
910c6d09
ZJS
571 condition = condition_new(CONDITION_KERNEL_VERSION, ">0.1.2", false, false);
572 assert_se(condition);
a0b191b7 573 assert_se(condition_test(condition, environ) > 0);
910c6d09
ZJS
574 condition_free(condition);
575
576 condition = condition_new(CONDITION_KERNEL_VERSION, "'>0.1.2' '<9.0.0'", false, false);
577 assert_se(condition);
a0b191b7 578 assert_se(condition_test(condition, environ) > 0);
910c6d09
ZJS
579 condition_free(condition);
580
581 condition = condition_new(CONDITION_KERNEL_VERSION, "> 0.1.2 < 9.0.0", false, false);
582 assert_se(condition);
a0b191b7 583 assert_se(condition_test(condition, environ) == -EINVAL);
910c6d09
ZJS
584 condition_free(condition);
585
586 condition = condition_new(CONDITION_KERNEL_VERSION, ">", false, false);
587 assert_se(condition);
a0b191b7 588 assert_se(condition_test(condition, environ) == -EINVAL);
910c6d09
ZJS
589 condition_free(condition);
590
68c58c67
LP
591 condition = condition_new(CONDITION_KERNEL_VERSION, ">= 0.1.2", false, false);
592 assert_se(condition);
a0b191b7 593 assert_se(condition_test(condition, environ) > 0);
68c58c67
LP
594 condition_free(condition);
595
596 condition = condition_new(CONDITION_KERNEL_VERSION, "< 0.1.2", false, false);
597 assert_se(condition);
a0b191b7 598 assert_se(condition_test(condition, environ) == 0);
68c58c67
LP
599 condition_free(condition);
600
601 condition = condition_new(CONDITION_KERNEL_VERSION, "<= 0.1.2", false, false);
602 assert_se(condition);
a0b191b7 603 assert_se(condition_test(condition, environ) == 0);
68c58c67
LP
604 condition_free(condition);
605
606 condition = condition_new(CONDITION_KERNEL_VERSION, "= 0.1.2", false, false);
607 assert_se(condition);
a0b191b7 608 assert_se(condition_test(condition, environ) == 0);
68c58c67
LP
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);
a0b191b7 614 assert_se(condition_test(condition, environ) > 0);
68c58c67
LP
615 condition_free(condition);
616
617 condition = condition_new(CONDITION_KERNEL_VERSION, "<= 4711.8.15", false, false);
618 assert_se(condition);
a0b191b7 619 assert_se(condition_test(condition, environ) > 0);
68c58c67
LP
620 condition_free(condition);
621
622 condition = condition_new(CONDITION_KERNEL_VERSION, "= 4711.8.15", false, false);
623 assert_se(condition);
a0b191b7 624 assert_se(condition_test(condition, environ) == 0);
68c58c67
LP
625 condition_free(condition);
626
627 condition = condition_new(CONDITION_KERNEL_VERSION, "> 4711.8.15", false, false);
628 assert_se(condition);
a0b191b7 629 assert_se(condition_test(condition, environ) == 0);
68c58c67
LP
630 condition_free(condition);
631
bf07a125 632 condition = condition_new(CONDITION_KERNEL_VERSION, " >= 4711.8.15", false, false);
68c58c67 633 assert_se(condition);
a0b191b7 634 assert_se(condition_test(condition, environ) == 0);
68c58c67
LP
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);
a0b191b7 642 assert_se(condition_test(condition, environ) > 0);
68c58c67
LP
643 condition_free(condition);
644
645 v = strjoina("= ", u.release);
646 condition = condition_new(CONDITION_KERNEL_VERSION, v, false, false);
647 assert_se(condition);
a0b191b7 648 assert_se(condition_test(condition, environ) > 0);
68c58c67
LP
649 condition_free(condition);
650
651 v = strjoina("<=", u.release);
652 condition = condition_new(CONDITION_KERNEL_VERSION, v, false, false);
653 assert_se(condition);
a0b191b7 654 assert_se(condition_test(condition, environ) > 0);
68c58c67
LP
655 condition_free(condition);
656
657 v = strjoina("> ", u.release);
658 condition = condition_new(CONDITION_KERNEL_VERSION, v, false, false);
659 assert_se(condition);
a0b191b7 660 assert_se(condition_test(condition, environ) == 0);
68c58c67
LP
661 condition_free(condition);
662
663 v = strjoina("< ", u.release);
664 condition = condition_new(CONDITION_KERNEL_VERSION, v, false, false);
665 assert_se(condition);
a0b191b7 666 assert_se(condition_test(condition, environ) == 0);
68c58c67 667 condition_free(condition);
5022f08a
LP
668}
669
4f80cfca
LP
670TEST(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
68337e55 724#if defined(__i386__) || defined(__x86_64__)
4f7452a8 725TEST(condition_test_cpufeature) {
68337e55
GS
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
4f7452a8 745TEST(condition_test_security) {
015df1f7
RC
746 Condition *condition;
747
748 condition = condition_new(CONDITION_SECURITY, "garbage oifdsjfoidsjoj", false, false);
4d548a7d 749 assert_se(condition);
a0b191b7 750 assert_se(condition_test(condition, environ) == 0);
015df1f7
RC
751 condition_free(condition);
752
753 condition = condition_new(CONDITION_SECURITY, "selinux", false, true);
4d548a7d 754 assert_se(condition);
a0b191b7 755 assert_se(condition_test(condition, environ) != mac_selinux_use());
015df1f7
RC
756 condition_free(condition);
757
fc65dabd 758 condition = condition_new(CONDITION_SECURITY, "apparmor", false, false);
4d548a7d 759 assert_se(condition);
a0b191b7 760 assert_se(condition_test(condition, environ) == mac_apparmor_use());
015df1f7
RC
761 condition_free(condition);
762
fc65dabd 763 condition = condition_new(CONDITION_SECURITY, "tomoyo", false, false);
4d548a7d 764 assert_se(condition);
a0b191b7 765 assert_se(condition_test(condition, environ) == mac_tomoyo_use());
fc65dabd
ZJS
766 condition_free(condition);
767
768 condition = condition_new(CONDITION_SECURITY, "ima", false, false);
769 assert_se(condition);
a0b191b7 770 assert_se(condition_test(condition, environ) == use_ima());
015df1f7
RC
771 condition_free(condition);
772
773 condition = condition_new(CONDITION_SECURITY, "smack", false, false);
4d548a7d 774 assert_se(condition);
a0b191b7 775 assert_se(condition_test(condition, environ) == mac_smack_use());
015df1f7
RC
776 condition_free(condition);
777
778 condition = condition_new(CONDITION_SECURITY, "audit", false, false);
4d548a7d 779 assert_se(condition);
a0b191b7 780 assert_se(condition_test(condition, environ) == use_audit());
015df1f7 781 condition_free(condition);
fc65dabd
ZJS
782
783 condition = condition_new(CONDITION_SECURITY, "uefi-secureboot", false, false);
784 assert_se(condition);
a0b191b7 785 assert_se(condition_test(condition, environ) == is_efi_secure_boot());
fc65dabd
ZJS
786 condition_free(condition);
787}
788
4f7452a8 789TEST(print_securities) {
fc65dabd
ZJS
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("-------------------------------------------");
015df1f7
RC
799}
800
4f7452a8 801TEST(condition_test_virtualization) {
239a5707 802 Condition *condition;
239a5707
ZJS
803 int r;
804
805 condition = condition_new(CONDITION_VIRTUALIZATION, "garbage oifdsjfoidsjoj", false, false);
806 assert_se(condition);
a0b191b7 807 r = condition_test(condition, environ);
3c14dc61
TM
808 if (ERRNO_IS_PRIVILEGE(r))
809 return;
239a5707
ZJS
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);
a0b191b7 816 r = condition_test(condition, environ);
239a5707
ZJS
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);
a0b191b7 823 r = condition_test(condition, environ);
239a5707
ZJS
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);
a0b191b7 830 r = condition_test(condition, environ);
239a5707
ZJS
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"
b6eca373 837 "amazon\0"
239a5707
ZJS
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);
a0b191b7 852 r = condition_test(condition, environ);
239a5707
ZJS
853 log_info("ConditionVirtualization=%s → %i", virt, r);
854 assert_se(r >= 0);
855 condition_free(condition);
856 }
857}
858
4f7452a8 859TEST(condition_test_user) {
c465a29f
FS
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);
a0b191b7 867 r = condition_test(condition, environ);
c465a29f
FS
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);
a0b191b7 875 r = condition_test(condition, environ);
c465a29f
FS
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);
a0b191b7 884 r = condition_test(condition, environ);
c465a29f
FS
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);
a0b191b7 893 r = condition_test(condition, environ);
c465a29f
FS
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);
a0b191b7 903 r = condition_test(condition, environ);
c465a29f
FS
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);
a0b191b7 912 r = condition_test(condition, environ);
c465a29f
FS
913 log_info("ConditionUser=%s → %i", username, r);
914 assert_se(r == 0);
915 condition_free(condition);
534bab66
FS
916
917 condition = condition_new(CONDITION_USER, "@system", false, false);
918 assert_se(condition);
a0b191b7 919 r = condition_test(condition, environ);
534bab66 920 log_info("ConditionUser=@system → %i", r);
ece877d4 921 if (uid_is_system(getuid()) || uid_is_system(geteuid()))
534bab66
FS
922 assert_se(r > 0);
923 else
924 assert_se(r == 0);
925 condition_free(condition);
c465a29f
FS
926}
927
4f7452a8 928TEST(condition_test_group) {
c465a29f
FS
929 Condition *condition;
930 char* gid;
931 char* groupname;
932 gid_t *gids, max_gid;
ecaa5ad8 933 int ngroups_max, ngroups, r, i;
c465a29f
FS
934
935 assert_se(0 < asprintf(&gid, "%u", UINT32_C(0xFFFF)));
936 condition = condition_new(CONDITION_GROUP, gid, false, false);
937 assert_se(condition);
a0b191b7 938 r = condition_test(condition, environ);
c465a29f
FS
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);
a0b191b7 947 r = condition_test(condition, environ);
c465a29f
FS
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);
f21b863e 954 assert_se(ngroups_max > 0);
c465a29f 955
cf409d15 956 gids = newa(gid_t, ngroups_max);
c465a29f 957
ecaa5ad8 958 ngroups = getgroups(ngroups_max, gids);
f21b863e 959 assert_se(ngroups >= 0);
c465a29f
FS
960
961 max_gid = getgid();
ecaa5ad8 962 for (i = 0; i < ngroups; i++) {
c465a29f
FS
963 assert_se(0 < asprintf(&gid, "%u", gids[i]));
964 condition = condition_new(CONDITION_GROUP, gid, false, false);
965 assert_se(condition);
a0b191b7 966 r = condition_test(condition, environ);
c465a29f
FS
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);
a0b191b7 977 r = condition_test(condition, environ);
c465a29f
FS
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);
a0b191b7 988 r = condition_test(condition, environ);
c465a29f
FS
989 log_info("ConditionGroup=%s → %i", gid, r);
990 assert_se(r == 0);
991 condition_free(condition);
992 free(gid);
993
98cd752a 994 groupname = (char*)(getegid() == 0 ? NOBODY_GROUP_NAME : "root");
c465a29f
FS
995 condition = condition_new(CONDITION_GROUP, groupname, false, false);
996 assert_se(condition);
a0b191b7 997 r = condition_test(condition, environ);
c465a29f
FS
998 log_info("ConditionGroup=%s → %i", groupname, r);
999 assert_se(r == 0);
1000 condition_free(condition);
1001}
1002
a70984c0
LP
1003static 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
a0b191b7 1012 r = condition_test(condition, environ);
a70984c0
LP
1013 assert_se(r >= 0);
1014 assert_se(r == result);
1015 condition_free(condition);
1016}
1017
4f7452a8 1018TEST(condition_test_cpus) {
a70984c0
LP
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
1064static 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
a0b191b7 1073 r = condition_test(condition, environ);
a70984c0
LP
1074 assert_se(r >= 0);
1075 assert_se(r == result);
1076 condition_free(condition);
1077}
1078
4f7452a8 1079TEST(condition_test_memory) {
a70984c0
LP
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
a61473bd
ZJS
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
a70984c0
LP
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
a0b191b7
LP
1145static 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
4f7452a8 1160TEST(condition_test_environment) {
a0b191b7
LP
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
4f7452a8 1173TEST(condition_test_os_release) {
1e26f8a6
LB
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);
18f806b8 1227 assert_se(condition_test(condition, environ) > 0);
1e26f8a6
LB
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);
18f806b8 1237 assert_se(condition_test(condition, environ) > 0);
1e26f8a6
LB
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
bf07a125 1246 /* Test fnmatch() operators */
71a3ff03 1247 key_value_pair = strjoina(os_release_pairs[0], "$=", quote, os_release_pairs[1], quote);
bf07a125
DB
1248 condition = condition_new(CONDITION_OS_RELEASE, key_value_pair, false, false);
1249 assert_se(condition);
8daa6740 1250 assert_se(condition_test(condition, environ) > 0);
bf07a125
DB
1251 condition_free(condition);
1252
71a3ff03 1253 key_value_pair = strjoina(os_release_pairs[0], "!$=", quote, os_release_pairs[1], quote);
bf07a125
DB
1254 condition = condition_new(CONDITION_OS_RELEASE, key_value_pair, false, false);
1255 assert_se(condition);
8daa6740 1256 assert_se(condition_test(condition, environ) == 0);
bf07a125
DB
1257 condition_free(condition);
1258
1e26f8a6
LB
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);
18f806b8 1266 assert_se(condition_test(condition, environ) > 0);
1e26f8a6
LB
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);
18f806b8 1278 assert_se(condition_test(condition, environ) > 0);
1e26f8a6
LB
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);
18f806b8 1284 assert_se(condition_test(condition, environ) > 0);
1e26f8a6
LB
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);
18f806b8 1290 assert_se(condition_test(condition, environ) > 0);
1e26f8a6
LB
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);
18f806b8 1302 assert_se(condition_test(condition, environ) > 0);
1e26f8a6
LB
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);
18f806b8 1326 assert_se(condition_test(condition, environ) > 0);
1e26f8a6
LB
1327 condition_free(condition);
1328}
1329
81513b38
LB
1330TEST(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
4f7452a8 1484DEFINE_TEST_MAIN(LOG_DEBUG);