]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
test: several cleanups for TEST-35-LOGIN
authorYu Watanabe <watanabe.yu+github@gmail.com>
Thu, 7 Jul 2022 01:10:05 +0000 (10:10 +0900)
committerFrantisek Sumsal <frantisek@sumsal.cz>
Thu, 7 Jul 2022 13:15:00 +0000 (13:15 +0000)
- use test_append_files() to install additional commands
- drop use of expect
- include assert.sh and use assertions at several places
- use timeout command at several places
- always use logind-test-user
- etc

test/TEST-35-LOGIN/test.sh
test/test-functions
test/units/testsuite-35.sh

index 9762410fa371f017a71cc53dc530a7bcf3623f1f..add862c962aad78f4bc47b1dd74fd7911d3cc438 100755 (executable)
@@ -2,9 +2,13 @@
 # SPDX-License-Identifier: LGPL-2.1-or-later
 set -e
 
-TEST_DESCRIPTION="LOGIN"
+TEST_DESCRIPTION="Tests for systemd-logind"
 
 # shellcheck source=test/test-functions
 . "${TEST_BASE_DIR:?}/test-functions"
 
+test_append_files() {
+    image_install -o evemu-device evemu-event crond crontab
+}
+
 do_test "$@"
index 974fa4384beb1363b8cf4b65ca164c944550ddc9..acb09c20be0de5e1adbec8780403d3f64c7bde92 100644 (file)
@@ -1735,16 +1735,6 @@ install_basic_tools() {
     image_install -o sushell
     # in Debian ldconfig is just a shell script wrapper around ldconfig.real
     image_install -o ldconfig.real
-    # for TEST-35-LOGIN
-    image_install -o evemu-device evemu-event crond crontab
-    image_install -o evemu-device evemu-event
-    if command -v expect >/dev/null && command -v tclsh >/dev/null ; then
-        # shellcheck disable=SC2016
-        version="$(tclsh <<< 'puts $tcl_version')"
-
-        image_install expect
-        inst_recursive /usr/lib64/tcl"$version" /usr/share/tcl"$version"
-    fi
 }
 
 install_debug_tools() {
index 98283cad25b59ef867903fcc16df284591c0b52d..147604e2936c3a50709cb5b248a66e82207d3b1d 100755 (executable)
@@ -3,6 +3,24 @@
 set -eux
 set -o pipefail
 
+# shellcheck source=test/units/assert.sh
+. "$(dirname "$0")"/assert.sh
+
+cleanup_test_user() (
+    set +ex
+
+    pkill -u "$(id -u logind-test-user)"
+    sleep 1
+    pkill -KILL -u "$(id -u logind-test-user)"
+    userdel -r logind-test-user
+)
+
+setup_test_user() {
+    mkdir -p /var/spool/cron /var/spool/mail
+    useradd -m -s /bin/bash logind-test-user
+    trap cleanup_test_user EXIT
+}
+
 test_enable_debug() {
     mkdir -p /run/systemd/system/systemd-logind.service.d
     cat >/run/systemd/system/systemd-logind.service.d/debug.conf <<EOF
@@ -10,6 +28,7 @@ test_enable_debug() {
 Environment=SYSTEMD_LOG_LEVEL=debug
 EOF
     systemctl daemon-reload
+    systemctl stop systemd-logind.service
 }
 
 test_properties() {
@@ -21,11 +40,7 @@ KillUserProcesses=no
 EOF
 
     systemctl restart systemd-logind.service
-    r=$(busctl get-property org.freedesktop.login1 /org/freedesktop/login1 org.freedesktop.login1.Manager KillUserProcesses)
-    if [[ "$r" != "b false" ]]; then
-        echo "Unexpected KillUserProcesses property '$r', expected='b false'" >&2
-        exit 1
-    fi
+    assert_eq "$(busctl get-property org.freedesktop.login1 /org/freedesktop/login1 org.freedesktop.login1.Manager KillUserProcesses)" "b false"
 
     cat >/run/systemd/logind.conf.d/kill-user-processes.conf <<EOF
 [Login]
@@ -33,46 +48,46 @@ KillUserProcesses=yes
 EOF
 
     systemctl restart systemd-logind.service
-    r=$(busctl get-property org.freedesktop.login1 /org/freedesktop/login1 org.freedesktop.login1.Manager KillUserProcesses)
-    if [[ "$r" != "b true" ]]; then
-        echo "Unexpected KillUserProcesses property '$r', expected='b true'" >&2
-        exit 1
-    fi
+    assert_eq "$(busctl get-property org.freedesktop.login1 /org/freedesktop/login1 org.freedesktop.login1.Manager KillUserProcesses)" "b true"
 
     rm -rf /run/systemd/logind.conf.d
 }
 
 test_started() {
+    local pid
+
     systemctl restart systemd-logind.service
 
     # should start at boot, not with D-BUS activation
-    LOGINDPID=$(systemctl show systemd-logind.service -p ExecMainPID --value)
+    pid=$(systemctl show systemd-logind.service -p ExecMainPID --value)
 
     # loginctl should succeed
-    loginctl --no-pager
+    loginctl
+
+    # logind should still be running
+    assert_eq "$(systemctl show systemd-logind.service -p ExecMainPID --value)" "$pid"
 }
 
-# args: <timeout>
 wait_suspend() {
-    timeout="$1"
-    while [[ $timeout -gt 0 && ! -e /run/suspend.flag ]]; do
-        sleep 1
-        timeout=$((timeout - 1))
-    done
-    if [[ ! -e /run/suspend.flag ]]; then
-        echo "closing lid did not cause suspend" >&2
-        exit 1
-    fi
+    timeout "${1?}" bash -c "while [[ ! -e /run/suspend.flag ]]; do sleep 1; done"
     rm /run/suspend.flag
 }
 
-test_suspend_tear_down() {
-    set +e
+teardown_suspend() (
+    set +eux
 
-    kill "$KILL_PID"
-}
+    pkill evemu-device
+
+    rm -rf /run/systemd/system/systemd-suspend.service.d
+    systemctl daemon-reload
+
+    rm -f /run/udev/rules.d/70-logindtest-lid.rules
+    udevadm control --reload
+)
 
 test_suspend_on_lid() {
+    local pid input_name lid_dev
+
     if systemd-detect-virt --quiet --container; then
         echo "Skipping suspend test in container"
         return
@@ -90,8 +105,10 @@ test_suspend_on_lid() {
         return
     fi
 
-    KILL_PID=
-    trap test_suspend_tear_down RETURN
+    trap teardown_suspend RETURN
+
+    # save pid
+    pid=$(systemctl show systemd-logind.service -p ExecMainPID --value)
 
     # create fake suspend
     mkdir -p /run/systemd/system/systemd-suspend.service.d
@@ -147,129 +164,127 @@ B: 15 00 00 00 00 00 00 00 00
 EOF
 
     evemu-device /run/lidswitch.evemu &
-    KILL_PID="$!"
-
-    for ((i = 0; i < 20; i++)); do
-        if (( i != 0 )); then sleep .5; fi
 
-        INPUT_NAME=$(grep -l '^Fake Lid Switch' /sys/class/input/*/device/name || :)
-        if [[ -n "$INPUT_NAME" ]]; then break; fi
-    done
-    if [[ -z "$INPUT_NAME" ]]; then
+    timeout 20 bash -c 'while ! grep "^Fake Lid Switch" /sys/class/input/*/device/name; do sleep .5; done'
+    input_name=$(grep -l '^Fake Lid Switch' /sys/class/input/*/device/name || :)
+    if [[ -z "$input_name" ]]; then
         echo "cannot find fake lid switch." >&2
         exit 1
     fi
-    INPUT_NAME=${INPUT_NAME%/device/name}
-    LID_DEV=/dev/${INPUT_NAME#/sys/class/}
-    udevadm info --wait-for-initialization=10s "$LID_DEV"
+    input_name=${input_name%/device/name}
+    lid_dev=/dev/${input_name#/sys/class/}
+    udevadm info --wait-for-initialization=10s "$lid_dev"
     udevadm settle
 
     # close lid
-    evemu-event "$LID_DEV" --sync --type 5 --code 0 --value 1
+    evemu-event "$lid_dev" --sync --type 5 --code 0 --value 1
     # need to wait for 30s suspend inhibition after boot
     wait_suspend 31
     # open lid again
-    evemu-event "$LID_DEV" --sync --type 5 --code 0 --value 0
+    evemu-event "$lid_dev" --sync --type 5 --code 0 --value 0
 
     # waiting for 30s inhibition time between suspends
     sleep 30
 
     # now closing lid should cause instant suspend
-    evemu-event "$LID_DEV" --sync --type 5 --code 0 --value 1
+    evemu-event "$lid_dev" --sync --type 5 --code 0 --value 1
     wait_suspend 2
-    evemu-event "$LID_DEV" --sync --type 5 --code 0 --value 0
+    evemu-event "$lid_dev" --sync --type 5 --code 0 --value 0
 
-    P=$(systemctl show systemd-logind.service -p ExecMainPID --value)
-    if [[ "$P" != "$LOGINDPID" ]]; then
-        echo "logind crashed" >&2
-        exit 1
-    fi
+    assert_eq "$(systemctl show systemd-logind.service -p ExecMainPID --value)" "$pid"
 }
 
 test_shutdown() {
+    local pid
+
+    # save pid
+    pid=$(systemctl show systemd-logind.service -p ExecMainPID --value)
+
     # scheduled shutdown with wall message
     shutdown 2>&1
     sleep 5
     shutdown -c || :
     # logind should still be running
-    P=$(systemctl show systemd-logind.service -p ExecMainPID --value)
-    if [[ "$P" != "$LOGINDPID" ]]; then
-        echo "logind crashed" >&2
-        exit 1
-    fi
+    assert_eq "$(systemctl show systemd-logind.service -p ExecMainPID --value)" "$pid"
 
     # scheduled shutdown without wall message
     shutdown --no-wall 2>&1
     sleep 5
     shutdown -c --no-wall || true
-    P=$(systemctl show systemd-logind.service -p ExecMainPID --value)
-    if [[ "$P" != "$LOGINDPID" ]]; then
-        echo "logind crashed" >&2
-        exit 1
-    fi
+    assert_eq "$(systemctl show systemd-logind.service -p ExecMainPID --value)" "$pid"
 }
 
-test_session_tear_down() {
-    set +e
-
-    rm -f /run/udev/rules.d/70-logindtest-scsi_debug-user.rules
-    udevadm control --reload
+teardown_session() (
+    set +ex
 
     systemctl stop getty@tty2.service
     rm -rf /run/systemd/system/getty@tty2.service.d
     systemctl daemon-reload
 
-    pkill -u logind-test-user
-    userdel logind-test-user
+    pkill -u "$(id -u logind-test-user)"
+    sleep 1
+    pkill -KILL -u "$(id -u logind-test-user)"
 
+    rm -f /run/udev/rules.d/70-logindtest-scsi_debug-user.rules
+    udevadm control --reload
     rmmod scsi_debug
-}
+)
+
+check_session() (
+    set +ex
+
+    local seat session leader_pid
 
-check_session() {
-    loginctl
     if [[ $(loginctl --no-legend | grep -c "logind-test-user") != 1 ]]; then
         echo "no session or multiple sessions for logind-test-user." >&2
         return 1
     fi
 
-    SEAT=$(loginctl --no-legend | grep 'logind-test-user *seat' | awk '{ print $4 }')
-    if [[ -z "$SEAT" ]]; then
+    seat=$(loginctl --no-legend | grep 'logind-test-user *seat' | awk '{ print $4 }')
+    if [[ -z "$seat" ]]; then
         echo "no seat found for user logind-test-user" >&2
         return 1
     fi
 
-    SESSION=$(loginctl --no-legend | grep "logind-test-user" | awk '{ print $1 }')
-    if [[ -z "$SESSION" ]]; then
+    session=$(loginctl --no-legend | grep "logind-test-user" | awk '{ print $1 }')
+    if [[ -z "$session" ]]; then
         echo "no session found for user logind-test-user" >&2
         return 1
     fi
 
-    loginctl session-status "$SESSION"
-    loginctl session-status "$SESSION" | grep -q "Unit: session-${SESSION}\.scope"
-    LEADER_PID=$(loginctl session-status "$SESSION" | grep "Leader:" | awk '{ print $2 }')
-    if [[ -z "$LEADER_PID" ]]; then
-        echo "cannot found leader process for session $SESSION" >&2
+    if ! loginctl session-status "$session" | grep -q "Unit: session-${session}\.scope"; then
+        echo "cannot find scope unit for session $session" >&2
+        return 1
+    fi
+
+    leader_pid=$(loginctl session-status "$session" | grep "Leader:" | awk '{ print $2 }')
+    if [[ -z "$leader_pid" ]]; then
+        echo "cannot found leader process for session $session" >&2
         return 1
     fi
 
     # cgroup v1: "1:name=systemd:/user.slice/..."; unified hierarchy: "0::/user.slice"
-    if ! grep -q -E '(name=systemd|^0:):.*session.*scope' /proc/"$LEADER_PID"/cgroup; then
-        echo "FAIL: process $LEADER_PID is not in the session cgroup" >&2
+    if ! grep -q -E '(name=systemd|^0:):.*session.*scope' /proc/"$leader_pid"/cgroup; then
+        echo "FAIL: process $leader_pid is not in the session cgroup" >&2
         cat /proc/self/cgroup
         return 1
     fi
-}
+)
 
 test_session() {
+    local dev
+
     if systemd-detect-virt --quiet --container; then
-        echo " * Skipping ACL tests in container"
+        echo "Skipping ACL tests in container"
         return
     fi
 
-    trap test_session_tear_down RETURN
+    if [[ ! -c /dev/tty2 ]]; then
+        echo "/dev/tty2 does not exist, skipping test ${FUNCNAME[0]}."
+        return
+    fi
 
-    # add user
-    useradd -s /bin/bash logind-test-user
+    trap teardown_session RETURN
 
     # login with the test user to start a session
     mkdir -p /run/systemd/system/getty@tty2.service.d
@@ -280,20 +295,14 @@ ExecStart=
 ExecStart=-/sbin/agetty --autologin logind-test-user --noclear %I $TERM
 EOF
     systemctl daemon-reload
-    systemctl start getty@tty2.service
+    systemctl restart getty@tty2.service
 
     # check session
-    ret=1
     for ((i = 0; i < 30; i++)); do
-        if (( i != 0)); then sleep 1; fi
-        if check_session; then
-            ret=0
-            break
-        fi
+        (( i != 0 )) && sleep 1
+        check_session && break
     done
-    if [[ "$ret" == "1" ]]; then
-        exit 1
-    fi
+    check_session
 
     # scsi_debug should not be loaded yet
     if [[ -d /sys/bus/pseudo/drivers/scsi_debug ]]; then
@@ -312,12 +321,8 @@ EOF
     # coldplug: logind started with existing device
     systemctl stop systemd-logind.service
     modprobe scsi_debug
-    for ((i = 0; i < 30; i++)); do
-        if (( i != 0)); then sleep 1; fi
-        if dev=/dev/$(ls /sys/bus/pseudo/drivers/scsi_debug/adapter*/host*/target*/*:*/block 2>/dev/null); then
-            break
-        fi
-    done
+    timeout 30 bash -c 'while ! ls /sys/bus/pseudo/drivers/scsi_debug/adapter*/host*/target*/*:*/block 2>/dev/null; do sleep 1; done'
+    dev=/dev/$(ls /sys/bus/pseudo/drivers/scsi_debug/adapter*/host*/target*/*:*/block 2>/dev/null)
     if [[ ! -b "$dev" ]]; then
         echo "cannot find suitable scsi block device" >&2
         exit 1
@@ -326,25 +331,17 @@ EOF
     udevadm info "$dev"
 
     # trigger logind and activate session
-    loginctl activate "$SESSION"
+    loginctl activate "$(loginctl --no-legend | grep "logind-test-user" | awk '{ print $1 }')"
 
     # check ACL
     sleep 1
-    if ! getfacl -p "$dev" | grep -q "user:logind-test-user:rw-"; then
-        echo "$dev has no ACL for user logind-test-user" >&2
-        getfacl -p "$dev" >&2
-        exit 1
-    fi
+    assert_in "user:logind-test-user:rw-" "$(getfacl -p "$dev")"
 
     # hotplug: new device appears while logind is running
     rmmod scsi_debug
     modprobe scsi_debug
-    for ((i = 0; i < 30; i++)); do
-        if (( i != 0)); then sleep 1; fi
-        if dev=/dev/$(ls /sys/bus/pseudo/drivers/scsi_debug/adapter*/host*/target*/*:*/block 2>/dev/null); then
-            break
-        fi
-    done
+    timeout 30 bash -c 'while ! ls /sys/bus/pseudo/drivers/scsi_debug/adapter*/host*/target*/*:*/block 2>/dev/null; do sleep 1; done'
+    dev=/dev/$(ls /sys/bus/pseudo/drivers/scsi_debug/adapter*/host*/target*/*:*/block 2>/dev/null)
     if [[ ! -b "$dev" ]]; then
         echo "cannot find suitable scsi block device" >&2
         exit 1
@@ -353,161 +350,132 @@ EOF
 
     # check ACL
     sleep 1
-    if ! getfacl -p "$dev" | grep -q "user:logind-test-user:rw-"; then
-        echo "$dev has no ACL for user logind-test-user" >&2
-        getfacl -p "$dev" >&2
-        exit 1
-    fi
+    assert_in "user:logind-test-user:rw-" "$(getfacl -p "$dev")"
 }
 
-setup_idle_action_lock() {
-    useradd testuser ||:
+teardown_lock_idle_action() (
+    set +eux
 
-    mkdir -p /run/systemd/logind.conf.d/
-    cat >/run/systemd/logind.conf.d/idle-action-lock.conf <<EOF
-[Login]
-IdleAction=lock
-IdleActionSec=1s
-EOF
-    systemctl restart systemd-logind.service
-    systemctl service-log-level systemd-logind.service debug
-}
+    systemctl stop getty@tty2.service
+    rm -rf /run/systemd/system/getty@tty2.service.d
+    systemctl daemon-reload
+
+    pkill -u "$(id -u logind-test-user)"
+    sleep 1
+    pkill -KILL -u "$(id -u logind-test-user)"
 
-teardown_idle_action_lock() {(
-    set +ex
     rm -f /run/systemd/logind.conf.d/idle-action-lock.conf
-    pkill -9 -u "$(id -u testuser)"
-    userdel -r testuser
     systemctl restart systemd-logind.service
-)}
+)
 
 test_lock_idle_action() {
-    if ! command -v expect >/dev/null ; then
-        echo >&2 "expect not installed, skipping test ${FUNCNAME[0]}"
-        return 0
+    local ts
+
+    if [[ ! -c /dev/tty2 ]]; then
+        echo "/dev/tty2 does not exist, skipping test ${FUNCNAME[0]}."
+        return
     fi
 
-    setup_idle_action_lock
-    trap teardown_idle_action_lock RETURN
+    trap teardown_lock_idle_action RETURN
 
-    if loginctl --no-legend | awk '{ print $3; }' | sort -u | grep -q testuser ; then
-        echo >&2 "Session of the \'testuser\' is already present."
-        return 1
+    mkdir -p /run/systemd/logind.conf.d
+    cat >/run/systemd/logind.conf.d/idle-action-lock.conf <<EOF
+[Login]
+IdleAction=lock
+IdleActionSec=1s
+EOF
+    systemctl restart systemd-logind.service
+
+    if loginctl --no-legend | grep -q logind-test-user; then
+        echo >&2 "Session of the \'logind-test-user\' is already present."
+        exit 1
     fi
 
-    # IdleActionSec is set 1s but the accuracy of associated timer is 30s so we
-    # need to sleep in worst case for 31s to make sure timer elapsed. We sleep
-    # here for 35s to accommodate for any possible scheduling delays.
-    cat > /tmp/test.exp <<EOF
-spawn systemd-run -G -t -p PAMName=login -p User=testuser bash
-send "sleep 35\r"
-send "echo foobar\r"
-send "sleep 35\r"
-send "exit\r"
-interact
-wait
+    # login with the test user to start a session
+    mkdir -p /run/systemd/system/getty@tty2.service.d
+    cat >/run/systemd/system/getty@tty2.service.d/override.conf <<EOF
+[Service]
+Type=simple
+ExecStart=
+ExecStart=-/sbin/agetty --autologin logind-test-user --noclear %I $TERM
 EOF
+    systemctl daemon-reload
 
     ts="$(date '+%H:%M:%S')"
-    busctl --match "type='signal',sender='org.freedesktop.login1',interface='org.freedesktop.login1.Session',member='Lock'" monitor  > dbus.log &
-
-    expect /tmp/test.exp &
-
-    # Sleep a bit to give expect time to spawn systemd-run before we check for
-    # the presence of resulting session.
-    sleep 1
-    if [ "$(loginctl --no-legend | awk '{ print $3; }' | sort -u | grep -c testuser)" != 1 ] ; then
-        echo >&2 "\'testuser\' is expected to have exactly one session running."
-        return 1
-    fi
+    systemctl restart getty@tty2.service
 
-    wait %2
-    kill %1
+    # check session
+    for ((i = 0; i < 30; i++)); do
+        (( i != 0 )) && sleep 1
+        check_session && break
+    done
+    check_session
+    assert_eq "$(loginctl --no-legend | awk '$3=="logind-test-user" { print $5 }')" "tty2"
 
-    # We slept for 35s , in that interval all sessions should have become idle
+    # Wait for 35s, in that interval all sessions should have become idle
     # and "Lock" signal should have been sent out. Then we wrote to tty to make
     # session active again and next we slept for another 35s so sessions have
     # become idle again. 'Lock' signal is sent out for each session, we have at
     # least one session, so minimum of 2 "Lock" signals must have been sent.
-    if [ "$(grep -c Member=Lock dbus.log)" -lt 2 ]; then
-        echo >&2 "Too few 'Lock' D-Bus signal sent, expected at least 2."
-        return 1
-    fi
+    timeout 35 bash -c "while [[ \"\$(journalctl -b -u systemd-logind.service --since=$ts | grep -c 'Sent message type=signal .* member=Lock')\" -lt 1 ]]; do sleep 1; done"
 
-    journalctl -b -u systemd-logind.service --since="$ts" > logind.log
-    if [ "$(grep -c 'System idle. Will be locked now.' logind.log)" -lt 2 ]; then
-        echo >&2 "System haven't entered idle state at least 2 times."
-        return 1
-    fi
+    # Wakeup
+    touch /dev/tty2
 
-    rm -f dbus.log logind.log
-}
+    # Wait again
+    timeout 35 bash -c "while [[ \"\$(journalctl -b -u systemd-logind.service --since=$ts | grep -c 'Sent message type=signal .* member=Lock')\" -lt 2 ]]; do sleep 1; done"
 
-setup_cron() {
-    # Setup test user and cron
-    useradd test || :
-    crond -s -n &
-    # Install crontab for the test user that runs sleep every minute. But let's sleep for
-    # 65 seconds to make sure there is overlap between two consecutive runs, i.e. we have
-    # always a cron session running.
-    crontab -u test - <<EOF
-RANDOM_DELAY=0
-* * * * * /bin/sleep 65
-EOF
-    # Let's wait (at most one interval plus 10s to accomodate for slow machines) for at least one session of test user
-    timeout 70s bash -c "while true; do loginctl --no-legend list-sessions | awk '{ print \$3 }' | grep -q test && break || sleep 1 ; done"
+    if [[ "$(journalctl -b -u systemd-logind.service --since="$ts" | grep -c 'System idle. Will be locked now.')" -lt 2 ]]; then
+        echo >&2 "System haven't entered idle state at least 2 times."
+        exit 1
+    fi
 }
 
 teardown_cron() (
     set +ex
-    pkill -9 -u "$(id -u test)"
+
+    pkill -u "$(id -u logind-test-user)"
+    sleep 1
+    pkill -KILL -u "$(id -u logind-test-user)"
     pkill crond
-    crontab -r -u test
-    userdel -r test
+    crontab -r -u logind-test-user
 )
 
 test_no_user_instance_for_cron() {
     if ! command -v crond || ! command -v crontab ; then
-        echo >&2 "Skipping test for background cron sessions because cron is missing."
+        echo "Skipping test for background cron sessions because cron is missing."
         return
     fi
 
-    trap teardown_cron EXIT
-    setup_cron
+    trap teardown_cron RETURN
 
-    if [[ $(loginctl --no-legend list-sessions | grep -c test) -lt 1 ]]; then
-        echo >&2 '"test" user should have at least one session'
-        loginctl list-sessions
-        return 1
-    fi
+    # Setup cron
+    crond -s -n &
+    # Install crontab for the test user that runs sleep every minute. But let's sleep for
+    # 65 seconds to make sure there is overlap between two consecutive runs, i.e. we have
+    # always a cron session running.
+    crontab -u logind-test-user - <<EOF
+RANDOM_DELAY=0
+* * * * * /bin/sleep 65
+EOF
+
+    # Let's wait (at most one interval plus 10s to accommodate for slow machines) for at least one session
+    # of the test user
+    timeout 70 bash -c "while ! loginctl --no-legend list-sessions | grep -q logind-test-user; do sleep 1; done"
 
     # Check that all sessions of test user have class=background and no user instance was started
     # for the test user.
     while read -r s _; do
-        local class
-
-        class=$(loginctl --property Class --value show-session "$s")
-        if [[ "$class" != "background" ]]; then
-            echo >&2 "Session has incorrect class, expected \"background\", got \"$class\"."
-            return 1
-        fi
-    done < <(loginctl --no-legend list-sessions | grep test)
-
-    state=$(systemctl --property ActiveState --value show user@"$(id -u test)".service)
-    if [[ "$state" != "inactive" ]]; then
-        echo >&2 "User instance state is unexpected, expected \"inactive\", got \"$state\""
-        return 1
-    fi
+        assert_eq "$(loginctl --property Class --value show-session "$s")" "background"
+    done < <(loginctl --no-legend list-sessions | grep logind-test-user)
 
-    state=$(systemctl --property SubState --value show user@"$(id -u test)".service)
-    if [[ "$state" != "dead" ]]; then
-        echo >&2 "User instance state is unexpected, expected \"dead\", got \"$state\""
-        return 1
-    fi
+    assert_eq "$(systemctl --property ActiveState --value show user@"$(id -u logind-test-user)".service)" "inactive"
+    assert_eq "$(systemctl --property SubState --value show user@"$(id -u logind-test-user)".service)" "dead"
 }
 
 : >/failed
 
+setup_test_user
 test_enable_debug
 test_properties
 test_started