feat: harden issue lock store against concurrent session clobbering (Closes #438)
Replace read-modify-write on the global /tmp/gitea_issue_lock.json pointer with atomic per-issue locks under GITEA_ISSUE_LOCK_DIR using flock serialization, PID/session metadata, fail-closed stale recovery, and pre-mutation freshness re-checks in gitea_create_pr. Queue inventory now surfaces live_issue_locks. Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
This commit is contained in:
@@ -3042,13 +3042,38 @@ class TestIssueLocking(unittest.TestCase):
|
||||
"""Test issue locking and PR gating constraints."""
|
||||
|
||||
def setUp(self):
|
||||
self._env_patcher = patch.dict(os.environ, ISSUE_WRITE_ENV, clear=True)
|
||||
import shutil
|
||||
import tempfile
|
||||
|
||||
self._lock_dir = tempfile.mkdtemp(prefix="mcp-issue-lock-")
|
||||
self._session_lock = os.path.join(self._lock_dir, "session.json")
|
||||
env = {
|
||||
**ISSUE_WRITE_ENV,
|
||||
"GITEA_ISSUE_LOCK_DIR": self._lock_dir,
|
||||
"GITEA_ISSUE_LOCK_FILE": self._session_lock,
|
||||
}
|
||||
self._env_patcher = patch.dict(os.environ, env, clear=True)
|
||||
self._env_patcher.start()
|
||||
self._patchers = [
|
||||
patch("mcp_server.ISSUE_LOCK_FILE", self._session_lock),
|
||||
patch("mcp_server.issue_lock_store.DEFAULT_LOCK_DIR", self._lock_dir),
|
||||
patch("mcp_server.issue_lock_store.LEGACY_LOCK_FILE", self._session_lock),
|
||||
patch("tests.test_mcp_server.ISSUE_LOCK_FILE", self._session_lock),
|
||||
patch(
|
||||
"mcp_server.issue_lock_worktree.read_worktree_git_state",
|
||||
return_value=_clean_master_git_state_for_lock(),
|
||||
),
|
||||
]
|
||||
for patcher in self._patchers:
|
||||
patcher.start()
|
||||
|
||||
def tearDown(self):
|
||||
import shutil
|
||||
|
||||
for patcher in reversed(getattr(self, "_patchers", [])):
|
||||
patcher.stop()
|
||||
self._env_patcher.stop()
|
||||
if os.path.exists(ISSUE_LOCK_FILE):
|
||||
os.remove(ISSUE_LOCK_FILE)
|
||||
shutil.rmtree(getattr(self, "_lock_dir", ""), ignore_errors=True)
|
||||
|
||||
@patch(
|
||||
"mcp_server.issue_lock_worktree.read_worktree_git_state",
|
||||
|
||||
Reference in New Issue
Block a user