Add Handbook.md benchmark tasks

This commit is contained in:
DerekSurge
2026-06-24 12:44:34 -07:00
commit 72f9a65917
1800 changed files with 323589 additions and 0 deletions
@@ -0,0 +1,305 @@
"""Pin `sandbox._agent_env`: the single chokepoint that hides /opt/venv from
agent-spawned subprocesses (bash)."""
from __future__ import annotations
import os
from unittest import mock
import pytest
from core.tools import sandbox
def _polluted_environ() -> dict[str, str]:
return {
"HOME": "/home/model",
"USER": "model",
"LANG": "C.UTF-8",
"PATH": "/opt/venv/bin:/app/scripts:/usr/local/bin:/usr/bin:/bin",
"VIRTUAL_ENV": "/opt/venv",
"UV_PROJECT_ENVIRONMENT": "/opt/venv",
"PYTHONPATH": "/app:/opt/venv/lib/python3.13/site-packages",
"PYTHONHOME": "/opt/venv",
"SETUID": "1000",
"SETGID": "1000",
}
def test_strips_opt_venv_from_path():
with mock.patch.dict(os.environ, _polluted_environ(), clear=True):
env = sandbox._agent_env()
assert "/opt/venv" not in env["PATH"], env["PATH"]
def test_strips_app_from_path():
with mock.patch.dict(os.environ, _polluted_environ(), clear=True):
env = sandbox._agent_env()
assert "/app" not in env["PATH"], env["PATH"]
def test_drops_venv_pointers():
with mock.patch.dict(os.environ, _polluted_environ(), clear=True):
env = sandbox._agent_env()
for var in ("VIRTUAL_ENV", "UV_PROJECT_ENVIRONMENT", "PYTHONPATH", "PYTHONHOME"):
assert var not in env, f"{var!r} leaked: {env.get(var)!r}"
def test_drops_privilege_control_vars():
with mock.patch.dict(os.environ, _polluted_environ(), clear=True):
env = sandbox._agent_env()
assert "SETUID" not in env
assert "SETGID" not in env
def test_preserves_user_facing_vars():
with mock.patch.dict(os.environ, _polluted_environ(), clear=True):
env = sandbox._agent_env()
assert env["HOME"] == "/home/model"
assert env["USER"] == "model"
assert env["LANG"] == "C.UTF-8"
def test_path_is_a_concrete_default_not_absent():
with mock.patch.dict(os.environ, _polluted_environ(), clear=True):
env = sandbox._agent_env()
assert env.get("PATH"), "agent PATH unexpectedly empty"
assert "/usr/bin" in env["PATH"]
assert "/usr/local/bin" in env["PATH"]
# Regression guard for the P1: derived images (docker/stem-*) append dirs like
# /opt/conda/bin; sanitising must strip only /opt/venv and /app, never the rest.
def _derived_image_environ() -> dict[str, str]:
env = _polluted_environ()
env["PATH"] = "/opt/venv/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/opt/conda/bin"
return env
def test_preserves_derived_image_path_additions():
with mock.patch.dict(os.environ, _derived_image_environ(), clear=True):
env = sandbox._agent_env()
entries = env["PATH"].split(os.pathsep)
assert "/opt/conda/bin" in entries, env["PATH"]
assert "/opt/venv/bin" not in entries, env["PATH"]
def test_preserves_path_entry_order():
with mock.patch.dict(os.environ, _derived_image_environ(), clear=True):
env = sandbox._agent_env()
entries = env["PATH"].split(os.pathsep)
assert entries == ["/usr/local/sbin", "/usr/local/bin", "/usr/sbin", "/usr/bin", "/sbin", "/bin", "/opt/conda/bin"]
def test_strips_only_venv_and_app_prefixes_not_lookalikes():
polluted = _polluted_environ()
polluted["PATH"] = "/opt/venv/bin:/opt/venvtools/bin:/application/bin:/app/scripts:/usr/bin"
with mock.patch.dict(os.environ, polluted, clear=True):
env = sandbox._agent_env()
entries = env["PATH"].split(os.pathsep)
assert entries == ["/opt/venvtools/bin", "/application/bin", "/usr/bin"], env["PATH"]
def test_falls_back_to_default_when_only_server_entries():
polluted = _polluted_environ()
polluted["PATH"] = "/opt/venv/bin:/app/scripts"
with mock.patch.dict(os.environ, polluted, clear=True):
env = sandbox._agent_env()
assert env["PATH"] == sandbox._AGENT_DEFAULT_PATH
def test_falls_back_to_default_when_path_unset():
polluted = _polluted_environ()
del polluted["PATH"]
with mock.patch.dict(os.environ, polluted, clear=True):
env = sandbox._agent_env()
assert env["PATH"] == sandbox._AGENT_DEFAULT_PATH
def test_parent_env_unchanged():
# Sanitiser must not mutate os.environ — core itself relies on those
# vars for its own subsequent imports.
polluted = _polluted_environ()
with mock.patch.dict(os.environ, polluted, clear=True):
sandbox._agent_env()
assert os.environ["PATH"] == polluted["PATH"]
assert os.environ["VIRTUAL_ENV"] == polluted["VIRTUAL_ENV"]
assert os.environ["UV_PROJECT_ENVIRONMENT"] == polluted["UV_PROJECT_ENVIRONMENT"]
assert os.environ["SETUID"] == polluted["SETUID"]
def test_drops_harness_internal_vars():
polluted = _polluted_environ()
polluted.update(
{
"WORLDBENCH_ROOT": "/app",
"WORLDBENCH_SEED": "deadbeef",
"WORLDBENCH_TOOL_SETS": "core_debug",
# A harness var nobody listed explicitly — the prefix sweep must catch it.
"WORLDBENCH_SOME_FUTURE_VAR": "/app/whatever",
"INPUTDIR": "/app/setup_data/entities/core",
"OUTPUTDIR": "/app/output_data/core",
"BUNDLE_OUTPUT_DIR": "/app/output_data/services",
"BUNDLE_INPUT_DIR": "/app/bundle/services/core",
"BUNDLEDIR": "/app/bundle",
"PORT": "41984",
"VIEWER_PORT": "8123",
}
)
with mock.patch.dict(os.environ, polluted, clear=True):
env = sandbox._agent_env()
for var in (
"WORLDBENCH_ROOT",
"WORLDBENCH_SEED",
"WORLDBENCH_TOOL_SETS",
"WORLDBENCH_SOME_FUTURE_VAR",
"INPUTDIR",
"OUTPUTDIR",
"BUNDLE_OUTPUT_DIR",
"BUNDLE_INPUT_DIR",
"BUNDLEDIR",
"PORT",
"VIEWER_PORT",
):
assert var not in env, f"{var!r} leaked to the agent: {env.get(var)!r}"
# /app must not survive anywhere in the agent env (paths or otherwise).
assert not any("/app" in v for v in env.values()), env
def test_preserves_clock_var():
# The fake clock must reach the agent's shell; it is NOT a harness leak.
polluted = _polluted_environ()
polluted["WORLDBENCH_CURRENT_TIME"] = "2026-01-02T03:04:05Z"
with mock.patch.dict(os.environ, polluted, clear=True):
env = sandbox._agent_env()
assert env["WORLDBENCH_CURRENT_TIME"] == "2026-01-02T03:04:05Z"
def test_privilege_drop_kwargs_noop_when_not_root():
# Tests/CI run unprivileged: nothing to drop to, so subprocess gets no
# user/group kwargs and runs as the invoking user.
with mock.patch("core.tools.sandbox.os.geteuid", return_value=1000):
assert sandbox._privilege_drop_kwargs() == {}
def test_privilege_drop_kwargs_drops_when_root():
polluted = _polluted_environ() # has SETUID/SETGID = 1000
with (
mock.patch("core.tools.sandbox.os.geteuid", return_value=0),
mock.patch.dict(os.environ, polluted, clear=True),
):
kwargs = sandbox._privilege_drop_kwargs()
assert kwargs == {"user": 1000, "group": 1000, "extra_groups": []}
def test_privilege_drop_kwargs_fails_closed_when_root_without_ids():
# Root but no SETUID/SETGID: refuse rather than run the agent's command as
# root (a sandbox escape).
env = {k: v for k, v in _polluted_environ().items() if k not in ("SETUID", "SETGID")}
with (
mock.patch("core.tools.sandbox.os.geteuid", return_value=0),
mock.patch.dict(os.environ, env, clear=True),
pytest.raises(RuntimeError, match="SETUID/SETGID are not both set"),
):
sandbox._privilege_drop_kwargs()
# ---------------------------------------------------------------------------
# agent_stream_file — the unprivileged whole-file reader the viewer streams from
# ---------------------------------------------------------------------------
def test_agent_stream_file_streams_whole_file(tmp_path, monkeypatch):
monkeypatch.setattr(sandbox, "WORKDIR", str(tmp_path))
target = tmp_path / "data.bin"
payload = bytes(range(256)) * 1000 # 256 KB, spans many read() calls
target.write_bytes(payload)
chunks = list(sandbox.agent_stream_file(str(target), chunk_size=4096))
assert b"".join(chunks) == payload
# Actually streamed in pieces rather than buffered as one blob.
assert len(chunks) > 1
def test_agent_stream_file_empty_file_yields_nothing(tmp_path, monkeypatch):
monkeypatch.setattr(sandbox, "WORKDIR", str(tmp_path))
target = tmp_path / "empty.bin"
target.write_bytes(b"")
assert list(sandbox.agent_stream_file(str(target))) == []
def test_agent_stream_file_missing_file_raises(tmp_path, monkeypatch):
monkeypatch.setattr(sandbox, "WORKDIR", str(tmp_path))
with pytest.raises(sandbox.AgentReadError):
list(sandbox.agent_stream_file(str(tmp_path / "nope.bin")))
def test_agent_stream_file_rejects_fifo(tmp_path, monkeypatch):
# A named pipe with no writer would block a reader forever; the helper must
# refuse non-regular files instead of hanging. (No writer is opened here, so
# this test would deadlock if the guard regressed.)
monkeypatch.setattr(sandbox, "WORKDIR", str(tmp_path))
fifo = tmp_path / "pipe"
os.mkfifo(fifo)
with pytest.raises(sandbox.AgentReadError):
list(sandbox.agent_stream_file(str(fifo)))
def test_agent_read_window_rejects_fifo(tmp_path, monkeypatch):
# Same guard on the windowed reader (backs readFile / viewer / grading).
monkeypatch.setattr(sandbox, "WORKDIR", str(tmp_path))
fifo = tmp_path / "pipe"
os.mkfifo(fifo)
with pytest.raises(sandbox.AgentReadError):
sandbox.agent_read_window(str(fifo))
def test_agent_read_window_roundtrips(tmp_path):
sandbox.WORKDIR = str(tmp_path)
p = tmp_path / "data.bin"
p.write_bytes(b"0123456789abcdef")
size, header, raw, start = sandbox.agent_read_window(str(p), offset=4, limit=5, sniff=3)
assert size == 16
assert header == b"012"
assert raw == b"45678"
assert start == 4
def test_agent_read_window_raises_on_missing(tmp_path):
sandbox.WORKDIR = str(tmp_path)
with pytest.raises(sandbox.AgentReadError):
sandbox.agent_read_window(str(tmp_path / "nope.bin"))
def test_agent_list_dir(tmp_path):
sandbox.WORKDIR = str(tmp_path)
(tmp_path / "a.txt").write_text("hi")
(tmp_path / "sub").mkdir()
entries = {e["name"]: e for e in sandbox.agent_list_dir(str(tmp_path))}
assert entries["a.txt"]["is_dir"] is False
assert entries["a.txt"]["size"] == 2
assert entries["sub"]["is_dir"] is True
def test_run_in_sandbox_passes_sanitised_env(tmp_path):
# End-to-end: catches the failure mode where _agent_env exists but
# run_in_sandbox forgot to call it.
sandbox.WORKDIR = str(tmp_path)
polluted = _polluted_environ()
with mock.patch.dict(os.environ, polluted, clear=True):
result = sandbox.run_in_sandbox(
[
"sh",
"-c",
"echo PATH=$PATH; echo VENV=${VIRTUAL_ENV:-}; echo UV=${UV_PROJECT_ENVIRONMENT:-}; echo SU=${SETUID:-}",
],
timeout=10,
)
assert result["returncode"] == 0, result
out = result["stdout"]
assert "/opt/venv" not in out, out
assert "/app" not in out, out
assert "VENV=\n" in out or out.rstrip().endswith("VENV="), out
assert "UV=\n" in out or ("UV=" in out and "/opt/venv" not in out), out
assert "SU=\n" in out or out.rstrip().endswith("SU="), out
@@ -0,0 +1,52 @@
"""Verify HiddenToolFilter: hidden tools excluded from list_tools but still callable."""
import asyncio
from fastmcp import Client, FastMCP
from fastmcp.server.middleware import Middleware
from fastmcp.tools.function_tool import FunctionTool
class HiddenToolFilter(Middleware):
async def on_list_tools(self, context, call_next):
tool_list = await call_next(context)
return [t for t in tool_list if "hidden" not in (t.tags or set())]
def _build_app() -> FastMCP:
app = FastMCP("test")
def visible_tool() -> str:
"""A normal tool."""
return "visible"
def hidden_tool() -> str:
"""A hidden tool."""
return "hidden"
app.add_tool(FunctionTool.from_function(fn=visible_tool, name="visible_tool"))
app.add_tool(FunctionTool.from_function(fn=hidden_tool, name="hidden_tool", tags={"hidden"}))
app.add_middleware(HiddenToolFilter())
return app
async def main():
app = _build_app()
async with Client(app) as client:
# 1. Hidden tool should NOT appear in list_tools
tools = await client.list_tools()
tool_names = [t.name for t in tools]
assert "visible_tool" in tool_names, f"visible_tool missing from {tool_names}"
assert "hidden_tool" not in tool_names, f"hidden_tool should be hidden but found in {tool_names}"
print("PASS: hidden tool excluded from list_tools")
# 2. Hidden tool should still be callable
result = await client.call_tool("hidden_tool", {})
assert result.content[0].text == "hidden", f"unexpected result: {result}"
print("PASS: hidden tool still callable via call_tool")
print("\nAll checks passed.")
if __name__ == "__main__":
asyncio.run(main())
@@ -0,0 +1,524 @@
import os
import pathlib
import shutil
import tempfile
import unittest
from unittest import mock
import pytest
from core.tools import sandbox
from core.tools.prepare_grading_context import (
_extract_docx,
_extract_pptx,
_extract_text,
_extract_xlsx,
_format_evidence_as_xml,
_get_extension,
_is_excluded,
_walk_dir,
prepareGradingContext,
)
class TestHelpers(unittest.TestCase):
def test_get_extension(self):
assert _get_extension("/foo/bar.txt") == "txt"
assert _get_extension("/foo/bar.CSV") == "csv"
assert _get_extension("/foo/bar") == ""
# Dotfiles like .hidden have no extension per os.path.splitext
assert _get_extension("/foo/.hidden") == ""
def test_is_excluded(self):
excl = {"__pycache__", ".git"}
assert _is_excluded("__pycache__/foo.pyc", excl)
assert _is_excluded("src/__pycache__/foo.pyc", excl)
assert _is_excluded(".git/config", excl)
assert not _is_excluded("src/main.py", excl)
def test_walk_dir_sorted(self):
with tempfile.TemporaryDirectory() as d:
os.makedirs(os.path.join(d, "b"))
open(os.path.join(d, "b", "z.txt"), "w").close()
open(os.path.join(d, "b", "a.txt"), "w").close()
open(os.path.join(d, "c.txt"), "w").close()
results = _walk_dir(d)
names = [os.path.basename(r) for r in results]
assert names == ["a.txt", "z.txt", "c.txt"] or results == sorted(results)
class TestExtractText(unittest.TestCase):
# _extract_text now takes (raw_bytes, file_size, max_bytes) — the actual file
# read happens earlier, as the sandbox user, in prepareGradingContext.
def test_extract_text_normal(self):
content, method, truncated = _extract_text(b"hello world", 11, 50_000)
assert content == "hello world"
assert method == "read"
assert not truncated
def test_extract_text_truncated(self):
raw = b"a" * 1000
content, _method, truncated = _extract_text(raw, len(raw), 100)
assert truncated
assert content is not None
assert "[... truncated at 100 bytes" in content
assert "total size: 1,000 bytes]" in content
def test_extract_text_decodes_non_utf8_lossily(self):
# Invalid UTF-8 bytes are replaced, never raise.
content, _method, _truncated = _extract_text(b"\xff\xfe bad bytes", 12, 50_000)
assert content is not None
class TestFormatEvidenceAsXml(unittest.TestCase):
def test_empty_evidence(self):
assert _format_evidence_as_xml([]) == ""
def test_single_file_with_content(self):
evidence = [
{
"path": "/tmp/test.txt",
"extension": "txt",
"size_bytes": 11,
"content": "hello world",
"truncated": False,
}
]
xml = _format_evidence_as_xml(evidence, "/tmp")
assert '<workspace_files directory="/tmp">' in xml
assert 'path="/tmp/test.txt"' in xml
assert 'type="txt"' in xml
assert 'size_bytes="11"' in xml
assert "hello world" in xml
assert "</workspace_files>" in xml
def test_null_content_self_closing(self):
evidence = [
{
"path": "/tmp/test.bin",
"extension": "bin",
"size_bytes": 100,
"content": None,
"truncated": False,
}
]
xml = _format_evidence_as_xml(evidence)
assert "/>" in xml
assert "</file>" not in xml
def test_special_extension_extraction_method(self):
evidence = [
{
"path": "/tmp/test.pdf",
"extension": "pdf",
"size_bytes": 5000,
"content": "pdf text",
"extraction_method": "pypdf",
"truncated": False,
}
]
xml = _format_evidence_as_xml(evidence)
assert 'extraction_method="pypdf"' in xml
def test_truncated_attribute(self):
evidence = [
{
"path": "/tmp/big.txt",
"extension": "txt",
"size_bytes": 100000,
"content": "partial...",
"truncated": True,
}
]
xml = _format_evidence_as_xml(evidence)
assert 'truncated="true"' in xml
class TestPrepareGradingContext(unittest.IsolatedAsyncioTestCase):
def setUp(self):
self.temp_dir = tempfile.mkdtemp()
self.original_workdir = sandbox.WORKDIR
# prepareGradingContext now confines reads to the sandbox workdir, so
# point WORKDIR at the dir under test (mirrors production, where grading
# collects the agent's deliverables from WORKDIR).
sandbox.WORKDIR = self.temp_dir
def tearDown(self):
shutil.rmtree(self.temp_dir, ignore_errors=True)
sandbox.WORKDIR = self.original_workdir
def _write(self, rel_path: str, content: str = "test") -> str:
full = os.path.join(self.temp_dir, rel_path)
os.makedirs(os.path.dirname(full), exist_ok=True)
with open(full, "w") as f:
f.write(content)
return full
async def test_returns_xml_prepended_to_final_output(self):
self._write("hello.txt", "hello world")
result = await prepareGradingContext(final_output="agent response", directory=self.temp_dir)
assert result.startswith("<workspace_files")
assert result.endswith("agent response")
assert "\n\nagent response" in result
async def test_no_files_returns_just_final_output(self):
result = await prepareGradingContext(final_output="agent response", directory=self.temp_dir)
assert result == "agent response"
async def test_nonexistent_directory_returns_final_output(self):
result = await prepareGradingContext(final_output="agent response", directory="/nonexistent/path")
assert result == "agent response"
async def test_default_workdir(self):
workdir = tempfile.mkdtemp()
sandbox.WORKDIR = workdir
with open(os.path.join(workdir, "file.txt"), "w") as f:
f.write("test")
result = await prepareGradingContext(final_output="output")
assert "<workspace_files" in result
assert result.endswith("output")
shutil.rmtree(workdir)
async def test_extension_filter(self):
self._write("hello.txt", "text")
self._write("hello.py", "print('hi')")
self._write("hello.csv", "a,b")
result = await prepareGradingContext(
final_output="output",
directory=self.temp_dir,
extensions=["txt", "csv"],
)
assert 'type="txt"' in result
assert 'type="csv"' in result
assert 'type="py"' not in result
async def test_unsupported_extension_raises(self):
with pytest.raises(ValueError) as ctx:
await prepareGradingContext(
final_output="output",
directory=self.temp_dir,
extensions=["exe"],
)
assert "Unsupported" in str(ctx.value)
async def test_exclude_patterns(self):
self._write("src/main.py", "code")
self._write("__pycache__/cache.py", "cached")
self._write(".git/config", "git stuff")
result = await prepareGradingContext(final_output="output", directory=self.temp_dir)
assert "main.py" in result
assert "cache.py" not in result
assert "config" not in result
async def test_max_files_limit(self):
for i in range(10):
self._write(f"file{i:02d}.txt", f"content {i}")
result = await prepareGradingContext(final_output="output", directory=self.temp_dir, max_files=3)
assert result.count("<file ") == 3
async def test_max_files_overflow_is_reported_not_silent(self):
# The walk is flat + alphabetical, so a low cap can drop later files.
# Those must be surfaced (count + names), not silently dropped, so a
# rubric does not wrongly conclude an existing file is missing.
for i in range(5):
self._write(f"file{i:02d}.txt", f"content {i}")
result = await prepareGradingContext(final_output="output", directory=self.temp_dir, max_files=2)
assert result.count("<file ") == 2
assert 'truncated_to_max_files="true"' in result
assert 'dropped_file_count="3"' in result
assert "<files_omitted_due_to_max_files" in result
# The dropped files are the alphabetically-later ones.
assert "file04.txt" in result
assert result.count("<omitted_file ") == 3
async def test_no_overflow_has_no_truncation_marker(self):
for i in range(3):
self._write(f"file{i:02d}.txt", f"content {i}")
result = await prepareGradingContext(final_output="output", directory=self.temp_dir, max_files=10)
assert "truncated_to_max_files" not in result
assert "files_omitted_due_to_max_files" not in result
async def test_overflow_marker_emitted_even_when_no_files_fit(self):
# max_files=0: nothing is included, but the dir is non-empty. The grader
# must still see that files exist (and were omitted), not a bare output.
self._write("only.txt", "content")
result = await prepareGradingContext(final_output="output", directory=self.temp_dir, max_files=0)
assert result.startswith("<workspace_files")
assert 'dropped_file_count="1"' in result
assert "only.txt" in result
async def test_unsupported_files_skipped(self):
self._write("image.png", "binary")
self._write("doc.txt", "text")
result = await prepareGradingContext(final_output="output", directory=self.temp_dir)
assert 'type="txt"' in result
# Check for the unsupported file's marker tokens specifically — the
# tempdir path itself can contain "png" as a random substring.
assert "image.png" not in result
assert 'type="png"' not in result
async def test_oversized_special_file_recorded_not_extracted(self):
# A special file over the raw-read cap must be surfaced as evidence (so
# the rubric knows it exists) but NOT extracted — extracting truncated
# PDF/Office bytes would corrupt, and reading it whole could OOM grading.
self._write("big.pdf", "x" * 100)
with mock.patch("core.tools.prepare_grading_context.MAX_SPECIAL_FILE_BYTES", 10):
result = await prepareGradingContext(final_output="output", directory=self.temp_dir)
assert 'type="pdf"' in result
assert 'size_bytes="100"' in result
assert "exceeds" in result and "grading read cap" in result
assert 'truncated="true"' in result
# content is None -> self-closing tag, and the raw bytes never appear.
assert "<big.pdf" not in result
async def test_special_file_under_cap_is_extracted(self):
# A small docx under the cap still flows through normal extraction — the
# cap must not block legitimate files.
from docx import Document
path = os.path.join(self.temp_dir, "report.docx")
doc = Document()
doc.add_paragraph("under-cap evidence")
doc.save(path)
result = await prepareGradingContext(final_output="output", directory=self.temp_dir)
assert 'extraction_method="python-docx"' in result
assert "under-cap evidence" in result
async def test_returns_plain_string(self):
self._write("test.txt", "content")
result = await prepareGradingContext(final_output="my output", directory=self.temp_dir)
assert isinstance(result, str)
# Should NOT be JSON
assert not result.startswith("{")
assert not result.startswith("[")
async def test_empty_directory_returns_final_output(self):
result = await prepareGradingContext(final_output="my output", directory=self.temp_dir)
assert result == "my output"
class TestExtractDocx(unittest.TestCase):
def _make_docx(self, path: str) -> None:
from docx import Document
doc = Document()
doc.add_paragraph("Quarterly summary: revenue up 20%.")
table = doc.add_table(rows=2, cols=2)
table.cell(0, 0).text = "Metric"
table.cell(0, 1).text = "Value"
table.cell(1, 0).text = "Revenue"
table.cell(1, 1).text = "1000"
doc.save(path)
def test_extracts_paragraphs(self):
with tempfile.TemporaryDirectory() as d:
path = os.path.join(d, "report.docx")
self._make_docx(path)
content, method, truncated = _extract_docx(pathlib.Path(path).read_bytes(), 50_000)
assert method == "python-docx"
assert not truncated
assert content is not None
assert "revenue up 20%" in content
def test_includes_table_cells(self):
with tempfile.TemporaryDirectory() as d:
path = os.path.join(d, "report.docx")
self._make_docx(path)
content, _method, _truncated = _extract_docx(pathlib.Path(path).read_bytes(), 50_000)
# Regression: table cell text used to be dropped (paragraphs only).
assert content is not None
assert "Metric" in content
assert "Revenue" in content
assert "1000" in content
def test_includes_nested_table_cells(self):
from docx import Document
with tempfile.TemporaryDirectory() as d:
path = os.path.join(d, "nested.docx")
doc = Document()
outer = doc.add_table(rows=1, cols=1)
cell = outer.cell(0, 0)
cell.paragraphs[0].text = "OuterCell"
inner = cell.add_table(rows=1, cols=2)
inner.cell(0, 0).text = "InnerA"
inner.cell(0, 1).text = "InnerB"
doc.save(path)
content, _method, _truncated = _extract_docx(pathlib.Path(path).read_bytes(), 50_000)
assert content is not None
# cell.text flattens only direct paragraphs; nested tables must recurse.
assert "OuterCell" in content
assert "InnerA" in content
assert "InnerB" in content
def test_missing_file_returns_none(self):
content, method, truncated = _extract_docx(b"not a real docx", 50_000)
assert content is None
assert method == "python-docx"
assert not truncated
class TestExtractXlsx(unittest.TestCase):
def _make_xlsx(self, path: str) -> None:
from openpyxl import Workbook
wb = Workbook()
ws = wb.active
ws.title = "Data"
ws.append(["Name", "Value"])
ws.append(["foo", 42])
wb.save(path)
def test_extracts_rows(self):
with tempfile.TemporaryDirectory() as d:
path = os.path.join(d, "sheet.xlsx")
self._make_xlsx(path)
content, method, truncated = _extract_xlsx(pathlib.Path(path).read_bytes(), 50_000)
assert method == "openpyxl"
assert not truncated
assert content is not None
assert "--- Sheet: Data ---" in content
assert "Name\tValue" in content
assert "foo\t42" in content
def test_missing_file_returns_none(self):
content, method, truncated = _extract_xlsx(b"not a real xlsx", 50_000)
assert content is None
assert method == "openpyxl"
assert not truncated
def test_every_sheet_appears_even_when_earlier_sheet_truncated(self):
# Regression: a big first sheet used to drain the whole budget, so later
# tabs never appeared. The budget is now per-sheet.
from openpyxl import Workbook
with tempfile.TemporaryDirectory() as d:
path = os.path.join(d, "big.xlsx")
wb = Workbook()
ws1 = wb.active
ws1.title = "TB Current"
for i in range(2000):
ws1.append([f"row{i}", "Trial Balance as of 12/31/2025", i, i * 2, "padding text"])
ws2 = wb.create_sheet("TB Prior")
ws2.append(["Trial Balance as of 11/30/2025"])
ws2.append(["Prior period data", 123])
wb.save(path)
content, _method, truncated = _extract_xlsx(pathlib.Path(path).read_bytes(), 2000)
assert truncated
assert content is not None
assert "--- Sheet: TB Current ---" in content
assert "--- Sheet: TB Prior ---" in content
# The starved later sheet's data survives, and truncation is attributed.
assert "11/30/2025" in content
assert "Prior period data\t123" in content
assert "'TB Current' truncated" in content
def test_empty_trailing_rows_do_not_consume_budget(self):
# openpyxl read-only dimensions can be inflated; fully-empty rows must be
# skipped so they don't burn the budget producing only blank tab output.
from openpyxl import Workbook
with tempfile.TemporaryDirectory() as d:
path = os.path.join(d, "sparse.xlsx")
wb = Workbook()
ws = wb.active
ws.title = "Sparse"
ws.append(["header", "value"])
ws.append(["real", 1])
# Force a large inflated dimension with empty cells far below.
ws.cell(row=5000, column=1, value=None)
wb.save(path)
content, _method, truncated = _extract_xlsx(pathlib.Path(path).read_bytes(), 50_000)
assert content is not None
assert not truncated
assert "header\tvalue" in content
assert "real\t1" in content
# No run of empty tab-joined rows should appear.
assert "\t\t\t" not in content
class TestExtractPptx(unittest.TestCase):
def _make_pptx(self, path: str) -> None:
from pptx import Presentation
from pptx.util import Inches
prs = Presentation()
s1 = prs.slides.add_slide(prs.slide_layouts[5])
s1.shapes.title.text = "Helix Pricing SLT Deck"
# Slide 2: a textbox, a table, and speaker notes.
s2 = prs.slides.add_slide(prs.slide_layouts[6])
tb = s2.shapes.add_textbox(Inches(1), Inches(1), Inches(4), Inches(1))
tb.text_frame.text = "Recommended price: $499"
table = s2.shapes.add_table(2, 2, Inches(1), Inches(3), Inches(4), Inches(1)).table
table.cell(0, 0).text = "Tier"
table.cell(0, 1).text = "Price"
table.cell(1, 0).text = "Pro"
table.cell(1, 1).text = "499"
s2.notes_slide.notes_text_frame.text = "Emphasize ROI in the meeting"
prs.save(path)
def test_extracts_slides_tables_and_notes(self):
with tempfile.TemporaryDirectory() as d:
path = os.path.join(d, "deck.pptx")
self._make_pptx(path)
content, method, truncated = _extract_pptx(pathlib.Path(path).read_bytes(), 50_000)
assert method == "python-pptx"
assert not truncated
assert content is not None
assert "--- Slide 1 ---" in content
assert "--- Slide 2 ---" in content
assert "Helix Pricing SLT Deck" in content
assert "Recommended price: $499" in content
assert "Tier\tPrice" in content
assert "Pro\t499" in content
assert "[Notes] Emphasize ROI in the meeting" in content
def test_missing_file_returns_none(self):
content, method, truncated = _extract_pptx(b"not a real pptx", 50_000)
assert content is None
assert method == "python-pptx"
assert not truncated
class TestPrepareGradingContextBinary(unittest.IsolatedAsyncioTestCase):
async def test_docx_and_xlsx_evidence_assembled(self):
from docx import Document
from openpyxl import Workbook
original_workdir = sandbox.WORKDIR
with tempfile.TemporaryDirectory() as d:
sandbox.WORKDIR = d # reads are confined to WORKDIR
self.addCleanup(setattr, sandbox, "WORKDIR", original_workdir)
doc = Document()
doc.add_paragraph("agent wrote this in a docx")
doc.save(os.path.join(d, "out.docx"))
wb = Workbook()
wb.active.append(["col", "val"])
wb.save(os.path.join(d, "out.xlsx"))
from pptx import Presentation
prs = Presentation()
slide = prs.slides.add_slide(prs.slide_layouts[5])
slide.shapes.title.text = "agent wrote this in a pptx"
prs.save(os.path.join(d, "out.pptx"))
result = await prepareGradingContext(final_output="FINAL", directory=d)
assert 'type="docx"' in result
assert 'extraction_method="python-docx"' in result
assert "agent wrote this in a docx" in result
assert 'type="xlsx"' in result
assert 'extraction_method="openpyxl"' in result
# Regression: a .pptx deliverable used to be silently skipped.
assert 'type="pptx"' in result
assert 'extraction_method="python-pptx"' in result
assert "agent wrote this in a pptx" in result
assert result.endswith("FINAL")
if __name__ == "__main__":
unittest.main()
@@ -0,0 +1,136 @@
"""Tests for ``core.privilege`` — the workdir-ownership helpers
(``ensure_workdir``, ``chown_tree_to_target``) used by ``core.setup``.
The per-command privilege drop lives in ``core.tools.sandbox`` now (the
server stays root and drops each agent command instead of the whole process);
its tests are in ``test_agent_env.py``.
"""
from __future__ import annotations
from unittest import mock
from core import privilege
def _patch_root(is_root: bool):
return mock.patch("core.privilege.os.geteuid", return_value=0 if is_root else 1000)
# ---------------------------------------------------------------------------
# ensure_workdir
# ---------------------------------------------------------------------------
def test_ensure_workdir_creates_and_chowns_when_root(tmp_path, monkeypatch):
monkeypatch.setenv("SETUID", "1000")
monkeypatch.setenv("SETGID", "1000")
target = tmp_path / "workdir-new"
with (
_patch_root(True),
mock.patch("core.privilege.os.chown") as chown,
mock.patch("core.privilege.sandbox.WORKDIR", str(target)),
):
privilege.ensure_workdir()
assert target.is_dir()
chown.assert_called_once_with(str(target), 1000, 1000)
def test_ensure_workdir_noop_when_not_root(tmp_path):
"""Non-root can't mkdir at / and can't chown, so the whole function is a
no-op — WORKDIR must already exist (or the caller will fail loudly)."""
target = tmp_path / "workdir-missing"
with (
_patch_root(False),
mock.patch("core.privilege.os.chown") as chown,
mock.patch("core.privilege.sandbox.WORKDIR", str(target)),
):
privilege.ensure_workdir()
assert not target.exists()
chown.assert_not_called()
def test_ensure_workdir_skips_chown_when_env_vars_unset(tmp_path, monkeypatch):
monkeypatch.delenv("SETUID", raising=False)
monkeypatch.delenv("SETGID", raising=False)
target = tmp_path / "workdir"
with (
_patch_root(True),
mock.patch("core.privilege.os.chown") as chown,
mock.patch("core.privilege.sandbox.WORKDIR", str(target)),
):
privilege.ensure_workdir()
assert target.is_dir()
chown.assert_not_called()
# ---------------------------------------------------------------------------
# chown_tree_to_target
# ---------------------------------------------------------------------------
def _make_tree(root):
"""Build a small tree: root/a.txt, root/sub/b.txt, root/sub/c.txt."""
root.mkdir(parents=True, exist_ok=True)
(root / "a.txt").write_text("a")
(root / "sub").mkdir()
(root / "sub" / "b.txt").write_text("b")
(root / "sub" / "c.txt").write_text("c")
def test_chown_tree_recursively_when_root(tmp_path, monkeypatch):
monkeypatch.setenv("SETUID", "1000")
monkeypatch.setenv("SETGID", "1000")
target = tmp_path / "workdir"
_make_tree(target)
with _patch_root(True), mock.patch("core.privilege.os.chown") as chown:
privilege.chown_tree_to_target(target)
paths = sorted(call.args[0] for call in chown.call_args_list)
expected = sorted(
[
str(target),
str(target / "a.txt"),
str(target / "sub"),
str(target / "sub" / "b.txt"),
str(target / "sub" / "c.txt"),
]
)
assert paths == expected
for call in chown.call_args_list:
assert call.args[1:] == (1000, 1000)
assert call.kwargs == {"follow_symlinks": False}
def test_chown_tree_noop_when_not_root(tmp_path, monkeypatch):
"""Local dev / CI: same env vars, but no real privilege to chown — skip."""
monkeypatch.setenv("SETUID", "1000")
monkeypatch.setenv("SETGID", "1000")
target = tmp_path / "workdir"
_make_tree(target)
with _patch_root(False), mock.patch("core.privilege.os.chown") as chown:
privilege.chown_tree_to_target(target)
chown.assert_not_called()
def test_chown_tree_noop_when_env_vars_unset(tmp_path, monkeypatch):
monkeypatch.delenv("SETUID", raising=False)
monkeypatch.delenv("SETGID", raising=False)
target = tmp_path / "workdir"
_make_tree(target)
with _patch_root(True), mock.patch("core.privilege.os.chown") as chown:
privilege.chown_tree_to_target(target)
chown.assert_not_called()
def test_chown_tree_uses_minus_one_for_missing_uid_or_gid(tmp_path, monkeypatch):
"""When only one of SETUID/SETGID is set, the other side is left unchanged
via the chown ``-1`` sentinel."""
monkeypatch.setenv("SETUID", "1000")
monkeypatch.delenv("SETGID", raising=False)
target = tmp_path / "workdir"
target.mkdir()
(target / "f.txt").write_text("x")
with _patch_root(True), mock.patch("core.privilege.os.chown") as chown:
privilege.chown_tree_to_target(target)
for call in chown.call_args_list:
assert call.args[1:] == (1000, -1)
File diff suppressed because it is too large Load Diff
+190
View File
@@ -0,0 +1,190 @@
"""Tests for core.setup — copies uploaded context files into the workdir."""
import os
import shutil
import tempfile
import unittest
from pathlib import Path
from unittest import mock
from core import setup as setup_mod # aliased to avoid clash with pytest's xunit setup_module fixture
from core.tools import sandbox
class SetupTests(unittest.TestCase):
def setUp(self):
self.temp_dir = Path(tempfile.mkdtemp())
self.world_root = self.temp_dir / "world"
self.workdir = self.temp_dir / "workdir"
self.world_root.mkdir()
self._original_workdir = sandbox.WORKDIR
sandbox.WORKDIR = str(self.workdir)
def tearDown(self):
sandbox.WORKDIR = self._original_workdir
shutil.rmtree(self.temp_dir, ignore_errors=True)
def _run(self, task_id: str | None = None) -> int:
"""Invoke setup.main() in-process and return its exit code (0 on normal return)."""
env = {"WORLDBENCH_ROOT": str(self.world_root)}
if task_id is not None:
env["WORLDBENCH_TASK_ID"] = task_id
with mock.patch.dict(os.environ, env, clear=False):
os.environ.pop("BUNDLEDIR", None)
if task_id is None:
os.environ.pop("WORLDBENCH_TASK_ID", None)
try:
setup_mod.main()
return 0
except SystemExit as e:
return int(e.code or 0)
def test_copies_task_specific_files_into_workdir(self):
"""Task-specific setup_data/{task_id}/files/ is copied into WORKDIR."""
task_id = "task-abc"
files_dir = self.world_root / "tasks" / "setup_data" / task_id / "files"
files_dir.mkdir(parents=True)
(files_dir / "james.txt").write_text("james is the CEO")
(files_dir / "nested").mkdir()
(files_dir / "nested" / "notes.md").write_text("# notes")
assert self._run(task_id=task_id) == 0
assert (self.workdir / "james.txt").read_text() == "james is the CEO"
assert (self.workdir / "nested" / "notes.md").read_text() == "# notes"
def test_falls_back_to_generic_setup_data_when_task_dir_missing(self):
"""If no task-specific dir exists, copies from {world_root}/setup_data/files/."""
generic_files = self.world_root / "setup_data" / "files"
generic_files.mkdir(parents=True)
(generic_files / "shared.txt").write_text("shared context")
assert self._run(task_id="unknown-task") == 0
assert (self.workdir / "shared.txt").read_text() == "shared context"
def test_uses_generic_when_no_task_id(self):
"""With no WORLDBENCH_TASK_ID set, generic setup_data/files/ is used."""
generic_files = self.world_root / "setup_data" / "files"
generic_files.mkdir(parents=True)
(generic_files / "default.txt").write_text("default")
assert self._run(task_id=None) == 0
assert (self.workdir / "default.txt").read_text() == "default"
def test_merges_into_existing_workdir(self):
"""Existing workdir contents are preserved; new files are added alongside."""
self.workdir.mkdir(parents=True)
(self.workdir / "preexisting.txt").write_text("keep me")
generic_files = self.world_root / "setup_data" / "files"
generic_files.mkdir(parents=True)
(generic_files / "new.txt").write_text("new file")
assert self._run(task_id=None) == 0
assert (self.workdir / "preexisting.txt").read_text() == "keep me"
assert (self.workdir / "new.txt").read_text() == "new file"
def test_no_setup_data_exits_cleanly(self):
"""If neither task-specific nor generic setup_data exists, exit 0 without error."""
assert self._run(task_id="whatever") == 0
def test_setup_data_without_files_subdir_is_noop(self):
"""setup_data/ with no files/ subdirectory is a no-op (does not error).
Workdir IS created (ensure_workdir runs unconditionally so subsequent
tools have something to chdir into), but no files are copied.
"""
(self.world_root / "setup_data").mkdir()
assert self._run(task_id=None) == 0
def test_rejects_symlink_in_setup_files(self):
"""Symlinks in the source tree are refused — they'd let a bundle
materialize an arbitrary host path (e.g. /app/tasks) into /workdir
and then chown it to the model user."""
files_dir = self.world_root / "setup_data" / "files"
files_dir.mkdir(parents=True)
(files_dir / "real.txt").write_text("ok")
# Target doesn't need to exist for the check to fire.
os.symlink("/app/tasks", str(files_dir / "rubrics"))
assert self._run(task_id=None) == 1
assert not (self.workdir / "rubrics").exists()
assert not (self.workdir / "real.txt").exists() # copytree never ran
def test_rejects_symlinked_files_dir_root(self):
"""A symlinked files/ root is rejected too."""
real_dir = self.world_root / "setup_data" / "real_files"
real_dir.mkdir(parents=True)
(real_dir / "x.txt").write_text("x")
os.symlink(str(real_dir), str(self.world_root / "setup_data" / "files"))
assert self._run(task_id=None) == 1
assert not (self.workdir / "x.txt").exists()
def test_rejects_hardlink_in_setup_files(self):
"""Hardlinked files in the source tree are refused — they could
point at a locked-down inode (e.g. /app/packages/grading/*) and
slip past the symlink guard."""
files_dir = self.world_root / "setup_data" / "files"
files_dir.mkdir(parents=True)
# Two paths sharing one inode: the "target" simulates a protected
# file outside the bundle; the entry inside files/ is its hardlink.
protected = self.temp_dir / "fake-protected.py"
protected.write_text("rubric body")
os.link(str(protected), str(files_dir / "rubric.py"))
assert self._run(task_id=None) == 1
assert not (self.workdir / "rubric.py").exists()
def test_rejects_preexisting_workdir_symlink(self):
"""A symlink planted in /workdir before setup runs is refused —
otherwise copytree(dirs_exist_ok=True) would write through it as
root, into paths the model can't normally write."""
files_dir = self.world_root / "setup_data" / "files"
files_dir.mkdir(parents=True)
(files_dir / "context").mkdir()
(files_dir / "context" / "doc.txt").write_text("payload")
# Plant a model-controlled symlink in /workdir before setup.
self.workdir.mkdir(parents=True)
protected_target = self.temp_dir / "fake-protected-dir"
protected_target.mkdir()
os.symlink(str(protected_target), str(self.workdir / "context"))
assert self._run(task_id=None) == 1
# The bundle file must not have been written through the symlink.
assert not (protected_target / "doc.txt").exists()
def test_chowns_workdir_to_target_uid_gid_when_root(self):
"""Under (mocked) root, copied files are chowned back to SETUID:SETGID
so the unprivileged model user can modify them."""
generic_files = self.world_root / "setup_data" / "files"
generic_files.mkdir(parents=True)
(generic_files / "a.txt").write_text("hello")
(generic_files / "sub").mkdir()
(generic_files / "sub" / "b.txt").write_text("world")
env = {"WORLDBENCH_ROOT": str(self.world_root), "SETUID": "1000", "SETGID": "1000"}
with (
mock.patch.dict(os.environ, env, clear=False),
mock.patch("core.privilege.os.geteuid", return_value=0),
mock.patch("core.privilege.os.chown") as chown,
):
os.environ.pop("BUNDLEDIR", None)
os.environ.pop("WORLDBENCH_TASK_ID", None)
setup_mod.main()
chowned = sorted(call.args[0] for call in chown.call_args_list)
# ensure_workdir chowns WORKDIR; chown_tree_to_target chowns it again plus
# every entry under it. We only assert the post-copy entries are present.
assert str(self.workdir / "a.txt") in chowned
assert str(self.workdir / "sub") in chowned
assert str(self.workdir / "sub" / "b.txt") in chowned
for call in chown.call_args_list:
assert call.args[1:] == (1000, 1000)
if __name__ == "__main__":
unittest.main()
@@ -0,0 +1,120 @@
"""Tests for the unified-bundle layout in core.setup.
When ``$BUNDLEDIR/files/`` is mounted (the production harness unpacks the unified
trajectory bundle there), core.setup should copy from that path instead
of the legacy ``setup_data/files/`` location. We point ``BUNDLEDIR`` at a
temp path so the test doesn't depend on the production mount path.
"""
import os
import shutil
import tempfile
import unittest
from pathlib import Path
from unittest import mock
from core import setup as setup_mod # aliased to avoid clash with pytest's xunit setup_module fixture
from core.tools import sandbox
class BundleLayoutTests(unittest.TestCase):
def setUp(self):
self.temp_dir = Path(tempfile.mkdtemp())
self.world_root = self.temp_dir / "world"
self.workdir = self.temp_dir / "workdir"
self.bundle_dir = self.temp_dir / "bundle"
self.world_root.mkdir()
self._env_patch = mock.patch.dict(
os.environ,
{
"WORLDBENCH_ROOT": str(self.world_root),
"BUNDLEDIR": str(self.bundle_dir),
},
clear=False,
)
self._env_patch.start()
os.environ.pop("WORLDBENCH_TASK_ID", None)
self._original_workdir = sandbox.WORKDIR
sandbox.WORKDIR = str(self.workdir)
def tearDown(self):
sandbox.WORKDIR = self._original_workdir
self._env_patch.stop()
shutil.rmtree(self.temp_dir, ignore_errors=True)
def test_bundle_files_take_precedence_over_legacy_setup_data(self):
"""When $BUNDLEDIR/files/ exists, it's used instead of setup_data/files/."""
bundle_files = self.bundle_dir / "files"
bundle_files.mkdir(parents=True)
(bundle_files / "from_bundle.txt").write_text("from bundle")
legacy_files = self.world_root / "setup_data" / "files"
legacy_files.mkdir(parents=True)
(legacy_files / "from_legacy.txt").write_text("from legacy")
setup_mod.main()
assert (self.workdir / "from_bundle.txt").read_text() == "from bundle"
assert not (self.workdir / "from_legacy.txt").exists()
def test_falls_back_to_legacy_when_bundle_dir_absent(self):
"""When BUNDLEDIR points at a path that doesn't exist on disk, the
legacy setup_data path still works."""
# bundle_dir intentionally not created
legacy_files = self.world_root / "setup_data" / "files"
legacy_files.mkdir(parents=True)
(legacy_files / "from_legacy.txt").write_text("from legacy")
setup_mod.main()
assert (self.workdir / "from_legacy.txt").read_text() == "from legacy"
def test_falls_back_to_legacy_when_bundledir_unset(self):
"""When BUNDLEDIR isn't set at all (common local-dev path), the
legacy setup_data path is used."""
os.environ.pop("BUNDLEDIR", None)
legacy_files = self.world_root / "setup_data" / "files"
legacy_files.mkdir(parents=True)
(legacy_files / "from_legacy.txt").write_text("from legacy")
setup_mod.main()
assert (self.workdir / "from_legacy.txt").read_text() == "from legacy"
def test_bundle_and_legacy_produce_equivalent_workdir(self):
"""Same files served via either layout yield the same WORKDIR contents."""
contents = {"a.txt": "alpha", "nested/b.md": "# beta"}
# First run: bundle layout
bundle_files = self.bundle_dir / "files"
for rel, body in contents.items():
p = bundle_files / rel
p.parent.mkdir(parents=True, exist_ok=True)
p.write_text(body)
setup_mod.main()
bundle_snapshot = {
str(p.relative_to(self.workdir)): p.read_text() for p in self.workdir.rglob("*") if p.is_file()
}
# Second run: same files via legacy layout, fresh workdir
shutil.rmtree(self.bundle_dir)
shutil.rmtree(self.workdir, ignore_errors=True)
legacy_files = self.world_root / "setup_data" / "files"
for rel, body in contents.items():
p = legacy_files / rel
p.parent.mkdir(parents=True, exist_ok=True)
p.write_text(body)
setup_mod.main()
legacy_snapshot = {
str(p.relative_to(self.workdir)): p.read_text() for p in self.workdir.rglob("*") if p.is_file()
}
assert bundle_snapshot == legacy_snapshot
if __name__ == "__main__":
unittest.main()
+55
View File
@@ -0,0 +1,55 @@
"""Tests for core's sandbox viewer app — focused on the download path, which
streams file bytes from a uid-1000 reader instead of buffering them whole."""
import os
import pytest
from starlette.testclient import TestClient
from core import viewer
from core.tools import sandbox
@pytest.fixture
def client(tmp_path, monkeypatch):
# Point WORKDIR at a temp dir so reads stay confined to it, and run the
# viewer with no proxy token so the middleware lets requests through.
monkeypatch.setattr(sandbox, "WORKDIR", str(tmp_path))
monkeypatch.setattr(viewer, "get_proxy_token", lambda: None)
return TestClient(viewer.create_core_viewer_app())
def test_download_streams_file_contents(client, tmp_path):
payload = bytes(range(256)) * 1000 # 256 KB — larger than one read() chunk
(tmp_path / "data.bin").write_bytes(payload)
resp = client.get("/api/download", params={"path": "data.bin"})
assert resp.status_code == 200
assert resp.content == payload
assert resp.headers["content-type"] == "application/octet-stream"
assert 'filename="data.bin"' in resp.headers["content-disposition"]
def test_download_empty_file(client, tmp_path):
(tmp_path / "empty.bin").write_bytes(b"")
resp = client.get("/api/download", params={"path": "empty.bin"})
assert resp.status_code == 200
assert resp.content == b""
def test_download_missing_file_returns_404(client):
resp = client.get("/api/download", params={"path": "nope.bin"})
assert resp.status_code == 404
def test_download_path_escape_rejected(client):
resp = client.get("/api/download", params={"path": "../../etc/passwd"})
assert resp.status_code == 400
def test_download_fifo_returns_404_not_hang(client, tmp_path):
# An agent-created named pipe must not block a request worker waiting for a
# writer — it's rejected as a non-regular file. (No writer is opened, so a
# regression here would hang the test.)
os.mkfifo(tmp_path / "pipe")
resp = client.get("/api/download", params={"path": "pipe"})
assert resp.status_code == 404