|
15 | 15 | """Tests for the ExecuteProcess Action.""" |
16 | 16 |
|
17 | 17 | import os |
| 18 | +import platform |
| 19 | +import signal |
18 | 20 | import sys |
19 | 21 |
|
20 | 22 | from launch import LaunchDescription |
21 | 23 | from launch import LaunchService |
| 24 | +from launch.actions.emit_event import EmitEvent |
22 | 25 | from launch.actions.execute_process import ExecuteProcess |
23 | 26 | from launch.actions.opaque_function import OpaqueFunction |
| 27 | +from launch.actions.register_event_handler import RegisterEventHandler |
24 | 28 | from launch.actions.shutdown_action import Shutdown |
25 | 29 | from launch.actions.timer_action import TimerAction |
| 30 | +from launch.event_handlers.on_process_start import OnProcessStart |
| 31 | +from launch.events.shutdown import Shutdown as ShutdownEvent |
26 | 32 |
|
27 | 33 | import pytest |
28 | 34 |
|
@@ -88,6 +94,50 @@ def on_exit_function(context): |
88 | 94 | assert on_exit_function.called |
89 | 95 |
|
90 | 96 |
|
| 97 | +def test_execute_process_shutdown(): |
| 98 | + """Test shutting down a process in (non)interactive settings.""" |
| 99 | + def on_exit(event, ctx): |
| 100 | + on_exit.returncode = event.returncode |
| 101 | + |
| 102 | + def generate_launch_description(): |
| 103 | + process_action = ExecuteProcess( |
| 104 | + cmd=[sys.executable, '-c', 'import signal; signal.pause()'], |
| 105 | + sigterm_timeout='1', # shorten timeouts |
| 106 | + on_exit=on_exit |
| 107 | + ) |
| 108 | + # Launch process and emit shutdown event as if |
| 109 | + # launch had received a SIGINT |
| 110 | + return LaunchDescription([ |
| 111 | + process_action, |
| 112 | + RegisterEventHandler(event_handler=OnProcessStart( |
| 113 | + target_action=process_action, |
| 114 | + on_start=[ |
| 115 | + EmitEvent(event=ShutdownEvent( |
| 116 | + reason='none', |
| 117 | + due_to_sigint=True |
| 118 | + )) |
| 119 | + ] |
| 120 | + )) |
| 121 | + ]) |
| 122 | + |
| 123 | + ls = LaunchService(noninteractive=True) |
| 124 | + ls.include_launch_description(generate_launch_description()) |
| 125 | + assert 0 == ls.run() |
| 126 | + if platform.system() != 'Windows': |
| 127 | + assert on_exit.returncode == -signal.SIGINT # Got SIGINT |
| 128 | + else: |
| 129 | + assert on_exit.returncode != 0 # Process terminated |
| 130 | + |
| 131 | + ls = LaunchService() # interactive |
| 132 | + ls.include_launch_description(generate_launch_description()) |
| 133 | + assert 0 == ls.run() |
| 134 | + if platform.system() != 'Windows': |
| 135 | + # Assume interactive Ctrl+C (i.e. SIGINT to process group) |
| 136 | + assert on_exit.returncode == -signal.SIGTERM # Got SIGTERM |
| 137 | + else: |
| 138 | + assert on_exit.returncode != 0 # Process terminated |
| 139 | + |
| 140 | + |
91 | 141 | def test_execute_process_with_respawn(): |
92 | 142 | """Test launching a process with a respawn and respawn_delay attribute.""" |
93 | 143 | def on_exit_callback(event, context): |
|
0 commit comments