Files
strix/tests/test_session_entries.py
Mads Hvelplund 7141ccff62 Support large target repos with with bind-mount option. (#577)
* fix: resolve pre-commit check failures

- Change RuntimeError to TypeError for type validation in report/writer.py
- Update pyupgrade to v3.21.2 for Python 3.14 compatibility

* chore: add pytest test infrastructure

Mirror the layout introduced on feature/438-token_budget: pytest +
pytest-asyncio dev deps, asyncio_mode auto, a tests.* mypy override, and
pytest in the mypy pre-commit hook deps so the tests/ package type-checks.

* feat: add --mount and large-target pre-flight for local repos (#492)

Large local targets were copied into the sandbox file-by-file via the SDK
LocalDir entry, which stalls on big repos and could leave /workspace empty.

- --mount <path> bind-mounts a host directory read-only at /workspace/<subdir>
  instead of copying it, bypassing the per-file stream.
- A size pre-flight (STRIX_MAX_LOCAL_COPY_MB, default 1024) fails fast with a
  clear message suggesting --mount when a non-mounted local target is too big.

* fix: reject empty --mount paths

An empty or whitespace-only --mount value resolves to the current working
directory and would silently bind-mount it into the sandbox. Reject it.

* fix: dedupe local targets so a dir is never both copied and mounted

If the same directory is passed via --target and --mount (or as duplicate
values), it previously produced two targets — copied AND bind-mounted, and
the copied one could trip the size pre-flight. Dedupe by resolved path,
preferring the bind mount.

* fix: treat non-positive STRIX_MAX_LOCAL_COPY_MB as disabled

Previously a value of 0 (or negative) made every local target count as
oversized, aborting all local scans. Now <= 0 disables the pre-flight.

* fix: log unreadable subtrees during size pre-flight

os.walk silently swallowed directory-listing errors, so a permission-denied
subtree could make a large repo under-count and slip past the pre-flight.
Surface such omissions via an onerror warning.

* docs: document --mount and STRIX_MAX_LOCAL_COPY_MB

Add CLI reference + example for --mount, document the size pre-flight env var,
note the read-only-is-not-a-hard-boundary caveat and that remote repos are not
size-checked, and clarify the backends docstring on when bind mounts apply.

* Update strix/interface/main.py


* Update strix/runtime/docker_client.py


---------
2026-06-22 12:41:42 -04:00

68 lines
1.9 KiB
Python

"""Tests for build_session_entries: splitting copied vs bind-mounted sources."""
from __future__ import annotations
from typing import TYPE_CHECKING, Any
from agents.sandbox.entries import LocalDir
from strix.runtime.session_manager import build_session_entries
if TYPE_CHECKING:
from pathlib import Path
def _source(subdir: str, path: str, *, mount: bool = False) -> dict[str, Any]:
return {"source_path": path, "workspace_subdir": subdir, "mount": mount}
def test_copied_source_becomes_localdir_entry(tmp_path: Path) -> None:
entries, bind_mounts = build_session_entries([_source("repo", str(tmp_path))])
assert bind_mounts == []
assert isinstance(entries["repo"], LocalDir)
assert entries["repo"].src == tmp_path.resolve()
def test_mounted_source_becomes_bind_mount(tmp_path: Path) -> None:
entries, bind_mounts = build_session_entries([_source("repo", str(tmp_path), mount=True)])
assert entries == {}
assert bind_mounts == [
{
"source": str(tmp_path.resolve()),
"target": "/workspace/repo",
"read_only": True,
}
]
def test_mixed_sources_split_correctly(tmp_path: Path) -> None:
copied = tmp_path / "copied"
mounted = tmp_path / "mounted"
copied.mkdir()
mounted.mkdir()
entries, bind_mounts = build_session_entries(
[
_source("copied", str(copied)),
_source("mounted", str(mounted), mount=True),
]
)
assert list(entries) == ["copied"]
assert isinstance(entries["copied"], LocalDir)
assert [m["target"] for m in bind_mounts] == ["/workspace/mounted"]
def test_incomplete_sources_are_skipped() -> None:
entries, bind_mounts = build_session_entries(
[
{"source_path": "", "workspace_subdir": "x"},
{"source_path": "/p", "workspace_subdir": ""},
]
)
assert entries == {}
assert bind_mounts == []