@@ -570,22 +570,32 @@ EOF
570570 [ " $( cat " $ROOT_DIR /etc/airplanes/feeder-claim-secret.version" ) " = " 7" ]
571571}
572572
573- @test " claim set never invokes systemctl (no daemon consumes the secret)" {
573+ @test " claim set never restarts feeder daemons (no daemon consumes the secret)" {
574574 # The claim secret is consumed only by apl-feed itself, not by
575575 # airplanes-feed or airplanes-mlat. Saving it must not bounce a
576- # working feeder. Use a sentinel stub that fails the test if invoked.
576+ # working feeder. The only permitted systemctl call is the post-write
577+ # stop of airplanes-claim.timer (see test_claim_timer_stop.bats);
578+ # this assertion pins that NOTHING ELSE is touched.
579+ COMMAND_LOG=" $( mktemp) "
577580 cat > " $STUB_BIN_DIR /systemctl" << 'STUB '
578581#!/usr/bin/env bash
579- echo " systemctl invoked with: $*" >&2
580- exit 99
582+ { printf ' systemctl'; for a in "$@"; do printf ' %s' "$a"; done; printf '\n'; } >> "$COMMAND_LOG"
583+ exit 0
581584STUB
582585 chmod +x " $STUB_BIN_DIR /systemctl"
586+ export COMMAND_LOG APL_FEED_TEST_TIMER_STOP_FORCE=1
583587
584588 run env " $SCRIPT " claim set --root " $ROOT_DIR " <<< " ABCDEFGHIJKLMNOP"
585589
586590 [ " $status " -eq 0 ]
587- [[ ! " $output " =~ " systemctl invoked" ]]
588591 [[ ! " $output " =~ " Restarted" ]]
592+ # Every recorded systemctl invocation must be the timer-stop. No
593+ # restart, no reload, no apl-feed daemon touched.
594+ while IFS= read -r line; do
595+ [[ " $line " == " systemctl --no-block stop airplanes-claim.timer" ]] \
596+ || { echo " unexpected systemctl call: $line " >&2 ; false ; }
597+ done < " $COMMAND_LOG "
598+ rm -f " $COMMAND_LOG "
589599}
590600
591601@test " claim set is idempotent when supplied secret already matches local" {
@@ -657,6 +667,93 @@ STUB
657667 [ ! -f " $restart_log " ]
658668}
659669
670+
671+ # --- claim set: post-write timer stop -------------------------------------
672+ #
673+ # Coordinated with the image-side airplanes-claim.timer. Once claim set
674+ # lands the secret on disk, the timer has nothing left to do, and every
675+ # subsequent fire pollutes the service journal with condition-skip lines
676+ # that the webconfig Claim activity panel surfaces.
677+
678+ @test " claim set new-secret write stops airplanes-claim.timer" {
679+ COMMAND_LOG=" $( mktemp) "
680+ cat > " $STUB_BIN_DIR /systemctl" << 'STUB '
681+ #!/usr/bin/env bash
682+ { printf 'systemctl'; for a in "$@"; do printf ' %s' "$a"; done; printf '\n'; } >> "$COMMAND_LOG"
683+ exit 0
684+ STUB
685+ chmod +x " $STUB_BIN_DIR /systemctl"
686+ export COMMAND_LOG APL_FEED_TEST_TIMER_STOP_FORCE=1
687+
688+ run env " $SCRIPT " claim set --root " $ROOT_DIR " <<< " ABCDEFGHIJKLMNOP"
689+
690+ [ " $status " -eq 0 ]
691+ grep -F -- ' --no-block stop airplanes-claim.timer' " $COMMAND_LOG "
692+ rm -f " $COMMAND_LOG "
693+ }
694+
695+ @test " claim set same-canonical-value (idempotent) still stops the timer" {
696+ # The re-normalize path also writes the file (to fix mode / casing), so
697+ # we want the timer-stop here too — keeps the helper invariant simple:
698+ # any successful secret write triggers the stop.
699+ echo " abcd-efgh-ijkl-mnop" > " $ROOT_DIR /etc/airplanes/feeder-claim-secret"
700+ chmod 644 " $ROOT_DIR /etc/airplanes/feeder-claim-secret"
701+ COMMAND_LOG=" $( mktemp) "
702+ cat > " $STUB_BIN_DIR /systemctl" << 'STUB '
703+ #!/usr/bin/env bash
704+ { printf 'systemctl'; for a in "$@"; do printf ' %s' "$a"; done; printf '\n'; } >> "$COMMAND_LOG"
705+ exit 0
706+ STUB
707+ chmod +x " $STUB_BIN_DIR /systemctl"
708+ export COMMAND_LOG APL_FEED_TEST_TIMER_STOP_FORCE=1
709+
710+ run env " $SCRIPT " claim set --root " $ROOT_DIR " <<< " ABCD-EFGH-IJKL-MNOP"
711+
712+ [ " $status " -eq 0 ]
713+ [[ " $output " =~ " already matches" ]]
714+ grep -F -- ' --no-block stop airplanes-claim.timer' " $COMMAND_LOG "
715+ rm -f " $COMMAND_LOG "
716+ }
717+
718+ @test " claim set --dry-run does NOT stop the timer (no secret was written)" {
719+ COMMAND_LOG=" $( mktemp) "
720+ cat > " $STUB_BIN_DIR /systemctl" << 'STUB '
721+ #!/usr/bin/env bash
722+ { printf 'systemctl'; for a in "$@"; do printf ' %s' "$a"; done; printf '\n'; } >> "$COMMAND_LOG"
723+ exit 0
724+ STUB
725+ chmod +x " $STUB_BIN_DIR /systemctl"
726+ export COMMAND_LOG APL_FEED_TEST_TIMER_STOP_FORCE=1
727+
728+ run env " $SCRIPT " claim set --root " $ROOT_DIR " --dry-run <<< " ABCDEFGHIJKLMNOP"
729+
730+ [ " $status " -eq 0 ]
731+ [[ " $output " =~ " dry-run" ]]
732+ [ ! -f " $ROOT_DIR /etc/airplanes/feeder-claim-secret" ]
733+ ! grep -F -- ' stop airplanes-claim.timer' " $COMMAND_LOG "
734+ rm -f " $COMMAND_LOG "
735+ }
736+
737+ @test " claim set refuse-without-force does NOT stop the timer (nothing written)" {
738+ echo " OLDSECRETXYZ1234" > " $ROOT_DIR /etc/airplanes/feeder-claim-secret"
739+ chmod 600 " $ROOT_DIR /etc/airplanes/feeder-claim-secret"
740+ COMMAND_LOG=" $( mktemp) "
741+ cat > " $STUB_BIN_DIR /systemctl" << 'STUB '
742+ #!/usr/bin/env bash
743+ { printf 'systemctl'; for a in "$@"; do printf ' %s' "$a"; done; printf '\n'; } >> "$COMMAND_LOG"
744+ exit 0
745+ STUB
746+ chmod +x " $STUB_BIN_DIR /systemctl"
747+ export COMMAND_LOG APL_FEED_TEST_TIMER_STOP_FORCE=1
748+
749+ run env " $SCRIPT " claim set --root " $ROOT_DIR " <<< " NEWSECRETXYZ5678"
750+
751+ [ " $status " -ne 0 ]
752+ [[ " $output " =~ " different claim secret" ]]
753+ ! grep -F -- ' stop airplanes-claim.timer' " $COMMAND_LOG "
754+ rm -f " $COMMAND_LOG "
755+ }
756+
660757@test " id set writes a new UUID and restarts both daemons feed-first" {
661758 rm -f " $ROOT_DIR /etc/airplanes/feeder-id"
662759 local restart_log=" $ROOT_DIR /restart.log"
0 commit comments