mirror of
https://github.com/elder-plinius/OBLITERATUS.git
synced 2026-08-19 01:17:12 +02:00
ci: add conditional environment test gates
This commit is contained in:
@@ -0,0 +1,94 @@
|
||||
"""Tests for conditional policy, runner, and evidence helpers."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import json
|
||||
from pathlib import Path
|
||||
|
||||
from scripts import check_conditional_policy
|
||||
from scripts import conditional_gate_summary
|
||||
from scripts import run_conditional_gate
|
||||
|
||||
|
||||
ROOT = Path(__file__).parents[1]
|
||||
|
||||
|
||||
def test_committed_conditional_policy_is_complete():
|
||||
assert check_conditional_policy.validate(
|
||||
ROOT / "ci" / "conditional-test-policy.json",
|
||||
ROOT / "ci" / "test-quality-policy.json",
|
||||
ROOT / ".github" / "workflows" / "conditional-tests.yml",
|
||||
) == []
|
||||
|
||||
|
||||
def test_policy_rejects_unknown_cpu_exclusion_gate(tmp_path):
|
||||
policy = json.loads((ROOT / "ci" / "conditional-test-policy.json").read_text())
|
||||
quality = {
|
||||
"mature_cpu_scope": {
|
||||
"exclusions": [{"path": "obliteratus/device.py", "conditional_gate": "missing"}]
|
||||
}
|
||||
}
|
||||
policy_path = tmp_path / "policy.json"
|
||||
quality_path = tmp_path / "quality.json"
|
||||
policy_path.write_text(json.dumps(policy))
|
||||
quality_path.write_text(json.dumps(quality))
|
||||
errors = check_conditional_policy.validate(
|
||||
policy_path,
|
||||
quality_path,
|
||||
ROOT / ".github" / "workflows" / "conditional-tests.yml",
|
||||
)
|
||||
assert errors == ["CPU exclusion obliteratus/device.py references unknown gate missing"]
|
||||
|
||||
|
||||
def test_junit_counts_and_report_are_machine_readable(tmp_path):
|
||||
junit = tmp_path / "result.xml"
|
||||
junit.write_text(
|
||||
'<testsuites><testsuite tests="3" failures="1" errors="0" skipped="1"/>'
|
||||
'<testsuite tests="2" failures="0" errors="1" skipped="0"/></testsuites>'
|
||||
)
|
||||
assert run_conditional_gate.counts(junit) == {
|
||||
"tests": 5,
|
||||
"failures": 1,
|
||||
"errors": 1,
|
||||
"skipped": 1,
|
||||
}
|
||||
report = tmp_path / "report.json"
|
||||
run_conditional_gate.write_report(report, "network-services", "passed", counts={"tests": 1})
|
||||
evidence = json.loads(report.read_text())
|
||||
assert evidence["gate"] == "network-services"
|
||||
assert evidence["status"] == "passed"
|
||||
assert evidence["counts"] == {"tests": 1}
|
||||
|
||||
|
||||
def test_remote_prerequisites_are_actionable(monkeypatch):
|
||||
names = {
|
||||
"OBLITERATUS_REMOTE_HOST",
|
||||
"OBLITERATUS_REMOTE_USER",
|
||||
"OBLITERATUS_REMOTE_KEY",
|
||||
"OBLITERATUS_REMOTE_KNOWN_HOSTS",
|
||||
}
|
||||
for name in names:
|
||||
monkeypatch.delenv(name, raising=False)
|
||||
assert set(run_conditional_gate.missing_prerequisites("remote-execution")) == names
|
||||
for name in names:
|
||||
monkeypatch.setenv(name, "fixture")
|
||||
assert run_conditional_gate.missing_prerequisites("remote-execution") == []
|
||||
|
||||
|
||||
def test_summary_rejects_selected_failure_and_marks_unselected_stale():
|
||||
policy = {
|
||||
"gates": [
|
||||
{"id": "first", "job": "shared"},
|
||||
{"id": "second", "job": "shared"},
|
||||
{"id": "optional", "job": "optional"},
|
||||
]
|
||||
}
|
||||
rows, failures = conditional_gate_summary.summarize(
|
||||
policy,
|
||||
{"shared": "failure", "optional": "skipped"},
|
||||
{"shared": True, "optional": False},
|
||||
)
|
||||
assert failures == ["shared: selected but result was failure"]
|
||||
assert rows[0]["status"] == "failure"
|
||||
assert rows[1]["status"] == "failure"
|
||||
assert rows[2]["status"] == "not_selected_no_fresh_evidence"
|
||||
Reference in New Issue
Block a user