]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
test-login: make the test non-manual
authorZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>
Fri, 12 May 2017 18:25:17 +0000 (14:25 -0400)
committerZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>
Fri, 19 May 2017 02:11:58 +0000 (22:11 -0400)
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.

Makefile.am
man/sd_pid_get_session.xml
man/sd_session_is_active.xml
src/libsystemd/sd-login/test-login.c
src/test/meson.build

index 771efa4f8e7757b0398f41d908b291ef3c667d76..cd9a683e57e246bb491bf659422beda0dca011aa 100644 (file)
@@ -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
 
index 806cff34e443bf6f1180970ed5f3b315d1b7b8a0..0c135ba871237f29c6df771b9a7f23de222eb1ae 100644 (file)
     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>
     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>
     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
     <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
index a6076b177abac6815d29733c494a8367bc4b3913..f95e74ead63ee9c47b94617b50c92140355876aa 100644 (file)
     <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>
 
index 9de33d85dbd1dce83e167df759601e5be809171a..fb7d4e2ece9f13e26e9051858b03deab2084596c 100644 (file)
 #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);
+        r = sd_pid_get_user_unit(0, &user_unit);
+        assert_se(r >= 0 || r == -ENODATA);
+        log_info("sd_pid_get_user_unit(0, …) → \"%s\"", user_unit);
 
-        assert_se(sd_pid_get_cgroup(0, &cgroup) == 0);
-        printf("cgroup = %s\n", cgroup);
-        free(cgroup);
+        assert_se(sd_pid_get_slice(0, &slice) >= 0);
+        log_info("sd_pid_get_slice(0, …) → \"%s\"", slice);
 
-        display_session = NULL;
-        r = sd_uid_get_display(u2, &display_session);
-        assert_se(r >= 0 || r == -ENODATA);
-        printf("user's display session = %s\n", strna(display_session));
-        free(display_session);
+        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(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_owner_uid(0, &u2) == 0);
+                log_info("sd_pid_get_owner_uid(0, …) → "UID_FMT, u2);
 
-        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);
+                assert_se(sd_pid_get_cgroup(0, &cgroup) == 0);
+                log_info("sd_pid_get_cgroup(0, …) → \"%s\"", cgroup);
 
-        assert_se(r == sd_uid_get_sessions(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_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(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(r == sd_uid_get_seats(u2, false, NULL));
+                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_is_active(session);
-        assert_se(r >= 0);
-        printf("active = %s\n", yes_no(r));
+                assert_se(r == sd_uid_get_sessions(u2, false, NULL));
 
-        r = sd_session_is_remote(session);
-        assert_se(r >= 0);
-        printf("remote = %s\n", yes_no(r));
+                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);
 
-        r = sd_session_get_state(session, &state);
-        assert_se(r >= 0);
-        printf("state = %s\n", state);
-        free(state);
+                assert_se(r == sd_uid_get_seats(u2, false, NULL));
+        }
 
-        assert_se(sd_session_get_uid(session, &u) >= 0);
-        printf("uid = "UID_FMT"\n", u);
-        assert_se(u == u2);
+        if (session) {
+                r = sd_session_is_active(session);
+                assert_se(r >= 0);
+                log_info("sd_session_is_active(\"%s\") → %s", session, yes_no(r));
 
-        assert_se(sd_session_get_type(session, &type) >= 0);
-        printf("type = %s\n", type);
-        free(type);
+                r = sd_session_is_remote(session);
+                assert_se(r >= 0);
+                log_info("sd_session_is_remote(\"%s\") → %s", session, yes_no(r));
 
-        assert_se(sd_session_get_class(session, &class) >= 0);
-        printf("class = %s\n", class);
-        free(class);
+                r = sd_session_get_state(session, &state);
+                assert_se(r >= 0);
+                log_info("sd_session_get_state(\"%s\") → \"%s\"", session, state);
 
-        display = NULL;
-        r = sd_session_get_display(session, &display);
-        assert_se(r >= 0 || r == -ENODATA);
-        printf("display = %s\n", strna(display));
-        free(display);
+                assert_se(sd_session_get_uid(session, &u) >= 0);
+                log_info("sd_session_get_uid(\"%s\") → "UID_FMT, session, u);
+                assert_se(u == u2);
 
-        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);
+                assert_se(sd_session_get_type(session, &type) >= 0);
+                log_info("sd_session_get_type(\"%s\") → \"%s\"", session, type);
 
-        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_class(session, &class) >= 0);
+                log_info("sd_session_get_class(\"%s\") → \"%s\"", session, class);
 
-        assert_se(sd_session_get_seat(session, &seat) >= 0);
-        printf("seat = %s\n", seat);
+                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_multi_session(seat);
-        assert_se(r >= 0);
-        printf("can do multi session = %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));
 
-        r = sd_seat_can_tty(seat);
-        assert_se(r >= 0);
-        printf("can do tty = %s\n", yes_no(r));
+                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));
 
-        r = sd_seat_can_graphical(seat);
-        assert_se(r >= 0);
-        printf("can do graphical = %s\n", yes_no(r));
+                r = sd_session_get_seat(session, &seat);
+                if (r >= 0) {
+                        assert_se(seat);
 
-        assert_se(sd_uid_get_state(u, &state) >= 0);
-        printf("state = %s\n", state);
+                        log_info("sd_session_get_display(\"%s\") → \"%s\"", session, seat);
 
-        assert_se(sd_uid_is_on_seat(u, 0, seat) > 0);
+                        r = sd_seat_can_multi_session(seat);
+                        assert_se(r >= 0);
+                        log_info("sd_session_can_multi_seat(\"%s\") → %s", seat, yes_no(r));
 
-        k = sd_uid_is_on_seat(u, 1, seat);
-        assert_se(k >= 0);
-        assert_se(!!r == !!r);
+                        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_active(seat, &session2, &u2) >= 0);
-        printf("session2 = %s\n", session2);
-        printf("uid2 = "UID_FMT"\n", u2);
+                        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);
+                }
 
-        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);
+                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);
 
-        assert_se(sd_seat_get_sessions(seat, NULL, NULL, NULL) == r);
+                k = sd_uid_is_on_seat(u, 1, seat);
+                assert_se(k >= 0);
+                assert_se(!!k == !!r);
 
-        free(session);
-        free(state);
-        free(session2);
-        free(seat);
+                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;
+
+                r = sd_get_uids(&uids);
+                assert_se(r >= 0);
+                log_info("sd_get_uids(…) → [%i] {%s}", r, format_uids(&buf, uids, r));
 
-        printf("uids =");
-        for (k = 0; k < r; k++)
-                printf(" "UID_FMT, uids[k]);
-        printf("\n");
-        free(uids);
+                assert_se(sd_get_uids(NULL) == r);
+        }
 
-        printf("n_uids = %i\n", r);
-        assert_se(sd_get_uids(NULL) == r);
+        {
+                _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(t = strv_join(machines, ", "));
-        strv_free(machines);
-        printf("n_machines = %i\n", r);
-        printf("machines = %s\n", t);
-        free(t);
+                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;
 }
index 4ae1210fe14e24b6376a2665f638835a71785e61..6573bed00f22d90916ff95b397c487a3ad5d8def 100644 (file)
@@ -786,8 +786,7 @@ tests += [
 
         [['src/libsystemd/sd-login/test-login.c'],
          [],
-         [],
-         '', 'manual'],
+         []],
 ]
 
 ############################################################