Skip to content

Commit 6a693bd

Browse files
committed
wip
Signed-off-by: Joe Isaacs <joe.isaacs@live.co.uk>
1 parent d0918f5 commit 6a693bd

1 file changed

Lines changed: 81 additions & 0 deletions

File tree

vortex-test/compat-gen/scripts/compat.py

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -650,6 +650,66 @@ def cmd_list(args: argparse.Namespace) -> None:
650650
print(v)
651651

652652

653+
def cmd_verify(args: argparse.Namespace) -> None:
654+
"""Verify fixture file integrity against manifest sha256 hashes."""
655+
store = _parse_store(args.store)
656+
versions = store.list_versions()
657+
658+
if not versions:
659+
_info("no versions found")
660+
sys.exit(1)
661+
662+
_info(f"verifying {len(versions)} version(s) in {store.display_name()}...")
663+
664+
total_ok = 0
665+
errors: list[str] = []
666+
667+
for version in versions:
668+
_info(f"\n--- v{version} ---")
669+
manifest = _read_manifest(store, version)
670+
if manifest is None:
671+
msg = f"v{version}: manifest not found"
672+
_info(f" FAIL: {msg}")
673+
errors.append(msg)
674+
continue
675+
676+
prefix = manifest.pop("_prefix", f"v{version}/arrays")
677+
678+
for entry in manifest["fixtures"]:
679+
name = entry["name"]
680+
expected_hash = entry.get("sha256")
681+
data = store.read(f"{prefix}/{name}")
682+
683+
if data is None:
684+
msg = f"v{version}/{name}: file missing from store"
685+
_info(f" FAIL: {msg}")
686+
errors.append(msg)
687+
continue
688+
689+
if expected_hash is None:
690+
msg = f"v{version}/{name}: no sha256 in manifest"
691+
_info(f" FAIL: {msg}")
692+
errors.append(msg)
693+
continue
694+
695+
actual_hash = hashlib.sha256(data).hexdigest()
696+
if actual_hash != expected_hash:
697+
msg = f"v{version}/{name}: sha256 mismatch expected={expected_hash[:12]} actual={actual_hash[:12]}"
698+
_info(f" FAIL: {msg}")
699+
errors.append(msg)
700+
else:
701+
_info(f" {name}: ok ({len(data)} bytes)")
702+
total_ok += 1
703+
704+
_info(f"\nresult: {total_ok} ok, {len(errors)} failed")
705+
if errors:
706+
for e in errors:
707+
_info(f" {e}")
708+
sys.exit(1)
709+
else:
710+
_info("all fixtures verified.")
711+
712+
653713
def cmd_validate_manifest(args: argparse.Namespace) -> None:
654714
"""Check that manifests are additive-only across all versions."""
655715
store = _parse_store(args.store)
@@ -904,6 +964,26 @@ def main() -> None:
904964
)
905965
p.add_argument("version", nargs="?", help="Show manifest for this version")
906966

967+
# -- verify --
968+
p = sub.add_parser(
969+
"verify",
970+
help="Verify fixture file integrity against manifest sha256 hashes",
971+
description=(
972+
"Download every fixture file for every version and verify its\n"
973+
"SHA-256 hash matches the manifest. Also checks that all files\n"
974+
"listed in manifests are present in the store."
975+
),
976+
epilog=(
977+
"examples:\n"
978+
" uv run compat.py verify\n"
979+
" uv run compat.py verify --store /tmp/store"
980+
),
981+
formatter_class=argparse.RawDescriptionHelpFormatter,
982+
)
983+
p.add_argument(
984+
"--store", default=DEFAULT_STORE, help="Store spec (default: %(default)s)"
985+
)
986+
907987
# -- validate-manifest --
908988
p = sub.add_parser(
909989
"validate-manifest",
@@ -930,6 +1010,7 @@ def main() -> None:
9301010
"publish": cmd_publish,
9311011
"check": cmd_check,
9321012
"list": cmd_list,
1013+
"verify": cmd_verify,
9331014
"validate-manifest": cmd_validate_manifest,
9341015
}
9351016
commands[args.command](args)

0 commit comments

Comments
 (0)