feat: let verify fail on a missing required file

This commit is contained in:
Abdessamad Derraz committed 2026-10-17 12:36:35 +02:00
1 parent 4544006aff
commit f6b808b1d9
4 files changed
+63 -1

No files matched your search

+1 -1
View File
@@ -450,7 +450,7 @@ def main():
all_ok = _truth_steps(args, results) and all_ok
# Step 3: Verify
verify_cmd = [sys.executable, "scripts/verify.py", "--all"]
verify_cmd = [sys.executable, "scripts/verify.py", "--all", "--strict"]
if args.include_archived:
verify_cmd.append("--include-archived")
if args.target:
+26
View File
@@ -2064,6 +2064,11 @@ def main():
help="Show emulator ground truth details",
)
parser.add_argument("--json", action="store_true", help="JSON output")
parser.add_argument(
"--strict",
action="store_true",
help="Exit 1 when a platform that checks hashes misses a required file",
)
args = parser.parse_args()
if args.platform:
require_platform(args.platform, args.platforms_dir)
@@ -2190,12 +2195,33 @@ def main():
for result, group in group_results:
print_platform_result(result, group, verbose=args.verbose)
print()
if len(group_results) > 1:
print(_overall_summary(group_results))
if args.json:
for r in all_results.values():
r["details"] = [d for d in r["details"] if d["status"] != Status.OK]
print(json.dumps(all_results, indent=2))
critical = sum(r["severity_counts"].get(Severity.CRITICAL, 0) for r, _ in group_results)
if args.strict and critical:
print(f"ERROR: {critical} required file(s) missing where the frontend "
"checks hashes", file=sys.stderr)
sys.exit(1)
def _overall_summary(group_results: list[tuple[dict, list[str]]]) -> str:
"""One closing line for a multi-platform run, worst severity first."""
platforms = sum(len(group) for _, group in group_results)
totals = {
sev: sum(r["severity_counts"].get(sev, 0) for r, _ in group_results)
for sev in (Severity.CRITICAL, Severity.WARNING, Severity.INFO)
}
return (
f"{platforms} platforms: {totals[Severity.CRITICAL]} critical, "
f"{totals[Severity.WARNING]} warning, {totals[Severity.INFO]} info"
)
if __name__ == "__main__":
main()
+35
View File
@@ -111,5 +111,40 @@ class AMistypedPlatformIsNamed(unittest.TestCase):
self.assertIn("Did you mean 'batocera'?", proc.stderr)
self.assertFalse(out.exists())
class StrictVerifyFailsOnACriticalMiss(unittest.TestCase):
"""verify exited 0 with a required file missing on an md5 platform, so
the pipeline printed "verify OK" over a pack the frontend rejects."""
def test_strict_exits_nonzero_and_plain_does_not(self):
with tempfile.TemporaryDirectory(dir=REPO_ROOT / "tmp") as tmp:
root = Path(tmp)
(root / "plat").mkdir()
(root / "emu").mkdir()
(root / "plat" / "fx.yml").write_text(
"platform: Fx\nverification_mode: md5\nbase_destination: bios\n"
"systems:\n sony-playstation:\n files:\n - name: absent.bin\n"
" destination: absent.bin\n required: true\n"
" md5: 00000000000000000000000000000000\n"
)
(root / "db.json").write_text(
'{"files": {}, "indexes": {"by_md5": {}, "by_name": {}, '
'"by_crc32": {}, "by_path_suffix": {}}}'
)
base = [sys.executable, "scripts/verify.py", "--platform", "fx",
"--platforms-dir", str(root / "plat"), "--emulators-dir",
str(root / "emu"), "--db", str(root / "db.json")]
plain = subprocess.run(base, capture_output=True, text=True,
cwd=str(REPO_ROOT), timeout=300, check=False)
strict = subprocess.run([*base, "--strict"], capture_output=True, text=True,
cwd=str(REPO_ROOT), timeout=300, check=False)
self.assertEqual(plain.returncode, 0, plain.stderr)
self.assertEqual(strict.returncode, 1, strict.stderr)
self.assertIn("1 required file(s) missing", strict.stderr)
def test_the_pipeline_asks_for_it(self):
source = (REPO_ROOT / "scripts" / "pipeline.py").read_text()
self.assertIn('"scripts/verify.py", "--all", "--strict"', source)
if __name__ == "__main__":
unittest.main()
+1
View File
@@ -78,6 +78,7 @@ Check BIOS coverage for each platform using its native verification mode.
```bash
python scripts/verify.py --all # all platforms
python scripts/verify.py --all --strict # exit 1 on a missing required file (md5/sha1 platforms)
python scripts/verify.py --platform batocera # single platform
python scripts/verify.py --platform retroarch --verbose # with ground truth details
python scripts/verify.py --emulator dolphin # single emulator