Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 3 additions & 20 deletions flake.nix
Original file line number Diff line number Diff line change
Expand Up @@ -61,27 +61,10 @@
# Inspect every Git-source entry, including names cleanSource excludes.
src = self;
MERGEMASTER_PYTHON_ORACLE = "${python-oracle}";
MERGEMASTER_FRACTAL_FIXTURE = "${fractal-fixture}";
} ''
python3 - <<'PY'
import os
from pathlib import Path

scripts = Path(os.environ["src"]) / "scripts"
oracle = Path(os.environ["MERGEMASTER_PYTHON_ORACLE"]) / "scripts"
# Repository metadata and orchestration, not copied upstream scripts.
exempt = {"PROVENANCE", "test-scripts", "parity-drift", "parity-drift-test"}
for path in sorted(scripts.rglob("*")):
if path.is_dir() and not path.is_symlink():
continue
relative = path.relative_to(scripts)
if relative.as_posix() in exempt:
continue
reference = oracle / relative
if (path.is_symlink() or not reference.is_file()
or path.read_bytes() != reference.read_bytes()
or (path.stat().st_mode & 0o111) != (reference.stat().st_mode & 0o111)):
raise SystemExit(f"scripts/{relative}: differs from pinned oracle or is not an oracle copy")
PY
python3 -B "$src/tests/test-oracle-scripts.py"
python3 -B "$src/tests/oracle_scripts.py"
touch "$out"
'';
fmt = pkgs.runCommand "mergemaster-fmt" {
Expand Down
27 changes: 27 additions & 0 deletions scripts/PROVENANCE
Original file line number Diff line number Diff line change
@@ -1,6 +1,33 @@
# Source: compoundingtech/fractal
# Commit: e83871ec919f95b3b3e2a9a1cd211c2ac37babda
# Scripts copied as-is except the documented upstream patches below; Git blob SHA-1 hashes (not file SHA-1 hashes).
# Resync exception; exit: https://github.com/compoundingtech/mergemaster/issues/115
# Pending until the fixture reaches this revision; no copied-script exception before activation.
# resync-rev e2721e52463428b4ff655addee129cecd2839763
# resync-blob scripts/ci-evidence-gate 2952f89514a584465a428017b3f3e8ea043f41b2
# resync-blob scripts/ci-evidence-gate-test 38a34e7d48ed407b428f739c0f3d38b151fced59
# resync-blob scripts/ci-signed-tree 77a560621f8182d2ca19f622782ff24c95e7d514
# resync-blob scripts/ci-signed-tree-test 91612975e7ae383ca5c55b94a19af20b0b1c7df2
# resync-blob scripts/evidence-gc 1340a798f6bda78ad6319352fabd8de2050312f9
# resync-blob scripts/evidence-gc-test 3c7482d742f104780158789154491d290ab7a693
# resync-blob scripts/evidence-gc-timer dd5781ab377653d43b1cfda67a46e897ec0e51d8
# resync-blob scripts/evidence-log 73e22e8252a1ceab4eba0324a0063c97f1d75b18
# resync-blob scripts/evidence-log-test 746aa09bc2363c2d57523220c084fb6a4e34ef66
# resync-blob scripts/evidence-log-timer 85ffab484040914c4ae14f72b86cc70c97b7e358
# resync-blob scripts/evidence-log-watch f580ed13fe4f8130ec936dfeefb64f6c3b97b2f1
# resync-blob scripts/evidence-log-watch-test e29deab9f1bfdfa27989e618de577e5f748871e4
# resync-blob scripts/evidence-log.service 341638d61c71d41358e2b147d141ce76b6d6c06e
# resync-blob scripts/evidence-presign-worker d68abbd4351ee70449a517e2c9566b54239e34be
# resync-blob scripts/evidence-queue-signer 0be3140016868d1e383d9c301c1e229066c6dd22
# resync-blob scripts/evidence-queue-signer-test e5c8a3c7cc59e4bf6343a9f5a8601e5ba45cbc43
# resync-blob scripts/evidence-skip-report 2bdb6c3ebee8bb381c93c736cc99c22cbb82c0b3
# resync-blob scripts/evidence-skip-report-test 2d51833fa53146709634090bd75ebf8dc4a91c50
# resync-blob scripts/evidence-wrap b31f1737e55f187471cd15b8d0b938dd982c72a0
# resync-blob scripts/evidence-wrap-test 603ae3a411bfcd31e70160f7fba05854ec38df36
# resync-blob scripts/fractal-test-report 52ebcb098a323b013eba5b136457393ef88e2951
# resync-blob scripts/fractal-test-report-test b0dc50163986760343d7eb67c701cb4b775e9945
# resync-blob scripts/lane-definition-closure 492b3741b117092395855d9790dc96e6ce3612e6
# resync-blob scripts/lane-definition-closure-test 635945d2a01f18e9c4716c50a2eb9803896cbb08
# scripts/fractal-test-test: apply the fixture maintenance-isolation patch from
# https://github.com/compoundingtech/fractal/pull/4398 (5f995f26e5).
# The source_blob column remains the original import; mergemaster_blob includes applied patches.
Expand Down
74 changes: 74 additions & 0 deletions tests/oracle_scripts.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
"""Byte/mode oracle guard with the single PROVENANCE resync exception."""
import hashlib
import json
import os
from pathlib import Path
import re

EXEMPT = {"PROVENANCE", "test-scripts", "parity-drift", "parity-drift-test"}
ORIGINAL = "e83871ec919f95b3b3e2a9a1cd211c2ac37babda"
TARGET = "e2721e52463428b4ff655addee129cecd2839763"


def blob(data):
return hashlib.sha1(b"blob " + str(len(data)).encode() + b"\0" + data).hexdigest()


def table(text):
revisions, original, rows = [], [], {}
for line in text.splitlines():
if line.startswith("# Commit: "):
original.append(line.removeprefix("# Commit: "))
elif line.startswith("# resync-rev "):
revisions.append(line.removeprefix("# resync-rev "))
elif line.startswith("# resync-blob "):
path, oid = line.removeprefix("# resync-blob ").split()
if not re.fullmatch(r"scripts/[A-Za-z0-9._-]+", path) or path in rows:
raise ValueError("invalid/duplicate resync path")
if not re.fullmatch(r"[0-9a-f]{40}", oid) or path[8:] in EXEMPT:
raise ValueError("invalid resync blob")
rows[path] = oid
if len(revisions) != 1 or len(original) != 1 or not rows:
raise ValueError("resync requires one target, one original revision and paths")
if ORIGINAL == TARGET or original[0] != ORIGINAL or revisions[0] != TARGET:
raise ValueError("resync revision differs from approved constants")
return revisions[0], original[0], rows


def snapshot(path):
if path.is_symlink() or not path.is_file():
raise ValueError(f"{path}: not a regular script")
return path.read_bytes(), path.stat().st_mode & 0o111


def check(src, oracle, fixture, fixture_rev):
_, _, rows = table((src / "scripts/PROVENANCE").read_text())
if fixture_rev not in (ORIGINAL, TARGET):
raise ValueError("fixture revision differs from approved constants")
active = fixture_rev == TARGET
for path, oid in rows.items():
local, old = snapshot(src / path), snapshot(oracle / path)
if blob(old[0]) == oid:
raise ValueError(f"{path}: expired resync exception; remove it (#115)")
if active:
upstream = snapshot(fixture / path)
if blob(upstream[0]) != oid or local != upstream or local[0] == old[0]:
raise ValueError(f"{path}: resync bytes/mode/blob mismatch")
elif local != old:
raise ValueError(f"{path}: pending resync must still equal oracle")
for path in sorted((src / "scripts").rglob("*")):
if path.is_dir() and not path.is_symlink():
continue
relative = path.relative_to(src).as_posix()
if relative[8:] in EXEMPT or relative in rows:
continue
if snapshot(path) != snapshot(oracle / relative):
raise ValueError(f"{relative}: differs from pinned oracle")


if __name__ == "__main__":
src = Path(os.environ["src"])
lock = json.loads((src / "flake.lock").read_text())
node = lock["nodes"][lock["nodes"]["root"]["inputs"]["fractal-fixture"]]
check(src, Path(os.environ["MERGEMASTER_PYTHON_ORACLE"]),
Path(os.environ["MERGEMASTER_FRACTAL_FIXTURE"]), node["locked"]["rev"])
110 changes: 110 additions & 0 deletions tests/test-oracle-scripts.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
import tempfile
from pathlib import Path
import unittest

from oracle_scripts import ORIGINAL, TARGET, blob, check


class ResyncGuard(unittest.TestCase):
def setUp(self):
self.temp = tempfile.TemporaryDirectory()
self.addCleanup(self.temp.cleanup)
self.src, self.oracle, self.fixture = [Path(self.temp.name) / p for p in ("src", "oracle", "fixture")]
for root in (self.src, self.oracle, self.fixture):
(root / "scripts").mkdir(parents=True)
self.old, self.target = ORIGINAL, TARGET
self.oid = blob(b"new")
self.write(self.src, "one", b"new")
self.write(self.oracle, "one", b"old")
self.write(self.fixture, "one", b"new")
self.manifest()

def write(self, root, name, data, mode=0o755):
path = root / "scripts" / name
path.write_bytes(data)
path.chmod(mode)

def manifest(self):
(self.src / "scripts/PROVENANCE").write_text(
f"# Commit: {self.old}\n# resync-rev {self.target}\n# resync-blob scripts/one {self.oid}\n")

def run_check(self, rev=None):
check(self.src, self.oracle, self.fixture, rev or self.target)

def test_match(self):
self.run_check()

def test_pending_is_oracle_only(self):
with self.assertRaises(ValueError):
self.run_check(self.old)
self.write(self.src, "one", b"old")
self.run_check(self.old)
with self.assertRaises(ValueError):
self.run_check("c" * 40)

def test_local_mismatch_and_oracle_copy(self):
for data in (b"edited", b"old"):
self.write(self.src, "one", data)
with self.assertRaises(ValueError):
self.run_check()

def test_fixture_and_table_must_agree(self):
self.write(self.fixture, "one", b"edited")
with self.assertRaises(ValueError):
self.run_check()
self.write(self.fixture, "one", b"new")
self.oid = blob(b"edited")
self.manifest()
with self.assertRaises(ValueError):
self.run_check()

def test_modes_and_missing_paths(self):
self.write(self.src, "one", b"new", 0o644)
with self.assertRaises(ValueError):
self.run_check()
(self.src / "scripts/one").unlink()
with self.assertRaises(ValueError):
self.run_check()

def test_unlisted_stays_oracle(self):
self.write(self.src, "two", b"old")
self.write(self.oracle, "two", b"old")
self.run_check()
self.write(self.src, "two", b"new")
with self.assertRaises(ValueError):
self.run_check()

def test_expiry_is_byte_identical_even_if_modes_differ(self):
self.write(self.oracle, "one", b"new", 0o644)
with self.assertRaisesRegex(ValueError, "expired"):
self.run_check()

def test_manifest_cannot_retarget_approved_revisions(self):
for original, target in [("c" * 40, "c" * 40), (ORIGINAL, "c" * 40),
(TARGET, TARGET), (ORIGINAL, ORIGINAL)]:
self.old, self.target = original, target
self.manifest()
with self.assertRaisesRegex(ValueError, "approved constants"):
self.run_check(target)

def test_duplicate_or_malformed_rows(self):
path = self.src / "scripts/PROVENANCE"
original = path.read_text()
for row in [f"# resync-blob scripts/one {self.oid}",
"# resync-blob scripts/../escape " + self.oid,
"# resync-blob scripts/two invalid",
"# resync-blob scripts/two"]:
path.write_text(original + row + "\n")
with self.assertRaises(ValueError):
self.run_check()

def test_listed_symlink_is_not_a_script(self):
path = self.src / "scripts/one"
path.unlink()
path.symlink_to(self.fixture / "scripts/one")
with self.assertRaisesRegex(ValueError, "not a regular script"):
self.run_check()


if __name__ == "__main__":
unittest.main()