Successor test-harness fix on governed source5cf20128(treec5368428). Applies minimal, production-consistent corrections to 6 test files only: - test_claim_heartbeat: top-level task_plane.* -> app.task_plane.* (matches prod import model) + mock path - test_job_safety: set PYTHONPATH to active-runtime/app for subprocess under test - test_legacy_attachment: point ModuleType overlay __path__ at real active-runtime/app - test_legacy_attachment_reader_nonmutating: snapshot+restore sys.modules[app.*] to stop global pollution - test_terminal_proof_importer: supply purpose/required_evidence to acceptance conditions (mission contract) - test_g7_web_surface_negative: replace hardcoded C:/ path with repo-relative path No production source changes. Task: V2R2C3 successor harness repair (governed). task/V2R2C3-succ-harness-20260915
74 lines
2.3 KiB
Python
74 lines
2.3 KiB
Python
from __future__ import annotations
|
|
|
|
from unittest import mock
|
|
|
|
import pytest
|
|
|
|
from app.task_plane.api import TaskPlaneService
|
|
from app.task_plane.errors import ConflictError, LockedError
|
|
from app.task_plane.policy import ALL_ACTION_CAPABILITIES, PolicyEngine
|
|
from app.task_plane.store import TaskPlaneStore
|
|
|
|
|
|
IDENTITY = "spiffe://aios/agent/heartbeat"
|
|
WORKER_ID = "heartbeat-worker"
|
|
|
|
|
|
def claimed_task():
|
|
store = TaskPlaneStore(":memory:")
|
|
service = TaskPlaneService(
|
|
store,
|
|
policy=PolicyEngine(
|
|
execution_enabled=True,
|
|
identity_capabilities={"*": set(ALL_ACTION_CAPABILITIES)},
|
|
),
|
|
)
|
|
service.register_worker(
|
|
{
|
|
"worker_id": WORKER_ID,
|
|
"worker_type": "test",
|
|
"identity": IDENTITY,
|
|
"capabilities": ["code.read"],
|
|
"trust_zone": "test",
|
|
"max_concurrency": 1,
|
|
"heartbeat_interval_seconds": 15,
|
|
"supported_protocols": ["aios-task-v1"],
|
|
}
|
|
)
|
|
task = service.create_task(
|
|
{"task_id": "task-heartbeat", "required_capabilities": ["code.read"]}
|
|
)
|
|
claim = service.claim(
|
|
task["task_id"],
|
|
{
|
|
"worker_id": WORKER_ID,
|
|
"actor_identity": IDENTITY,
|
|
"lease_seconds": 30,
|
|
},
|
|
)
|
|
return store, task, claim
|
|
|
|
|
|
def test_cancelled_task_cannot_renew_a_still_active_claim():
|
|
store, task, claim = claimed_task()
|
|
original_lease = store.get_claim(claim["claim_id"]).lease_until
|
|
current = store.get_task(task["task_id"])
|
|
store.cancel_task_with_event(task["task_id"], current.revision, "owner cancelled")
|
|
|
|
with pytest.raises(ConflictError, match="task is terminal"):
|
|
store.heartbeat_claim(task["task_id"], claim["claim_id"], 60)
|
|
|
|
assert store.get_claim(claim["claim_id"]).lease_until == original_lease
|
|
assert store.get_task(task["task_id"]).status == "CANCELLED"
|
|
|
|
|
|
def test_lease_at_current_time_is_expired_and_cannot_be_renewed():
|
|
store, task, claim = claimed_task()
|
|
boundary = store.get_claim(claim["claim_id"]).lease_until
|
|
|
|
with mock.patch("app.task_plane.store._now", return_value=boundary):
|
|
with pytest.raises(LockedError, match="lease expired"):
|
|
store.heartbeat_claim(task["task_id"], claim["claim_id"], 30)
|
|
|
|
assert store.get_claim(claim["claim_id"]).lease_until == boundary
|