|
14 | 14 |
|
15 | 15 | """Tests for the IncludeLaunchDescription action class.""" |
16 | 16 |
|
| 17 | +import os |
17 | 18 | from pathlib import Path |
18 | 19 |
|
19 | 20 | from launch import LaunchContext |
|
22 | 23 | from launch import LaunchService |
23 | 24 | from launch.actions import DeclareLaunchArgument |
24 | 25 | from launch.actions import IncludeLaunchDescription |
| 26 | +from launch.actions import OpaqueFunction |
25 | 27 | from launch.actions import ResetLaunchConfigurations |
| 28 | +from launch.actions import SetEnvironmentVariable |
26 | 29 | from launch.actions import SetLaunchConfiguration |
27 | 30 | from launch.launch_description_sources import PythonLaunchDescriptionSource |
| 31 | +from launch.substitutions import ThisLaunchFile |
| 32 | +from launch.substitutions import ThisLaunchFileDir |
28 | 33 | from launch.utilities import perform_substitutions |
29 | 34 |
|
30 | 35 | import pytest |
@@ -87,6 +92,53 @@ def test_include_launch_description_launch_file_location(): |
87 | 92 | assert action2.get_asyncio_future() is None |
88 | 93 |
|
89 | 94 |
|
| 95 | +def test_include_launch_description_launch_file_dir_location_scoped(): |
| 96 | + """Test that the launch file name & dir locals are scoped to the included launch file.""" |
| 97 | + # Rely on the test launch files to set environment variables with |
| 98 | + # ThisLaunchFile()/ThisLaunchFileDir() to make testing easier |
| 99 | + parent_dir = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'launch') |
| 100 | + parent_launch_file = os.path.join(parent_dir, 'parent_launch_file_dir.launch.py') |
| 101 | + included_dir = os.path.join(parent_dir, 'included') |
| 102 | + included_launch_file = os.path.join(included_dir, 'launch_file_dir.launch.py') |
| 103 | + |
| 104 | + # The current launch file/dir context locals should be scoped to the included launch file |
| 105 | + ld = LaunchDescription([IncludeLaunchDescription(parent_launch_file)]) |
| 106 | + ls = LaunchService() |
| 107 | + ls.include_launch_description(ld) |
| 108 | + assert 0 == ls.run() |
| 109 | + lc = ls.context |
| 110 | + assert lc.environment.get('Before_ThisLaunchFile') == parent_launch_file |
| 111 | + assert lc.environment.get('Before_ThisLaunchFileDir') == parent_dir |
| 112 | + assert lc.environment.get('Included_ThisLaunchFile') == included_launch_file |
| 113 | + assert lc.environment.get('Included_ThisLaunchFileDir') == included_dir |
| 114 | + assert lc.environment.get('After_ThisLaunchFile') == parent_launch_file |
| 115 | + assert lc.environment.get('After_ThisLaunchFileDir') == parent_dir |
| 116 | + |
| 117 | + # The launch file/dir context locals should be completely removed after the first included |
| 118 | + # (parent) launch file, because at that point we're in a launch script and not a launch file, |
| 119 | + # and therefore these substitutions should raise an error |
| 120 | + ld2 = LaunchDescription([ |
| 121 | + IncludeLaunchDescription(parent_launch_file), |
| 122 | + SetEnvironmentVariable('Outside_ThisLaunchFile', ThisLaunchFile()), |
| 123 | + SetEnvironmentVariable('Outside_ThisLaunchFileDir', ThisLaunchFileDir()), |
| 124 | + ]) |
| 125 | + ls2 = LaunchService() |
| 126 | + ls2.include_launch_description(ld2) |
| 127 | + assert 1 == ls2.run() |
| 128 | + |
| 129 | + # The non-launch file/dir context locals should not be scoped to the included launch file |
| 130 | + def assert_unscoped_context_local(context: LaunchContext): |
| 131 | + assert context.locals.included_local == 'context_local_value' |
| 132 | + |
| 133 | + ld3 = LaunchDescription([ |
| 134 | + IncludeLaunchDescription(parent_launch_file), |
| 135 | + OpaqueFunction(function=assert_unscoped_context_local), |
| 136 | + ]) |
| 137 | + ls3 = LaunchService() |
| 138 | + ls3.include_launch_description(ld3) |
| 139 | + assert 0 == ls3.run() |
| 140 | + |
| 141 | + |
90 | 142 | def test_include_launch_description_launch_arguments(): |
91 | 143 | """Test the interactions between declared launch arguments and IncludeLaunchDescription.""" |
92 | 144 | # test that arguments are set when given, even if they are not declared |
|
0 commit comments