From 9ce6fdcb2252ea005b4fa98ca50bd3857e1f681a Mon Sep 17 00:00:00 2001 From: Shxiao Date: Tue, 8 Sep 2026 10:21:38 +0900 Subject: [PATCH] test(skills): skip POSIX mode-bit assertions on Windows (#5244) * test(skills): skip POSIX mode-bit assertions on Windows Windows has no POSIX mode bits: st_mode always reports 0o777 and Path.chmod only honors the read-only flag, so the readability assertions in both skill-permissions tests cannot hold on Windows hosts. Skip them there with an explicit reason; they still run on POSIX where the chmod contract applies. * test(skills): address review feedback on Windows skips - correct the skip reason: Windows mode bits are observable; it is Path.chmod() that only toggles the read-only bit, so the asserted 0o644/0o755 modes are never observable there; - hoist the repeated skipif to a module-level requires_posix_mode_bits decorator so the reason stays single-sourced; - keep test_written_path_readability_is_limited_to_written_path executing the resolve()/relative_to() traversal on Windows with content-intact smoke assertions, skipping only the mode-bit asserts. * test(skills): single-source the skip reason string Follow-up to the re-review: the reason text lived verbatim in both the module-level skipif and the inline pytest.skip() call; promote it to a _POSIX_MODE_BITS_REASON constant used by both call sites. --- backend/tests/test_skill_permissions.py | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/backend/tests/test_skill_permissions.py b/backend/tests/test_skill_permissions.py index dc32c9c4c..fd9654516 100644 --- a/backend/tests/test_skill_permissions.py +++ b/backend/tests/test_skill_permissions.py @@ -1,5 +1,8 @@ +import os import stat +import pytest + from deerflow.skills.permissions import make_skill_tree_sandbox_readable, make_skill_written_path_sandbox_readable @@ -7,6 +10,12 @@ def _mode(path): return stat.S_IMODE(path.stat().st_mode) +_POSIX_MODE_BITS_REASON = "Windows chmod only toggles the read-only bit, so the 0o644/0o755 modes asserted here are never observable" + +requires_posix_mode_bits = pytest.mark.skipif(os.name == "nt", reason=_POSIX_MODE_BITS_REASON) + + +@requires_posix_mode_bits def test_skill_tree_readability_includes_hidden_paths_and_removes_sandbox_write(tmp_path): root = tmp_path / "demo-skill" hidden_dir = root / ".hidden" @@ -56,6 +65,15 @@ def test_written_path_readability_is_limited_to_written_path(tmp_path): make_skill_written_path_sandbox_readable(root, target) + # The resolve()/relative_to() traversal is the platform-sensitive part + # (drive letters, case-insensitive roots, symlinks), so keep it executing + # on Windows where the chmod effects themselves are not observable. + assert target.read_text(encoding="utf-8") == "guide" + assert sibling.read_text(encoding="utf-8") == "note" + + if os.name == "nt": + pytest.skip(_POSIX_MODE_BITS_REASON) + assert _mode(root) == 0o755 assert _mode(ref_dir) == 0o755 assert _mode(target) == 0o644