Files
wehub-resource-sync 25576b0be6
Checks (magui2.0) / python-lint (push) Failing after 1s
Checks (magui2.0) / python-test (push) Failing after 0s
Checks (magui2.0) / frontend-lint (push) Failing after 0s
CodeQL Advanced / Analyze (actions) (push) Failing after 1s
Checks (magui2.0) / python-format (push) Failing after 1s
CodeQL Advanced / Analyze (python) (push) Failing after 0s
Checks (magui2.0) / python-pyright (push) Failing after 1s
Checks (magui2.0) / frontend-format (push) Failing after 1s
Checks (magui2.0) / frontend-typecheck (push) Failing after 0s
Checks (magui2.0) / frontend-test (push) Failing after 2s
CodeQL Advanced / Analyze (javascript-typescript) (push) Failing after 1s
chore: import upstream snapshot with attribution
2026-07-13 12:24:32 +08:00

89 lines
3.1 KiB
Python

"""Share one sandbox venv across the OmniAgent test suite.
Every ``NullSandbox`` builds a Python venv under its ``agent_home`` and installs
``markitdown[all]`` (``src/magentic_ui/sandbox/requirements.txt``). These tests
use a per-test ``tmp_path`` as both workspace and (by default) ``agent_home``,
so each test rebuilt that heavy venv from scratch. With enough tests, the
per-test venvs piled up in pytest's session temp tree and exhausted the CI
runner disk (``[Errno 28] No space left on device``).
This builds the venv once per session at a shared ``agent_home`` and points
every ``NullSandbox`` at it (unless a test passes its own ``agent_home``). Each
test keeps its own ``tmp_path`` workspace, so file isolation is unchanged — only
the venv is shared.
"""
from __future__ import annotations
import subprocess
from pathlib import Path
import pytest
from magentic_ui.sandbox._local import _SANDBOX_REQUIREMENTS
from magentic_ui.sandbox._null import NullSandbox
@pytest.fixture(scope="session")
def shared_sandbox_agent_home(
tmp_path_factory: pytest.TempPathFactory,
) -> Path:
# Anchored under this run's pytest-<N> base dir so pytest's normal
# "keep last 3 runs" cleanup removes it — no manual teardown.
shared_home = tmp_path_factory.getbasetemp() / "sandbox_agent_home"
venv = shared_home / "sandbox" / "venv"
# Build the full venv once. Use uv (the project's package manager) so we
# don't depend on the system python3 shipping ensurepip. Tests run serially
# today; if pytest-xdist is added, guard this build with a cross-process
# lock and anchor ``shared_home`` at ``getbasetemp().parent`` so workers
# share it.
if not venv.exists():
venv.parent.mkdir(parents=True, exist_ok=True)
subprocess.run(["uv", "venv", str(venv)], check=True, capture_output=True)
subprocess.run(
[
"uv",
"pip",
"install",
"-q",
"--python",
str(venv / "bin" / "python"),
"-r",
str(_SANDBOX_REQUIREMENTS),
],
check=True,
)
return shared_home
@pytest.fixture(autouse=True)
def _redirect_null_sandbox_to_shared_venv(
monkeypatch: pytest.MonkeyPatch,
shared_sandbox_agent_home: Path,
) -> None:
# Function-scoped (and confined to this package's conftest) so the redirect
# is torn down after each test and never leaks onto NullSandbox usage in
# other test directories. Tests that pass an explicit ``agent_home`` keep
# it; everything else lands on the shared venv.
original_init = NullSandbox.__init__
def patched_init(
self: NullSandbox,
workspace: Path,
agent_home: Path | None = None,
reset: bool = False,
bash_only: bool = False,
) -> None:
original_init(
self,
workspace,
agent_home=agent_home
if agent_home is not None
else shared_sandbox_agent_home,
reset=reset,
bash_only=bash_only,
)
monkeypatch.setattr(NullSandbox, "__init__", patched_init)