1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221
|
#!/usr/bin/env bash
# SPDX-License-Identifier: LGPL-2.1-or-later
# shellcheck disable=SC2016
set -eux
set -o pipefail
# shellcheck source=test/units/util.sh
. "$(dirname "$0")"/util.sh
# Simple test for that daemon-reexec works in container.
# See: https://github.com/systemd/systemd/pull/23883
systemctl daemon-reexec
# Test merging of a --job-mode=ignore-dependencies job into a previously
# installed job.
systemctl start --no-block hello-after-sleep.target
timeout 10 bash -c "until systemctl list-jobs | tee /root/list-jobs.txt | grep 'sleep\.service.*running'; do sleep .1; done"
grep 'hello\.service.*waiting' /root/list-jobs.txt
# This is supposed to finish quickly, not wait for sleep to finish.
timeout 10 systemctl start --job-mode=ignore-dependencies hello
# sleep should still be running, hello not.
systemctl list-jobs >/root/list-jobs.txt
grep 'sleep\.service.*running' /root/list-jobs.txt
(! grep 'hello\.service' /root/list-jobs.txt)
systemctl stop sleep.service hello-after-sleep.target
# Some basic testing that --show-transaction does something useful
(! systemctl is-active systemd-importd)
systemctl -T start systemd-importd
systemctl is-active systemd-importd
systemctl --show-transaction stop systemd-importd
(! systemctl is-active systemd-importd)
# Test for a crash when enqueuing a JOB_NOP when other job already exists
systemctl start --no-block hello-after-sleep.target
# hello.service should still be waiting, so these try-restarts will collapse
# into NOPs.
systemctl try-restart --job-mode=fail hello.service
systemctl try-restart hello.service
systemctl stop hello.service sleep.service hello-after-sleep.target
# TODO: add more job queueing/merging tests here.
# Test that restart propagates to activating units
systemctl -T --no-block start always-activating.service
systemctl list-jobs | grep 'always-activating.service'
ACTIVATING_ID_PRE=$(systemctl show -P InvocationID always-activating.service)
systemctl -T start always-activating.socket # Wait for the socket to come up
systemctl -T restart always-activating.socket
ACTIVATING_ID_POST=$(systemctl show -P InvocationID always-activating.service)
[[ "$ACTIVATING_ID_PRE" != "$ACTIVATING_ID_POST" ]]
# Test for irreversible jobs
systemctl start unstoppable.service
# This is expected to fail with 'job cancelled'
(! systemctl stop unstoppable.service)
# But this should succeed
systemctl stop --job-mode=replace-irreversibly unstoppable.service
# We're going to shutdown soon. Let's see if it succeeds when
# there's an active service that tries to be unstoppable.
# Shutdown of the container/VM will hang if not.
systemctl start unstoppable.service
# Test waiting for a started units to terminate again
cat <<EOF >/run/systemd/system/wait2.service
[Unit]
Description=Wait for 2 seconds
[Service]
ExecStart=bash -ec 'sleep 2'
EOF
cat <<EOF >/run/systemd/system/wait5fail.service
[Unit]
Description=Wait for 5 seconds and fail
[Service]
ExecStart=bash -ec 'sleep 5; false'
EOF
# wait2 succeeds
START_SEC=$(date -u '+%s')
timeout 10 systemctl start --wait wait2.service
END_SEC=$(date -u '+%s')
ELAPSED=$((END_SEC-START_SEC))
[[ "$ELAPSED" -ge 2 ]]
# wait5fail fails, so systemctl should fail
START_SEC=$(date -u '+%s')
(! systemctl start --wait wait2.service wait5fail.service)
END_SEC=$(date -u '+%s')
ELAPSED=$((END_SEC-START_SEC))
[[ "$ELAPSED" -ge 5 ]]
# Test time-limited scopes
START_SEC=$(date -u '+%s')
set +e
systemd-run --scope --property=RuntimeMaxSec=3s sleep 30
RESULT=$?
END_SEC=$(date -u '+%s')
ELAPSED=$((END_SEC-START_SEC))
[[ "$ELAPSED" -ge 3 ]]
[[ "$ELAPSED" -le 10 ]]
[[ "$RESULT" -ne 0 ]]
# Test transactions with cycles
# Provides coverage for issues like https://github.com/systemd/systemd/issues/26872
for i in {0..19}; do
cat >"/run/systemd/system/transaction-cycle$i.service" <<EOF
[Unit]
After=transaction-cycle$(((i + 1) % 20)).service
Requires=transaction-cycle$(((i + 1) % 20)).service
[Service]
ExecStart=true
EOF
done
systemctl daemon-reload
for i in {0..19}; do
systemctl start "transaction-cycle$i.service"
done
IDS_FILE="/tmp/TEST-03-JOBS-CYCLE-IDS-$RANDOM"
varlinkctl call /run/systemd/io.systemd.Manager io.systemd.Manager.Describe '{}' | jq '.runtime.TransactionsWithOrderingCycle' >"$IDS_FILE"
[[ "$(jq length "$IDS_FILE")" -ge 20 ]]
for i in {0..19}; do
journalctl -b TRANSACTION_ID="$(jq -r ".[$i]" "$IDS_FILE")" --grep "cycle starting with"
done
# Test PropagatesStopTo= when restart (issue #26839)
systemctl start propagatestopto-and-pullin.target
systemctl --quiet is-active propagatestopto-and-pullin.target
systemctl restart propagatestopto-and-pullin.target
systemctl --quiet is-active propagatestopto-and-pullin.target
systemctl --quiet is-active sleep-infinity-simple.service
systemctl start propagatestopto-only.target
systemctl --quiet is-active propagatestopto-only.target
systemctl --quiet is-active sleep-infinity-simple.service
systemctl restart propagatestopto-only.target
assert_rc 3 systemctl --quiet is-active sleep-infinity-simple.service
systemctl start propagatesstopto-indirect.target propagatestopto-and-pullin.target
systemctl --quiet is-active propagatestopto-indirect.target
systemctl --quiet is-active propagatestopto-and-pullin.target
systemctl restart propagatestopto-indirect.target
assert_rc 3 systemctl --quiet is-active propagatestopto-and-pullin.target
assert_rc 3 systemctl --quiet is-active sleep-infinity-simple.service
# Test restart mode direct
systemctl start succeeds-on-restart-restartdirect.target
assert_rc 0 systemctl --quiet is-active succeeds-on-restart-restartdirect.target
systemctl start fails-on-restart-restartdirect.target || :
assert_rc 3 systemctl --quiet is-active fails-on-restart-restartdirect.target
systemctl start succeeds-on-restart.target || :
assert_rc 3 systemctl --quiet is-active succeeds-on-restart.target
systemctl start fails-on-restart.target || :
assert_rc 3 systemctl --quiet is-active fails-on-restart.target
COUNTER_FILE=/tmp/test-03-restart-counter
export FAILURE_FLAG_FILE=/tmp/test-03-restart-failure-flag
assert_rc 3 systemctl --quiet is-active sleep-infinity-restart-normal.service
assert_rc 3 systemctl --quiet is-active sleep-infinity-restart-direct.service
assert_rc 3 systemctl --quiet is-active counter.service
echo 0 >"$COUNTER_FILE"
systemctl start counter.service
assert_eq "$(cat "$COUNTER_FILE")" "1"
systemctl --quiet is-active sleep-infinity-restart-normal.service
systemctl --quiet is-active sleep-infinity-restart-direct.service
systemctl --quiet is-active counter.service
systemctl kill --signal=KILL sleep-infinity-restart-direct.service
systemctl --quiet is-active counter.service
assert_eq "$(cat "$COUNTER_FILE")" "1"
[[ ! -f "$FAILURE_FLAG_FILE" ]]
systemctl kill --signal=KILL sleep-infinity-restart-normal.service
timeout 10 bash -c 'while [[ ! -f $FAILURE_FLAG_FILE ]]; do sleep .5; done'
timeout 10 bash -c 'while ! systemctl --quiet is-active counter.service; do sleep .5; done'
assert_eq "$(cat "$COUNTER_FILE")" "2"
# Test shortcutting auto restart
export UNIT_NAME="TEST-03-JOBS-shortcut-restart.service"
TMP_FILE="/tmp/test-03-shortcut-restart-test$RANDOM"
cat >"/run/systemd/system/$UNIT_NAME" <<EOF
[Service]
Type=oneshot
ExecStart=rm -v "$TMP_FILE"
Restart=on-failure
RestartSec=1d
RemainAfterExit=yes
EOF
(! systemctl start "$UNIT_NAME")
timeout 10 bash -c 'while [[ "$(systemctl show "$UNIT_NAME" -P SubState)" != "auto-restart" ]]; do sleep .5; done'
touch "$TMP_FILE"
assert_eq "$(systemctl show "$UNIT_NAME" -P SubState)" "auto-restart"
timeout 30 systemctl start "$UNIT_NAME"
systemctl --quiet is-active "$UNIT_NAME"
assert_eq "$(systemctl show "$UNIT_NAME" -P NRestarts)" "1"
[[ ! -f "$TMP_FILE" ]]
rm /run/systemd/system/"$UNIT_NAME"
touch /testok
|