]> git.ipfire.org Git - thirdparty/systemd.git/blobdiff - src/test/test-process-util.c
tree-wide: use -EBADF for fd initialization
[thirdparty/systemd.git] / src / test / test-process-util.c
index cc0f870e5720355cef581f411a04cede1a7aa019..1864f8a750b6d43437072c60a9404344fa59daea 100644 (file)
 #include "terminal-util.h"
 #include "tests.h"
 #include "user-util.h"
-#include "util.h"
 #include "virt.h"
 
-static void test_get_process_comm(pid_t pid) {
+static void test_get_process_comm_one(pid_t pid) {
         struct stat st;
         _cleanup_free_ char *a = NULL, *c = NULL, *d = NULL, *f = NULL, *i = NULL;
         _cleanup_free_ char *env = NULL;
@@ -98,6 +97,18 @@ static void test_get_process_comm(pid_t pid) {
         log_info("PID"PID_FMT" $PATH: '%s'", pid, strna(i));
 }
 
+TEST(get_process_comm) {
+        if (saved_argc > 1) {
+                pid_t pid = 0;
+
+                (void) parse_pid(saved_argv[1], &pid);
+                test_get_process_comm_one(pid);
+        } else {
+                TEST_REQ_RUNNING_SYSTEMD(test_get_process_comm_one(1));
+                test_get_process_comm_one(getpid());
+        }
+}
+
 static void test_get_process_cmdline_one(pid_t pid) {
         _cleanup_free_ char *c = NULL, *d = NULL, *e = NULL, *f = NULL, *g = NULL, *h = NULL;
         int r;
@@ -121,11 +132,8 @@ static void test_get_process_cmdline_one(pid_t pid) {
         log_info("      %s", r >= 0 ? h : errno_to_name(r));
 }
 
-static void test_get_process_cmdline(void) {
+TEST(get_process_cmdline) {
         _cleanup_closedir_ DIR *d = NULL;
-        struct dirent *de;
-
-        log_info("/* %s */", __func__);
 
         assert_se(d = opendir("/proc"));
 
@@ -155,11 +163,9 @@ static void test_get_process_comm_escape_one(const char *input, const char *outp
         assert_se(streq_ptr(n, output));
 }
 
-static void test_get_process_comm_escape(void) {
+TEST(get_process_comm_escape) {
         _cleanup_free_ char *saved = NULL;
 
-        log_info("/* %s */", __func__);
-
         assert_se(get_process_comm(0, &saved) >= 0);
 
         test_get_process_comm_escape_one("", "");
@@ -176,7 +182,7 @@ static void test_get_process_comm_escape(void) {
         assert_se(prctl(PR_SET_NAME, saved) >= 0);
 }
 
-static void test_pid_is_unwaited(void) {
+TEST(pid_is_unwaited) {
         pid_t pid;
 
         pid = fork();
@@ -193,11 +199,9 @@ static void test_pid_is_unwaited(void) {
         assert_se(!pid_is_unwaited(-1));
 }
 
-static void test_pid_is_alive(void) {
+TEST(pid_is_alive) {
         pid_t pid;
 
-        log_info("/* %s */", __func__);
-
         pid = fork();
         assert_se(pid >= 0);
         if (pid == 0) {
@@ -212,9 +216,7 @@ static void test_pid_is_alive(void) {
         assert_se(!pid_is_alive(-1));
 }
 
-static void test_personality(void) {
-        log_info("/* %s */", __func__);
-
+TEST(personality) {
         assert_se(personality_to_string(PER_LINUX));
         assert_se(!personality_to_string(PERSONALITY_INVALID));
 
@@ -236,14 +238,12 @@ static void test_personality(void) {
 #endif
 }
 
-static void test_get_process_cmdline_harder(void) {
+TEST(get_process_cmdline_harder) {
         char path[] = "/tmp/test-cmdlineXXXXXX";
-        _cleanup_close_ int fd = -1;
+        _cleanup_close_ int fd = -EBADF;
         _cleanup_free_ char *line = NULL;
         pid_t pid;
 
-        log_info("/* %s */", __func__);
-
         if (geteuid() != 0) {
                 log_info("Skipping %s: not root", __func__);
                 return;
@@ -482,8 +482,8 @@ static void test_get_process_cmdline_harder(void) {
         /* Test with multiple arguments that do require quoting */
 
 #define CMDLINE1 "foo\0'bar'\0\"bar$\"\0x y z\0!``\0"
-#define EXPECT1  "foo \"'bar'\" \"\\\"bar\\$\\\"\" \"x y z\" \"!\\`\\`\" \"\""
-#define EXPECT1p  "foo $'\\'bar\\'' $'\"bar$\"' $'x y z' $'!``' \"\""
+#define EXPECT1  "foo \"'bar'\" \"\\\"bar\\$\\\"\" \"x y z\" \"!\\`\\`\""
+#define EXPECT1p  "foo $'\\'bar\\'' $'\"bar$\"' $'x y z' $'!``'"
         assert_se(lseek(fd, SEEK_SET, 0) == 0);
         assert_se(write(fd, CMDLINE1, sizeof CMDLINE1) == sizeof CMDLINE1);
         assert_se(ftruncate(fd, sizeof CMDLINE1) == 0);
@@ -501,8 +501,8 @@ static void test_get_process_cmdline_harder(void) {
         line = mfree(line);
 
 #define CMDLINE2 "foo\0\1\2\3\0\0"
-#define EXPECT2  "foo \"\\001\\002\\003\" \"\" \"\""
-#define EXPECT2p  "foo $'\\001\\002\\003' \"\" \"\""
+#define EXPECT2  "foo \"\\001\\002\\003\""
+#define EXPECT2p  "foo $'\\001\\002\\003'"
         assert_se(lseek(fd, SEEK_SET, 0) == 0);
         assert_se(write(fd, CMDLINE2, sizeof CMDLINE2) == sizeof CMDLINE2);
         assert_se(ftruncate(fd, sizeof CMDLINE2) == 0);
@@ -523,114 +523,10 @@ static void test_get_process_cmdline_harder(void) {
         _exit(EXIT_SUCCESS);
 }
 
-static void test_rename_process_now(const char *p, int ret) {
-        _cleanup_free_ char *comm = NULL, *cmdline = NULL;
-        int r;
-
-        log_info("/* %s */", __func__);
-
-        r = rename_process(p);
-        assert_se(r == ret ||
-                  (ret == 0 && r >= 0) ||
-                  (ret > 0 && r > 0));
-
-        log_debug_errno(r, "rename_process(%s): %m", p);
-
-        if (r < 0)
-                return;
-
-#if HAVE_VALGRIND_VALGRIND_H
-        /* see above, valgrind is weird, we can't verify what we are doing here */
-        if (RUNNING_ON_VALGRIND)
-                return;
-#endif
-
-        assert_se(get_process_comm(0, &comm) >= 0);
-        log_debug("comm = <%s>", comm);
-        assert_se(strneq(comm, p, TASK_COMM_LEN-1));
-        /* We expect comm to be at most 16 bytes (TASK_COMM_LEN). The kernel may raise this limit in the
-         * future. We'd only check the initial part, at least until we recompile, but this will still pass. */
-
-        r = get_process_cmdline(0, SIZE_MAX, 0, &cmdline);
-        assert_se(r >= 0);
-        /* we cannot expect cmdline to be renamed properly without privileges */
-        if (geteuid() == 0) {
-                if (r == 0 && detect_container() > 0)
-                        log_info("cmdline = <%s> (not verified, Running in unprivileged container?)", cmdline);
-                else {
-                        log_info("cmdline = <%s> (expected <%.*s>)", cmdline, (int) strlen("test-process-util"), p);
-
-                        bool skip = cmdline[0] == '"'; /* A shortcut to check if the string is quoted */
-
-                        assert_se(strneq(cmdline + skip, p, strlen("test-process-util")));
-                        assert_se(startswith(cmdline + skip, p));
-                }
-        } else
-                log_info("cmdline = <%s> (not verified)", cmdline);
-}
-
-static void test_rename_process_one(const char *p, int ret) {
-        siginfo_t si;
-        pid_t pid;
-
-        log_info("/* %s */", __func__);
-
-        pid = fork();
-        assert_se(pid >= 0);
-
-        if (pid == 0) {
-                /* child */
-                test_rename_process_now(p, ret);
-                _exit(EXIT_SUCCESS);
-        }
-
-        assert_se(wait_for_terminate(pid, &si) >= 0);
-        assert_se(si.si_code == CLD_EXITED);
-        assert_se(si.si_status == EXIT_SUCCESS);
-}
-
-static void test_rename_process_multi(void) {
-        pid_t pid;
-
-        pid = fork();
-        assert_se(pid >= 0);
-
-        if (pid > 0) {
-                siginfo_t si;
-
-                assert_se(wait_for_terminate(pid, &si) >= 0);
-                assert_se(si.si_code == CLD_EXITED);
-                assert_se(si.si_status == EXIT_SUCCESS);
-
-                return;
-        }
-
-        /* child */
-        test_rename_process_now("one", 1);
-        test_rename_process_now("more", 0); /* longer than "one", hence truncated */
-        (void) setresuid(99, 99, 99); /* change uid when running privileged */
-        test_rename_process_now("time!", 0);
-        test_rename_process_now("0", 1); /* shorter than "one", should fit */
-        test_rename_process_one("", -EINVAL);
-        test_rename_process_one(NULL, -EINVAL);
-        _exit(EXIT_SUCCESS);
-}
-
-static void test_rename_process(void) {
-        test_rename_process_one(NULL, -EINVAL);
-        test_rename_process_one("", -EINVAL);
-        test_rename_process_one("foo", 1); /* should always fit */
-        test_rename_process_one("this is a really really long process name, followed by some more words", 0); /* unlikely to fit */
-        test_rename_process_one("1234567", 1); /* should always fit */
-        test_rename_process_multi(); /* multiple invocations and dropped privileges */
-}
-
-static void test_getpid_cached(void) {
+TEST(getpid_cached) {
         siginfo_t si;
         pid_t a, b, c, d, e, f, child;
 
-        log_info("/* %s */", __func__);
-
         a = raw_getpid();
         b = getpid_cached();
         c = getpid();
@@ -661,7 +557,7 @@ static void test_getpid_cached(void) {
         assert_se(si.si_code == CLD_EXITED);
 }
 
-static void test_getpid_measure(void) {
+TEST(getpid_measure) {
         usec_t t, q;
 
         unsigned long long iterations = slow_tests_enabled() ? 1000000 : 1000;
@@ -685,13 +581,11 @@ static void test_getpid_measure(void) {
         log_info("getpid_cached(): %lf µs each\n", (double) q / iterations);
 }
 
-static void test_safe_fork(void) {
+TEST(safe_fork) {
         siginfo_t status;
         pid_t pid;
         int r;
 
-        log_info("/* %s */", __func__);
-
         BLOCK_SIGNALS(SIGCHLD);
 
         r = safe_fork("(test-child)", FORK_RESET_SIGNALS|FORK_CLOSE_ALL_FDS|FORK_DEATHSIG|FORK_NULL_STDIO|FORK_REOPEN_LOG, &pid);
@@ -709,8 +603,7 @@ static void test_safe_fork(void) {
         assert_se(status.si_status == 88);
 }
 
-static void test_pid_to_ptr(void) {
-
+TEST(pid_to_ptr) {
         assert_se(PTR_TO_PID(NULL) == 0);
         assert_se(PID_TO_PTR(0) == NULL);
 
@@ -745,9 +638,7 @@ static void test_ioprio_class_from_to_string_one(const char *val, int expected,
         }
 }
 
-static void test_ioprio_class_from_to_string(void) {
-        log_info("/* %s */", __func__);
-
+TEST(ioprio_class_from_to_string) {
         test_ioprio_class_from_to_string_one("none", IOPRIO_CLASS_NONE, IOPRIO_CLASS_BE);
         test_ioprio_class_from_to_string_one("realtime", IOPRIO_CLASS_RT, IOPRIO_CLASS_RT);
         test_ioprio_class_from_to_string_one("best-effort", IOPRIO_CLASS_BE, IOPRIO_CLASS_BE);
@@ -760,11 +651,9 @@ static void test_ioprio_class_from_to_string(void) {
         test_ioprio_class_from_to_string_one("-1", -EINVAL, -EINVAL);
 }
 
-static void test_setpriority_closest(void) {
+TEST(setpriority_closest) {
         int r;
 
-        log_info("/* %s */", __func__);
-
         r = safe_fork("(test-setprio)",
                       FORK_RESET_SIGNALS|FORK_CLOSE_ALL_FDS|FORK_DEATHSIG|FORK_WAIT|FORK_LOG, NULL);
         assert_se(r >= 0);
@@ -849,12 +738,10 @@ static void test_setpriority_closest(void) {
         }
 }
 
-static void test_get_process_ppid(void) {
+TEST(get_process_ppid) {
         uint64_t limit;
         int r;
 
-        log_info("/* %s */", __func__);
-
         assert_se(get_process_ppid(1, NULL) == -EADDRNOTAVAIL);
 
         /* the process with the PID above the global limit definitely doesn't exist. Verify that */
@@ -888,7 +775,7 @@ static void test_get_process_ppid(void) {
         }
 }
 
-static void test_set_oom_score_adjust(void) {
+TEST(set_oom_score_adjust) {
         int a, b, r;
 
         assert_se(get_oom_score_adjust(&a) >= 0);
@@ -906,37 +793,9 @@ static void test_set_oom_score_adjust(void) {
         assert_se(b == a);
 }
 
-int main(int argc, char *argv[]) {
+static int intro(void) {
         log_show_color(true);
-        test_setup_logging(LOG_INFO);
-
-        save_argc_argv(argc, argv);
-
-        if (argc > 1) {
-                pid_t pid = 0;
-
-                (void) parse_pid(argv[1], &pid);
-                test_get_process_comm(pid);
-        } else {
-                TEST_REQ_RUNNING_SYSTEMD(test_get_process_comm(1));
-                test_get_process_comm(getpid());
-        }
-
-        test_get_process_comm_escape();
-        test_get_process_cmdline();
-        test_pid_is_unwaited();
-        test_pid_is_alive();
-        test_personality();
-        test_get_process_cmdline_harder();
-        test_rename_process();
-        test_getpid_cached();
-        test_getpid_measure();
-        test_safe_fork();
-        test_pid_to_ptr();
-        test_ioprio_class_from_to_string();
-        test_setpriority_closest();
-        test_get_process_ppid();
-        test_set_oom_score_adjust();
-
-        return 0;
+        return EXIT_SUCCESS;
 }
+
+DEFINE_TEST_MAIN_WITH_INTRO(LOG_INFO, intro);