]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
test-sd-login: add a "test" that just calls all sd_pid_get_* functions
authorZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>
Tue, 6 May 2025 11:42:27 +0000 (13:42 +0200)
committerYu Watanabe <watanabe.yu+github@gmail.com>
Wed, 7 May 2025 13:02:46 +0000 (22:02 +0900)
As a test, it just increases our code coverage in a fake way.
When run manually, it can be used to conveniently print what logind
thinks about various processes:

$ build/test-sd-login
sd_pid_get_session(0) → No data available
sd_pid_get_unit(0) → user@1000.service
sd_pid_get_user_unit(0) → app-ghostty-transient-5088.scope
sd_pid_get_machine_name(0) → No such file or directory
sd_pid_get_slice(0) → user-1000.slice
sd_pid_get_user_slice(0) → app.slice
sd_pid_get_owner_uid(0) → 1000
sd_pid_get_cgroup(0) → /user.slice/user-1000.slice/user@1000.service/app.slice/app-ghostty-transient-5088.scope/surfaces/556FAF50BA40.scope

$ build/test-sd-login cgroup 1
sd_pid_get_cgroup(1) → /init.scope

src/libsystemd/meson.build
src/libsystemd/sd-login/test-sd-login.c [new file with mode: 0644]

index 000b56880f19d566c01b68f7ad1d08b749ccb7de..9558bfb4ab9f64a2b73fc6446b1a7019681876f6 100644 (file)
@@ -223,6 +223,7 @@ simple_tests += files(
         'sd-journal/test-journal-stream.c',
         'sd-journal/test-journal.c',
         'sd-login/test-login.c',
+        'sd-login/test-sd-login.c',
         'sd-netlink/test-netlink.c',
 )
 
diff --git a/src/libsystemd/sd-login/test-sd-login.c b/src/libsystemd/sd-login/test-sd-login.c
new file mode 100644 (file)
index 0000000..a9026eb
--- /dev/null
@@ -0,0 +1,101 @@
+/* SPDX-License-Identifier: LGPL-2.1-or-later */
+
+#include "sd-login.h"
+
+#include "alloc-util.h"
+#include "main-func.h"
+#include "parse-util.h"
+#include "tests.h"
+
+static const char *arg_verb = NULL;  /* NULL means all */
+static pid_t arg_pid = 0;            /* 0 == self */
+
+static int print_info(void) {
+        const char* const *verbs = arg_verb ?
+                STRV_MAKE_CONST(arg_verb) :
+                STRV_MAKE_CONST("session",
+                                "unit",
+                                "user_unit",
+                                "machine_name",
+                                "slice",
+                                "user_slice",
+                                "owner_uid",
+                                "cgroup");
+        int r = 0;
+
+        STRV_FOREACH(verb, verbs) {
+                _cleanup_free_ char *ans = NULL;
+                int k;
+
+                if (streq(*verb, "session"))
+                        k = sd_pid_get_session(arg_pid, &ans);
+                else if (streq(*verb, "unit"))
+                        k = sd_pid_get_unit(arg_pid, &ans);
+                else if (streq(*verb, "user_unit"))
+                        k = sd_pid_get_user_unit(arg_pid, &ans);
+                else if (streq(*verb, "machine_name"))
+                        k = sd_pid_get_machine_name(arg_pid, &ans);
+                else if (streq(*verb, "slice"))
+                        k = sd_pid_get_slice(arg_pid, &ans);
+                else if (streq(*verb, "user_slice"))
+                        k = sd_pid_get_user_slice(arg_pid, &ans);
+                else if (streq(*verb, "owner_uid")) {
+                        uid_t owner;
+
+                        k = sd_pid_get_owner_uid(arg_pid, &owner);
+                        if (k < 0)
+                                log_info_errno(k, "sd_pid_get_%s("PID_FMT") → %m", *verb, arg_pid);
+                        else
+                                log_info("sd_pid_get_%s("PID_FMT") → "UID_FMT, *verb, arg_pid, owner);
+                        RET_GATHER(r, k);
+                        continue;
+                } else if (streq(*verb, "cgroup"))
+                        k = sd_pid_get_cgroup(arg_pid, &ans);
+                else
+                        return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Unknown verb '%s'.", *verb);
+
+                log_info("sd_pid_get_%s("PID_FMT") → %s",
+                         *verb, arg_pid, k < 0 ? STRERROR(k) : ans);
+                RET_GATHER(r, k);
+        }
+
+        return r;
+}
+
+static int parse_argv(int argc, char *argv[]) {
+        int r;
+
+        if (argc > 3)
+                return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
+                                       "Syntax: test-sd-login [VERB|all [PID]]");
+
+        arg_verb = streq_ptr(argv[1], "all") ? NULL : argv[1];
+
+        if (argc == 3) {
+                r = parse_pid(argv[2], &arg_pid);
+                if (r < 0)
+                        return log_error_errno(r, "Cannot parse PID %s: %m", argv[2]);
+        }
+
+        return 0;
+}
+
+static int run(int argc, char *argv[]) {
+        int r;
+
+        r = parse_argv(argc, argv);
+        if (r < 0)
+                return r;
+
+        r = print_info();
+        if (argc > 1)
+                /* We were called manually… */
+                return r;
+
+        /* This is how we get executed by the test suite.
+         * Do not return the error. */
+        assert_se(IN_SET(r, 0, -ENODATA, -ENOENT));
+        return 0;
+}
+
+DEFINE_MAIN_FUNCTION(run);