199 lines
6.4 KiB
Python
199 lines
6.4 KiB
Python
|
|
#!/usr/bin/env python3
|
|||
|
|
"""Tests for dual-layer symbolic integration.
|
|||
|
|
|
|||
|
|
Tests verify:
|
|||
|
|
- dual_layer_integration.py module imports correctly
|
|||
|
|
- setup_dual_layer installs endpoints on FastAPI app
|
|||
|
|
- integrate_with_server convenience function works
|
|||
|
|
- Endpoints are registered with correct routes
|
|||
|
|
"""
|
|||
|
|
|
|||
|
|
import sys
|
|||
|
|
from pathlib import Path
|
|||
|
|
|
|||
|
|
sys.path.insert(0, str(Path.cwd()))
|
|||
|
|
|
|||
|
|
|
|||
|
|
def test_dual_layer_module_import():
|
|||
|
|
"""Test that dual_layer_integration.py imports correctly."""
|
|||
|
|
try:
|
|||
|
|
import dual_layer_integration as dli
|
|||
|
|
assert hasattr(dli, 'setup_dual_layer'), "Missing setup_dual_layer"
|
|||
|
|
assert hasattr(dli, 'integrate_with_server'), "Missing integrate_with_server"
|
|||
|
|
print("PASS: dual_layer_integration module imports with all symbols")
|
|||
|
|
return True
|
|||
|
|
except Exception as e:
|
|||
|
|
print(f"FAIL: Import failed: {e}")
|
|||
|
|
return False
|
|||
|
|
|
|||
|
|
|
|||
|
|
def test_setup_dual_layer_creates_endpoints():
|
|||
|
|
"""Test that setup_dual_layer installs expected routes."""
|
|||
|
|
try:
|
|||
|
|
from fastapi import FastAPI
|
|||
|
|
from dual_layer_integration import setup_dual_layer
|
|||
|
|
|
|||
|
|
app = FastAPI()
|
|||
|
|
setup_dual_layer(app)
|
|||
|
|
|
|||
|
|
routes = [r.path for r in app.routes]
|
|||
|
|
|
|||
|
|
expected_routes = [
|
|||
|
|
"/api/symbolic/status",
|
|||
|
|
"/api/symbolic/glyphs",
|
|||
|
|
"/api/symbolic/activate",
|
|||
|
|
"/api/symbolic/deactivate",
|
|||
|
|
"/api/symbolic/routing/summary",
|
|||
|
|
]
|
|||
|
|
|
|||
|
|
for route in expected_routes:
|
|||
|
|
if route not in routes:
|
|||
|
|
print(f"FAIL: Route {route} not registered. Routes: {routes}")
|
|||
|
|
return False
|
|||
|
|
|
|||
|
|
print(f"PASS: All {len(expected_routes)} symbolic routes registered")
|
|||
|
|
return True
|
|||
|
|
except Exception as e:
|
|||
|
|
print(f"FAIL: setup_dual_layer failed: {e}")
|
|||
|
|
return False
|
|||
|
|
|
|||
|
|
|
|||
|
|
def test_integrate_with_server():
|
|||
|
|
"""Test integrate_with_server convenience function."""
|
|||
|
|
try:
|
|||
|
|
from fastapi import FastAPI
|
|||
|
|
from dual_layer_integration import integrate_with_server
|
|||
|
|
|
|||
|
|
app = FastAPI()
|
|||
|
|
integrate_with_server(app)
|
|||
|
|
|
|||
|
|
routes = [r.path for r in app.routes]
|
|||
|
|
symbolic_routes = [r for r in routes if "/api/symbolic" in r]
|
|||
|
|
|
|||
|
|
if len(symbolic_routes) < 3:
|
|||
|
|
print(f"FAIL: Expected at least 3 symbolic routes, got {len(symbolic_routes)}")
|
|||
|
|
return False
|
|||
|
|
|
|||
|
|
print(f"PASS: integrate_with_server installs {len(symbolic_routes)} symbolic routes")
|
|||
|
|
return True
|
|||
|
|
except Exception as e:
|
|||
|
|
print(f"FAIL: integrate_with_server failed: {e}")
|
|||
|
|
return False
|
|||
|
|
|
|||
|
|
|
|||
|
|
def test_dual_layer_routing_config():
|
|||
|
|
"""Test that the routing map is properly configured."""
|
|||
|
|
try:
|
|||
|
|
from dual_layer.router import TYPE_ROUTING_MAP
|
|||
|
|
|
|||
|
|
assert isinstance(TYPE_ROUTING_MAP, dict), "TYPE_ROUTING_MAP should be a dict"
|
|||
|
|
|
|||
|
|
expected_keys = {
|
|||
|
|
"frost_steel_stabilizer", "mirror_weave_reasoning", "solar_veil_memory",
|
|||
|
|
"orbital_thread_network", "star_bloom_creativity", "frost_circuit_logic",
|
|||
|
|
"twin_vector_identity", "monument_grade_equilibrium", "aether_node",
|
|||
|
|
}
|
|||
|
|
present_keys = set(TYPE_ROUTING_MAP.keys())
|
|||
|
|
missing = expected_keys - present_keys
|
|||
|
|
|
|||
|
|
for key in present_keys:
|
|||
|
|
config = TYPE_ROUTING_MAP[key]
|
|||
|
|
assert "model" in config, f"{key} missing 'model'"
|
|||
|
|
assert "vram_budget" in config, f"{key} missing 'vram_budget'"
|
|||
|
|
|
|||
|
|
print(f"PASS: Routing config has {len(TYPE_ROUTING_MAP)} specialized types, all with model + vram_budget")
|
|||
|
|
if missing:
|
|||
|
|
print(f" ℹ️ Expected but missing: {missing}")
|
|||
|
|
return True
|
|||
|
|
except Exception as e:
|
|||
|
|
print(f"FAIL: Routing config check failed: {e}")
|
|||
|
|
return False
|
|||
|
|
|
|||
|
|
|
|||
|
|
def test_dual_layer_vram_manager():
|
|||
|
|
"""Test that VRAM manager exists with correct thresholds."""
|
|||
|
|
try:
|
|||
|
|
from dual_layer.vram_manager import VRAMManager, MAX_VRAM, WARNING_THRESHOLD, CRITICAL_THRESHOLD
|
|||
|
|
|
|||
|
|
manager = VRAMManager()
|
|||
|
|
assert manager is not None
|
|||
|
|
|
|||
|
|
assert MAX_VRAM == 8.0, f"MAX_VRAM should be 8.0, got {MAX_VRAM}"
|
|||
|
|
assert WARNING_THRESHOLD == 6.5, f"WARNING_THRESHOLD should be 6.5, got {WARNING_THRESHOLD}"
|
|||
|
|
assert CRITICAL_THRESHOLD == 7.5, f"CRITICAL_THRESHOLD should be 7.5, got {CRITICAL_THRESHOLD}"
|
|||
|
|
|
|||
|
|
print("PASS: VRAM manager active with correct thresholds (8GB / 6.5GB / 7.5GB)")
|
|||
|
|
return True
|
|||
|
|
except Exception as e:
|
|||
|
|
print(f"FAIL: VRAM manager check failed: {e}")
|
|||
|
|
return False
|
|||
|
|
|
|||
|
|
|
|||
|
|
def test_dual_layer_status_endpoint():
|
|||
|
|
"""Test the symbolic status endpoint returns valid data."""
|
|||
|
|
try:
|
|||
|
|
from fastapi import FastAPI
|
|||
|
|
from dual_layer_integration import setup_dual_layer
|
|||
|
|
from fastapi.testclient import TestClient
|
|||
|
|
|
|||
|
|
app = FastAPI()
|
|||
|
|
setup_dual_layer(app)
|
|||
|
|
client = TestClient(app)
|
|||
|
|
|
|||
|
|
response = client.get("/api/symbolic/status")
|
|||
|
|
data = response.json()
|
|||
|
|
|
|||
|
|
assert response.status_code == 200, f"Status endpoint returned {response.status_code}"
|
|||
|
|
assert "status" in data, "Missing status field"
|
|||
|
|
|
|||
|
|
print(f"PASS: Status endpoint returns: {data['status']}")
|
|||
|
|
return True
|
|||
|
|
except ImportError:
|
|||
|
|
print(" SKIP: TestClient not available (requires httpx)")
|
|||
|
|
return True
|
|||
|
|
except Exception as e:
|
|||
|
|
print(f"FAIL: Status endpoint failed: {e}")
|
|||
|
|
return False
|
|||
|
|
|
|||
|
|
|
|||
|
|
def main_test():
|
|||
|
|
print("[TEST SUITE] test_dual_layer_integration.py")
|
|||
|
|
print()
|
|||
|
|
|
|||
|
|
tests = [
|
|||
|
|
("Module import", test_dual_layer_module_import),
|
|||
|
|
("Endpoints created", test_setup_dual_layer_creates_endpoints),
|
|||
|
|
("integrate_with_server", test_integrate_with_server),
|
|||
|
|
("Routing config", test_dual_layer_routing_config),
|
|||
|
|
("VRAM manager", test_dual_layer_vram_manager),
|
|||
|
|
("Status endpoint", test_dual_layer_status_endpoint),
|
|||
|
|
]
|
|||
|
|
|
|||
|
|
passed = 0
|
|||
|
|
failed = 0
|
|||
|
|
skipped = 0
|
|||
|
|
|
|||
|
|
for name, test_func in tests:
|
|||
|
|
print(f"Running: {name}...", end=" ")
|
|||
|
|
try:
|
|||
|
|
result = test_func()
|
|||
|
|
if result is True:
|
|||
|
|
passed += 1
|
|||
|
|
elif result is None:
|
|||
|
|
skipped += 1
|
|||
|
|
print("SKIP")
|
|||
|
|
else:
|
|||
|
|
failed += 1
|
|||
|
|
except Exception as e:
|
|||
|
|
print(f"FAIL: {e}")
|
|||
|
|
failed += 1
|
|||
|
|
|
|||
|
|
print()
|
|||
|
|
print(f"Results: {passed} passed, {failed} failed, {skipped} skipped")
|
|||
|
|
|
|||
|
|
return 0 if failed == 0 else 1
|
|||
|
|
|
|||
|
|
|
|||
|
|
if __name__ == "__main__":
|
|||
|
|
sys.exit(main_test())
|