Skip to content

Commit ddcbb76

Browse files
germa89akaszynski
andauthored
Injecting env vars in MAPDL process (#1219)
* First commit. Implementation + tests * increasing coverage * reordering tests to run some * Now tests in test_launcher needs to be individually skipped. * Apply suggestions from code review Co-authored-by: Alex Kaszynski <[email protected]>
1 parent 8493c2f commit ddcbb76

File tree

2 files changed

+109
-7
lines changed

2 files changed

+109
-7
lines changed

src/ansys/mapdl/core/launcher.py

Lines changed: 73 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -220,6 +220,8 @@ def launch_grpc(
220220
override=True,
221221
timeout=20,
222222
verbose=False,
223+
add_env_vars=None,
224+
replace_env_vars=None,
223225
**kwargs,
224226
) -> tuple: # pragma: no cover
225227
"""Start MAPDL locally in gRPC mode.
@@ -496,9 +498,14 @@ def launch_grpc(
496498
]
497499
)
498500
command = " ".join(command_parm)
501+
502+
env_vars = update_env_vars(add_env_vars, replace_env_vars)
503+
499504
LOG.info(f"Running in {ip}:{port} the following command: '{command}'")
500-
if verbose:
501-
subprocess.Popen(command, shell=os.name != "nt", cwd=run_location)
505+
506+
if verbose: # pragma: no cover
507+
subprocess.Popen(command, shell=os.name != "nt", cwd=run_location, env=env_vars)
508+
502509
else:
503510
subprocess.Popen(
504511
command,
@@ -507,6 +514,7 @@ def launch_grpc(
507514
stdin=subprocess.DEVNULL,
508515
stdout=subprocess.DEVNULL,
509516
stderr=subprocess.DEVNULL,
517+
env=env_vars,
510518
)
511519

512520
# watch for the creation of temporary files at the run_directory.
@@ -978,6 +986,8 @@ def launch_mapdl(
978986
license_server_check=True,
979987
license_type=None,
980988
print_com=False,
989+
add_env_vars=None,
990+
replace_env_vars=None,
981991
**kwargs,
982992
) -> _MapdlCore:
983993
"""Start MAPDL locally.
@@ -1109,6 +1119,16 @@ def launch_mapdl(
11091119
Print the command ``/COM`` arguments to the standard output.
11101120
Default ``False``.
11111121
1122+
add_env_vars : dict, optional
1123+
The provided dictionary will be used to extend the system or process
1124+
environment variables. If you want to control all of the environment
1125+
variables, use ``replace_env_vars``. Defaults to ``None``.
1126+
1127+
replace_env_vars : dict, optional
1128+
The provided dictionary will be used to replace all the system or process
1129+
environment variables. To just add some environment variables to the MAPDL
1130+
process, use ``add_env_vars``. Defaults to ``None``.
1131+
11121132
Returns
11131133
-------
11141134
ansys.mapdl.core.mapdl._MapdlCore
@@ -1483,7 +1503,12 @@ def launch_mapdl(
14831503
)
14841504
elif mode == "grpc":
14851505
port, actual_run_location = launch_grpc(
1486-
port=port, verbose=verbose_mapdl, ip=ip, **start_parm
1506+
port=port,
1507+
verbose=verbose_mapdl,
1508+
ip=ip,
1509+
add_env_vars=add_env_vars,
1510+
replace_env_vars=replace_env_vars,
1511+
**start_parm,
14871512
)
14881513
mapdl = MapdlGrpc(
14891514
ip=ip,
@@ -1567,3 +1592,48 @@ def check_mode(mode, version):
15671592
warnings.warn("MAPDL as a service has not been tested on MAPDL < v13")
15681593

15691594
return mode
1595+
1596+
1597+
def update_env_vars(add_env_vars, replace_env_vars):
1598+
"""
1599+
Update environment variables for the MAPDL process.
1600+
1601+
Parameters
1602+
----------
1603+
add_env_vars : dict, None
1604+
Dictionary with a mapping of env variables.
1605+
replace_env_vars : dict, None
1606+
Dictionary with a mapping of env variables.
1607+
1608+
Raises
1609+
------
1610+
TypeError
1611+
'add_env_vars' and 'replace_env_vars' are incompatible. Please provide only one.
1612+
TypeError
1613+
The variable 'add_env_vars' should be a dict with env vars.
1614+
TypeError
1615+
The variable 'replace_env_vars' should be a dict with env vars.
1616+
"""
1617+
1618+
# Expanding/replacing env variables for the process.
1619+
if add_env_vars and replace_env_vars:
1620+
raise ValueError(
1621+
"'add_env_vars' and 'replace_env_vars' are incompatible. Please provide only one."
1622+
)
1623+
1624+
elif add_env_vars:
1625+
if not isinstance(add_env_vars, dict):
1626+
raise TypeError(
1627+
"The variable 'add_env_vars' should be a dict with env vars."
1628+
)
1629+
1630+
add_env_vars.update(os.environ)
1631+
return add_env_vars
1632+
1633+
elif replace_env_vars:
1634+
if not isinstance(replace_env_vars, dict):
1635+
raise TypeError(
1636+
"The variable 'replace_env_vars' should be a dict with env vars."
1637+
)
1638+
1639+
return replace_env_vars

tests/test_launcher.py

Lines changed: 36 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
is_valid_executable_path,
1414
launch_mapdl,
1515
save_ansys_path,
16+
update_env_vars,
1617
warn_uncommon_executable_path,
1718
)
1819
from ansys.mapdl.core.licensing import LICENSES
@@ -50,9 +51,6 @@
5051

5152
V150_EXEC = get_ansys_bin("150")
5253

53-
if not valid_versions:
54-
pytestmark = pytest.mark.skip("Requires MAPDL")
55-
5654
paths = [
5755
("/usr/dir_v2019.1/slv/ansys_inc/v211/ansys/bin/ansys211", 211),
5856
("C:/Program Files/ANSYS Inc/v202/ansys/bin/win64/ANSYS202.exe", 202),
@@ -63,6 +61,7 @@
6361
@pytest.mark.skipif(
6462
not get_start_instance(), reason="Skip when start instance is disabled"
6563
)
64+
@pytest.mark.skipif(not valid_versions, reason="Requires MAPDL installed.")
6665
@pytest.mark.skipif(os.name != "nt", reason="Requires Windows")
6766
def test_validate_sw():
6867
# ensure that windows adds msmpi
@@ -75,6 +74,7 @@ def test_validate_sw():
7574
@pytest.mark.skipif(
7675
not get_start_instance(), reason="Skip when start instance is disabled"
7776
)
77+
@pytest.mark.skipif(not valid_versions, reason="Requires MAPDL installed.")
7878
@pytest.mark.parametrize("path_data", paths)
7979
def test_version_from_path(path_data):
8080
exec_file, version = path_data
@@ -84,6 +84,7 @@ def test_version_from_path(path_data):
8484
@pytest.mark.skipif(
8585
not get_start_instance(), reason="Skip when start instance is disabled"
8686
)
87+
@pytest.mark.skipif(not valid_versions, reason="Requires MAPDL installed.")
8788
def test_catch_version_from_path():
8889
with pytest.raises(RuntimeError):
8990
_version_from_path("abc")
@@ -92,8 +93,8 @@ def test_catch_version_from_path():
9293
@pytest.mark.skipif(
9394
not get_start_instance(), reason="Skip when start instance is disabled"
9495
)
96+
@pytest.mark.skipif(not valid_versions, reason="Requires MAPDL installed.")
9597
@pytest.mark.skipif(os.name != "posix", reason="Requires Linux")
96-
@pytest.mark.skipif(not versions, reason="Requires ANSYS install")
9798
def test_find_ansys_linux():
9899
# assuming ansys is installed, should be able to find it on linux
99100
# without env var
@@ -105,6 +106,7 @@ def test_find_ansys_linux():
105106
@pytest.mark.skipif(
106107
not get_start_instance(), reason="Skip when start instance is disabled"
107108
)
109+
@pytest.mark.skipif(not valid_versions, reason="Requires MAPDL installed.")
108110
def test_invalid_mode():
109111
with pytest.raises(ValueError):
110112
exec_file = get_ansys_bin(valid_versions[0])
@@ -114,6 +116,7 @@ def test_invalid_mode():
114116
@pytest.mark.skipif(
115117
not get_start_instance(), reason="Skip when start instance is disabled"
116118
)
119+
@pytest.mark.skipif(not valid_versions, reason="Requires MAPDL installed.")
117120
@pytest.mark.skipif(not os.path.isfile(V150_EXEC), reason="Requires v150")
118121
def test_old_version():
119122
exec_file = get_ansys_bin("150")
@@ -124,6 +127,7 @@ def test_old_version():
124127
@pytest.mark.skipif(
125128
not get_start_instance(), reason="Skip when start instance is disabled"
126129
)
130+
@pytest.mark.skipif(not valid_versions, reason="Requires MAPDL installed.")
127131
@pytest.mark.skipif(not os.name == "nt", reason="Requires windows")
128132
@pytest.mark.console
129133
def test_failed_console():
@@ -135,6 +139,7 @@ def test_failed_console():
135139
@pytest.mark.skipif(
136140
not get_start_instance(), reason="Skip when start instance is disabled"
137141
)
142+
@pytest.mark.skipif(not valid_versions, reason="Requires MAPDL installed.")
138143
@pytest.mark.parametrize("version", valid_versions)
139144
@pytest.mark.console
140145
@pytest.mark.skipif(os.name != "posix", reason="Only supported on Linux")
@@ -147,6 +152,7 @@ def test_launch_console(version):
147152
@pytest.mark.skipif(
148153
not get_start_instance(), reason="Skip when start instance is disabled"
149154
)
155+
@pytest.mark.skipif(not valid_versions, reason="Requires MAPDL installed.")
150156
@pytest.mark.corba
151157
@pytest.mark.parametrize("version", valid_versions)
152158
def test_launch_corba(version):
@@ -163,6 +169,7 @@ def test_launch_corba(version):
163169
@pytest.mark.skipif(
164170
not get_start_instance(), reason="Skip when start instance is disabled"
165171
)
172+
@pytest.mark.skipif(not valid_versions, reason="Requires MAPDL installed.")
166173
def test_license_type_keyword():
167174
# This test might became a way to check available licenses, which is not the purpose.
168175

@@ -189,6 +196,7 @@ def test_license_type_keyword():
189196
@pytest.mark.skipif(
190197
not get_start_instance(), reason="Skip when start instance is disabled"
191198
)
199+
@pytest.mark.skipif(not valid_versions, reason="Requires MAPDL installed.")
192200
def test_license_type_keyword_names():
193201
# This test might became a way to check available licenses, which is not the purpose.
194202

@@ -209,6 +217,7 @@ def test_license_type_keyword_names():
209217
@pytest.mark.skipif(
210218
not get_start_instance(), reason="Skip when start instance is disabled"
211219
)
220+
@pytest.mark.skipif(not valid_versions, reason="Requires MAPDL installed.")
212221
def test_license_type_additional_switch():
213222
# This test might became a way to check available licenses, which is not the purpose.
214223
successful_check = False
@@ -233,6 +242,7 @@ def test_license_type_additional_switch():
233242
mapdl.exit()
234243

235244

245+
@pytest.mark.skipif(not valid_versions, reason="Requires MAPDL installed.")
236246
@pytest.mark.parametrize(
237247
"exe_loc",
238248
[
@@ -246,6 +256,7 @@ def test_save_ansys_path(exe_loc):
246256
assert os.path.exists(path_)
247257

248258

259+
@pytest.mark.skipif(not valid_versions, reason="Requires MAPDL installed.")
249260
@pytest.mark.parametrize(
250261
"file,result",
251262
[
@@ -265,6 +276,7 @@ def test_is_valid_executable_path(tmpdir, file, result):
265276
assert is_valid_executable_path(filename) == result
266277

267278

279+
@pytest.mark.skipif(not valid_versions, reason="Requires MAPDL installed.")
268280
@pytest.mark.parametrize(
269281
"file_path,result",
270282
[
@@ -301,6 +313,26 @@ def test_warn_uncommon_executable_path():
301313
warn_uncommon_executable_path("")
302314

303315

316+
def test_env_injection():
317+
318+
assert update_env_vars(None, None) is None
319+
320+
assert "myenvvar" in update_env_vars({"myenvvar": "True"}, None)
321+
322+
_env_vars = update_env_vars(None, {"myenvvar": "True"})
323+
assert len(_env_vars) == 1
324+
assert "myenvvar" in _env_vars
325+
326+
with pytest.raises(ValueError):
327+
update_env_vars({"myenvvar": "True"}, {"myenvvar": "True"})
328+
329+
with pytest.raises(TypeError):
330+
update_env_vars("asdf", None)
331+
332+
with pytest.raises(TypeError):
333+
update_env_vars(None, "asdf")
334+
335+
304336
@pytest.mark.requires_gui
305337
def test_open_gui(mapdl):
306338

0 commit comments

Comments
 (0)