Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
43 changes: 43 additions & 0 deletions tests/conftest.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
"""Keep the test suite away from the developer's real DevOrch data.

Several modules compute ``Path.home() / ".devorch"`` at import time, and some tests (for example
``Permissions().set_tool_permission(...)``) save through those paths. Without isolation, running
``pytest`` overwrote the developer's real ``~/.devorch/permissions.yaml`` (replacing their saved rules
with ``edit: allow`` / ``filesystem: allow``) and wrote to their real sessions folder.

This must run before the application modules are imported, hence environment variables set at import
time of this conftest rather than a fixture.
"""

import os
import shutil
import tempfile

_TEST_HOME = tempfile.mkdtemp(prefix="devorch-test-home-")

# Path.home() reads HOME on POSIX and USERPROFILE on Windows
os.environ["HOME"] = _TEST_HOME
os.environ["USERPROFILE"] = _TEST_HOME
os.environ.pop("HOMEDRIVE", None)
os.environ.pop("HOMEPATH", None)
# never read from or write to the developer's real keychain
os.environ["PYTHON_KEYRING_BACKEND"] = "keyring.backends.null.Keyring"
# and no real API keys leak into tests
for _var in (
"OPENAI_API_KEY",
"ANTHROPIC_API_KEY",
"GOOGLE_API_KEY",
"GROQ_API_KEY",
"MISTRAL_API_KEY",
"OPENROUTER_API_KEY",
"TOGETHER_API_KEY",
"GITHUB_TOKEN",
"DEEPSEEK_API_KEY",
"MOONSHOT_API_KEY",
"CUSTOM_API_KEY",
):
os.environ.pop(_var, None)


def pytest_sessionfinish(session, exitstatus):
shutil.rmtree(_TEST_HOME, ignore_errors=True)
41 changes: 41 additions & 0 deletions tests/test_isolation.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
"""The suite must never read or write the developer's real ~/.devorch."""

import os
from pathlib import Path

from config import permissions as perm_mod
from config import settings as settings_mod
from core import sessions as sessions_mod
from core.memory import MEMORY_DIR


def test_home_is_a_throwaway_directory():
home = Path.home()
assert "devorch-test-home-" in home.name
assert home == Path(os.environ["HOME"])


def test_application_paths_resolve_under_the_test_home():
home = Path.home()
for path in (
perm_mod.PERMISSIONS_FILE,
settings_mod.CONFIG_FILE,
sessions_mod.DB_PATH,
MEMORY_DIR,
):
assert home in path.parents, f"{path} is outside the test HOME"


def test_saving_permissions_does_not_touch_the_real_file():
from config.permissions import PermissionLevel, Permissions

Permissions().set_tool_permission("edit", PermissionLevel.ALLOW) # saves to PERMISSIONS_FILE
assert perm_mod.PERMISSIONS_FILE.exists()
assert Path.home() in perm_mod.PERMISSIONS_FILE.parents


def test_keyring_is_the_null_backend():
import keyring

assert keyring.get_password("devorch", "openai") is None
assert type(keyring.get_keyring()).__module__ == "keyring.backends.null"
Loading