feat: add institutional governance and recovery contracts

This commit is contained in:
2026-08-01 17:46:54 +02:00
parent b65b48832b
commit 7192d32e65
61 changed files with 12539 additions and 168 deletions
+58
View File
@@ -0,0 +1,58 @@
from __future__ import annotations
from datetime import datetime, timezone
import subprocess
from govoplan_core.commands import fenced_run
from govoplan_core.core.runtime_coordination import LeaseClaim
class _IgnoringProcess:
def __init__(self) -> None:
self.terminated = False
self.killed = False
self.wait_count = 0
def poll(self):
return None if not self.killed else -9
def terminate(self) -> None:
self.terminated = True
def kill(self) -> None:
self.killed = True
def wait(self, *, timeout: float):
self.wait_count += 1
if not self.killed:
raise subprocess.TimeoutExpired("command", timeout)
return -9
def test_fenced_process_is_killed_when_it_ignores_termination() -> None:
process = _IgnoringProcess()
fenced_run._terminate_process(process, timeout_seconds=0.01)
assert process.terminated is True
assert process.killed is True
assert process.wait_count == 2
def test_lease_release_is_best_effort_after_database_loss(monkeypatch) -> None:
claim = LeaseClaim(
installation_id="installation-1",
resource_key="scheduler",
holder_node_id="scheduler-1",
holder_incarnation="incarnation-1",
fencing_token=1,
expires_at=datetime(2026, 8, 1, 12, 0, tzinfo=timezone.utc),
)
monkeypatch.setattr(
fenced_run,
"get_database",
lambda: (_ for _ in ()).throw(RuntimeError("database unavailable")),
)
fenced_run._release(claim)