mirror of
https://github.com/priyanshujain/messageboardbench.git
synced 2026-10-02 19:17:07 +00:00
Support immutable local SWE image IDs
This commit is contained in:
1 parent
69c5793562
commit
1428c2b08e
9 files changed
+129
-43
No files matched your search
+12
-8
@@ -13,6 +13,10 @@ from messageboardbench.board import MESSAGEBOARD_V2_INTERFACE_VERSION, initializ
|
||||
from messageboardbench.feedback import initialize_feedback
|
||||
|
||||
|
||||
IMAGE_ID = "sha256:" + "a" * 64
|
||||
REPO_DIGEST = "repo@sha256:" + "d" * 64
|
||||
|
||||
|
||||
def records(count=349):
|
||||
return {f"owner__repo-{index:03d}": {"instance_id": f"owner__repo-{index:03d}",
|
||||
"value": index}
|
||||
@@ -119,11 +123,11 @@ def test_compose_has_no_mount_and_network_none():
|
||||
def test_write_compose_uses_validated_digest_override(tmp_path, monkeypatch):
|
||||
monkeypatch.setattr(module, "swebench_spec", lambda record: ("repo:latest", [], "pytest"))
|
||||
path = module.write_compose(
|
||||
{"instance_id": "task"}, tmp_path, image_override="repo@sha256:validated"
|
||||
{"instance_id": "task"}, tmp_path, image_override=REPO_DIGEST
|
||||
)
|
||||
assert "repo@sha256:validated" in path.read_text()
|
||||
assert REPO_DIGEST in path.read_text()
|
||||
assert "repo:latest" not in path.read_text()
|
||||
with pytest.raises(ValueError, match="repository digest"):
|
||||
with pytest.raises(ValueError, match="immutable image reference"):
|
||||
module.write_compose({"instance_id": "other"}, tmp_path, image_override="repo:latest")
|
||||
|
||||
|
||||
@@ -134,10 +138,10 @@ def test_sample_binds_fresh_grader_to_validated_digest(tmp_path):
|
||||
"instance_id": "task", "problem_statement": "fix it", "test_patch": "patch"
|
||||
}
|
||||
sample = module.sample_from_record(
|
||||
value, compose, grader_image="repo@sha256:validated"
|
||||
value, compose, grader_image=IMAGE_ID
|
||||
)
|
||||
assert sample.metadata["messageboardbench_grader_image"] == "repo@sha256:validated"
|
||||
with pytest.raises(ValueError, match="repository digest"):
|
||||
assert sample.metadata["messageboardbench_grader_image"] == IMAGE_ID
|
||||
with pytest.raises(ValueError, match="immutable image reference"):
|
||||
module.sample_from_record(value, compose, grader_image="repo:latest")
|
||||
|
||||
|
||||
@@ -237,7 +241,7 @@ def test_paid_scorer_restores_tests_and_uses_fresh_digest_grader(
|
||||
state = SimpleNamespace(
|
||||
metadata={
|
||||
"_messageboardbench_evaluator_commit": "a" * 40,
|
||||
"messageboardbench_grader_image": "repo@sha256:validated",
|
||||
"messageboardbench_grader_image": IMAGE_ID,
|
||||
"test_patch": "--- a/tests/test_x.py\n+++ b/tests/test_x.py\n",
|
||||
"base_commit": "b" * 40,
|
||||
"FAIL_TO_PASS": ["target"], "PASS_TO_PASS": [],
|
||||
@@ -252,7 +256,7 @@ def test_paid_scorer_restores_tests_and_uses_fresh_digest_grader(
|
||||
score = asyncio.run(invocation)
|
||||
assert score.value == 1.0
|
||||
assert captured["model_patch"] == "model patch"
|
||||
assert captured["image"] == "repo@sha256:validated"
|
||||
assert captured["image"] == IMAGE_ID
|
||||
assert captured["memory"] == "9g" and captured["timeout_seconds"] == 77
|
||||
assert score.metadata["test_modified_ever"] is True
|
||||
assert score.metadata["grader_container_fresh"] is True
|
||||
|
||||
@@ -21,6 +21,10 @@ from scripts.validate_swe_population_prerequisites import (
|
||||
)
|
||||
|
||||
|
||||
IMAGE_ID = "sha256:" + "a" * 64
|
||||
REPO_DIGEST = "repo@sha256:" + "d" * 64
|
||||
|
||||
|
||||
def write(path, value):
|
||||
path.parent.mkdir(parents=True, exist_ok=True)
|
||||
path.write_text(value if isinstance(value, str) else json.dumps(value))
|
||||
@@ -52,7 +56,7 @@ def fixture(tmp_path):
|
||||
eval_hash = write(tmp_path / "evidence" / eval_name, eval_text)
|
||||
cells.append({"split": split, "mode": mode, "resolved": expected[split, mode],
|
||||
"image": "repo:tag", "test_command": ["pytest"],
|
||||
"image_id": "sha256:image", "repo_digests": ["repo@sha256:digest"],
|
||||
"image_id": IMAGE_ID, "repo_digests": [REPO_DIGEST],
|
||||
"grader_container_fresh": True,
|
||||
"eval_script_sha256": eval_hash, "eval_script_file": eval_name,
|
||||
"model_patch_sha256": (
|
||||
@@ -69,8 +73,8 @@ def fixture(tmp_path):
|
||||
"grader_isolation": "fresh-container-per-scoring-attempt",
|
||||
"grading_lifecycle": prerequisites_module.GRADING_LIFECYCLE,
|
||||
"image": "repo:tag",
|
||||
"remote_image": {"id": "sha256:image",
|
||||
"repo_digests": ["repo@sha256:digest"]},
|
||||
"remote_image": {"id": IMAGE_ID, "repo_digests": [REPO_DIGEST],
|
||||
"immutable_ref": REPO_DIGEST},
|
||||
"test_command": ["pytest"],
|
||||
"base_commit": "base", "repo": "org/repo", "version": "1",
|
||||
"original_test_patch_sha256": hashlib.sha256(b"original").hexdigest(),
|
||||
@@ -116,6 +120,28 @@ def test_environment_index_is_required_and_plan_bound(tmp_path):
|
||||
validate_environment_index(plan, tmp_path)
|
||||
|
||||
|
||||
def test_environment_index_accepts_content_addressed_local_image_without_repo_digest(
|
||||
tmp_path,
|
||||
):
|
||||
plan, manifest_path, record = fixture(tmp_path)
|
||||
manifest = json.loads(manifest_path.read_text())
|
||||
manifest["remote_image"] = {
|
||||
"id": IMAGE_ID, "repo_digests": [], "immutable_ref": IMAGE_ID,
|
||||
}
|
||||
for row in manifest["results"]:
|
||||
row["repo_digests"] = []
|
||||
manifest_hash = write(manifest_path, manifest)
|
||||
index_path = tmp_path / "index.json"
|
||||
index = json.loads(index_path.read_text())
|
||||
index["manifests"]["task"]["sha256"] = manifest_hash
|
||||
write(index_path, index)
|
||||
|
||||
evidence = validate_environment_index_for_records(plan, tmp_path, {"task": record})
|
||||
selected = evidence["validated_instances"][0]
|
||||
assert selected["validated_image_ref"] == IMAGE_ID
|
||||
assert selected["validated_repo_digest"] is None
|
||||
|
||||
|
||||
def test_unresolved_cell_requires_an_actual_failed_target(tmp_path):
|
||||
plan, manifest_path, record = fixture(tmp_path)
|
||||
manifest = json.loads(manifest_path.read_text())
|
||||
|
||||
@@ -10,6 +10,10 @@ import pytest
|
||||
from messageboardbench import swe_validation as module
|
||||
|
||||
|
||||
IMAGE_ID = "sha256:" + "a" * 64
|
||||
REPO_DIGEST = "repo@sha256:" + "d" * 64
|
||||
|
||||
|
||||
def record(**changes):
|
||||
value = {
|
||||
"instance_id": "owner__repo-1",
|
||||
@@ -34,8 +38,8 @@ def result(split: str, mode: str, *, resolved: bool, exit_code: int):
|
||||
output_file=f"{split}-{mode}.txt",
|
||||
output_sha256="0" * 64,
|
||||
image="swebench/sweb.eval.x86_64.example:latest",
|
||||
image_id="sha256:abc",
|
||||
repo_digests=["swebench/example@sha256:def"],
|
||||
image_id=IMAGE_ID,
|
||||
repo_digests=[REPO_DIGEST],
|
||||
test_command=["pytest", "tests/test_x.py"],
|
||||
target_statuses={"tests/test_x.py::test_bug": "PASSED" if resolved else "FAILED"},
|
||||
resolved=resolved,
|
||||
@@ -115,18 +119,32 @@ def test_matrix_rejects_image_identity_drift():
|
||||
def test_image_identity_requires_digest_and_amd64():
|
||||
def run(command, **kwargs):
|
||||
payload = {
|
||||
"Id": "sha256:abc",
|
||||
"RepoDigests": ["repo@sha256:def"],
|
||||
"Id": IMAGE_ID,
|
||||
"RepoDigests": [REPO_DIGEST],
|
||||
"Os": "linux",
|
||||
"Architecture": "amd64",
|
||||
}
|
||||
return subprocess.CompletedProcess(command, 0, __import__("json").dumps(payload), "")
|
||||
|
||||
assert module.image_identity("repo:tag", {"DOCKER_HOST": module.REMOTE_DOCKER_HOST}, run) == (
|
||||
"sha256:abc", ["repo@sha256:def"]
|
||||
IMAGE_ID, [REPO_DIGEST]
|
||||
)
|
||||
|
||||
|
||||
def test_image_identity_accepts_local_content_address_without_repo_digest():
|
||||
def run(command, **kwargs):
|
||||
payload = {
|
||||
"Id": IMAGE_ID, "RepoDigests": [], "Os": "linux", "Architecture": "amd64",
|
||||
}
|
||||
return subprocess.CompletedProcess(command, 0, __import__("json").dumps(payload), "")
|
||||
|
||||
identity = module.image_identity(
|
||||
"local:tag", {"DOCKER_HOST": module.REMOTE_DOCKER_HOST}, run
|
||||
)
|
||||
assert identity == (IMAGE_ID, [])
|
||||
assert module.immutable_image_reference(*identity) == IMAGE_ID
|
||||
|
||||
|
||||
def test_semantic_audit_is_bound_to_pair_hashes():
|
||||
expected = {
|
||||
"dataset": module.DATASET,
|
||||
@@ -198,7 +216,7 @@ def test_fresh_grader_runs_exact_testspec_script_with_install_and_network_none(m
|
||||
return subprocess.CompletedProcess(command, 0, stdout, "")
|
||||
|
||||
evaluated, output, statuses, script_hash, preserved_script = module.run_fresh_grader(
|
||||
record(), model_patch="diff --git a/x b/x\n", image="repo@sha256:digest",
|
||||
record(), model_patch="diff --git a/x b/x\n", image=REPO_DIGEST,
|
||||
environ={"DOCKER_HOST": module.REMOTE_DOCKER_HOST}, run=run,
|
||||
)
|
||||
assert evaluated.returncode == 0
|
||||
|
||||
@@ -103,6 +103,7 @@ def test_environment_validation_uses_preserved_snapshot(tmp_path, monkeypatch):
|
||||
"manifest_sha256": digest(archived_manifest),
|
||||
"validated_image": "image",
|
||||
"validated_image_id": "image-id",
|
||||
"validated_image_ref": "repo-digest",
|
||||
"validated_repo_digest": "repo-digest",
|
||||
}],
|
||||
}
|
||||
@@ -110,7 +111,8 @@ def test_environment_validation_uses_preserved_snapshot(tmp_path, monkeypatch):
|
||||
from messageboardbench import swe_prerequisites
|
||||
monkeypatch.setattr(swe_prerequisites, "validate_task_manifest", lambda *args, **kwargs: {
|
||||
"image": "image",
|
||||
"remote_image": {"id": "image-id", "repo_digests": ["repo-digest"]},
|
||||
"remote_image": {"id": "image-id", "repo_digests": ["repo-digest"],
|
||||
"immutable_ref": "repo-digest"},
|
||||
})
|
||||
|
||||
assert matches(manifest, frozen, tmp_path / "run")
|
||||
|
||||
Reference in new issue
Block a user