fix(recovery): bound scorecard and align coordinator gates
This commit is contained in:
@@ -92,6 +92,19 @@ def test_coordinator_covers_all_hosts_and_full_recovery_evidence() -> None:
|
||||
assert field in control
|
||||
|
||||
|
||||
def test_host188_hygiene_is_advisory_not_a_recovery_completion_gate() -> None:
|
||||
control = read("agent99-control-plane.ps1")
|
||||
conversion = control.split("function Convert-AgentRecoveryReadback", 1)[1]
|
||||
conversion = conversion.split("function Invoke-AgentRecoveryCoordinatorReadback", 1)[0]
|
||||
|
||||
advisory = conversion.split("$advisoryChecks = @(", 1)[1].split("$checks = @(", 1)[0]
|
||||
mandatory = conversion.split("$checks = @(", 1)[1].split("$sloChecks = @()", 1)[0]
|
||||
assert 'name = "host_188_hygiene_green"' in advisory
|
||||
assert 'name = "host_188_hygiene_green"' not in mandatory
|
||||
assert "advisoryFailedChecks = $advisoryFailedChecks" in conversion
|
||||
assert "verified = [bool]($failedChecks.Count -eq 0)" in conversion
|
||||
|
||||
|
||||
def test_fresh_reboot_claim_requires_fresh_artifact_and_zero_blockers() -> None:
|
||||
control = read("agent99-control-plane.ps1")
|
||||
|
||||
|
||||
@@ -87,7 +87,33 @@ def test_service_uses_deployed_source_root_and_bounded_oneshot() -> None:
|
||||
assert "Environment=TEXTFILE_DIR=/home/wooo/node_exporter_textfiles" in text
|
||||
assert "Environment=LOG_DIR=/home/wooo/reboot-recovery" in text
|
||||
assert "ExecStart=/usr/local/bin/awoooi-reboot-auto-recovery-slo.sh" in text
|
||||
assert "TimeoutStartSec=600" in text
|
||||
assert "TimeoutStartSec=330" in text
|
||||
|
||||
|
||||
def test_service_worst_case_probe_budget_finishes_before_agent99_freshness_window() -> None:
|
||||
text = SERVICE.read_text(encoding="utf-8")
|
||||
|
||||
def environment_seconds(name: str) -> int:
|
||||
match = re.search(rf"^Environment={name}=([0-9]+)$", text, re.MULTILINE)
|
||||
assert match is not None, name
|
||||
return int(match.group(1))
|
||||
|
||||
service_timeout_match = re.search(r"^TimeoutStartSec=([0-9]+)$", text, re.MULTILINE)
|
||||
assert service_timeout_match is not None
|
||||
service_timeout = int(service_timeout_match.group(1))
|
||||
agent99_freshness_wait = 420
|
||||
worst_case_budget = (
|
||||
environment_seconds("AI_LOG_TRIAGE_AUTO_RECOVERY_TIMEOUT_SECONDS")
|
||||
+ environment_seconds("AI_LOG_TRIAGE_AUTO_RECOVERY_POST_APPLY_SETTLE_SECONDS")
|
||||
+ environment_seconds("SSH_COMMAND_TIMEOUT_SECONDS") * 6
|
||||
+ environment_seconds("POST_REBOOT_READINESS_TIMEOUT_SECONDS")
|
||||
+ environment_seconds("STOCK_READBACK_TIMEOUT_SECONDS") * 2
|
||||
+ environment_seconds("PUBLIC_MAINTENANCE_READBACK_TIMEOUT_SECONDS") * 6
|
||||
+ environment_seconds("WINDOWS99_REMOTE_VERIFY_TIMEOUT")
|
||||
)
|
||||
|
||||
assert worst_case_budget <= service_timeout - 30
|
||||
assert service_timeout < agent99_freshness_wait
|
||||
|
||||
|
||||
def test_timer_waits_after_completion_instead_of_running_back_to_back() -> None:
|
||||
@@ -136,7 +162,7 @@ def test_exporter_projects_each_scorecard_blocker_to_textfile_metric() -> None:
|
||||
assert "windows99_vmware_verify_fallback_max_age_seconds" in text
|
||||
assert "find \"$LOG_DIR\" -mindepth 2 -maxdepth 2" in text
|
||||
assert "POST_REBOOT_READINESS_TIMEOUT_SECONDS" in text
|
||||
assert 'POST_REBOOT_READINESS_TIMEOUT_SECONDS="${POST_REBOOT_READINESS_TIMEOUT_SECONDS:-120}"' in text
|
||||
assert 'POST_REBOOT_READINESS_TIMEOUT_SECONDS="${POST_REBOOT_READINESS_TIMEOUT_SECONDS:-60}"' in text
|
||||
assert "POST_REBOOT_SKIP_RUNNER_GUARD=1" in text
|
||||
assert "POST_REBOOT_READINESS_SUMMARY_TIMEOUT=1" in text
|
||||
assert "POST_REBOOT_READINESS_PARTIAL_FROM_POST_START=1" in text
|
||||
|
||||
Reference in New Issue
Block a user