Spaces:
Sleeping
Sleeping
| """DGXC discovery verifier — exercise the new recursive discover_assets | |
| against four synthetic layouts. Self-contained: imports validate.py with | |
| SIMREADY_INSIDE_KIT + SIMREADY_FOUNDATIONS_PATH already set so the bootstrap | |
| gate clears. | |
| Usage on the pod: | |
| export SIMREADY_FOUNDATIONS_PATH=/home/horde/.simready/simready_foundations | |
| /home/horde/.simready/venv/bin/python3 test_discover_dgxc.py | |
| """ | |
| from __future__ import annotations | |
| import os | |
| import sys | |
| import tempfile | |
| from pathlib import Path | |
| # Skip the Kit re-exec gate (we're testing pure-Python discovery, no Kit). | |
| os.environ.setdefault("SIMREADY_INSIDE_KIT", "1") | |
| # Resolve the repo: env var first (DGXC ad-hoc run), then assume the | |
| # script lives inside a checkout (workflow / local). | |
| _env_repo = os.environ.get("SIMREADY_REPO") | |
| if _env_repo: | |
| REPO = Path(_env_repo) | |
| else: | |
| REPO = Path(__file__).resolve().parents[2] | |
| SKILL = REPO / "tools" / "validation" / "plugins" / "simready-report" / "skills" / "simready-report" | |
| if not SKILL.is_dir(): | |
| raise SystemExit( | |
| f"Validator skill dir not found at {SKILL}. " | |
| f"Set SIMREADY_REPO to the simready-oem-library-pm checkout root." | |
| ) | |
| sys.path.insert(0, str(SKILL)) | |
| import validate as v # noqa: E402 | |
| CASES = [ | |
| # (label, build_tree, expected_assets, expected_finding_codes) | |
| ("well_shaped", | |
| lambda root: [ | |
| (root / "well_shaped" / "well_shaped.usda", "interface"), | |
| (root / "well_shaped" / "Geometry" / "mesh.usda", "sublayer (Geometry)"), | |
| (root / "well_shaped" / "Materials" / "mat.usda", "sublayer (Materials)"), | |
| ], | |
| # Old behavior preserved: only the bundle interface is returned. | |
| ["well_shaped/well_shaped.usda"], | |
| []), | |
| ("flat", | |
| lambda root: [ | |
| (root / "flat" / "scene_a.usda", "root-level USD, no bundle"), | |
| (root / "flat" / "scene_b.usda", "root-level USD, no bundle"), | |
| ], | |
| # New behavior: both found, both tagged as non-standard. | |
| ["flat/scene_a.usda", "flat/scene_b.usda"], | |
| ["LAYOUT.NON_STANDARD_BUNDLE", "LAYOUT.NON_STANDARD_BUNDLE"]), | |
| ("deep", | |
| lambda root: [ | |
| (root / "deep" / "team1" / "v1" / "scenes" / "render_target.usda", | |
| "deeply-nested USD, no bundle wrapper"), | |
| ], | |
| # New behavior: found at depth, flagged. | |
| ["deep/team1/v1/scenes/render_target.usda"], | |
| ["LAYOUT.NON_STANDARD_BUNDLE"]), | |
| ("mixed", | |
| lambda root: [ | |
| (root / "mixed" / "proper_bundle" / "proper_bundle.usda", "interface"), | |
| (root / "mixed" / "proper_bundle" / "Geometry" / "g.usda", "sublayer"), | |
| (root / "mixed" / "orphan.usda", "standalone — not a bundle"), | |
| ], | |
| # Bundle interface and the orphan validate; sublayer excluded; orphan flagged. | |
| ["mixed/orphan.usda", "mixed/proper_bundle/proper_bundle.usda"], | |
| ["LAYOUT.NON_STANDARD_BUNDLE"]), | |
| # Real-world layout from Aperdata's Kitchen-01 dataset: | |
| # `<top_dir>/<asset>.usd` for the top-level interface plus a | |
| # `<top_dir>/SubUSDs/<many>.usd` sublayer tree. The interface | |
| # stem (`Indoor`) doesn't match the dir name (`0_Kitchen_Indoor`), | |
| # so older logic missed the SubUSDs filter and counted them as | |
| # standalone assets — Aperdata went from 23 expected to 933 | |
| # validated. New logic excludes anything under a SUBLAYER_DIR | |
| # ancestor structurally, regardless of bundle naming. | |
| ("aperdata_kitchen", | |
| lambda root: [ | |
| (root / "aperdata_kitchen" / "0_Kitchen_Indoor" / "Indoor.usda", "interface (stem != parent dir)"), | |
| (root / "aperdata_kitchen" / "0_Kitchen_Indoor" / "SubUSDs" / "CL06.usda", "sublayer (under SubUSDs)"), | |
| (root / "aperdata_kitchen" / "0_Kitchen_Indoor" / "SubUSDs" / "CL06_1.usda", "sublayer (under SubUSDs)"), | |
| (root / "aperdata_kitchen" / "0_Kitchen_Indoor" / "SubUSDs" / "DEC_large_leaf.usda", "sublayer (under SubUSDs)"), | |
| (root / "aperdata_kitchen" / "mug_handheld" / "Collected_dining_mug_handheld" / "dining_mug_handheld.usda", | |
| "interface in nested Collected_* dir"), | |
| ], | |
| # Only the two interface USDs validate. SubUSDs/* are excluded | |
| # structurally. The deep mug_handheld interface IS the only | |
| # candidate in its top-level dir, so it counts as a bundle | |
| # interface (no layout warning). Indoor.usd is also the only | |
| # candidate under 0_Kitchen_Indoor → no warning. | |
| [ | |
| "aperdata_kitchen/0_Kitchen_Indoor/Indoor.usda", | |
| "aperdata_kitchen/mug_handheld/Collected_dining_mug_handheld/dining_mug_handheld.usda", | |
| ], | |
| []), | |
| ] | |
| def _normalize(paths: list[Path], root: Path) -> list[str]: | |
| return sorted(str(p.relative_to(root)).replace("\\", "/") for p in paths) | |
| def main() -> int: | |
| failures = 0 | |
| with tempfile.TemporaryDirectory(prefix="sr-discover-test-") as td: | |
| root = Path(td) | |
| for label, build, expected_assets, expected_codes in CASES: | |
| case_dir = root / label | |
| case_dir.mkdir(parents=True, exist_ok=True) | |
| for usd_path, _why in build(root): | |
| usd_path.parent.mkdir(parents=True, exist_ok=True) | |
| usd_path.write_text("()") # empty stage — discover_assets is pure FS walk | |
| assets, findings = v.discover_assets(case_dir) | |
| got_assets = _normalize(assets, root) | |
| got_codes = sorted([f["code"] for f in findings]) | |
| exp_assets = sorted(expected_assets) | |
| exp_codes = sorted(expected_codes) | |
| ok = (got_assets == exp_assets and got_codes == exp_codes) | |
| mark = "PASS" if ok else "FAIL" | |
| print(f" [{mark}] {label}") | |
| print(f" expected assets: {exp_assets}") | |
| print(f" got assets: {got_assets}") | |
| print(f" expected findings: {exp_codes}") | |
| print(f" got findings: {got_codes}") | |
| if not ok: | |
| failures += 1 | |
| for f in findings: | |
| print(f" finding detail: {f}") | |
| print() | |
| if failures: | |
| print(f"{failures} case(s) FAILED") | |
| return 1 | |
| print("all cases passed — recursive discovery + layout findings working end-to-end on DGXC") | |
| return 0 | |
| if __name__ == "__main__": | |
| raise SystemExit(main()) | |