def setUp(self): rospy_patcher = patch('hbp_nrp_cleserver.server.ROSNotificator.rospy') self.__mocked_rospy = rospy_patcher.start() self.__ros_notificator = ROSNotificator() # Be sure we create as many publishers as required. from hbp_nrp_cleserver.server import * number_of_publishers = 0 for var_name in vars().keys(): if (var_name.startswith("TOPIC_")): number_of_publishers += 1 # Lifecycle topic not published by ROSNotificator number_of_publishers -= 1 self.assertEqual(number_of_publishers, self.__mocked_rospy.Publisher.call_count) # Assure that also the publish method of the rospy.Publisher is # injected as a mock here so that we can use it later in our single # test methods self.__mocked_pub = ROSNotificator.rospy.Publisher() self.__mocked_pub.publish = MagicMock() self.__mocked_rospy.Publisher.return_value = self.__mocked_pub
def initialize(self, environment, except_hook): """ Initializes the simulation :param environment: The environment that should be simulated :param except_hook: A method that should be called when there is a critical error """ # Change working directory to experiment directory logger.info("Path is " + self.__exc.path) os.chdir(self.__exc.dir) # Create backend->frontend/client ROS notificator logger.info("Setting up backend Notificator") self.ros_notificator = ROSNotificator() Notificator.register_notification_function( lambda subtask, update_progress: self.ros_notificator.update_task( subtask, update_progress, True)) # Number of subtasks is not used in frontend notificator logic self.ros_notificator.start_task("Neurorobotics Platform", "Neurorobotics Platform", number_of_subtasks=1, block_ui=True) self._notify("Starting Neurorobotics Platform") self._initialize(environment, except_hook) # Loading is completed. self._notify("Finished") self.ros_notificator.finish_task() logger.info("CLELauncher Finished.")
def initialize(self, except_hook): """ Initializes the simulation :param environment: The environment that should be simulated :param except_hook: A method that should be called when there is a critical error """ # Change working directory to experiment directory logger.info("Path is " + self._sim_config.sim_dir) os.chdir(self._sim_config.sim_dir) # RNG seed for components, use config value if specified or generate a new one self.rng_seed = self.sim_config.rng_seed if self.rng_seed is None: logger.info( 'No RNG seed specified in the exc, using random value.') self.rng_seed = random.randint(1, sys.maxint) logger.info('RNG seed = %i', self.rng_seed) # Create backend->frontend/client ROS notificator logger.info("Setting up backend Notificator") self.ros_notificator = ROSNotificator() Notificator.register_notification_function( lambda subtask, update_progress: self.ros_notificator.update_task( subtask, update_progress, True)) # Number of subtasks is not used in frontend notificator logic self.ros_notificator.start_task("Neurorobotics Platform", "Neurorobotics Platform", number_of_subtasks=1, block_ui=True) self._notify("Starting Neurorobotics Platform") self._initialize(except_hook) # Loading is completed. self._notify("Finished") self.ros_notificator.finish_task() logger.info("CLELauncher Finished.")
def test_shutdown(self): tmp = ROSNotificator() mock_unregister = Mock() tmp._ROSNotificator__ros_status_pub.unregister = mock_unregister tmp._ROSNotificator__ros_cle_error_pub.unregister = mock_unregister mock_publish = Mock() tmp._ROSNotificator__ros_status_pub.publish = mock_publish tmp._ROSNotificator__ros_cle_error_pub.publish = mock_publish # shutdown should unregister the publishers tmp.shutdown() self.assertEquals(mock_unregister.call_count, 2) self.assertEquals(tmp._ROSNotificator__ros_status_pub, None) self.assertEquals(tmp._ROSNotificator__ros_cle_error_pub, None) # publish methods should fail now tmp.publish_state('foo') tmp.publish_error('bar') self.assertEquals(mock_publish.call_count, 0)
class SimulationAssembly(object): """ This class is the abstract base class of a simulation assembly """ def __init__(self, sim_id, exc, bibi, par): """ Creates a new simulation assembly :param sim_id: The simulation ID :param exc: The experiment configuration :param bibi: The BIBI configuration :param token: the request token in case we want to use the storage :param ctx_id: the ctx_id of collab based simulations """ self.__sim_id = sim_id self.__exc = exc self.__bibi = bibi self.__token = par.get('token') self.__ctx_id = par.get('ctx_id') self._abort_initialization = None self.ros_notificator = None @property def bibi(self): """ Gets the BIBI configuration for this simulation assembly """ return self.__bibi @property def exc(self): """ Gets the experiment configuration for this simulation assembly """ return self.__exc @property def token(self): """ Returns the token assigned to this simulation """ return self.__token @property def ctx_id(self): """ Returns the context id assigned to this simulation """ return self.__ctx_id @property def sim_id(self): """ Gets the simulation id """ return self.__sim_id def initialize(self, environment, except_hook): """ Initializes the simulation :param environment: The environment that should be simulated :param except_hook: A method that should be called when there is a critical error """ # Change working directory to experiment directory logger.info("Path is " + self.__exc.path) os.chdir(self.__exc.dir) # Create backend->frontend/client ROS notificator logger.info("Setting up backend Notificator") self.ros_notificator = ROSNotificator() Notificator.register_notification_function( lambda subtask, update_progress: self.ros_notificator.update_task( subtask, update_progress, True)) # Number of subtasks is not used in frontend notificator logic self.ros_notificator.start_task("Neurorobotics Platform", "Neurorobotics Platform", number_of_subtasks=1, block_ui=True) self._notify("Starting Neurorobotics Platform") self._initialize(environment, except_hook) # Loading is completed. self._notify("Finished") self.ros_notificator.finish_task() logger.info("CLELauncher Finished.") def _initialize(self, environment, except_hook): # pragma: no cover """ Internally initialize the simulation :param environment: The environment that should be simulated :param except_hook: A method that should be called when there is a critical error """ raise NotImplementedError( "This method must be overridden in an implementation") def _notify(self, message): """ Checks whether the simulation should abort immediately """ if self._abort_initialization is not None: raise Exception("The simulation must abort due to: " + self._abort_initialization) Notificator.notify(message, True) def run(self): # pragma: no cover """ Runs the simulation """ raise NotImplementedError( "This method must be overridden in an implementation") def shutdown(self): # pragma: no cover """ Shuts down the simulation """ raise NotImplementedError( "This method must be overridden in an implementation")
class SimulationAssembly(object): """ This class is the abstract base class of a simulation assembly """ def __init__(self, sim_config): """ Creates a new simulation assembly :param sim_config: Simulation configuration """ self._sim_config = sim_config self._abort_initialization = None self.ros_notificator = None self.rng_seed = None @property def sim_config(self): """ Gets the sim_config """ return self._sim_config @sim_config.setter def sim_config(self, sim_config): """ Restrict external assignment of sim_config :raises AttributeError if the setter is called """ # pylint: disable=no-self-use logger.info( "Raising exception instead of assigning {} to sim_config".format( sim_config)) raise AttributeError( "sim_config has to be initialized on Assembly instantiation") # TODO: remove @property def simdir(self): """ Gets the simulation directory """ return self._sim_config.sim_dir @property def sim_dir(self): """ Gets the simulation directory """ return self._sim_config.sim_dir def initialize(self, except_hook): """ Initializes the simulation :param environment: The environment that should be simulated :param except_hook: A method that should be called when there is a critical error """ # Change working directory to experiment directory logger.info("Path is " + self._sim_config.sim_dir) os.chdir(self._sim_config.sim_dir) # RNG seed for components, use config value if specified or generate a new one self.rng_seed = self.sim_config.rng_seed if self.rng_seed is None: logger.info( 'No RNG seed specified in the exc, using random value.') self.rng_seed = random.randint(1, sys.maxint) logger.info('RNG seed = %i', self.rng_seed) # Create backend->frontend/client ROS notificator logger.info("Setting up backend Notificator") self.ros_notificator = ROSNotificator() Notificator.register_notification_function( lambda subtask, update_progress: self.ros_notificator.update_task( subtask, update_progress, True)) # Number of subtasks is not used in frontend notificator logic self.ros_notificator.start_task("Neurorobotics Platform", "Neurorobotics Platform", number_of_subtasks=1, block_ui=True) self._notify("Starting Neurorobotics Platform") self._initialize(except_hook) # Loading is completed. self._notify("Finished") self.ros_notificator.finish_task() logger.info("CLELauncher Finished.") def _initialize(self, except_hook): # pragma: no cover """ Internally initialize the simulation :param environment: The environment that should be simulated :param except_hook: A method that should be called when there is a critical error """ raise NotImplementedError( "This method must be overridden in an implementation") def _notify(self, message): """ Checks whether the simulation should abort immediately """ if self._abort_initialization is not None: raise Exception("The simulation must abort due to: " + self._abort_initialization) Notificator.notify(message, True) def run(self): # pragma: no cover """ Runs the simulation """ raise NotImplementedError( "This method must be overridden in an implementation") def shutdown(self): # pragma: no cover """ Shuts down the simulation """ raise NotImplementedError( "This method must be overridden in an implementation")
class TestROSNotificator(unittest.TestCase): def setUp(self): rospy_patcher = patch('hbp_nrp_cleserver.server.ROSNotificator.rospy') self.__mocked_rospy = rospy_patcher.start() self.__ros_notificator = ROSNotificator() # Be sure we create as many publishers as required. from hbp_nrp_cleserver.server import * number_of_publishers = 0 for var_name in vars().keys(): if (var_name.startswith("TOPIC_")): number_of_publishers += 1 # Lifecycle topic not published by ROSNotificator number_of_publishers -= 1 self.assertEqual(number_of_publishers, self.__mocked_rospy.Publisher.call_count) # Assure that also the publish method of the rospy.Publisher is # injected as a mock here so that we can use it later in our single # test methods self.__mocked_pub = ROSNotificator.rospy.Publisher() self.__mocked_pub.publish = MagicMock() self.__mocked_rospy.Publisher.return_value = self.__mocked_pub def test_ros_node_initialized(self): self.__mocked_rospy.init_node.assert_called_with('ros_cle_simulation', anonymous=True) def test_shutdown(self): tmp = ROSNotificator() mock_unregister = Mock() tmp._ROSNotificator__ros_status_pub.unregister = mock_unregister tmp._ROSNotificator__ros_cle_error_pub.unregister = mock_unregister mock_publish = Mock() tmp._ROSNotificator__ros_status_pub.publish = mock_publish tmp._ROSNotificator__ros_cle_error_pub.publish = mock_publish # shutdown should unregister the publishers tmp.shutdown() self.assertEquals(mock_unregister.call_count, 2) self.assertEquals(tmp._ROSNotificator__ros_status_pub, None) self.assertEquals(tmp._ROSNotificator__ros_cle_error_pub, None) # publish methods should fail now tmp.publish_state('foo') tmp.publish_error('bar') self.assertEquals(mock_publish.call_count, 0) def test_publish(self): self.__mocked_pub.reset_mock() self.__ros_notificator.publish_state('foo') self.__mocked_pub.publish.assert_called_once_with('foo') self.__mocked_pub.reset_mock() self.__ros_notificator.publish_error('bar') self.__mocked_pub.publish.assert_called_once_with('bar') def test_task(self): mock_publisher = Mock() self.__ros_notificator._ROSNotificator__ros_status_pub = mock_publisher self.__ros_notificator.start_task('task', 'subtask', 1, False) self.assertEquals(mock_publisher.publish.call_count, 1) self.__ros_notificator.update_task('new_subtask', True, False) self.assertEquals(mock_publisher.publish.call_count, 2) self.__ros_notificator.finish_task() self.assertEquals(mock_publisher.publish.call_count, 3) def test_start_task(self): self.__mocked_pub.reset_mock() task_name = 'test_name' subtask_name = 'test_subtaskname' number_of_subtasks = 1 block_ui = False self.__ros_notificator.start_task(task_name, subtask_name, number_of_subtasks, block_ui) self.assertEqual(1, self.__mocked_pub.publish.call_count) message = { 'progress': { 'task': task_name, 'subtask': subtask_name, 'number_of_subtasks': number_of_subtasks, 'subtask_index': 0, 'block_ui': block_ui } } self.__mocked_pub.publish.assert_called_with(json.dumps(message)) with patch.object(self.__ros_notificator, 'finish_task') as mock_finish: self.__ros_notificator.start_task(task_name, subtask_name, number_of_subtasks, block_ui) mock_finish.assert_called_once() @log_capture(level=logging.WARNING) def test_current_task_no_task(self, logcapture): self.__ros_notificator.update_task("new_subtask", True, True) logcapture.check(('hbp_nrp_cleserver.server.ROSNotificator', 'WARNING', "Can't update a non existing task.")) @log_capture(level=logging.WARNING) def test_finish_task_no_task(self, logcapture): self.__ros_notificator.finish_task() logcapture.check(('hbp_nrp_cleserver.server.ROSNotificator', 'WARNING', "Can't finish a non existing task.")) def test_task_notifier(self): with patch.object(self.__ros_notificator, 'start_task') as mock_start,\ patch.object(self.__ros_notificator, 'finish_task') as mock_finish: with self.__ros_notificator.task_notifier('foo', 'bar') as tn: mock_start.assert_called_once_with('foo', 'bar', number_of_subtasks=0, block_ui=True) mock_finish.assert_called_once()