Skip to content

Commit cba4e28

Browse files
committed
Enhance tests for 'sh' and 'bat' shells
The existing tests exercise much of the code for implementing colcon's shell subsystem, but it doesn't validate the results. If the platform supports the shell, we should check that the code for appending and prepending paths to lists function as intended.
1 parent 3310754 commit cba4e28

File tree

2 files changed

+349
-42
lines changed

2 files changed

+349
-42
lines changed

test/test_shell_bat.py

Lines changed: 168 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,14 @@
55
from pathlib import Path
66
import sys
77
from tempfile import TemporaryDirectory
8+
from unittest.mock import patch
89

910
from colcon_core import shell
11+
from colcon_core.location import get_relative_package_index_path
1012
from colcon_core.plugin_system import SkipExtensionException
13+
from colcon_core.shell import get_environment_variables
1114
from colcon_core.shell.bat import BatShell
15+
from colcon_core.shell.dsv import DsvShell
1216
import pytest
1317

1418
from .run_until_complete import run_until_complete
@@ -20,6 +24,7 @@ def test_extension():
2024
try:
2125
with TemporaryDirectory(prefix='test_colcon_') as prefix_path:
2226
_test_extension(Path(prefix_path))
27+
_test_prefix_script(Path(prefix_path))
2328
finally:
2429
shell.use_all_shell_extensions = use_all_shell_extensions
2530

@@ -39,33 +44,36 @@ def _test_extension(prefix_path):
3944
extension.create_prefix_script(prefix_path, False)
4045
assert (prefix_path / 'local_setup.bat').exists()
4146

47+
# create_hook_append_value
48+
append_hook_path = extension.create_hook_append_value(
49+
'append_env_hook_name', prefix_path, 'pkg_name',
50+
'APPEND_NAME', 'subdirectory')
51+
assert append_hook_path.exists()
52+
assert append_hook_path.name == 'append_env_hook_name.bat'
53+
content = append_hook_path.read_text()
54+
assert 'APPEND_NAME' in content
55+
56+
# create_hook_prepend_value
57+
prepend_hook_path = extension.create_hook_prepend_value(
58+
'prepend_env_hook_name', prefix_path, 'pkg_name',
59+
'PREPEND_NAME', 'subdirectory')
60+
assert prepend_hook_path.exists()
61+
assert prepend_hook_path.name == 'prepend_env_hook_name.bat'
62+
content = prepend_hook_path.read_text()
63+
assert 'PREPEND_NAME' in content
64+
4265
# create_package_script
4366
extension.create_package_script(
4467
prefix_path, 'pkg_name', [
45-
('hookA.bat', '/some/path/hookA.bat'),
68+
(append_hook_path.relative_to(prefix_path), ()),
69+
(prepend_hook_path.relative_to(prefix_path), ()),
4670
('hookB.other', '/some/path/hookB.other')])
4771
assert (prefix_path / 'share' / 'pkg_name' / 'package.bat').exists()
4872
content = (prefix_path / 'share' / 'pkg_name' / 'package.bat').read_text()
49-
assert 'hookA' in content
73+
assert append_hook_path.name in content
74+
assert prepend_hook_path.name in content
5075
assert 'hookB' not in content
5176

52-
# create_hook_append_value
53-
hook_path = extension.create_hook_append_value(
54-
'append_env_hook_name', prefix_path, 'pkg_name',
55-
'APPEND_NAME', 'append_subdirectory')
56-
assert hook_path.exists()
57-
assert hook_path.name == 'append_env_hook_name.bat'
58-
content = hook_path.read_text()
59-
assert 'APPEND_NAME' in content
60-
61-
# create_hook_prepend_value
62-
hook_path = extension.create_hook_prepend_value(
63-
'env_hook_name', prefix_path, 'pkg_name', 'NAME', 'subdirectory')
64-
assert hook_path.exists()
65-
assert hook_path.name == 'env_hook_name.bat'
66-
content = hook_path.read_text()
67-
assert 'NAME' in content
68-
6977
# generate_command_environment
7078
if sys.platform != 'win32':
7179
with pytest.raises(SkipExtensionException) as e:
@@ -93,3 +101,144 @@ def _test_extension(prefix_path):
93101
'task_name', prefix_path, {'dep': str(prefix_path)})
94102
env = run_until_complete(coroutine)
95103
assert isinstance(env, dict)
104+
105+
subdirectory_path = str(prefix_path / 'subdirectory')
106+
107+
# validate appending/prepending without existing values
108+
with patch.dict(os.environ) as env_patch:
109+
env_patch.pop('APPEND_NAME', None)
110+
env_patch.pop('PREPEND_NAME', None)
111+
coroutine = extension.generate_command_environment(
112+
'task_name', prefix_path, {'pkg_name': str(prefix_path)})
113+
env = run_until_complete(coroutine)
114+
assert env.get('APPEND_NAME') == subdirectory_path
115+
assert env.get('PREPEND_NAME') == subdirectory_path
116+
117+
# validate appending/prepending with existing values
118+
with patch.dict(os.environ, {
119+
'APPEND_NAME': 'control',
120+
'PREPEND_NAME': 'control',
121+
}):
122+
coroutine = extension.generate_command_environment(
123+
'task_name', prefix_path, {'pkg_name': str(prefix_path)})
124+
env = run_until_complete(coroutine)
125+
assert env.get('APPEND_NAME') == os.pathsep.join((
126+
'control',
127+
subdirectory_path,
128+
))
129+
assert env.get('PREPEND_NAME') == os.pathsep.join((
130+
subdirectory_path,
131+
'control',
132+
))
133+
134+
# validate appending/prepending unique values
135+
with patch.dict(os.environ, {
136+
'APPEND_NAME': os.pathsep.join((subdirectory_path, 'control')),
137+
'PREPEND_NAME': os.pathsep.join(('control', subdirectory_path)),
138+
}):
139+
coroutine = extension.generate_command_environment(
140+
'task_name', prefix_path, {'pkg_name': str(prefix_path)})
141+
env = run_until_complete(coroutine)
142+
# Expect no change, value already appears earlier in the list
143+
assert env.get('APPEND_NAME') == os.pathsep.join((
144+
subdirectory_path,
145+
'control',
146+
))
147+
# Expect value to be *moved* to the front of the list
148+
assert env.get('PREPEND_NAME') == os.pathsep.join((
149+
subdirectory_path,
150+
'control',
151+
))
152+
153+
154+
def _test_prefix_script(prefix_path):
155+
extension = BatShell()
156+
157+
# BatShell requires the (non-primary) DsvShell extension as well
158+
dsv_extension = DsvShell()
159+
160+
# create_hook_append_value
161+
append_hook_path = dsv_extension.create_hook_append_value(
162+
'append_env_hook_name', prefix_path, 'pkg_name',
163+
'APPEND_NAME', 'subdirectory')
164+
assert append_hook_path.exists()
165+
assert append_hook_path.name == 'append_env_hook_name.dsv'
166+
content = append_hook_path.read_text()
167+
assert 'APPEND_NAME' in content
168+
169+
# create_hook_prepend_value
170+
prepend_hook_path = dsv_extension.create_hook_prepend_value(
171+
'prepend_env_hook_name', prefix_path, 'pkg_name',
172+
'PREPEND_NAME', 'subdirectory')
173+
assert prepend_hook_path.exists()
174+
assert prepend_hook_path.name == 'prepend_env_hook_name.dsv'
175+
content = prepend_hook_path.read_text()
176+
assert 'PREPEND_NAME' in content
177+
178+
# mark package as installed
179+
package_index = prefix_path / get_relative_package_index_path()
180+
package_index.mkdir(parents=True)
181+
(package_index / 'pkg_name').write_text('')
182+
183+
# create_package_script
184+
dsv_extension.create_package_script(
185+
prefix_path, 'pkg_name', [
186+
(append_hook_path.relative_to(prefix_path), ()),
187+
(prepend_hook_path.relative_to(prefix_path), ())])
188+
assert (prefix_path / 'share' / 'pkg_name' / 'package.dsv').exists()
189+
content = (prefix_path / 'share' / 'pkg_name' / 'package.dsv').read_text()
190+
assert append_hook_path.name in content
191+
assert prepend_hook_path.name in content
192+
193+
# create_prefix_script
194+
extension.create_prefix_script(prefix_path, True)
195+
prefix_script = prefix_path / 'local_setup.bat'
196+
prefix_script.exists()
197+
assert (prefix_path / '_local_setup_util_bat.py').exists()
198+
199+
if sys.platform == 'win32':
200+
subdirectory_path = str(prefix_path / 'subdirectory')
201+
202+
# validate appending/prepending without existing values
203+
with patch.dict(os.environ) as env_patch:
204+
env_patch.pop('APPEND_NAME', None)
205+
env_patch.pop('PREPEND_NAME', None)
206+
coroutine = get_environment_variables([prefix_script, '&&', 'set'])
207+
env = run_until_complete(coroutine)
208+
assert env.get('APPEND_NAME') == subdirectory_path
209+
assert env.get('PREPEND_NAME') == subdirectory_path
210+
211+
# validate appending/prepending with existing values
212+
with patch.dict(os.environ, {
213+
'APPEND_NAME': 'control',
214+
'PREPEND_NAME': 'control',
215+
}):
216+
coroutine = get_environment_variables([prefix_script, '&&', 'set'])
217+
env = run_until_complete(coroutine)
218+
assert env.get('APPEND_NAME') == os.pathsep.join((
219+
'control',
220+
subdirectory_path,
221+
))
222+
assert env.get('PREPEND_NAME') == os.pathsep.join((
223+
subdirectory_path,
224+
'control',
225+
))
226+
227+
# validate appending/prepending unique values
228+
with patch.dict(os.environ, {
229+
'APPEND_NAME': os.pathsep.join((subdirectory_path, 'control')),
230+
'PREPEND_NAME': os.pathsep.join(('control', subdirectory_path)),
231+
}):
232+
coroutine = get_environment_variables([prefix_script, '&&', 'set'])
233+
env = run_until_complete(coroutine)
234+
# Expect no change, value already appears earlier in the list
235+
assert env.get('APPEND_NAME') == os.pathsep.join((
236+
subdirectory_path,
237+
'control',
238+
))
239+
# TODO: The DsvShell behavior doesn't align with BatShell!
240+
# ~~Expect value to be *moved* to the front of the list~~
241+
assert env.get('PREPEND_NAME') == os.pathsep.join((
242+
'control',
243+
subdirectory_path,
244+
))

0 commit comments

Comments
 (0)