Files
ModelForge-Public/.gitea/tests/test_production_deploy_policy.py
T

164 lines
7.2 KiB
Python

"""Fail-closed checks for the production delivery workflow.
This test intentionally uses only the Python standard library so it can run before
project dependencies are installed. The small helpers parse indentation-delimited
YAML blocks that are relevant to the policy; they are not a general YAML parser.
"""
from __future__ import annotations
import re
import subprocess
import unittest
from pathlib import Path
REPOSITORY_ROOT = Path(__file__).resolve().parents[2]
VALIDATION_WORKFLOW = REPOSITORY_ROOT / ".gitea" / "workflows" / "managed-validation.yml"
def _indented_block(text: str, header: str) -> str:
"""Return a YAML block beginning at an exact header line."""
lines = text.splitlines()
try:
start = lines.index(header)
except ValueError as exc:
raise AssertionError(f"Missing YAML header: {header!r}") from exc
indent = len(header) - len(header.lstrip())
end = len(lines)
for index in range(start + 1, len(lines)):
line = lines[index]
if not line.strip() or line.lstrip().startswith("#"):
continue
current_indent = len(line) - len(line.lstrip())
if current_indent <= indent:
end = index
break
return "\n".join(lines[start:end])
def _named_step(text: str, name: str) -> str:
return _indented_block(text, f" - name: {name}")
def _run_script(step: str) -> str:
"""Extract one inline or literal run body without normalizing shell content."""
lines = step.splitlines()
if " run: |" not in lines:
inline = next((line for line in lines if line.startswith(" run: ")), None)
if inline is None:
raise AssertionError("Named step does not contain a run command")
return inline.removeprefix(" run: ") + "\n"
start = lines.index(" run: |") + 1
script_lines = lines[start:]
if any(line and not line.startswith(" ") for line in script_lines):
raise AssertionError("Unexpected indentation in literal run block")
return "\n".join(line[10:] if line else "" for line in script_lines) + "\n"
class ProductionDeployPolicyTests(unittest.TestCase):
@classmethod
def setUpClass(cls) -> None:
cls.validation = VALIDATION_WORKFLOW.read_text(encoding="utf-8")
def test_legacy_production_delivery_workflow_is_retired(self) -> None:
self.assertFalse(
(REPOSITORY_ROOT / ".gitea" / "workflows" / "unraid-deploy.yml").exists()
)
def test_managed_validation_uses_the_shared_validation_pool(self) -> None:
self.assertRegex(self.validation, r"(?m)^\s*runs-on:\s*linux-validation\s*$")
def test_managed_validation_runs_policy_before_profile_work(self) -> None:
policy_step = _named_step(self.validation, "Production delivery policy")
self.assertIn("python3 -m unittest discover -s .gitea/tests", policy_step)
self.assertNotRegex(policy_step, r"(?m)^ if:")
self.assertLess(
self.validation.index(policy_step),
self.validation.index(" - name: Validate the requested profile"),
)
def test_full_validation_uses_a_disposable_managed_postgres_boundary(self) -> None:
job = _indented_block(self.validation, " full:")
boundary = _named_step(self.validation, "Managed PostgreSQL boundary")
cleanup = _named_step(self.validation, "Remove managed PostgreSQL boundary")
for variable in ("VALIDATION_COMPOSE_PROJECT", "MODELFORGE_POSTGRES_PORT"):
self.assertRegex(job, rf"(?m)^ {variable}: .+$")
self.assertIn("modelforge-validation-${{ gitea.run_id }}", job)
self.assertIn('MODELFORGE_POSTGRES_PORT: "0"', job)
self.assertIn("env.PROFILE == 'full'", boundary)
self.assertIn("export MODELFORGE_MIGRATION_DATABASE_URL=", boundary)
self.assertIn("export MODELFORGE_RUNTIME_DATABASE_URL=", boundary)
self.assertIn("up --detach --wait postgres", boundary)
self.assertIn('validation_network="${VALIDATION_COMPOSE_PROJECT}_default"', boundary)
self.assertIn('job_container="$(hostname)"', boundary)
self.assertIn('docker network connect "${validation_network}" "${job_container}"', boundary)
self.assertIn('socket.create_connection(("postgres", 5432)', boundary)
self.assertNotIn("port postgres 5432", boundary)
for variable in (
"MODELFORGE_TEST_POSTGRES_URL",
"MODELFORGE_TEST_POSTGRES_OWNER_URL",
"MODELFORGE_TEST_POSTGRES_RUNTIME_URL",
):
self.assertIn(f'echo "{variable}=', boundary)
self.assertIn('>> "${GITHUB_ENV}"', boundary)
self.assertNotIn("SKIPPED", boundary)
self.assertIn("always() && env.PROFILE == 'full'", cleanup)
self.assertIn("docker network disconnect", cleanup)
self.assertIn('"$(hostname)"', cleanup)
self.assertIn("down --volumes --remove-orphans", cleanup)
self.assertIn("export MODELFORGE_MIGRATION_DATABASE_URL=", cleanup)
self.assertIn("export MODELFORGE_RUNTIME_DATABASE_URL=", cleanup)
def test_full_validation_traverses_the_live_schema_and_tests_the_built_console(self) -> None:
backend = _named_step(self.validation, "Backend — install, lint, typecheck, test")
console = _named_step(self.validation, "Console — install frozen, typecheck, test, build")
boundary = _named_step(self.validation, "Managed PostgreSQL boundary")
self.assertIn('MODELFORGE_MIGRATION_DATABASE_URL="${MODELFORGE_TEST_POSTGRES_OWNER_URL}"', backend)
upgrade_commands = re.findall(
r'"\$\{BACKEND_VENV\}/bin/python" -m alembic ([^\n]+)',
backend,
)
self.assertEqual(
upgrade_commands,
["upgrade head", "downgrade 20260828_0022", "upgrade head"],
)
self.assertLess(self.validation.index(console), self.validation.index(boundary))
self.assertLess(self.validation.index(boundary), self.validation.index(backend))
def test_managed_postgres_shell_blocks_parse(self) -> None:
for name in (
"Managed PostgreSQL boundary",
"Backend — install, lint, typecheck, test",
"Remove managed PostgreSQL boundary",
):
script = _run_script(_named_step(self.validation, name))
result = subprocess.run(
["bash", "-n"],
input=script.encode("utf-8"),
capture_output=True,
check=False,
)
with self.subTest(step=name):
self.assertEqual(result.returncode, 0, result.stderr.decode("utf-8", "replace"))
def test_compose_projection_uses_explicit_non_secret_validation_inputs(self) -> None:
projection = _named_step(self.validation, "Compose projections")
for variable in (
"MODELFORGE_POSTGRES_ADMIN_PASSWORD",
"MODELFORGE_MIGRATION_DB_PASSWORD",
"MODELFORGE_RUNTIME_DB_PASSWORD",
"MODELFORGE_RUNTIME_DATABASE_URL",
"MODELFORGE_MIGRATION_DATABASE_URL",
):
self.assertIn(f"export {variable}=", projection)
self.assertIn("docker compose --env-file .env.example", projection)
if __name__ == "__main__":
unittest.main()