def test_interrupt_default_launcher(): desc = LaunchDescriptor() desc.add_process( cmd=[sys.executable, '-c', 'import time', 'time.sleep(30)'], name='test_interrupt_default_launcher__python_blocking') launcher = DefaultLauncher() launcher.add_launch_descriptor(desc) def thread_target(): # wait up to 10 seconds to get to the point where at least all of the # asyncio-subprocess coroutines have been run (the processes are still # not guaranteed to be running yet) launcher.wait_on_processes_to_spawn(10) if not launcher.are_processes_spawned(): # if the processes didn't launch after 10 seconds, fail the test _thread.interrupt_main() assert False, 'launcher never reported processes launched' launcher.interrupt_launch() # now wait for the launcher to finish and error if if doesn't launcher.wait_on_launch_to_finish(60) if launcher.is_launch_running(): # if still running fail the test _thread.interrupt_main() assert False, 'launcher failed to shutdown' t = threading.Thread(target=thread_target) t.start() try: launcher.launch() except KeyboardInterrupt: assert False, 'failed by watchdog thread, see other AssertionErrors' t.join()
def test_launch_with_coroutine(): default_launcher = DefaultLauncher() launch_file = os.path.join(os.path.abspath(os.path.dirname(__file__)), 'launch_counter.py') launch_descriptor = LaunchDescriptor() load_launch_file(launch_file, launch_descriptor, {}) async def coroutine(): await asyncio.sleep(1) print('one', file=sys.stderr) await asyncio.sleep(1) print('two', file=sys.stderr) await asyncio.sleep(1) print('three', file=sys.stderr) async def coroutine2(): await asyncio.sleep(1) print('one mississippi', file=sys.stderr) await asyncio.sleep(1) print('two mississippi', file=sys.stderr) await asyncio.sleep(1) print('three mississippi', file=sys.stderr) launch_descriptor.add_coroutine( coroutine(), name='coroutine', exit_handler=primary_exit_handler) # launch_descriptor.add_coroutine(coroutine2()) print('launch', file=sys.stderr) default_launcher.add_launch_descriptor(launch_descriptor) rc = default_launcher.launch() print('done', rc, file=sys.stderr)
def test_logging_long_messages(): launch_descriptor = LaunchDescriptor() output_file = os.path.join(os.path.dirname(__file__), 'test_logging_long_messages') handler = create_handler('test_logging_long_messages', launch_descriptor, output_file) assert handler, 'Cannot find appropriate handler for %s' % output_file # Set the output format to a "verbose" format that is expected by the executable output os.environ['RCUTILS_CONSOLE_OUTPUT_FORMAT'] = \ '[{severity}] [{name}]: {message} ({function_name}() at {file_name}:{line_number})' executable = os.path.join(os.getcwd(), 'test_logging_long_messages') if os.name == 'nt': executable += '.exe' launch_descriptor.add_process( cmd=[executable], name='test_logging_long_messages', exit_handler= ignore_exit_handler, # The process will automatically exit after printing. output_handlers=[ConsoleOutput(), handler], ) launcher = DefaultLauncher() launcher.add_launch_descriptor(launch_descriptor) rc = launcher.launch() assert rc == 0, \ "The launch file failed with exit code '" + str(rc) + "'" handler.check()
def launch(index): default_launcher = DefaultLauncher() async def coroutine(): await asyncio.sleep(1) print('message %d' % index, file=sys.stderr) launch_descriptor = LaunchDescriptor() launch_descriptor.add_coroutine(coroutine(), name='coroutine%d' % index) print('launch %d' % index, file=sys.stderr) default_launcher.add_launch_descriptor(launch_descriptor) rc = default_launcher.launch() print('done %d' % index, rc, file=sys.stderr)
def main(): launcher = DefaultLauncher() launch_descriptor = LaunchDescriptor() package = 'topic_monitor' executable = get_executable_path(package_name=package, executable_name='data_publisher') # Strip the logger name from the message format in favor of the shorter executable name os.environ['RCUTILS_CONSOLE_OUTPUT_FORMAT'] = '[{severity}] {message}' os.environ[ 'PYTHONUNBUFFERED'] = '1' # force unbuffered output to get prints to sync correctly launch_descriptor.add_process( cmd=[executable, 'sensor', '--best-effort'], name='sensor', ) launch_descriptor.add_process( cmd=[executable, 'critical'], name='critical', ) launcher.add_launch_descriptor(launch_descriptor) rc = launcher.launch() if rc != 0: print('Something went wrong. Return code: ' + str(rc), file=sys.stderr) exit(rc)
def test_non_primary_return_code(): # since Python < 3.5 on Windows does not support signaling SIGINT to the subprocesses # we can't expect them to shutdown cleanly, therefore we ignore this test if os.name == 'nt': return default_launcher = DefaultLauncher() async def coroutine1(): await asyncio.sleep(1) print('one', file=sys.stderr) await asyncio.sleep(1) print('two', file=sys.stderr) return 3 async def coroutine2(): await asyncio.sleep(1) print('one mississippi', file=sys.stderr) return 0 launch_descriptor = LaunchDescriptor() launch_descriptor.add_coroutine(coroutine1(), name='coroutine1') launch_descriptor.add_coroutine(coroutine2(), name='coroutine2', exit_handler=primary_exit_handler) print('launch', file=sys.stderr) default_launcher.add_launch_descriptor(launch_descriptor) rc = default_launcher.launch() print('done', rc, file=sys.stderr) assert rc == 3, 'Expected return code is 3'
def test_func(node_fixture): """Run an executable with cli_args and coroutine test in the same asyncio loop.""" nonlocal cli_args # Create a command launching a name_maker executable specified by the pytest fixture command = [node_fixture['executable']] # format command line arguments with random string from test fixture for arg in cli_args: command.append( arg.format(random_string=node_fixture['random_string'])) # Execute python files using same python used to start this test env = dict(os.environ) if command[0][-3:] == '.py': command.insert(0, sys.executable) env['PYTHONUNBUFFERED'] = '1' ld = LaunchDescriptor() ld.add_process(cmd=command, name='name_maker_' + coroutine_test.__name__, env=env) ld.add_coroutine(coroutine_test(node_fixture), name=coroutine_test.__name__, exit_handler=primary_exit_handler) launcher = DefaultLauncher() launcher.add_launch_descriptor(ld) return_code = launcher.launch() assert return_code == 0, 'Launch failed with exit code %r' % ( return_code, )
def test_matching(): output_handlers = [] launch_descriptor = LaunchDescriptor() # This temporary directory and files contained in it will be deleted when the process ends. tempdir = tempfile.mkdtemp() output_file = tempdir + os.sep + 'testfile' full_output_file = output_file + '.regex' with open(full_output_file, 'w+') as f: f.write('this is line \d\nthis is line [a-z]') name = 'test_executable_0' handler = create_handler(name, launch_descriptor, output_file) assert handler, 'Cannot find appropriate handler for %s' % output_file output_handlers.append(handler) executable_command = [ sys.executable, os.path.join(os.path.abspath(os.path.dirname(__file__)), 'matching.py') ] launch_descriptor.add_process(cmd=executable_command, name=name, exit_handler=ignore_exit_handler, output_handlers=output_handlers) launcher = DefaultLauncher() launcher.add_launch_descriptor(launch_descriptor) rc = launcher.launch() assert rc == 0, \ "The launch file failed with exit code '" + str(rc) + "'. " for handler in output_handlers: handler.check()
def test_env(): ld = LaunchDescriptor() sub_env = copy.deepcopy(os.environ) sub_env['testenv1'] = 'testval1' os.environ['testenv2'] = 'testval2' ld.add_process( cmd=[ sys.executable, os.path.join( os.path.abspath( os.path.dirname(__file__)), 'check_env.py')], name='test_env', env=sub_env, exit_handler=primary_exit_handler, ) launcher = DefaultLauncher() launcher.add_launch_descriptor(ld) rc = launcher.launch() assert rc == 0, \ "The launch file failed with exit code '" + str(rc) + "'. "
def main(): launcher = DefaultLauncher() launch_descriptor = LaunchDescriptor() package = 'topic_monitor' executable = get_executable_path(package_name=package, executable_name='data_publisher') os.environ[ 'PYTHONUNBUFFERED'] = '1' # force unbuffered output to get prints to sync correctly name = 'small' launch_descriptor.add_process( cmd=[executable, name, '--payload-size', '1', '--period', '4'], name=name, ) name = 'medium' launch_descriptor.add_process( cmd=[executable, name, '--payload-size', '50000', '--period', '4'], name=name, ) name = 'large' launch_descriptor.add_process( cmd=[executable, name, '--payload-size', '100000', '--period', '4'], name=name, ) name = 'xlarge' launch_descriptor.add_process( cmd=[executable, name, '--payload-size', '150000', '--period', '4'], name=name, ) launcher.add_launch_descriptor(launch_descriptor) rc = launcher.launch() if rc != 0: print('Something went wrong. Return code: ' + str(rc), file=sys.stderr) exit(rc)
def main(): launcher = DefaultLauncher() launch_descriptor = LaunchDescriptor() os.environ[ 'PYTHONUNBUFFERED'] = '1' # force unbuffered output to get prints to sync correctly add_process_to_descriptor(launch_descriptor, 'small', 1) add_process_to_descriptor(launch_descriptor, 'small', 50) add_process_to_descriptor(launch_descriptor, 'large', 1) add_process_to_descriptor(launch_descriptor, 'large', 50) launcher.add_launch_descriptor(launch_descriptor) rc = launcher.launch() if rc != 0: print('Something went wrong. Return code: ' + str(rc), file=sys.stderr) exit(rc)
def launch(launch_descriptor, argv): counter_file = os.path.join(os.path.abspath(os.path.dirname(__file__)), 'counter.py') with NamedTemporaryFile(mode='w', prefix='foo_', delete=False) as h: foo_filename = h.name with NamedTemporaryFile(mode='w', prefix='baz-err_', delete=False) as h: baz_filename = h.name ld = launch_descriptor ld.add_process( cmd=[sys.executable, '-u', counter_file, '--limit', '9', '--sleep', '0.5'], name='foo', output_handlers=[FileOutput(filename=foo_filename)], exit_handler=restart_exit_handler, ) ld.add_process( cmd=[sys.executable, '-u', counter_file, '--limit', '10', '--sleep', '0.25'], name='bar', env=None, exit_handler=ignore_exit_handler, ) ld.add_process( cmd=[sys.executable, '-u', counter_file, '--limit', '5', '--sleep', '1'], name='baz', output_handlers=[FileOutput(filename_stderr=baz_filename)], ) ld.add_process( cmd=[sys.executable, '-u', counter_file, '--sleep', '0.5'], name='qux', output_handlers=[ConsoleOutput(stderr_only=True)], ) other_launch_file = os.path.join( os.path.abspath(os.path.dirname(__file__)), 'launch_counter.py') sub_ld = LaunchDescriptor() load_launch_file(other_launch_file, sub_ld, {}) # namespace all processes from other launch file for d in sub_ld.task_descriptors: d.name = 'sub.' + d.name ld.task_descriptors.append(d)
def main(argv=sys.argv[1:]): parser = argparse.ArgumentParser( description='Launch the processes specified in a launch file.') parser.add_argument('launch_file', type=file_exists, nargs='+', help='The launch file.') parser.add_argument( '--args', metavar='arg', type=str, nargs='+', help='An argument to the launch file (e.g., arg_name:=value). All ' 'arguments will be passed to each launch file.') args = parser.parse_args(argv) launcher = DefaultLauncher() for launch_file in args.launch_file: launch_descriptor = LaunchDescriptor() load_launch_file(launch_file, launch_descriptor, args.args) launcher.add_launch_descriptor(launch_descriptor) rc = launcher.launch() return rc
def main(argv=sys.argv[1:]): launcher = DefaultLauncher() launch_descriptor = launch(LaunchDescriptor(), argv) launcher.add_launch_descriptor(launch_descriptor) rc = launcher.launch() return rc
def test_logging_output_format(): launch_descriptor = LaunchDescriptor() handlers = [] # Re-use the test_logging_long_messages test binary and modify the output format from an # environment variable. executable = os.path.join(os.getcwd(), 'test_logging_long_messages') if os.name == 'nt': executable += '.exe' env_long = dict(os.environ) # In this custom output, the long message is output twice, to test both dynamic allocation and # re-allocation. env_long['RCUTILS_CONSOLE_OUTPUT_FORMAT'] = \ '[{{name}}].({severity}) output: {file_name}:{line_number} {message}, again: {message} ({function_name}()){' # noqa name = 'test_logging_output_format_long' output_file = os.path.join(os.path.dirname(__file__), name) handler = create_handler(name, launch_descriptor, output_file) assert handler, 'Cannot find appropriate handler for %s' % output_file launch_descriptor.add_process( cmd=[executable], env=env_long, name=name, exit_handler=ignore_exit_handler, output_handlers=[ConsoleOutput(), handler], ) handlers.append(handler) env_edge_cases = dict(os.environ) # This custom output is to check different edge cases of the output format string parsing. env_edge_cases[ 'RCUTILS_CONSOLE_OUTPUT_FORMAT'] = '{}}].({unknown_token}) {{{{' name = 'test_logging_output_format_edge_cases' output_file = os.path.join(os.path.dirname(__file__), name) handler = create_handler(name, launch_descriptor, output_file) assert handler, 'Cannot find appropriate handler for %s' % output_file launch_descriptor.add_process( cmd=[executable], env=env_edge_cases, name=name, exit_handler=ignore_exit_handler, output_handlers=[ConsoleOutput(), handler], ) handlers.append(handler) env_no_tokens = dict(os.environ) # This custom output is to check that there are no issues when no tokens are used. env_no_tokens['RCUTILS_CONSOLE_OUTPUT_FORMAT'] = 'no_tokens' name = 'test_logging_output_format_no_tokens' output_file = os.path.join(os.path.dirname(__file__), name) handler = create_handler(name, launch_descriptor, output_file) assert handler, 'Cannot find appropriate handler for %s' % output_file launch_descriptor.add_process( cmd=[executable], env=env_no_tokens, name=name, exit_handler=ignore_exit_handler, output_handlers=[ConsoleOutput(), handler], ) handlers.append(handler) env_time_tokens = dict(os.environ) # This custom output is to check that time stamps work correctly env_time_tokens[ 'RCUTILS_CONSOLE_OUTPUT_FORMAT'] = "'{time}' '{time_as_nanoseconds}'" name = 'test_logging_output_timestamps' output_file = os.path.join(os.path.dirname(__file__), name) handler = create_handler(name, launch_descriptor, output_file) assert handler, 'Cannot find appropriate handler for %s' % output_file launch_descriptor.add_process( cmd=[executable], env=env_time_tokens, name=name, exit_handler=ignore_exit_handler, output_handlers=[ConsoleOutput(), handler], ) handlers.append(handler) launcher = DefaultLauncher() launcher.add_launch_descriptor(launch_descriptor) rc = launcher.launch() assert rc == 0, \ "The launch file failed with exit code '" + str(rc) + "'" for handler in handlers: handler.check()