feat: add repository mesh reconciliation round

This commit is contained in:
2026-04-30 10:50:07 -03:00
parent 3d2748adf5
commit b79fdce99d
113 changed files with 81555 additions and 22807 deletions

View File

@@ -0,0 +1,162 @@
from __future__ import annotations
import json
import os
import unittest
from datetime import datetime, timezone
from pathlib import Path
from mais_humana.repository_mesh import MeshEnvironment, MeshEnvironmentKind, RepositoryTarget, build_mesh_report
from mais_humana.repository_mesh_reconciliation import build_reconciliation_plan
from mais_humana.repository_mesh_runtime import (
RuntimeCommandStatus,
RuntimeLockStatus,
acquire_lock,
build_runtime_cycle,
commands_from_report_and_plan,
cron_scheduler_spec,
lock_is_stale,
release_lock,
runtime_csv,
runtime_jsonl,
runtime_markdown,
scheduler_markdown,
scheduler_payload,
windows_scheduler_spec,
write_runtime_artifacts,
)
from tests.helpers import make_tmp
from tests.test_repository_mesh import FakeGit, make_repo
def target() -> RepositoryTarget:
return RepositoryTarget("alpha", "admin/alpha", "alpha", "01_alpha")
def env(root: Path) -> MeshEnvironment:
return MeshEnvironment("primary", MeshEnvironmentKind.WINDOWS_PRIMARY, str(root), "test")
def clean_report(root: Path):
repo = make_repo(root, "alpha")
fake = FakeGit()
fake.set_repo(repo, remote="https://git.ami.app.br/admin/alpha.git")
return build_mesh_report(root, targets=(target(),), environments=(env(root),), runner=fake)
class RepositoryMeshRuntimeTests(unittest.TestCase):
def test_lock_acquire_busy_release_cycle(self) -> None:
tmp = make_tmp()
lock_path = tmp / "mesh.lock.json"
first = acquire_lock(lock_path, owner="one", expires_after_seconds=600)
self.assertEqual(first.status, RuntimeLockStatus.ACQUIRED)
second = acquire_lock(lock_path, owner="two", expires_after_seconds=600)
self.assertEqual(second.status, RuntimeLockStatus.BUSY)
released = release_lock(first)
self.assertEqual(released.status, RuntimeLockStatus.RELEASED)
third = acquire_lock(lock_path, owner="three", expires_after_seconds=600)
self.assertEqual(third.status, RuntimeLockStatus.ACQUIRED)
release_lock(third)
def test_lock_stale_detection_accepts_malformed_payload_as_recoverable(self) -> None:
self.assertTrue(lock_is_stale({"createdAt": "bad", "expiresAfterSeconds": 600}))
self.assertTrue(lock_is_stale({"createdAt": "2026-01-01T00:00:00+00:00", "expiresAfterSeconds": 0}))
self.assertTrue(
lock_is_stale(
{
"createdAt": datetime.now(timezone.utc).isoformat(),
"expiresAfterSeconds": 600,
"pid": 99999999 if os.name == "nt" else 999999,
}
)
)
def test_commands_from_clean_report_allow_only_safe_fetch_like_commands(self) -> None:
tmp = make_tmp()
report = clean_report(tmp)
plan = build_reconciliation_plan(report)
commands = commands_from_report_and_plan(report, plan)
self.assertTrue(commands)
self.assertTrue(any(command.status == RuntimeCommandStatus.ALLOWED for command in commands))
self.assertFalse(any("reset" in command.command for command in commands))
def test_dirty_report_blocks_runtime_commands(self) -> None:
tmp = make_tmp()
repo = make_repo(tmp, "alpha")
fake = FakeGit()
fake.set_repo(repo, remote="https://git.ami.app.br/admin/alpha.git", status=(" M README.md",))
report = build_mesh_report(tmp, targets=(target(),), environments=(env(tmp),), runner=fake)
plan = build_reconciliation_plan(report)
commands = commands_from_report_and_plan(report, plan)
self.assertTrue(any(command.status == RuntimeCommandStatus.BLOCKED for command in commands))
self.assertTrue(any("destrutivo" in " ".join(command.blocked_reasons) or "manual" in " ".join(command.blocked_reasons) for command in commands))
def test_runtime_cycle_blocks_everything_when_lock_not_acquired(self) -> None:
tmp = make_tmp()
report = clean_report(tmp)
plan = build_reconciliation_plan(report)
first = acquire_lock(tmp / "lock.json", owner="one")
busy = acquire_lock(tmp / "lock.json", owner="two")
cycle = build_runtime_cycle(report, plan, lock=busy)
self.assertEqual(cycle.lock.status, RuntimeLockStatus.BUSY)
self.assertTrue(all(result.status == RuntimeCommandStatus.BLOCKED for result in cycle.results))
release_lock(first)
def test_runtime_outputs_csv_jsonl_and_markdown(self) -> None:
tmp = make_tmp()
report = clean_report(tmp)
plan = build_reconciliation_plan(report)
lock = acquire_lock(tmp / "lock.json", owner="one")
cycle = build_runtime_cycle(report, plan, lock=lock)
self.assertIn("command_id,target_name,status", runtime_csv(cycle))
self.assertIn("Repository Mesh Runtime Cycle", runtime_markdown(cycle))
first_line = runtime_jsonl(cycle).splitlines()[0]
self.assertIn("command", json.loads(first_line))
release_lock(lock)
def test_scheduler_specs_include_five_minute_commands(self) -> None:
tmp = make_tmp()
win = windows_scheduler_spec(
python_exe="python.exe",
project_root=tmp,
ecosystem_root=tmp / "eco",
central_platform_folder=tmp / "central",
)
cron = cron_scheduler_spec(
python_exe="python",
project_root=tmp,
ecosystem_root=tmp / "eco",
central_platform_folder=tmp / "central",
)
payload = scheduler_payload((win, cron))
md = scheduler_markdown((win, cron))
self.assertIn("windows_task", payload["kinds"])
self.assertIn("cron", payload["kinds"])
self.assertIn("New-ScheduledTaskAction", md)
self.assertIn("crontab", md)
def test_write_runtime_artifacts_records_project_and_central_files(self) -> None:
tmp = make_tmp()
project = tmp / "project"
central = tmp / "central"
project.mkdir()
central.mkdir()
report = clean_report(tmp / "eco")
plan = build_reconciliation_plan(report)
lock = acquire_lock(project / "dados" / "lock.json", owner="one")
cycle = build_runtime_cycle(report, plan, lock=lock)
specs = (
windows_scheduler_spec(python_exe="python.exe", project_root=project, ecosystem_root=tmp / "eco", central_platform_folder=central),
cron_scheduler_spec(python_exe="python", project_root=project, ecosystem_root=tmp / "eco", central_platform_folder=central),
)
records = write_runtime_artifacts(cycle, specs, project, central_platform_folder=central)
self.assertTrue((project / "dados" / "repository-mesh-runtime-cycle.json").exists())
self.assertTrue((project / "dados" / "repository-mesh-runtime.jsonl").exists())
self.assertTrue((project / "ecossistema" / "REPOSITORY-MESH-SCHEDULERS.md").exists())
self.assertTrue((central / "reports" / "EXECUTADO__repository-mesh-runtime.md").exists())
self.assertGreaterEqual(len(records), 6)
release_lock(lock)
if __name__ == "__main__":
unittest.main()