def generate_launch_description(): share_dir = get_package_share_directory('serial_driver') node_name = 'serial_bridge_node' params_declare = DeclareLaunchArgument( 'params_file', default_value=os.path.join(share_dir, 'params', 'example.params.yaml'), description='File path to the ROS2 parameters file to use') bridge_node = LifecycleNode( package='serial_driver', executable='serial_bridge', name=node_name, namespace=TextSubstitution(text=''), parameters=[LaunchConfiguration('params_file')], output='screen', ) configure_event_handler = RegisterEventHandler( event_handler=OnProcessStart( target_action=bridge_node, on_start=[ EmitEvent(event=ChangeState( lifecycle_node_matcher=matches_action(bridge_node), transition_id=Transition.TRANSITION_CONFIGURE, ), ), ], )) activate_event_handler = RegisterEventHandler( event_handler=OnStateTransition( target_lifecycle_node=bridge_node, start_state='configuring', goal_state='inactive', entities=[ EmitEvent(event=ChangeState( lifecycle_node_matcher=matches_action(bridge_node), transition_id=Transition.TRANSITION_ACTIVATE, ), ), ], )) shutdown_event_handler = RegisterEventHandler(event_handler=OnShutdown( on_shutdown=[ EmitEvent(event=ChangeState( lifecycle_node_matcher=matches_node_name(node_name), transition_id=Transition.TRANSITION_ACTIVE_SHUTDOWN, )) ])) return LaunchDescription([ params_declare, bridge_node, configure_event_handler, activate_event_handler, shutdown_event_handler, ])
def __init__( self, target_action, log_file, timeout=None, **kwargs ) -> None: """ Construct a SystemMetricCollector action. Parameters ---------- target_action : ExecuteProcess ExecuteProcess (or Node) instance to collect metrics on log_file : str or LaunchSubstitutionsType Path to where the collected metrics should be written to timeout : int or LaunchSubstitutionsType Maximum time to run the metrics collector if the target process does not exit """ # These Node/ExecuteProcess arguments are invalid in this context # because we implicitly set them right here. assert 'arguments' not in kwargs assert 'package' not in kwargs assert 'executable' not in kwargs assert 'executable' not in kwargs self.__pid_var_name = '__PROCESS_ID_%d' % id(self) kwargs['package'] = 'buildfarm_perf_tests' kwargs['executable'] = 'system_metric_collector' kwargs['arguments'] = [ '--log', log_file, '--process_pid', LocalSubstitution(self.__pid_var_name)] if timeout is not None: kwargs['arguments'] += [ '--timeout', str(timeout) if isinstance(timeout, int) else timeout ] super().__init__(**kwargs) self.__target_start_handler = OnProcessStart( target_action=target_action, on_start=self.__on_target_start) self.__target_exit_handler = OnProcessExit( target_action=target_action, on_exit=EmitEvent( event=ShutdownProcess( process_matcher=matches_action(self))))
def setUpClass(cls): # It's easier to actually capture some IO from the launch system than it is to fake it # but it takes a few seconds. We'll do it once and run tests on the same captured # IO proc_env = os.environ.copy() proc_env['PYTHONUNBUFFERED'] = '1' cls.proc_output = ActiveIoHandler() cls.proc_1 = launch.actions.ExecuteProcess(cmd=TEST_CMD, name='terminating_proc', env=proc_env) # This process should be distinguishable by its cmd line args cls.proc_2 = launch.actions.ExecuteProcess(cmd=TEST_CMD + ['--extra'], name='terminating_proc', env=proc_env) # This process should be distinguishable by its different name cls.proc_3 = launch.actions.ExecuteProcess(cmd=TEST_CMD + ['node:=different_name'], name='terminating_proc', env=proc_env) launch_description = launch.LaunchDescription([ cls.proc_1, cls.proc_2, cls.proc_3, # This plumbs all the output to our IoHandler just like the LaunchTestRunner does RegisterEventHandler( OnProcessStart(on_start=lambda event, _: cls.proc_output.track( event.process_name))), RegisterEventHandler( OnProcessIO( on_stdout=cls.proc_output.append, on_stderr=cls.proc_output.append, )) ]) launch_service = launch.LaunchService() launch_service.include_launch_description(launch_description) launch_service.run()
def run(self): """ Launch the processes under test and run the tests. :return: A tuple of two unittest.Results - one for tests that ran while processes were active, and another set for tests that ran after processes were shutdown """ test_ld, test_context = self._test_run.normalized_test_description( ready_fn=lambda: self._processes_launched.set()) # Data that needs to be bound to the tests: proc_info = ActiveProcInfoHandler() proc_output = ActiveIoHandler() full_context = dict(test_context, **self._test_run.param_args) parsed_launch_arguments = parse_launch_arguments( self._launch_file_arguments) test_args = {} for k, v in parsed_launch_arguments: test_args[k] = v self._test_run.bind( self._test_run.pre_shutdown_tests, injected_attributes={ 'proc_info': proc_info, 'proc_output': proc_output, 'test_args': test_args, }, injected_args=dict( full_context, # Add a few more things to the args dictionary: **{ 'proc_info': proc_info, 'proc_output': proc_output, 'test_args': test_args })) self._test_run.bind( self._test_run.post_shutdown_tests, injected_attributes={ 'proc_info': proc_info._proc_info_handler, 'proc_output': proc_output._io_handler, 'test_args': test_args, }, injected_args=dict( full_context, # Add a few more things to the args dictionary: **{ 'proc_info': proc_info._proc_info_handler, 'proc_output': proc_output._io_handler, 'test_args': test_args })) # Wrap the test_ld in another launch description so we can bind command line arguments to # the test and add our own event handlers for process IO and process exit: launch_description = LaunchDescription([ *self._test_run_preamble, RegisterEventHandler( OnProcessStart( on_start=lambda info, unused: proc_info.append(info))), RegisterEventHandler( OnProcessExit( on_exit=lambda info, unused: proc_info.append(info))), RegisterEventHandler( OnProcessIO( on_stdout=proc_output.append, on_stderr=proc_output.append, )), launch.actions.IncludeLaunchDescription( launch.LaunchDescriptionSource(launch_description=test_ld), launch_arguments=parsed_launch_arguments), ]) self._launch_service.include_launch_description(launch_description) self._test_tr.start() # Run the tests on another thread self._launch_service.run( ) # This will block until the test thread stops it if not self._tests_completed.wait(timeout=0): # LaunchService.run returned before the tests completed. This can be because the user # did ctrl+c, or because all of the launched nodes died before the tests completed print('Processes under test stopped before tests completed') # Give some extra help debugging why processes died early self._print_process_output_summary(proc_info, proc_output) # We treat this as a test failure and return some test results indicating such raise _LaunchDiedException() inactive_results = unittest.TextTestRunner( verbosity=2, resultclass=TestResult).run(self._test_run.post_shutdown_tests) self._results.append(inactive_results) return self._results
def generate_launch_description(): params_file = LaunchConfiguration( 'params', default=[ThisLaunchFileDir(), '/launch_params.yaml']) # make sure the dbc file gets installed with the launch file # dbc_file_path = get_package_share_directory('raptor_dbw_can') + \ # "/launch/New_Eagle_DBW_3.3.542.dbc" dbc_file_path = get_package_share_directory('raptor_dbw_can') + \ "/launch/CAN1_HIL_test_1.dbc" socket_can_receiver_node = LifecycleNode( package='ros2_socketcan', executable='socket_can_receiver_node_exe', name='socket_can_receiver', namespace=TextSubstitution(text=''), parameters=[{ 'interface': LaunchConfiguration('interface'), 'interval_sec': LaunchConfiguration('interval_sec'), }], output='screen') socket_can_receiver_configure_event_handler = RegisterEventHandler( event_handler=OnProcessStart( target_action=socket_can_receiver_node, on_start=[ EmitEvent( event=ChangeState( lifecycle_node_matcher=matches_action(socket_can_receiver_node), transition_id=Transition.TRANSITION_CONFIGURE, ), ), ], ), condition=IfCondition(LaunchConfiguration('auto_configure')), ) socket_can_receiver_activate_event_handler = RegisterEventHandler( event_handler=OnStateTransition( target_lifecycle_node=socket_can_receiver_node, start_state='configuring', goal_state='inactive', entities=[ EmitEvent( event=ChangeState( lifecycle_node_matcher=matches_action(socket_can_receiver_node), transition_id=Transition.TRANSITION_ACTIVATE, ), ), ], ), condition=IfCondition(LaunchConfiguration('auto_activate')), ) socket_can_sender_node = LifecycleNode( package='ros2_socketcan', executable='socket_can_sender_node_exe', name='socket_can_sender', namespace=TextSubstitution(text=''), parameters=[{ 'interface': LaunchConfiguration('interface'), 'timeout_sec': LaunchConfiguration('timeout_sec'), }], output='screen') socket_can_sender_configure_event_handler = RegisterEventHandler( event_handler=OnProcessStart( target_action=socket_can_sender_node, on_start=[ EmitEvent( event=ChangeState( lifecycle_node_matcher=matches_action(socket_can_sender_node), transition_id=Transition.TRANSITION_CONFIGURE, ), ), ], ), condition=IfCondition(LaunchConfiguration('auto_configure')), ) socket_can_sender_activate_event_handler = RegisterEventHandler( event_handler=OnStateTransition( target_lifecycle_node=socket_can_sender_node, start_state='configuring', goal_state='inactive', entities=[ EmitEvent( event=ChangeState( lifecycle_node_matcher=matches_action(socket_can_sender_node), transition_id=Transition.TRANSITION_ACTIVATE, ), ), ], ), condition=IfCondition(LaunchConfiguration('auto_activate')), ) return LaunchDescription( [ DeclareLaunchArgument('interface', default_value='can1'), DeclareLaunchArgument('interval_sec', default_value='0.01'), DeclareLaunchArgument('auto_configure', default_value='true'), DeclareLaunchArgument('auto_activate', default_value='true'), socket_can_receiver_node, socket_can_receiver_configure_event_handler, socket_can_receiver_activate_event_handler, DeclareLaunchArgument('interface', default_value='can1'), DeclareLaunchArgument('timeout_sec', default_value='0.01'), DeclareLaunchArgument('auto_configure', default_value='true'), DeclareLaunchArgument('auto_activate', default_value='true'), socket_can_sender_node, socket_can_sender_configure_event_handler, socket_can_sender_activate_event_handler, Node( package='raptor_dbw_can', executable='raptor_dbw_can_node', output='screen', namespace='raptor_dbw_interface', parameters=[ {"dbw_dbc_file": dbc_file_path} ], remappings=[ ('/raptor_dbw_interface/can_rx', '/from_can_bus'), ('/raptor_dbw_interface/can_tx', '/to_can_bus'), ], ), ])