The eight test files Q98 leaves open (plus test_bfs.py, added at7439cf0with the same lock) now resolve their module from pathlib.Path(__file__).resolve().parent instead of /root/.hermes/wizard-outputs/<lane>. tools/import_resolve_check.py --repo . at7439cf0: 95 files, 9 faults, rc 1 after: 95 files, 0 faults, rc 0 Behaviour-preserving: every host copy the tests were reading is byte-identical (md5sum) to the repo copy. Three absolute literals in spark/test_validator.py that the static leg does not grade (load_json(...) argument strings at pre-fix lines 12/16/25) are re-pointed too. ledger/test_scratch_manifest.py was red before any edit (str ROOT vs gen_manifest ROOT.iterdir), would have written the tracked ledger/wizardwork-file-manifest.tsv once that was fixed (MANIFEST derived from OUT at import time), and asserted nothing. It now re-points ROOT/OUT/MANIFEST, guards MANIFEST inside a tempfile.mkdtemp(), and asserts the exact manifest row. Non-vacuity: scratch/q98b/poison_probe.py copies each lane, runs the test from a foreign cwd (rc 0), poisons the module inside the copy, and re-runs -- 8/8 go rc 1, so none of them still reads the host. Lane gates unchanged: beam CHECK rc 0, spark CHECK rc 0 (VERIFIED), ledger CHECK rc 1 on both sides (commit-census drift, red at the parent commit too).
63 lines
2.2 KiB
Python
63 lines
2.2 KiB
Python
#!/usr/bin/env python3
|
|
"""Isolated scratch test of gen_manifest.py.
|
|
|
|
Binds to the module in THIS directory -- never to a host copy -- builds a
|
|
manifest over a throwaway tree, and ASSERTS the rows it emitted. Before this
|
|
rewrite the whole file was print statements with no assertion, so a
|
|
gen_manifest that wrote nothing still exited 0.
|
|
"""
|
|
import importlib.util
|
|
import sys
|
|
import tempfile
|
|
from pathlib import Path
|
|
|
|
HERE = Path(__file__).resolve().parent
|
|
sys.path.insert(0, str(HERE))
|
|
|
|
|
|
def main():
|
|
scratch = Path(tempfile.mkdtemp(prefix="scratch_wiz_"))
|
|
(scratch / "beam").mkdir()
|
|
(scratch / "a.txt").write_text("hello")
|
|
(scratch / "b.sh").write_text("#!/bin/bash\necho hi\n")
|
|
(scratch / "beam" / "CHECK").write_text(
|
|
"#!/bin/bash\n# CHECK: verify\nset -e\n"
|
|
'cd "$(dirname "$(readlink -f "$0")")"\necho content > /tmp/x\n'
|
|
)
|
|
out = scratch / "_out"
|
|
out.mkdir()
|
|
|
|
spec = importlib.util.spec_from_file_location(
|
|
"gen_manifest", str(HERE / "gen_manifest.py")
|
|
)
|
|
m = importlib.util.module_from_spec(spec)
|
|
spec.loader.exec_module(m)
|
|
# ROOT, OUT and MANIFEST are all module-level globals fixed at import time
|
|
# (MANIFEST is derived from OUT there), so assigning OUT alone would leave
|
|
# build() writing the repository's tracked manifest. Re-point all three.
|
|
m.ROOT = scratch
|
|
m.OUT = out
|
|
m.MANIFEST = out / "wizardwork-file-manifest.tsv"
|
|
assert scratch in m.MANIFEST.parents, f"refusing to write outside scratch: {m.MANIFEST}"
|
|
m.build()
|
|
|
|
print("--- scratch manifest ---")
|
|
body = m.MANIFEST.read_text()
|
|
print(body)
|
|
rows = [line.split("\t") for line in body.splitlines() if line]
|
|
print("--- row count ---")
|
|
print(len(rows))
|
|
|
|
# build() skips top-level *files* (it iterates sorted(ROOT.iterdir()) and
|
|
# `continue`s on anything that is not a directory), so the one file under
|
|
# beam/ is the entire expected manifest.
|
|
assert [r[0] for r in rows] == ["beam/CHECK"], rows
|
|
assert rows[0][1] == str(len((scratch / "beam" / "CHECK").read_bytes())), rows[0]
|
|
assert rows[0][2:] == ["CHECK", "beam"], rows[0]
|
|
print("OK: 1 row, beam/CHECK")
|
|
return 0
|
|
|
|
|
|
if __name__ == "__main__":
|
|
sys.exit(main())
|