Add durable external-effect runtime identity
This commit is contained in:
@@ -6,6 +6,8 @@ from types import SimpleNamespace
|
||||
from govoplan_core.core.runtime_coordination import (
|
||||
RuntimeCoordinationError,
|
||||
RuntimeIdentity,
|
||||
bind_process_runtime_identity,
|
||||
process_runtime_identity,
|
||||
)
|
||||
from govoplan_core.server.runtime_agent import RuntimeNodeAgent
|
||||
|
||||
@@ -64,6 +66,32 @@ def test_api_runtime_agent_fails_readiness_on_heartbeat_error() -> None:
|
||||
assert agent.coordination_healthy is True
|
||||
|
||||
|
||||
def test_process_runtime_identity_is_explicit_and_replaceable() -> None:
|
||||
from govoplan_core.core import runtime_coordination
|
||||
|
||||
previous = runtime_coordination._process_runtime_identity
|
||||
identity = RuntimeIdentity(
|
||||
installation_id="installation-1",
|
||||
node_id="api-1",
|
||||
incarnation="incarnation-1",
|
||||
role="api",
|
||||
software_version="0.1.14",
|
||||
composition_hash="a" * 64,
|
||||
)
|
||||
try:
|
||||
bind_process_runtime_identity(None)
|
||||
try:
|
||||
process_runtime_identity()
|
||||
except RuntimeCoordinationError:
|
||||
pass
|
||||
else: # pragma: no cover - assertion branch
|
||||
raise AssertionError("An unbound process identity must fail closed")
|
||||
bind_process_runtime_identity(identity)
|
||||
assert process_runtime_identity() is identity
|
||||
finally:
|
||||
bind_process_runtime_identity(previous)
|
||||
|
||||
|
||||
def test_worker_disables_consumers_without_reclaiming_stale_identity(
|
||||
monkeypatch,
|
||||
) -> None:
|
||||
@@ -127,8 +155,19 @@ def test_worker_disables_consumers_without_reclaiming_stale_identity(
|
||||
|
||||
def test_worker_child_replaces_inherited_database_pool(monkeypatch) -> None:
|
||||
from govoplan_core import celery_app
|
||||
from govoplan_core.core import runtime_coordination
|
||||
|
||||
calls: list[tuple[str, bool]] = []
|
||||
previous_process_identity = runtime_coordination._process_runtime_identity
|
||||
previous_worker_identity = celery_app._worker_identity
|
||||
inherited = RuntimeIdentity(
|
||||
installation_id="installation-1",
|
||||
node_id="parent-worker",
|
||||
incarnation="parent-incarnation",
|
||||
role="worker",
|
||||
software_version="0.1.14",
|
||||
composition_hash="a" * 64,
|
||||
)
|
||||
monkeypatch.setattr(
|
||||
celery_app,
|
||||
"configure_database",
|
||||
@@ -136,7 +175,19 @@ def test_worker_child_replaces_inherited_database_pool(monkeypatch) -> None:
|
||||
(url, dispose_previous)
|
||||
),
|
||||
)
|
||||
try:
|
||||
celery_app._worker_identity = inherited
|
||||
bind_process_runtime_identity(inherited)
|
||||
celery_app._reset_worker_process_database()
|
||||
|
||||
celery_app._reset_worker_process_database()
|
||||
|
||||
assert calls == [(celery_app.settings.database_url, True)]
|
||||
assert calls == [(celery_app.settings.database_url, True)]
|
||||
assert celery_app._worker_identity is None
|
||||
try:
|
||||
process_runtime_identity()
|
||||
except RuntimeCoordinationError:
|
||||
pass
|
||||
else: # pragma: no cover - assertion branch
|
||||
raise AssertionError("A worker child must discard inherited authority")
|
||||
finally:
|
||||
celery_app._worker_identity = previous_worker_identity
|
||||
bind_process_runtime_identity(previous_process_identity)
|
||||
|
||||
Reference in New Issue
Block a user