def test_missing_command_raises(commands): """Test that a command that doesn't exist raises.""" context = LaunchContext() command = Command('ros2_launch_test_command_i_m_not_a_command') with pytest.raises(SubstitutionFailure) as ex: command.perform(context) ex.match('file not found:')
def test_reset(): xml_file = \ """\ <launch> <let name="foo" value="FOO"/> <let name="bar" value="BAR"/> <reset> <keep name="bar" value="$(var bar)"/> <keep name="baz" value="BAZ"/> </reset> </launch> """ # noqa: E501 xml_file = textwrap.dedent(xml_file) root_entity, parser = Parser.load(io.StringIO(xml_file)) ld = parser.parse_description(root_entity) assert isinstance(ld.entities[0], SetLaunchConfiguration) assert isinstance(ld.entities[1], SetLaunchConfiguration) assert isinstance(ld.entities[2], ResetLaunchConfigurations) lc = LaunchContext() assert len(lc.launch_configurations) == 0 ld.entities[0].visit(lc) ld.entities[1].visit(lc) assert len(lc.launch_configurations) == 2 assert 'foo' in lc.launch_configurations.keys() assert lc.launch_configurations['foo'] == 'FOO' assert 'bar' in lc.launch_configurations.keys() assert lc.launch_configurations['bar'] == 'BAR' ld.entities[2].visit(lc) assert 'foo' not in lc.launch_configurations.keys() assert 'bar' in lc.launch_configurations.keys() assert lc.launch_configurations['bar'] == 'BAR' assert 'baz' in lc.launch_configurations.keys() assert lc.launch_configurations['baz'] == 'BAZ'
def test_group(): yaml_file = \ """\ launch: - let: name: 'foo' value: 'FOO' - let: name: 'bar' value: 'BAR' - group: scoped: True forwarding: False keep: - name: 'bar' value: $(var bar) - name: 'baz' value: 'BAZ' children: - let: name: 'var1' value: 'asd' - let: name: 'var2' value: 'asd' """ # noqa: E501 yaml_file = textwrap.dedent(yaml_file) root_entity, parser = Parser.load(io.StringIO(yaml_file)) ld = parser.parse_description(root_entity) assert isinstance(ld.entities[0], SetLaunchConfiguration) assert isinstance(ld.entities[1], SetLaunchConfiguration) assert isinstance(ld.entities[2], GroupAction) lc = LaunchContext() assert 0 == len(lc.launch_configurations) ld.entities[0].visit(lc) ld.entities[1].visit(lc) assert 2 == len(lc.launch_configurations) assert 'foo' in lc.launch_configurations.keys() assert 'FOO' == lc.launch_configurations['foo'] assert 'bar' in lc.launch_configurations.keys() assert 'BAR' == lc.launch_configurations['bar'] actions = ld.entities[2].execute(lc) assert 5 == len(actions) assert isinstance(actions[0], PushLaunchConfigurations) assert isinstance(actions[1], ResetLaunchConfigurations) assert isinstance(actions[2], SetLaunchConfiguration) assert isinstance(actions[3], SetLaunchConfiguration) assert isinstance(actions[4], PopLaunchConfigurations) actions[0].visit(lc) actions[1].visit(lc) assert 'foo' not in lc.launch_configurations.keys() assert 'bar' in lc.launch_configurations.keys() assert 'BAR' == lc.launch_configurations['bar'] assert 'baz' in lc.launch_configurations.keys() assert 'BAZ' == lc.launch_configurations['baz'] actions[2].visit(lc) actions[3].visit(lc) actions[4].visit(lc)
def test_failing_command_rises(commands): """Test that a failing command raises.""" context = LaunchContext() command = Command(commands['failing']) with pytest.raises(SubstitutionFailure) as ex: command.perform(context) ex.match('executed command failed. Command: .*failing_command')
def generate_launch_description(): map_yaml_file = os.getenv('TEST_MAP') world = os.getenv('TEST_WORLD') bt_navigator_xml = os.path.join(get_package_share_directory('nav2_bt_navigator'), 'behavior_trees', os.getenv('BT_NAVIGATOR_XML')) bringup_dir = get_package_share_directory('nav2_bringup') params_file = os.path.join(bringup_dir, 'params', 'nav2_params.yaml') # Replace the `use_astar` setting on the params file param_substitutions = { 'planner_server.ros__parameters.GridBased.use_astar': 'False'} configured_params = RewrittenYaml( source_file=params_file, root_key='', param_rewrites=param_substitutions, convert_types=True) context = LaunchContext() new_yaml = configured_params.perform(context) return LaunchDescription([ SetEnvironmentVariable('RCUTILS_LOGGING_BUFFERED_STREAM', '1'), SetEnvironmentVariable('RCUTILS_LOGGING_USE_STDOUT', '1'), # Launch gazebo server for simulation ExecuteProcess( cmd=['gzserver', '-s', 'libgazebo_ros_init.so', '--minimal_comms', world], output='screen'), # TODO(orduno) Launch the robot state publisher instead # using a local copy of TB3 urdf file Node( package='tf2_ros', executable='static_transform_publisher', output='screen', arguments=['0', '0', '0', '0', '0', '0', 'base_footprint', 'base_link']), Node( package='tf2_ros', executable='static_transform_publisher', output='screen', arguments=['0', '0', '0', '0', '0', '0', 'base_link', 'base_scan']), IncludeLaunchDescription( PythonLaunchDescriptionSource( os.path.join(bringup_dir, 'launch', 'bringup_launch.py')), launch_arguments={'namespace': '', 'use_namespace': 'False', 'map': map_yaml_file, 'use_sim_time': 'True', 'params_file': new_yaml, 'bt_xml_file': bt_navigator_xml, 'autostart': 'True'}.items()), ])
def test_command_with_stderr_raises(commands): """Test that a command that produces stderr raises.""" context = LaunchContext() command = Command(commands['with_stderr']) with pytest.raises(SubstitutionFailure) as ex: command.perform(context) ex.match( 'executed command showed stderr output. Command: .*command_with_stderr' r'[\w\W]*asd bsd')
def test_passthrough_properties(): name = 'name' cwd = 'cwd' env = {'a': '1'} exe = Executable(cmd=['test'], name=name, cwd=cwd, env=env) exe.prepare(LaunchContext(), None) assert exe.final_name.startswith(name) assert exe.final_cwd == cwd assert exe.final_env == env
def test_group(): xml_file = \ """\ <launch> <let name="foo" value="FOO"/> <let name="bar" value="BAR"/> <group scoped="True" forwarding="False"> <keep name="bar" value="$(var bar)"/> <keep name="baz" value="BAZ"/> <let name="var1" value="asd"/> <let name="var2" value="asd"/> </group> </launch> """ # noqa: E501 xml_file = textwrap.dedent(xml_file) root_entity, parser = Parser.load(io.StringIO(xml_file)) ld = parser.parse_description(root_entity) assert isinstance(ld.entities[0], SetLaunchConfiguration) assert isinstance(ld.entities[1], SetLaunchConfiguration) assert isinstance(ld.entities[2], GroupAction) lc = LaunchContext() assert 0 == len(lc.launch_configurations) ld.entities[0].visit(lc) ld.entities[1].visit(lc) assert 2 == len(lc.launch_configurations) assert 'foo' in lc.launch_configurations.keys() assert 'FOO' == lc.launch_configurations['foo'] assert 'bar' in lc.launch_configurations.keys() assert 'BAR' == lc.launch_configurations['bar'] actions = ld.entities[2].execute(lc) assert 5 == len(actions) assert isinstance(actions[0], PushLaunchConfigurations) assert isinstance(actions[1], ResetLaunchConfigurations) assert isinstance(actions[2], SetLaunchConfiguration) assert isinstance(actions[3], SetLaunchConfiguration) assert isinstance(actions[4], PopLaunchConfigurations) actions[0].visit(lc) actions[1].visit(lc) assert 'foo' not in lc.launch_configurations.keys() assert 'bar' in lc.launch_configurations.keys() assert 'BAR' == lc.launch_configurations['bar'] assert 'baz' in lc.launch_configurations.keys() assert 'BAZ' == lc.launch_configurations['baz'] actions[2].visit(lc) actions[3].visit(lc) actions[4].visit(lc)
def test_reset(): yaml_file = \ """\ launch: - let: name: 'foo' value: 'FOO' - let: name: 'bar' value: 'BAR' - reset: keep: - name: 'bar' value: $(var bar) - name: 'baz' value: 'BAZ' """ # noqa: E501 print('Load YAML') yaml_file = textwrap.dedent(yaml_file) print('Load Parser') root_entity, parser = Parser.load(io.StringIO(yaml_file)) print('Parse Description') ld = parser.parse_description(root_entity) assert isinstance(ld.entities[0], SetLaunchConfiguration) assert isinstance(ld.entities[1], SetLaunchConfiguration) assert isinstance(ld.entities[2], ResetLaunchConfigurations) lc = LaunchContext() assert len(lc.launch_configurations) == 0 ld.entities[0].visit(lc) ld.entities[1].visit(lc) assert len(lc.launch_configurations) == 2 assert 'foo' in lc.launch_configurations.keys() assert lc.launch_configurations['foo'] == 'FOO' assert 'bar' in lc.launch_configurations.keys() assert lc.launch_configurations['bar'] == 'BAR' ld.entities[2].visit(lc) assert 'foo' not in lc.launch_configurations.keys() assert 'bar' in lc.launch_configurations.keys() assert lc.launch_configurations['bar'] == 'BAR' assert 'baz' in lc.launch_configurations.keys() assert lc.launch_configurations['baz'] == 'BAZ'
def test_substituted_properties(): os.environ['EXECUTABLE_NAME'] = 'name' os.environ['EXECUTABLE_CWD'] = 'cwd' os.environ['EXECUTABLE_ENVVAR'] = 'var' os.environ['EXECUTABLE_ENVVAL'] = 'value' name = EnvironmentVariable('EXECUTABLE_NAME') cwd = EnvironmentVariable('EXECUTABLE_CWD') env = { EnvironmentVariable('EXECUTABLE_ENVVAR'): EnvironmentVariable('EXECUTABLE_ENVVAL') } exe = Executable(cmd=['test'], name=name, cwd=cwd, env=env) exe.prepare(LaunchContext(), None) assert exe.final_name.startswith('name') assert exe.final_cwd == 'cwd' assert exe.final_env == {'var': 'value'} del os.environ['EXECUTABLE_NAME'] del os.environ['EXECUTABLE_CWD'] del os.environ['EXECUTABLE_ENVVAR'] del os.environ['EXECUTABLE_ENVVAL']
default_value='127.0.0.1', description='ROBOT_IP'), DeclareLaunchArgument('port', default_value='12345', description='ROBOT_PORT'), DeclareLaunchArgument('mode', default_value='virtual', description='OPERATION MODE'), DeclareLaunchArgument('model', default_value='m1013', description='ROBOT_MODEL'), DeclareLaunchArgument('color', default_value='white', description='ROBOT_COLOR'), ] context = LaunchContext() def load_file(package_name, file_path): package_path = get_package_share_directory(package_name) absolute_file_path = os.path.join(package_path, file_path) try: with open(absolute_file_path, 'r') as file: return file.read() except EnvironmentError: # parent of IOError, OSError *and* WindowsError where available return None def load_yaml(package_name, file_path): package_path = get_package_share_directory(package_name)
def test_command_with_stderr_capture(commands): """Test `Command` substitution with `on_stderr='capture'`.""" context = LaunchContext() command = Command(commands['with_stderr'], on_stderr='capture') output = command.perform(context) assert output == 'asd bsd\n'
def test_command_with_stderr_warn(commands): """Test `Command` substitution with `on_stderr='warn'`.""" context = LaunchContext() command = Command(commands['with_stderr'], on_stderr='warn') output = command.perform(context) assert output == ''
def test_command_with_stderr_ignored(commands): """Test `Command` substitution ignoring stderr.""" context = LaunchContext() command = Command(commands['with_stderr'], on_stderr='ignore') output = command.perform(context) assert output == ''
def test_cmd_multiple_arguments_in_string(): exe = Executable(cmd=['ls', '-opt1', '-opt2', '-opt3']) exe.prepare(LaunchContext(), None) assert all( a == b for a, b in zip(exe.final_cmd, ['ls', '-opt1', '-opt2', '-opt3']))
def test_command(commands): """Test a simple command.""" context = LaunchContext() command = Command(commands['normal']) output = command.perform(context) assert output == 'asd bsd csd\n'
def generate_launch_description(): map_yaml_file = os.getenv('TEST_MAP') world = os.getenv('TEST_WORLD') bt_navigator_xml = os.path.join(get_package_share_directory('nav2_bt_navigator'), 'behavior_trees', os.getenv('BT_NAVIGATOR_XML')) bringup_dir = get_package_share_directory('nav2_bringup') params_file = os.path.join(bringup_dir, 'params', 'nav2_params.yaml') # Replace the default parameter values for testing special features # without having multiple params_files inside the nav2 stack context = LaunchContext() param_substitutions = {} if (os.getenv('ASTAR') == 'True'): param_substitutions.update({'use_astar': 'True'}) if (os.getenv('GROOT_MONITORING') == 'True'): param_substitutions.update({'enable_groot_monitoring': 'True'}) configured_params = RewrittenYaml( source_file=params_file, root_key='', param_rewrites=param_substitutions, convert_types=True) new_yaml = configured_params.perform(context) return LaunchDescription([ SetEnvironmentVariable('RCUTILS_CONSOLE_STDOUT_LINE_BUFFERED', '1'), # Launch gazebo server for simulation ExecuteProcess( cmd=['gzserver', '-s', 'libgazebo_ros_init.so', '--minimal_comms', world], output='screen'), # TODO(orduno) Launch the robot state publisher instead # using a local copy of TB3 urdf file Node( package='tf2_ros', executable='static_transform_publisher', output='screen', arguments=['0', '0', '0', '0', '0', '0', 'base_footprint', 'base_link']), Node( package='tf2_ros', executable='static_transform_publisher', output='screen', arguments=['0', '0', '0', '0', '0', '0', 'base_link', 'base_scan']), IncludeLaunchDescription( PythonLaunchDescriptionSource( os.path.join(bringup_dir, 'launch', 'bringup_launch.py')), launch_arguments={'namespace': '', 'use_namespace': 'False', 'map': map_yaml_file, 'use_sim_time': 'True', 'params_file': new_yaml, 'bt_xml_file': bt_navigator_xml, 'autostart': 'True'}.items()), ])
else: raise RuntimeError('No launch file supplied') launch_arguments.extend(args.launch_arguments) parsed_launch_arguments = parse_launch_arguments(launch_arguments) launch_description = launch.LaunchDescription([ launch.actions.IncludeLaunchDescription( launch.launch_description_sources.AnyLaunchDescriptionSource(path), launch_arguments=parsed_launch_arguments, ), ]) walker = [] walker.append(launch_description) ros_specific_arguments: Dict[str, Union[str, List[str]]] = {} context = LaunchContext(argv=launch_arguments) context._set_asyncio_loop(asyncio.get_event_loop()) try: # * Here we mimic the run loop inside launch_service, # but without actually kicking off the processes. # * Traverse the sub entities by DFS. # * Shadow the stdout to avoid random print outputs. mystring = StringIO() sys.stdout = mystring while walker: entity = walker.pop() visit_future = entity.visit(context) if visit_future is not None: visit_future.reverse() walker.extend(visit_future)
def test_cmd_strings_in_list(): exe = Executable(cmd=['ls', '"my/subdir/with spaces/"']) exe.prepare(LaunchContext(), None) assert all( a == b for a, b in zip(exe.final_cmd, ['ls', '"my/subdir/with spaces/"']))