]> git.ipfire.org Git - thirdparty/systemd.git/blobdiff - src/test/test-unit-file.c
core: support <soft:hard> ranges for RLIMIT options
[thirdparty/systemd.git] / src / test / test-unit-file.c
index f9107e0d0dbf127047111b286f02aea030524643..854f60be80f9cbcfd8e206bb0637caf7befb7832 100644 (file)
@@ -40,6 +40,7 @@
 #include "string-util.h"
 #include "strv.h"
 #include "test-helper.h"
+#include "user-util.h"
 #include "util.h"
 
 static int test_unit_file_get_set(void) {
@@ -558,76 +559,66 @@ static void test_load_env_file_5(void) {
 
 static void test_install_printf(void) {
         char    name[] = "name.service",
-                path[] = "/run/systemd/system/name.service",
-                user[] = "xxxx-no-such-user";
-        UnitFileInstallInfo i = {name, path, user};
-        UnitFileInstallInfo i2 = {name, path, NULL};
+                path[] = "/run/systemd/system/name.service";
+        UnitFileInstallInfo i = { .name = name, .path = path, };
+        UnitFileInstallInfo i2 = { .name= name, .path = path, };
         char    name3[] = "name@inst.service",
                 path3[] = "/run/systemd/system/name.service";
-        UnitFileInstallInfo i3 = {name3, path3, user};
-        UnitFileInstallInfo i4 = {name3, path3, NULL};
+        UnitFileInstallInfo i3 = { .name = name3, .path = path3, };
+        UnitFileInstallInfo i4 = { .name = name3, .path = path3, };
 
-        _cleanup_free_ char *mid, *bid, *host;
+        _cleanup_free_ char *mid = NULL, *bid = NULL, *host = NULL, *uid = NULL, *user = NULL;
 
         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(asprintf(&uid, UID_FMT, getuid()) >= 0);
 
 #define expect(src, pattern, result)                                    \
         do {                                                            \
                 _cleanup_free_ char *t = NULL;                          \
                 _cleanup_free_ char                                     \
                         *d1 = strdup(i.name),                           \
-                        *d2 = strdup(i.path),                           \
-                        *d3 = strdup(i.user);                           \
+                        *d2 = strdup(i.path);                           \
                 assert_se(install_full_printf(&src, pattern, &t) >= 0 || !result); \
                 memzero(i.name, strlen(i.name));                        \
                 memzero(i.path, strlen(i.path));                        \
-                memzero(i.user, strlen(i.user));                        \
-                assert_se(d1 && d2 && d3);                                 \
+                assert_se(d1 && d2);                                    \
                 if (result) {                                           \
                         printf("%s\n", t);                              \
-                        assert_se(streq(t, result));                       \
-                } else assert_se(t == NULL);                               \
+                        assert_se(streq(t, result));                    \
+                } else assert_se(t == NULL);                            \
                 strcpy(i.name, d1);                                     \
                 strcpy(i.path, d2);                                     \
-                strcpy(i.user, d3);                                     \
         } while(false)
 
-        assert_se(setenv("USER", "root", 1) == 0);
-
         expect(i, "%n", "name.service");
         expect(i, "%N", "name");
         expect(i, "%p", "name");
         expect(i, "%i", "");
-        expect(i, "%u", "xxxx-no-such-user");
-
-        DISABLE_WARNING_NONNULL;
-        expect(i, "%U", NULL);
-        REENABLE_WARNING;
+        expect(i, "%u", user);
+        expect(i, "%U", uid);
 
         expect(i, "%m", mid);
         expect(i, "%b", bid);
         expect(i, "%H", host);
 
-        expect(i2, "%u", "root");
-        expect(i2, "%U", "0");
+        expect(i2, "%u", user);
+        expect(i2, "%U", uid);
 
         expect(i3, "%n", "name@inst.service");
         expect(i3, "%N", "name@inst");
         expect(i3, "%p", "name");
-        expect(i3, "%u", "xxxx-no-such-user");
-
-        DISABLE_WARNING_NONNULL;
-        expect(i3, "%U", NULL);
-        REENABLE_WARNING;
+        expect(i3, "%u", user);
+        expect(i3, "%U", uid);
 
         expect(i3, "%m", mid);
         expect(i3, "%b", bid);
         expect(i3, "%H", host);
 
-        expect(i4, "%u", "root");
-        expect(i4, "%U", "0");
+        expect(i4, "%u", user);
+        expect(i4, "%U", uid);
 }
 
 static uint64_t make_cap(int cap) {
@@ -681,6 +672,134 @@ static void test_config_parse_bounding_set(void) {
         assert_se(capability_bounding_set_drop == ~(make_cap(CAP_NET_RAW) | make_cap(CAP_NET_ADMIN)));
 }
 
+static void test_config_parse_rlimit(void) {
+        struct rlimit * rl[_RLIMIT_MAX] = {};
+
+        assert_se(config_parse_limit(NULL, "fake", 1, "section", 1, "LimitNOFILE", RLIMIT_NOFILE, "55", rl, NULL) >= 0);
+        assert_se(rl[RLIMIT_NOFILE]);
+        assert_se(rl[RLIMIT_NOFILE]->rlim_cur == 55);
+        assert_se(rl[RLIMIT_NOFILE]->rlim_cur == rl[RLIMIT_NOFILE]->rlim_max);
+
+        assert_se(config_parse_limit(NULL, "fake", 1, "section", 1, "LimitNOFILE", RLIMIT_NOFILE, "55:66", rl, NULL) >= 0);
+        assert_se(rl[RLIMIT_NOFILE]);
+        assert_se(rl[RLIMIT_NOFILE]->rlim_cur == 55);
+        assert_se(rl[RLIMIT_NOFILE]->rlim_max == 66);
+
+        assert_se(config_parse_limit(NULL, "fake", 1, "section", 1, "LimitNOFILE", RLIMIT_NOFILE, "infinity", rl, NULL) >= 0);
+        assert_se(rl[RLIMIT_NOFILE]);
+        assert_se(rl[RLIMIT_NOFILE]->rlim_cur == RLIM_INFINITY);
+        assert_se(rl[RLIMIT_NOFILE]->rlim_cur == rl[RLIMIT_NOFILE]->rlim_max);
+
+        assert_se(config_parse_limit(NULL, "fake", 1, "section", 1, "LimitNOFILE", RLIMIT_NOFILE, "infinity:infinity", rl, NULL) >= 0);
+        assert_se(rl[RLIMIT_NOFILE]);
+        assert_se(rl[RLIMIT_NOFILE]->rlim_cur == RLIM_INFINITY);
+        assert_se(rl[RLIMIT_NOFILE]->rlim_cur == rl[RLIMIT_NOFILE]->rlim_max);
+
+        rl[RLIMIT_NOFILE] = mfree(rl[RLIMIT_NOFILE]);
+
+        assert_se(config_parse_sec_limit(NULL, "fake", 1, "section", 1, "LimitCPU", RLIMIT_CPU, "56", rl, NULL) >= 0);
+        assert_se(rl[RLIMIT_CPU]);
+        assert_se(rl[RLIMIT_CPU]->rlim_cur == 56);
+        assert_se(rl[RLIMIT_CPU]->rlim_cur == rl[RLIMIT_CPU]->rlim_max);
+
+        assert_se(config_parse_sec_limit(NULL, "fake", 1, "section", 1, "LimitCPU", RLIMIT_CPU, "57s", rl, NULL) >= 0);
+        assert_se(rl[RLIMIT_CPU]);
+        assert_se(rl[RLIMIT_CPU]->rlim_cur == 57);
+        assert_se(rl[RLIMIT_CPU]->rlim_cur == rl[RLIMIT_CPU]->rlim_max);
+
+        assert_se(config_parse_sec_limit(NULL, "fake", 1, "section", 1, "LimitCPU", RLIMIT_CPU, "40s:1m", rl, NULL) >= 0);
+        assert_se(rl[RLIMIT_CPU]);
+        assert_se(rl[RLIMIT_CPU]->rlim_cur == 40);
+        assert_se(rl[RLIMIT_CPU]->rlim_max == 60);
+
+        assert_se(config_parse_sec_limit(NULL, "fake", 1, "section", 1, "LimitCPU", RLIMIT_CPU, "infinity", rl, NULL) >= 0);
+        assert_se(rl[RLIMIT_CPU]);
+        assert_se(rl[RLIMIT_CPU]->rlim_cur == RLIM_INFINITY);
+        assert_se(rl[RLIMIT_CPU]->rlim_cur == rl[RLIMIT_CPU]->rlim_max);
+
+        assert_se(config_parse_sec_limit(NULL, "fake", 1, "section", 1, "LimitCPU", RLIMIT_CPU, "1234ms", rl, NULL) >= 0);
+        assert_se(rl[RLIMIT_CPU]);
+        assert_se(rl[RLIMIT_CPU]->rlim_cur == 2);
+        assert_se(rl[RLIMIT_CPU]->rlim_cur == rl[RLIMIT_CPU]->rlim_max);
+
+        rl[RLIMIT_CPU] = mfree(rl[RLIMIT_CPU]);
+
+        assert_se(config_parse_usec_limit(NULL, "fake", 1, "section", 1, "LimitRTTIME", RLIMIT_RTTIME, "58", rl, NULL) >= 0);
+        assert_se(rl[RLIMIT_RTTIME]);
+        assert_se(rl[RLIMIT_RTTIME]->rlim_cur == 58);
+        assert_se(rl[RLIMIT_RTTIME]->rlim_cur == rl[RLIMIT_RTTIME]->rlim_max);
+
+        assert_se(config_parse_usec_limit(NULL, "fake", 1, "section", 1, "LimitRTTIME", RLIMIT_RTTIME, "58:60", rl, NULL) >= 0);
+        assert_se(rl[RLIMIT_RTTIME]);
+        assert_se(rl[RLIMIT_RTTIME]->rlim_cur == 58);
+        assert_se(rl[RLIMIT_RTTIME]->rlim_max == 60);
+
+        assert_se(config_parse_usec_limit(NULL, "fake", 1, "section", 1, "LimitRTTIME", RLIMIT_RTTIME, "59s", rl, NULL) >= 0);
+        assert_se(rl[RLIMIT_RTTIME]);
+        assert_se(rl[RLIMIT_RTTIME]->rlim_cur == 59 * USEC_PER_SEC);
+        assert_se(rl[RLIMIT_RTTIME]->rlim_cur == rl[RLIMIT_RTTIME]->rlim_max);
+
+        assert_se(config_parse_usec_limit(NULL, "fake", 1, "section", 1, "LimitRTTIME", RLIMIT_RTTIME, "59s:123s", rl, NULL) >= 0);
+        assert_se(rl[RLIMIT_RTTIME]);
+        assert_se(rl[RLIMIT_RTTIME]->rlim_cur == 59 * USEC_PER_SEC);
+        assert_se(rl[RLIMIT_RTTIME]->rlim_max == 123 * USEC_PER_SEC);
+
+        assert_se(config_parse_usec_limit(NULL, "fake", 1, "section", 1, "LimitRTTIME", RLIMIT_RTTIME, "infinity", rl, NULL) >= 0);
+        assert_se(rl[RLIMIT_RTTIME]);
+        assert_se(rl[RLIMIT_RTTIME]->rlim_cur == RLIM_INFINITY);
+        assert_se(rl[RLIMIT_RTTIME]->rlim_cur == rl[RLIMIT_RTTIME]->rlim_max);
+
+        assert_se(config_parse_usec_limit(NULL, "fake", 1, "section", 1, "LimitRTTIME", RLIMIT_RTTIME, "infinity:infinity", rl, NULL) >= 0);
+        assert_se(rl[RLIMIT_RTTIME]);
+        assert_se(rl[RLIMIT_RTTIME]->rlim_cur == RLIM_INFINITY);
+        assert_se(rl[RLIMIT_RTTIME]->rlim_cur == rl[RLIMIT_RTTIME]->rlim_max);
+
+        assert_se(config_parse_usec_limit(NULL, "fake", 1, "section", 1, "LimitRTTIME", RLIMIT_RTTIME, "2345ms", rl, NULL) >= 0);
+        assert_se(rl[RLIMIT_RTTIME]);
+        assert_se(rl[RLIMIT_RTTIME]->rlim_cur == 2345 * USEC_PER_MSEC);
+        assert_se(rl[RLIMIT_RTTIME]->rlim_cur == rl[RLIMIT_RTTIME]->rlim_max);
+
+        rl[RLIMIT_RTTIME] = mfree(rl[RLIMIT_RTTIME]);
+}
+
+static void test_config_parse_pass_environ(void) {
+        /* int config_parse_pass_environ(
+                 const char *unit,
+                 const char *filename,
+                 unsigned line,
+                 const char *section,
+                 unsigned section_line,
+                 const char *lvalue,
+                 int ltype,
+                 const char *rvalue,
+                 void *data,
+                 void *userdata) */
+        int r;
+        _cleanup_strv_free_ char **passenv = NULL;
+
+        r = config_parse_pass_environ(NULL, "fake", 1, "section", 1,
+                              "PassEnvironment", 0, "A B",
+                              &passenv, NULL);
+        assert_se(r >= 0);
+        assert_se(strv_length(passenv) == 2);
+        assert_se(streq(passenv[0], "A"));
+        assert_se(streq(passenv[1], "B"));
+
+        r = config_parse_pass_environ(NULL, "fake", 1, "section", 1,
+                              "PassEnvironment", 0, "",
+                              &passenv, NULL);
+        assert_se(r >= 0);
+        assert_se(strv_isempty(passenv));
+
+        r = config_parse_pass_environ(NULL, "fake", 1, "section", 1,
+                              "PassEnvironment", 0, "'invalid name' 'normal_name' A=1 \\",
+                              &passenv, NULL);
+        assert_se(r >= 0);
+        assert_se(strv_length(passenv) == 1);
+        assert_se(streq(passenv[0], "normal_name"));
+
+}
+
 int main(int argc, char *argv[]) {
         int r;
 
@@ -690,6 +809,8 @@ int main(int argc, char *argv[]) {
         r = test_unit_file_get_set();
         test_config_parse_exec();
         test_config_parse_bounding_set();
+        test_config_parse_rlimit();
+        test_config_parse_pass_environ();
         test_load_env_file_1();
         test_load_env_file_2();
         test_load_env_file_3();