Phase 12.J.E.5 — healthcheck retries env-var override (Rule 8)
Summary
Production hardening + CI speedup. Adds SQUID_TARGET_WINDOWS_TENTACLE_HEALTHCHECK_RETRIES env-var override following the established Rule 8 pattern (e.g. SQUID_TARGET_WINDOWS_TENTACLE_DOWNLOAD_BASE_URL).
Operator value
Deployments with slow-starting agents (heavy plugin enumeration, runtime warmup, >60s startup) get false healthcheck didn't respond warnings on every upgrade today. This PR lets such operators set a longer wait window without changing default behaviour for everyone else.
Example: SQUID_TARGET_WINDOWS_TENTACLE_HEALTHCHECK_RETRIES=90 → 90 attempts × 2s = 180s wait.
CI value
J.E.3 + J.E.4 lifecycle E2E tests each spent ~60s in the hardcoded healthcheck wait loop (test service doesn't expose HTTP → every poll 404'd → all 30 retries × 2s elapsed before the .ps1's ::warning:: + proceed path fired). Setting retries=1 in the test render cuts this to ~2s per test.
Expected E1.h drop from 2m2s to ~25s; multi-test suite drops by ~5 min.
Changes
| File | Change |
|---|---|
WindowsTentacleUpgradeStrategy.cs |
public const HealthcheckRetriesEnvVar, internal const DefaultHealthcheckRetries = 30, ResolveHealthcheckRetries() with positive-integer validation + fallback-with-warning, {{HEALTHCHECK_RETRIES}} substitution wired in RenderInnerScript
|
upgrade-windows-tentacle.ps1 |
$HEALTHCHECK_RETRIES variable replaces hardcoded 30; warning message uses dynamic $totalWaitSeconds instead of stale 60s literal |
WindowsTentacleUpgradeStrategyTests.cs |
5 new unit tests + 2 drift detector updates |
TentacleUpgradeLifecycleE2ETests.cs |
E2E renders set HEALTHCHECK_RETRIES=1 to bypass the wait |
Unit tests (5 new)
-
HealthcheckRetriesEnvVar_ConstantNamePinned— Rule 8 pin against silent rename breaking pre-pinned operators -
ResolveHealthcheckRetries_NoEnvVar_ReturnsDefault30— pin the default so a future "tighten / loosen" change surfaces in review -
ResolveHealthcheckRetries_ValidValue_RoundTripsAsInteger(Theory) — 1 / 90 / whitespace-padded / 3600 all parse correctly -
ResolveHealthcheckRetries_InvalidValue_FallsBackToDefault(Theory) — 0 / -1 / non-numeric / float → default-30 with warning (operator-friendly: typo'd env doesn't break upgrades) -
RenderInnerScript_HealthcheckRetriesPlaceholder_SubstitutedFromEnv— end-to-end strategy injection AND asserts stale '60s' literal is gone
Drift detectors updated
-
WindowsTentacleUpgradeStrategyTests.RenderInnerScript_PlaceholderTokens_AppearExactlyOnceInTemplatenow expectsHEALTHCHECK_RETRIES -
TentacleUpgradeLifecycleE2ETests.UpgradeScript_PlaceholderSet_PinnedToProductionContractsame — caught my own miss on first run
Local verification
- 212/212 unit tests pass
- 84/84 cross-platform E2E tests pass
- Will verify on Windows runner that lifecycle suite drops from ~5 min to ~1 min
Foundation for J.E.6
The next phase (rollback logic in .ps1) needs to distinguish "healthcheck slow" (retry warning, proceed) from "service genuinely dead" (rollback). The retries override is the test seam that makes this distinction testable without each E2E sitting 60s in a fixed wait.