From 96e69cb655c703d5312c4aa44912e6ce90b4f76f Mon Sep 17 00:00:00 2001 From: Frantisek Sumsal Date: Wed, 29 Mar 2023 22:38:55 +0200 Subject: [PATCH] test: make TEST-35-LOGIN stable again The expect stuff was anything but expected, so let's just backport the upstream test case and tweak it a bit to account for the missing parts in our downstream testing infrastructure. Follow-up to 638c2418e7. Related: #2179309 rhel-only --- test/TEST-35-LOGIN/testsuite.sh | 225 ++++++++++++++++++++++++-------- test/test-functions | 2 +- 2 files changed, 175 insertions(+), 52 deletions(-) diff --git a/test/TEST-35-LOGIN/testsuite.sh b/test/TEST-35-LOGIN/testsuite.sh index e4d72beb74..149b2354a1 100755 --- a/test/TEST-35-LOGIN/testsuite.sh +++ b/test/TEST-35-LOGIN/testsuite.sh @@ -3,6 +3,141 @@ set -eux set -o pipefail +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 + + return 0 +) + +setup_test_user() { + mkdir -p /var/spool/cron /var/spool/mail /var/run/console + 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 <&2 + return 1 + fi + + 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 | awk '$3 == "logind-test-user" { print $1 }') + if [[ -z "$session" ]]; then + echo "no session found for user logind-test-user" >&2 + return 1 + fi + + 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" | awk '$1 == "Leader:" { 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 + cat /proc/self/cgroup + return 1 + fi +) + +create_session() { + # 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 </dev/null ; then - echo >&2 "expect not installed, skiping test ${FUNCNAME[0]}" - return 0 - fi + cleanup_session - setup_idle_action_lock - trap teardown_idle_action_lock RETURN + return 0 +) - if loginctl --no-legend | awk '{ print $3; }' | sort -u | grep -q testuser ; then - echo >&2 "Session of the \'testuser\' is already present." - return 1 +test_lock_idle_action() { + local ts + + if [[ ! -c /dev/tty2 ]]; then + echo "/dev/tty2 does not exist, skipping test ${FUNCNAME[0]}." + return 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 accomodate for any possible scheudling delays. - cat > /tmp/test.exp <&2 "Session of the \'logind-test-user\' is already present." + exit 1 + fi - ts="$(date '+%H:%M:%S')" - busctl --match "type='signal',sender='org.freedesktop.login1',interface='org.freedesktop.login1.Session',member='Lock'" monitor > dbus.log & + trap teardown_lock_idle_action RETURN - expect /tmp/test.exp & + create_session - # Sleep a bit to give expect time to spawn systemd-run before we check for - # the presence of resulting session. - sleep 2 - 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 + ts="$(date '+%H:%M:%S')" - wait %2 - sleep 20 - kill %1 + mkdir -p /run/systemd/logind.conf.d + cat >/run/systemd/logind.conf.d/idle-action-lock.conf <&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" + + # Wakeup + touch /dev/tty2 + + # 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" - journalctl -b -u systemd-logind.service --since="$ts" > logind.log - if [ "$(grep -c 'System idle. Doing lock operation.' logind.log)" -lt 2 ]; then + if [[ "$(journalctl -b -u systemd-logind.service --since="$ts" | grep -c 'System idle. Doing lock operation.')" -lt 2 ]]; then echo >&2 "System haven't entered idle state at least 2 times." - return 1 + exit 1 fi - - rm -f dbus.log logind.log } : >/failed +setup_test_user +test_enable_debug test_lock_idle_action touch /testok diff --git a/test/test-functions b/test/test-functions index 9606a1b085..e5d4d28a5f 100644 --- a/test/test-functions +++ b/test/test-functions @@ -23,7 +23,7 @@ fi PATH_TO_INIT=$ROOTLIBDIR/systemd -BASICTOOLS="test sh bash setsid loadkeys setfont login sulogin gzip sleep echo mount umount cryptsetup date dmsetup modprobe sed cmp tee rm true false chmod chown ln xargs env mktemp mountpoint useradd userdel" +BASICTOOLS="test sh bash setsid loadkeys setfont login sulogin gzip sleep echo mount umount cryptsetup date dmsetup modprobe sed cmp tee rm true false chmod chown ln xargs env mktemp mountpoint useradd userdel timeout" DEBUGTOOLS="df free ls stty cat ps ln ip route dmesg dhclient mkdir cp ping dhclient strace less grep id tty touch du sort hostname find" STATEDIR="${BUILD_DIR:-.}/test/$(basename $(dirname $(realpath $0)))"