aboutsummaryrefslogtreecommitdiff
path: root/app/tests/test_backends_envs.py
diff options
context:
space:
mode:
Diffstat (limited to 'app/tests/test_backends_envs.py')
-rw-r--r--app/tests/test_backends_envs.py33
1 files changed, 27 insertions, 6 deletions
diff --git a/app/tests/test_backends_envs.py b/app/tests/test_backends_envs.py
index 2f0f910..d3b35c1 100644
--- a/app/tests/test_backends_envs.py
+++ b/app/tests/test_backends_envs.py
@@ -1,7 +1,9 @@
"""Tests for the managed Python environment (backends/envs.py)."""
import json
+import os
import sys
+import tempfile
import unittest
from pathlib import Path
from unittest.mock import patch
@@ -63,15 +65,34 @@ class EnvPathTests(unittest.TestCase):
return_value=Path("/no/such/path/python")):
self.assertFalse(envs.env_exists())
- def test_is_managed_env_compares_resolved_executable(self):
- fake_env_python = Path("/tmp/opencode/managed-env/bin/python")
- with patch.object(envs, "env_python", return_value=fake_env_python), \
- patch.object(sys, "executable", str(fake_env_python)):
+ def test_is_managed_env_compares_prefix_to_env_dir(self):
+ # sys.prefix is the environment the current interpreter belongs to:
+ # the env dir for its python, the base install (/usr, ...) otherwise.
+ with patch.object(envs, "ENV_DIR", Path(sys.prefix)):
self.assertTrue(envs.is_managed_env())
- with patch.object(envs, "env_python", return_value=fake_env_python), \
- patch.object(sys, "executable", "/usr/bin/python3"):
+ with patch.object(envs, "ENV_DIR",
+ Path(tempfile.gettempdir()) / "managed-env"):
self.assertFalse(envs.is_managed_env())
+ def test_is_managed_env_not_fooled_by_symlinked_venv_python(self):
+ # Regression: a venv's bin/python is a symlink to the base
+ # interpreter, so resolving sys.executable made the bare system
+ # python compare equal to env_python() and pass as the managed env —
+ # silently skipping the bootstrap (and the requirements install).
+ # The check must use sys.prefix, which stays the base install's.
+ if sys.platform == "win32":
+ self.skipTest("requires POSIX symlinks")
+ with tempfile.TemporaryDirectory() as tmp:
+ env_dir = Path(tmp) / "tts"
+ bin_dir = env_dir / "bin"
+ bin_dir.mkdir(parents=True)
+ os.symlink(sys.executable, bin_dir / "python")
+ with patch.object(envs, "ENV_DIR", env_dir):
+ # The bare system interpreter: sys.executable resolves to
+ # exactly what the venv python symlink points at, yet its
+ # prefix is not the env dir, so this must stay False.
+ self.assertFalse(envs.is_managed_env())
+
class CreateEnvTests(unittest.TestCase):
def test_create_env_invokes_venv_module(self):