fix(release): fail closed on dashboard parse errors
This commit is contained in:
177
tests/test_release_dashboard_diagnostics.py
Normal file
177
tests/test_release_dashboard_diagnostics.py
Normal file
@@ -0,0 +1,177 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import subprocess
|
||||
import sys
|
||||
import tempfile
|
||||
import unittest
|
||||
from pathlib import Path
|
||||
|
||||
from fastapi.testclient import TestClient
|
||||
|
||||
|
||||
META_ROOT = Path(__file__).resolve().parents[1]
|
||||
RELEASE_ROOT = META_ROOT / "tools" / "release"
|
||||
if str(RELEASE_ROOT) not in sys.path:
|
||||
sys.path.insert(0, str(RELEASE_ROOT))
|
||||
|
||||
from server.app import create_app # noqa: E402
|
||||
|
||||
|
||||
class ReleaseDashboardDiagnosticsTests(unittest.TestCase):
|
||||
def test_malformed_core_version_is_bounded_and_blocks_api_plans(self) -> None:
|
||||
with tempfile.TemporaryDirectory() as temp_dir:
|
||||
workspace = Path(temp_dir)
|
||||
core = workspace / "govoplan-core"
|
||||
core.mkdir()
|
||||
(core / "pyproject.toml").write_text("[project\n", encoding="utf-8")
|
||||
|
||||
with TestClient(create_app(workspace_root=workspace)) as client:
|
||||
dashboard_response = client.get(
|
||||
"/api/dashboard", params={"public_catalog": "false"}
|
||||
)
|
||||
selective_response = client.get(
|
||||
"/api/selective-plan",
|
||||
params={
|
||||
"repos": "govoplan-core",
|
||||
"repo_versions": "govoplan-core:1.2.4",
|
||||
"public_catalog": "false",
|
||||
},
|
||||
)
|
||||
full_plan_response = client.get(
|
||||
"/api/plan", params={"public_catalog": "false"}
|
||||
)
|
||||
|
||||
self.assertEqual(200, dashboard_response.status_code)
|
||||
dashboard = dashboard_response.json()
|
||||
self.assertEqual("blocked", dashboard["summary"]["status"])
|
||||
error = next(
|
||||
item
|
||||
for item in dashboard["collection_errors"]
|
||||
if item["code"] == "core_version_metadata_unreadable"
|
||||
)
|
||||
self.assertEqual("govoplan-core/pyproject.toml", error["source"])
|
||||
self.assertIn("TOMLDecodeError", error["message"])
|
||||
self.assertIn("Repair govoplan-core/pyproject.toml", error["remediation"])
|
||||
self.assertLess(len(error["message"]), 200)
|
||||
self.assertNotIn(str(workspace), error["message"])
|
||||
|
||||
self.assertEqual(200, selective_response.status_code)
|
||||
selective_plan = selective_response.json()
|
||||
self.assertEqual("blocked", selective_plan["status"])
|
||||
self.assertFalse(selective_plan["source_preflight_ready"])
|
||||
finding = next(
|
||||
item
|
||||
for item in selective_plan["gate_findings"]
|
||||
if item["code"] == "core_version_metadata_unreadable"
|
||||
)
|
||||
self.assertEqual(error["remediation"], finding["remediation"])
|
||||
self.assertEqual(
|
||||
"resolve_release_gate", selective_plan["recommended_action"]["id"]
|
||||
)
|
||||
|
||||
self.assertEqual(200, full_plan_response.status_code)
|
||||
full_plan = full_plan_response.json()
|
||||
self.assertEqual("blocked", full_plan["status"])
|
||||
self.assertTrue(
|
||||
any(
|
||||
action["id"].startswith("dashboard:core_version_metadata_unreadable:")
|
||||
for action in full_plan["actions"]
|
||||
)
|
||||
)
|
||||
|
||||
def test_malformed_manifest_is_not_silently_omitted_from_selected_plan(
|
||||
self,
|
||||
) -> None:
|
||||
with tempfile.TemporaryDirectory() as temp_dir:
|
||||
workspace = Path(temp_dir)
|
||||
core = workspace / "govoplan-core"
|
||||
core.mkdir()
|
||||
(core / "pyproject.toml").write_text(
|
||||
'[project]\nname = "govoplan-core"\nversion = "0.1.13"\n',
|
||||
encoding="utf-8",
|
||||
)
|
||||
files = workspace / "govoplan-files"
|
||||
manifest = files / "src" / "govoplan_files" / "backend" / "manifest.py"
|
||||
manifest.parent.mkdir(parents=True)
|
||||
(files / "pyproject.toml").write_text(
|
||||
'[project]\nname = "govoplan-files"\nversion = "1.2.4"\n',
|
||||
encoding="utf-8",
|
||||
)
|
||||
manifest.write_text("def broken(:\n", encoding="utf-8")
|
||||
initialize_repository(files)
|
||||
|
||||
with TestClient(create_app(workspace_root=workspace)) as client:
|
||||
dashboard_response = client.get(
|
||||
"/api/dashboard", params={"public_catalog": "false"}
|
||||
)
|
||||
selective_response = client.get(
|
||||
"/api/selective-plan",
|
||||
params={
|
||||
"repos": "govoplan-files",
|
||||
"repo_versions": "govoplan-files:1.2.4",
|
||||
"public_catalog": "false",
|
||||
},
|
||||
)
|
||||
|
||||
self.assertEqual(200, dashboard_response.status_code)
|
||||
dashboard = dashboard_response.json()
|
||||
error = next(
|
||||
item
|
||||
for item in dashboard["collection_errors"]
|
||||
if item["code"] == "module_contract_unreadable"
|
||||
)
|
||||
self.assertEqual("govoplan-files", error["repo"])
|
||||
self.assertEqual(
|
||||
"govoplan-files/src/govoplan_files/backend/manifest.py",
|
||||
error["source"],
|
||||
)
|
||||
self.assertIn("SyntaxError", error["message"])
|
||||
self.assertIn("Repair the manifest", error["remediation"])
|
||||
|
||||
self.assertEqual(200, selective_response.status_code)
|
||||
plan = selective_response.json()
|
||||
self.assertEqual("blocked", plan["status"])
|
||||
self.assertFalse(plan["source_preflight_ready"])
|
||||
self.assertIn(
|
||||
"module_contract_unreadable",
|
||||
{finding["code"] for finding in plan["gate_findings"]},
|
||||
)
|
||||
self.assertEqual("resolve_release_gate", plan["recommended_action"]["id"])
|
||||
|
||||
|
||||
def initialize_repository(path: Path) -> None:
|
||||
subprocess.run(
|
||||
["git", "init", "--initial-branch=main", str(path)],
|
||||
check=True,
|
||||
stdout=subprocess.DEVNULL,
|
||||
stderr=subprocess.DEVNULL,
|
||||
)
|
||||
subprocess.run(
|
||||
["git", "-C", str(path), "add", "."],
|
||||
check=True,
|
||||
stdout=subprocess.DEVNULL,
|
||||
stderr=subprocess.DEVNULL,
|
||||
)
|
||||
subprocess.run(
|
||||
[
|
||||
"git",
|
||||
"-C",
|
||||
str(path),
|
||||
"-c",
|
||||
"user.name=Release Test",
|
||||
"-c",
|
||||
"user.email=release@example.invalid",
|
||||
"-c",
|
||||
"commit.gpgsign=false",
|
||||
"commit",
|
||||
"-m",
|
||||
"Initial fixture",
|
||||
],
|
||||
check=True,
|
||||
stdout=subprocess.DEVNULL,
|
||||
stderr=subprocess.DEVNULL,
|
||||
)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
Reference in New Issue
Block a user