from pathlib import Path from deepagents.backends import LocalShellBackend from arena.codebase_executor import ( CodebaseSandboxExecutor, LocalCodebaseExecutor, ) from arena.codebase_archive import RedisCodebaseArchiveStore from arena.codebase_handoff import CodebaseHandoff class FakeDownload: def __init__(self, path: str, content: bytes | None = None, error: str | None = None) -> None: self.path = path self.content = content self.error = error class FakeGlob: def __init__(self, matches: list[dict], error: str | None = None) -> None: self.matches = matches self.error = error class FakeBackend: def __init__(self) -> None: self.files = { "/workspace/app.py": b"print('ok')\n", "/workspace/pkg/data.txt": b"data", } self.expected_glob = "/workspace/**" def glob(self, pattern: str) -> FakeGlob: assert pattern == self.expected_glob return FakeGlob([{"path": path, "is_dir": False} for path in self.files]) def download_files(self, paths: list[str]) -> list[FakeDownload]: return [FakeDownload(path, self.files[path]) for path in paths] class FakeRedisClient: def __init__(self) -> None: self.data: dict[str, str] = {} def execute(self, *args: str): command = args[0].upper() if command == "GET": return self.data.get(args[1]) if command == "SET": self.data[args[1]] = args[2] return "OK" raise AssertionError(f"unexpected command: {args}") class FakeUploadResult: error = None class ReopenableBackend: def __init__(self, name: str, closed: list[str]) -> None: self.name = name self.closed = closed self.uploaded: list[tuple[str, bytes]] = [] self._validator_workspace = "/workspace" def upload_files(self, files: list[tuple[str, bytes]]) -> list[FakeUploadResult]: self.uploaded.extend(files) return [FakeUploadResult() for _ in files] def execute(self, command: str, timeout: int): class Result: exit_code = 0 output = "" assert command.startswith("cd /workspace && ") return Result() def delete(self) -> None: self.closed.append(self.name) def test_local_codebase_executor_runs_command_in_workspace(tmp_path) -> None: source_root = tmp_path / "sandbox" workspace = source_root / "workspace" workspace.mkdir(parents=True) (workspace / "answer.txt").write_text("ok") pointer = CodebaseHandoff(root_dir=tmp_path / "snapshots").snapshot_local_workspace(source_root, "run-1") passed, output = LocalCodebaseExecutor(root_dir=tmp_path / "snapshots").run(pointer, "test -f answer.txt") assert passed is True assert "exit code 0" in output def test_local_codebase_executor_captures_failed_command(tmp_path) -> None: source_root = tmp_path / "sandbox" (source_root / "workspace").mkdir(parents=True) pointer = CodebaseHandoff(root_dir=tmp_path / "snapshots").snapshot_local_workspace(source_root, "run-1") passed, output = LocalCodebaseExecutor(root_dir=tmp_path / "snapshots").run( pointer, "printf 'bad' >&2; exit 7", ) assert passed is False assert "bad" in output assert "exit code 7" in output def test_local_codebase_executor_rejects_unknown_or_unsafe_pointer(tmp_path) -> None: executor = LocalCodebaseExecutor(root_dir=tmp_path / "snapshots") unsupported = executor.run("daytona://sandbox/x/workspace", "echo no") traversal = executor.run("local-snapshot://../secret", "echo no") assert unsupported[0] is False assert "unsupported archive pointer" in unsupported[1] assert traversal[0] is False assert "invalid snapshot id" in traversal[1] def test_snapshot_replaces_previous_copy_without_mutating_source(tmp_path) -> None: source_root = tmp_path / "sandbox" workspace = source_root / "workspace" workspace.mkdir(parents=True) (workspace / "answer.txt").write_text("v1") snapshot_root = tmp_path / "snapshots" handoff = CodebaseHandoff(root_dir=snapshot_root) pointer = handoff.snapshot_local_workspace(source_root, "run-1") (workspace / "answer.txt").write_text("v2") handoff.snapshot_local_workspace(source_root, "run-1") snapshot_file = snapshot_root / pointer.removeprefix("local-snapshot://") / "workspace" / "answer.txt" assert snapshot_file.read_text() == "v2" assert (workspace / "answer.txt").read_text() == "v2" def test_backend_snapshot_uses_deepagents_filesystem_interface(tmp_path) -> None: pointer = CodebaseHandoff(root_dir=tmp_path / "snapshots").snapshot_backend_workspace(FakeBackend(), "run-1") passed, output = LocalCodebaseExecutor(root_dir=tmp_path / "snapshots").run( pointer, "python app.py && test -f pkg/data.txt", ) assert passed is True assert "exit code 0" in output def test_backend_snapshot_supports_custom_workspace_dir(tmp_path) -> None: backend = FakeBackend() backend.files = {"/home/daytona/workspace/app.py": b"print('ok')\n"} backend.expected_glob = "/home/daytona/workspace/**" pointer = CodebaseHandoff(root_dir=tmp_path / "snapshots").snapshot_backend_workspace( backend, "run-1", workspace_dir="/home/daytona/workspace", ) passed, output = LocalCodebaseExecutor(root_dir=tmp_path / "snapshots").run(pointer, "python app.py") assert passed is True assert "exit code 0" in output def test_codebase_sandbox_executor_restores_snapshot_into_backend(tmp_path) -> None: source_root = tmp_path / "sandbox" workspace = source_root / "workspace" workspace.mkdir(parents=True) (workspace / "answer.txt").write_text("ok") pointer = CodebaseHandoff(root_dir=tmp_path / "snapshots").snapshot_local_workspace(source_root, "run-1") validator_root = tmp_path / "validator" executor = CodebaseSandboxExecutor( root_dir=tmp_path / "snapshots", backend_factory=lambda: LocalShellBackend(root_dir=validator_root, virtual_mode=True, inherit_env=False), ) passed, output = executor.run(pointer, "test -f answer.txt") assert passed is True assert "exit code 0" in output assert (validator_root / "workspace" / "answer.txt").read_text() == "ok" def test_codebase_sandbox_executor_opens_backend_lazily(tmp_path) -> None: calls: list[bool] = [] executor = CodebaseSandboxExecutor( root_dir=tmp_path / "snapshots", backend_factory=lambda: calls.append(True) or ReopenableBackend("backend-1", []), ) assert calls == [] assert executor.backend is None def test_codebase_sandbox_executor_restores_redis_archive_pointer(tmp_path) -> None: archive_store = RedisCodebaseArchiveStore(client=FakeRedisClient()) pointer = CodebaseHandoff(archive_store=archive_store).snapshot_backend_workspace(FakeBackend(), "run-1") validator_root = tmp_path / "validator" executor = CodebaseSandboxExecutor( archive_store=archive_store, backend_factory=lambda: LocalShellBackend(root_dir=validator_root, virtual_mode=True, inherit_env=False), ) passed, output = executor.run(pointer, "test -f app.py && test -f pkg/data.txt") assert pointer == "redis-archive://run-1" assert passed is True assert "exit code 0" in output def test_codebase_sandbox_executor_reports_failed_command(tmp_path) -> None: source_root = tmp_path / "sandbox" (source_root / "workspace").mkdir(parents=True) pointer = CodebaseHandoff(root_dir=tmp_path / "snapshots").snapshot_local_workspace(source_root, "run-1") executor = CodebaseSandboxExecutor( root_dir=tmp_path / "snapshots", backend_factory=lambda: LocalShellBackend( root_dir=tmp_path / "validator", virtual_mode=True, inherit_env=False, ), ) passed, output = executor.run(pointer, "test -f missing.txt") assert passed is False assert "exit code" in output.lower() def test_codebase_sandbox_executor_reopens_backend_after_close(tmp_path) -> None: source_root = tmp_path / "sandbox" workspace = source_root / "workspace" workspace.mkdir(parents=True) (workspace / "answer.txt").write_text("ok") pointer = CodebaseHandoff(root_dir=tmp_path / "snapshots").snapshot_local_workspace(source_root, "run-1") closed: list[str] = [] created: list[ReopenableBackend] = [] def backend_factory() -> ReopenableBackend: backend = ReopenableBackend(f"backend-{len(created) + 1}", closed) created.append(backend) return backend executor = CodebaseSandboxExecutor( root_dir=tmp_path / "snapshots", backend_factory=backend_factory, sandbox_ttl_seconds=60, ) first = executor.run(pointer, "test -f answer.txt") executor.close() second = executor.run(pointer, "test -f answer.txt") assert first[0] is True assert second[0] is True assert closed == ["backend-1"] assert [backend.name for backend in created] == ["backend-1", "backend-2"]