From: Zbigniew Jędrzejewski-Szmek Date: Tue, 6 May 2025 11:42:27 +0000 (+0200) Subject: test-sd-login: add a "test" that just calls all sd_pid_get_* functions X-Git-Tag: v258-rc1~673 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=463c301fbb9e9d49434fff19b90a5522767314c6;p=thirdparty%2Fsystemd.git test-sd-login: add a "test" that just calls all sd_pid_get_* functions 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 --- diff --git a/src/libsystemd/meson.build b/src/libsystemd/meson.build index 000b56880f1..9558bfb4ab9 100644 --- a/src/libsystemd/meson.build +++ b/src/libsystemd/meson.build @@ -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 index 00000000000..a9026eb4182 --- /dev/null +++ b/src/libsystemd/sd-login/test-sd-login.c @@ -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);