From 6a43cf23ea887c2a67f274b4cdb4ab26cb281e2b Mon Sep 17 00:00:00 2001 From: indieindie7 Date: Sat, 31 Oct 2026 22:33:28 -0300 Subject: [PATCH] tests: make hardcoded /tmp assertions OS-neutral (#6864) Root cause: _is_sensitive_path splits on os.sep, so POSIX literals missed on Windows; /tmp is not a root on Windows (only $TMPDIR); inline-JSON test compared against "/tmp/wf.txt" while Windows abspath is C:\tmp\wf.txt. Change: native-separator helper, TMPDIR monkeypatch, abspath alternative. Before: 9 failed; after: 0 failed (74 passed, 1 symlink skip). Part of #4287 Co-authored-by: Claude Fable 5.1 Co-authored-by: Alexandre Teixeira --- tests/test_review_regressions.py | 3 ++- tests/test_tool_path_confinement.py | 29 ++++++++++++++++++----------- 2 files changed, 20 insertions(+), 12 deletions(-) diff --git a/tests/test_review_regressions.py b/tests/test_review_regressions.py index 8cc7c5a79..2ccc7ad71 100644 --- a/tests/test_review_regressions.py +++ b/tests/test_review_regressions.py @@ -2,6 +2,7 @@ import importlib import json +import os import sys import types from types import SimpleNamespace @@ -1202,7 +1203,7 @@ async def test_write_file_inline_json_args(monkeypatch): for b in blocks: await _execute_without_run_context(execute_tool_block, b, owner="admin", workspace="/tmp") - assert captured.get("path") == "/tmp/wf.txt", ( + assert captured.get("path") in ("/tmp/wf.txt", os.path.abspath("/tmp/wf.txt")), ( f"write_file did not decode inline JSON args; got path {captured.get('path')!r}" ) diff --git a/tests/test_tool_path_confinement.py b/tests/test_tool_path_confinement.py index 4d9b2261a..5dace2df1 100644 --- a/tests/test_tool_path_confinement.py +++ b/tests/test_tool_path_confinement.py @@ -28,6 +28,11 @@ def standalone_dispatch_authority(monkeypatch): server_authorized_executor(tool_execution.execute_tool_block)) +def _native(path: str) -> str: + """POSIX-style literal -> native separators (the policy splits on os.sep).""" + return path.replace("/", os.sep) + + def _make_block(tool_type, content): return SimpleNamespace(tool_type=tool_type, content=content) @@ -36,27 +41,27 @@ def _make_block(tool_type, content): def test_sensitive_ssh_dir(): from src.tool_execution import _is_sensitive_path - assert _is_sensitive_path("/home/user/.ssh/authorized_keys") - assert _is_sensitive_path(os.path.expanduser("~") + "/.ssh/config") + assert _is_sensitive_path(_native("/home/user/.ssh/authorized_keys")) + assert _is_sensitive_path(_native(os.path.expanduser("~") + "/.ssh/config")) def test_sensitive_gnupg_dir(): from src.tool_execution import _is_sensitive_path - assert _is_sensitive_path("/home/user/.gnupg/pubring.kbx") + assert _is_sensitive_path(_native("/home/user/.gnupg/pubring.kbx")) def test_sensitive_shell_rc(): from src.tool_execution import _is_sensitive_path - assert _is_sensitive_path("/home/user/.bashrc") - assert _is_sensitive_path("/home/user/.zshrc") - assert _is_sensitive_path("/home/user/.profile") + assert _is_sensitive_path(_native("/home/user/.bashrc")) + assert _is_sensitive_path(_native("/home/user/.zshrc")) + assert _is_sensitive_path(_native("/home/user/.profile")) def test_sensitive_key_filenames(): from src.tool_execution import _is_sensitive_path - assert _is_sensitive_path("/tmp/id_rsa") - assert _is_sensitive_path("/tmp/id_ed25519") - assert _is_sensitive_path("/tmp/authorized_keys") + assert _is_sensitive_path(_native("/tmp/id_rsa")) + assert _is_sensitive_path(_native("/tmp/id_ed25519")) + assert _is_sensitive_path(_native("/tmp/authorized_keys")) def test_non_sensitive_path(): @@ -186,9 +191,11 @@ def test_allows_agent_workspace(tmp_path): os.unlink(target) -def test_allows_tmp(tmp_path): +def test_allows_tmp(tmp_path, monkeypatch): """Paths under /tmp (or its realpath) must resolve cleanly.""" from src.tool_execution import _resolve_tool_path + # Windows has no /tmp; its temp root is only allowed via $TMPDIR. + monkeypatch.setenv("TMPDIR", str(tmp_path)) f = tmp_path / "confinement-test.txt" f.write_text("ok") resolved = _resolve_tool_path(str(f)) @@ -358,4 +365,4 @@ async def test_write_file_dispatch_blocks_cron(monkeypatch): def test_application_secrets_are_sensitive_paths(filename): from src.tool_execution import _is_sensitive_path - assert _is_sensitive_path(f"/tmp/odysseus-data/{filename}") + assert _is_sensitive_path(_native(f"/tmp/odysseus-data/{filename}"))