import pytest import time from nucon import Nucon, PumpStatus, PumpDryStatus, PumpOverloadStatus, BreakerStatus from nucon.sim import NuconSimulator, OperatingState @pytest.fixture(scope="module") def simulator_setup(): simulator = NuconSimulator(port=8786) simulator.run() time.sleep(1) # Give the simulator time to start nucon = Nucon(port=8786) return simulator, nucon def test_simulator_initialization(simulator_setup): simulator, nucon = simulator_setup assert simulator is not None assert nucon is not None def test_read_all_parameters(simulator_setup): _, nucon = simulator_setup all_params = nucon.get_all() assert len(all_params) == len(nucon) for param_id, value in all_params.items(): param = nucon[param_id] assert isinstance(value, param.param_type), f"Parameter {param.id} has incorrect type. Expected {param.param_type}, got {type(value)}" def test_write_writable_parameters(simulator_setup): _, nucon = simulator_setup writable_params = nucon.get_all_writable() for param in writable_params.values(): current_value = param.value if param.param_type == float: new_value = current_value + 1.0 elif param.param_type == int: new_value = current_value + 1 elif param.param_type == bool: new_value = not current_value elif issubclass(param.param_type, Enum): new_value = list(param.param_type)[0] else: continue # Skip if we can't determine a new value param.value = new_value assert param.value == new_value, f"Failed to write to parameter {param.id}" def test_non_writable_parameters(simulator_setup): _, nucon = simulator_setup non_writable_params = [param for param in nucon.get_all_readable().values() if not param.is_writable] for param in non_writable_params: with pytest.raises(ValueError, match=f"Parameter {param.id} is not writable"): param.value = param.value # Attempt to write the current value def test_enum_parameters(simulator_setup): _, nucon = simulator_setup pump_status = nucon.COOLANT_CORE_CIRCULATION_PUMP_0_STATUS.value assert isinstance(pump_status, PumpStatus) dry_status = nucon.COOLANT_CORE_CIRCULATION_PUMP_0_DRY_STATUS.value assert isinstance(dry_status, PumpDryStatus) overload_status = nucon.COOLANT_CORE_CIRCULATION_PUMP_0_OVERLOAD_STATUS.value assert isinstance(overload_status, PumpOverloadStatus) breaker_status = nucon.GENERATOR_0_BREAKER.value assert isinstance(breaker_status, BreakerStatus) def test_custom_truthy_values(simulator_setup): _, nucon = simulator_setup assert bool(nucon.COOLANT_CORE_CIRCULATION_PUMP_0_STATUS.value) == (nucon.COOLANT_CORE_CIRCULATION_PUMP_0_STATUS.value in [PumpStatus.ACTIVE_NO_SPEED_REACHED, PumpStatus.ACTIVE_SPEED_REACHED]) assert bool(nucon.COOLANT_CORE_CIRCULATION_PUMP_0_DRY_STATUS.value) == (nucon.COOLANT_CORE_CIRCULATION_PUMP_0_DRY_STATUS.value == PumpDryStatus.INACTIVE_OR_ACTIVE_WITH_FLUID) assert bool(nucon.COOLANT_CORE_CIRCULATION_PUMP_0_OVERLOAD_STATUS.value) == (nucon.COOLANT_CORE_CIRCULATION_PUMP_0_OVERLOAD_STATUS.value == PumpOverloadStatus.INACTIVE_OR_ACTIVE_NO_OVERLOAD) assert bool(nucon.GENERATOR_0_BREAKER.value) == (nucon.GENERATOR_0_BREAKER.value == BreakerStatus.OPEN) def test_get_multiple_parameters(simulator_setup): _, nucon = simulator_setup params_to_get = [nucon.CORE_TEMP, nucon.CORE_PRESSURE, nucon.RODS_POS_ACTUAL] multiple_params = nucon.get_multiple(params_to_get) assert len(multiple_params) == len(params_to_get) for param_id, value in multiple_params.items(): assert isinstance(value, nucon[param_id].param_type) def test_simulator_update(simulator_setup): simulator, nucon = simulator_setup initial_temp = nucon.CORE_TEMP.value simulator.update(10) # Update for 10 seconds new_temp = nucon.CORE_TEMP.value assert new_temp != initial_temp, "Core temperature should change after update" def test_set_operating_state(simulator_setup): simulator, nucon = simulator_setup simulator._set_state(OperatingState.NOMINAL) time.sleep(1) # Give the simulator time to update assert nucon.CORE_STATE.value == 'NOMINAL' assert 290 <= nucon.CORE_TEMP.value <= 370 def test_allow_all_writes(simulator_setup): simulator, nucon = simulator_setup simulator.set_allow_all_writes(True) non_writable_param = next(param for param in nucon.get_all_readable().values() if not param.is_writable) current_value = non_writable_param.value new_value = current_value + 1 if isinstance(current_value, (int, float)) else not current_value non_writable_param.value = new_value assert non_writable_param.value == new_value, f"Failed to write to non-writable parameter {non_writable_param.id} when allow_all_writes is True" def test_simulator_consistency(simulator_setup): simulator, nucon = simulator_setup for _ in range(10): simulator.update(1) all_params = nucon.get_all() for param_id, value in all_params.items(): assert value == getattr(simulator.parameters, param_id), f"Inconsistency found for parameter {param_id}" if __name__ == "__main__": pytest.main()