From a51220f2deaced39ab06079de8ebb0bb0d6e0cfb Mon Sep 17 00:00:00 2001 From: nexxo Date: Tue, 4 Aug 2026 17:42:25 +0200 Subject: [PATCH] HostStepTest: Vertragsversion zur Laufzeit vergleichen statt aus Text ziehen MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Seit Task 2 steht in update.sh HOST_STEP_NEEDS="$(release_host_step_needs)" statt einer nackten Zahl. Str::between() zog daraufhin die Kommandoersetzung selbst aus dem Text, (int) davon war 0 — der Test verglich 3 gegen 0 und war rot. Der vorgegebene Filter HostStepContract|... traf HostStepTest.php nicht (falscher Teilstring), deshalb fiel das erst im Review auf. Die rechte Seite des Vergleichs ruft jetzt release_host_step_needs() aus deploy/lib/release.sh tatsächlich per Shell auf (gleiches Muster wie HostStepContractTest), statt sie aus update.sh herauszulesen. Damit kommen beide verglichenen Zahlen aus zwei verschiedenen Dateien (install-agent.sh CONTRACT vs. release.sh release_host_step_needs) und die Kopplung ist wieder erzwungen — verifiziert, indem CONTRACT testweise auf 4 gesetzt wurde und der Test daraufhin rot wurde ("4 is identical to 3"), dann zurückgesetzt. --- tests/Feature/HostStepTest.php | 26 ++++++++++++++++++++++++-- 1 file changed, 24 insertions(+), 2 deletions(-) diff --git a/tests/Feature/HostStepTest.php b/tests/Feature/HostStepTest.php index 5e165c8..ed7019d 100644 --- a/tests/Feature/HostStepTest.php +++ b/tests/Feature/HostStepTest.php @@ -130,9 +130,31 @@ it('reports the contract version the updater compares against', function () { // failure mode this number exists for; if update.sh asked for a version the // current installer never writes, every up-to-date server would be told to // run the installer again forever. - $needs = Str::between(file_get_contents(base_path('deploy/update.sh')), 'HOST_STEP_NEEDS=', "\n"); + // + // Compared at RUNTIME against deploy/lib/release.sh's + // release_host_step_needs(), not by pulling the literal `HOST_STEP_NEEDS=` + // line out of update.sh: since Task 2 update.sh no longer carries the bare + // number itself, it asks that shell function for it — + // `HOST_STEP_NEEDS="$(release_host_step_needs)"`. Extracting the text + // between `HOST_STEP_NEEDS=` and the newline would hand back the command + // substitution string, not a number, and this test would silently compare + // "3" against "0" forever without ever catching the two halves drifting + // apart. The left side (CONTRACT) and the right side (release_host_step_needs) + // come from two different files — install-agent.sh and deploy/lib/release.sh + // — so raising one without the other still turns this test red. + $needsProcess = Process::fromShellCommandline( + 'bash -c '.escapeshellarg( + 'set -Eeuo pipefail; . '.escapeshellarg(base_path('deploy/lib/release.sh')).'; release_host_step_needs' + ) + ); + $needsProcess->run(); - expect((int) trim($process->getOutput()))->toBe((int) trim($needs)); + expect($needsProcess->getExitCode())->toBe(0); + + $needs = trim($needsProcess->getOutput()); + + expect($needs)->toMatch('/^\d+$/') + ->and((int) trim($process->getOutput()))->toBe((int) $needs); }); it('grants one command line, not a script the service account can rewrite', function () {