## Integration test: BlenderBridge + VirtualTexture working together.
##
## Run with: godot4 --headless --script test/test_integration.gd
##
## Tests:
## 1. Both nodes initialize and start
## 2. Scene export populates shared memory
## 3. VirtualTexture creates GPU resources
## 4. Texture registration returns valid IDs
## 5. Invalidation forwards from BlenderBridge to VirtualTexture
## 6. Stats report correct values
extends SceneTree
func _init() -> void:
print("=== Integration Test: BlenderBridge + VirtualTexture ===")
var passed := 0
var failed := 0
# ── Test 1: Create and configure both nodes ──────────────────────
print(" Creating nodes...")
var bridge := BlenderBridge.new()
bridge.name = "Bridge"
bridge.shm_name = "/test_integration"
bridge.shm_size = 1024 * 1024 # 1 MB for testing
bridge.max_objects = 32
var vt := VirtualTexture.new()
vt.name = "VT"
vt.tile_size = 64 # Smaller for testing
vt.tile_budget = 8
vt.cache_grid_size = 4 # 4×4 = 16 slots
vt.mip_levels = 4
root.add_child(bridge)
root.add_child(vt)
# Wire them together
bridge.virtual_texture_path = bridge.get_path_to(vt)
# ── Test 2: Start server ─────────────────────────────────────────
var err := bridge.start_server("/tmp/test_bb_integration.sock")
if err == OK:
print(" start_server... PASS")
passed += 1
else:
print(" start_server... FAIL (err=%d)" % err)
failed += 1
# ── Test 3: Export scene with a mesh ──────────────────────────────
var mesh_inst := MeshInstance3D.new()
mesh_inst.name = "TestCube"
mesh_inst.mesh = BoxMesh.new()
mesh_inst.position = Vector3(1.0, 2.0, 3.0)
root.add_child(mesh_inst)
err = bridge.export_scene(root)
if err == OK:
print(" export_scene... PASS")
passed += 1
else:
print(" export_scene... FAIL (err=%d)" % err)
failed += 1
# ── Test 4: Verify export info ───────────────────────────────────
var info: Dictionary = bridge.get_export_info()
if info["object_count"] >= 1:
print(" export_info object_count... PASS")
passed += 1
else:
print(" export_info object_count... FAIL (count=%d)" % info["object_count"])
failed += 1
# ── Test 5: Register textures ────────────────────────────────────
var tex_id1: int = vt.register_texture("diffuse_01")
var tex_id2: int = vt.register_texture("normal_01")
if tex_id1 > 0 and tex_id2 > 0 and tex_id1 != tex_id2:
print(" register_texture... PASS")
passed += 1
else:
print(" register_texture... FAIL (ids=%d,%d)" % [tex_id1, tex_id2])
failed += 1
# ── Test 6: Texture count ────────────────────────────────────────
if vt.get_texture_count() == 2:
print(" texture_count... PASS")
passed += 1
else:
print(" texture_count... FAIL (count=%d)" % vt.get_texture_count())
failed += 1
# ── Test 7: Invalidation forwarding ──────────────────────────────
# This should forward to SVT without crashing
bridge.notify_texture_dirty(tex_id1, 0, 0, 2, 2, 0)
print(" notify_texture_dirty... PASS")
passed += 1
# ── Test 8: Stats ────────────────────────────────────────────────
var stats: Dictionary = vt.get_stats()
if stats.has("cache_total") and stats["cache_total"] == 16:
print(" svt_stats... PASS")
passed += 1
else:
print(" svt_stats... FAIL")
failed += 1
# ── Test 9: Unregister texture ───────────────────────────────────
vt.unregister_texture(tex_id2)
if vt.get_texture_count() == 1:
print(" unregister_texture... PASS")
passed += 1
else:
print(" unregister_texture... FAIL (count=%d)" % vt.get_texture_count())
failed += 1
# ── Cleanup ──────────────────────────────────────────────────────
bridge.stop_server()
mesh_inst.queue_free()
print("")
if failed == 0:
print("All %d tests passed." % passed)
else:
print("%d passed, %d FAILED." % [passed, failed])
quit()