summaryrefslogtreecommitdiff
path: root/test/units/testsuite-35.sh
diff options
context:
space:
mode:
authorYu Watanabe <watanabe.yu+github@gmail.com>2022-07-07 10:10:05 +0900
committerFrantisek Sumsal <frantisek@sumsal.cz>2022-07-07 13:15:00 +0000
commit63663a0f0f0e1dcd6036cecf013de3f1de87cd99 (patch)
treed666634ee4f996afcf8e5f2bf08ceadb2b645d57 /test/units/testsuite-35.sh
parent1f7eed4c3504ea6e852d64057c1e6b8df2091eeb (diff)
downloadsystemd-63663a0f0f0e1dcd6036cecf013de3f1de87cd99.tar.gz
test: several cleanups for TEST-35-LOGIN
- 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
Diffstat (limited to 'test/units/testsuite-35.sh')
-rwxr-xr-xtest/units/testsuite-35.sh408
1 files changed, 188 insertions, 220 deletions
diff --git a/test/units/testsuite-35.sh b/test/units/testsuite-35.sh
index 98283cad25..147604e293 100755
--- a/test/units/testsuite-35.sh
+++ b/test/units/testsuite-35.sh
@@ -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