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:
@@ -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,
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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"
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user