summaryrefslogtreecommitdiff
path: root/src/test
diff options
context:
space:
mode:
Diffstat (limited to 'src/test')
-rw-r--r--src/test/test-acl-util.c2
-rw-r--r--src/test/test-async.c2
-rw-r--r--src/test/test-calendarspec.c50
-rw-r--r--src/test/test-cgroup-util.c25
-rw-r--r--src/test/test-clock.c2
-rw-r--r--src/test/test-condition.c111
-rw-r--r--src/test/test-copy.c12
-rw-r--r--src/test/test-dns-domain.c3
-rw-r--r--src/test/test-engine.c2
-rw-r--r--src/test/test-execute.c119
-rw-r--r--src/test/test-fd-util.c8
-rw-r--r--src/test/test-fdset.c16
-rw-r--r--src/test/test-fileio.c24
-rw-r--r--src/test/test-fs-util.c168
-rw-r--r--src/test/test-glob-util.c2
-rw-r--r--src/test/test-hostname-util.c3
-rw-r--r--src/test/test-id128.c2
-rw-r--r--src/test/test-install-root.c66
-rw-r--r--src/test/test-install.c38
-rw-r--r--src/test/test-ipcrm.c2
-rw-r--r--src/test/test-list.c23
-rw-r--r--src/test/test-ns.c22
-rw-r--r--src/test/test-parse-util.c35
-rw-r--r--src/test/test-path-util.c63
-rw-r--r--src/test/test-path.c2
-rw-r--r--src/test/test-proc-cmdline.c7
-rw-r--r--src/test/test-process-util.c4
-rw-r--r--src/test/test-sched-prio.c2
-rw-r--r--src/test/test-seccomp.c136
-rw-r--r--src/test/test-sigbus.c3
-rw-r--r--src/test/test-stat-util.c4
-rw-r--r--src/test/test-strv.c30
-rw-r--r--src/test/test-tables.c4
-rw-r--r--src/test/test-terminal-util.c2
-rw-r--r--src/test/test-time.c44
-rw-r--r--src/test/test-tmpfiles.c2
-rw-r--r--src/test/test-unit-file.c20
-rw-r--r--src/test/test-user-util.c87
38 files changed, 981 insertions, 166 deletions
diff --git a/src/test/test-acl-util.c b/src/test/test-acl-util.c
index 39302135d7..28b2e5e38c 100644
--- a/src/test/test-acl-util.c
+++ b/src/test/test-acl-util.c
@@ -35,7 +35,7 @@ static void test_add_acls_for_user(void) {
uid_t uid;
int r;
- fd = mkostemp_safe(fn, O_RDWR|O_CLOEXEC);
+ fd = mkostemp_safe(fn);
assert_se(fd >= 0);
/* Use the mode that user journal files use */
diff --git a/src/test/test-async.c b/src/test/test-async.c
index 1e4a182dfa..ba69670fe0 100644
--- a/src/test/test-async.c
+++ b/src/test/test-async.c
@@ -36,7 +36,7 @@ int main(int argc, char *argv[]) {
int fd;
char name[] = "/tmp/test-asynchronous_close.XXXXXX";
- fd = mkostemp_safe(name, O_RDWR|O_CLOEXEC);
+ fd = mkostemp_safe(name);
assert_se(fd >= 0);
asynchronous_close(fd);
diff --git a/src/test/test-calendarspec.c b/src/test/test-calendarspec.c
index 94e755bf3c..031d41fa99 100644
--- a/src/test/test-calendarspec.c
+++ b/src/test/test-calendarspec.c
@@ -73,7 +73,7 @@ static void test_next(const char *input, const char *new_tz, usec_t after, usec_
u = after;
r = calendar_spec_next_usec(c, after, &u);
- printf("At: %s\n", r < 0 ? strerror(-r) : format_timestamp_us(buf, sizeof(buf), u));
+ printf("At: %s\n", r < 0 ? strerror(-r) : format_timestamp_us(buf, sizeof buf, u));
if (expect != (usec_t)-1)
assert_se(r >= 0 && u == expect);
else
@@ -88,6 +88,51 @@ static void test_next(const char *input, const char *new_tz, usec_t after, usec_
tzset();
}
+static void test_timestamp(void) {
+ char buf[FORMAT_TIMESTAMP_MAX];
+ _cleanup_free_ char *t = NULL;
+ CalendarSpec *c;
+ usec_t x, y;
+
+ /* Ensure that a timestamp is also a valid calendar specification. Convert forth and back */
+
+ x = now(CLOCK_REALTIME);
+
+ assert_se(format_timestamp_us(buf, sizeof(buf), x));
+ printf("%s\n", buf);
+ assert_se(calendar_spec_from_string(buf, &c) >= 0);
+ assert_se(calendar_spec_to_string(c, &t) >= 0);
+ calendar_spec_free(c);
+ printf("%s\n", t);
+
+ assert_se(parse_timestamp(t, &y) >= 0);
+ assert_se(y == x);
+}
+
+static void test_hourly_bug_4031(void) {
+ CalendarSpec *c;
+ usec_t n, u, w;
+ char buf[FORMAT_TIMESTAMP_MAX], zaf[FORMAT_TIMESTAMP_MAX];
+ int r;
+
+ assert_se(calendar_spec_from_string("hourly", &c) >= 0);
+ n = now(CLOCK_REALTIME);
+ assert_se((r = calendar_spec_next_usec(c, n, &u)) >= 0);
+
+ printf("Now: %s (%"PRIu64")\n", format_timestamp_us(buf, sizeof buf, n), n);
+ printf("Next hourly: %s (%"PRIu64")\n", r < 0 ? strerror(-r) : format_timestamp_us(buf, sizeof buf, u), u);
+
+ assert_se((r = calendar_spec_next_usec(c, u, &w)) >= 0);
+ printf("Next hourly: %s (%"PRIu64")\n", r < 0 ? strerror(-r) : format_timestamp_us(zaf, sizeof zaf, w), w);
+
+ assert_se(n < u);
+ assert_se(u <= n + USEC_PER_HOUR);
+ assert_se(u < w);
+ assert_se(w <= u + USEC_PER_HOUR);
+
+ calendar_spec_free(c);
+}
+
int main(int argc, char* argv[]) {
CalendarSpec *c;
@@ -155,5 +200,8 @@ int main(int argc, char* argv[]) {
assert_se(calendar_spec_from_string("00:00:00/0.00000001", &c) < 0);
assert_se(calendar_spec_from_string("00:00:00.0..00.9", &c) < 0);
+ test_timestamp();
+ test_hourly_bug_4031();
+
return 0;
}
diff --git a/src/test/test-cgroup-util.c b/src/test/test-cgroup-util.c
index 1b3e55083a..fe9636c5c1 100644
--- a/src/test/test-cgroup-util.c
+++ b/src/test/test-cgroup-util.c
@@ -24,6 +24,7 @@
#include "systemd-basic/formats-util.h"
#include "systemd-basic/parse-util.h"
#include "systemd-basic/process-util.h"
+#include "systemd-basic/stat-util.h"
#include "systemd-basic/string-util.h"
#include "systemd-basic/user-util.h"
#include "systemd-basic/util.h"
@@ -310,6 +311,28 @@ static void test_mask_supported(void) {
printf("'%s' is supported: %s\n", cgroup_controller_to_string(c), yes_no(m & CGROUP_CONTROLLER_TO_MASK(c)));
}
+static void test_is_cgroup_fs(void) {
+ struct statfs sfs;
+ assert_se(statfs("/sys/fs/cgroup", &sfs) == 0);
+ if (is_temporary_fs(&sfs))
+ assert_se(statfs("/sys/fs/cgroup/systemd", &sfs) == 0);
+ assert_se(is_cgroup_fs(&sfs));
+}
+
+static void test_fd_is_cgroup_fs(void) {
+ int fd;
+
+ fd = open("/sys/fs/cgroup", O_RDONLY|O_DIRECTORY|O_CLOEXEC|O_NOFOLLOW);
+ assert_se(fd >= 0);
+ if (fd_is_temporary_fs(fd)) {
+ fd = safe_close(fd);
+ fd = open("/sys/fs/cgroup/systemd", O_RDONLY|O_DIRECTORY|O_CLOEXEC|O_NOFOLLOW);
+ assert_se(fd >= 0);
+ }
+ assert_se(fd_is_cgroup_fs(fd));
+ fd = safe_close(fd);
+}
+
int main(void) {
test_path_decode_unit();
test_path_get_unit();
@@ -325,6 +348,8 @@ int main(void) {
test_slice_to_path();
test_shift_path();
TEST_REQ_RUNNING_SYSTEMD(test_mask_supported());
+ TEST_REQ_RUNNING_SYSTEMD(test_is_cgroup_fs());
+ TEST_REQ_RUNNING_SYSTEMD(test_fd_is_cgroup_fs());
return 0;
}
diff --git a/src/test/test-clock.c b/src/test/test-clock.c
index 251e41f8bd..51a6aada55 100644
--- a/src/test/test-clock.c
+++ b/src/test/test-clock.c
@@ -55,7 +55,7 @@ static void test_clock_is_localtime(void) {
/* without an adjtime file we default to UTC */
assert_se(clock_is_localtime("/nonexisting/adjtime") == 0);
- fd = mkostemp_safe(adjtime, O_WRONLY|O_CLOEXEC);
+ fd = mkostemp_safe(adjtime);
assert_se(fd >= 0);
log_info("adjtime test file: %s", adjtime);
f = fdopen(fd, "w");
diff --git a/src/test/test-condition.c b/src/test/test-condition.c
index 848de002b0..bbb4cc1bdd 100644
--- a/src/test/test-condition.c
+++ b/src/test/test-condition.c
@@ -19,6 +19,7 @@
#include <systemd/sd-id128.h>
+#include "sd-id128/id128-util.h"
#include "systemd-basic/alloc-util.h"
#include "systemd-basic/architecture.h"
#include "systemd-basic/audit-util.h"
@@ -27,7 +28,9 @@
#include "systemd-basic/macro.h"
#include "systemd-basic/selinux-util.h"
#include "systemd-basic/smack-util.h"
+#include "systemd-basic/strv.h"
#include "systemd-basic/util.h"
+#include "systemd-basic/virt.h"
#include "systemd-shared/apparmor-util.h"
#include "systemd-shared/condition.h"
#include "systemd-shared/ima-util.h"
@@ -36,66 +39,82 @@ static void test_condition_test_path(void) {
Condition *condition;
condition = condition_new(CONDITION_PATH_EXISTS, "/bin/sh", false, false);
+ assert_se(condition);
assert_se(condition_test(condition));
condition_free(condition);
condition = condition_new(CONDITION_PATH_EXISTS, "/bin/s?", false, false);
+ assert_se(condition);
assert_se(!condition_test(condition));
condition_free(condition);
condition = condition_new(CONDITION_PATH_EXISTS_GLOB, "/bin/s?", false, false);
+ assert_se(condition);
assert_se(condition_test(condition));
condition_free(condition);
condition = condition_new(CONDITION_PATH_EXISTS_GLOB, "/bin/s?", false, true);
+ assert_se(condition);
assert_se(!condition_test(condition));
condition_free(condition);
condition = condition_new(CONDITION_PATH_EXISTS, "/thiscertainlywontexist", false, false);
+ assert_se(condition);
assert_se(!condition_test(condition));
condition_free(condition);
condition = condition_new(CONDITION_PATH_EXISTS, "/thiscertainlywontexist", false, true);
+ assert_se(condition);
assert_se(condition_test(condition));
condition_free(condition);
condition = condition_new(CONDITION_PATH_IS_DIRECTORY, "/bin", false, false);
+ assert_se(condition);
assert_se(condition_test(condition));
condition_free(condition);
condition = condition_new(CONDITION_DIRECTORY_NOT_EMPTY, "/bin", false, false);
+ assert_se(condition);
assert_se(condition_test(condition));
condition_free(condition);
condition = condition_new(CONDITION_FILE_NOT_EMPTY, "/bin/sh", false, false);
+ assert_se(condition);
assert_se(condition_test(condition));
condition_free(condition);
condition = condition_new(CONDITION_FILE_IS_EXECUTABLE, "/bin/sh", false, false);
+ assert_se(condition);
assert_se(condition_test(condition));
condition_free(condition);
condition = condition_new(CONDITION_FILE_IS_EXECUTABLE, "/etc/passwd", false, false);
+ assert_se(condition);
assert_se(!condition_test(condition));
condition_free(condition);
condition = condition_new(CONDITION_PATH_IS_MOUNT_POINT, "/proc", false, false);
+ assert_se(condition);
assert_se(condition_test(condition));
condition_free(condition);
condition = condition_new(CONDITION_PATH_IS_MOUNT_POINT, "/", false, false);
+ assert_se(condition);
assert_se(condition_test(condition));
condition_free(condition);
condition = condition_new(CONDITION_PATH_IS_MOUNT_POINT, "/bin", false, false);
+ assert_se(condition);
assert_se(!condition_test(condition));
condition_free(condition);
condition = condition_new(CONDITION_PATH_IS_READ_WRITE, "/tmp", false, false);
+ assert_se(condition);
assert_se(condition_test(condition));
condition_free(condition);
condition = condition_new(CONDITION_PATH_IS_SYMBOLIC_LINK, "/dev/stdout", false, false);
+ assert_se(condition);
assert_se(condition_test(condition));
condition_free(condition);
}
@@ -104,47 +123,59 @@ static void test_condition_test_ac_power(void) {
Condition *condition;
condition = condition_new(CONDITION_AC_POWER, "true", false, false);
+ assert_se(condition);
assert_se(condition_test(condition) == on_ac_power());
condition_free(condition);
condition = condition_new(CONDITION_AC_POWER, "false", false, false);
+ assert_se(condition);
assert_se(condition_test(condition) != on_ac_power());
condition_free(condition);
condition = condition_new(CONDITION_AC_POWER, "false", false, true);
+ assert_se(condition);
assert_se(condition_test(condition) == on_ac_power());
condition_free(condition);
}
static void test_condition_test_host(void) {
+ _cleanup_free_ char *hostname = NULL;
+ char sid[SD_ID128_STRING_MAX];
Condition *condition;
sd_id128_t id;
int r;
- char sid[SD_ID128_STRING_MAX];
- _cleanup_free_ char *hostname = NULL;
r = sd_id128_get_machine(&id);
assert_se(r >= 0);
assert_se(sd_id128_to_string(id, sid));
condition = condition_new(CONDITION_HOST, sid, false, false);
+ assert_se(condition);
assert_se(condition_test(condition));
condition_free(condition);
condition = condition_new(CONDITION_HOST, "garbage value jjjjjjjjjjjjjj", false, false);
+ assert_se(condition);
assert_se(!condition_test(condition));
condition_free(condition);
condition = condition_new(CONDITION_HOST, sid, false, true);
+ assert_se(condition);
assert_se(!condition_test(condition));
condition_free(condition);
hostname = gethostname_malloc();
assert_se(hostname);
- condition = condition_new(CONDITION_HOST, hostname, false, false);
- assert_se(condition_test(condition));
- condition_free(condition);
+ /* if hostname looks like an id128 then skip testing it */
+ if (id128_is_valid(hostname))
+ log_notice("hostname is an id128, skipping test");
+ else {
+ condition = condition_new(CONDITION_HOST, hostname, false, false);
+ assert_se(condition);
+ assert_se(condition_test(condition));
+ condition_free(condition);
+ }
}
static void test_condition_test_architecture(void) {
@@ -159,14 +190,17 @@ static void test_condition_test_architecture(void) {
assert_se(sa);
condition = condition_new(CONDITION_ARCHITECTURE, sa, false, false);
+ assert_se(condition);
assert_se(condition_test(condition) > 0);
condition_free(condition);
condition = condition_new(CONDITION_ARCHITECTURE, "garbage value", false, false);
+ assert_se(condition);
assert_se(condition_test(condition) == 0);
condition_free(condition);
condition = condition_new(CONDITION_ARCHITECTURE, sa, false, true);
+ assert_se(condition);
assert_se(condition_test(condition) == 0);
condition_free(condition);
}
@@ -175,10 +209,12 @@ static void test_condition_test_kernel_command_line(void) {
Condition *condition;
condition = condition_new(CONDITION_KERNEL_COMMAND_LINE, "thisreallyshouldntbeonthekernelcommandline", false, false);
+ assert_se(condition);
assert_se(!condition_test(condition));
condition_free(condition);
condition = condition_new(CONDITION_KERNEL_COMMAND_LINE, "andthis=neither", false, false);
+ assert_se(condition);
assert_se(!condition_test(condition));
condition_free(condition);
}
@@ -187,10 +223,12 @@ static void test_condition_test_null(void) {
Condition *condition;
condition = condition_new(CONDITION_NULL, NULL, false, false);
+ assert_se(condition);
assert_se(condition_test(condition));
condition_free(condition);
condition = condition_new(CONDITION_NULL, NULL, false, true);
+ assert_se(condition);
assert_se(!condition_test(condition));
condition_free(condition);
}
@@ -199,32 +237,94 @@ static void test_condition_test_security(void) {
Condition *condition;
condition = condition_new(CONDITION_SECURITY, "garbage oifdsjfoidsjoj", false, false);
+ assert_se(condition);
assert_se(!condition_test(condition));
condition_free(condition);
condition = condition_new(CONDITION_SECURITY, "selinux", false, true);
+ assert_se(condition);
assert_se(condition_test(condition) != mac_selinux_have());
condition_free(condition);
condition = condition_new(CONDITION_SECURITY, "ima", false, false);
+ assert_se(condition);
assert_se(condition_test(condition) == use_ima());
condition_free(condition);
condition = condition_new(CONDITION_SECURITY, "apparmor", false, false);
+ assert_se(condition);
assert_se(condition_test(condition) == mac_apparmor_use());
condition_free(condition);
condition = condition_new(CONDITION_SECURITY, "smack", false, false);
+ assert_se(condition);
assert_se(condition_test(condition) == mac_smack_use());
condition_free(condition);
condition = condition_new(CONDITION_SECURITY, "audit", false, false);
+ assert_se(condition);
assert_se(condition_test(condition) == use_audit());
condition_free(condition);
}
+static void test_condition_test_virtualization(void) {
+ Condition *condition;
+ const char *virt;
+ int r;
+
+ condition = condition_new(CONDITION_VIRTUALIZATION, "garbage oifdsjfoidsjoj", false, false);
+ assert_se(condition);
+ r = condition_test(condition);
+ log_info("ConditionVirtualization=garbage → %i", r);
+ assert_se(r == 0);
+ condition_free(condition);
+
+ condition = condition_new(CONDITION_VIRTUALIZATION, "container", false, false);
+ assert_se(condition);
+ r = condition_test(condition);
+ log_info("ConditionVirtualization=container → %i", r);
+ assert_se(r == !!detect_container());
+ condition_free(condition);
+
+ condition = condition_new(CONDITION_VIRTUALIZATION, "vm", false, false);
+ assert_se(condition);
+ r = condition_test(condition);
+ log_info("ConditionVirtualization=vm → %i", r);
+ assert_se(r == (detect_vm() && !detect_container()));
+ condition_free(condition);
+
+ condition = condition_new(CONDITION_VIRTUALIZATION, "private-users", false, false);
+ assert_se(condition);
+ r = condition_test(condition);
+ log_info("ConditionVirtualization=private-users → %i", r);
+ assert_se(r == !!running_in_userns());
+ condition_free(condition);
+
+ NULSTR_FOREACH(virt,
+ "kvm\0"
+ "qemu\0"
+ "bochs\0"
+ "xen\0"
+ "uml\0"
+ "vmware\0"
+ "oracle\0"
+ "microsoft\0"
+ "zvm\0"
+ "parallels\0"
+ "bhyve\0"
+ "vm_other\0") {
+
+ condition = condition_new(CONDITION_VIRTUALIZATION, virt, false, false);
+ assert_se(condition);
+ r = condition_test(condition);
+ log_info("ConditionVirtualization=%s → %i", virt, r);
+ assert_se(r >= 0);
+ condition_free(condition);
+ }
+}
int main(int argc, char *argv[]) {
+ log_set_max_level(LOG_DEBUG);
log_parse_environment();
log_open();
@@ -235,6 +335,7 @@ int main(int argc, char *argv[]) {
test_condition_test_kernel_command_line();
test_condition_test_null();
test_condition_test_security();
+ test_condition_test_virtualization();
return 0;
}
diff --git a/src/test/test-copy.c b/src/test/test-copy.c
index fca324c90a..5f6bcf19ef 100644
--- a/src/test/test-copy.c
+++ b/src/test/test-copy.c
@@ -42,11 +42,11 @@ static void test_copy_file(void) {
log_info("%s", __func__);
- fd = mkostemp_safe(fn, O_RDWR|O_CLOEXEC);
+ fd = mkostemp_safe(fn);
assert_se(fd >= 0);
close(fd);
- fd = mkostemp_safe(fn_copy, O_RDWR|O_CLOEXEC);
+ fd = mkostemp_safe(fn_copy);
assert_se(fd >= 0);
close(fd);
@@ -71,9 +71,9 @@ static void test_copy_file_fd(void) {
log_info("%s", __func__);
- in_fd = mkostemp_safe(in_fn, O_RDWR);
+ in_fd = mkostemp_safe(in_fn);
assert_se(in_fd >= 0);
- out_fd = mkostemp_safe(out_fn, O_RDWR);
+ out_fd = mkostemp_safe(out_fn);
assert_se(out_fd >= 0);
assert_se(write_string_file(in_fn, text, WRITE_STRING_FILE_CREATE) == 0);
@@ -207,10 +207,10 @@ static void test_copy_bytes_regular_file(const char *src, bool try_reflink, uint
fd = open(src, O_RDONLY | O_CLOEXEC | O_NOCTTY);
assert_se(fd >= 0);
- fd2 = mkostemp_safe(fn2, O_RDWR);
+ fd2 = mkostemp_safe(fn2);
assert_se(fd2 >= 0);
- fd3 = mkostemp_safe(fn3, O_WRONLY);
+ fd3 = mkostemp_safe(fn3);
assert_se(fd3 >= 0);
r = copy_bytes(fd, fd2, max_bytes, try_reflink);
diff --git a/src/test/test-dns-domain.c b/src/test/test-dns-domain.c
index c31d09e945..20c6f1b759 100644
--- a/src/test/test-dns-domain.c
+++ b/src/test/test-dns-domain.c
@@ -48,6 +48,7 @@ static void test_dns_label_unescape(void) {
test_dns_label_unescape_one("..", "", 20, -EINVAL);
test_dns_label_unescape_one(".foobar", "", 20, -EINVAL);
test_dns_label_unescape_one("foobar.", "foobar", 20, 6);
+ test_dns_label_unescape_one("foobar..", "foobar", 20, -EINVAL);
}
static void test_dns_name_to_wire_format_one(const char *what, const char *expect, size_t buffer_sz, int ret) {
@@ -359,6 +360,7 @@ static void test_dns_name_is_valid_one(const char *s, int ret) {
static void test_dns_name_is_valid(void) {
test_dns_name_is_valid_one("foo", 1);
test_dns_name_is_valid_one("foo.", 1);
+ test_dns_name_is_valid_one("foo..", 0);
test_dns_name_is_valid_one("Foo", 1);
test_dns_name_is_valid_one("foo.bar", 1);
test_dns_name_is_valid_one("foo.bar.baz", 1);
@@ -366,6 +368,7 @@ static void test_dns_name_is_valid(void) {
test_dns_name_is_valid_one("foo..bar", 0);
test_dns_name_is_valid_one(".foo.bar", 0);
test_dns_name_is_valid_one("foo.bar.", 1);
+ test_dns_name_is_valid_one("foo.bar..", 0);
test_dns_name_is_valid_one("\\zbar", 0);
test_dns_name_is_valid_one("ä", 1);
test_dns_name_is_valid_one("\n", 0);
diff --git a/src/test/test-engine.c b/src/test/test-engine.c
index 7878707cbe..2f12daecf3 100644
--- a/src/test/test-engine.c
+++ b/src/test/test-engine.c
@@ -44,7 +44,7 @@ int main(int argc, char *argv[]) {
assert_se(set_unit_path(TEST_DIR) >= 0);
r = manager_new(UNIT_FILE_USER, true, &m);
if (MANAGER_SKIP_TEST(r)) {
- printf("Skipping test: manager_new: %s\n", strerror(-r));
+ log_notice_errno(r, "Skipping test: manager_new: %m");
return EXIT_TEST_SKIP;
}
assert_se(r >= 0);
diff --git a/src/test/test-execute.c b/src/test/test-execute.c
index 8ea0618576..be8160ed19 100644
--- a/src/test/test-execute.c
+++ b/src/test/test-execute.c
@@ -24,14 +24,18 @@
#include <sys/types.h>
#include "core/manager.h"
-#include "core/unit.h"
#include "systemd-basic/fileio.h"
#include "systemd-basic/fs-util.h"
#include "systemd-basic/macro.h"
#include "systemd-basic/mkdir.h"
#include "systemd-basic/path-util.h"
#include "systemd-basic/rm-rf.h"
+#ifdef HAVE_SECCOMP
+#include "systemd-shared/seccomp-util.h"
+#endif
+#include "core/unit.h"
#include "systemd-basic/util.h"
+#include "systemd-basic/virt.h"
#include "test-helper.h"
@@ -67,6 +71,24 @@ static void check(Manager *m, Unit *unit, int status_expected, int code_expected
assert_se(service->main_exec_status.code == code_expected);
}
+static bool is_inaccessible_available(void) {
+ char *p;
+
+ FOREACH_STRING(p,
+ "/run/systemd/inaccessible/reg",
+ "/run/systemd/inaccessible/dir",
+ "/run/systemd/inaccessible/chr",
+ "/run/systemd/inaccessible/blk",
+ "/run/systemd/inaccessible/fifo",
+ "/run/systemd/inaccessible/sock"
+ ) {
+ if (access(p, F_OK) < 0)
+ return false;
+ }
+
+ return true;
+}
+
static void test(Manager *m, const char *unit_name, int status_expected, int code_expected) {
Unit *unit;
@@ -92,6 +114,16 @@ static void test_exec_personality(Manager *m) {
#elif defined(__s390__)
test(m, "exec-personality-s390.service", 0, CLD_EXITED);
+#elif defined(__powerpc64__)
+# if __BYTE_ORDER == __BIG_ENDIAN
+ test(m, "exec-personality-ppc64.service", 0, CLD_EXITED);
+# else
+ test(m, "exec-personality-ppc64le.service", 0, CLD_EXITED);
+# endif
+
+#elif defined(__aarch64__)
+ test(m, "exec-personality-aarch64.service", 0, CLD_EXITED);
+
#elif defined(__i386__)
test(m, "exec-personality-x86.service", 0, CLD_EXITED);
#endif
@@ -112,27 +144,86 @@ static void test_exec_privatetmp(Manager *m) {
}
static void test_exec_privatedevices(Manager *m) {
+ if (detect_container() > 0) {
+ log_notice("testing in container, skipping private device tests");
+ return;
+ }
+ if (!is_inaccessible_available()) {
+ log_notice("testing without inaccessible, skipping private device tests");
+ return;
+ }
+
test(m, "exec-privatedevices-yes.service", 0, CLD_EXITED);
test(m, "exec-privatedevices-no.service", 0, CLD_EXITED);
}
+static void test_exec_privatedevices_capabilities(Manager *m) {
+ if (detect_container() > 0) {
+ log_notice("testing in container, skipping private device tests");
+ return;
+ }
+ if (!is_inaccessible_available()) {
+ log_notice("testing without inaccessible, skipping private device tests");
+ return;
+ }
+
+ test(m, "exec-privatedevices-yes-capability-mknod.service", 0, CLD_EXITED);
+ test(m, "exec-privatedevices-no-capability-mknod.service", 0, CLD_EXITED);
+ test(m, "exec-privatedevices-yes-capability-sys-rawio.service", 0, CLD_EXITED);
+ test(m, "exec-privatedevices-no-capability-sys-rawio.service", 0, CLD_EXITED);
+}
+
+static void test_exec_protectkernelmodules(Manager *m) {
+ if (detect_container() > 0) {
+ log_notice("testing in container, skipping protectkernelmodules tests");
+ return;
+ }
+ if (!is_inaccessible_available()) {
+ log_notice("testing without inaccessible, skipping protectkernelmodules tests");
+ return;
+ }
+
+ test(m, "exec-protectkernelmodules-no-capabilities.service", 0, CLD_EXITED);
+ test(m, "exec-protectkernelmodules-yes-capabilities.service", 0, CLD_EXITED);
+ test(m, "exec-protectkernelmodules-yes-mount-propagation.service", 0, CLD_EXITED);
+}
+
+static void test_exec_readonlypaths(Manager *m) {
+ test(m, "exec-readonlypaths.service", 0, CLD_EXITED);
+ test(m, "exec-readonlypaths-mount-propagation.service", 0, CLD_EXITED);
+}
+
+static void test_exec_readwritepaths(Manager *m) {
+ test(m, "exec-readwritepaths-mount-propagation.service", 0, CLD_EXITED);
+}
+
+static void test_exec_inaccessiblepaths(Manager *m) {
+ test(m, "exec-inaccessiblepaths-mount-propagation.service", 0, CLD_EXITED);
+}
+
static void test_exec_systemcallfilter(Manager *m) {
#ifdef HAVE_SECCOMP
+ if (!is_seccomp_available())
+ return;
test(m, "exec-systemcallfilter-not-failing.service", 0, CLD_EXITED);
test(m, "exec-systemcallfilter-not-failing2.service", 0, CLD_EXITED);
test(m, "exec-systemcallfilter-failing.service", SIGSYS, CLD_KILLED);
test(m, "exec-systemcallfilter-failing2.service", SIGSYS, CLD_KILLED);
+
#endif
}
static void test_exec_systemcallerrornumber(Manager *m) {
#ifdef HAVE_SECCOMP
- test(m, "exec-systemcallerrornumber.service", 1, CLD_EXITED);
+ if (is_seccomp_available())
+ test(m, "exec-systemcallerrornumber.service", 1, CLD_EXITED);
#endif
}
static void test_exec_systemcall_system_mode_with_user(Manager *m) {
#ifdef HAVE_SECCOMP
+ if (!is_seccomp_available())
+ return;
if (getpwnam("nobody"))
test(m, "exec-systemcallfilter-system-user.service", 0, CLD_EXITED);
else if (getpwnam("nfsnobody"))
@@ -160,6 +251,21 @@ static void test_exec_group(Manager *m) {
log_error_errno(errno, "Skipping test_exec_group, could not find nobody/nfsnobody group: %m");
}
+static void test_exec_supplementary_groups(Manager *m) {
+ test(m, "exec-supplementarygroups.service", 0, CLD_EXITED);
+ test(m, "exec-supplementarygroups-single-group.service", 0, CLD_EXITED);
+ test(m, "exec-supplementarygroups-single-group-user.service", 0, CLD_EXITED);
+ test(m, "exec-supplementarygroups-multiple-groups-default-group-user.service", 0, CLD_EXITED);
+ test(m, "exec-supplementarygroups-multiple-groups-withgid.service", 0, CLD_EXITED);
+ test(m, "exec-supplementarygroups-multiple-groups-withuid.service", 0, CLD_EXITED);
+}
+
+static void test_exec_dynamic_user(Manager *m) {
+ test(m, "exec-dynamicuser-fixeduser.service", 0, CLD_EXITED);
+ test(m, "exec-dynamicuser-fixeduser-one-supplementarygroup.service", 0, CLD_EXITED);
+ test(m, "exec-dynamicuser-supplementarygroups.service", 0, CLD_EXITED);
+}
+
static void test_exec_environment(Manager *m) {
test(m, "exec-environment.service", 0, CLD_EXITED);
test(m, "exec-environment-multiple.service", 0, CLD_EXITED);
@@ -301,7 +407,7 @@ static int run_tests(UnitFileScope scope, test_function_t *tests) {
r = manager_new(scope, true, &m);
if (MANAGER_SKIP_TEST(r)) {
- printf("Skipping test: manager_new: %s\n", strerror(-r));
+ log_notice_errno(r, "Skipping test: manager_new: %m");
return EXIT_TEST_SKIP;
}
assert_se(r >= 0);
@@ -322,11 +428,18 @@ int main(int argc, char *argv[]) {
test_exec_ignoresigpipe,
test_exec_privatetmp,
test_exec_privatedevices,
+ test_exec_privatedevices_capabilities,
+ test_exec_protectkernelmodules,
+ test_exec_readonlypaths,
+ test_exec_readwritepaths,
+ test_exec_inaccessiblepaths,
test_exec_privatenetwork,
test_exec_systemcallfilter,
test_exec_systemcallerrornumber,
test_exec_user,
test_exec_group,
+ test_exec_supplementary_groups,
+ test_exec_dynamic_user,
test_exec_environment,
test_exec_environmentfile,
test_exec_passenvironment,
diff --git a/src/test/test-fd-util.c b/src/test/test-fd-util.c
index 10577bfbed..6fbb6e58f8 100644
--- a/src/test/test-fd-util.c
+++ b/src/test/test-fd-util.c
@@ -31,9 +31,9 @@ static void test_close_many(void) {
char name1[] = "/tmp/test-close-many.XXXXXX";
char name2[] = "/tmp/test-close-many.XXXXXX";
- fds[0] = mkostemp_safe(name0, O_RDWR|O_CLOEXEC);
- fds[1] = mkostemp_safe(name1, O_RDWR|O_CLOEXEC);
- fds[2] = mkostemp_safe(name2, O_RDWR|O_CLOEXEC);
+ fds[0] = mkostemp_safe(name0);
+ fds[1] = mkostemp_safe(name1);
+ fds[2] = mkostemp_safe(name2);
close_many(fds, 2);
@@ -52,7 +52,7 @@ static void test_close_nointr(void) {
char name[] = "/tmp/test-test-close_nointr.XXXXXX";
int fd;
- fd = mkostemp_safe(name, O_RDWR|O_CLOEXEC);
+ fd = mkostemp_safe(name);
assert_se(fd >= 0);
assert_se(close_nointr(fd) >= 0);
assert_se(close_nointr(fd) < 0);
diff --git a/src/test/test-fdset.c b/src/test/test-fdset.c
index 5073e0bf17..103e61a1c5 100644
--- a/src/test/test-fdset.c
+++ b/src/test/test-fdset.c
@@ -31,7 +31,7 @@ static void test_fdset_new_fill(void) {
_cleanup_fdset_free_ FDSet *fdset = NULL;
char name[] = "/tmp/test-fdset_new_fill.XXXXXX";
- fd = mkostemp_safe(name, O_RDWR|O_CLOEXEC);
+ fd = mkostemp_safe(name);
assert_se(fd >= 0);
assert_se(fdset_new_fill(&fdset) >= 0);
assert_se(fdset_contains(fdset, fd));
@@ -45,7 +45,7 @@ static void test_fdset_put_dup(void) {
_cleanup_fdset_free_ FDSet *fdset = NULL;
char name[] = "/tmp/test-fdset_put_dup.XXXXXX";
- fd = mkostemp_safe(name, O_RDWR|O_CLOEXEC);
+ fd = mkostemp_safe(name);
assert_se(fd >= 0);
fdset = fdset_new();
@@ -64,7 +64,7 @@ static void test_fdset_cloexec(void) {
int flags = -1;
char name[] = "/tmp/test-fdset_cloexec.XXXXXX";
- fd = mkostemp_safe(name, O_RDWR|O_CLOEXEC);
+ fd = mkostemp_safe(name);
assert_se(fd >= 0);
fdset = fdset_new();
@@ -91,7 +91,7 @@ static void test_fdset_close_others(void) {
int flags = -1;
char name[] = "/tmp/test-fdset_close_others.XXXXXX";
- fd = mkostemp_safe(name, O_RDWR|O_CLOEXEC);
+ fd = mkostemp_safe(name);
assert_se(fd >= 0);
fdset = fdset_new();
@@ -113,7 +113,7 @@ static void test_fdset_remove(void) {
FDSet *fdset = NULL;
char name[] = "/tmp/test-fdset_remove.XXXXXX";
- fd = mkostemp_safe(name, O_RDWR|O_CLOEXEC);
+ fd = mkostemp_safe(name);
assert_se(fd >= 0);
fdset = fdset_new();
@@ -136,7 +136,7 @@ static void test_fdset_iterate(void) {
int c = 0;
int a;
- fd = mkostemp_safe(name, O_RDWR|O_CLOEXEC);
+ fd = mkostemp_safe(name);
assert_se(fd >= 0);
fdset = fdset_new();
@@ -161,7 +161,7 @@ static void test_fdset_isempty(void) {
_cleanup_fdset_free_ FDSet *fdset = NULL;
char name[] = "/tmp/test-fdset_isempty.XXXXXX";
- fd = mkostemp_safe(name, O_RDWR|O_CLOEXEC);
+ fd = mkostemp_safe(name);
assert_se(fd >= 0);
fdset = fdset_new();
@@ -179,7 +179,7 @@ static void test_fdset_steal_first(void) {
_cleanup_fdset_free_ FDSet *fdset = NULL;
char name[] = "/tmp/test-fdset_steal_first.XXXXXX";
- fd = mkostemp_safe(name, O_RDWR|O_CLOEXEC);
+ fd = mkostemp_safe(name);
assert_se(fd >= 0);
fdset = fdset_new();
diff --git a/src/test/test-fileio.c b/src/test/test-fileio.c
index c58abff8d6..6e1056a466 100644
--- a/src/test/test-fileio.c
+++ b/src/test/test-fileio.c
@@ -45,11 +45,11 @@ static void test_parse_env_file(void) {
char **i;
unsigned k;
- fd = mkostemp_safe(p, O_RDWR|O_CLOEXEC);
+ fd = mkostemp_safe(p);
assert_se(fd >= 0);
close(fd);
- fd = mkostemp_safe(t, O_RDWR|O_CLOEXEC);
+ fd = mkostemp_safe(t);
assert_se(fd >= 0);
f = fdopen(fd, "w");
@@ -158,11 +158,11 @@ static void test_parse_multiline_env_file(void) {
_cleanup_strv_free_ char **a = NULL, **b = NULL;
char **i;
- fd = mkostemp_safe(p, O_RDWR|O_CLOEXEC);
+ fd = mkostemp_safe(p);
assert_se(fd >= 0);
close(fd);
- fd = mkostemp_safe(t, O_RDWR|O_CLOEXEC);
+ fd = mkostemp_safe(t);
assert_se(fd >= 0);
f = fdopen(fd, "w");
@@ -211,7 +211,7 @@ static void test_executable_is_script(void) {
FILE *f;
char *command;
- fd = mkostemp_safe(t, O_RDWR|O_CLOEXEC);
+ fd = mkostemp_safe(t);
assert_se(fd >= 0);
f = fdopen(fd, "w");
@@ -300,7 +300,7 @@ static void test_write_string_stream(void) {
int fd;
char buf[64];
- fd = mkostemp_safe(fn, O_RDWR);
+ fd = mkostemp_safe(fn);
assert_se(fd >= 0);
f = fdopen(fd, "r");
@@ -334,7 +334,7 @@ static void test_write_string_file(void) {
char buf[64] = {};
_cleanup_close_ int fd;
- fd = mkostemp_safe(fn, O_RDWR);
+ fd = mkostemp_safe(fn);
assert_se(fd >= 0);
assert_se(write_string_file(fn, "boohoo", WRITE_STRING_FILE_CREATE) == 0);
@@ -350,7 +350,7 @@ static void test_write_string_file_no_create(void) {
_cleanup_close_ int fd;
char buf[64] = {0};
- fd = mkostemp_safe(fn, O_RDWR);
+ fd = mkostemp_safe(fn);
assert_se(fd >= 0);
assert_se(write_string_file("/a/file/which/does/not/exists/i/guess", "boohoo", 0) < 0);
@@ -390,7 +390,7 @@ static void test_load_env_file_pairs(void) {
_cleanup_strv_free_ char **l = NULL;
char **k, **v;
- fd = mkostemp_safe(fn, O_RDWR);
+ fd = mkostemp_safe(fn);
assert_se(fd >= 0);
r = write_string_file(fn,
@@ -433,7 +433,7 @@ static void test_search_and_fopen(void) {
int r;
FILE *f;
- fd = mkostemp_safe(name, O_RDWR|O_CLOEXEC);
+ fd = mkostemp_safe(name);
assert_se(fd >= 0);
close(fd);
@@ -469,7 +469,7 @@ static void test_search_and_fopen_nulstr(void) {
int r;
FILE *f;
- fd = mkostemp_safe(name, O_RDWR|O_CLOEXEC);
+ fd = mkostemp_safe(name);
assert_se(fd >= 0);
close(fd);
@@ -504,7 +504,7 @@ static void test_writing_tmpfile(void) {
IOVEC_SET_STRING(iov[1], ALPHANUMERICAL "\n");
IOVEC_SET_STRING(iov[2], "");
- fd = mkostemp_safe(name, O_RDWR|O_CLOEXEC);
+ fd = mkostemp_safe(name);
printf("tmpfile: %s", name);
r = writev(fd, iov, 3);
diff --git a/src/test/test-fs-util.c b/src/test/test-fs-util.c
index e98da45197..280918fe57 100644
--- a/src/test/test-fs-util.c
+++ b/src/test/test-fs-util.c
@@ -25,16 +25,109 @@
#include "systemd-basic/fs-util.h"
#include "systemd-basic/macro.h"
#include "systemd-basic/mkdir.h"
+#include "systemd-basic/path-util.h"
#include "systemd-basic/rm-rf.h"
#include "systemd-basic/string-util.h"
#include "systemd-basic/strv.h"
#include "systemd-basic/util.h"
+static void test_chase_symlinks(void) {
+ _cleanup_free_ char *result = NULL;
+ char temp[] = "/tmp/test-chase.XXXXXX";
+ const char *top, *p, *q;
+ int r;
+
+ assert_se(mkdtemp(temp));
+
+ top = strjoina(temp, "/top");
+ assert_se(mkdir(top, 0700) >= 0);
+
+ p = strjoina(top, "/dot");
+ assert_se(symlink(".", p) >= 0);
+
+ p = strjoina(top, "/dotdot");
+ assert_se(symlink("..", p) >= 0);
+
+ p = strjoina(top, "/dotdota");
+ assert_se(symlink("../a", p) >= 0);
+
+ p = strjoina(temp, "/a");
+ assert_se(symlink("b", p) >= 0);
+
+ p = strjoina(temp, "/b");
+ assert_se(symlink("/usr", p) >= 0);
+
+ p = strjoina(temp, "/start");
+ assert_se(symlink("top/dot/dotdota", p) >= 0);
+
+ r = chase_symlinks(p, NULL, &result);
+ assert_se(r >= 0);
+ assert_se(path_equal(result, "/usr"));
+
+ result = mfree(result);
+ r = chase_symlinks(p, temp, &result);
+ assert_se(r == -ENOENT);
+
+ q = strjoina(temp, "/usr");
+ assert_se(mkdir(q, 0700) >= 0);
+
+ r = chase_symlinks(p, temp, &result);
+ assert_se(r >= 0);
+ assert_se(path_equal(result, q));
+
+ p = strjoina(temp, "/slash");
+ assert_se(symlink("/", p) >= 0);
+
+ result = mfree(result);
+ r = chase_symlinks(p, NULL, &result);
+ assert_se(r >= 0);
+ assert_se(path_equal(result, "/"));
+
+ result = mfree(result);
+ r = chase_symlinks(p, temp, &result);
+ assert_se(r >= 0);
+ assert_se(path_equal(result, temp));
+
+ p = strjoina(temp, "/slashslash");
+ assert_se(symlink("///usr///", p) >= 0);
+
+ result = mfree(result);
+ r = chase_symlinks(p, NULL, &result);
+ assert_se(r >= 0);
+ assert_se(path_equal(result, "/usr"));
+
+ result = mfree(result);
+ r = chase_symlinks(p, temp, &result);
+ assert_se(r >= 0);
+ assert_se(path_equal(result, q));
+
+ result = mfree(result);
+ r = chase_symlinks("/etc/./.././", NULL, &result);
+ assert_se(r >= 0);
+ assert_se(path_equal(result, "/"));
+
+ result = mfree(result);
+ r = chase_symlinks("/etc/./.././", "/etc", &result);
+ assert_se(r == -EINVAL);
+
+ result = mfree(result);
+ r = chase_symlinks("/etc/machine-id/foo", NULL, &result);
+ assert_se(r == -ENOTDIR);
+
+ result = mfree(result);
+ p = strjoina(temp, "/recursive-symlink");
+ assert_se(symlink("recursive-symlink", p) >= 0);
+ r = chase_symlinks(p, NULL, &result);
+ assert_se(r == -ELOOP);
+
+ assert_se(rm_rf(temp, REMOVE_ROOT|REMOVE_PHYSICAL) >= 0);
+}
+
static void test_unlink_noerrno(void) {
char name[] = "/tmp/test-close_nointr.XXXXXX";
int fd;
- fd = mkostemp_safe(name, O_RDWR|O_CLOEXEC);
+ fd = mkostemp_safe(name);
assert_se(fd >= 0);
assert_se(close_nointr(fd) >= 0);
@@ -83,47 +176,59 @@ static void test_get_files_in_directory(void) {
}
static void test_var_tmp(void) {
- char *tmp_dir = NULL;
- char *tmpdir_backup = NULL;
- const char *default_var_tmp = NULL;
- const char *var_name;
- bool do_overwrite = true;
-
- default_var_tmp = "/var/tmp";
- var_name = "TMPDIR";
-
- if (getenv(var_name) != NULL) {
- tmpdir_backup = strdup(getenv(var_name));
- assert_se(tmpdir_backup != NULL);
+ _cleanup_free_ char *tmpdir_backup = NULL, *temp_backup = NULL, *tmp_backup = NULL;
+ const char *tmp_dir = NULL, *t;
+
+ t = getenv("TMPDIR");
+ if (t) {
+ tmpdir_backup = strdup(t);
+ assert_se(tmpdir_backup);
}
- unsetenv(var_name);
+ t = getenv("TEMP");
+ if (t) {
+ temp_backup = strdup(t);
+ assert_se(temp_backup);
+ }
- var_tmp(&tmp_dir);
- assert_se(!strcmp(tmp_dir, default_var_tmp));
+ t = getenv("TMP");
+ if (t) {
+ tmp_backup = strdup(t);
+ assert_se(tmp_backup);
+ }
- free(tmp_dir);
+ assert(unsetenv("TMPDIR") >= 0);
+ assert(unsetenv("TEMP") >= 0);
+ assert(unsetenv("TMP") >= 0);
- setenv(var_name, "/tmp", do_overwrite);
- assert_se(!strcmp(getenv(var_name), "/tmp"));
+ assert_se(var_tmp_dir(&tmp_dir) >= 0);
+ assert_se(streq(tmp_dir, "/var/tmp"));
- var_tmp(&tmp_dir);
- assert_se(!strcmp(tmp_dir, "/tmp"));
+ assert_se(setenv("TMPDIR", "/tmp", true) >= 0);
+ assert_se(streq(getenv("TMPDIR"), "/tmp"));
- free(tmp_dir);
+ assert_se(var_tmp_dir(&tmp_dir) >= 0);
+ assert_se(streq(tmp_dir, "/tmp"));
- setenv(var_name, "/88_does_not_exist_88", do_overwrite);
- assert_se(!strcmp(getenv(var_name), "/88_does_not_exist_88"));
+ assert_se(setenv("TMPDIR", "/88_does_not_exist_88", true) >= 0);
+ assert_se(streq(getenv("TMPDIR"), "/88_does_not_exist_88"));
- var_tmp(&tmp_dir);
- assert_se(!strcmp(tmp_dir, default_var_tmp));
+ assert_se(var_tmp_dir(&tmp_dir) >= 0);
+ assert_se(streq(tmp_dir, "/var/tmp"));
- free(tmp_dir);
+ if (tmpdir_backup) {
+ assert_se(setenv("TMPDIR", tmpdir_backup, true) >= 0);
+ assert_se(streq(getenv("TMPDIR"), tmpdir_backup));
+ }
+
+ if (temp_backup) {
+ assert_se(setenv("TEMP", temp_backup, true) >= 0);
+ assert_se(streq(getenv("TEMP"), temp_backup));
+ }
- if (tmpdir_backup != NULL) {
- setenv(var_name, tmpdir_backup, do_overwrite);
- assert_se(!strcmp(getenv(var_name), tmpdir_backup));
- free(tmpdir_backup);
+ if (tmp_backup) {
+ assert_se(setenv("TMP", tmp_backup, true) >= 0);
+ assert_se(streq(getenv("TMP"), tmp_backup));
}
}
@@ -132,6 +237,7 @@ int main(int argc, char *argv[]) {
test_readlink_and_make_absolute();
test_get_files_in_directory();
test_var_tmp();
+ test_chase_symlinks();
return 0;
}
diff --git a/src/test/test-glob-util.c b/src/test/test-glob-util.c
index b5cf10a683..364549b9f4 100644
--- a/src/test/test-glob-util.c
+++ b/src/test/test-glob-util.c
@@ -30,7 +30,7 @@ static void test_glob_exists(void) {
int fd = -1;
int r;
- fd = mkostemp_safe(name, O_RDWR|O_CLOEXEC);
+ fd = mkostemp_safe(name);
assert_se(fd >= 0);
close(fd);
diff --git a/src/test/test-hostname-util.c b/src/test/test-hostname-util.c
index 62ce59ae4b..9992cb4766 100644
--- a/src/test/test-hostname-util.c
+++ b/src/test/test-hostname-util.c
@@ -42,6 +42,7 @@ static void test_hostname_is_valid(void) {
assert_se(!hostname_is_valid("foo..bar", false));
assert_se(!hostname_is_valid("foo.bar..", false));
assert_se(!hostname_is_valid("xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", false));
+ assert_se(!hostname_is_valid("au-xph5-rvgrdsb5hcxc-47et3a5vvkrc-server-wyoz4elpdpe3.openstack.local", false));
assert_se(hostname_is_valid("foobar", true));
assert_se(hostname_is_valid("foobar.com", true));
@@ -103,7 +104,7 @@ static void test_read_hostname_config(void) {
char *hostname;
int fd;
- fd = mkostemp_safe(path, O_RDWR|O_CLOEXEC);
+ fd = mkostemp_safe(path);
assert(fd > 0);
close(fd);
diff --git a/src/test/test-id128.c b/src/test/test-id128.c
index ada678a6c9..23209f44c0 100644
--- a/src/test/test-id128.c
+++ b/src/test/test-id128.c
@@ -144,7 +144,7 @@ int main(int argc, char *argv[]) {
assert_se(ftruncate(fd, 0) >= 0);
assert_se(sd_id128_randomize(&id) >= 0);
- assert_se(write(fd, id128_to_uuid_string(id, t), 36) == 36);
+ assert_se(write(fd, id128_to_uuid_string(id, q), 36) == 36);
assert_se(lseek(fd, 0, SEEK_SET) == 0);
assert_se(id128_read_fd(fd, ID128_PLAIN, &id2) == -EINVAL);
diff --git a/src/test/test-install-root.c b/src/test/test-install-root.c
index 9124c0c73a..bf37f754a4 100644
--- a/src/test/test-install-root.c
+++ b/src/test/test-install-root.c
@@ -64,7 +64,7 @@ static void test_basic_mask_and_enable(const char *root) {
assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "d.service", NULL) >= 0);
assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "d.service", &state) >= 0 && state == UNIT_FILE_DISABLED);
- assert_se(unit_file_mask(UNIT_FILE_SYSTEM, false, root, STRV_MAKE("a.service"), false, &changes, &n_changes) >= 0);
+ assert_se(unit_file_mask(UNIT_FILE_SYSTEM, 0, root, STRV_MAKE("a.service"), &changes, &n_changes) >= 0);
assert_se(n_changes == 1);
assert_se(changes[0].type == UNIT_FILE_SYMLINK);
assert_se(streq(changes[0].source, "/dev/null"));
@@ -80,11 +80,11 @@ static void test_basic_mask_and_enable(const char *root) {
assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "d.service", &state) >= 0 && state == UNIT_FILE_MASKED);
/* Enabling a masked unit should fail! */
- assert_se(unit_file_enable(UNIT_FILE_SYSTEM, false, root, STRV_MAKE("a.service"), false, &changes, &n_changes) == -ERFKILL);
+ assert_se(unit_file_enable(UNIT_FILE_SYSTEM, 0, root, STRV_MAKE("a.service"), &changes, &n_changes) == -ERFKILL);
unit_file_changes_free(changes, n_changes);
changes = NULL; n_changes = 0;
- assert_se(unit_file_unmask(UNIT_FILE_SYSTEM, false, root, STRV_MAKE("a.service"), &changes, &n_changes) >= 0);
+ assert_se(unit_file_unmask(UNIT_FILE_SYSTEM, 0, root, STRV_MAKE("a.service"), &changes, &n_changes) >= 0);
assert_se(n_changes == 1);
assert_se(changes[0].type == UNIT_FILE_UNLINK);
p = strjoina(root, SYSTEM_CONFIG_UNIT_PATH"/a.service");
@@ -92,7 +92,7 @@ static void test_basic_mask_and_enable(const char *root) {
unit_file_changes_free(changes, n_changes);
changes = NULL; n_changes = 0;
- assert_se(unit_file_enable(UNIT_FILE_SYSTEM, false, root, STRV_MAKE("a.service"), false, &changes, &n_changes) == 1);
+ assert_se(unit_file_enable(UNIT_FILE_SYSTEM, 0, root, STRV_MAKE("a.service"), &changes, &n_changes) == 1);
assert_se(n_changes == 1);
assert_se(changes[0].type == UNIT_FILE_SYMLINK);
assert_se(streq(changes[0].source, "/usr/lib/systemd/system/a.service"));
@@ -107,12 +107,12 @@ static void test_basic_mask_and_enable(const char *root) {
assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "d.service", &state) >= 0 && state == UNIT_FILE_ENABLED);
/* Enabling it again should succeed but be a NOP */
- assert_se(unit_file_enable(UNIT_FILE_SYSTEM, false, root, STRV_MAKE("a.service"), false, &changes, &n_changes) >= 0);
+ assert_se(unit_file_enable(UNIT_FILE_SYSTEM, 0, root, STRV_MAKE("a.service"), &changes, &n_changes) >= 0);
assert_se(n_changes == 0);
unit_file_changes_free(changes, n_changes);
changes = NULL; n_changes = 0;
- assert_se(unit_file_disable(UNIT_FILE_SYSTEM, false, root, STRV_MAKE("a.service"), &changes, &n_changes) >= 0);
+ assert_se(unit_file_disable(UNIT_FILE_SYSTEM, 0, root, STRV_MAKE("a.service"), &changes, &n_changes) >= 0);
assert_se(n_changes == 1);
assert_se(changes[0].type == UNIT_FILE_UNLINK);
p = strjoina(root, SYSTEM_CONFIG_UNIT_PATH"/multi-user.target.wants/a.service");
@@ -126,13 +126,13 @@ static void test_basic_mask_and_enable(const char *root) {
assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "d.service", &state) >= 0 && state == UNIT_FILE_DISABLED);
/* Disabling a disabled unit must suceed but be a NOP */
- assert_se(unit_file_disable(UNIT_FILE_SYSTEM, false, root, STRV_MAKE("a.service"), &changes, &n_changes) >= 0);
+ assert_se(unit_file_disable(UNIT_FILE_SYSTEM, 0, root, STRV_MAKE("a.service"), &changes, &n_changes) >= 0);
assert_se(n_changes == 0);
unit_file_changes_free(changes, n_changes);
changes = NULL; n_changes = 0;
/* Let's enable this indirectly via a symlink */
- assert_se(unit_file_enable(UNIT_FILE_SYSTEM, false, root, STRV_MAKE("d.service"), false, &changes, &n_changes) >= 0);
+ assert_se(unit_file_enable(UNIT_FILE_SYSTEM, 0, root, STRV_MAKE("d.service"), &changes, &n_changes) >= 0);
assert_se(n_changes == 1);
assert_se(changes[0].type == UNIT_FILE_SYMLINK);
assert_se(streq(changes[0].source, "/usr/lib/systemd/system/a.service"));
@@ -148,7 +148,7 @@ static void test_basic_mask_and_enable(const char *root) {
/* Let's try to reenable */
- assert_se(unit_file_reenable(UNIT_FILE_SYSTEM, false, root, STRV_MAKE("b.service"), false, &changes, &n_changes) >= 0);
+ assert_se(unit_file_reenable(UNIT_FILE_SYSTEM, 0, root, STRV_MAKE("b.service"), &changes, &n_changes) >= 0);
assert_se(n_changes == 2);
assert_se(changes[0].type == UNIT_FILE_UNLINK);
p = strjoina(root, SYSTEM_CONFIG_UNIT_PATH"/multi-user.target.wants/a.service");
@@ -217,7 +217,7 @@ static void test_linked_units(const char *root) {
assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "linked3.service", &state) >= 0 && state == UNIT_FILE_LINKED);
/* First, let's link the unit into the search path */
- assert_se(unit_file_link(UNIT_FILE_SYSTEM, false, root, STRV_MAKE("/opt/linked.service"), false, &changes, &n_changes) >= 0);
+ assert_se(unit_file_link(UNIT_FILE_SYSTEM, 0, root, STRV_MAKE("/opt/linked.service"), &changes, &n_changes) >= 0);
assert_se(n_changes == 1);
assert_se(changes[0].type == UNIT_FILE_SYMLINK);
assert_se(streq(changes[0].source, "/opt/linked.service"));
@@ -229,7 +229,7 @@ static void test_linked_units(const char *root) {
assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "linked.service", &state) >= 0 && state == UNIT_FILE_LINKED);
/* Let's unlink it from the search path again */
- assert_se(unit_file_disable(UNIT_FILE_SYSTEM, false, root, STRV_MAKE("linked.service"), &changes, &n_changes) >= 0);
+ assert_se(unit_file_disable(UNIT_FILE_SYSTEM, 0, root, STRV_MAKE("linked.service"), &changes, &n_changes) >= 0);
assert_se(n_changes == 1);
assert_se(changes[0].type == UNIT_FILE_UNLINK);
p = strjoina(root, SYSTEM_CONFIG_UNIT_PATH"/linked.service");
@@ -240,7 +240,7 @@ static void test_linked_units(const char *root) {
assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "linked.service", NULL) == -ENOENT);
/* Now, let's not just link it, but also enable it */
- assert_se(unit_file_enable(UNIT_FILE_SYSTEM, false, root, STRV_MAKE("/opt/linked.service"), false, &changes, &n_changes) >= 0);
+ assert_se(unit_file_enable(UNIT_FILE_SYSTEM, 0, root, STRV_MAKE("/opt/linked.service"), &changes, &n_changes) >= 0);
assert_se(n_changes == 2);
p = strjoina(root, SYSTEM_CONFIG_UNIT_PATH"/multi-user.target.wants/linked.service");
q = strjoina(root, SYSTEM_CONFIG_UNIT_PATH"/linked.service");
@@ -262,7 +262,7 @@ static void test_linked_units(const char *root) {
assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "linked.service", &state) >= 0 && state == UNIT_FILE_ENABLED);
/* And let's unlink it again */
- assert_se(unit_file_disable(UNIT_FILE_SYSTEM, false, root, STRV_MAKE("linked.service"), &changes, &n_changes) >= 0);
+ assert_se(unit_file_disable(UNIT_FILE_SYSTEM, 0, root, STRV_MAKE("linked.service"), &changes, &n_changes) >= 0);
assert_se(n_changes == 2);
p = strjoina(root, SYSTEM_CONFIG_UNIT_PATH"/multi-user.target.wants/linked.service");
q = strjoina(root, SYSTEM_CONFIG_UNIT_PATH"/linked.service");
@@ -282,7 +282,7 @@ static void test_linked_units(const char *root) {
assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "linked.service", NULL) == -ENOENT);
- assert_se(unit_file_enable(UNIT_FILE_SYSTEM, false, root, STRV_MAKE("linked2.service"), false, &changes, &n_changes) >= 0);
+ assert_se(unit_file_enable(UNIT_FILE_SYSTEM, 0, root, STRV_MAKE("linked2.service"), &changes, &n_changes) >= 0);
assert_se(n_changes == 2);
p = strjoina(root, SYSTEM_CONFIG_UNIT_PATH"/multi-user.target.wants/linked2.service");
q = strjoina(root, SYSTEM_CONFIG_UNIT_PATH"/linked2.service");
@@ -301,7 +301,7 @@ static void test_linked_units(const char *root) {
unit_file_changes_free(changes, n_changes);
changes = NULL; n_changes = 0;
- assert_se(unit_file_enable(UNIT_FILE_SYSTEM, false, root, STRV_MAKE("linked3.service"), false, &changes, &n_changes) >= 0);
+ assert_se(unit_file_enable(UNIT_FILE_SYSTEM, 0, root, STRV_MAKE("linked3.service"), &changes, &n_changes) >= 0);
assert_se(n_changes == 1);
assert_se(changes[0].type == UNIT_FILE_SYMLINK);
assert_se(startswith(changes[0].path, root));
@@ -325,14 +325,16 @@ static void test_default(const char *root) {
assert_se(unit_file_get_default(UNIT_FILE_SYSTEM, root, &def) == -ENOENT);
- assert_se(unit_file_set_default(UNIT_FILE_SYSTEM, root, "idontexist.target", false, &changes, &n_changes) == -ENOENT);
- assert_se(n_changes == 0);
+ assert_se(unit_file_set_default(UNIT_FILE_SYSTEM, 0, root, "idontexist.target", &changes, &n_changes) == -ENOENT);
+ assert_se(n_changes == 1);
+ assert_se(changes[0].type == -ENOENT);
+ assert_se(streq_ptr(changes[0].path, "idontexist.target"));
unit_file_changes_free(changes, n_changes);
changes = NULL; n_changes = 0;
assert_se(unit_file_get_default(UNIT_FILE_SYSTEM, root, &def) == -ENOENT);
- assert_se(unit_file_set_default(UNIT_FILE_SYSTEM, root, "test-default.target", false, &changes, &n_changes) >= 0);
+ assert_se(unit_file_set_default(UNIT_FILE_SYSTEM, 0, root, "test-default.target", &changes, &n_changes) >= 0);
assert_se(n_changes == 1);
assert_se(changes[0].type == UNIT_FILE_SYMLINK);
assert_se(streq(changes[0].source, "/usr/lib/systemd/system/test-default-real.target"));
@@ -362,7 +364,7 @@ static void test_add_dependency(const char *root) {
p = strjoina(root, "/usr/lib/systemd/system/add-dependency-test-service.service");
assert_se(symlink("real-add-dependency-test-service.service", p) >= 0);
- assert_se(unit_file_add_dependency(UNIT_FILE_SYSTEM, false, root, STRV_MAKE("add-dependency-test-service.service"), "add-dependency-test-target.target", UNIT_WANTS, false, &changes, &n_changes) >= 0);
+ assert_se(unit_file_add_dependency(UNIT_FILE_SYSTEM, 0, root, STRV_MAKE("add-dependency-test-service.service"), "add-dependency-test-target.target", UNIT_WANTS, &changes, &n_changes) >= 0);
assert_se(n_changes == 1);
assert_se(changes[0].type == UNIT_FILE_SYMLINK);
assert_se(streq(changes[0].source, "/usr/lib/systemd/system/real-add-dependency-test-service.service"));
@@ -399,7 +401,7 @@ static void test_template_enable(const char *root) {
assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "template-symlink@def.service", &state) >= 0 && state == UNIT_FILE_DISABLED);
assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "template-symlink@foo.service", &state) >= 0 && state == UNIT_FILE_DISABLED);
- assert_se(unit_file_enable(UNIT_FILE_SYSTEM, false, root, STRV_MAKE("template@.service"), false, &changes, &n_changes) >= 0);
+ assert_se(unit_file_enable(UNIT_FILE_SYSTEM, 0, root, STRV_MAKE("template@.service"), &changes, &n_changes) >= 0);
assert_se(n_changes == 1);
assert_se(changes[0].type == UNIT_FILE_SYMLINK);
assert_se(streq(changes[0].source, "/usr/lib/systemd/system/template@.service"));
@@ -415,7 +417,7 @@ static void test_template_enable(const char *root) {
assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "template-symlink@def.service", &state) >= 0 && state == UNIT_FILE_ENABLED);
assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "template-symlink@foo.service", &state) >= 0 && state == UNIT_FILE_DISABLED);
- assert_se(unit_file_disable(UNIT_FILE_SYSTEM, false, root, STRV_MAKE("template@.service"), &changes, &n_changes) >= 0);
+ assert_se(unit_file_disable(UNIT_FILE_SYSTEM, 0, root, STRV_MAKE("template@.service"), &changes, &n_changes) >= 0);
assert_se(n_changes == 1);
assert_se(changes[0].type == UNIT_FILE_UNLINK);
assert_se(streq(changes[0].path, p));
@@ -429,7 +431,7 @@ static void test_template_enable(const char *root) {
assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "template-symlink@def.service", &state) >= 0 && state == UNIT_FILE_DISABLED);
assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "template-symlink@foo.service", &state) >= 0 && state == UNIT_FILE_DISABLED);
- assert_se(unit_file_enable(UNIT_FILE_SYSTEM, false, root, STRV_MAKE("template@foo.service"), false, &changes, &n_changes) >= 0);
+ assert_se(unit_file_enable(UNIT_FILE_SYSTEM, 0, root, STRV_MAKE("template@foo.service"), &changes, &n_changes) >= 0);
assert_se(changes[0].type == UNIT_FILE_SYMLINK);
assert_se(streq(changes[0].source, "/usr/lib/systemd/system/template@.service"));
p = strjoina(root, SYSTEM_CONFIG_UNIT_PATH"/multi-user.target.wants/template@foo.service");
@@ -444,7 +446,7 @@ static void test_template_enable(const char *root) {
assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "template-symlink@def.service", &state) >= 0 && state == UNIT_FILE_DISABLED);
assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "template-symlink@foo.service", &state) >= 0 && state == UNIT_FILE_ENABLED);
- assert_se(unit_file_disable(UNIT_FILE_SYSTEM, false, root, STRV_MAKE("template@foo.service"), &changes, &n_changes) >= 0);
+ assert_se(unit_file_disable(UNIT_FILE_SYSTEM, 0, root, STRV_MAKE("template@foo.service"), &changes, &n_changes) >= 0);
assert_se(n_changes == 1);
assert_se(changes[0].type == UNIT_FILE_UNLINK);
assert_se(streq(changes[0].path, p));
@@ -460,7 +462,7 @@ static void test_template_enable(const char *root) {
assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "template-symlink@foo.service", &state) >= 0 && state == UNIT_FILE_DISABLED);
assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "template-symlink@quux.service", &state) >= 0 && state == UNIT_FILE_DISABLED);
- assert_se(unit_file_enable(UNIT_FILE_SYSTEM, false, root, STRV_MAKE("template-symlink@quux.service"), false, &changes, &n_changes) >= 0);
+ assert_se(unit_file_enable(UNIT_FILE_SYSTEM, 0, root, STRV_MAKE("template-symlink@quux.service"), &changes, &n_changes) >= 0);
assert_se(changes[0].type == UNIT_FILE_SYMLINK);
assert_se(streq(changes[0].source, "/usr/lib/systemd/system/template@.service"));
p = strjoina(root, SYSTEM_CONFIG_UNIT_PATH"/multi-user.target.wants/template@quux.service");
@@ -505,7 +507,7 @@ static void test_indirect(const char *root) {
assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "indirectb.service", &state) >= 0 && state == UNIT_FILE_DISABLED);
assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "indirectc.service", &state) >= 0 && state == UNIT_FILE_INDIRECT);
- assert_se(unit_file_enable(UNIT_FILE_SYSTEM, false, root, STRV_MAKE("indirectc.service"), false, &changes, &n_changes) >= 0);
+ assert_se(unit_file_enable(UNIT_FILE_SYSTEM, 0, root, STRV_MAKE("indirectc.service"), &changes, &n_changes) >= 0);
assert_se(n_changes == 1);
assert_se(changes[0].type == UNIT_FILE_SYMLINK);
assert_se(streq(changes[0].source, "/usr/lib/systemd/system/indirectb.service"));
@@ -518,7 +520,7 @@ static void test_indirect(const char *root) {
assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "indirectb.service", &state) >= 0 && state == UNIT_FILE_ENABLED);
assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "indirectc.service", &state) >= 0 && state == UNIT_FILE_INDIRECT);
- assert_se(unit_file_disable(UNIT_FILE_SYSTEM, false, root, STRV_MAKE("indirectc.service"), &changes, &n_changes) >= 0);
+ assert_se(unit_file_disable(UNIT_FILE_SYSTEM, 0, root, STRV_MAKE("indirectc.service"), &changes, &n_changes) >= 0);
assert_se(n_changes == 1);
assert_se(changes[0].type == UNIT_FILE_UNLINK);
p = strjoina(root, SYSTEM_CONFIG_UNIT_PATH"/multi-user.target.wants/indirectb.service");
@@ -558,7 +560,7 @@ static void test_preset_and_list(const char *root) {
assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "preset-yes.service", &state) >= 0 && state == UNIT_FILE_DISABLED);
assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "preset-no.service", &state) >= 0 && state == UNIT_FILE_DISABLED);
- assert_se(unit_file_preset(UNIT_FILE_SYSTEM, false, root, STRV_MAKE("preset-yes.service"), UNIT_FILE_PRESET_FULL, false, &changes, &n_changes) >= 0);
+ assert_se(unit_file_preset(UNIT_FILE_SYSTEM, 0, root, STRV_MAKE("preset-yes.service"), UNIT_FILE_PRESET_FULL, &changes, &n_changes) >= 0);
assert_se(n_changes == 1);
assert_se(changes[0].type == UNIT_FILE_SYMLINK);
assert_se(streq(changes[0].source, "/usr/lib/systemd/system/preset-yes.service"));
@@ -570,7 +572,7 @@ static void test_preset_and_list(const char *root) {
assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "preset-yes.service", &state) >= 0 && state == UNIT_FILE_ENABLED);
assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "preset-no.service", &state) >= 0 && state == UNIT_FILE_DISABLED);
- assert_se(unit_file_disable(UNIT_FILE_SYSTEM, false, root, STRV_MAKE("preset-yes.service"), &changes, &n_changes) >= 0);
+ assert_se(unit_file_disable(UNIT_FILE_SYSTEM, 0, root, STRV_MAKE("preset-yes.service"), &changes, &n_changes) >= 0);
assert_se(n_changes == 1);
assert_se(changes[0].type == UNIT_FILE_UNLINK);
p = strjoina(root, SYSTEM_CONFIG_UNIT_PATH"/multi-user.target.wants/preset-yes.service");
@@ -581,7 +583,7 @@ static void test_preset_and_list(const char *root) {
assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "preset-yes.service", &state) >= 0 && state == UNIT_FILE_DISABLED);
assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "preset-no.service", &state) >= 0 && state == UNIT_FILE_DISABLED);
- assert_se(unit_file_preset(UNIT_FILE_SYSTEM, false, root, STRV_MAKE("preset-no.service"), UNIT_FILE_PRESET_FULL, false, &changes, &n_changes) >= 0);
+ assert_se(unit_file_preset(UNIT_FILE_SYSTEM, 0, root, STRV_MAKE("preset-no.service"), UNIT_FILE_PRESET_FULL, &changes, &n_changes) >= 0);
assert_se(n_changes == 0);
unit_file_changes_free(changes, n_changes);
changes = NULL; n_changes = 0;
@@ -589,7 +591,7 @@ static void test_preset_and_list(const char *root) {
assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "preset-yes.service", &state) >= 0 && state == UNIT_FILE_DISABLED);
assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "preset-no.service", &state) >= 0 && state == UNIT_FILE_DISABLED);
- assert_se(unit_file_preset_all(UNIT_FILE_SYSTEM, false, root, UNIT_FILE_PRESET_FULL, false, &changes, &n_changes) >= 0);
+ assert_se(unit_file_preset_all(UNIT_FILE_SYSTEM, 0, root, UNIT_FILE_PRESET_FULL, &changes, &n_changes) >= 0);
assert_se(n_changes > 0);
@@ -714,7 +716,7 @@ static void test_preset_order(const char *root) {
assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "prefix-1.service", &state) >= 0 && state == UNIT_FILE_DISABLED);
assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "prefix-2.service", &state) >= 0 && state == UNIT_FILE_DISABLED);
- assert_se(unit_file_preset(UNIT_FILE_SYSTEM, false, root, STRV_MAKE("prefix-1.service"), UNIT_FILE_PRESET_FULL, false, &changes, &n_changes) >= 0);
+ assert_se(unit_file_preset(UNIT_FILE_SYSTEM, 0, root, STRV_MAKE("prefix-1.service"), UNIT_FILE_PRESET_FULL, &changes, &n_changes) >= 0);
assert_se(n_changes == 1);
assert_se(changes[0].type == UNIT_FILE_SYMLINK);
assert_se(streq(changes[0].source, "/usr/lib/systemd/system/prefix-1.service"));
@@ -726,7 +728,7 @@ static void test_preset_order(const char *root) {
assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "prefix-1.service", &state) >= 0 && state == UNIT_FILE_ENABLED);
assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "prefix-2.service", &state) >= 0 && state == UNIT_FILE_DISABLED);
- assert_se(unit_file_preset(UNIT_FILE_SYSTEM, false, root, STRV_MAKE("prefix-2.service"), UNIT_FILE_PRESET_FULL, false, &changes, &n_changes) >= 0);
+ assert_se(unit_file_preset(UNIT_FILE_SYSTEM, 0, root, STRV_MAKE("prefix-2.service"), UNIT_FILE_PRESET_FULL, &changes, &n_changes) >= 0);
assert_se(n_changes == 0);
assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "prefix-1.service", &state) >= 0 && state == UNIT_FILE_ENABLED);
diff --git a/src/test/test-install.c b/src/test/test-install.c
index d9b93c306a..936d606061 100644
--- a/src/test/test-install.c
+++ b/src/test/test-install.c
@@ -70,12 +70,12 @@ int main(int argc, char* argv[]) {
log_info("/*** enable **/");
- r = unit_file_enable(UNIT_FILE_SYSTEM, false, NULL, (char**) files, false, &changes, &n_changes);
+ r = unit_file_enable(UNIT_FILE_SYSTEM, 0, NULL, (char**) files, &changes, &n_changes);
assert_se(r >= 0);
log_info("/*** enable2 **/");
- r = unit_file_enable(UNIT_FILE_SYSTEM, false, NULL, (char**) files, false, &changes, &n_changes);
+ r = unit_file_enable(UNIT_FILE_SYSTEM, 0, NULL, (char**) files, &changes, &n_changes);
assert_se(r >= 0);
dump_changes(changes, n_changes);
@@ -89,7 +89,7 @@ int main(int argc, char* argv[]) {
changes = NULL;
n_changes = 0;
- r = unit_file_disable(UNIT_FILE_SYSTEM, false, NULL, (char**) files, &changes, &n_changes);
+ r = unit_file_disable(UNIT_FILE_SYSTEM, 0, NULL, (char**) files, &changes, &n_changes);
assert_se(r >= 0);
dump_changes(changes, n_changes);
@@ -103,10 +103,10 @@ int main(int argc, char* argv[]) {
changes = NULL;
n_changes = 0;
- r = unit_file_mask(UNIT_FILE_SYSTEM, false, NULL, (char**) files, false, &changes, &n_changes);
+ r = unit_file_mask(UNIT_FILE_SYSTEM, 0, NULL, (char**) files, &changes, &n_changes);
assert_se(r >= 0);
log_info("/*** mask2 ***/");
- r = unit_file_mask(UNIT_FILE_SYSTEM, false, NULL, (char**) files, false, &changes, &n_changes);
+ r = unit_file_mask(UNIT_FILE_SYSTEM, 0, NULL, (char**) files, &changes, &n_changes);
assert_se(r >= 0);
dump_changes(changes, n_changes);
@@ -120,10 +120,10 @@ int main(int argc, char* argv[]) {
changes = NULL;
n_changes = 0;
- r = unit_file_unmask(UNIT_FILE_SYSTEM, false, NULL, (char**) files, &changes, &n_changes);
+ r = unit_file_unmask(UNIT_FILE_SYSTEM, 0, NULL, (char**) files, &changes, &n_changes);
assert_se(r >= 0);
log_info("/*** unmask2 ***/");
- r = unit_file_unmask(UNIT_FILE_SYSTEM, false, NULL, (char**) files, &changes, &n_changes);
+ r = unit_file_unmask(UNIT_FILE_SYSTEM, 0, NULL, (char**) files, &changes, &n_changes);
assert_se(r >= 0);
dump_changes(changes, n_changes);
@@ -137,7 +137,7 @@ int main(int argc, char* argv[]) {
changes = NULL;
n_changes = 0;
- r = unit_file_mask(UNIT_FILE_SYSTEM, false, NULL, (char**) files, false, &changes, &n_changes);
+ r = unit_file_mask(UNIT_FILE_SYSTEM, 0, NULL, (char**) files, &changes, &n_changes);
assert_se(r >= 0);
dump_changes(changes, n_changes);
@@ -151,10 +151,10 @@ int main(int argc, char* argv[]) {
changes = NULL;
n_changes = 0;
- r = unit_file_disable(UNIT_FILE_SYSTEM, false, NULL, (char**) files, &changes, &n_changes);
+ r = unit_file_disable(UNIT_FILE_SYSTEM, 0, NULL, (char**) files, &changes, &n_changes);
assert_se(r >= 0);
log_info("/*** disable2 ***/");
- r = unit_file_disable(UNIT_FILE_SYSTEM, false, NULL, (char**) files, &changes, &n_changes);
+ r = unit_file_disable(UNIT_FILE_SYSTEM, 0, NULL, (char**) files, &changes, &n_changes);
assert_se(r >= 0);
dump_changes(changes, n_changes);
@@ -168,7 +168,7 @@ int main(int argc, char* argv[]) {
changes = NULL;
n_changes = 0;
- r = unit_file_unmask(UNIT_FILE_SYSTEM, false, NULL, (char**) files, &changes, &n_changes);
+ r = unit_file_unmask(UNIT_FILE_SYSTEM, 0, NULL, (char**) files, &changes, &n_changes);
assert_se(r >= 0);
dump_changes(changes, n_changes);
@@ -182,7 +182,7 @@ int main(int argc, char* argv[]) {
changes = NULL;
n_changes = 0;
- r = unit_file_enable(UNIT_FILE_SYSTEM, false, NULL, (char**) files2, false, &changes, &n_changes);
+ r = unit_file_enable(UNIT_FILE_SYSTEM, 0, NULL, (char**) files2, &changes, &n_changes);
assert_se(r >= 0);
dump_changes(changes, n_changes);
@@ -196,7 +196,7 @@ int main(int argc, char* argv[]) {
changes = NULL;
n_changes = 0;
- r = unit_file_disable(UNIT_FILE_SYSTEM, false, NULL, STRV_MAKE(basename(files2[0])), &changes, &n_changes);
+ r = unit_file_disable(UNIT_FILE_SYSTEM, 0, NULL, STRV_MAKE(basename(files2[0])), &changes, &n_changes);
assert_se(r >= 0);
dump_changes(changes, n_changes);
@@ -209,7 +209,7 @@ int main(int argc, char* argv[]) {
changes = NULL;
n_changes = 0;
- r = unit_file_link(UNIT_FILE_SYSTEM, false, NULL, (char**) files2, false, &changes, &n_changes);
+ r = unit_file_link(UNIT_FILE_SYSTEM, 0, NULL, (char**) files2, &changes, &n_changes);
assert_se(r >= 0);
dump_changes(changes, n_changes);
@@ -223,7 +223,7 @@ int main(int argc, char* argv[]) {
changes = NULL;
n_changes = 0;
- r = unit_file_disable(UNIT_FILE_SYSTEM, false, NULL, STRV_MAKE(basename(files2[0])), &changes, &n_changes);
+ r = unit_file_disable(UNIT_FILE_SYSTEM, 0, NULL, STRV_MAKE(basename(files2[0])), &changes, &n_changes);
assert_se(r >= 0);
dump_changes(changes, n_changes);
@@ -236,7 +236,7 @@ int main(int argc, char* argv[]) {
changes = NULL;
n_changes = 0;
- r = unit_file_link(UNIT_FILE_SYSTEM, false, NULL, (char**) files2, false, &changes, &n_changes);
+ r = unit_file_link(UNIT_FILE_SYSTEM, 0, NULL, (char**) files2, &changes, &n_changes);
assert_se(r >= 0);
dump_changes(changes, n_changes);
@@ -250,7 +250,7 @@ int main(int argc, char* argv[]) {
changes = NULL;
n_changes = 0;
- r = unit_file_reenable(UNIT_FILE_SYSTEM, false, NULL, (char**) files2, false, &changes, &n_changes);
+ r = unit_file_reenable(UNIT_FILE_SYSTEM, 0, NULL, (char**) files2, &changes, &n_changes);
assert_se(r >= 0);
dump_changes(changes, n_changes);
@@ -264,7 +264,7 @@ int main(int argc, char* argv[]) {
changes = NULL;
n_changes = 0;
- r = unit_file_disable(UNIT_FILE_SYSTEM, false, NULL, STRV_MAKE(basename(files2[0])), &changes, &n_changes);
+ r = unit_file_disable(UNIT_FILE_SYSTEM, 0, NULL, STRV_MAKE(basename(files2[0])), &changes, &n_changes);
assert_se(r >= 0);
dump_changes(changes, n_changes);
@@ -276,7 +276,7 @@ int main(int argc, char* argv[]) {
changes = NULL;
n_changes = 0;
- r = unit_file_preset(UNIT_FILE_SYSTEM, false, NULL, (char**) files, UNIT_FILE_PRESET_FULL, false, &changes, &n_changes);
+ r = unit_file_preset(UNIT_FILE_SYSTEM, 0, NULL, (char**) files, UNIT_FILE_PRESET_FULL, &changes, &n_changes);
assert_se(r >= 0);
dump_changes(changes, n_changes);
diff --git a/src/test/test-ipcrm.c b/src/test/test-ipcrm.c
index 9705884b6c..d7f9564d6a 100644
--- a/src/test/test-ipcrm.c
+++ b/src/test/test-ipcrm.c
@@ -32,5 +32,5 @@ int main(int argc, char *argv[]) {
return EXIT_FAILURE;
}
- return clean_ipc(uid) < 0 ? EXIT_FAILURE : EXIT_SUCCESS;
+ return clean_ipc_by_uid(uid) < 0 ? EXIT_FAILURE : EXIT_SUCCESS;
}
diff --git a/src/test/test-list.c b/src/test/test-list.c
index 542e2ef623..4fb4173231 100644
--- a/src/test/test-list.c
+++ b/src/test/test-list.c
@@ -132,6 +132,29 @@ int main(int argc, const char *argv[]) {
assert_se(items[1].item_prev == &items[3]);
assert_se(items[3].item_prev == NULL);
+ LIST_INSERT_BEFORE(item, head, &items[3], &items[0]);
+ assert_se(items[2].item_next == NULL);
+ assert_se(items[1].item_next == &items[2]);
+ assert_se(items[3].item_next == &items[1]);
+ assert_se(items[0].item_next == &items[3]);
+
+ assert_se(items[2].item_prev == &items[1]);
+ assert_se(items[1].item_prev == &items[3]);
+ assert_se(items[3].item_prev == &items[0]);
+ assert_se(items[0].item_prev == NULL);
+ assert_se(head == &items[0]);
+
+ LIST_REMOVE(item, head, &items[0]);
+ assert_se(LIST_JUST_US(item, &items[0]));
+
+ assert_se(items[2].item_next == NULL);
+ assert_se(items[1].item_next == &items[2]);
+ assert_se(items[3].item_next == &items[1]);
+
+ assert_se(items[2].item_prev == &items[1]);
+ assert_se(items[1].item_prev == &items[3]);
+ assert_se(items[3].item_prev == NULL);
+
LIST_INSERT_BEFORE(item, head, NULL, &items[0]);
assert_se(items[0].item_next == NULL);
assert_se(items[2].item_next == &items[0]);
diff --git a/src/test/test-ns.c b/src/test/test-ns.c
index 151c88bc8c..83e955430c 100644
--- a/src/test/test-ns.c
+++ b/src/test/test-ns.c
@@ -26,13 +26,18 @@
int main(int argc, char *argv[]) {
const char * const writable[] = {
"/home",
+ "-/home/lennart/projects/foobar", /* this should be masked automatically */
NULL
};
const char * const readonly[] = {
- "/",
- "/usr",
+ /* "/", */
+ /* "/usr", */
"/boot",
+ "/lib",
+ "/usr/lib",
+ "-/lib64",
+ "-/usr/lib64",
NULL
};
@@ -40,13 +45,22 @@ int main(int argc, char *argv[]) {
"/home/lennart/projects",
NULL
};
+
+ static const NameSpaceInfo ns_info = {
+ .private_dev = true,
+ .protect_control_groups = true,
+ .protect_kernel_tunables = true,
+ .protect_kernel_modules = true,
+ };
+
char *root_directory;
char *projects_directory;
-
int r;
char tmp_dir[] = "/tmp/systemd-private-XXXXXX",
var_tmp_dir[] = "/var/tmp/systemd-private-XXXXXX";
+ log_set_max_level(LOG_DEBUG);
+
assert_se(mkdtemp(tmp_dir));
assert_se(mkdtemp(var_tmp_dir));
@@ -63,12 +77,12 @@ int main(int argc, char *argv[]) {
log_info("Not chrooted");
r = setup_namespace(root_directory,
+ &ns_info,
(char **) writable,
(char **) readonly,
(char **) inaccessible,
tmp_dir,
var_tmp_dir,
- true,
PROTECT_HOME_NO,
PROTECT_SYSTEM_NO,
0);
diff --git a/src/test/test-parse-util.c b/src/test/test-parse-util.c
index 20c6fd9b92..17f4d2c8b3 100644
--- a/src/test/test-parse-util.c
+++ b/src/test/test-parse-util.c
@@ -493,6 +493,39 @@ static void test_parse_percent(void) {
assert_se(parse_percent("1%%") == -EINVAL);
}
+static void test_parse_percent_unbounded(void) {
+ assert_se(parse_percent_unbounded("101%") == 101);
+ assert_se(parse_percent_unbounded("400%") == 400);
+}
+
+static void test_parse_nice(void) {
+ int n;
+
+ assert_se(parse_nice("0", &n) >= 0 && n == 0);
+ assert_se(parse_nice("+0", &n) >= 0 && n == 0);
+ assert_se(parse_nice("-1", &n) >= 0 && n == -1);
+ assert_se(parse_nice("-2", &n) >= 0 && n == -2);
+ assert_se(parse_nice("1", &n) >= 0 && n == 1);
+ assert_se(parse_nice("2", &n) >= 0 && n == 2);
+ assert_se(parse_nice("+1", &n) >= 0 && n == 1);
+ assert_se(parse_nice("+2", &n) >= 0 && n == 2);
+ assert_se(parse_nice("-20", &n) >= 0 && n == -20);
+ assert_se(parse_nice("19", &n) >= 0 && n == 19);
+ assert_se(parse_nice("+19", &n) >= 0 && n == 19);
+
+
+ assert_se(parse_nice("", &n) == -EINVAL);
+ assert_se(parse_nice("-", &n) == -EINVAL);
+ assert_se(parse_nice("+", &n) == -EINVAL);
+ assert_se(parse_nice("xx", &n) == -EINVAL);
+ assert_se(parse_nice("-50", &n) == -ERANGE);
+ assert_se(parse_nice("50", &n) == -ERANGE);
+ assert_se(parse_nice("+50", &n) == -ERANGE);
+ assert_se(parse_nice("-21", &n) == -ERANGE);
+ assert_se(parse_nice("20", &n) == -ERANGE);
+ assert_se(parse_nice("+20", &n) == -ERANGE);
+}
+
int main(int argc, char *argv[]) {
log_parse_environment();
log_open();
@@ -507,6 +540,8 @@ int main(int argc, char *argv[]) {
test_safe_atoi16();
test_safe_atod();
test_parse_percent();
+ test_parse_percent_unbounded();
+ test_parse_nice();
return 0;
}
diff --git a/src/test/test-path-util.c b/src/test/test-path-util.c
index 852c85d2e6..7221b1abde 100644
--- a/src/test/test-path-util.c
+++ b/src/test/test-path-util.c
@@ -114,7 +114,8 @@ static void test_find_binary(const char *self) {
assert_se(find_binary(self, &p) == 0);
puts(p);
- assert_se(endswith(p, "/lt-test-path-util"));
+ /* libtool might prefix the binary name with "lt-" */
+ assert_se(endswith(p, "/lt-test-path-util") || endswith(p, "/test-path-util"));
assert_se(path_is_absolute(p));
free(p);
@@ -262,16 +263,37 @@ static void test_strv_resolve(void) {
}
static void test_path_startswith(void) {
- assert_se(path_startswith("/foo/bar/barfoo/", "/foo"));
- assert_se(path_startswith("/foo/bar/barfoo/", "/foo/"));
- assert_se(path_startswith("/foo/bar/barfoo/", "/"));
- assert_se(path_startswith("/foo/bar/barfoo/", "////"));
- assert_se(path_startswith("/foo/bar/barfoo/", "/foo//bar/////barfoo///"));
- assert_se(path_startswith("/foo/bar/barfoo/", "/foo/bar/barfoo////"));
- assert_se(path_startswith("/foo/bar/barfoo/", "/foo/bar///barfoo/"));
- assert_se(path_startswith("/foo/bar/barfoo/", "/foo////bar/barfoo/"));
- assert_se(path_startswith("/foo/bar/barfoo/", "////foo/bar/barfoo/"));
- assert_se(path_startswith("/foo/bar/barfoo/", "/foo/bar/barfoo"));
+ const char *p;
+
+ p = path_startswith("/foo/bar/barfoo/", "/foo");
+ assert_se(streq_ptr(p, "bar/barfoo/"));
+
+ p = path_startswith("/foo/bar/barfoo/", "/foo/");
+ assert_se(streq_ptr(p, "bar/barfoo/"));
+
+ p = path_startswith("/foo/bar/barfoo/", "/");
+ assert_se(streq_ptr(p, "foo/bar/barfoo/"));
+
+ p = path_startswith("/foo/bar/barfoo/", "////");
+ assert_se(streq_ptr(p, "foo/bar/barfoo/"));
+
+ p = path_startswith("/foo/bar/barfoo/", "/foo//bar/////barfoo///");
+ assert_se(streq_ptr(p, ""));
+
+ p = path_startswith("/foo/bar/barfoo/", "/foo/bar/barfoo////");
+ assert_se(streq_ptr(p, ""));
+
+ p = path_startswith("/foo/bar/barfoo/", "/foo/bar///barfoo/");
+ assert_se(streq_ptr(p, ""));
+
+ p = path_startswith("/foo/bar/barfoo/", "/foo////bar/barfoo/");
+ assert_se(streq_ptr(p, ""));
+
+ p = path_startswith("/foo/bar/barfoo/", "////foo/bar/barfoo/");
+ assert_se(streq_ptr(p, ""));
+
+ p = path_startswith("/foo/bar/barfoo/", "/foo/bar/barfoo");
+ assert_se(streq_ptr(p, ""));
assert_se(!path_startswith("/foo/bar/barfoo/", "/foo/bar/barfooa/"));
assert_se(!path_startswith("/foo/bar/barfoo/", "/foo/bar/barfooa"));
@@ -510,7 +532,24 @@ static void test_hidden_or_backup_file(void) {
assert_se(!hidden_or_backup_file("test.dpkg-old.foo"));
}
+static void test_systemd_installation_has_version(const char *path) {
+ int r;
+ const unsigned versions[] = {0, 231, atoi(PACKAGE_VERSION), 999};
+ unsigned i;
+
+ for (i = 0; i < ELEMENTSOF(versions); i++) {
+ r = systemd_installation_has_version(path, versions[i]);
+ assert_se(r >= 0);
+ log_info("%s has systemd >= %u: %s",
+ path ?: "Current installation", versions[i], yes_no(r));
+ }
+}
+
int main(int argc, char **argv) {
+ log_set_max_level(LOG_DEBUG);
+ log_parse_environment();
+ log_open();
+
test_path();
test_find_binary(argv[0]);
test_prefixes();
@@ -525,5 +564,7 @@ int main(int argc, char **argv) {
test_filename_is_valid();
test_hidden_or_backup_file();
+ test_systemd_installation_has_version(argv[1]); /* NULL is OK */
+
return 0;
}
diff --git a/src/test/test-path.c b/src/test/test-path.c
index b4f1547b35..894102efc6 100644
--- a/src/test/test-path.c
+++ b/src/test/test-path.c
@@ -48,7 +48,7 @@ static int setup_test(Manager **m) {
r = manager_new(UNIT_FILE_USER, true, &tmp);
if (MANAGER_SKIP_TEST(r)) {
- printf("Skipping test: manager_new: %s\n", strerror(-r));
+ log_notice_errno(r, "Skipping test: manager_new: %m");
return -EXIT_TEST_SKIP;
}
assert_se(r >= 0);
diff --git a/src/test/test-proc-cmdline.c b/src/test/test-proc-cmdline.c
index 1fbe620756..99cdb214bd 100644
--- a/src/test/test-proc-cmdline.c
+++ b/src/test/test-proc-cmdline.c
@@ -25,15 +25,18 @@
#include "systemd-basic/string-util.h"
#include "systemd-basic/util.h"
-static int parse_item(const char *key, const char *value) {
+static int obj;
+
+static int parse_item(const char *key, const char *value, void *data) {
assert_se(key);
+ assert_se(data == &obj);
log_info("kernel cmdline option <%s> = <%s>", key, strna(value));
return 0;
}
static void test_parse_proc_cmdline(void) {
- assert_se(parse_proc_cmdline(parse_item) >= 0);
+ assert_se(parse_proc_cmdline(parse_item, &obj, true) >= 0);
}
static void test_runlevel_to_target(void) {
diff --git a/src/test/test-process-util.c b/src/test/test-process-util.c
index 01dcee74b0..13dd72088e 100644
--- a/src/test/test-process-util.c
+++ b/src/test/test-process-util.c
@@ -43,6 +43,8 @@
#include "systemd-basic/util.h"
#include "systemd-basic/virt.h"
+#include "test-helper.h"
+
static void test_get_process_comm(pid_t pid) {
struct stat st;
_cleanup_free_ char *a = NULL, *c = NULL, *d = NULL, *f = NULL, *i = NULL;
@@ -357,7 +359,7 @@ int main(int argc, char *argv[]) {
(void) parse_pid(argv[1], &pid);
test_get_process_comm(pid);
} else {
- test_get_process_comm(1);
+ TEST_REQ_RUNNING_SYSTEMD(test_get_process_comm(1));
test_get_process_comm(getpid());
}
diff --git a/src/test/test-sched-prio.c b/src/test/test-sched-prio.c
index f4c5864149..17eea84e7e 100644
--- a/src/test/test-sched-prio.c
+++ b/src/test/test-sched-prio.c
@@ -41,7 +41,7 @@ int main(int argc, char *argv[]) {
assert_se(set_unit_path(TEST_DIR) >= 0);
r = manager_new(UNIT_FILE_USER, true, &m);
if (MANAGER_SKIP_TEST(r)) {
- printf("Skipping test: manager_new: %s\n", strerror(-r));
+ log_notice_errno(r, "Skipping test: manager_new: %m");
return EXIT_TEST_SKIP;
}
assert_se(r >= 0);
diff --git a/src/test/test-seccomp.c b/src/test/test-seccomp.c
new file mode 100644
index 0000000000..c3f4798d15
--- /dev/null
+++ b/src/test/test-seccomp.c
@@ -0,0 +1,136 @@
+/***
+ This file is part of systemd.
+
+ Copyright 2016 Lennart Poettering
+
+ systemd is free software; you can redistribute it and/or modify it
+ under the terms of the GNU Lesser General Public License as published by
+ the Free Software Foundation; either version 2.1 of the License, or
+ (at your option) any later version.
+
+ systemd is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <stdlib.h>
+#include <sys/eventfd.h>
+#include <unistd.h>
+
+#include "systemd-basic/fd-util.h"
+#include "systemd-basic/macro.h"
+#include "systemd-basic/process-util.h"
+#include "systemd-basic/string-util.h"
+#include "systemd-basic/util.h"
+#include "systemd-shared/seccomp-util.h"
+
+static void test_seccomp_arch_to_string(void) {
+ uint32_t a, b;
+ const char *name;
+
+ a = seccomp_arch_native();
+ assert_se(a > 0);
+ name = seccomp_arch_to_string(a);
+ assert_se(name);
+ assert_se(seccomp_arch_from_string(name, &b) >= 0);
+ assert_se(a == b);
+}
+
+static void test_architecture_table(void) {
+ const char *n, *n2;
+
+ NULSTR_FOREACH(n,
+ "native\0"
+ "x86\0"
+ "x86-64\0"
+ "x32\0"
+ "arm\0"
+ "arm64\0"
+ "mips\0"
+ "mips64\0"
+ "mips64-n32\0"
+ "mips-le\0"
+ "mips64-le\0"
+ "mips64-le-n32\0"
+ "ppc\0"
+ "ppc64\0"
+ "ppc64-le\0"
+ "s390\0"
+ "s390x\0") {
+ uint32_t c;
+
+ assert_se(seccomp_arch_from_string(n, &c) >= 0);
+ n2 = seccomp_arch_to_string(c);
+ log_info("seccomp-arch: %s → 0x%"PRIx32" → %s", n, c, n2);
+ assert_se(streq_ptr(n, n2));
+ }
+}
+
+static void test_syscall_filter_set_find(void) {
+ assert_se(!syscall_filter_set_find(NULL));
+ assert_se(!syscall_filter_set_find(""));
+ assert_se(!syscall_filter_set_find("quux"));
+ assert_se(!syscall_filter_set_find("@quux"));
+
+ assert_se(syscall_filter_set_find("@clock") == syscall_filter_sets + SYSCALL_FILTER_SET_CLOCK);
+ assert_se(syscall_filter_set_find("@default") == syscall_filter_sets + SYSCALL_FILTER_SET_DEFAULT);
+ assert_se(syscall_filter_set_find("@raw-io") == syscall_filter_sets + SYSCALL_FILTER_SET_RAW_IO);
+}
+
+static void test_filter_sets(void) {
+ unsigned i;
+ int r;
+
+ if (!is_seccomp_available())
+ return;
+
+ if (geteuid() != 0)
+ return;
+
+ for (i = 0; i < _SYSCALL_FILTER_SET_MAX; i++) {
+ pid_t pid;
+
+ log_info("Testing %s", syscall_filter_sets[i].name);
+
+ pid = fork();
+ assert_se(pid >= 0);
+
+ if (pid == 0) { /* Child? */
+ int fd;
+
+ if (i == SYSCALL_FILTER_SET_DEFAULT) /* if we look at the default set, whitelist instead of blacklist */
+ r = seccomp_load_filter_set(SCMP_ACT_ERRNO(EPERM), syscall_filter_sets + i, SCMP_ACT_ALLOW);
+ else
+ r = seccomp_load_filter_set(SCMP_ACT_ALLOW, syscall_filter_sets + i, SCMP_ACT_ERRNO(EPERM));
+ if (r < 0)
+ _exit(EXIT_FAILURE);
+
+ /* Test the sycall filter with one random system call */
+ fd = eventfd(0, EFD_NONBLOCK|EFD_CLOEXEC);
+ if (IN_SET(i, SYSCALL_FILTER_SET_IO_EVENT, SYSCALL_FILTER_SET_DEFAULT))
+ assert_se(fd < 0 && errno == EPERM);
+ else {
+ assert_se(fd >= 0);
+ safe_close(fd);
+ }
+
+ _exit(EXIT_SUCCESS);
+ }
+
+ assert_se(wait_for_terminate_and_warn(syscall_filter_sets[i].name, pid, true) == EXIT_SUCCESS);
+ }
+}
+
+int main(int argc, char *argv[]) {
+
+ test_seccomp_arch_to_string();
+ test_architecture_table();
+ test_syscall_filter_set_find();
+ test_filter_sets();
+
+ return 0;
+}
diff --git a/src/test/test-sigbus.c b/src/test/test-sigbus.c
index 8f6bc1ef2f..8f71594952 100644
--- a/src/test/test-sigbus.c
+++ b/src/test/test-sigbus.c
@@ -29,6 +29,9 @@ int main(int argc, char *argv[]) {
void *addr = NULL;
uint8_t *p;
+#ifdef __SANITIZE_ADDRESS__
+ return EXIT_TEST_SKIP;
+#endif
sigbus_install();
assert_se(sigbus_pop(&addr) == 0);
diff --git a/src/test/test-stat-util.c b/src/test/test-stat-util.c
index e183ef101f..f973ce39a8 100644
--- a/src/test/test-stat-util.c
+++ b/src/test/test-stat-util.c
@@ -31,7 +31,7 @@ static void test_files_same(void) {
char name[] = "/tmp/test-files_same.XXXXXX";
char name_alias[] = "/tmp/test-files_same.alias";
- fd = mkostemp_safe(name, O_RDWR|O_CLOEXEC);
+ fd = mkostemp_safe(name);
assert_se(fd >= 0);
assert_se(symlink(name, name_alias) >= 0);
@@ -47,7 +47,7 @@ static void test_is_symlink(void) {
char name_link[] = "/tmp/test-is_symlink.link";
_cleanup_close_ int fd = -1;
- fd = mkostemp_safe(name, O_RDWR|O_CLOEXEC);
+ fd = mkostemp_safe(name);
assert_se(fd >= 0);
assert_se(symlink(name, name_link) >= 0);
diff --git a/src/test/test-strv.c b/src/test/test-strv.c
index ebee80d08e..266c6af814 100644
--- a/src/test/test-strv.c
+++ b/src/test/test-strv.c
@@ -54,6 +54,25 @@ static void test_specifier_printf(void) {
puts(w);
}
+static void test_str_in_set(void) {
+ assert_se(STR_IN_SET("x", "x", "y", "z"));
+ assert_se(!STR_IN_SET("X", "x", "y", "z"));
+ assert_se(!STR_IN_SET("", "x", "y", "z"));
+ assert_se(STR_IN_SET("x", "w", "x"));
+}
+
+static void test_strptr_in_set(void) {
+ assert_se(STRPTR_IN_SET("x", "x", "y", "z"));
+ assert_se(!STRPTR_IN_SET("X", "x", "y", "z"));
+ assert_se(!STRPTR_IN_SET("", "x", "y", "z"));
+ assert_se(STRPTR_IN_SET("x", "w", "x"));
+
+ assert_se(!STRPTR_IN_SET(NULL, "x", "y", "z"));
+ assert_se(!STRPTR_IN_SET(NULL, ""));
+ /* strv cannot contain a null, hence the result below */
+ assert_se(!STRPTR_IN_SET(NULL, NULL));
+}
+
static const char* const input_table_multiple[] = {
"one",
"two",
@@ -434,9 +453,14 @@ static void test_strv_foreach_backwards(void) {
assert_se(a);
- STRV_FOREACH_BACKWARDS(check, a) {
+ STRV_FOREACH_BACKWARDS(check, a)
assert_se(streq_ptr(*check, input_table_multiple[i--]));
- }
+
+ STRV_FOREACH_BACKWARDS(check, (char**) NULL)
+ assert_not_reached("Let's see that we check empty strv right, too.");
+
+ STRV_FOREACH_BACKWARDS(check, (char**) { NULL })
+ assert_not_reached("Let's see that we check empty strv right, too.");
}
static void test_strv_foreach_pair(void) {
@@ -703,6 +727,8 @@ static void test_strv_fnmatch(void) {
int main(int argc, char *argv[]) {
test_specifier_printf();
+ test_str_in_set();
+ test_strptr_in_set();
test_strv_foreach();
test_strv_foreach_backwards();
test_strv_foreach_pair();
diff --git a/src/test/test-tables.c b/src/test/test-tables.c
index 92f9c48c27..6bc2b0d6e3 100644
--- a/src/test/test-tables.c
+++ b/src/test/test-tables.c
@@ -44,6 +44,7 @@
#include "systemd-basic/socket-util.h"
#include "systemd-basic/unit-name.h"
#include "systemd-basic/util.h"
+#include "systemd-basic/virt.h"
#include "systemd-shared/condition.h"
#include "systemd-shared/install.h"
#include "systemd-shared/logs-show.h"
@@ -63,7 +64,7 @@ int main(int argc, char **argv) {
test_table(device_state, DEVICE_STATE);
test_table(exec_input, EXEC_INPUT);
test_table(exec_output, EXEC_OUTPUT);
- test_table(failure_action, FAILURE_ACTION);
+ test_table(emergency_action, EMERGENCY_ACTION);
test_table(job_mode, JOB_MODE);
test_table(job_result, JOB_RESULT);
test_table(job_state, JOB_STATE);
@@ -114,6 +115,7 @@ int main(int argc, char **argv) {
test_table(unit_load_state, UNIT_LOAD_STATE);
test_table(unit_type, UNIT_TYPE);
test_table(locale_variable, VARIABLE_LC);
+ test_table(virtualization, VIRTUALIZATION);
test_table_sparse(object_compressed, OBJECT_COMPRESSED);
diff --git a/src/test/test-terminal-util.c b/src/test/test-terminal-util.c
index a8f3d44ece..ced2f969e0 100644
--- a/src/test/test-terminal-util.c
+++ b/src/test/test-terminal-util.c
@@ -50,7 +50,7 @@ static void test_read_one_char(void) {
char name[] = "/tmp/test-read_one_char.XXXXXX";
int fd;
- fd = mkostemp_safe(name, O_RDWR|O_CLOEXEC);
+ fd = mkostemp_safe(name);
assert_se(fd >= 0);
file = fdopen(fd, "r+");
assert_se(file);
diff --git a/src/test/test-time.c b/src/test/test-time.c
index 77f3474494..310506d7f5 100644
--- a/src/test/test-time.c
+++ b/src/test/test-time.c
@@ -17,6 +17,7 @@
along with systemd; If not, see <http://www.gnu.org/licenses/>.
***/
+#include "systemd-basic/random-util.h"
#include "systemd-basic/strv.h"
#include "systemd-basic/time-util.h"
@@ -201,6 +202,48 @@ static void test_usec_sub(void) {
assert_se(usec_sub(USEC_INFINITY, 5) == USEC_INFINITY);
}
+static void test_format_timestamp(void) {
+ unsigned i;
+
+ for (i = 0; i < 100; i++) {
+ char buf[MAX(FORMAT_TIMESTAMP_MAX, FORMAT_TIMESPAN_MAX)];
+ usec_t x, y;
+
+ random_bytes(&x, sizeof(x));
+ x = x % (2147483600 * USEC_PER_SEC) + 1;
+
+ assert_se(format_timestamp(buf, sizeof(buf), x));
+ log_info("%s", buf);
+ assert_se(parse_timestamp(buf, &y) >= 0);
+ assert_se(x / USEC_PER_SEC == y / USEC_PER_SEC);
+
+ assert_se(format_timestamp_utc(buf, sizeof(buf), x));
+ log_info("%s", buf);
+ assert_se(parse_timestamp(buf, &y) >= 0);
+ assert_se(x / USEC_PER_SEC == y / USEC_PER_SEC);
+
+ assert_se(format_timestamp_us(buf, sizeof(buf), x));
+ log_info("%s", buf);
+ assert_se(parse_timestamp(buf, &y) >= 0);
+ assert_se(x == y);
+
+ assert_se(format_timestamp_us_utc(buf, sizeof(buf), x));
+ log_info("%s", buf);
+ assert_se(parse_timestamp(buf, &y) >= 0);
+ assert_se(x == y);
+
+ assert_se(format_timestamp_relative(buf, sizeof(buf), x));
+ log_info("%s", buf);
+ assert_se(parse_timestamp(buf, &y) >= 0);
+
+ /* The two calls above will run with a slightly different local time. Make sure we are in the same
+ * range however, but give enough leeway that this is unlikely to explode. And of course,
+ * format_timestamp_relative() scales the accuracy with the distance from the current time up to one
+ * month, cover for that too. */
+ assert_se(y > x ? y - x : x - y <= USEC_PER_MONTH + USEC_PER_DAY);
+ }
+}
+
int main(int argc, char *argv[]) {
uintmax_t x;
@@ -214,6 +257,7 @@ int main(int argc, char *argv[]) {
test_get_timezones();
test_usec_add();
test_usec_sub();
+ test_format_timestamp();
/* Ensure time_t is signed */
assert_cc((time_t) -1 < (time_t) 1);
diff --git a/src/test/test-tmpfiles.c b/src/test/test-tmpfiles.c
index 1c88434d0b..9e528e1e5e 100644
--- a/src/test/test-tmpfiles.c
+++ b/src/test/test-tmpfiles.c
@@ -51,7 +51,7 @@ int main(int argc, char** argv) {
log_debug("link1: %s", ans);
assert_se(endswith(ans, " (deleted)"));
- fd2 = mkostemp_safe(pattern, O_RDWR|O_CLOEXEC);
+ fd2 = mkostemp_safe(pattern);
assert_se(fd >= 0);
assert_se(unlink(pattern) == 0);
diff --git a/src/test/test-unit-file.c b/src/test/test-unit-file.c
index 3ab65865d3..0cc813db50 100644
--- a/src/test/test-unit-file.c
+++ b/src/test/test-unit-file.c
@@ -57,12 +57,12 @@ static int test_unit_file_get_set(void) {
r = unit_file_get_list(UNIT_FILE_SYSTEM, NULL, h, NULL, NULL);
if (r == -EPERM || r == -EACCES) {
- printf("Skipping test: unit_file_get_list: %s", strerror(-r));
+ log_notice_errno(r, "Skipping test: unit_file_get_list: %m");
return EXIT_TEST_SKIP;
}
- log_full(r == 0 ? LOG_INFO : LOG_ERR,
- "unit_file_get_list: %s", strerror(-r));
+ log_full_errno(r == 0 ? LOG_INFO : LOG_ERR, r,
+ "unit_file_get_list: %m");
if (r < 0)
return EXIT_FAILURE;
@@ -118,7 +118,7 @@ static void test_config_parse_exec(void) {
r = manager_new(UNIT_FILE_USER, true, &m);
if (MANAGER_SKIP_TEST(r)) {
- printf("Skipping test: manager_new: %s\n", strerror(-r));
+ log_notice_errno(r, "Skipping test: manager_new: %m");
return;
}
@@ -486,7 +486,7 @@ static void test_load_env_file_1(void) {
char name[] = "/tmp/test-load-env-file.XXXXXX";
_cleanup_close_ int fd;
- fd = mkostemp_safe(name, O_RDWR|O_CLOEXEC);
+ fd = mkostemp_safe(name);
assert_se(fd >= 0);
assert_se(write(fd, env_file_1, sizeof(env_file_1)) == sizeof(env_file_1));
@@ -509,7 +509,7 @@ static void test_load_env_file_2(void) {
char name[] = "/tmp/test-load-env-file.XXXXXX";
_cleanup_close_ int fd;
- fd = mkostemp_safe(name, O_RDWR|O_CLOEXEC);
+ fd = mkostemp_safe(name);
assert_se(fd >= 0);
assert_se(write(fd, env_file_2, sizeof(env_file_2)) == sizeof(env_file_2));
@@ -527,7 +527,7 @@ static void test_load_env_file_3(void) {
char name[] = "/tmp/test-load-env-file.XXXXXX";
_cleanup_close_ int fd;
- fd = mkostemp_safe(name, O_RDWR|O_CLOEXEC);
+ fd = mkostemp_safe(name);
assert_se(fd >= 0);
assert_se(write(fd, env_file_3, sizeof(env_file_3)) == sizeof(env_file_3));
@@ -543,7 +543,7 @@ static void test_load_env_file_4(void) {
_cleanup_close_ int fd;
int r;
- fd = mkostemp_safe(name, O_RDWR|O_CLOEXEC);
+ fd = mkostemp_safe(name);
assert_se(fd >= 0);
assert_se(write(fd, env_file_4, sizeof(env_file_4)) == sizeof(env_file_4));
@@ -563,7 +563,7 @@ static void test_load_env_file_5(void) {
char name[] = "/tmp/test-load-env-file.XXXXXX";
_cleanup_close_ int fd;
- fd = mkostemp_safe(name, O_RDWR|O_CLOEXEC);
+ fd = mkostemp_safe(name);
assert_se(fd >= 0);
assert_se(write(fd, env_file_5, sizeof(env_file_5)) == sizeof(env_file_5));
@@ -590,7 +590,7 @@ static void test_install_printf(void) {
assert_se(specifier_machine_id('m', NULL, NULL, &mid) >= 0 && mid);
assert_se(specifier_boot_id('b', NULL, NULL, &bid) >= 0 && bid);
assert_se((host = gethostname_malloc()));
- assert_se((user = getusername_malloc()));
+ assert_se((user = uid_to_name(getuid())));
assert_se(asprintf(&uid, UID_FMT, getuid()) >= 0);
#define expect(src, pattern, result) \
diff --git a/src/test/test-user-util.c b/src/test/test-user-util.c
index 16311d2264..10523f5e07 100644
--- a/src/test/test-user-util.c
+++ b/src/test/test-user-util.c
@@ -61,6 +61,88 @@ static void test_uid_ptr(void) {
assert_se(PTR_TO_UID(UID_TO_PTR(1000)) == 1000);
}
+static void test_valid_user_group_name(void) {
+ assert_se(!valid_user_group_name(NULL));
+ assert_se(!valid_user_group_name(""));
+ assert_se(!valid_user_group_name("1"));
+ assert_se(!valid_user_group_name("65535"));
+ assert_se(!valid_user_group_name("-1"));
+ assert_se(!valid_user_group_name("-kkk"));
+ assert_se(!valid_user_group_name("rööt"));
+ assert_se(!valid_user_group_name("."));
+ assert_se(!valid_user_group_name("eff.eff"));
+ assert_se(!valid_user_group_name("foo\nbar"));
+ assert_se(!valid_user_group_name("0123456789012345678901234567890123456789"));
+ assert_se(!valid_user_group_name_or_id("aaa:bbb"));
+
+ assert_se(valid_user_group_name("root"));
+ assert_se(valid_user_group_name("lennart"));
+ assert_se(valid_user_group_name("LENNART"));
+ assert_se(valid_user_group_name("_kkk"));
+ assert_se(valid_user_group_name("kkk-"));
+ assert_se(valid_user_group_name("kk-k"));
+
+ assert_se(valid_user_group_name("some5"));
+ assert_se(!valid_user_group_name("5some"));
+ assert_se(valid_user_group_name("INNER5NUMBER"));
+}
+
+static void test_valid_user_group_name_or_id(void) {
+ assert_se(!valid_user_group_name_or_id(NULL));
+ assert_se(!valid_user_group_name_or_id(""));
+ assert_se(valid_user_group_name_or_id("0"));
+ assert_se(valid_user_group_name_or_id("1"));
+ assert_se(valid_user_group_name_or_id("65534"));
+ assert_se(!valid_user_group_name_or_id("65535"));
+ assert_se(valid_user_group_name_or_id("65536"));
+ assert_se(!valid_user_group_name_or_id("-1"));
+ assert_se(!valid_user_group_name_or_id("-kkk"));
+ assert_se(!valid_user_group_name_or_id("rööt"));
+ assert_se(!valid_user_group_name_or_id("."));
+ assert_se(!valid_user_group_name_or_id("eff.eff"));
+ assert_se(!valid_user_group_name_or_id("foo\nbar"));
+ assert_se(!valid_user_group_name_or_id("0123456789012345678901234567890123456789"));
+ assert_se(!valid_user_group_name_or_id("aaa:bbb"));
+
+ assert_se(valid_user_group_name_or_id("root"));
+ assert_se(valid_user_group_name_or_id("lennart"));
+ assert_se(valid_user_group_name_or_id("LENNART"));
+ assert_se(valid_user_group_name_or_id("_kkk"));
+ assert_se(valid_user_group_name_or_id("kkk-"));
+ assert_se(valid_user_group_name_or_id("kk-k"));
+
+ assert_se(valid_user_group_name_or_id("some5"));
+ assert_se(!valid_user_group_name_or_id("5some"));
+ assert_se(valid_user_group_name_or_id("INNER5NUMBER"));
+}
+
+static void test_valid_gecos(void) {
+
+ assert_se(!valid_gecos(NULL));
+ assert_se(valid_gecos(""));
+ assert_se(valid_gecos("test"));
+ assert_se(valid_gecos("Ümläüt"));
+ assert_se(!valid_gecos("In\nvalid"));
+ assert_se(!valid_gecos("In:valid"));
+}
+
+static void test_valid_home(void) {
+
+ assert_se(!valid_home(NULL));
+ assert_se(!valid_home(""));
+ assert_se(!valid_home("."));
+ assert_se(!valid_home("/home/.."));
+ assert_se(!valid_home("/home/../"));
+ assert_se(!valid_home("/home\n/foo"));
+ assert_se(!valid_home("./piep"));
+ assert_se(!valid_home("piep"));
+ assert_se(!valid_home("/home/user:lennart"));
+
+ assert_se(valid_home("/"));
+ assert_se(valid_home("/home"));
+ assert_se(valid_home("/home/foo"));
+}
+
int main(int argc, char*argv[]) {
test_uid_to_name_one(0, "root");
@@ -75,5 +157,10 @@ int main(int argc, char*argv[]) {
test_parse_uid();
test_uid_ptr();
+ test_valid_user_group_name();
+ test_valid_user_group_name_or_id();
+ test_valid_gecos();
+ test_valid_home();
+
return 0;
}