titan-iac/testing/tests/test_repo_structure.py
jenkins 0da9e4c82d refactor: restructure services layout, retire oceanus, add aether scaffolding
- Move flat service manifests into structured subdirs (apps/, bootstrap-jobs/,
  repair-jobs/, migration-jobs/, validation-jobs/, node-ops/, networking/)
- Retire oneoffs/ directories across services
- Remove oceanus cluster and its host roles; add aether cluster + terraform scaffolding
- Reorganize scripts/ into ops/, render/, sync/, manual-tests/
- Add Makefile with render/validate/test/flux targets and repo-structure tests
- Update flux-system application CRs to the new paths
- Add hermes-automated-triage-24h-plan knowledge doc (+ comms mirror)
- Refresh knowledge catalogs, dashboards, vmalert rules, quality contract

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-05 16:21:36 -03:00

127 lines
4.5 KiB
Python

"""Repository structure guardrails for the GitOps control plane."""
from __future__ import annotations
import datetime as dt
import json
import stat
from pathlib import Path
import yaml
REPO_ROOT = Path(__file__).resolve().parents[2]
def _yaml_docs(path: Path) -> list[dict]:
docs = []
for doc in yaml.safe_load_all(path.read_text(encoding="utf-8")):
if isinstance(doc, dict):
docs.append(doc)
return docs
def test_root_jenkinsfile_mirrors_canonical_pipeline() -> None:
"""The root Jenkinsfile exists for discovery, but CI logic lives in ci/."""
root = (REPO_ROOT / "Jenkinsfile").read_text(encoding="utf-8").splitlines()
canonical = (REPO_ROOT / "ci/Jenkinsfile.titan-iac").read_text(
encoding="utf-8"
).splitlines()
if root and root[0].startswith("// Mirror of "):
root = root[1:]
assert root == canonical
def test_suspended_flux_kustomizations_have_reasons() -> None:
"""Suspended reconciliations should say why they are parked."""
missing = []
for path in sorted((REPO_ROOT / "clusters/atlas/flux-system").rglob("*.yaml")):
for doc in _yaml_docs(path):
if doc.get("kind") != "Kustomization":
continue
if not str(doc.get("apiVersion") or "").startswith(
"kustomize.toolkit.fluxcd.io/"
):
continue
spec = doc.get("spec") or {}
if spec.get("suspend") is not True:
continue
annotations = (doc.get("metadata") or {}).get("annotations") or {}
if not annotations.get("atlas.bstein.dev/suspend-reason"):
missing.append(str(path.relative_to(REPO_ROOT)))
assert missing == []
def test_trivy_waiver_targets_still_exist() -> None:
"""Waivers should stay temporary and point at files that still exist."""
path = REPO_ROOT / "ci/titan-iac-trivy-waivers.json"
payload = json.loads(path.read_text(encoding="utf-8"))
expires = dt.date.fromisoformat(payload["default_expires_at"])
assert expires >= dt.date.today()
missing = []
for entry in payload.get("misconfigurations", []):
for target in entry.get("targets", []):
if target and not (REPO_ROOT / target).exists():
missing.append(f"{entry.get('id')}:{target}")
assert missing == []
def test_oceanus_is_not_a_standalone_flux_cluster() -> None:
"""Oceanus now belongs to Atlas capacity, not a separate Flux root."""
assert not (REPO_ROOT / "clusters/oceanus").exists()
assert not (REPO_ROOT / "infrastructure/modules/profiles/oceanus-validator").exists()
def test_service_job_directories_use_lifecycle_names() -> None:
"""Manual job folders should say when they are used."""
old_dirs = list((REPO_ROOT / "services").rglob("oneoffs"))
assert old_dirs == []
stale_refs = []
for root in ["clusters", "services", "ci", "testing"]:
for path in (REPO_ROOT / root).rglob("*"):
if not path.is_file():
continue
if path == Path(__file__).resolve():
continue
if path.suffix not in {".json", ".py", ".yaml", ".yml"}:
continue
if "oneoffs" in path.read_text(encoding="utf-8"):
stale_refs.append(str(path.relative_to(REPO_ROOT)))
assert stale_refs == []
def test_knowledge_service_mirror_matches_source() -> None:
"""Atlasbot should serve the generated knowledge tree, not a fork."""
source = REPO_ROOT / "knowledge"
mirror = REPO_ROOT / "services/comms/knowledge"
source_files = sorted(path.relative_to(source) for path in source.rglob("*") if path.is_file())
mirror_files = sorted(path.relative_to(mirror) for path in mirror.rglob("*") if path.is_file())
assert mirror_files == source_files
mismatched = [
str(rel)
for rel in source_files
if (source / rel).read_bytes() != (mirror / rel).read_bytes()
]
assert mismatched == []
def test_scripts_shell_entrypoints_are_executable_with_shebangs() -> None:
"""Runnable shell and Fish helpers should not need tribal chmod knowledge."""
broken = []
for path in sorted((REPO_ROOT / "scripts").rglob("*")):
if path.suffix not in {".sh", ".fish"} or not path.is_file():
continue
mode = path.stat().st_mode
first_line = path.read_text(encoding="utf-8").splitlines()[0]
if not mode & stat.S_IXUSR or not first_line.startswith("#!"):
broken.append(str(path.relative_to(REPO_ROOT)))
assert broken == []