178 lines
6.3 KiB
Python
178 lines
6.3 KiB
Python
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()
|