Skip to content

Commit 4c3bf5b

Browse files
SABUJ123472tjb-tech
authored andcommitted
fix(platform): harden Windows lock detection
Recognize win32 as a Windows platform alias and wrap missing platform lock modules in SwarmLockUnavailableError instead of leaking raw ImportError. Based-on: #34
1 parent 63ac368 commit 4c3bf5b

4 files changed

Lines changed: 44 additions & 4 deletions

File tree

src/openharness/platforms.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ def detect_platform(
3737

3838
if system == "darwin":
3939
return "macos"
40-
if system == "windows":
40+
if system in {"windows", "win32"}:
4141
return "windows"
4242
if system == "linux":
4343
if "microsoft" in kernel_release or env_map.get("WSL_DISTRO_NAME") or env_map.get("WSL_INTEROP"):
@@ -84,4 +84,3 @@ def get_platform_capabilities(platform_name: PlatformName | None = None) -> Plat
8484
supports_sandbox_runtime=False,
8585
supports_docker_sandbox=False,
8686
)
87-

src/openharness/utils/file_lock.py

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,10 @@ def exclusive_file_lock(
4646

4747
@contextmanager
4848
def _exclusive_posix_lock(lock_path: Path) -> Iterator[None]:
49-
import fcntl
49+
try:
50+
import fcntl
51+
except ImportError as exc:
52+
raise SwarmLockUnavailableError(f"fcntl not available: {exc}") from exc
5053

5154
lock_path.parent.mkdir(parents=True, exist_ok=True)
5255
lock_path.touch(exist_ok=True)
@@ -60,7 +63,10 @@ def _exclusive_posix_lock(lock_path: Path) -> Iterator[None]:
6063

6164
@contextmanager
6265
def _exclusive_windows_lock(lock_path: Path) -> Iterator[None]:
63-
import msvcrt
66+
try:
67+
import msvcrt
68+
except ImportError as exc:
69+
raise SwarmLockUnavailableError(f"msvcrt not available: {exc}") from exc
6470

6571
lock_path.parent.mkdir(parents=True, exist_ok=True)
6672
with lock_path.open("a+b") as lock_file:

tests/test_platforms.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,10 @@ def test_detect_platform_recognizes_windows():
1818
assert detect_platform(system_name="Windows", release="10", env={}) == "windows"
1919

2020

21+
def test_detect_platform_recognizes_win32_alias():
22+
assert detect_platform(system_name="win32", release="10", env={}) == "windows"
23+
24+
2125
def test_windows_capabilities_disable_swarm_mailbox_and_sandbox():
2226
capabilities = get_platform_capabilities("windows")
2327
assert capabilities.supports_native_windows_shell is True

tests/test_swarm/test_lockfile.py

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
from __future__ import annotations
44

5+
import builtins
56
from contextlib import contextmanager
67
from pathlib import Path
78

@@ -45,6 +46,36 @@ def test_exclusive_file_lock_rejects_unknown_platform(tmp_path: Path):
4546
pass
4647

4748

49+
def test_posix_lock_reports_unavailable_when_fcntl_missing(monkeypatch, tmp_path: Path):
50+
real_import = builtins.__import__
51+
52+
def fake_import(name, *args, **kwargs):
53+
if name == "fcntl":
54+
raise ImportError("missing fcntl")
55+
return real_import(name, *args, **kwargs)
56+
57+
monkeypatch.setattr(builtins, "__import__", fake_import)
58+
59+
with pytest.raises(lockfile.SwarmLockUnavailableError, match="fcntl not available"):
60+
with file_lock._exclusive_posix_lock(tmp_path / "posix.lock"):
61+
pass
62+
63+
64+
def test_windows_lock_reports_unavailable_when_msvcrt_missing(monkeypatch, tmp_path: Path):
65+
real_import = builtins.__import__
66+
67+
def fake_import(name, *args, **kwargs):
68+
if name == "msvcrt":
69+
raise ImportError("missing msvcrt")
70+
return real_import(name, *args, **kwargs)
71+
72+
monkeypatch.setattr(builtins, "__import__", fake_import)
73+
74+
with pytest.raises(lockfile.SwarmLockUnavailableError, match="msvcrt not available"):
75+
with file_lock._exclusive_windows_lock(tmp_path / "windows.lock"):
76+
pass
77+
78+
4879
def test_swarm_lockfile_shim_re_exports_public_api():
4980
"""Existing callers importing from ``swarm.lockfile`` must keep working."""
5081
assert lockfile.exclusive_file_lock is file_lock.exclusive_file_lock

0 commit comments

Comments
 (0)