import argparse
import importlib.util
import subprocess
import sys
import tempfile
import unittest
from pathlib import Path
from unittest.mock import patch
from bench import gate_local as local
class WorktreeTests(unittest.TestCase):
def test_a_failure_inside_the_build_still_removes_the_worktree(self):
calls = []
def fake_git(*arguments, **kwargs):
calls.append(arguments)
return ""
with patch.object(local, "git", fake_git):
with patch.object(local.subprocess, "run", side_effect=RuntimeError("build blew up")):
with self.assertRaises(RuntimeError):
with local.at_commit("abc123", "kache", "kache", "head"):
pass
self.assertIn("add", calls[0])
self.assertEqual(calls[-1][:2], ("worktree", "remove"))
def test_the_body_runs_with_the_worktree_and_it_is_removed_after(self):
calls = []
with patch.object(local, "git", lambda *a, **k: calls.append(a) or ""):
with patch.object(local.subprocess, "run"):
with local.at_commit("abc123", "kache", "kache", "head") as tree:
self.assertTrue(str(tree).endswith("tree"))
self.assertEqual(calls[-1][:2], ("worktree", "remove"))
class StagingTests(unittest.TestCase):
def test_staged_entry_points_run_from_the_staging_directory(self):
scripts = Path(local.__file__).resolve().parent.parent
with tempfile.TemporaryDirectory() as tmp:
staging = Path(tmp) / "instrument"
staging.mkdir()
local.copy_instrument_scripts(scripts, staging)
self.assertFalse((staging / "bench" / "tests").exists())
for name in ("bench-short.py", "perf-gate-report.py"):
completed = subprocess.run(
[sys.executable, str(staging / name), "--help"],
capture_output=True,
text=True,
cwd=tmp,
)
self.assertEqual(completed.returncode, 0, completed.stderr)
class MeasureTests(unittest.TestCase):
def command_for(self, **overrides):
args = argparse.Namespace(
samples=3,
cold_every=1,
skip_contention=True,
head_sha="h" * 40,
base_sha="b" * 40,
instrument_sha="i" * 40,
)
for key, value in overrides.items():
setattr(args, key, value)
captured = {}
def fake_run(command, env=None, check=None):
captured["command"] = command
captured["env"] = env
return subprocess.CompletedProcess(command, 0)
with patch.object(local.subprocess, "run", fake_run):
local.measure(
"eza", args, Path("/stage"), Path("/head"), Path("/base"), Path("/out")
)
return captured
def test_it_drives_the_staged_instrument_not_the_working_tree(self):
captured = self.command_for()
command = captured["command"]
self.assertIn("/stage/bench-short.py", command)
self.assertEqual(command[command.index("--engine") + 1], "/stage/kache-scenario")
self.assertEqual(command[command.index("--scenarios") + 1], "/stage/scenarios")
self.assertEqual(command[command.index("--kache") + 1], "/head")
self.assertEqual(command[command.index("--base") + 1], "/base")
def test_cold_every_reaches_the_harness(self):
for value in (1, 3):
command = self.command_for(cold_every=value)["command"]
self.assertEqual(command[command.index("--cold-every") + 1], str(value))
def test_contention_is_opt_in(self):
self.assertIn("--skip-contention", self.command_for()["command"])
self.assertNotIn(
"--skip-contention", self.command_for(skip_contention=False)["command"]
)
def test_the_run_identifies_both_sides_and_the_instrument(self):
env = self.command_for()["env"]
self.assertEqual(env["BENCH_HEAD_SHA"], "h" * 40)
self.assertEqual(env["BENCH_BASE_SHA"], "b" * 40)
self.assertEqual(env["BENCH_INSTRUMENT_SHA"], "i" * 40)
self.assertEqual(env["RUSTC_WRAPPER"], "")
class ResolveTests(unittest.TestCase):
def test_an_unfetched_ref_says_to_fetch_it(self):
error = subprocess.CalledProcessError(1, ["git"])
with patch.object(local, "git", side_effect=error):
with self.assertRaises(SystemExit) as raised:
local.resolve("origin/main")
self.assertIn("git fetch", str(raised.exception))
def test_a_real_repository_resolves_head(self):
with tempfile.TemporaryDirectory() as tmp:
root = Path(tmp)
subprocess.run(["git", "init", "--quiet", str(root)], check=True)
subprocess.run(["git", "-C", str(root), "config", "user.email", "t@t"], check=True)
subprocess.run(["git", "-C", str(root), "config", "user.name", "t"], check=True)
(root / "f").write_text("x")
subprocess.run(["git", "-C", str(root), "add", "f"], check=True)
subprocess.run(
["git", "-C", str(root), "commit", "--quiet", "-m", "c", "--no-gpg-sign"],
check=True,
)
with patch.object(local, "REPO", root):
self.assertEqual(len(local.resolve("HEAD")), 40)
if __name__ == "__main__":
unittest.main()