1
0
mirror of https://github.com/systemd/systemd synced 2024-07-09 04:26:06 +00:00
systemd/test/units/TEST-38-FREEZER.sh
Daan De Meyer 7a321b5a21 test: Rename testsuite-XX units to match test name
Having these named differently than the test itself mostly creates
unecessary confusion and makes writing logic against the tests harder
so let's rename the testsuite-xx units and scripts to just use the
test name itself.
2024-05-14 12:43:28 +02:00

364 lines
9.9 KiB
Bash
Executable File

#!/usr/bin/env bash
# SPDX-License-Identifier: LGPL-2.1-or-later
# shellcheck disable=SC2317
set -eux
set -o pipefail
# shellcheck source=test/units/test-control.sh
. "$(dirname "$0")"/test-control.sh
systemd-analyze log-level debug
unit=TEST-38-FREEZER-sleep.service
start_test_service() {
systemctl daemon-reload
systemctl start "${unit}"
}
dbus_freeze() {
local name object_path suffix
suffix="${1##*.}"
name="${1%".$suffix"}"
object_path="/org/freedesktop/systemd1/unit/${name//-/_2d}_2e${suffix}"
busctl call \
org.freedesktop.systemd1 \
"${object_path}" \
org.freedesktop.systemd1.Unit \
Freeze
}
dbus_thaw() {
local name object_path suffix
suffix="${1##*.}"
name="${1%".$suffix"}"
object_path="/org/freedesktop/systemd1/unit/${name//-/_2d}_2e${suffix}"
busctl call \
org.freedesktop.systemd1 \
"${object_path}" \
org.freedesktop.systemd1.Unit \
Thaw
}
dbus_freeze_unit() {
busctl call \
org.freedesktop.systemd1 \
/org/freedesktop/systemd1 \
org.freedesktop.systemd1.Manager \
FreezeUnit \
s \
"$1"
}
dbus_thaw_unit() {
busctl call \
org.freedesktop.systemd1 \
/org/freedesktop/systemd1 \
org.freedesktop.systemd1.Manager \
ThawUnit \
s \
"$1"
}
dbus_can_freeze() {
local name object_path suffix
suffix="${1##*.}"
name="${1%".$suffix"}"
object_path="/org/freedesktop/systemd1/unit/${name//-/_2d}_2e${suffix}"
busctl get-property \
org.freedesktop.systemd1 \
"${object_path}" \
org.freedesktop.systemd1.Unit \
CanFreeze
}
check_freezer_state() {
local name object_path suffix
suffix="${1##*.}"
name="${1%".$suffix"}"
object_path="/org/freedesktop/systemd1/unit/${name//-/_2d}_2e${suffix}"
for _ in {0..10}; do
state=$(busctl get-property \
org.freedesktop.systemd1 \
"${object_path}" \
org.freedesktop.systemd1.Unit \
FreezerState | cut -d " " -f2 | tr -d '"')
# Ignore the intermediate freezing & thawing states in case we check
# the unit state too quickly
[[ "$state" =~ ^(freezing|thawing) ]] || break
sleep .5
done
[ "$state" = "$2" ] || {
echo "error: unexpected freezer state, expected: $2, actual: $state" >&2
exit 1
}
}
check_cgroup_state() {
# foo.unit -> /system.slice/foo.unit/
# foo.slice/ -> /foo.slice/./
# foo.slice/foo.unit -> /foo.slice/foo.unit/
local slice unit
unit="${1##*/}"
slice="${1%"$unit"}"
slice="${slice%/}"
grep -q "frozen $2" /sys/fs/cgroup/"${slice:-system.slice}"/"${unit:-.}"/cgroup.events
}
testcase_dbus_api() {
echo "Test that DBus API works:"
echo -n " - Freeze(): "
dbus_freeze "${unit}"
check_freezer_state "${unit}" "frozen"
check_cgroup_state "$unit" 1
echo "[ OK ]"
echo -n " - Thaw(): "
dbus_thaw "${unit}"
check_freezer_state "${unit}" "running"
check_cgroup_state "$unit" 0
echo "[ OK ]"
echo -n " - FreezeUnit(): "
dbus_freeze_unit "${unit}"
check_freezer_state "${unit}" "frozen"
check_cgroup_state "$unit" 1
echo "[ OK ]"
echo -n " - ThawUnit(): "
dbus_thaw_unit "${unit}"
check_freezer_state "${unit}" "running"
check_cgroup_state "$unit" 0
echo "[ OK ]"
echo -n " - CanFreeze(): "
output=$(dbus_can_freeze "${unit}")
[ "$output" = "b true" ]
echo "[ OK ]"
echo
}
testcase_systemctl() {
echo "Test that systemctl freeze/thaw verbs:"
systemctl start "$unit"
echo -n " - freeze: "
systemctl freeze "$unit"
check_freezer_state "${unit}" "frozen"
check_cgroup_state "$unit" 1
# Freezing already frozen unit should be NOP and return quickly
timeout 3s systemctl freeze "$unit"
echo "[ OK ]"
echo -n " - thaw: "
systemctl thaw "$unit"
check_freezer_state "${unit}" "running"
check_cgroup_state "$unit" 0
# Likewise thawing already running unit shouldn't block
timeout 3s systemctl thaw "$unit"
echo "[ OK ]"
systemctl stop "$unit"
echo
}
testcase_systemctl_show() {
echo "Test systemctl show integration:"
systemctl start "$unit"
echo -n " - FreezerState property: "
state=$(systemctl show -p FreezerState --value "$unit")
[ "$state" = "running" ]
systemctl freeze "$unit"
state=$(systemctl show -p FreezerState --value "$unit")
[ "$state" = "frozen" ]
systemctl thaw "$unit"
echo "[ OK ]"
echo -n " - CanFreeze property: "
state=$(systemctl show -p CanFreeze --value "$unit")
[ "$state" = "yes" ]
echo "[ OK ]"
systemctl stop "$unit"
echo
}
testcase_recursive() {
local slice="bar.slice"
local unit="baz.service"
systemd-run --unit "$unit" --slice "$slice" sleep 3600 >/dev/null 2>&1
echo "Test recursive freezing:"
echo -n " - freeze/thaw parent: "
systemctl freeze "$slice"
check_freezer_state "$slice" "frozen"
check_freezer_state "$unit" "frozen-by-parent"
check_cgroup_state "$slice/" 1
check_cgroup_state "$slice/$unit" 1
systemctl thaw "$slice"
check_freezer_state "$slice" "running"
check_freezer_state "$unit" "running"
check_cgroup_state "$slice/" 0
check_cgroup_state "$slice/$unit" 0
echo "[ OK ]"
echo -n " - child freeze/thaw during frozen parent: "
systemctl freeze "$slice"
check_freezer_state "$slice" "frozen"
check_freezer_state "$unit" "frozen-by-parent"
check_cgroup_state "$slice/" 1
check_cgroup_state "$slice/$unit" 1
systemctl freeze "$unit"
check_freezer_state "$slice" "frozen"
check_freezer_state "$unit" "frozen"
check_cgroup_state "$slice/" 1
check_cgroup_state "$slice/$unit" 1
systemctl thaw "$unit"
check_freezer_state "$slice" "frozen"
check_freezer_state "$unit" "frozen-by-parent"
check_cgroup_state "$slice/" 1
check_cgroup_state "$slice/$unit" 1
systemctl thaw "$slice"
check_freezer_state "$slice" "running"
check_freezer_state "$unit" "running"
check_cgroup_state "$slice/" 0
check_cgroup_state "$slice/$unit" 0
echo "[ OK ]"
echo -n " - pre-frozen child not thawed by parent: "
systemctl freeze "$unit"
check_freezer_state "$slice" "running"
check_freezer_state "$unit" "frozen"
check_cgroup_state "$slice/" 0
check_cgroup_state "$slice/$unit" 1
systemctl freeze "$slice"
check_freezer_state "$slice" "frozen"
check_freezer_state "$unit" "frozen"
check_cgroup_state "$slice/" 1
check_cgroup_state "$slice/$unit" 1
systemctl thaw "$slice"
check_freezer_state "$slice" "running"
check_freezer_state "$unit" "frozen"
check_cgroup_state "$slice/" 0
check_cgroup_state "$slice/$unit" 1
echo "[ OK ]"
echo -n " - pre-frozen child demoted and thawed by parent: "
systemctl freeze "$slice"
check_freezer_state "$slice" "frozen"
check_freezer_state "$unit" "frozen"
check_cgroup_state "$slice/" 1
check_cgroup_state "$slice/$unit" 1
systemctl thaw "$unit"
check_freezer_state "$slice" "frozen"
check_freezer_state "$unit" "frozen-by-parent"
check_cgroup_state "$slice/" 1
check_cgroup_state "$slice/$unit" 1
systemctl thaw "$slice"
check_freezer_state "$slice" "running"
check_freezer_state "$unit" "running"
check_cgroup_state "$slice/" 0
check_cgroup_state "$slice/$unit" 0
echo "[ OK ]"
echo -n " - child promoted and not thawed by parent: "
systemctl freeze "$slice"
check_freezer_state "$slice" "frozen"
check_freezer_state "$unit" "frozen-by-parent"
check_cgroup_state "$slice/" 1
check_cgroup_state "$slice/$unit" 1
systemctl freeze "$unit"
check_freezer_state "$slice" "frozen"
check_freezer_state "$unit" "frozen"
check_cgroup_state "$slice/" 1
check_cgroup_state "$slice/$unit" 1
systemctl thaw "$slice"
check_freezer_state "$slice" "running"
check_freezer_state "$unit" "frozen"
check_cgroup_state "$slice/" 0
check_cgroup_state "$slice/$unit" 1
echo "[ OK ]"
echo -n " - can't stop a frozen unit: "
(! systemctl -q stop "$unit" )
echo "[ OK ]"
systemctl thaw "$unit"
systemctl stop "$unit"
systemctl stop "$slice"
echo
}
testcase_preserve_state() {
local slice="bar.slice"
local unit="baz.service"
systemd-run --unit "$unit" --slice "$slice" sleep 3600 >/dev/null 2>&1
echo "Test that freezer state is preserved when recursive freezing is initiated from outside (e.g. by manager up the tree):"
echo -n " - freeze from outside: "
echo 1 >/sys/fs/cgroup/"$slice"/cgroup.freeze
# Give kernel some time to freeze the slice
sleep 1
# Our state should not be affected
check_freezer_state "$slice" "running"
check_freezer_state "$unit" "running"
# However actual kernel state should be frozen
check_cgroup_state "$slice/" 1
check_cgroup_state "$slice/$unit" 1
echo "[ OK ]"
echo -n " - thaw from outside: "
echo 0 >/sys/fs/cgroup/"$slice"/cgroup.freeze
sleep 1
check_freezer_state "$unit" "running"
check_freezer_state "$slice" "running"
check_cgroup_state "$slice/" 0
check_cgroup_state "$slice/$unit" 0
echo "[ OK ]"
echo -n " - thaw from outside while inner service is frozen: "
systemctl freeze "$unit"
check_freezer_state "$unit" "frozen"
echo 1 >/sys/fs/cgroup/"$slice"/cgroup.freeze
echo 0 >/sys/fs/cgroup/"$slice"/cgroup.freeze
check_freezer_state "$slice" "running"
check_freezer_state "$unit" "frozen"
echo "[ OK ]"
systemctl thaw "$unit"
systemctl stop "$unit"
systemctl stop "$slice"
echo
}
if [[ -e /sys/fs/cgroup/system.slice/cgroup.freeze ]]; then
start_test_service
run_testcases
fi
touch /testok