From 3448dc27709d71251fa0bc9561414fc4ffa132e7 Mon Sep 17 00:00:00 2001 From: "pulse-triage[bot]" <249995291+pulse-triage[bot]@users.noreply.github.com> Date: Sun, 11 Oct 2026 13:43:36 +0100 Subject: [PATCH] Align updater discovery and URL fixture handoffs Keep simulated process acceptance explicit in portable discovery and URL controls. Require the running-executable callback to receive the same selected service; refused and prior-inactive URL cases must not invoke it. Actual owned process identity remains covered independently. Change-source: pulse-maintainer Contract-Neutral: Portable fixture adapters and assertions only; no change to production acceptance or deployment contract. --- scripts/installtests/install_sh_test.go | 15 +++++++++++++++ scripts/tests/test_server_service_discovery.py | 14 +++++++++++++- 2 files changed, 28 insertions(+), 1 deletion(-) diff --git a/scripts/installtests/install_sh_test.go b/scripts/installtests/install_sh_test.go index 134a2435b2..2acfad95e3 100644 --- a/scripts/installtests/install_sh_test.go +++ b/scripts/installtests/install_sh_test.go @@ -5474,6 +5474,13 @@ esac `) script := `source "$AUTO_UPDATER" log() { printf '[%s] %s\n' "$1" "${*:2}"; } +# This URL/handoff fixture has script binaries and a simulated manager, +# not a managed process. Record the exact verifier handoff; real owned +# process identity and fail-closed transactions are required separately. +verify_update_running_executable() { + [[ "$1" == pulse-url-fixture ]] || return 97 + printf '%s\n' "$1" >> "$FIXTURE_DIR/process-readback.log" +} # Relocate only the helper's temporary files, keeping creation/mode/cleanup real. mktemp() { local -a args=("$@") @@ -5515,6 +5522,14 @@ fi t.Fatalf("unexpected manager mutation or query: %s\n%s", call, out) } } + processReadback, processErr := os.ReadFile(filepath.Join(tmpDir, "process-readback.log")) + if tc.admitted && tc.state == "active" { + if processErr != nil || string(processReadback) != "pulse-url-fixture\n" { + t.Fatalf("active verifier handoff did not use the selected service: %v\n%s", processErr, processReadback) + } + } else if !os.IsNotExist(processErr) { + t.Fatalf("inactive/refused transaction reached process verification: %v\n%s", processErr, processReadback) + } temporary, err := os.ReadDir(filepath.Join(tmpDir, "tmp")) if err != nil || len(temporary) != 0 { t.Fatalf("unexpected retained temporary/backup files: %v, %v\n%s", temporary, err, out) diff --git a/scripts/tests/test_server_service_discovery.py b/scripts/tests/test_server_service_discovery.py index 86371e9fa7..32728f1bfa 100644 --- a/scripts/tests/test_server_service_discovery.py +++ b/scripts/tests/test_server_service_discovery.py @@ -73,7 +73,16 @@ sys.exit(97) HARNESS = r''' source "$INSTALLER" -if [[ "$PRODUCER" == updater ]]; then source "$UPDATER"; fi +if [[ "$PRODUCER" == updater ]]; then + source "$UPDATER" + # Discovery/handoff uses a manager double and fake script executables, + # not a managed process. Check the callback's selected service here; + # real process identity is mandatory in the separate updater controls. + verify_update_running_executable() { + printf '%s\n' "$1" > "$FIXTURE/process-readback-service" + [[ "$1" == pulse-backend ]] + } +fi print_header() { :; } print_info() { echo "$*" >&2; } print_warn() { echo "$*" >&2; } @@ -234,6 +243,8 @@ class ServiceDiscovery(unittest.TestCase): units=[p.name for p in (f / "units").iterdir()], installer_service=(f / "installer-service").read_text() if (f / "installer-service").exists() else None, + process_readback_service=(f / "process-readback-service").read_text() + if (f / "process-readback-service").exists() else None, broken_pipe=(f / "broken-pipe").exists()) def assert_refused(self, e): @@ -345,6 +356,7 @@ class ServiceDiscovery(unittest.TestCase): e = self.run_fixture(producer="updater", mode="large", flow="automatic") self.assertEqual(e["result"].returncode, 0, e["result"].stderr) self.assertEqual(e["installer_service"], "pulse-backend\n") + self.assertEqual(e["process_readback_service"], "pulse-backend\n") self.assertEqual(e["binary"], e["new"]) self.assertEqual(e["calls"][0], QUERY) self.assertFalse(e["broken_pipe"])