Spaces:
Sleeping
Sleeping
| """R0-1 β golden-image gate. | |
| Renders the reference matrix (bundle x tile) through golden_render and compares | |
| against the committed goldens. Any drift beyond tolerance fails with a | |
| side-by-side (golden | current | amplified diff) written to verify_out/. | |
| Usage: | |
| python verify_goldens.py # check against goldens (CI mode) | |
| python verify_goldens.py --bless # regenerate goldens (intentional change) | |
| Tolerances: renders are deterministic numpy, so genuine engine changes show up | |
| as large diffs; the small allowance absorbs PIL/numpy version drift only. | |
| """ | |
| import os | |
| import sys | |
| import numpy as np | |
| from PIL import Image | |
| import golden_render | |
| HERE = os.path.dirname(os.path.abspath(__file__)) | |
| TILES = os.path.join(HERE, "..", "..", "frontend", "viz2d-demo", "src", "assets", "tiles") | |
| GOLDEN_DIR = os.path.join(HERE, "goldens") | |
| OUT = os.path.join(HERE, "verify_out") | |
| MEAN_TOL = 0.5 # mean abs diff per channel | |
| P999_TOL = 8.0 # 99.9th percentile abs diff | |
| MATRIX = [ | |
| # (golden name, bundle, tile) β tiles cover the three texture-prep paths: | |
| # checkered = period-snap, rustic-wood = masked-shift, basalt = native wrap | |
| ("desk_checkered", "data/current_bundle.vizbundle.json", "checkered.jpeg"), | |
| ("desk_rustic", "data/current_bundle.vizbundle.json", "rustic-wood.jpg"), | |
| ("desk_basalt", "data/current_bundle.vizbundle.json", "basalt-outside-wal.jpg"), | |
| ("kitchen_checkered", "data/ref_kitchen.vizbundle.json", "checkered.jpeg"), | |
| ("kitchen_rustic", "data/ref_kitchen.vizbundle.json", "rustic-wood.jpg"), | |
| ("kitchen_basalt", "data/ref_kitchen.vizbundle.json", "basalt-outside-wal.jpg"), | |
| ] | |
| def main(): | |
| bless = "--bless" in sys.argv | |
| os.makedirs(GOLDEN_DIR, exist_ok=True) | |
| os.makedirs(OUT, exist_ok=True) | |
| ok = True | |
| for name, bundle, tile in MATRIX: | |
| img = golden_render.render(os.path.join(HERE, bundle), os.path.join(TILES, tile)) | |
| golden_path = os.path.join(GOLDEN_DIR, f"{name}.png") | |
| if bless: | |
| img.save(golden_path) | |
| print(f" blessed {name}.png ({img.width}x{img.height})") | |
| continue | |
| if not os.path.exists(golden_path): | |
| print(f" [FAIL] {name}: golden missing β run `make bless`") | |
| ok = False | |
| continue | |
| cur = np.asarray(img).astype(np.float64) | |
| gold = np.asarray(Image.open(golden_path).convert("RGB")).astype(np.float64) | |
| if cur.shape != gold.shape: | |
| print(f" [FAIL] {name}: size changed {gold.shape} -> {cur.shape}") | |
| ok = False | |
| continue | |
| diff = np.abs(cur - gold) | |
| mean_d = float(diff.mean()) | |
| p999 = float(np.percentile(diff, 99.9)) | |
| passed = mean_d <= MEAN_TOL and p999 <= P999_TOL | |
| print(f" [{'PASS' if passed else 'FAIL'}] {name}: mean={mean_d:.3f} p99.9={p999:.1f}") | |
| if not passed: | |
| ok = False | |
| amplified = np.clip(diff * 8, 0, 255).astype(np.uint8) | |
| panel = np.concatenate( | |
| [gold.astype(np.uint8), cur.astype(np.uint8), amplified], axis=1 | |
| ) | |
| fail_path = os.path.join(OUT, f"golden_fail_{name}.png") | |
| Image.fromarray(panel).save(fail_path) | |
| print(f" side-by-side: {fail_path} (golden | current | diff x8)") | |
| if bless: | |
| print("goldens regenerated β commit backend/floor-visualizer/goldens/") | |
| return 0 | |
| print("\n" + ("ALL GOLDEN CHECKS PASSED" if ok else "GOLDEN CHECKS FAILED")) | |
| return 0 if ok else 1 | |
| if __name__ == "__main__": | |
| raise SystemExit(main()) | |