From 2b81535f74e738d79f399d025c6654e7cac945ed Mon Sep 17 00:00:00 2001 From: Frantisek Sumsal Date: Tue, 11 Aug 2026 12:40:53 +0200 Subject: [PATCH 1/4] test: fix typo in test unit Follow-up for bf3dfa62021db45e8b3c6e301659f9a51deb31cd. --- test/units/TEST-03-JOBS.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/units/TEST-03-JOBS.sh b/test/units/TEST-03-JOBS.sh index 67fe117fc8..d332606ae2 100755 --- a/test/units/TEST-03-JOBS.sh +++ b/test/units/TEST-03-JOBS.sh @@ -146,7 +146,7 @@ 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 start propagatestopto-indirect.target propagatestopto-and-pullin.target systemctl --quiet is-active propagatestopto-indirect.target systemctl --quiet is-active propagatestopto-and-pullin.target From 2c4e86c290689a57687bada20234e4db8de1f994 Mon Sep 17 00:00:00 2001 From: Frantisek Sumsal Date: Tue, 11 Aug 2026 14:06:54 +0200 Subject: [PATCH 2/4] test: fix & enhance test for RestartMode= Stay `set +e` in the test masked that this test has apparently never worked in the first place: when a unit is killed with a signal, any bound unit is stopped retroactively via retroactively_stop_dependencies() but it's not restarted again, as the restart for the bound unit is queued as TRY_RESTART in a following transaction - but at this point the bound unit is already inactive, so the TRY_RESTART job collapses into a NOP. Let's account for this and also add a couple of test cases for RestartMode= with an explicit restart, which should trigger the bound unit as well (assuming it's active). Follow-up for 9b42c58a2b0f0703ff48cd8e8b37eee1a36c1887. --- test/units/TEST-03-JOBS.sh | 32 +++++++++++++++++++++++++------- 1 file changed, 25 insertions(+), 7 deletions(-) diff --git a/test/units/TEST-03-JOBS.sh b/test/units/TEST-03-JOBS.sh index d332606ae2..cecd35fa26 100755 --- a/test/units/TEST-03-JOBS.sh +++ b/test/units/TEST-03-JOBS.sh @@ -175,6 +175,7 @@ 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" +rm -f "$FAILURE_FLAG_FILE" systemctl start counter.service assert_eq "$(cat "$COUNTER_FILE")" "1" @@ -182,15 +183,32 @@ 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' +# RestartMode=direct + restart: explicit restart should get propagated as TRY_RESTART to the still active +# counter.service +systemctl restart sleep-infinity-restart-direct.service timeout 10 bash -c 'while ! systemctl --quiet is-active counter.service; do sleep .5; done' assert_eq "$(cat "$COUNTER_FILE")" "2" +[[ ! -f "$FAILURE_FLAG_FILE" ]] + +# RestartMode=direct + kill: the fail/inactive state shouldn't get propagated to the counter.service +systemctl kill --signal=KILL sleep-infinity-restart-direct.service +systemctl --quiet is-active counter.service +assert_eq "$(cat "$COUNTER_FILE")" "2" +[[ ! -f "$FAILURE_FLAG_FILE" ]] + +# RestartMode=normal + restart: explicit restart should get propagated as TRY_RESTART to the still active +# counter.service +systemctl restart sleep-infinity-restart-normal.service +timeout 10 bash -c 'while ! systemctl --quiet is-active counter.service; do sleep .5; done' +assert_eq "$(cat "$COUNTER_FILE")" "3" +[[ ! -f "$FAILURE_FLAG_FILE" ]] + +# RestartMode=normal + kill: the fail/inactive state should get propagated to the counter.service, which in +# turn should be stopped +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")" "3" # Test shortcutting auto restart From 143c2845676fa5838ac4abf6b6fb9de80e12915e Mon Sep 17 00:00:00 2001 From: Frantisek Sumsal Date: Tue, 11 Aug 2026 14:18:32 +0200 Subject: [PATCH 3/4] test: drop forgotten `set +e` This was introduced all the way back in 2019 where this particular test case was the last one in the file, so it worked as intended. Unfortunately, since then we added new tests after this one, which means this particular `set +e` masked fails in any of them (except for assert_*() calls, which call exit on fail). --- test/units/TEST-03-JOBS.sh | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/test/units/TEST-03-JOBS.sh b/test/units/TEST-03-JOBS.sh index cecd35fa26..fec48da0f8 100755 --- a/test/units/TEST-03-JOBS.sh +++ b/test/units/TEST-03-JOBS.sh @@ -98,14 +98,11 @@ ELAPSED=$((END_SEC-START_SEC)) # Test time-limited scopes START_SEC=$(date -u '+%s') -set +e -systemd-run --scope --property=RuntimeMaxSec=3s sleep 30 -RESULT=$? +(! systemd-run --scope --property=RuntimeMaxSec=3s sleep 30) 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 @@ -121,7 +118,9 @@ EOF done systemctl daemon-reload for i in {0..19}; do - systemctl start "transaction-cycle$i.service" + # This intentionally fails with: + # Failed to start transaction-cycle0.service: Transaction order is cyclic. See system logs for details. + systemctl start "transaction-cycle$i.service" || : done IDS_FILE="/tmp/TEST-03-JOBS-CYCLE-IDS-$RANDOM" @@ -168,6 +167,8 @@ 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 +systemctl stop fails-on-restart.service + COUNTER_FILE=/tmp/test-03-restart-counter export FAILURE_FLAG_FILE=/tmp/test-03-restart-failure-flag From ed0727fecd958abf8e10c702cc25c71bb08cf227 Mon Sep 17 00:00:00 2001 From: Frantisek Sumsal Date: Tue, 11 Aug 2026 15:57:34 +0200 Subject: [PATCH 4/4] test: sync the journal before checking it for ordering cycle messages MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Otherwise we might get an empty match: TEST-03-JOBS.sh[100]: + IDS_FILE=/tmp/TEST-03-JOBS-CYCLE-IDS-30241 TEST-03-JOBS.sh[314]: + varlinkctl call /run/systemd/io.systemd.Manager io.systemd.Manager.Describe '{}' TEST-03-JOBS.sh[315]: + jq .runtime.TransactionsWithOrderingCycle TEST-03-JOBS.sh[316]: ++ jq length /tmp/TEST-03-JOBS-CYCLE-IDS-30241 TEST-03-JOBS.sh[100]: + [[ 20 -ge 20 ]] TEST-03-JOBS.sh[100]: + for i in {0..19} TEST-03-JOBS.sh[317]: ++ jq -r '.[0]' /tmp/TEST-03-JOBS-CYCLE-IDS-30241 TEST-03-JOBS.sh[100]: + journalctl -b TRANSACTION_ID=48 --grep 'cycle starting with' TEST-03-JOBS.sh[318]: -- No entries -- [FAILED] Failed to start TEST-03-JOBS.service - TEST-03-JOBS. [ !! ] Exiting: unit TEST-03-JOBS.service failed Even though the message was properly emitted: $ journalctl --file TEST-03-JOBS-1.journal -b TRANSACTION_ID=48 --grep 'cycle starting with' Aug 11 14:46:15 H systemd[1]: [🡕] transaction-cycle17.service: Unable to break cycle starting with transaction-cycle17.service/start --- test/units/TEST-03-JOBS.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/test/units/TEST-03-JOBS.sh b/test/units/TEST-03-JOBS.sh index fec48da0f8..50089c1965 100755 --- a/test/units/TEST-03-JOBS.sh +++ b/test/units/TEST-03-JOBS.sh @@ -126,6 +126,7 @@ 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 ]] +journalctl --sync for i in {0..19}; do journalctl -b TRANSACTION_ID="$(jq -r ".[$i]" "$IDS_FILE")" --grep "cycle starting with" done