CtrEditor/tsnet_complete_test_suite.py

402 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()