Skip to content

Commit 82789a1

Browse files
janvonrickenbachroosregreschd
authored
Set env vars for licensing (#230)
* Set env vars for licensing * Fix name arg * Improve load_composites_plugin * pre-commit checks * switch to dpf_composites:latest * Update tests/conftest.py Co-authored-by: Dominik Gresch <[email protected]> --------- Co-authored-by: Rene Roos <[email protected]> Co-authored-by: Dominik Gresch <[email protected]>
1 parent 7b29e9f commit 82789a1

File tree

6 files changed

+93
-35
lines changed

6 files changed

+93
-35
lines changed

.github/workflows/ci_cd.yml

Lines changed: 17 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -89,14 +89,18 @@ jobs:
8989
# Only the tox environment specified in the tox.ini gh-actions is run
9090
run: |
9191
tox
92-
93-
- name: "Upload server output"
94-
if: always()
95-
uses: actions/upload-artifact@v3
96-
with:
97-
name: server_output
98-
path: tests/logs/*_log_*.txt
99-
retention-days: 7
92+
env:
93+
LICENSE_SERVER: ${{ secrets.LICENSE_SERVER }}
94+
95+
# enable for debugging purposes. Ensure that the output does not contain
96+
# pipeline secrets.
97+
# - name: "Upload server output"
98+
# if: always()
99+
# uses: actions/upload-artifact@v3
100+
# with:
101+
# name: server_output
102+
# path: tests/logs/*_log_*.txt
103+
# retention-days: 7
100104

101105
tests_minimal_version:
102106
name: "Test with lower-bound dependency versions"
@@ -123,7 +127,10 @@ jobs:
123127
python -m pip install --upgrade poetry
124128
125129
- name: Test with tox
126-
run: tox -e test-minimal
130+
run: |
131+
tox -e test-minimal
132+
env:
133+
LICENSE_SERVER: ${{ secrets.LICENSE_SERVER }}
127134

128135
doc-build:
129136
name: "Documentation build"
@@ -144,7 +151,7 @@ jobs:
144151
- name: "Pull and start dpf container"
145152
run: |
146153
docker pull ghcr.io/pyansys/pydpf-composites:${{ env.CONTAINER_TAG }}
147-
docker run -d --restart always -p 21002:50052 ghcr.io/pyansys/pydpf-composites:${{ env.CONTAINER_TAG }}
154+
docker run -d --restart always -p 21002:50052 -e ANSYSLMD_LICENSE_FILE=1055@${{ secrets.LICENSE_SERVER }} -e ANSYS_DPF_ACCEPT_LA=Y ghcr.io/pyansys/pydpf-composites:${{ env.CONTAINER_TAG }}
148155
149156
- name: "Checkout the project"
150157
uses: actions/checkout@v3

README.rst

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,9 @@ Test
103103

104104
The Docker container referenced in the first option is not yet publicly available.
105105

106+
Set the environment variable `ANSYSLMD_LICENSE_FILE` to configure the licensing or pass it
107+
as argument (`--license-server=1055@mylicenseserver`) to the pytest call.
108+
106109
There are three ways to run the PyDPF Composites tests, depending on how the DPF
107110
server is started.
108111

@@ -147,7 +150,7 @@ On Windows, build documentation with this code:
147150
.. code:: bash
148151
149152
docker pull ghcr.io/pyansys/pydpf-composites:latest
150-
docker run -d -p 21002:50052 ghcr.io/pyansys/pydpf-composites:latest
153+
docker run -d -p 21002:50052 -e ANSYSLMD_LICENSE_FILE=10555@mylicserver -e ANSYS_DPF_ACCEPT_LA=Y ghcr.io/pyansys/pydpf-composites:latest
151154
tox -e doc-windows
152155
153156
@@ -156,7 +159,7 @@ On Linux, build documentation with this code:
156159
.. code:: bash
157160
158161
docker pull ghcr.io/pyansys/pydpf-composites:latest
159-
docker run -d -p 21002:50052 ghcr.io/pyansys/pydpf-composites:latest
162+
docker run -d -p 21002:50052 -e ANSYSLMD_LICENSE_FILE=10555@mylicserver -e ANSYS_DPF_ACCEPT_LA=Y ghcr.io/pyansys/pydpf-composites:latest
160163
tox -e doc-linux
161164
162165

src/ansys/dpf/composites/server_helpers/_connect_to_or_start_server.py

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -75,9 +75,11 @@ def connect_to_or_start_server(
7575
connect_kwargs["ip"] = ip
7676

7777
if len(list(connect_kwargs.keys())) > 0:
78-
server = connect_to_server(**connect_kwargs)
79-
server.apply_context(
80-
_dpf_server.server_context.ServerContext(server_context.LicensingContextType.premium)
78+
server = connect_to_server(
79+
**connect_kwargs,
80+
context=_dpf_server.server_context.ServerContext(
81+
server_context.LicensingContextType.premium
82+
),
8183
)
8284
else:
8385
server = start_local_server(
Lines changed: 29 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,14 @@
11
"""Helper to load composites plugin."""
22
import os
3+
import pathlib
34
from typing import Optional
45

56
import ansys.dpf.core as dpf
7+
from ansys.dpf.core.misc import get_ansys_path
68
from ansys.dpf.core.server_types import BaseServer
79

10+
AWP_ROOT_DOCKER = "/ansys_inc/ansys/dpf/server_2023_2_pre1"
11+
812

913
def load_composites_plugin(server: BaseServer, ansys_path: Optional[str] = None) -> None:
1014
r"""Load composites plugins and its dependencies.
@@ -13,20 +17,15 @@ def load_composites_plugin(server: BaseServer, ansys_path: Optional[str] = None)
1317
----------
1418
server:
1519
ansys_path:
16-
Ansys root path, for example C:\Program Files\ANSYS Inc\v231.
20+
Ansys root path, for example C:\Program Files\ANSYS Inc\v232.
1721
If None, it is assumed that all the plugins and their dependencies
1822
are found in the PATH/LD_LIBRARY_PATH. If ansys_path
1923
is set, the composite_operators and
2024
Ans.Dpf.EngineeringData plugins are loaded from their location
2125
in the installer.
2226
"""
23-
# The native plugins need to be loaded because currently,
24-
# they are not automatically loaded
25-
# in the docker container.
26-
# Once we use the dpf core container, that probably already
27-
# loads these plugins by default,
28-
# we only need to load composite_operators
29-
# and Ans.Dpf.EngineeringData.
27+
# The automatic load of the plug can be disabled by the user and so
28+
# all plugins which are required for dpf composites are loaded
3029
libs = [
3130
"Ans.Dpf.Native",
3231
"mapdlOperatorsCore",
@@ -48,17 +47,31 @@ def get_lib_from_name(name: str) -> str:
4847
"nt": ["dpf", "plugins", "dpf_composites"],
4948
"posix": ["dpf", "plugins", "dpf_composites"],
5049
},
51-
"Ans.Dpf.EngineeringData": {
52-
"nt": ["dpf", "bin", "winx64"],
53-
"posix": ["dpf", "bin", "linx64"],
54-
},
5550
}
5651

52+
# March 2023 R.Roos
53+
# the dpf load_plugin method requires an absolute path because the dfp_composites
54+
# plugin is not in the search path. The logic below should support all cases
55+
# except a local gRPC sever on linux (local in-process server on Linux is supported)
56+
# DPF core team thinks about to expose ANSYS_ROOT_FOLDER so that the absolute path
57+
# can be easily constructed here.
58+
if not ansys_path:
59+
if server.ansys_path:
60+
ansys_path = server.ansys_path
61+
elif server.os == "posix":
62+
ansys_path = AWP_ROOT_DOCKER
63+
else:
64+
ansys_path = get_ansys_path()
65+
66+
if not ansys_path:
67+
raise RuntimeError("Ansys path is not available. DPF Composites plugin cannot be loaded.")
68+
5769
for name in libs:
58-
if ansys_path is not None and name in location_in_installer:
59-
relative_installer_location = location_in_installer[name][server.os]
60-
absolute_installer_location = os.path.join(ansys_path, *relative_installer_location)
61-
library = os.path.join(absolute_installer_location, get_lib_from_name(name))
70+
if name in location_in_installer:
71+
relative_location = location_in_installer[name][server.os]
72+
library = os.path.join(ansys_path, *relative_location, get_lib_from_name(name))
73+
if server.os == "posix":
74+
library = pathlib.Path(library).as_posix()
6275
else:
6376
library = get_lib_from_name(name)
6477
dpf.load_library(library, name, server=server)

tests/conftest.py

Lines changed: 35 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,8 @@
2525
SERVER_BIN_OPTION_KEY = "--server-bin"
2626
PORT_OPTION_KEY = "--port"
2727
ANSYS_PATH_OPTION_KEY = "--ansys-path"
28+
LICENSE_SERVER_OPTION_KEY = "--license-server"
29+
ANSYSLMD_LICENSE_FILE_KEY = "ANSYSLMD_LICENSE_FILE"
2830

2931

3032
def pytest_addoption(parser: pytest.Parser) -> None:
@@ -49,6 +51,12 @@ def pytest_addoption(parser: pytest.Parser) -> None:
4951
r"Example: C:\Program Files\Ansys Inc\v231",
5052
)
5153

54+
parser.addoption(
55+
LICENSE_SERVER_OPTION_KEY,
56+
action="store",
57+
help="Value of the ANSYSLMD_LICENSE_FILE for the gRPC server.",
58+
)
59+
5260

5361
ServerContext = namedtuple("ServerContext", ["port", "platform", "server"])
5462

@@ -62,16 +70,22 @@ def __enter__(self):
6270
cmd += ["-v", f"/{pathlib.Path(source_dir).as_posix().replace(':', '')}:{target_dir}"]
6371
if sys.platform == "linux":
6472
cmd += ["-u", f"{os.getuid()}:{os.getgid()}"]
73+
6574
cmd += [
6675
"-p",
6776
f"{self.port}:50052/tcp",
6877
"-e",
69-
"HOME=/home/container",
78+
"HOME=/tmp",
79+
"-e",
80+
"ANSYS_DPF_ACCEPT_LA=Y",
81+
"-e",
82+
f"{ANSYSLMD_LICENSE_FILE_KEY}={self.license_server}",
7083
"--name",
7184
self.name,
7285
self.image_name,
7386
]
74-
self.process_stdout.write(f"Starting docker container: {cmd}\n\n")
87+
# ensure that the output does not contain any pipeline secrets
88+
# self.process_stdout.write(f"Starting docker container: {cmd}\n\n")
7589
self.server_process = subprocess.Popen(
7690
cmd,
7791
stdout=self.server_stdout,
@@ -92,6 +106,7 @@ def __init__(
92106
server_err_file: pathlib.Path,
93107
process_out_file: pathlib.Path,
94108
process_err_file: pathlib.Path,
109+
license_server: str = "",
95110
image_name: str = "ghcr.io/pyansys/pydpf-composites:latest",
96111
mount_directories: Mapping[str, str] = MappingProxyType({}),
97112
):
@@ -104,6 +119,8 @@ def __init__(
104119
Local directories which should be mounted to the Docker container.
105120
The keys contain the path in the context of the host, and the
106121
values are the paths as they should appear inside the container.
122+
license_server:
123+
Definition of the license server. E.g. 1055@my_ansys_license_server
107124
server_out_file :
108125
Path (on the host) to which the output of ``docker run`` is redirected.
109126
server_err_file :
@@ -124,6 +141,7 @@ def __init__(
124141
self.process_stderr = open(process_err_file, mode="w", encoding="utf-8")
125142
self.name = str(uuid.uuid4())
126143
self.mount_directories = mount_directories
144+
self.license_server = license_server
127145
self.image_name = image_name
128146

129147
def __exit__(
@@ -268,6 +286,19 @@ def dpf_server(request: pytest.FixtureRequest):
268286
server_bin = request.config.getoption(SERVER_BIN_OPTION_KEY)
269287
running_server_port = request.config.getoption(PORT_OPTION_KEY)
270288
installer_path = request.config.getoption(ANSYS_PATH_OPTION_KEY)
289+
license_server = request.config.getoption(LICENSE_SERVER_OPTION_KEY)
290+
291+
if not license_server:
292+
if ANSYSLMD_LICENSE_FILE_KEY in os.environ.keys():
293+
license_server = os.environ[ANSYSLMD_LICENSE_FILE_KEY]
294+
else:
295+
raise RuntimeError(
296+
"License server not set. Either run test with --license-server of "
297+
f" set ENV {ANSYSLMD_LICENSE_FILE_KEY}."
298+
)
299+
300+
if "@" not in license_server:
301+
license_server = "1055@" + license_server
271302

272303
active_options = [
273304
option for option in [installer_path, server_bin, running_server_port] if option is not None
@@ -289,11 +320,13 @@ def start_server_process():
289320

290321
process_log_stdout = TEST_ROOT_DIR / "logs" / f"process_log_out-{uid}.txt"
291322
process_log_stderr = TEST_ROOT_DIR / "logs" / f"process_log_err-{uid}.txt"
323+
292324
return DockerProcess(
293325
server_out_file=server_log_stdout,
294326
server_err_file=server_log_stderr,
295327
process_out_file=process_log_stdout,
296328
process_err_file=process_log_stderr,
329+
license_server=license_server,
297330
)
298331

299332
with start_server_process() as server_process:

tox.ini

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ setenv =
3131
coverage: PYTEST_EXTRA_ARGS = --cov=ansys.dpf.composites --cov-report=term --cov-report=xml --cov-report=html
3232
commands =
3333
poetry install -E test
34-
poetry run pytest {env:PYTEST_MARKERS:} {env:PYTEST_EXTRA_ARGS:} {posargs:-vv}
34+
poetry run pytest --license-server={env:LICENSE_SERVER:} {env:PYTEST_MARKERS:} {env:PYTEST_EXTRA_ARGS:} {posargs:-vv}
3535

3636
[testenv:test-minimal]
3737
description = Checks for project unit tests with minimal package versions
@@ -45,7 +45,7 @@ setenv =
4545
commands =
4646
poetry install -E test
4747
poetry run python -m pip install -r minimum_requirements.txt
48-
poetry run pytest {env:PYTEST_MARKERS:} {posargs:-vv}
48+
poetry run pytest --license-server={env:LICENSE_SERVER:} {env:PYTEST_MARKERS:} {posargs:-vv}
4949

5050
[testenv:style]
5151
description = Checks project code style

0 commit comments

Comments
 (0)