"""Paused tasks yield their device and resume with a fresh lease.""" import asyncio import pytest import artemis.runtime.task_control as task_control @pytest.mark.asyncio async def test_pause_releases_device_and_resume_waits_for_new_acquisition(tmp_path, monkeypatch): monkeypatch.setattr(task_control, "TRACES_PATH", tmp_path) events = [] class Lock: def __init__(self, device_id, **kwargs): self.device_id = device_id self.description = kwargs.get("description", "test") self.max_concurrency = kwargs.get("max_concurrency") self.concurrency_mode = kwargs.get("concurrency_mode", "per_device") self.ingress = kwargs.get("ingress", "web") self.lock_scope = kwargs.get("lock_scope", "test") def release(self): events.append("released") def acquire(self, cancel_event=None): events.append("acquired") monkeypatch.setattr(task_control, "DeviceExecutionLock", Lock) original = Lock("test-device") control = task_control.TaskControl("task-123", original) task_control.request_pause("task-123") waiter = asyncio.create_task( control.checkpoint( on_pause=lambda: _event("capture_stopped", events), on_resume=lambda: _event("capture_started", events), ) ) for _ in range(30): if task_control.read_state("task-123").get("status") == "task_paused": break await asyncio.sleep(0.01) assert task_control.read_state("task-123")["status"] == "task_paused" assert events == ["capture_stopped", "released"] task_control.request_resume("task-123") assert await asyncio.wait_for(waiter, 2) is True assert events == ["capture_stopped", "released", "acquired", "capture_started"] control.release() assert task_control.read_state("task-123") == {} async def _event(name, events): events.append(name)