Some checks failed
Build Simulation and Test / Run All Tests (push) Failing after 1m46s
218 lines
7.3 KiB
Python
218 lines
7.3 KiB
Python
"""Tests for headless simulation engine."""
|
|
|
|
import time
|
|
from unittest.mock import Mock, patch
|
|
|
|
from engines.headless_engine import HeadlessSimulationEngine, HeadlessConfig
|
|
from config.simulation_config import SimulationConfig
|
|
|
|
|
|
class TestHeadlessConfig:
|
|
"""Test headless configuration."""
|
|
|
|
def test_custom_values(self):
|
|
"""Test custom configuration values."""
|
|
sim_config = SimulationConfig(initial_cells=50, default_tps=120.0)
|
|
|
|
config = HeadlessConfig(
|
|
simulation=sim_config,
|
|
max_ticks=10000,
|
|
max_duration=300.0,
|
|
output_dir="custom_output",
|
|
enable_metrics=False,
|
|
enable_entities=True,
|
|
enable_evolution=False,
|
|
metrics_interval=50,
|
|
entities_interval=500,
|
|
evolution_interval=2000,
|
|
output_formats=['json', 'csv'],
|
|
real_time=True
|
|
)
|
|
|
|
assert config.simulation == sim_config
|
|
assert config.max_ticks == 10000
|
|
assert config.max_duration == 300.0
|
|
assert config.output_dir == "custom_output"
|
|
assert config.enable_metrics == False
|
|
assert config.enable_entities == True
|
|
assert config.enable_evolution == False
|
|
assert config.metrics_interval == 50
|
|
assert config.entities_interval == 500
|
|
assert config.evolution_interval == 2000
|
|
assert config.output_formats == ['json', 'csv']
|
|
assert config.real_time == True
|
|
|
|
|
|
class TestHeadlessSimulationEngine:
|
|
"""Test headless simulation engine."""
|
|
|
|
def test_initialization(self):
|
|
"""Test engine initialization."""
|
|
sim_config = SimulationConfig(initial_cells=5, initial_food=10)
|
|
config = HeadlessConfig(
|
|
simulation=sim_config,
|
|
max_ticks=1000,
|
|
output_formats=['json']
|
|
)
|
|
|
|
engine = HeadlessSimulationEngine(config)
|
|
|
|
assert engine.config == config
|
|
assert engine.event_bus is not None
|
|
assert engine.simulation_core is not None
|
|
assert engine.file_writer is not None
|
|
assert engine.formatters is not None
|
|
assert engine.collectors is not None
|
|
assert engine.running == False
|
|
assert engine.start_time is None
|
|
|
|
def test_collectors_creation(self):
|
|
"""Test collectors are created based on configuration."""
|
|
sim_config = SimulationConfig()
|
|
config = HeadlessConfig(
|
|
simulation=sim_config,
|
|
enable_metrics=True,
|
|
enable_entities=True,
|
|
enable_evolution=False,
|
|
metrics_interval=50,
|
|
entities_interval=200
|
|
)
|
|
|
|
engine = HeadlessSimulationEngine(config)
|
|
|
|
assert 'metrics' in engine.collectors
|
|
assert 'entities' in engine.collectors
|
|
assert 'evolution' not in engine.collectors
|
|
assert engine.collectors['metrics'].collection_interval == 50
|
|
assert engine.collectors['entities'].collection_interval == 200
|
|
|
|
def test_formatters_creation(self):
|
|
"""Test formatters are created based on configuration."""
|
|
sim_config = SimulationConfig()
|
|
config = HeadlessConfig(
|
|
simulation=sim_config,
|
|
output_formats=['json', 'csv']
|
|
)
|
|
|
|
engine = HeadlessSimulationEngine(config)
|
|
|
|
assert 'json' in engine.formatters
|
|
assert 'csv' in engine.formatters
|
|
|
|
def test_should_terminate_max_ticks(self):
|
|
"""Test termination condition for max ticks."""
|
|
sim_config = SimulationConfig()
|
|
config = HeadlessConfig(simulation=sim_config, max_ticks=100)
|
|
|
|
engine = HeadlessSimulationEngine(config)
|
|
engine.running = True
|
|
engine.start_time = time.time()
|
|
|
|
# Mock the simulation core to report tick count
|
|
engine.simulation_core.state.total_ticks = 99
|
|
assert engine._should_terminate() == False
|
|
|
|
engine.simulation_core.state.total_ticks = 100
|
|
assert engine._should_terminate() == True
|
|
|
|
def test_should_terminate_max_duration(self):
|
|
"""Test termination condition for max duration."""
|
|
sim_config = SimulationConfig()
|
|
config = HeadlessConfig(simulation=sim_config, max_duration=1.0)
|
|
|
|
engine = HeadlessSimulationEngine(config)
|
|
engine.running = True
|
|
engine.start_time = time.time()
|
|
|
|
# Should not terminate immediately
|
|
assert engine._should_terminate() == False
|
|
|
|
# Mock time passage
|
|
with patch('time.time', return_value=engine.start_time + 1.5):
|
|
assert engine._should_terminate() == True
|
|
|
|
def test_should_terminate_no_limits(self):
|
|
"""Test no termination conditions."""
|
|
sim_config = SimulationConfig()
|
|
config = HeadlessConfig(simulation=sim_config)
|
|
|
|
engine = HeadlessSimulationEngine(config)
|
|
engine.running = True
|
|
engine.start_time = time.time()
|
|
|
|
# Should never terminate without limits
|
|
assert engine._should_terminate() == False
|
|
|
|
def test_collect_data(self):
|
|
"""Test data collection from collectors."""
|
|
sim_config = SimulationConfig()
|
|
config = HeadlessConfig(
|
|
simulation=sim_config,
|
|
enable_metrics=True,
|
|
enable_entities=False,
|
|
enable_evolution=False
|
|
)
|
|
|
|
engine = HeadlessSimulationEngine(config)
|
|
|
|
# Mock simulation core's get_world_state method
|
|
engine.simulation_core.get_world_state = Mock(return_value={
|
|
'tick_count': 1000,
|
|
'actual_tps': 60.0,
|
|
'entity_counts': {'total': 25}
|
|
})
|
|
|
|
# Mock collector
|
|
mock_collector = Mock()
|
|
mock_collector.update.return_value = [
|
|
{'tick_count': 1000, 'actual_tps': 60.0, 'collection_type': 'metrics'}
|
|
]
|
|
engine.collectors['metrics'] = mock_collector
|
|
|
|
engine._collect_data()
|
|
|
|
# Verify collector was called
|
|
mock_collector.update.assert_called_once()
|
|
|
|
# Verify data was collected
|
|
assert len(engine.batch_data['metrics']) == 1
|
|
assert engine.batch_data['metrics'][0]['tick_count'] == 1000
|
|
|
|
def test_get_real_time_status(self):
|
|
"""Test real-time status reporting."""
|
|
sim_config = SimulationConfig()
|
|
config = HeadlessConfig(simulation=sim_config)
|
|
|
|
engine = HeadlessSimulationEngine(config)
|
|
engine.running = True
|
|
engine.start_time = time.time() - 5.0
|
|
|
|
# Mock simulation state
|
|
engine.simulation_core.state.total_ticks = 300
|
|
engine.simulation_core.state.actual_tps = 60.0
|
|
engine.simulation_core.get_world_state = Mock(return_value={
|
|
'tick_count': 300,
|
|
'actual_tps': 60.0,
|
|
'entity_counts': {'total': 50}
|
|
})
|
|
|
|
status = engine.get_real_time_status()
|
|
|
|
assert status['running'] == True
|
|
assert status['ticks'] == 300
|
|
assert status['tps'] == 60.0
|
|
assert status['duration'] > 4.0 # Approximately 5 seconds
|
|
assert status['world_state']['tick_count'] == 300
|
|
|
|
def test_signal_handler(self):
|
|
"""Test signal handling for graceful shutdown."""
|
|
sim_config = SimulationConfig()
|
|
config = HeadlessConfig(simulation=sim_config)
|
|
|
|
engine = HeadlessSimulationEngine(config)
|
|
engine.running = True
|
|
|
|
# Simulate signal handler
|
|
engine._signal_handler(2, None) # SIGINT
|
|
|
|
assert engine.running == False |