mirror of
https://github.com/Abdess/retroarch_system.git
synced 2026-11-03 08:33:46 -06:00
refactor: read measurements from the local tree
The site compiles the index and the SQLite files from measurements/ instead of a pinned clone. The pin, the sync script, the CI clone steps, the freshness area and its refresh handler are gone. core_probe --record writes into measurements/ of the checkout by default, and a test fails when a line or data file HEAD holds changed or vanished.
This commit is contained in:
1 parent
7dca6ae052
commit
571e50f2a8
17 files changed
+699
-881
No files matched your search
+11
-15
@@ -263,9 +263,10 @@ class FakeCoreTests(unittest.TestCase):
|
||||
self.assertEqual(record["emulator"], "fake")
|
||||
self.assertEqual(sorted(p.relative_to(record_dir).as_posix()
|
||||
for p in record_dir.rglob("*") if p.is_file()),
|
||||
sorted(["records/fake.jsonl", f"data/fake/{self._only_id(record_dir)}.json.gz"]))
|
||||
line = json.loads((record_dir / "records" / "fake.jsonl").read_text())
|
||||
blob = (record_dir / "data" / "fake" / f"{line['id']}.json.gz").read_bytes()
|
||||
sorted(["measurements/fake.jsonl",
|
||||
f"measurements/data/fake/{self._only_id(record_dir)}.json.gz"]))
|
||||
line = json.loads((record_dir / "measurements" / "fake.jsonl").read_text())
|
||||
blob = (record_dir / "measurements" / "data" / "fake" / f"{line['id']}.json.gz").read_bytes()
|
||||
self.assertEqual(measurement_records.check_line(line), [])
|
||||
self.assertEqual(measurement_records.check_pair(line, blob), [])
|
||||
# The line and its sidecar give back the record the run printed.
|
||||
@@ -281,14 +282,14 @@ class FakeCoreTests(unittest.TestCase):
|
||||
|
||||
@staticmethod
|
||||
def _only_id(record_dir: Path) -> str:
|
||||
return json.loads((record_dir / "records" / "fake.jsonl").read_text())["id"]
|
||||
return json.loads((record_dir / "measurements" / "fake.jsonl").read_text())["id"]
|
||||
|
||||
def test_second_run_is_appended_beside_the_first(self) -> None:
|
||||
record_dir = self.tmp / "appended"
|
||||
argv = ["run", "--core", str(self.core), "--frames", "1", "--no-trace", "--max-load", "1000",
|
||||
"--record", str(record_dir), "--subject", "smoke"]
|
||||
self.assertEqual(self.probe(argv)[0], 0)
|
||||
lines = record_dir / "records" / "fake.jsonl"
|
||||
lines = record_dir / "measurements" / "fake.jsonl"
|
||||
first = lines.read_text()
|
||||
code, record = self.probe(argv)
|
||||
self.assertEqual(code, 0)
|
||||
@@ -301,16 +302,11 @@ class FakeCoreTests(unittest.TestCase):
|
||||
self.assertEqual(code, 2)
|
||||
self.assertEqual(len(lines.read_text().splitlines()), 3)
|
||||
|
||||
def test_recording_inside_the_tracked_tree_is_refused(self) -> None:
|
||||
inside = REPO_ROOT / "measurements"
|
||||
err = io.StringIO()
|
||||
with contextlib.redirect_stdout(io.StringIO()), contextlib.redirect_stderr(err):
|
||||
code = core_probe.main(["run", "--core", str(self.core), "--frames", "1", "--no-trace",
|
||||
"--record", str(inside), "--work-dir", str(self.tmp / "work")])
|
||||
self.assertEqual(code, 2)
|
||||
self.assertIn("inside the tracked tree", err.getvalue())
|
||||
self.assertIn(".cache/measurements", err.getvalue())
|
||||
self.assertFalse(inside.exists())
|
||||
def test_record_defaults_to_this_checkout(self) -> None:
|
||||
parser = core_probe.build_parser()
|
||||
args = parser.parse_args(["run", "--core", sys.executable, "--record", "--frames", "1"])
|
||||
self.assertEqual(Path(args.record), REPO_ROOT)
|
||||
self.assertIsNone(parser.parse_args(["run", "--core", sys.executable]).record)
|
||||
|
||||
def test_bench_stats(self) -> None:
|
||||
code, record = self.probe(["bench", "--core", str(self.core), "--frames", "2", "--warmup", "1",
|
||||
|
||||
+160
-117
@@ -1,16 +1,15 @@
|
||||
"""Core probe records in their own repository, and what the site makes of them.
|
||||
"""Core probe records under measurements/, and what the site makes of them.
|
||||
|
||||
A synthetic measurements repository is built with git under tmp/tests:
|
||||
records split into a line and a sidecar, read at a pinned commit, compiled
|
||||
into the index and the SQLite files. The append-only rule is checked the
|
||||
way --fetch applies it, and two branches that each add a line merge.
|
||||
Synthetic record trees are built under tmp/tests: records split into a line
|
||||
and a sidecar, read from the tree, compiled into the index and the SQLite
|
||||
files. The append-only rule is checked against a commit, two branches that
|
||||
each add a line merge, and the records this repository holds are checked
|
||||
against HEAD.
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import contextlib
|
||||
import copy
|
||||
import io
|
||||
import json
|
||||
import os
|
||||
import re
|
||||
@@ -26,10 +25,10 @@ REPO_ROOT = Path(__file__).resolve().parent.parent
|
||||
sys.path.insert(0, str(REPO_ROOT / "scripts"))
|
||||
|
||||
import measurement_records as mr # noqa: E402
|
||||
import sitemeasurements # noqa: E402
|
||||
import sync_measurements as sm # noqa: E402
|
||||
import sitemeasurements as sm # noqa: E402
|
||||
|
||||
REPO_URL = "https://github.com/Abdess/retrobios-measurements"
|
||||
REPO_URL = "https://github.com/Abdess/retrobios"
|
||||
COMMIT = "e" * 40
|
||||
SHA1 = "a" * 40
|
||||
SHA256 = "b" * 64
|
||||
|
||||
@@ -95,6 +94,8 @@ def full_record(emulator: str, subject: str, when: str, kind: str = "check",
|
||||
return record
|
||||
|
||||
|
||||
|
||||
|
||||
def git(cwd: Path, *args: str) -> str:
|
||||
env = {**os.environ, "GIT_AUTHOR_NAME": "t", "GIT_AUTHOR_EMAIL": "t@t", "GIT_COMMITTER_NAME": "t",
|
||||
"GIT_COMMITTER_EMAIL": "t@t", "GIT_CEILING_DIRECTORIES": str(cwd.parent)}
|
||||
@@ -122,32 +123,33 @@ def commit_all(tree: Path, message: str) -> str:
|
||||
|
||||
|
||||
class Workspace(unittest.TestCase):
|
||||
"""A measurements repository with three records and a pin on it."""
|
||||
"""A tree with three records under measurements/ and one profile."""
|
||||
|
||||
def setUp(self) -> None:
|
||||
(REPO_ROOT / "tmp" / "tests").mkdir(parents=True, exist_ok=True)
|
||||
self.tmp = Path(tempfile.mkdtemp(dir=REPO_ROOT / "tmp" / "tests"))
|
||||
self.addCleanup(shutil.rmtree, self.tmp, True)
|
||||
self.repo = self.tmp / "remote"
|
||||
self.repo.mkdir()
|
||||
git(self.repo, "init", "-q", "-b", "main")
|
||||
(self.repo / ".gitattributes").write_text("records/*.jsonl merge=union\n")
|
||||
self.first = add_record(self.repo, full_record("alpha", "card", "2026-10-01T10:00:00+00:00"))
|
||||
self.bench = add_record(self.repo, full_record("alpha", "speed", "2026-10-01T11:00:00+00:00",
|
||||
self.tree = self.tmp / "tree"
|
||||
self.tree.mkdir()
|
||||
self.first = add_record(self.tree, full_record("alpha", "card", "2026-10-01T10:00:00+00:00"))
|
||||
self.bench = add_record(self.tree, full_record("alpha", "speed", "2026-10-01T11:00:00+00:00",
|
||||
kind="bench"))
|
||||
self.beta = add_record(self.repo, full_record("beta", "card", "2026-10-02T10:00:00+00:00",
|
||||
self.beta = add_record(self.tree, full_record("beta", "card", "2026-10-02T10:00:00+00:00",
|
||||
values=("1" * 40, "1" * 40)))
|
||||
self.commit = commit_all(self.repo, "feat: first records")
|
||||
self.pin = self.tmp / "pin.json"
|
||||
sm.write_pin({"repo": str(self.repo), "commit": self.commit}, self.pin)
|
||||
self.emulators = self.tmp / "emulators"
|
||||
self.emulators.mkdir()
|
||||
(self.emulators / "alpha.yml").write_text(
|
||||
'emulator: "Alpha"\ntype: libretro\nsystems:\n - sega-saturn\nfiles: []\n')
|
||||
|
||||
def built(self, public: Path, clone: Path | None = None) -> sm.Built:
|
||||
return sm.build(public, clone or self.repo, self.pin, self.emulators, require=True,
|
||||
scratch=self.tmp / "scratch", system_names={"sega-saturn": "Sega Saturn"})
|
||||
def built(self, public: Path) -> sm.Built:
|
||||
return sm.build(public, self.tree, self.emulators, scratch=self.tmp / "scratch",
|
||||
system_names={"sega-saturn": "Sega Saturn"}, repo=REPO_URL, commit=COMMIT)
|
||||
|
||||
def repository(self) -> str:
|
||||
"""Make the tree a git repository, its records committed on main."""
|
||||
git(self.tree, "init", "-q", "-b", "main")
|
||||
(self.tree / ".gitattributes").write_text("measurements/*.jsonl merge=union\n")
|
||||
return commit_all(self.tree, "feat: first records")
|
||||
|
||||
|
||||
class RecordSplit(unittest.TestCase):
|
||||
@@ -211,17 +213,29 @@ class RecordSplit(unittest.TestCase):
|
||||
self.assertTrue(mr.check_pair(forged, blob))
|
||||
|
||||
|
||||
class SyncAndIndex(Workspace):
|
||||
def test_records_are_read_at_the_pin_not_the_working_tree(self) -> None:
|
||||
add_record(self.repo, full_record("alpha", "card", "2026-10-03T10:00:00+00:00"))
|
||||
records = sm.read_records(self.repo, self.commit)
|
||||
self.assertEqual(len(records), 3)
|
||||
|
||||
|
||||
class ReadAndIndex(Workspace):
|
||||
def test_records_are_read_from_the_tree(self) -> None:
|
||||
records = mr.read_records(self.tree)
|
||||
self.assertEqual([(s.emulator, s.line) for s in records], [("alpha", 1), ("alpha", 2), ("beta", 1)])
|
||||
self.assertEqual(mr.read_records(self.tmp / "empty"), [])
|
||||
|
||||
def test_a_broken_tree_is_named(self) -> None:
|
||||
stray = self.tree / mr.DATA_DIR / "beta" / "2026-10-02-000000000000.json.gz"
|
||||
stray.write_bytes(b"x")
|
||||
(self.tree / mr.sidecar_path("alpha", self.bench["id"])).unlink()
|
||||
with self.assertRaises(mr.MeasurementsError) as caught:
|
||||
mr.read_records(self.tree)
|
||||
message = str(caught.exception)
|
||||
self.assertIn(f"{mr.sidecar_path('alpha', self.bench['id'])} is missing", message)
|
||||
self.assertIn(f"{mr.DATA_DIR}/beta/2026-10-02-000000000000.json.gz: no record line names it", message)
|
||||
|
||||
def test_index_shape(self) -> None:
|
||||
index = self.built(self.tmp / "public").index
|
||||
self.assertEqual({k: index[k] for k in ("schema_version", "kind", "repo", "commit", "records", "count")},
|
||||
{"schema_version": 1, "kind": "measurements", "repo": str(self.repo),
|
||||
"commit": self.commit, "records": 3, "count": 3})
|
||||
{"schema_version": 1, "kind": "measurements", "repo": REPO_URL,
|
||||
"commit": COMMIT, "records": 3, "count": 3})
|
||||
keys = {"emulator", "emulator_name", "profiled", "systems", "system_names", "subject", "kind",
|
||||
"claim", "method", "observable", "variable", "status", "statement", "content",
|
||||
"variants", "repetitions", "flags", "date", "host", "core", "frontend_commit", "id",
|
||||
@@ -232,18 +246,28 @@ class SyncAndIndex(Workspace):
|
||||
self.assertEqual(alpha["card"]["status"], "differs")
|
||||
self.assertEqual(alpha["card"]["system_names"], ["Sega Saturn"])
|
||||
self.assertEqual(alpha["card"]["record_url"],
|
||||
f"{self.repo}/blob/{self.commit}/records/alpha.jsonl#L1")
|
||||
f"{REPO_URL}/blob/{COMMIT}/measurements/alpha.jsonl#L1")
|
||||
self.assertEqual(alpha["card"]["data_url"],
|
||||
f"{REPO_URL}/blob/{COMMIT}/measurements/data/alpha/{self.first['id']}.json.gz")
|
||||
self.assertEqual(alpha["speed"]["status"], "measured")
|
||||
self.assertIn("ms per frame", alpha["speed"]["statement"])
|
||||
self.assertIn("Test CPU", alpha["speed"]["host"])
|
||||
written = json.loads((self.tmp / "public" / sm.INDEX_PATH).read_text())
|
||||
self.assertEqual(written, index)
|
||||
|
||||
def test_links_name_the_last_commit_that_touched_the_records(self) -> None:
|
||||
first = self.repository()
|
||||
(self.tree / "other.txt").write_text("x")
|
||||
commit_all(self.tree, "chore: unrelated")
|
||||
self.assertEqual(mr.last_commit(self.tree), first)
|
||||
index = sm.build(self.tmp / "public", self.tree, self.emulators, scratch=self.tmp / "scratch").index
|
||||
self.assertEqual(index["commit"], first)
|
||||
self.assertTrue(all(f"/blob/{first}/measurements/" in i["record_url"] for i in index["items"]))
|
||||
|
||||
def test_latest_record_of_a_subject_wins_and_a_superseded_one_is_dropped(self) -> None:
|
||||
later = full_record("alpha", "card", "2026-10-05T10:00:00+00:00", values=("3" * 40, "3" * 40))
|
||||
later["supersedes"] = self.first["id"]
|
||||
add_record(self.repo, later)
|
||||
sm.write_pin({"repo": str(self.repo), "commit": commit_all(self.repo, "feat: rerun")}, self.pin)
|
||||
add_record(self.tree, later)
|
||||
card = next(i for i in self.built(self.tmp / "public").index["items"]
|
||||
if i["emulator"] == "alpha" and i["subject"] == "card")
|
||||
self.assertEqual((card["status"], card["runs"]), ("same", 1))
|
||||
@@ -257,7 +281,7 @@ class SyncAndIndex(Workspace):
|
||||
"SELECT name FROM sqlite_master WHERE type = 'table' ORDER BY rowid")]
|
||||
self.assertEqual(tuple(tables), sm.TABLES)
|
||||
count = lambda table: connection.execute(f"SELECT COUNT(*) FROM {table}").fetchone()[0] # noqa: E731
|
||||
records = [s.record for s in sm.read_records(self.repo, self.commit)]
|
||||
records = [s.record for s in mr.read_records(self.tree)]
|
||||
self.assertEqual(count("runs"), len(records))
|
||||
self.assertEqual(count("checks"), sum(1 for r in records if r.get("check")))
|
||||
self.assertEqual(count("benchmarks"), 2 * sum(1 for r in records if r.get("timing")))
|
||||
@@ -266,10 +290,12 @@ class SyncAndIndex(Workspace):
|
||||
sum(len(r["check"]["result"]["groups"]) for r in records if r.get("check")))
|
||||
self.assertEqual(count("hosts"), 1)
|
||||
self.assertEqual(count("cores"), 1)
|
||||
self.assertEqual(dict(connection.execute("SELECT key, value FROM meta"))["measurements_commit"],
|
||||
self.commit)
|
||||
meta = dict(connection.execute("SELECT key, value FROM meta"))
|
||||
self.assertEqual((meta["measurements_repo"], meta["measurements_commit"]), (REPO_URL, COMMIT))
|
||||
self.assertEqual(connection.execute("SELECT system FROM emulator_systems").fetchall(),
|
||||
[("sega-saturn",)])
|
||||
self.assertEqual(connection.execute("SELECT record_url FROM runs WHERE line = 1 AND emulator = 'beta'")
|
||||
.fetchone()[0], f"{REPO_URL}/blob/{COMMIT}/measurements/beta.jsonl#L1")
|
||||
indexes = {row[0] for row in connection.execute("SELECT name FROM sqlite_master WHERE type = 'index'")}
|
||||
self.assertTrue({"runs_emulator_idx", "emulator_systems_system_idx", "checks_claim_idx"} <= indexes)
|
||||
connection.close()
|
||||
@@ -286,15 +312,11 @@ class SyncAndIndex(Workspace):
|
||||
for path in first.paths:
|
||||
self.assertEqual(path.read_bytes(), (two / path.relative_to(one)).read_bytes(), path.name)
|
||||
|
||||
def test_a_missing_pin_fails_only_when_required(self) -> None:
|
||||
sm.write_pin({"repo": str(self.repo), "commit": "f" * 40}, self.pin)
|
||||
with self.assertRaises(sm.MeasurementsError):
|
||||
self.built(self.tmp / "public")
|
||||
with contextlib.redirect_stderr(io.StringIO()) as err:
|
||||
built = sm.build(self.tmp / "public", self.repo, self.pin, self.emulators, require=False,
|
||||
scratch=self.tmp / "scratch")
|
||||
self.assertIn("WARNING", err.getvalue())
|
||||
self.assertEqual((built.index["count"], built.index["commit"]), (0, None))
|
||||
def test_no_records_writes_an_empty_index(self) -> None:
|
||||
shutil.rmtree(self.tree / mr.RECORDS_DIR)
|
||||
built = self.built(self.tmp / "public")
|
||||
self.assertEqual((built.index["records"], built.index["count"]), (0, 0))
|
||||
self.assertEqual(len(built.paths), 2)
|
||||
|
||||
def test_every_line_validates_against_the_schema(self) -> None:
|
||||
try:
|
||||
@@ -303,68 +325,82 @@ class SyncAndIndex(Workspace):
|
||||
self.skipTest("jsonschema is not installed")
|
||||
import validate_schemas # noqa: PLC0415
|
||||
|
||||
self.assertEqual(validate_schemas._measurement_errors(self.repo, self.pin), [])
|
||||
lines = self.repo / mr.records_path("beta")
|
||||
self.assertEqual(validate_schemas._measurement_errors(self.tree), [])
|
||||
lines = self.tree / mr.records_path("beta")
|
||||
record = json.loads(lines.read_text())
|
||||
record["kind"] = "guess"
|
||||
lines.write_text(mr.line_text(record) + "\n")
|
||||
sm.write_pin({"repo": str(self.repo), "commit": commit_all(self.repo, "bad")}, self.pin)
|
||||
errors = validate_schemas._measurement_errors(self.repo, self.pin)
|
||||
self.assertTrue(any("records/beta.jsonl:1" in e and "kind" in e for e in errors), errors)
|
||||
errors = validate_schemas._measurement_errors(self.tree)
|
||||
self.assertTrue(any("measurements/beta.jsonl:1" in e and "kind" in e for e in errors), errors)
|
||||
self.assertIsNotNone(Draft202012Validator)
|
||||
|
||||
|
||||
class AppendOnly(Workspace):
|
||||
def fetch(self, *extra: str) -> tuple[int, str]:
|
||||
err = io.StringIO()
|
||||
with contextlib.redirect_stdout(io.StringIO()), contextlib.redirect_stderr(err):
|
||||
code = sm.main(["--fetch", "--clone", str(self.tmp / "clone"), "--pin", str(self.pin), *extra])
|
||||
return code, err.getvalue()
|
||||
def setUp(self) -> None:
|
||||
super().setUp()
|
||||
self.commit = self.repository()
|
||||
|
||||
def test_an_appended_line_moves_the_pin(self) -> None:
|
||||
self.assertEqual(self.fetch()[0], 0)
|
||||
add_record(self.repo, full_record("alpha", "card", "2026-10-04T10:00:00+00:00"))
|
||||
head = commit_all(self.repo, "feat: rerun")
|
||||
self.assertEqual(self.fetch("--bump")[0], 0)
|
||||
self.assertEqual(sm.load_pin(self.pin)["commit"], head)
|
||||
def test_an_appended_line_and_a_new_file_pass(self) -> None:
|
||||
add_record(self.tree, full_record("alpha", "card", "2026-10-04T10:00:00+00:00"))
|
||||
add_record(self.tree, full_record("gamma", "card", "2026-10-04T10:00:00+00:00"))
|
||||
self.assertEqual(mr.append_only_problems(self.tree, "HEAD"), [])
|
||||
|
||||
def test_a_changed_line_is_refused(self) -> None:
|
||||
lines = self.repo / mr.records_path("alpha")
|
||||
def test_a_changed_line_is_named(self) -> None:
|
||||
lines = self.tree / mr.records_path("alpha")
|
||||
text = lines.read_text().splitlines()
|
||||
text[0] = text[0].replace('"Each card, twice."', '"Each card, once."')
|
||||
lines.write_text("\n".join(text) + "\n")
|
||||
commit_all(self.repo, "rewrite")
|
||||
code, err = self.fetch("--bump")
|
||||
self.assertEqual(code, 1)
|
||||
self.assertIn("records/alpha.jsonl: line 1 changed", err)
|
||||
self.assertEqual(sm.load_pin(self.pin)["commit"], self.commit)
|
||||
self.assertEqual(mr.append_only_problems(self.tree, "HEAD"),
|
||||
["measurements/alpha.jsonl: line 1 changed"])
|
||||
|
||||
def test_a_removed_line_or_data_file_is_refused(self) -> None:
|
||||
lines = self.repo / mr.records_path("alpha")
|
||||
def test_a_removed_line_or_data_file_is_named(self) -> None:
|
||||
lines = self.tree / mr.records_path("alpha")
|
||||
lines.write_text(lines.read_text().splitlines()[0] + "\n")
|
||||
(self.repo / mr.sidecar_path("beta", self.beta["id"])).unlink()
|
||||
commit_all(self.repo, "remove")
|
||||
code, err = self.fetch()
|
||||
self.assertEqual(code, 1)
|
||||
self.assertIn("records/alpha.jsonl: line 2 removed", err)
|
||||
self.assertIn(f"{mr.sidecar_path('beta', self.beta['id'])}: removed", err)
|
||||
(self.tree / mr.sidecar_path("beta", self.beta["id"])).unlink()
|
||||
problems = mr.append_only_problems(self.tree, "HEAD")
|
||||
self.assertIn("measurements/alpha.jsonl: line 2 removed", problems)
|
||||
self.assertIn(f"{mr.sidecar_path('beta', self.beta['id'])}: removed", problems)
|
||||
|
||||
def test_a_rewritten_data_file_is_named(self) -> None:
|
||||
data = self.tree / mr.sidecar_path("beta", self.beta["id"])
|
||||
data.write_bytes(data.read_bytes() + b"x")
|
||||
self.assertEqual(mr.append_only_problems(self.tree, "HEAD"),
|
||||
[f"{mr.sidecar_path('beta', self.beta['id'])}: rewritten"])
|
||||
|
||||
def test_two_branches_adding_a_line_merge_cleanly(self) -> None:
|
||||
git(self.repo, "checkout", "-q", "-b", "left")
|
||||
add_record(self.repo, full_record("alpha", "card", "2026-10-06T10:00:00+00:00"))
|
||||
commit_all(self.repo, "left")
|
||||
git(self.repo, "checkout", "-q", "main")
|
||||
git(self.repo, "checkout", "-q", "-b", "right")
|
||||
add_record(self.repo, full_record("alpha", "speed", "2026-10-06T11:00:00+00:00", kind="bench",
|
||||
git(self.tree, "checkout", "-q", "-b", "left")
|
||||
add_record(self.tree, full_record("alpha", "card", "2026-10-06T10:00:00+00:00"))
|
||||
commit_all(self.tree, "left")
|
||||
git(self.tree, "checkout", "-q", "main")
|
||||
git(self.tree, "checkout", "-q", "-b", "right")
|
||||
add_record(self.tree, full_record("alpha", "speed", "2026-10-06T11:00:00+00:00", kind="bench",
|
||||
values=("4" * 40,)))
|
||||
commit_all(self.repo, "right")
|
||||
git(self.repo, "merge", "-q", "--no-edit", "left")
|
||||
merged = git(self.repo, "rev-parse", "HEAD")
|
||||
self.assertEqual(sm.append_only_problems(self.repo, self.commit, merged), [])
|
||||
records = sm.read_records(self.repo, merged)
|
||||
commit_all(self.tree, "right")
|
||||
git(self.tree, "merge", "-q", "--no-edit", "left")
|
||||
self.assertEqual(mr.append_only_problems(self.tree, self.commit), [])
|
||||
records = mr.read_records(self.tree)
|
||||
self.assertEqual(sum(1 for s in records if s.emulator == "alpha"), 4)
|
||||
|
||||
|
||||
class CommittedRecords(unittest.TestCase):
|
||||
"""The records this repository holds."""
|
||||
|
||||
def test_no_line_or_data_file_changed_or_vanished_since_head(self) -> None:
|
||||
if subprocess.run(["git", "-C", str(REPO_ROOT), "rev-parse", "--verify", "-q", "HEAD"],
|
||||
capture_output=True, check=False).returncode != 0:
|
||||
self.skipTest("not a git checkout")
|
||||
self.assertEqual(mr.append_only_problems(REPO_ROOT, "HEAD"), [])
|
||||
|
||||
def test_every_record_reads_and_joins_its_data(self) -> None:
|
||||
records = mr.read_records(REPO_ROOT)
|
||||
self.assertGreaterEqual(len(records), 7)
|
||||
|
||||
def test_jsonl_files_merge_by_union(self) -> None:
|
||||
rules = (REPO_ROOT / ".gitattributes").read_text().splitlines()
|
||||
rule = next(line for line in rules if line.startswith(f"{mr.RECORDS_DIR}/*.jsonl "))
|
||||
self.assertIn("merge=union", rule.split())
|
||||
|
||||
|
||||
class SitePages(unittest.TestCase):
|
||||
ITEM = {
|
||||
"emulator": "beetle_saturn", "emulator_name": "Beetle Saturn", "profiled": True,
|
||||
@@ -376,14 +412,14 @@ class SitePages(unittest.TestCase):
|
||||
"host": "Test CPU, 12 CPUs", "core": {"library": "Beetle Saturn v1.32.1", "commit": "2ce77e2" * 5 + "abcde",
|
||||
"file": "x.so", "sha256": SHA256, "repo": None, "build": "make"},
|
||||
"frontend_commit": None, "id": "2026-10-27-43527b763ace", "runs": 2,
|
||||
"record_url": f"{REPO_URL}/blob/{'e' * 40}/records/beetle_saturn.jsonl#L4",
|
||||
"data_url": f"{REPO_URL}/blob/{'e' * 40}/data/beetle_saturn/2026-10-27-43527b763ace.json.gz",
|
||||
"record_url": f"{REPO_URL}/blob/{'e' * 40}/measurements/beetle_saturn.jsonl#L4",
|
||||
"data_url": f"{REPO_URL}/blob/{'e' * 40}/measurements/data/beetle_saturn/2026-10-27-43527b763ace.json.gz",
|
||||
"sqlite": "downloads/measurements/beetle_saturn.sqlite",
|
||||
}
|
||||
|
||||
def test_tested_block(self) -> None:
|
||||
self.assertEqual(sitemeasurements.tested_section("beetle_saturn", []), [])
|
||||
text = "\n".join(sitemeasurements.tested_section("beetle_saturn", [self.ITEM]))
|
||||
self.assertEqual(sm.tested_section("beetle_saturn", []), [])
|
||||
text = "\n".join(sm.tested_section("beetle_saturn", [self.ITEM]))
|
||||
self.assertTrue(text.startswith("## Tested\n"))
|
||||
for expected in ("**Result:** `same`", "**Method:** Twice per card. Every input fixed.", "**Ran on:** Test CPU, 12 CPUs",
|
||||
self.ITEM["record_url"], self.ITEM["data_url"], "1 flag raised", "2 runs",
|
||||
@@ -392,10 +428,10 @@ class SitePages(unittest.TestCase):
|
||||
self.assertIn(expected, text)
|
||||
|
||||
def test_hosts_table_on_the_method_page(self) -> None:
|
||||
page = sitemeasurements.with_hosts(f"x\n\n{sitemeasurements.HOSTS_MARKER}\n",
|
||||
page = sm.with_hosts(f"x\n\n{sm.HOSTS_MARKER}\n",
|
||||
{"items": [self.ITEM, {**self.ITEM, "host": "Test CPU, 12 CPUs, load 1 before, 2 after"}]})
|
||||
self.assertIn("| Test CPU, 12 CPUs | 2 |", page)
|
||||
self.assertNotIn(sitemeasurements.HOSTS_MARKER, page)
|
||||
self.assertNotIn(sm.HOSTS_MARKER, page)
|
||||
|
||||
def test_the_explorer_reads_the_index(self) -> None:
|
||||
source = (REPO_ROOT / "website" / "src" / "components" / "MeasurementsExplorer.astro").read_text()
|
||||
@@ -404,37 +440,44 @@ class SitePages(unittest.TestCase):
|
||||
read = set(re.findall(r"\b(?:item|i)\.([a-z_]+)", source)) - {"length"}
|
||||
self.assertTrue(read)
|
||||
self.assertLessEqual(read, set(self.ITEM), read - set(self.ITEM))
|
||||
page = sitemeasurements.generate_explorer_page({"records": 7, "count": 7, "commit": "e" * 40,
|
||||
page = sm.generate_explorer_page({"records": 7, "count": 7, "commit": "e" * 40,
|
||||
"repo": REPO_URL})
|
||||
self.assertIn("<MeasurementsExplorer />", page)
|
||||
self.assertIn("downloads/measurements.sqlite", page)
|
||||
self.assertIn(f"({REPO_URL}/tree/{'e' * 40}/measurements)", page)
|
||||
|
||||
def test_the_deploy_clones_the_measurements_at_the_pin(self) -> None:
|
||||
workflow = (REPO_ROOT / ".github" / "workflows" / "deploy-site.yml").read_text()
|
||||
clone = workflow.index("Clone the measurements at their pin")
|
||||
step = workflow[clone:workflow.index("- name:", clone)]
|
||||
self.assertIn("measurements-pin.json", step)
|
||||
self.assertIn('fetch -q --depth 1 "$repo" "$commit"', step)
|
||||
self.assertIn('checkout -q --detach "$commit"', step)
|
||||
self.assertNotIn("uses:", step)
|
||||
self.assertLess(clone, workflow.index("Validate data contracts"))
|
||||
self.assertLess(clone, workflow.index("python scripts/generate_site.py --require-measurements"))
|
||||
self.assertIn('- "measurements-pin.json"', workflow)
|
||||
pin = sm.load_pin()
|
||||
self.assertEqual(pin["repo"], REPO_URL)
|
||||
|
||||
def test_the_builds_read_the_records_in_this_repository(self) -> None:
|
||||
for name in ("deploy-site.yml", "validate.yml"):
|
||||
workflow = (REPO_ROOT / ".github" / "workflows" / name).read_text()
|
||||
with self.subTest(workflow=name):
|
||||
self.assertIn('- "measurements/**"', workflow)
|
||||
self.assertNotIn("measurements-pin", workflow)
|
||||
self.assertNotIn(".cache/measurements", workflow)
|
||||
self.assertNotIn("--require-measurements", workflow)
|
||||
self.assertFalse((REPO_ROOT / "measurements-pin.json").exists())
|
||||
self.assertFalse((REPO_ROOT / "scripts" / "sync_measurements.py").exists())
|
||||
|
||||
def test_nothing_links_the_former_measurements_repository(self) -> None:
|
||||
former = "retrobios-" + "measurements"
|
||||
roots = ["wiki", "schemas", "scripts", "website/src", ".github", "tests", "measurements"]
|
||||
suffixes = {".md", ".py", ".json", ".jsonl", ".yml", ".astro", ".ts", ".mjs"}
|
||||
stray = [path.relative_to(REPO_ROOT).as_posix()
|
||||
for root in roots for path in sorted((REPO_ROOT / root).rglob("*"))
|
||||
if path.is_file() and path.suffix in suffixes
|
||||
and former in path.read_text(encoding="utf-8", errors="replace")]
|
||||
stray += [name for name in ("README.md", "CONTRIBUTING.md")
|
||||
if former in (REPO_ROOT / name).read_text(encoding="utf-8")]
|
||||
self.assertEqual(stray, [])
|
||||
|
||||
|
||||
class Freshness(unittest.TestCase):
|
||||
def test_pin_against_the_remote_head(self) -> None:
|
||||
import check_freshness as cf # noqa: PLC0415
|
||||
def test_no_measurements_area(self) -> None:
|
||||
import check_freshness # noqa: PLC0415
|
||||
import refresh_stale # noqa: PLC0415
|
||||
|
||||
pin = sm.load_pin()
|
||||
self.assertEqual(cf.check_measurements(False, head=lambda _repo: pin["commit"]).status, cf.OK)
|
||||
stale = cf.check_measurements(False, head=lambda _repo: "f" * 40)
|
||||
self.assertEqual(stale.status, cf.STALE)
|
||||
self.assertIn("sync_measurements.py --fetch --bump", stale.detail)
|
||||
self.assertEqual(cf.check_measurements(True).status, cf.SKIPPED)
|
||||
self.assertIn("measurements", cf.AREAS)
|
||||
self.assertNotIn("measurements", check_freshness.AREAS)
|
||||
self.assertNotIn("measurements", refresh_stale.AUTO_AREAS)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
||||
@@ -248,32 +248,23 @@ class SourceLinksOnlyWhereTheFileIs(unittest.TestCase):
|
||||
def test_every_rendered_link_is_recorded(self):
|
||||
record = json.loads(sitesources.SOURCE_PATHS.read_text(encoding="utf-8"))
|
||||
pages = sorted(_built(DOCS / "emulators").rglob("*.md*")) + sorted(DOCS.glob("gaps*.md*"))
|
||||
import sync_measurements # noqa: PLC0415
|
||||
import measurement_records # noqa: PLC0415
|
||||
|
||||
# A Tested block links the measurements repository at its pin. The
|
||||
# record of source trees does not cover it: those paths are checked
|
||||
# against the pinned tree of the clone itself.
|
||||
measured_slug = urllib.parse.urlsplit(sync_measurements.load_pin()["repo"]).path.strip("/")
|
||||
measured: dict[str, set[str]] = {}
|
||||
# A Tested block links a record line and its data file in this
|
||||
# repository. The records are append-only, so a file a permalink
|
||||
# names is still in the tree.
|
||||
records = set(measurement_records.tree_files(REPO_ROOT))
|
||||
checked, stray = 0, []
|
||||
for page in pages:
|
||||
for found in _PERMALINK.finditer(page.read_text(encoding="utf-8")):
|
||||
if "/Abdess/retrobios/" in found[0]:
|
||||
continue
|
||||
key = f"{found['host']}/{found['slug']}@{found['pin']}"
|
||||
path = urllib.parse.unquote(found["path"])
|
||||
checked += 1
|
||||
if found["slug"] == measured_slug:
|
||||
if found["pin"] not in measured:
|
||||
if not sync_measurements.has_commit(sync_measurements.CLONE, found["pin"]):
|
||||
stray.append((page.name, key, "pin not in the measurements clone"))
|
||||
measured[found["pin"]] = set()
|
||||
continue
|
||||
measured[found["pin"]] = set(
|
||||
sync_measurements.tree_files(sync_measurements.CLONE, found["pin"]))
|
||||
if path not in measured[found["pin"]]:
|
||||
if "/Abdess/retrobios/" in found[0]:
|
||||
if path.startswith(f"{measurement_records.RECORDS_DIR}/") and path not in records:
|
||||
stray.append((page.name, key, path))
|
||||
elif path not in record.get(key, ()):
|
||||
continue
|
||||
checked += 1
|
||||
if path not in record.get(key, ()):
|
||||
stray.append((page.name, key, path))
|
||||
self.assertGreater(checked, 1000)
|
||||
self.assertEqual(stray[:20], [])
|
||||
|
||||
Reference in new issue
Block a user