Files
awoooi/apps/api/tests/test_gitea_workflow_runner_health.py
Your Name 943faaeef7
All checks were successful
CD Pipeline / tests (push) Successful in 1m30s
Code Review / ai-code-review (push) Successful in 13s
CD Pipeline / build-and-deploy (push) Successful in 4m2s
CD Pipeline / post-deploy-checks (push) Successful in 1m56s
feat(governance): 新增 Gitea workflow runner 健康合約
2026-06-05 11:30:56 +08:00

250 lines
9.5 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
from __future__ import annotations
import json
import pytest
from src.services.gitea_workflow_runner_health import load_latest_gitea_workflow_runner_health
def test_load_latest_gitea_workflow_runner_health_reads_newest_file(tmp_path):
older = _snapshot(generated_at="2026-06-04T00:00:00+08:00", completion=40)
newer = _snapshot(generated_at="2026-06-05T00:00:00+08:00", completion=100)
(tmp_path / "gitea_workflow_runner_health_2026-06-04.json").write_text(
json.dumps(older),
encoding="utf-8",
)
(tmp_path / "gitea_workflow_runner_health_2026-06-05.json").write_text(
json.dumps(newer),
encoding="utf-8",
)
loaded = load_latest_gitea_workflow_runner_health(tmp_path)
assert loaded["generated_at"] == "2026-06-05T00:00:00+08:00"
assert loaded["program_status"]["overall_completion_percent"] == 100
assert loaded["rollups"]["total_workflows"] == 2
assert loaded["operation_boundaries"]["workflow_modification_allowed"] is False
def test_gitea_workflow_runner_health_requires_read_only_mode(tmp_path):
snapshot = _snapshot()
snapshot["program_status"]["read_only_mode"] = False
(tmp_path / "gitea_workflow_runner_health_2026-06-05.json").write_text(
json.dumps(snapshot),
encoding="utf-8",
)
with pytest.raises(ValueError, match="read_only_mode"):
load_latest_gitea_workflow_runner_health(tmp_path)
def test_gitea_workflow_runner_health_requires_blocked_operations(tmp_path):
snapshot = _snapshot()
snapshot["operation_boundaries"]["runner_restart_allowed"] = True
(tmp_path / "gitea_workflow_runner_health_2026-06-05.json").write_text(
json.dumps(snapshot),
encoding="utf-8",
)
with pytest.raises(ValueError, match="operation boundaries"):
load_latest_gitea_workflow_runner_health(tmp_path)
def test_gitea_workflow_runner_health_requires_rollup_consistency(tmp_path):
snapshot = _snapshot()
snapshot["rollups"]["workflows_with_schedule"] = 99
(tmp_path / "gitea_workflow_runner_health_2026-06-05.json").write_text(
json.dumps(snapshot),
encoding="utf-8",
)
with pytest.raises(ValueError, match="workflows_with_schedule"):
load_latest_gitea_workflow_runner_health(tmp_path)
def test_gitea_workflow_runner_health_requires_quiet_notification_contracts(tmp_path):
snapshot = _snapshot()
snapshot["notification_contracts"][0]["success_noise_policy"] = "always send success"
(tmp_path / "gitea_workflow_runner_health_2026-06-05.json").write_text(
json.dumps(snapshot),
encoding="utf-8",
)
with pytest.raises(ValueError, match="suppress success noise"):
load_latest_gitea_workflow_runner_health(tmp_path)
def test_gitea_workflow_runner_health_rejects_secret_payload_keys(tmp_path):
snapshot = _snapshot()
snapshot["latest_observations"][0]["runner_token"] = "redacted"
(tmp_path / "gitea_workflow_runner_health_2026-06-05.json").write_text(
json.dumps(snapshot),
encoding="utf-8",
)
with pytest.raises(ValueError, match="forbidden secret payload key"):
load_latest_gitea_workflow_runner_health(tmp_path)
def test_gitea_workflow_runner_health_fails_when_missing(tmp_path):
with pytest.raises(FileNotFoundError):
load_latest_gitea_workflow_runner_health(tmp_path)
def _snapshot(
*,
generated_at: str = "2026-06-05T00:00:00+08:00",
completion: int = 100,
) -> dict:
return {
"schema_version": "gitea_workflow_runner_health_v1",
"generated_at": generated_at,
"program_status": {
"overall_completion_percent": completion,
"current_priority": "P1",
"current_task_id": "P1-002",
"next_task_id": "P1-003",
"read_only_mode": True,
},
"source_refs": ["docs/schemas/gitea_workflow_runner_health_v1.schema.json"],
"rollups": {
"total_workflows": 2,
"by_workflow_status": {"manifest_mapped": 2},
"by_runner_evidence_status": {"host_runner_mapped": 1, "owner_attestation_required": 1},
"workflows_with_schedule": 1,
"workflows_with_workflow_dispatch": 1,
"workflows_with_notify_bridge": 1,
"workflows_with_actionable_or_failure_quiet_policy": 1,
"workflow_ids_requiring_runner_attestation": ["e2e_health"],
"total_runner_contracts": 1,
"runner_contracts_requiring_action": ["ubuntu_latest"],
"notification_contracts_total": 2,
"notification_contracts_quiet_success_count": 2,
"notification_contracts_quiet_success_ids": ["actionable_only", "failure_only"],
},
"workflow_records": [
_workflow_record(
"cd_pipeline",
"host_runner_mapped",
["push"],
"deployment_status_exception",
1,
),
_workflow_record(
"e2e_health",
"owner_attestation_required",
["workflow_dispatch", "schedule"],
"failure_only",
0,
),
],
"runner_contracts": [
{
"contract_id": "ubuntu_latest",
"display_name": "ubuntu-latest runner label",
"status": "action_required",
"risk_level": "high",
"runner_labels": ["ubuntu-latest"],
"used_by_workflows": ["e2e_health"],
"health_contract": "只讀確認 runner label 與 recent run freshness。",
"guardrail_refs": ["docs/HARD_RULES.md"],
"evidence_refs": [".gitea/workflows/e2e-health.yaml"],
"next_action": "補 owner attestation不改 runner。",
}
],
"notification_contracts": [
_notification_contract("actionable_only", "actionable_only", "無 actionable 時不通知。"),
_notification_contract("failure_only", "failure_only", "健康成功不通知。"),
],
"latest_observations": [
{
"observation_id": "committed_only",
"status": "verified",
"summary": "只讀 committed workflow。",
"evidence_refs": ["docs/LOGBOOK.md"],
}
],
"operator_contract": {
"display_mode": "read_only_gitea_workflow_runner_health",
"must_not_interpret_as": [
"workflow 修改批准",
"runner restart / stop 批准",
"Secret 已讀取或可輸出",
"Telegram 測試通知批准",
"Gitea write token 授權",
"deploy / migration workflow 觸發批准",
],
"secret_display_policy": "只顯示 redacted metadata。",
"runner_mutation_policy": "不得 restart runner。",
"notification_policy": "成功不洗版。",
},
"operation_boundaries": {
"read_only_api_allowed": True,
"workflow_modification_allowed": False,
"runner_restart_allowed": False,
"runner_container_stop_allowed": False,
"runner_label_change_allowed": False,
"runner_registration_allowed": False,
"secret_read_allowed": False,
"secret_plaintext_allowed": False,
"notification_send_allowed": False,
"schedule_enable_allowed": False,
"gitea_api_write_allowed": False,
"deploy_trigger_allowed": False,
"migration_trigger_allowed": False,
},
"approval_boundaries": {
"workflow_modification_authorized": False,
"runner_mutation_authorized": False,
"notification_send_authorized": False,
"secret_plaintext_allowed": False,
"runtime_execution_authorized": False,
"schedule_change_authorized": False,
"gitea_write_authorized": False,
"deploy_trigger_authorized": False,
"migration_trigger_authorized": False,
},
}
def _workflow_record(
workflow_id: str,
runner_evidence_status: str,
triggers: list[str],
notification_policy: str,
notify_bridge_calls: int,
) -> dict:
return {
"workflow_id": workflow_id,
"file_ref": f".gitea/workflows/{workflow_id}.yaml",
"display_name": workflow_id,
"scope": "只讀 workflow 合約。",
"status": "manifest_mapped",
"risk_level": "medium",
"triggers": triggers,
"schedule_cadence": "每日" if "schedule" in triggers else "無定期排程",
"runner_labels": ["awoooi-host" if runner_evidence_status == "host_runner_mapped" else "ubuntu-latest"],
"runner_evidence_status": runner_evidence_status,
"job_count": 1,
"notification_policy": notification_policy,
"notify_bridge_calls": notify_bridge_calls,
"secrets_policy_status": "不讀 Secret payload。",
"evidence_refs": [f".gitea/workflows/{workflow_id}.yaml"],
"next_action": "只讀補證據。",
}
def _notification_contract(contract_id: str, policy_kind: str, success_noise_policy: str) -> dict:
return {
"contract_id": contract_id,
"display_name": contract_id,
"status": "preserved",
"policy_kind": policy_kind,
"success_noise_policy": success_noise_policy,
"failure_policy": "失敗才升級。",
"workflow_refs": ["e2e_health"],
"evidence_refs": [".gitea/workflows/e2e-health.yaml"],
"next_action": "保留通知政策。",
}