def test_properties(): """Tests that ProxySimulatorControls implements properties""" mock_sim_controls = mock.create_autospec(spec=AbstractSimulatorControls) mock_aircraft_controls = mock.create_autospec(spec=ProxyAircraftControls) properties_mock = mock.PropertyMock() properties_mock.return_value = _TEST_SIM_PROPERTIES type(mock_sim_controls).properties = properties_mock # Test call to _sim_controls.properties when not in agent mode proxy_simulator_controls = ProxySimulatorControls(mock_sim_controls, mock_aircraft_controls) props = proxy_simulator_controls.properties assert isinstance(props, SimProperties) assert props == _TEST_SIM_PROPERTIES properties_mock.assert_called_once() # Test call to _sim_controls.properties when in agent mode properties_mock.reset_mock() proxy_simulator_controls = ProxySimulatorControls(mock_sim_controls, mock_aircraft_controls) props = proxy_simulator_controls.properties assert isinstance(props, SimProperties) assert props == _TEST_SIM_PROPERTIES properties_mock.assert_called_once()
def __init__( self, sim_client: AbstractSimClient, metrics_providers: MetricsProviders ): self._logger = logging.getLogger(__name__) # The actual sim_client self._sim_client: AbstractSimClient = sim_client # The proxy implementations self._proxy_aircraft_controls = ProxyAircraftControls(self._sim_client.aircraft) self._proxy_simulator_controls = ProxySimulatorControls( self._sim_client.simulation, self._proxy_aircraft_controls ) self.metrics_providers = metrics_providers
def test_step(): """Tests that ProxySimulatorControls implements step""" mock_sim_controls = mock.Mock() mock_aircraft_controls = mock.Mock() proxy_simulator_controls = ProxySimulatorControls(mock_sim_controls, mock_aircraft_controls) # Test error message when no sector set res = proxy_simulator_controls.step() assert res == "No scenario set" # Test error handling from step proxy_simulator_controls._scenario = "test" mock_sim_controls.step = mock.Mock(return_value="Error") res = proxy_simulator_controls.step() assert res == "Error" # Test valid response mock_sim_controls.properties = _TEST_SIM_PROPERTIES mock_sim_controls.step = mock.Mock(sepc=AbstractSimulatorControls.step, return_value=None) _mock_logger = mock.Mock(spec=logging.Logger) proxy_simulator_controls._logger = _mock_logger res = proxy_simulator_controls.step() assert not res
def test_stop(): """Tests that ProxySimulatorControls implements stop""" mock_sim_controls = mock.create_autospec(spec=AbstractSimulatorControls) mock_aircraft_controls = mock.create_autospec(spec=ProxyAircraftControls) proxy_simulator_controls = ProxySimulatorControls(mock_sim_controls, mock_aircraft_controls) # Test error handling from stop mock_sim_controls.stop = mock.Mock(sepc=AbstractSimulatorControls.stop, return_value="Error") res = proxy_simulator_controls.stop() assert res == "Error" # Test valid response mock_sim_controls.stop = mock.Mock(sepc=AbstractSimulatorControls.stop, return_value=None) res = proxy_simulator_controls.stop() assert not res
def test_set_speed(): """Tests that ProxySimulatorControls implements set_speed""" mock_sim_controls = mock.create_autospec(spec=AbstractSimulatorControls) mock_aircraft_controls = mock.create_autospec(spec=ProxyAircraftControls) proxy_simulator_controls = ProxySimulatorControls(mock_sim_controls, mock_aircraft_controls) # Test error handling from set_speed mock_sim_controls.set_speed = mock.Mock( sepc=AbstractSimulatorControls.set_speed, return_value="Error") res = proxy_simulator_controls.set_speed(1.0) assert res == "Error" # Test set_speed mock_sim_controls.properties = _TEST_SIM_PROPERTIES mock_sim_controls.set_speed = mock.Mock( sepc=AbstractSimulatorControls.set_speed, return_value=None) res = proxy_simulator_controls.set_speed(1.0) assert not res mock_sim_controls.set_speed.assert_called_once_with(1.0)
def test_load_scenario(tmpdir): data_dir = Path(tmpdir) Settings.DATA_DIR = data_dir mock_sim_controls = mock.Mock() mock_aircraft_controls = mock.Mock() proxy_simulator_controls = ProxySimulatorControls(mock_sim_controls, mock_aircraft_controls) # Test error when no sector set res = proxy_simulator_controls.load_scenario(_TEST_SCENARIO) assert res == "No sector set" # First test uploading a new scenario # Test error handling from reset mock_sim_controls.reset.return_value = "Sim error (reset)" err = proxy_simulator_controls.load_sector(_TEST_SECTOR) assert err == "Sim error (reset)" # Test error handling from load_scenario proxy_simulator_controls.sector = _TEST_SECTOR mock_sim_controls.reset.return_value = None mock_sim_controls.load_scenario.return_value = "Sim error (load_scenario)" err = proxy_simulator_controls.load_scenario(_TEST_SCENARIO) assert err == "Sim error (load_scenario)" # Test valid response mock_sim_controls.load_scenario.return_value = None err = proxy_simulator_controls.load_scenario(_TEST_SCENARIO) assert not err # Assert scenario saved to file with open(data_dir / "scenarios" / f"{_TEST_SCENARIO.name}.json") as f: assert json.load(f) == _TEST_SCENARIO.content # Test load of existing scenario by name existing_scn = Scenario(_TEST_SCENARIO.name, None) err = proxy_simulator_controls.load_scenario(existing_scn) assert not err
def test_reset(): """Tests that ProxySimulatorControls implements reset""" mock_sim_controls = mock.create_autospec(spec=AbstractSimulatorControls) mock_aircraft_controls = mock.create_autospec(spec=ProxyAircraftControls) proxy_simulator_controls = ProxySimulatorControls(mock_sim_controls, mock_aircraft_controls) # Test error handling from reset mock_sim_controls.reset = mock.Mock(sepc=AbstractSimulatorControls.reset, return_value="Error") res = proxy_simulator_controls.reset() assert res == "Error" # Test valid response mock_sim_controls.properties = _TEST_SIM_PROPERTIES mock_sim_controls.reset = mock.Mock(sepc=AbstractSimulatorControls.reset, return_value=None) res = proxy_simulator_controls.reset() assert not res
def test_load_sector(tmpdir): data_dir = Path(tmpdir) Settings.DATA_DIR = data_dir mock_sim_controls = mock.Mock() mock_aircraft_controls = mock.Mock() proxy_simulator_controls = ProxySimulatorControls(mock_sim_controls, mock_aircraft_controls) # First test uploading a new sector # Test error handling from reset mock_sim_controls.reset.return_value = "Sim error (reset)" err = proxy_simulator_controls.load_sector(_TEST_SECTOR) assert err == "Sim error (reset)" # Test error handling from load_sector mock_sim_controls.reset.return_value = None mock_sim_controls.load_sector.return_value = "Sim error (load_sector)" err = proxy_simulator_controls.load_sector(_TEST_SECTOR) assert err == "Sim error (load_sector)" # Test valid response mock_sim_controls.load_sector.return_value = None err = proxy_simulator_controls.load_sector(_TEST_SECTOR) assert not err # Assert sector saved to file with open(data_dir / "sectors" / f"{_TEST_SECTOR.name}.geojson") as f: assert geojson.dumps(SectorElement.deserialise(f)) == geojson.dumps( _TEST_SECTOR.element) # Test load of existing sector by name existing_sector = Sector(_TEST_SECTOR.name, None) err = proxy_simulator_controls.load_sector(existing_sector) assert not err
def test_store_data(tmpdir): mock_sim_controls = mock.create_autospec(spec=AbstractSimulatorControls) mock_aircraft_controls = mock.create_autospec(spec=ProxyAircraftControls) proxy_simulator_controls = ProxySimulatorControls(mock_sim_controls, mock_aircraft_controls) # Set the scenario and sector proxy_simulator_controls.sector = _TEST_SECTOR mock_sim_controls.reset.return_value = None mock_sim_controls.load_scenario.return_value = None err = proxy_simulator_controls.load_scenario(_TEST_SCENARIO) assert not err # Assert exceptions are caught Settings.DATA_DIR = "fake" err = proxy_simulator_controls.store_data() assert err.startswith("Error storing data: ") # Assert .last_sector created data_dir = Path(tmpdir) Settings.DATA_DIR = data_dir err = proxy_simulator_controls.store_data() assert not err with open(tmpdir / "sectors" / ".last_sector") as f: assert f.read() == "test-sector\n" # Assert .last_scenario created with open(tmpdir / "scenarios" / ".last_scenario") as f: assert f.read() == "test-scenario\n"
class SimProxy(AbstractSimClient): """ Class which intercepts any requests before forwarding them to the sim client. Allows any actions to be taken which are independent of the particular sim client """ @property def aircraft(self) -> ProxyAircraftControls: return self._proxy_aircraft_controls @property def simulation(self) -> ProxySimulatorControls: return self._proxy_simulator_controls @property def sim_version(self) -> VersionInfo: return self._sim_client.sim_version def __init__( self, sim_client: AbstractSimClient, metrics_providers: MetricsProviders ): self._logger = logging.getLogger(__name__) # The actual sim_client self._sim_client: AbstractSimClient = sim_client # The proxy implementations self._proxy_aircraft_controls = ProxyAircraftControls(self._sim_client.aircraft) self._proxy_simulator_controls = ProxySimulatorControls( self._sim_client.simulation, self._proxy_aircraft_controls ) self.metrics_providers = metrics_providers def connect(self, timeout: int = 1) -> None: self._sim_client.connect(timeout) def start_timers(self) -> List[Timer]: return [ *self._sim_client.start_timers(), *self._proxy_simulator_controls.start_timers(), ] def pre_fetch_data(self): """Called on startup to fetch the initial state""" _ = self._sim_client.aircraft.all_properties _ = self._sim_client.simulation.properties def shutdown(self, shutdown_sim: bool = False) -> bool: """ Shutdown the sim client :param shutdown_sim: If true, and if the simulation server supports it, will also send a shutdown command :return: If shutdown_sim was requested, the return value will indicate whether the simulator was shut down successfully. Always returns True if shutdown_sim was not requested """ err = self._proxy_simulator_controls.store_data() if err: self._logger.error(err) return self._sim_client.shutdown(shutdown_sim) def call_metric_function( self, provider: AbstractMetricsProvider, metric_name: str, args: list ): """Calls the metric specified""" # NOTE(rkm 2020-01-12) We pass the aircraft and simulator control objects to any # metric which is called so that it can have access to any property it needs return provider( metric_name, *args, aircraft_controls=self._proxy_aircraft_controls, simulator_controls=self._proxy_simulator_controls )
def test_abstract_class_implemented(): """Tests that ProxySimulatorControls implements the abstract base class""" ProxySimulatorControls(mock.Mock(), mock.Mock())