mirror of
https://github.com/systemd/systemd
synced 2024-09-06 16:56:43 +00:00
![Daan De Meyer](/assets/img/avatar_default.png)
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.
364 lines
9.9 KiB
Bash
Executable file
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
|