fix(jobs): harden resume locks and durability
This commit is contained in:
@@ -1,4 +1,5 @@
|
||||
import multiprocessing
|
||||
import os
|
||||
from pathlib import Path
|
||||
|
||||
import pytest
|
||||
@@ -46,6 +47,36 @@ def test_lock_keys_cannot_escape_lock_directory(tmp_path):
|
||||
WorkspaceJobLock(tmp_path, "demo", "../evidence")
|
||||
|
||||
|
||||
def test_preexisting_lock_symlink_is_rejected(tmp_path):
|
||||
lock = WorkspaceJobLock(tmp_path, "demo", "evidence")
|
||||
lock.path.parent.mkdir(parents=True)
|
||||
target = tmp_path / "target"
|
||||
target.write_text("do not modify")
|
||||
lock.path.symlink_to(target)
|
||||
with pytest.raises(OSError):
|
||||
lock.acquire()
|
||||
assert target.read_text() == "do not modify"
|
||||
|
||||
|
||||
def test_preexisting_locks_directory_symlink_is_rejected(tmp_path):
|
||||
jobs = tmp_path / ".tht-jobs"
|
||||
jobs.mkdir()
|
||||
outside = tmp_path / "outside"
|
||||
outside.mkdir()
|
||||
(jobs / ".locks").symlink_to(outside, target_is_directory=True)
|
||||
with pytest.raises(OSError):
|
||||
WorkspaceJobLock(tmp_path, "demo", "evidence").acquire()
|
||||
assert list(outside.iterdir()) == []
|
||||
|
||||
|
||||
def test_lock_file_is_owner_only_regular_single_link(tmp_path):
|
||||
with WorkspaceJobLock(tmp_path, "demo", "evidence") as lock:
|
||||
stat = os.stat(lock.path, follow_symlinks=False)
|
||||
assert stat.st_uid == os.getuid()
|
||||
assert stat.st_nlink == 1
|
||||
assert stat.st_mode & 0o777 == 0o600
|
||||
|
||||
|
||||
def test_lock_is_recoverable_after_process_crash_without_stale_deletion(tmp_path):
|
||||
context = multiprocessing.get_context("spawn")
|
||||
ready = context.Event()
|
||||
|
||||
Reference in New Issue
Block a user