fix(eval): finish the index-cache removal in the docker harness

The eval-server side of the index cache is gone, but the docker harness
still carried the producer half: every container setup ran
_restore_or_skip_cache, which resolved a cache key, mkdir'd
/root/.gortex-cache and put_archive'd index.tar.gz into it, then logged
"Cached index restored". Nothing inside the container ever read that
tarball, so each eval instance paid the copy and emitted a cache-hit line
that did not correspond to a cache hit.

Remove the whole plumbing: the restore call and its method, _make_cache_key,
DEFAULT_CACHE_DIR, the cache_dir constructor parameter, _get_repo_identity
(its only caller was the restore path), the run_eval pass-through of
env_cfg["cache_dir"], and the cache-key/cache_dir assertions in the eval
tests. The module docstring no longer promises to mount cached indexes.
This commit is contained in:
Andrey Kumanyaev
2026-08-09 18:34:25 +02:00
parent 75a391edc1
commit dbc0feffe6
4 changed files with 4 additions and 90 deletions
+1 -51
View File
@@ -5,8 +5,7 @@ Manages the full container lifecycle for a single eval instance:
2. Copy gortex binary and tool bridge scripts (native/native_augment modes)
3. Start eval-server inside container, health-check with configurable timeout
4. Extract patch (git diff) before teardown
5. Mount/copy cached indexes when available
6. Record setup failures gracefully — never raise, return failure result
5. Record setup failures gracefully — never raise, return failure result
Architecture:
Agent bash cmd → /usr/local/bin/gortex-search → curl localhost:4747/tool/search_symbols
@@ -29,7 +28,6 @@ logger = logging.getLogger("gortex_docker")
DEFAULT_EVAL_SERVER_PORT = 4747
DEFAULT_GORTEX_TIMEOUT = 120
DEFAULT_CACHE_DIR = Path.home() / ".gortex-eval-cache"
HEALTH_CHECK_INTERVAL = 2.0
CONTAINER_WORKDIR = "/testbed"
GORTEX_BINARY_CONTAINER_PATH = "/usr/local/bin/gortex"
@@ -46,12 +44,6 @@ _BRIDGE_SCRIPTS = [
]
def _make_cache_key(repo_name: str, commit_hash: str) -> str:
"""Build a deterministic cache directory name from repo and commit."""
safe_repo = repo_name.replace("/", "__")
return f"{safe_repo}_{commit_hash}"
class GortexDockerEnvironment:
"""Docker environment managing the full container lifecycle for Gortex eval.
@@ -71,7 +63,6 @@ class GortexDockerEnvironment:
gortex_binary: str | Path | None = None,
gortex_timeout: int = DEFAULT_GORTEX_TIMEOUT,
eval_server_port: int = DEFAULT_EVAL_SERVER_PORT,
cache_dir: str | Path | None = None,
instance_id: str = "",
) -> None:
self.image = image
@@ -80,7 +71,6 @@ class GortexDockerEnvironment:
self.gortex_binary = Path(gortex_binary) if gortex_binary else None
self.gortex_timeout = gortex_timeout
self.eval_server_port = eval_server_port
self.cache_dir = Path(cache_dir) if cache_dir else DEFAULT_CACHE_DIR
self.instance_id = instance_id
self._client: docker.DockerClient | None = None
@@ -111,7 +101,6 @@ class GortexDockerEnvironment:
start = time.time()
self._copy_gortex_binary()
self._copy_bridge_scripts()
self._restore_or_skip_cache()
self._start_eval_server()
self._wait_for_health()
self.index_time = time.time() - start
@@ -263,31 +252,6 @@ class GortexDockerEnvironment:
copied += 1
logger.info("Copied %d bridge scripts into container", copied)
def _restore_or_skip_cache(self) -> None:
"""Mount/copy a cached index into the container if one exists."""
repo_name, commit_hash = self._get_repo_identity()
cache_key = _make_cache_key(repo_name, commit_hash)
cache_path = self.cache_dir / cache_key
if not cache_path.is_dir():
logger.info("No cached index for %s, eval-server will index fresh", cache_key)
return
tarball = cache_path / "index.tar.gz"
if not tarball.is_file():
logger.info("Cache dir exists but no tarball for %s, skipping", cache_key)
return
logger.info("Restoring cached index %s into container", cache_key)
try:
cache_dest = "/root/.gortex-cache"
self._container.exec_run(["mkdir", "-p", cache_dest])
with open(tarball, "rb") as f:
self._container.put_archive(cache_dest, f.read())
logger.info("Cached index restored to %s", cache_dest)
except Exception as exc:
logger.warning("Cache restore failed, will index fresh: %s", exc)
def _start_eval_server(self) -> None:
"""Start ``gortex eval-server`` as a background process in the container."""
cmd = (
@@ -341,20 +305,6 @@ class GortexDockerEnvironment:
f"for instance {self.instance_id}. Server log tail:\n{log_tail}"
)
def _get_repo_identity(self) -> tuple[str, str]:
"""Extract (repo_name, commit_hash) from the container's /testbed repo."""
_, repo_out = self._container.exec_run(
["bash", "-c", "basename $(git remote get-url origin 2>/dev/null || basename $(pwd)) .git"],
workdir=self.repo_path,
)
_, commit_out = self._container.exec_run(
["bash", "-c", "git rev-parse HEAD 2>/dev/null || echo unknown"],
workdir=self.repo_path,
)
repo_name = repo_out.decode("utf-8", errors="replace").strip() or "unknown"
commit_hash = commit_out.decode("utf-8", errors="replace").strip() or "unknown"
return repo_name, commit_hash
def _put_file_in_container(
self,
local_path: Path,
-1
View File
@@ -250,7 +250,6 @@ def process_instance(
gortex_binary=env_cfg.get("gortex_binary"),
gortex_timeout=int(env_cfg.get("gortex_timeout", 120)),
eval_server_port=int(env_cfg.get("eval_server_port", 4747)),
cache_dir=env_cfg.get("cache_dir"),
instance_id=instance_id,
)
env.setup()
+1 -13
View File
@@ -21,7 +21,7 @@ import pytest
sys.path.insert(0, str(Path(__file__).resolve().parent.parent))
from environments.gortex_docker import GortexDockerEnvironment, _make_cache_key
from environments.gortex_docker import GortexDockerEnvironment
# --- Docker availability check ---
@@ -152,15 +152,3 @@ class TestDockerEnvironmentMocked:
assert result is not None
assert result["exit_status"] == "setup_failure"
assert "fail-test" in result["instance_id"]
def test_cache_key_determinism(self) -> None:
"""Cache key for same inputs is always the same."""
k1 = _make_cache_key("repo", "abc123")
k2 = _make_cache_key("repo", "abc123")
assert k1 == k2
def test_cache_key_uniqueness(self) -> None:
"""Different inputs produce different cache keys."""
k1 = _make_cache_key("repo_a", "commit1")
k2 = _make_cache_key("repo_b", "commit2")
assert k1 != k2
+2 -25
View File
@@ -1,7 +1,7 @@
"""Unit tests for eval/environments/gortex_docker.py.
Tests focus on pure logic (cache key, failure recording, properties)
and mock Docker interactions to avoid requiring a running Docker daemon.
Tests focus on pure logic (failure recording, properties) and mock
Docker interactions to avoid requiring a running Docker daemon.
"""
from __future__ import annotations
@@ -20,30 +20,9 @@ from environments.gortex_docker import (
DEFAULT_EVAL_SERVER_PORT,
DEFAULT_GORTEX_TIMEOUT,
GortexDockerEnvironment,
_make_cache_key,
)
# -- _make_cache_key ---------------------------------------------------------
class TestMakeCacheKey:
def test_basic(self):
assert _make_cache_key("django", "abc123") == "django_abc123"
def test_slash_in_repo_name(self):
assert _make_cache_key("django/django", "abc123") == "django__django_abc123"
def test_deterministic(self):
k1 = _make_cache_key("repo", "commit")
k2 = _make_cache_key("repo", "commit")
assert k1 == k2
def test_different_inputs_different_keys(self):
k1 = _make_cache_key("repo_a", "commit1")
k2 = _make_cache_key("repo_b", "commit2")
assert k1 != k2
# -- GortexDockerEnvironment init -------------------------------------------
class TestInit:
@@ -66,13 +45,11 @@ class TestInit:
gortex_binary="/tmp/gortex",
gortex_timeout=60,
eval_server_port=9999,
cache_dir="/tmp/cache",
instance_id="django__django-1234",
)
assert env.gortex_binary == Path("/tmp/gortex")
assert env.gortex_timeout == 60
assert env.eval_server_port == 9999
assert env.cache_dir == Path("/tmp/cache")
assert env.instance_id == "django__django-1234"