Files
gogo2/test_architecture_compliance.py
2025-07-04 23:51:35 +03:00

273 lines
11 KiB
Python

#!/usr/bin/env python3
"""
Test Architecture Compliance After Cleanup
This test verifies that the system now follows the correct architecture:
1. Single, centralized data flow through orchestrator
2. Dashboard gets data through orchestrator, not direct stream management
3. UniversalDataAdapter is the only data stream implementation
4. No conflicting UnifiedDataStream implementations
"""
import sys
import os
import logging
from datetime import datetime
from typing import Dict, Any
# Add project root to path
sys.path.append(os.path.dirname(os.path.abspath(__file__)))
# Configure logging
logging.basicConfig(
level=logging.INFO,
format='%(asctime)s - %(name)s - %(levelname)s - %(message)s'
)
logger = logging.getLogger(__name__)
def test_architecture_imports():
"""Test that correct architecture components can be imported"""
logger.info("=== Testing Architecture Imports ===")
try:
# Test core architecture components
from core.orchestrator import TradingOrchestrator
from core.universal_data_adapter import UniversalDataAdapter, UniversalDataStream
from core.data_provider import DataProvider
logger.info("✓ Core architecture components imported successfully")
# Test dashboard imports
from web.clean_dashboard import create_clean_dashboard
logger.info("✓ Dashboard components imported successfully")
# Verify UnifiedDataStream is NOT available (should be removed)
try:
import importlib.util
spec = importlib.util.find_spec("core.unified_data_stream")
if spec is not None:
logger.error("✗ Old unified_data_stream module still exists - should have been removed")
return False
else:
logger.info("✓ Old unified_data_stream module correctly removed")
except Exception as e:
logger.info("✓ Old unified_data_stream module correctly removed")
return True
except Exception as e:
logger.error(f"✗ Import test failed: {e}")
return False
def test_orchestrator_data_integration():
"""Test that orchestrator properly integrates with UniversalDataAdapter"""
logger.info("=== Testing Orchestrator Data Integration ===")
try:
from core.orchestrator import TradingOrchestrator
from core.universal_data_adapter import UniversalDataAdapter
from core.data_provider import DataProvider
# Create data provider
data_provider = DataProvider()
# Create orchestrator
orchestrator = TradingOrchestrator(data_provider=data_provider)
# Verify orchestrator has universal_adapter
if not hasattr(orchestrator, 'universal_adapter'):
logger.error("✗ Orchestrator missing universal_adapter attribute")
return False
if not isinstance(orchestrator.universal_adapter, UniversalDataAdapter):
logger.error("✗ Orchestrator universal_adapter is not UniversalDataAdapter instance")
return False
logger.info("✓ Orchestrator properly integrated with UniversalDataAdapter")
# Test orchestrator data access methods
if not hasattr(orchestrator, 'get_universal_data_stream'):
logger.error("✗ Orchestrator missing get_universal_data_stream method")
return False
if not hasattr(orchestrator, 'get_universal_data_for_model'):
logger.error("✗ Orchestrator missing get_universal_data_for_model method")
return False
logger.info("✓ Orchestrator has required data access methods")
# Test data stream access
try:
data_stream = orchestrator.get_universal_data_stream()
logger.info("✓ Orchestrator data stream access working")
except Exception as e:
logger.warning(f"⚠ Orchestrator data stream access warning: {e}")
return True
except Exception as e:
logger.error(f"✗ Orchestrator integration test failed: {e}")
return False
def test_dashboard_architecture_compliance():
"""Test that dashboard follows correct architecture pattern"""
logger.info("=== Testing Dashboard Architecture Compliance ===")
try:
# Import dashboard components
from web.clean_dashboard import create_clean_dashboard
# Read dashboard source to verify architecture compliance
dashboard_path = os.path.join(os.path.dirname(__file__), 'web', 'clean_dashboard.py')
with open(dashboard_path, 'r') as f:
dashboard_source = f.read()
# Verify dashboard uses UniversalDataAdapter, not UnifiedDataStream
if 'UniversalDataAdapter' not in dashboard_source:
logger.error("✗ Dashboard not using UniversalDataAdapter")
return False
if 'UnifiedDataStream' in dashboard_source and 'UniversalDataAdapter' not in dashboard_source:
logger.error("✗ Dashboard still using old UnifiedDataStream")
return False
logger.info("✓ Dashboard using correct UniversalDataAdapter")
# Verify dashboard gets data through orchestrator
if '_get_universal_data_from_orchestrator' not in dashboard_source:
logger.error("✗ Dashboard not getting data through orchestrator")
return False
logger.info("✓ Dashboard getting data through orchestrator")
# Verify dashboard doesn't manage streams directly
problematic_patterns = [
'register_consumer',
'subscribe_to_stream',
'stream_consumer',
'add_consumer'
]
for pattern in problematic_patterns:
if pattern in dashboard_source:
logger.warning(f"⚠ Dashboard may still have direct stream management: {pattern}")
logger.info("✓ Dashboard architecture compliance verified")
return True
except Exception as e:
logger.error(f"✗ Dashboard architecture test failed: {e}")
return False
def test_data_flow_architecture():
"""Test the complete data flow architecture"""
logger.info("=== Testing Complete Data Flow Architecture ===")
try:
from core.data_provider import DataProvider
from core.universal_data_adapter import UniversalDataAdapter, UniversalDataStream
from core.orchestrator import TradingOrchestrator
# Create the data flow chain
data_provider = DataProvider()
universal_adapter = UniversalDataAdapter(data_provider)
orchestrator = TradingOrchestrator(data_provider=data_provider)
# Verify data flow: DataProvider -> UniversalDataAdapter -> Orchestrator
logger.info("✓ Data flow components created successfully")
# Test UniversalDataStream structure
try:
# Get sample data stream
sample_stream = universal_adapter.get_universal_data_stream()
# Verify it's a UniversalDataStream dataclass
if hasattr(sample_stream, 'eth_ticks'):
logger.info("✓ UniversalDataStream has eth_ticks")
if hasattr(sample_stream, 'eth_1m'):
logger.info("✓ UniversalDataStream has eth_1m")
if hasattr(sample_stream, 'eth_1h'):
logger.info("✓ UniversalDataStream has eth_1h")
if hasattr(sample_stream, 'eth_1d'):
logger.info("✓ UniversalDataStream has eth_1d")
if hasattr(sample_stream, 'btc_ticks'):
logger.info("✓ UniversalDataStream has btc_ticks")
logger.info("✓ UniversalDataStream structure verified")
except Exception as e:
logger.warning(f"⚠ UniversalDataStream structure test warning: {e}")
return True
except Exception as e:
logger.error(f"✗ Data flow architecture test failed: {e}")
return False
def test_removed_files():
"""Test that conflicting files were properly removed"""
logger.info("=== Testing Removed Files ===")
# Check that unified_data_stream.py was removed
unified_stream_path = os.path.join(os.path.dirname(__file__), 'core', 'unified_data_stream.py')
if os.path.exists(unified_stream_path):
logger.error("✗ core/unified_data_stream.py still exists - should be removed")
return False
logger.info("✓ Conflicting unified_data_stream.py properly removed")
# Check that universal_data_adapter.py still exists
universal_adapter_path = os.path.join(os.path.dirname(__file__), 'core', 'universal_data_adapter.py')
if not os.path.exists(universal_adapter_path):
logger.error("✗ core/universal_data_adapter.py missing - should exist")
return False
logger.info("✓ Correct universal_data_adapter.py exists")
return True
def run_all_tests():
"""Run all architecture compliance tests"""
logger.info("=" * 60)
logger.info("ARCHITECTURE COMPLIANCE TEST SUITE")
logger.info("Testing data flow cleanup and architecture compliance")
logger.info("=" * 60)
tests = [
("Import Architecture", test_architecture_imports),
("Orchestrator Integration", test_orchestrator_data_integration),
("Dashboard Compliance", test_dashboard_architecture_compliance),
("Data Flow Architecture", test_data_flow_architecture),
("Removed Files", test_removed_files)
]
passed = 0
total = len(tests)
for test_name, test_func in tests:
logger.info(f"\n--- {test_name} ---")
try:
if test_func():
logger.info(f"{test_name} PASSED")
passed += 1
else:
logger.error(f"{test_name} FAILED")
except Exception as e:
logger.error(f"{test_name} ERROR: {e}")
logger.info("\n" + "=" * 60)
logger.info(f"ARCHITECTURE COMPLIANCE TEST RESULTS: {passed}/{total} tests passed")
if passed == total:
logger.info("🎉 ALL TESTS PASSED - Architecture cleanup successful!")
logger.info("✓ Single, centralized data flow through orchestrator")
logger.info("✓ Dashboard gets data through orchestrator methods")
logger.info("✓ UniversalDataAdapter is the only data stream implementation")
logger.info("✓ No conflicting UnifiedDataStream implementations")
return True
else:
logger.error(f"{total - passed} tests failed - Architecture issues remain")
return False
if __name__ == "__main__":
success = run_all_tests()
sys.exit(0 if success else 1)