CtrEditor/tsnet_complete_test_suite.py

431 lines
14 KiB
Python

#!/usr/bin/env python3
"""
TSNet Phase 2 - Test Suite Completo
Tests exhaustivos para validar la funcionalidad de simulación TSNet
"""
import requests
import json
import time
import sys
from datetime import datetime
class TSNetTestSuite:
def __init__(self, base_url="http://localhost:5006"):
self.base_url = base_url
self.test_results = []
self.created_objects = []
def log_test(self, test_name, passed, details=""):
"""Registrar resultado de test"""
self.test_results.append(
{
"test": test_name,
"passed": passed,
"details": details,
"timestamp": datetime.now().isoformat(),
}
)
status = "✅ PASS" if passed else "❌ FAIL"
print(f"{status}: {test_name}")
if details:
print(f" Details: {details}")
def send_mcp_request(self, method, params=None, timeout=10):
"""Enviar request MCP con manejo de errores"""
try:
payload = {
"jsonrpc": "2.0",
"method": method,
"id": int(time.time() * 1000),
}
if params:
payload["params"] = params
response = requests.post(self.base_url, json=payload, timeout=timeout)
if response.status_code == 200:
result = response.json()
if "error" in result:
return False, f"MCP Error: {result['error']}"
return True, result.get("result", {})
else:
return False, f"HTTP {response.status_code}: {response.text[:200]}"
except Exception as e:
return False, f"Exception: {str(e)}"
def test_01_mcp_connectivity(self):
"""Test 1: Conectividad básica MCP"""
success, result = self.send_mcp_request("get_ctreditor_status")
if success:
status = result.get("connection_status", "unknown")
self.log_test(
"MCP Connectivity", status == "available", f"Status: {status}"
)
else:
self.log_test("MCP Connectivity", False, result)
return success
def test_02_clear_workspace(self):
"""Test 2: Limpiar workspace"""
success, result = self.send_mcp_request("list_objects")
if success:
objects = result.get("objects", [])
if objects:
# Eliminar objetos existentes
object_ids = [str(obj["id"]["Value"]) for obj in objects]
del_success, del_result = self.send_mcp_request(
"delete_objects", {"ids": object_ids}
)
self.log_test(
"Clear Workspace", del_success, f"Deleted {len(object_ids)} objects"
)
else:
self.log_test("Clear Workspace", True, "Workspace already empty")
else:
self.log_test("Clear Workspace", False, result)
return success
def test_03_create_hydraulic_system(self):
"""Test 3: Crear sistema hidráulico completo"""
components = [
{"type": "osHydTank", "x": 1.0, "y": 1.0, "name": "Source Tank"},
{"type": "osHydPump", "x": 3.0, "y": 1.0, "name": "Main Pump"},
{"type": "osHydPipe", "x": 5.0, "y": 1.0, "name": "Pipe 1"},
{"type": "osHydTank", "x": 7.0, "y": 1.0, "name": "Target Tank"},
]
created_count = 0
for comp in components:
success, result = self.send_mcp_request(
"create_object", {"type": comp["type"], "x": comp["x"], "y": comp["y"]}
)
if success:
created_count += 1
self.created_objects.append(comp["name"])
total_components = len(components)
all_created = created_count == total_components
self.log_test(
"Create Hydraulic System",
all_created,
f"Created {created_count}/{total_components} components",
)
return all_created
def test_04_list_created_objects(self):
"""Test 4: Verificar objetos creados"""
success, result = self.send_mcp_request("list_objects")
if success:
objects = result.get("objects", [])
hydraulic_objects = [
obj for obj in objects if "osHyd" in obj.get("type", "")
]
self.log_test(
"List Created Objects",
len(hydraulic_objects) > 0,
f"Found {len(hydraulic_objects)} hydraulic objects",
)
# Mostrar detalles de objetos hidráulicos
for obj in hydraulic_objects:
obj_type = obj.get("type", "Unknown")
obj_id = obj.get("id", {}).get("Value", "No ID")
print(f" - {obj_type} (ID: {obj_id})")
return len(hydraulic_objects) > 0
else:
self.log_test("List Created Objects", False, result)
return False
def test_05_tsnet_basic_integration(self):
"""Test 5: Integración básica TSNet"""
code = """
try:
print("Testing TSNet basic integration...")
app.TestTSNetIntegrationSync()
result = "SUCCESS: Basic TSNet integration test completed"
except Exception as e:
result = f"ERROR: {str(e)}"
import traceback
result += "\\n" + traceback.format_exc()
print(result)
"""
success, result = self.send_mcp_request(
"execute_python", {"code": code}, timeout=30
)
test_passed = success and "SUCCESS" in str(result)
self.log_test("TSNet Basic Integration", test_passed, str(result)[:200])
return test_passed
def test_06_tsnet_full_simulation(self):
"""Test 6: Simulación completa TSNet"""
code = """
try:
print("Testing TSNet full simulation...")
# Verificar objetos hidráulicos disponibles
hydraulic_objects = []
for obj in app.ObjetosSimulables:
if obj.GetType().Name.startswith("osHyd"):
hydraulic_objects.append({
'name': obj.Nombre,
'type': obj.GetType().Name,
'id': obj.Id.Value if obj.Id else None
})
print(f"Found {len(hydraulic_objects)} hydraulic objects:")
for hobj in hydraulic_objects:
print(f" - {hobj['name']} ({hobj['type']}) ID: {hobj['id']}")
# Ejecutar simulación TSNet
app.RunTSNetSimulationSync()
result = f"SUCCESS: Full TSNet simulation completed with {len(hydraulic_objects)} objects"
except Exception as e:
result = f"ERROR: {str(e)}"
import traceback
result += "\\n" + traceback.format_exc()
print(result)
"""
success, result = self.send_mcp_request(
"execute_python", {"code": code}, timeout=45
)
test_passed = success and "SUCCESS" in str(result)
self.log_test("TSNet Full Simulation", test_passed, str(result)[:300])
return test_passed
def test_07_adapter_validation(self):
"""Test 7: Validación de adaptadores TSNet"""
code = """
try:
print("Testing TSNet adapters validation...")
# Verificar adaptadores creados
adapter_count = {
'tanks': len(app.tsnetSimulationManager._tankAdapters) if hasattr(app.tsnetSimulationManager, '_tankAdapters') else 0,
'pumps': len(app.tsnetSimulationManager._pumpAdapters) if hasattr(app.tsnetSimulationManager, '_pumpAdapters') else 0,
'pipes': len(app.tsnetSimulationManager._pipeAdapters) if hasattr(app.tsnetSimulationManager, '_pipeAdapters') else 0
}
print(f"Adapters created: {adapter_count}")
# Validar configuraciones
config_errors = app.tsnetSimulationManager.ValidateAllConfigurations()
print(f"Configuration errors: {len(config_errors)}")
for error in config_errors:
print(f" - {error}")
total_adapters = sum(adapter_count.values())
result = f"SUCCESS: {total_adapters} adapters, {len(config_errors)} config errors"
except Exception as e:
result = f"ERROR: {str(e)}"
import traceback
result += "\\n" + traceback.format_exc()
print(result)
"""
success, result = self.send_mcp_request(
"execute_python", {"code": code}, timeout=30
)
test_passed = success and "SUCCESS" in str(result)
self.log_test("Adapter Validation", test_passed, str(result)[:300])
return test_passed
def test_08_network_rebuild(self):
"""Test 8: Reconstrucción de red hidráulica"""
code = """
try:
print("Testing network rebuild...")
# Reconstruir red
app.tsnetSimulationManager.RebuildNetwork()
# Verificar estado de la red
network_state = "Network rebuilt successfully"
if hasattr(app.tsnetSimulationManager, 'Network'):
network_state += " - Network object exists"
result = f"SUCCESS: {network_state}"
except Exception as e:
result = f"ERROR: {str(e)}"
import traceback
result += "\\n" + traceback.format_exc()
print(result)
"""
success, result = self.send_mcp_request(
"execute_python", {"code": code}, timeout=30
)
test_passed = success and "SUCCESS" in str(result)
self.log_test("Network Rebuild", test_passed, str(result)[:200])
return test_passed
def test_09_object_registration_stress(self):
"""Test 9: Stress test de registro de objetos"""
code = """
try:
print("Testing object registration stress...")
# Resetear manager
app.tsnetSimulationManager.ResetAllCalculatedValues()
# Registrar todos los objetos hidráulicos múltiples veces
registration_count = 0
for iteration in range(3):
for obj in app.ObjetosSimulables:
if obj.GetType().Name.startswith("osHyd"):
try:
app.tsnetSimulationManager.RegisterHydraulicObject(obj)
registration_count += 1
except Exception as reg_ex:
print(f"Registration error for {obj.Nombre}: {reg_ex}")
result = f"SUCCESS: {registration_count} registrations completed"
except Exception as e:
result = f"ERROR: {str(e)}"
import traceback
result += "\\n" + traceback.format_exc()
print(result)
"""
success, result = self.send_mcp_request(
"execute_python", {"code": code}, timeout=30
)
test_passed = success and "SUCCESS" in str(result)
self.log_test("Object Registration Stress", test_passed, str(result)[:200])
return test_passed
def test_10_performance_timing(self):
"""Test 10: Medición de rendimiento"""
code = """
import time
try:
print("Testing performance timing...")
# Medir tiempo de simulación completa
start_time = time.time()
# Resetear
app.tsnetSimulationManager.ResetAllCalculatedValues()
# Registrar objetos
reg_start = time.time()
hydraulic_count = 0
for obj in app.ObjetosSimulables:
if obj.GetType().Name.startswith("osHyd"):
app.tsnetSimulationManager.RegisterHydraulicObject(obj)
hydraulic_count += 1
reg_time = time.time() - reg_start
# Validar configuraciones
val_start = time.time()
config_errors = app.tsnetSimulationManager.ValidateAllConfigurations()
val_time = time.time() - val_start
# Reconstruir red
net_start = time.time()
app.tsnetSimulationManager.RebuildNetwork()
net_time = time.time() - net_start
total_time = time.time() - start_time
result = f"SUCCESS: Total: {total_time:.3f}s, Registration: {reg_time:.3f}s, Validation: {val_time:.3f}s, Network: {net_time:.3f}s ({hydraulic_count} objects)"
except Exception as e:
result = f"ERROR: {str(e)}"
import traceback
result += "\\n" + traceback.format_exc()
print(result)
"""
success, result = self.send_mcp_request(
"execute_python", {"code": code}, timeout=30
)
test_passed = success and "SUCCESS" in str(result)
self.log_test("Performance Timing", test_passed, str(result)[:300])
return test_passed
def run_all_tests(self):
"""Ejecutar todos los tests"""
print("🧪 TSNet Phase 2 - Complete Test Suite")
print("=" * 60)
print(f"Started at: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}")
print()
# Lista de tests a ejecutar
tests = [
self.test_01_mcp_connectivity,
self.test_02_clear_workspace,
self.test_03_create_hydraulic_system,
self.test_04_list_created_objects,
self.test_05_tsnet_basic_integration,
self.test_06_tsnet_full_simulation,
self.test_07_adapter_validation,
self.test_08_network_rebuild,
self.test_09_object_registration_stress,
self.test_10_performance_timing,
]
# Ejecutar tests
for i, test_func in enumerate(tests, 1):
print(f"\n--- Test {i:02d}: {test_func.__doc__.split(':')[1].strip()} ---")
try:
test_func()
except Exception as e:
self.log_test(f"Test {i:02d} Execution", False, f"Exception: {str(e)}")
# Pequeña pausa entre tests
time.sleep(1)
# Resumen final
self.print_summary()
def print_summary(self):
"""Imprimir resumen de resultados"""
print("\n" + "=" * 60)
print("📊 TEST SUMMARY")
print("=" * 60)
passed_tests = [r for r in self.test_results if r["passed"]]
failed_tests = [r for r in self.test_results if not r["passed"]]
print(f"Total Tests: {len(self.test_results)}")
print(f"Passed: {len(passed_tests)}")
print(f"Failed: {len(failed_tests)}")
print(f"Success Rate: {len(passed_tests)/len(self.test_results)*100:.1f}%")
if failed_tests:
print("\n❌ Failed Tests:")
for test in failed_tests:
print(f"{test['test']}: {test['details'][:100]}")
if len(passed_tests) == len(self.test_results):
print("\n🎉 ALL TESTS PASSED! TSNet Phase 2 is fully functional.")
elif len(passed_tests) >= len(self.test_results) * 0.8:
print("\n✅ Most tests passed. TSNet Phase 2 is mostly functional.")
else:
print("\n⚠️ Multiple test failures. Please review the implementation.")
print(f"\nCompleted at: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}")
def main():
test_suite = TSNetTestSuite()
test_suite.run_all_tests()
if __name__ == "__main__":
main()