feat(jobs): add resumable preprocessing envelope
This commit is contained in:
@@ -0,0 +1,61 @@
|
||||
import multiprocessing
|
||||
from pathlib import Path
|
||||
|
||||
import pytest
|
||||
|
||||
from tht.jobs.locking import JobAlreadyRunningError, WorkspaceJobLock
|
||||
|
||||
|
||||
def _hold_lock(root: str, ready, release):
|
||||
with WorkspaceJobLock(Path(root), "demo", "evidence"):
|
||||
ready.set()
|
||||
release.wait(10)
|
||||
|
||||
|
||||
def _crash_with_lock(root: str, ready):
|
||||
lock = WorkspaceJobLock(Path(root), "demo", "evidence")
|
||||
lock.acquire()
|
||||
ready.set()
|
||||
raise SystemExit(7)
|
||||
|
||||
|
||||
def test_same_workspace_and_job_are_exclusive_across_processes(tmp_path):
|
||||
context = multiprocessing.get_context("spawn")
|
||||
ready = context.Event()
|
||||
release = context.Event()
|
||||
process = context.Process(target=_hold_lock, args=(str(tmp_path), ready, release))
|
||||
process.start()
|
||||
assert ready.wait(10)
|
||||
try:
|
||||
with pytest.raises(JobAlreadyRunningError):
|
||||
WorkspaceJobLock(tmp_path, "demo", "evidence").acquire()
|
||||
finally:
|
||||
release.set()
|
||||
process.join(10)
|
||||
assert process.exitcode == 0
|
||||
|
||||
|
||||
def test_evidence_and_dwh_jobs_have_distinct_locks(tmp_path):
|
||||
with WorkspaceJobLock(tmp_path, "demo", "evidence"):
|
||||
with WorkspaceJobLock(tmp_path, "demo", "dwh"):
|
||||
pass
|
||||
|
||||
|
||||
def test_lock_keys_cannot_escape_lock_directory(tmp_path):
|
||||
with pytest.raises(ValueError, match="filesystem-safe"):
|
||||
WorkspaceJobLock(tmp_path, "demo", "../evidence")
|
||||
|
||||
|
||||
def test_lock_is_recoverable_after_process_crash_without_stale_deletion(tmp_path):
|
||||
context = multiprocessing.get_context("spawn")
|
||||
ready = context.Event()
|
||||
process = context.Process(target=_crash_with_lock, args=(str(tmp_path), ready))
|
||||
process.start()
|
||||
assert ready.wait(10)
|
||||
process.join(10)
|
||||
assert process.exitcode == 7
|
||||
|
||||
lock_path = WorkspaceJobLock(tmp_path, "demo", "evidence").path
|
||||
assert lock_path.exists()
|
||||
with WorkspaceJobLock(tmp_path, "demo", "evidence"):
|
||||
assert lock_path.exists()
|
||||
Reference in New Issue
Block a user