fix: resolve hooks_cli.py merge conflict + add mine_global_lock tests

- Resolve UU conflict in hooks_cli.py: take develop/HEAD approach
  (mine synchronously via _mine_sync, then pass through unconditionally).
  _mine_sync already catches subprocess.TimeoutExpired — fixes Copilot #1.
- Add tests/test_palace_locks.py: 4 tests covering mine_global_lock
  non-blocking semantics (acquire, second-acquire raises MineAlreadyRunning,
  reusable after release, release on exception) — fixes Copilot #4.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Felipe Truman
2026-04-17 17:14:22 -03:00
committed by Igor Lins e Silva
parent 91a60263e3
commit 7e18a70796
5 changed files with 175 additions and 2 deletions
+59
View File
@@ -0,0 +1,59 @@
"""Tests for mine_global_lock: non-blocking cross-process lock semantics."""
import threading
import pytest
from mempalace.palace import MineAlreadyRunning, mine_global_lock
def test_mine_global_lock_acquired(tmp_path, monkeypatch):
"""Lock is acquired and released without error."""
monkeypatch.setenv("HOME", str(tmp_path))
with mine_global_lock():
pass # should not raise
def test_mine_global_lock_second_acquire_raises(tmp_path, monkeypatch):
"""Concurrent second acquire raises MineAlreadyRunning."""
monkeypatch.setenv("HOME", str(tmp_path))
results: list[str] = []
with mine_global_lock():
# While this lock is held, spawn a thread that tries to acquire.
def try_acquire():
try:
with mine_global_lock():
results.append("acquired")
except MineAlreadyRunning:
results.append("blocked")
t = threading.Thread(target=try_acquire)
t.start()
t.join(timeout=5)
assert results == ["blocked"]
def test_mine_global_lock_reusable_after_release(tmp_path, monkeypatch):
"""Lock can be re-acquired after the context manager exits."""
monkeypatch.setenv("HOME", str(tmp_path))
with mine_global_lock():
pass # first acquire + release
# Second acquire must succeed; MineAlreadyRunning would propagate as failure.
with mine_global_lock():
pass
def test_mine_global_lock_exception_still_releases(tmp_path, monkeypatch):
"""Lock is released even when the body raises."""
monkeypatch.setenv("HOME", str(tmp_path))
with pytest.raises(ValueError):
with mine_global_lock():
raise ValueError("boom")
# Must be acquirable again after the exception.
with mine_global_lock():
pass