Files
Faset_Engine/tests/assets_bundle_test.py
T

70 lines
3.3 KiB
Python

#!/usr/bin/env python3
"""Tests actual GLB bundle publication without requiring Blender's GUI/Python runtime."""
import hashlib
import importlib.util
import json
from pathlib import Path
import struct
import tempfile
import sys
sys.dont_write_bytecode = True
import unittest
import uuid
MODULE = Path(__file__).resolve().parents[1] / "tools/blender_addon/bundle.py"
spec = importlib.util.spec_from_file_location("faset_bundle", MODULE)
bundle = importlib.util.module_from_spec(spec)
spec.loader.exec_module(bundle)
def glb(path, identity, name="Door", duplicate=False):
nodes = [{"name": name, "extras": {"faset_id": identity}}]
if duplicate:
nodes.append(nodes[0].copy())
doc = {"asset": {"version": "2.0"}, "scene": 0, "scenes": [{"nodes": [0]}], "nodes": nodes}
raw = json.dumps(doc).encode()
raw += b" " * (-len(raw) % 4)
path.write_bytes(struct.pack("<IIIII", 0x46546C67, 2, 20 + len(raw), len(raw), 0x4E4F534A) + raw)
class BundleTests(unittest.TestCase):
def test_atomic_roundtrip_and_duplicate_failure(self):
with tempfile.TemporaryDirectory() as tmp:
root = Path(tmp)
identity, asset_id = str(uuid.uuid4()), str(uuid.uuid4())
source, out = root / "scene.glb", root / "published"
glb(source, identity)
first = bundle.publish_bundle(source, out, asset_id, "fixture")
payload = out / first["files"][0]["path"]
self.assertEqual(hashlib.sha256(payload.read_bytes()).hexdigest(), first["files"][0]["sha256"])
self.assertEqual(json.loads((out / "manifest.json").read_text()), first)
glb(source, identity, name="Renamed door")
second = bundle.publish_bundle(source, out, asset_id, "fixture")
self.assertNotEqual(first["generation"], second["generation"])
self.assertEqual(first["outputs"][0]["source_id"], second["outputs"][0]["source_id"])
self.assertTrue(payload.exists(), "old immutable payload prematurely destroyed")
previous = (out / "manifest.json").read_bytes()
glb(source, identity, duplicate=True)
with self.assertRaisesRegex(ValueError, "DuplicateSourceId"):
bundle.publish_bundle(source, out, asset_id, "fixture")
self.assertEqual((out / "manifest.json").read_bytes(), previous)
source.write_bytes(b"broken")
with self.assertRaises(ValueError):
bundle.publish_bundle(source, out, asset_id, "fixture")
self.assertEqual((out / "manifest.json").read_bytes(), previous)
def test_rejects_external_uri_before_publication(self):
with tempfile.TemporaryDirectory() as tmp:
root = Path(tmp)
raw = json.dumps({"asset": {"version": "2.0"}, "buffers": [{"uri": "missing.bin", "byteLength": 4}]}).encode()
raw += b" " * (-len(raw) % 4)
source = root / "source.glb"
source.write_bytes(struct.pack("<IIIII", 0x46546C67, 2, 20 + len(raw), len(raw), 0x4E4F534A) + raw)
with self.assertRaisesRegex(ValueError, "embedded"):
bundle.publish_bundle(source, root / "out", str(uuid.uuid4()), "fixture")
self.assertFalse((root / "out" / "manifest.json").exists())
if __name__ == "__main__":
unittest.main()