92 lines
2.8 KiB
Python
92 lines
2.8 KiB
Python
|
|
# TinqsMDBridge smoke test -- run via:
|
||
|
|
# python tools/md_bridge.py --file tools/md_bridge/smoke_test.py --timeout 120
|
||
|
|
#
|
||
|
|
# Defensive by design: MD's api docs are incomplete and signatures unverified,
|
||
|
|
# so every step is independently try/except'd and the whole thing returns a
|
||
|
|
# step-by-step report instead of dying on the first surprise. Nothing here
|
||
|
|
# should be treated as the "right" calling convention until this has passed
|
||
|
|
# once -- it's a probe, not a recipe.
|
||
|
|
|
||
|
|
import inspect
|
||
|
|
import os
|
||
|
|
import tempfile
|
||
|
|
import traceback
|
||
|
|
|
||
|
|
report = {"steps": []}
|
||
|
|
|
||
|
|
|
||
|
|
def step(name, fn):
|
||
|
|
entry = {"step": name}
|
||
|
|
try:
|
||
|
|
entry["ok"] = True
|
||
|
|
entry["value"] = fn()
|
||
|
|
except Exception:
|
||
|
|
entry["ok"] = False
|
||
|
|
entry["error"] = traceback.format_exc().strip().splitlines()[-1]
|
||
|
|
report["steps"].append(entry)
|
||
|
|
return entry
|
||
|
|
|
||
|
|
|
||
|
|
def docs_of(mod, names):
|
||
|
|
out = {}
|
||
|
|
for n in names:
|
||
|
|
f = getattr(mod, n, None)
|
||
|
|
if f is None:
|
||
|
|
out[n] = "<missing>"
|
||
|
|
continue
|
||
|
|
try:
|
||
|
|
out[n] = str(inspect.signature(f))
|
||
|
|
except (ValueError, TypeError):
|
||
|
|
doc = (getattr(f, "__doc__", "") or "").strip()
|
||
|
|
out[n] = doc.splitlines()[0] if doc else "<no signature/doc>"
|
||
|
|
return out
|
||
|
|
|
||
|
|
|
||
|
|
# 1. what do the key functions actually look like?
|
||
|
|
step("signatures.pattern", lambda: docs_of(pattern_api, [
|
||
|
|
"CreatePatternWithPoints", "AddSeamlinePairGroup", "SetArrangementPosition",
|
||
|
|
"MovePatternPoint", "DeletePatternPiece"]))
|
||
|
|
step("signatures.utility", lambda: docs_of(utility_api, [
|
||
|
|
"NewProject", "Simulate", "GetAvatarCount", "GetAvatarNameList"]))
|
||
|
|
step("signatures.export", lambda: docs_of(export_api, [
|
||
|
|
"ExportSnapshot3D", "ExportCustomViewSnapshot", "ExportGLTF", "ExportFBX"]))
|
||
|
|
|
||
|
|
# 2. fresh project
|
||
|
|
step("NewProject", lambda: utility_api.NewProject())
|
||
|
|
|
||
|
|
# 3. default avatar present?
|
||
|
|
step("avatars", lambda: {
|
||
|
|
"count": utility_api.GetAvatarCount(),
|
||
|
|
"names": utility_api.GetAvatarNameList(),
|
||
|
|
})
|
||
|
|
|
||
|
|
# 4. create a 50cm square pattern (units unverified -- try mm first, the CLO
|
||
|
|
# convention; the snapshot will show which interpretation MD used)
|
||
|
|
SQUARE_MM = [(0.0, 0.0), (500.0, 0.0), (500.0, 500.0), (0.0, 500.0)]
|
||
|
|
|
||
|
|
|
||
|
|
def make_square():
|
||
|
|
return pattern_api.CreatePatternWithPoints(SQUARE_MM)
|
||
|
|
|
||
|
|
|
||
|
|
step("CreatePatternWithPoints(square)", make_square)
|
||
|
|
|
||
|
|
# 5. short drape
|
||
|
|
step("Simulate(30)", lambda: utility_api.Simulate(30))
|
||
|
|
|
||
|
|
# 6. snapshot -- the agent's eyes
|
||
|
|
SNAP = os.path.join(tempfile.gettempdir(), "tinqs_md_smoke.png")
|
||
|
|
|
||
|
|
|
||
|
|
def snap():
|
||
|
|
export_api.ExportSnapshot3D(SNAP)
|
||
|
|
return {"path": SNAP, "exists": os.path.exists(SNAP),
|
||
|
|
"size": os.path.getsize(SNAP) if os.path.exists(SNAP) else 0}
|
||
|
|
|
||
|
|
|
||
|
|
step("ExportSnapshot3D", snap)
|
||
|
|
|
||
|
|
report["passed"] = sum(1 for s in report["steps"] if s["ok"])
|
||
|
|
report["failed"] = sum(1 for s in report["steps"] if not s["ok"])
|
||
|
|
result = report
|