Spaces:
Sleeping
Sleeping
File size: 6,411 Bytes
6b5095a | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 | """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())
|