test(tools): probe and execute_code hand _create_environment the same container_config as the terminal tool

Replaces the source-reading AST check with a behaviour contract. Red on origin/main.
This commit is contained in:
kshitijk4poor
2026-09-05 18:25:05 +05:30
committed by kshitij
parent 7cad5da0f0
commit deaebd9b17

View File

@@ -18,45 +18,48 @@ def test_terminal_env_config_reads_docker_network_toggle(monkeypatch):
assert config["docker_network"] is False
def test_sibling_container_config_sites_carry_docker_network():
"""Every container_config dict that carries docker_run_as_host_user must
also carry docker_network — otherwise that code path silently falls back
to networked containers while the terminal path honors the lockdown
(the probe/exec asymmetry reported on issue #46358).
"""
import ast
import inspect
def test_every_sandbox_creator_passes_the_full_container_config(monkeypatch):
"""The terminal tool, execute_code and the prompt backend-probe must hand ``_create_environment``
the SAME container_config keys. Each used to keep a private (key, default) table and drifted:
the probe lost ``docker_network`` (bridge-networked probe under lockdown, #46358/#76906/#87995),
execute_code lost ``docker_extra_args``/``docker_forward_env``/``docker_env`` (#84027/#100019)."""
import agent.prompt_builder as prompt_builder
import tools.code_execution_tool as code_execution_tool
import tools.file_tools as file_tools
import tools.terminal_tool_backends as backends
# file_tools no longer builds its own container_config: it goes through
# the shared _create_configured_env, which is what carries docker_network.
assert "_create_configured_env(" in inspect.getsource(file_tools)
config = {"env_type": "docker", "cwd": "/root", "timeout": 60, "docker_network": False,
"docker_extra_args": ["--user", "1009:1009"], "docker_forward_env": ["DATABASE_URL"],
"docker_env": {"FOO": "bar"}, "docker_image": "debian:bookworm-slim"}
expected = backends._container_config_from_config(config)
seen: list = []
for module in (terminal_tool, code_execution_tool):
tree = ast.parse(inspect.getsource(module))
sites = 0
for node in ast.walk(tree):
# Accept a dict literal or a (key, default) pair table that a dict
# comprehension is built from.
if isinstance(node, ast.Dict):
keys = {k.value for k in node.keys if isinstance(k, ast.Constant)}
elif isinstance(node, ast.Tuple) and node.elts and all(
isinstance(e, ast.Tuple) and len(e.elts) == 2 and isinstance(e.elts[0], ast.Constant)
for e in node.elts
):
keys = {e.elts[0].value for e in node.elts}
else:
continue
if "docker_run_as_host_user" in keys:
sites += 1
assert "docker_network" in keys, (
f"{module.__name__} builds a container_config with "
f"docker_run_as_host_user but without docker_network "
f"(line {node.lineno})"
)
assert sites >= 1, f"expected at least one container_config site in {module.__name__}"
class _Env:
cwd = "/root"
def execute(self, *a, **k):
return {"output": "", "returncode": 0}
def cleanup(self, **k):
pass
def _fake_create(**kwargs):
seen.append(kwargs["container_config"])
return _Env()
# Both creators late-import their collaborators from terminal_tool / terminal_tool_backends.
monkeypatch.setattr(backends, "_create_environment", _fake_create)
monkeypatch.setattr(terminal_tool, "_get_env_config", lambda: config)
monkeypatch.setattr(terminal_tool, "_select_image", lambda *a, **k: "img")
monkeypatch.setattr(terminal_tool, "_resolve_task_host_cwd", lambda *a, **k: None)
monkeypatch.setattr(terminal_tool, "_start_cleanup_thread", lambda: None)
monkeypatch.setattr(terminal_tool, "_task_env_overrides", {})
monkeypatch.setattr(terminal_tool, "_active_environments", {})
prompt_builder._run_backend_probe("docker", terminal_tool)
code_execution_tool._get_or_create_env("cc-task")
assert seen == [expected, expected] # probe, then execute_code
assert expected["docker_network"] is False and expected["docker_extra_args"] == ["--user", "1009:1009"]
def _reuse_guard_harness(