mirror of
https://github.com/leonvanzyl/autocoder.git
synced 2026-01-30 06:12:06 +00:00
fix: add Windows compatibility to security unit tests
Add cross-platform temporary_home() context manager to handle environment variable differences between Unix and Windows systems. Changes: - Add temporary_home() context manager that handles both HOME (Unix) and USERPROFILE/HOMEDRIVE/HOMEPATH (Windows) environment variables - Update test_org_config_loading() to use temporary_home() - Update test_hierarchy_resolution() to use temporary_home() - Update test_org_blocklist_enforcement() to use temporary_home() - Add missing imports: os, contextmanager Why: The unit tests for org config loading were failing on Windows because they only set the HOME environment variable, but Windows uses USERPROFILE instead. The integration tests already had this fix via a similar context manager. Result: All 148 unit tests now pass on both Windows and Unix systems. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -8,8 +8,10 @@ Run with: python test_security.py
|
||||
"""
|
||||
|
||||
import asyncio
|
||||
import os
|
||||
import sys
|
||||
import tempfile
|
||||
from contextlib import contextmanager
|
||||
from pathlib import Path
|
||||
|
||||
from security import (
|
||||
@@ -25,6 +27,48 @@ from security import (
|
||||
)
|
||||
|
||||
|
||||
@contextmanager
|
||||
def temporary_home(home_path):
|
||||
"""
|
||||
Context manager to temporarily set HOME (and Windows equivalents).
|
||||
|
||||
Saves original environment variables and restores them on exit,
|
||||
even if an exception occurs.
|
||||
|
||||
Args:
|
||||
home_path: Path to use as temporary home directory
|
||||
"""
|
||||
# Save original values for Unix and Windows
|
||||
saved_env = {
|
||||
"HOME": os.environ.get("HOME"),
|
||||
"USERPROFILE": os.environ.get("USERPROFILE"),
|
||||
"HOMEDRIVE": os.environ.get("HOMEDRIVE"),
|
||||
"HOMEPATH": os.environ.get("HOMEPATH"),
|
||||
}
|
||||
|
||||
try:
|
||||
# Set new home directory for both Unix and Windows
|
||||
os.environ["HOME"] = str(home_path)
|
||||
if sys.platform == "win32":
|
||||
os.environ["USERPROFILE"] = str(home_path)
|
||||
# Note: HOMEDRIVE and HOMEPATH are typically set by Windows
|
||||
# but we update them for consistency
|
||||
drive, path = os.path.splitdrive(str(home_path))
|
||||
if drive:
|
||||
os.environ["HOMEDRIVE"] = drive
|
||||
os.environ["HOMEPATH"] = path
|
||||
|
||||
yield
|
||||
|
||||
finally:
|
||||
# Restore original values
|
||||
for key, value in saved_env.items():
|
||||
if value is None:
|
||||
os.environ.pop(key, None)
|
||||
else:
|
||||
os.environ[key] = value
|
||||
|
||||
|
||||
def check_hook(command: str, should_block: bool) -> bool:
|
||||
"""Check a single command against the security hook (helper function)."""
|
||||
input_data = {"tool_name": "Bash", "tool_input": {"command": command}}
|
||||
@@ -416,14 +460,9 @@ def test_org_config_loading():
|
||||
passed = 0
|
||||
failed = 0
|
||||
|
||||
# Save original org config path
|
||||
original_home = Path.home()
|
||||
|
||||
with tempfile.TemporaryDirectory() as tmpdir:
|
||||
# Temporarily override home directory for testing
|
||||
import os
|
||||
os.environ["HOME"] = tmpdir
|
||||
|
||||
# Use temporary_home for cross-platform compatibility
|
||||
with temporary_home(tmpdir):
|
||||
org_dir = Path(tmpdir) / ".autocoder"
|
||||
org_dir.mkdir()
|
||||
org_config_path = org_dir / "config.yaml"
|
||||
@@ -505,9 +544,6 @@ allowed_commands:
|
||||
print(f" Got: {config}")
|
||||
failed += 1
|
||||
|
||||
# Restore HOME
|
||||
os.environ["HOME"] = str(original_home)
|
||||
|
||||
return passed, failed
|
||||
|
||||
|
||||
@@ -519,11 +555,8 @@ def test_hierarchy_resolution():
|
||||
|
||||
with tempfile.TemporaryDirectory() as tmphome:
|
||||
with tempfile.TemporaryDirectory() as tmpproject:
|
||||
# Setup fake home directory
|
||||
import os
|
||||
original_home = os.environ.get("HOME")
|
||||
os.environ["HOME"] = tmphome
|
||||
|
||||
# Use temporary_home for cross-platform compatibility
|
||||
with temporary_home(tmphome):
|
||||
org_dir = Path(tmphome) / ".autocoder"
|
||||
org_dir.mkdir()
|
||||
org_config_path = org_dir / "config.yaml"
|
||||
@@ -595,12 +628,6 @@ commands:
|
||||
print(" FAIL: Hardcoded blocklist enforced")
|
||||
failed += 1
|
||||
|
||||
# Restore HOME
|
||||
if original_home:
|
||||
os.environ["HOME"] = original_home
|
||||
else:
|
||||
del os.environ["HOME"]
|
||||
|
||||
return passed, failed
|
||||
|
||||
|
||||
@@ -612,11 +639,8 @@ def test_org_blocklist_enforcement():
|
||||
|
||||
with tempfile.TemporaryDirectory() as tmphome:
|
||||
with tempfile.TemporaryDirectory() as tmpproject:
|
||||
# Setup fake home directory
|
||||
import os
|
||||
original_home = os.environ.get("HOME")
|
||||
os.environ["HOME"] = tmphome
|
||||
|
||||
# Use temporary_home for cross-platform compatibility
|
||||
with temporary_home(tmphome):
|
||||
org_dir = Path(tmphome) / ".autocoder"
|
||||
org_dir.mkdir()
|
||||
org_config_path = org_dir / "config.yaml"
|
||||
@@ -643,12 +667,6 @@ blocked_commands:
|
||||
print(" FAIL: Org blocked command 'terraform' should be rejected")
|
||||
failed += 1
|
||||
|
||||
# Restore HOME
|
||||
if original_home:
|
||||
os.environ["HOME"] = original_home
|
||||
else:
|
||||
del os.environ["HOME"]
|
||||
|
||||
return passed, failed
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user