mirror of
https://github.com/systemd/systemd
synced 2024-07-21 02:05:05 +00:00
test-login: make the test non-manual
test-login.c is largely rewritten to use _cleanup_ and give more meaningful messages (function names are used instead of creative terms like "active session", so that when something unexpected is returned, it's much easier to see what function is responsible). The monitoring part is only activated if '-m' is passed on the command line. It runs against the information from /run/systemd/ in the live system, but that should be OK: logind/sd-login interface is supposed to be stable and both backwards and forwards compatible. If not running in a login session, some tests are skipped. Those two changes together mean that it's possible to run test-login in the test suite. Tests for sd_pid_get_{unit,user_unit,slice} are added.
This commit is contained in:
parent
d440fb97ba
commit
ce737f46cd
|
@ -6096,10 +6096,10 @@ test_login_tables_LDADD = \
|
|||
liblogind-core.la
|
||||
|
||||
manual_tests += \
|
||||
test-login \
|
||||
test-inhibit
|
||||
|
||||
tests += \
|
||||
test-login \
|
||||
test-login-tables \
|
||||
test-login-shared
|
||||
|
||||
|
|
|
@ -177,7 +177,7 @@
|
|||
processes, user processes that are shared between multiple
|
||||
sessions of the same user, or kernel threads). For processes not
|
||||
being part of a login session, this function will fail with
|
||||
-ENODATA. The returned string needs to be freed with the libc
|
||||
<constant>-ENODATA</constant>. The returned string needs to be freed with the libc
|
||||
<citerefentry
|
||||
project='man-pages'><refentrytitle>free</refentrytitle><manvolnum>3</manvolnum></citerefentry>
|
||||
call after use.</para>
|
||||
|
@ -189,7 +189,7 @@
|
|||
paths. Note that not all processes are part of a system
|
||||
unit/service (e.g. user processes, or kernel threads). For
|
||||
processes not being part of a systemd system unit, this function
|
||||
will fail with -ENODATA. (More specifically, this call will not
|
||||
will fail with <constant>-ENODATA</constant>. (More specifically, this call will not
|
||||
work for kernel threads.) The returned string needs to be freed
|
||||
with the libc <citerefentry
|
||||
project='man-pages'><refentrytitle>free</refentrytitle><manvolnum>3</manvolnum></citerefentry>
|
||||
|
@ -208,7 +208,7 @@
|
|||
multiple login sessions of the same user, whereas
|
||||
<function>sd_pid_get_session()</function> will fail. For processes
|
||||
not being part of a login session and not being a shared process
|
||||
of a user, this function will fail with -ENODATA.</para>
|
||||
of a user, this function will fail with <constant>-ENODATA</constant>.</para>
|
||||
|
||||
<para><function>sd_pid_get_machine_name()</function> may be used
|
||||
to determine the name of the VM or container is a member of. The
|
||||
|
@ -217,7 +217,7 @@
|
|||
<citerefentry
|
||||
project='man-pages'><refentrytitle>free</refentrytitle><manvolnum>3</manvolnum></citerefentry>
|
||||
call after use. For processes not part of a VM or containers, this
|
||||
function fails with -ENODATA.</para>
|
||||
function fails with <constant>-ENODATA</constant>.</para>
|
||||
|
||||
<para><function>sd_pid_get_slice()</function> may be used to
|
||||
determine the slice unit the process is a member of. See
|
||||
|
|
|
@ -184,8 +184,9 @@
|
|||
<para><function>sd_session_get_seat()</function> may be used to
|
||||
determine the seat identifier of the seat the session identified
|
||||
by the specified session identifier belongs to. Note that not all
|
||||
sessions are attached to a seat, this call will fail for them. The
|
||||
returned string needs to be freed with the libc
|
||||
sessions are attached to a seat, this call will fail (returning
|
||||
<constant>-ENODATA</constant>) for them. The returned string needs
|
||||
to be freed with the libc
|
||||
<citerefentry project='man-pages'><refentrytitle>free</refentrytitle><manvolnum>3</manvolnum></citerefentry>
|
||||
call after use.</para>
|
||||
|
||||
|
|
|
@ -25,173 +25,197 @@
|
|||
#include "alloc-util.h"
|
||||
#include "fd-util.h"
|
||||
#include "format-util.h"
|
||||
#include "log.h"
|
||||
#include "string-util.h"
|
||||
#include "strv.h"
|
||||
#include "util.h"
|
||||
|
||||
static char* format_uids(char **buf, uid_t* uids, int count) {
|
||||
int pos = 0, k, inc;
|
||||
size_t size = (DECIMAL_STR_MAX(uid_t) + 1) * count + 1;
|
||||
|
||||
assert_se(*buf = malloc(size));
|
||||
|
||||
for (k = 0; k < count; k++) {
|
||||
sprintf(*buf + pos, "%s"UID_FMT"%n", k > 0 ? " " : "", uids[k], &inc);
|
||||
pos += inc;
|
||||
}
|
||||
|
||||
assert_se(pos < size);
|
||||
(*buf)[pos] = '\0';
|
||||
|
||||
return *buf;
|
||||
}
|
||||
|
||||
static void test_login(void) {
|
||||
_cleanup_close_pair_ int pair[2] = { -1, -1 };
|
||||
_cleanup_free_ char *pp = NULL, *qq = NULL;
|
||||
_cleanup_free_ char *pp = NULL, *qq = NULL,
|
||||
*display_session = NULL, *cgroup = NULL,
|
||||
*display = NULL, *remote_user = NULL, *remote_host = NULL,
|
||||
*type = NULL, *class = NULL, *state = NULL, *state2 = NULL,
|
||||
*seat = NULL, *session = NULL,
|
||||
*unit = NULL, *user_unit = NULL, *slice = NULL;
|
||||
int r, k;
|
||||
uid_t u, u2;
|
||||
char *seat, *type, *class, *display, *remote_user, *remote_host, *display_session, *cgroup;
|
||||
char *session;
|
||||
char *state;
|
||||
char *session2;
|
||||
char *t;
|
||||
char **seats, **sessions, **machines;
|
||||
uid_t *uids;
|
||||
unsigned n;
|
||||
struct pollfd pollfd;
|
||||
sd_login_monitor *m = NULL;
|
||||
char *t, **seats, **sessions;
|
||||
|
||||
assert_se(sd_pid_get_session(0, &session) == 0);
|
||||
printf("session = %s\n", session);
|
||||
assert_se(sd_pid_get_unit(0, &unit) >= 0);
|
||||
log_info("sd_pid_get_unit(0, …) → \"%s\"", unit);
|
||||
|
||||
assert_se(sd_pid_get_owner_uid(0, &u2) == 0);
|
||||
printf("user = "UID_FMT"\n", u2);
|
||||
|
||||
assert_se(sd_pid_get_cgroup(0, &cgroup) == 0);
|
||||
printf("cgroup = %s\n", cgroup);
|
||||
free(cgroup);
|
||||
|
||||
display_session = NULL;
|
||||
r = sd_uid_get_display(u2, &display_session);
|
||||
r = sd_pid_get_user_unit(0, &user_unit);
|
||||
assert_se(r >= 0 || r == -ENODATA);
|
||||
printf("user's display session = %s\n", strna(display_session));
|
||||
free(display_session);
|
||||
log_info("sd_pid_get_user_unit(0, …) → \"%s\"", user_unit);
|
||||
|
||||
assert_se(socketpair(AF_UNIX, SOCK_STREAM, 0, pair) == 0);
|
||||
sd_peer_get_session(pair[0], &pp);
|
||||
sd_peer_get_session(pair[1], &qq);
|
||||
assert_se(streq_ptr(pp, qq));
|
||||
assert_se(sd_pid_get_slice(0, &slice) >= 0);
|
||||
log_info("sd_pid_get_slice(0, …) → \"%s\"", slice);
|
||||
|
||||
r = sd_uid_get_sessions(u2, false, &sessions);
|
||||
assert_se(r >= 0);
|
||||
assert_se(r == (int) strv_length(sessions));
|
||||
assert_se(t = strv_join(sessions, ", "));
|
||||
strv_free(sessions);
|
||||
printf("sessions = %s\n", t);
|
||||
free(t);
|
||||
r = sd_pid_get_session(0, &session);
|
||||
if (r < 0) {
|
||||
log_warning_errno(r, "sd_pid_get_session(0, …): %m");
|
||||
if (r == -ENODATA)
|
||||
log_info("Seems we are not running in a session, skipping some tests.");
|
||||
} else {
|
||||
log_info("sd_pid_get_session(0, …) → \"%s\"", session);
|
||||
|
||||
assert_se(r == sd_uid_get_sessions(u2, false, NULL));
|
||||
assert_se(sd_pid_get_owner_uid(0, &u2) == 0);
|
||||
log_info("sd_pid_get_owner_uid(0, …) → "UID_FMT, u2);
|
||||
|
||||
r = sd_uid_get_seats(u2, false, &seats);
|
||||
assert_se(r >= 0);
|
||||
assert_se(r == (int) strv_length(seats));
|
||||
assert_se(t = strv_join(seats, ", "));
|
||||
strv_free(seats);
|
||||
printf("seats = %s\n", t);
|
||||
free(t);
|
||||
assert_se(sd_pid_get_cgroup(0, &cgroup) == 0);
|
||||
log_info("sd_pid_get_cgroup(0, …) → \"%s\"", cgroup);
|
||||
|
||||
assert_se(r == sd_uid_get_seats(u2, false, NULL));
|
||||
r = sd_uid_get_display(u2, &display_session);
|
||||
assert_se(r >= 0 || r == -ENODATA);
|
||||
log_info("sd_uid_get_display("UID_FMT", …) → \"%s\"",
|
||||
u2, strnull(display_session));
|
||||
|
||||
r = sd_session_is_active(session);
|
||||
assert_se(r >= 0);
|
||||
printf("active = %s\n", yes_no(r));
|
||||
assert_se(socketpair(AF_UNIX, SOCK_STREAM, 0, pair) == 0);
|
||||
sd_peer_get_session(pair[0], &pp);
|
||||
sd_peer_get_session(pair[1], &qq);
|
||||
assert_se(streq_ptr(pp, qq));
|
||||
|
||||
r = sd_session_is_remote(session);
|
||||
assert_se(r >= 0);
|
||||
printf("remote = %s\n", yes_no(r));
|
||||
r = sd_uid_get_sessions(u2, false, &sessions);
|
||||
assert_se(r >= 0);
|
||||
assert_se(r == (int) strv_length(sessions));
|
||||
assert_se(t = strv_join(sessions, " "));
|
||||
strv_free(sessions);
|
||||
log_info("sd_uid_get_sessions("UID_FMT", …) → [%i] \"%s\"", u2, r, t);
|
||||
free(t);
|
||||
|
||||
r = sd_session_get_state(session, &state);
|
||||
assert_se(r >= 0);
|
||||
printf("state = %s\n", state);
|
||||
free(state);
|
||||
assert_se(r == sd_uid_get_sessions(u2, false, NULL));
|
||||
|
||||
assert_se(sd_session_get_uid(session, &u) >= 0);
|
||||
printf("uid = "UID_FMT"\n", u);
|
||||
assert_se(u == u2);
|
||||
r = sd_uid_get_seats(u2, false, &seats);
|
||||
assert_se(r >= 0);
|
||||
assert_se(r == (int) strv_length(seats));
|
||||
assert_se(t = strv_join(seats, " "));
|
||||
strv_free(seats);
|
||||
log_info("sd_uid_get_seats("UID_FMT", …) → [%i] \"%s\"", u2, r, t);
|
||||
free(t);
|
||||
|
||||
assert_se(sd_session_get_type(session, &type) >= 0);
|
||||
printf("type = %s\n", type);
|
||||
free(type);
|
||||
assert_se(r == sd_uid_get_seats(u2, false, NULL));
|
||||
}
|
||||
|
||||
assert_se(sd_session_get_class(session, &class) >= 0);
|
||||
printf("class = %s\n", class);
|
||||
free(class);
|
||||
if (session) {
|
||||
r = sd_session_is_active(session);
|
||||
assert_se(r >= 0);
|
||||
log_info("sd_session_is_active(\"%s\") → %s", session, yes_no(r));
|
||||
|
||||
display = NULL;
|
||||
r = sd_session_get_display(session, &display);
|
||||
assert_se(r >= 0 || r == -ENODATA);
|
||||
printf("display = %s\n", strna(display));
|
||||
free(display);
|
||||
r = sd_session_is_remote(session);
|
||||
assert_se(r >= 0);
|
||||
log_info("sd_session_is_remote(\"%s\") → %s", session, yes_no(r));
|
||||
|
||||
remote_user = NULL;
|
||||
r = sd_session_get_remote_user(session, &remote_user);
|
||||
assert_se(r >= 0 || r == -ENODATA);
|
||||
printf("remote_user = %s\n", strna(remote_user));
|
||||
free(remote_user);
|
||||
r = sd_session_get_state(session, &state);
|
||||
assert_se(r >= 0);
|
||||
log_info("sd_session_get_state(\"%s\") → \"%s\"", session, state);
|
||||
|
||||
remote_host = NULL;
|
||||
r = sd_session_get_remote_host(session, &remote_host);
|
||||
assert_se(r >= 0 || r == -ENODATA);
|
||||
printf("remote_host = %s\n", strna(remote_host));
|
||||
free(remote_host);
|
||||
assert_se(sd_session_get_uid(session, &u) >= 0);
|
||||
log_info("sd_session_get_uid(\"%s\") → "UID_FMT, session, u);
|
||||
assert_se(u == u2);
|
||||
|
||||
assert_se(sd_session_get_seat(session, &seat) >= 0);
|
||||
printf("seat = %s\n", seat);
|
||||
assert_se(sd_session_get_type(session, &type) >= 0);
|
||||
log_info("sd_session_get_type(\"%s\") → \"%s\"", session, type);
|
||||
|
||||
r = sd_seat_can_multi_session(seat);
|
||||
assert_se(r >= 0);
|
||||
printf("can do multi session = %s\n", yes_no(r));
|
||||
assert_se(sd_session_get_class(session, &class) >= 0);
|
||||
log_info("sd_session_get_class(\"%s\") → \"%s\"", session, class);
|
||||
|
||||
r = sd_seat_can_tty(seat);
|
||||
assert_se(r >= 0);
|
||||
printf("can do tty = %s\n", yes_no(r));
|
||||
r = sd_session_get_display(session, &display);
|
||||
assert_se(r >= 0 || r == -ENODATA);
|
||||
log_info("sd_session_get_display(\"%s\") → \"%s\"", session, strna(display));
|
||||
|
||||
r = sd_seat_can_graphical(seat);
|
||||
assert_se(r >= 0);
|
||||
printf("can do graphical = %s\n", yes_no(r));
|
||||
r = sd_session_get_remote_user(session, &remote_user);
|
||||
assert_se(r >= 0 || r == -ENODATA);
|
||||
log_info("sd_session_get_remote_user(\"%s\") → \"%s\"",
|
||||
session, strna(remote_user));
|
||||
|
||||
assert_se(sd_uid_get_state(u, &state) >= 0);
|
||||
printf("state = %s\n", state);
|
||||
r = sd_session_get_remote_host(session, &remote_host);
|
||||
assert_se(r >= 0 || r == -ENODATA);
|
||||
log_info("sd_session_get_remote_host(\"%s\") → \"%s\"",
|
||||
session, strna(remote_host));
|
||||
|
||||
assert_se(sd_uid_is_on_seat(u, 0, seat) > 0);
|
||||
r = sd_session_get_seat(session, &seat);
|
||||
if (r >= 0) {
|
||||
assert_se(seat);
|
||||
|
||||
k = sd_uid_is_on_seat(u, 1, seat);
|
||||
assert_se(k >= 0);
|
||||
assert_se(!!r == !!r);
|
||||
log_info("sd_session_get_display(\"%s\") → \"%s\"", session, seat);
|
||||
|
||||
assert_se(sd_seat_get_active(seat, &session2, &u2) >= 0);
|
||||
printf("session2 = %s\n", session2);
|
||||
printf("uid2 = "UID_FMT"\n", u2);
|
||||
r = sd_seat_can_multi_session(seat);
|
||||
assert_se(r >= 0);
|
||||
log_info("sd_session_can_multi_seat(\"%s\") → %s", seat, yes_no(r));
|
||||
|
||||
r = sd_seat_get_sessions(seat, &sessions, &uids, &n);
|
||||
assert_se(r >= 0);
|
||||
printf("n_sessions = %i\n", r);
|
||||
assert_se(r == (int) strv_length(sessions));
|
||||
assert_se(t = strv_join(sessions, ", "));
|
||||
strv_free(sessions);
|
||||
printf("sessions = %s\n", t);
|
||||
free(t);
|
||||
printf("uids =");
|
||||
for (k = 0; k < (int) n; k++)
|
||||
printf(" "UID_FMT, uids[k]);
|
||||
printf("\n");
|
||||
free(uids);
|
||||
r = sd_seat_can_tty(seat);
|
||||
assert_se(r >= 0);
|
||||
log_info("sd_session_can_tty(\"%s\") → %s", seat, yes_no(r));
|
||||
|
||||
assert_se(sd_seat_get_sessions(seat, NULL, NULL, NULL) == r);
|
||||
r = sd_seat_can_graphical(seat);
|
||||
assert_se(r >= 0);
|
||||
log_info("sd_session_can_graphical(\"%s\") → %s", seat, yes_no(r));
|
||||
} else {
|
||||
log_info_errno(r, "sd_session_get_display(\"%s\"): %m", session);
|
||||
assert_se(r == -ENODATA);
|
||||
}
|
||||
|
||||
free(session);
|
||||
free(state);
|
||||
free(session2);
|
||||
free(seat);
|
||||
assert_se(sd_uid_get_state(u, &state2) >= 0);
|
||||
log_info("sd_uid_get_state("UID_FMT", …) → %s", u, state2);
|
||||
}
|
||||
|
||||
if (seat) {
|
||||
_cleanup_free_ char *session2 = NULL, *buf = NULL;
|
||||
_cleanup_free_ uid_t *uids = NULL;
|
||||
unsigned n;
|
||||
|
||||
assert_se(sd_uid_is_on_seat(u, 0, seat) > 0);
|
||||
|
||||
k = sd_uid_is_on_seat(u, 1, seat);
|
||||
assert_se(k >= 0);
|
||||
assert_se(!!k == !!r);
|
||||
|
||||
assert_se(sd_seat_get_active(seat, &session2, &u2) >= 0);
|
||||
log_info("sd_seat_get_active(\"%s\", …) → \"%s\", "UID_FMT, seat, session2, u2);
|
||||
|
||||
r = sd_seat_get_sessions(seat, &sessions, &uids, &n);
|
||||
assert_se(r >= 0);
|
||||
assert_se(r == (int) strv_length(sessions));
|
||||
assert_se(t = strv_join(sessions, " "));
|
||||
strv_free(sessions);
|
||||
log_info("sd_seat_get_sessions(\"%s\", …) → %i, \"%s\", [%i] {%s}",
|
||||
seat, r, t, n, format_uids(&buf, uids, n));
|
||||
free(t);
|
||||
|
||||
assert_se(sd_seat_get_sessions(seat, NULL, NULL, NULL) == r);
|
||||
}
|
||||
|
||||
r = sd_get_seats(&seats);
|
||||
assert_se(r >= 0);
|
||||
assert_se(r == (int) strv_length(seats));
|
||||
assert_se(t = strv_join(seats, ", "));
|
||||
strv_free(seats);
|
||||
printf("n_seats = %i\n", r);
|
||||
printf("seats = %s\n", t);
|
||||
free(t);
|
||||
log_info("sd_get_seats(…) → [%i] \"%s\"", r, t);
|
||||
t = mfree(t);
|
||||
|
||||
assert_se(sd_get_seats(NULL) == r);
|
||||
|
||||
r = sd_seat_get_active(NULL, &t, NULL);
|
||||
assert_se(r >= 0);
|
||||
printf("active session on current seat = %s\n", t);
|
||||
assert_se(IN_SET(r, 0, -ENODATA));
|
||||
log_info("sd_seat_get_active(NULL, …) (active session on current seat) → %s", strnull(t));
|
||||
free(t);
|
||||
|
||||
r = sd_get_sessions(&sessions);
|
||||
|
@ -199,40 +223,47 @@ static void test_login(void) {
|
|||
assert_se(r == (int) strv_length(sessions));
|
||||
assert_se(t = strv_join(sessions, ", "));
|
||||
strv_free(sessions);
|
||||
printf("n_sessions = %i\n", r);
|
||||
printf("sessions = %s\n", t);
|
||||
log_info("sd_get_sessions(…) → [%i] \"%s\"", r, t);
|
||||
free(t);
|
||||
|
||||
assert_se(sd_get_sessions(NULL) == r);
|
||||
|
||||
r = sd_get_uids(&uids);
|
||||
assert_se(r >= 0);
|
||||
{
|
||||
_cleanup_free_ uid_t *uids = NULL;
|
||||
_cleanup_free_ char *buf = NULL;
|
||||
|
||||
printf("uids =");
|
||||
for (k = 0; k < r; k++)
|
||||
printf(" "UID_FMT, uids[k]);
|
||||
printf("\n");
|
||||
free(uids);
|
||||
r = sd_get_uids(&uids);
|
||||
assert_se(r >= 0);
|
||||
log_info("sd_get_uids(…) → [%i] {%s}", r, format_uids(&buf, uids, r));
|
||||
|
||||
printf("n_uids = %i\n", r);
|
||||
assert_se(sd_get_uids(NULL) == r);
|
||||
assert_se(sd_get_uids(NULL) == r);
|
||||
}
|
||||
|
||||
r = sd_get_machine_names(&machines);
|
||||
assert_se(r >= 0);
|
||||
assert_se(r == (int) strv_length(machines));
|
||||
assert_se(t = strv_join(machines, ", "));
|
||||
strv_free(machines);
|
||||
printf("n_machines = %i\n", r);
|
||||
printf("machines = %s\n", t);
|
||||
free(t);
|
||||
{
|
||||
_cleanup_strv_free_ char **machines = NULL;
|
||||
_cleanup_free_ char *buf = NULL;
|
||||
|
||||
r = sd_get_machine_names(&machines);
|
||||
assert_se(r >= 0);
|
||||
assert_se(r == (int) strv_length(machines));
|
||||
assert_se(buf = strv_join(machines, " "));
|
||||
|
||||
log_info("sd_get_machines(…) → [%i] \"%s\"", r, buf);
|
||||
}
|
||||
}
|
||||
|
||||
static void test_monitor(void) {
|
||||
sd_login_monitor *m = NULL;
|
||||
unsigned n;
|
||||
int r;
|
||||
|
||||
r = sd_login_monitor_new("session", &m);
|
||||
assert_se(r >= 0);
|
||||
|
||||
for (n = 0; n < 5; n++) {
|
||||
struct pollfd pollfd = {};
|
||||
usec_t timeout, nw;
|
||||
|
||||
zero(pollfd);
|
||||
assert_se((pollfd.fd = sd_login_monitor_get_fd(m)) >= 0);
|
||||
assert_se((pollfd.events = sd_login_monitor_get_events(m)) >= 0);
|
||||
|
||||
|
@ -258,7 +289,12 @@ int main(int argc, char* argv[]) {
|
|||
log_parse_environment();
|
||||
log_open();
|
||||
|
||||
log_info("/* Information printed is from the live system */");
|
||||
|
||||
test_login();
|
||||
|
||||
if (streq_ptr(argv[1], "-m"))
|
||||
test_monitor();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -786,8 +786,7 @@ tests += [
|
|||
|
||||
[['src/libsystemd/sd-login/test-login.c'],
|
||||
[],
|
||||
[],
|
||||
'', 'manual'],
|
||||
[]],
|
||||
]
|
||||
|
||||
############################################################
|
||||
|
|
Loading…
Reference in a new issue