Skip to content

Commit

Permalink
ci: Infrastructure to run pyconsole tests in github
Browse files Browse the repository at this point in the history
  • Loading branch information
mkundu1 committed Oct 3, 2024
1 parent b0da2ea commit 48b3a5f
Show file tree
Hide file tree
Showing 8 changed files with 234 additions and 0 deletions.
116 changes: 116 additions & 0 deletions .ci/fluent_test_runner.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
"""Script to run Fluent test in Docker container."""

import argparse
import logging
import os
from pathlib import Path
from shutil import copytree
from tempfile import TemporaryDirectory
from time import sleep

import yaml

import ansys.fluent.core as pyfluent
import docker


class FluentRuntimeError(RuntimeError):
"""Exception raised when stderr is detected in Fluent output."""

pass


def run_fluent_test(journal_file: Path, launcher_args: str = "") -> None:
"""Run Fluent test.
Parameters
----------
journal_file : Path
Absolute path to the journal file.
launcher_args : str, optional
Additional arguments for the Fluent launcher.
Raises
------
FluentRuntimeError
Raised when stderr is detected in Fluent output.
"""
logging.debug(f"journal_file: {journal_file}")
src_pyfluent_dir = str(Path(pyfluent.__file__).parent)
dst_pyfluent_dir = "/ansys_inc/v251/commonfiles/CPython/3_10/linx64/Release/python/lib/python3.10/site-packages/ansys/fluent/core"
src_test_dir = str(journal_file.parent)
dst_test_dir = "/testing"
logging.debug(f"src_pyfluent_dir: {src_pyfluent_dir}")
logging.debug(f"dst_pyfluent_dir: {dst_pyfluent_dir}")
logging.debug(f"src_test_dir: {src_test_dir}")
logging.debug(f"dst_test_dir: {dst_test_dir}")

docker_client = docker.from_env()
image_name = "ghcr.io/ansys/pyfluent:v25.1.0"
container = docker_client.containers.run(
image=image_name,
volumes=[
f"{src_pyfluent_dir}:{dst_pyfluent_dir}",
f"{src_test_dir}:{dst_test_dir}",
],
working_dir=dst_test_dir,
environment={"ANSYSLMD_LICENSE_FILE": os.environ["ANSYSLMD_LICENSE_FILE"]},
command=f"3ddp {launcher_args} -gu -py -i {journal_file.name}",
detach=True,
stdout=True,
stderr=True,
)
while True:
container.reload()
if container.status == "exited":
break
stderr = container.logs(stdout=False, stderr=True)
if stderr:
stderr = stderr.decode()
for line in stderr.split("\n"):
if line.strip().startswith("Error:"):
if "Expected exception" in line: # for check_assert.py
container.stop()
else:
raise FluentRuntimeError(line)
sleep(1)
logging.debug(container.logs(stderr=True).decode())
container.remove()


MAX_TEST_PATH_LENGTH = 40


if __name__ == "__main__":
parser = argparse.ArgumentParser(description="Run Fluent test.")
parser.add_argument(
"test_dir",
help="Path to the Fluent test directory relative to the PyFluent repository root.",
)
args = parser.parse_args()
test_dir = Path.cwd() / args.test_dir
with TemporaryDirectory(ignore_cleanup_errors=True) as tmpdir:
copytree(test_dir, tmpdir, dirs_exist_ok=True)
exception_occurred = False
for test_file in Path(tmpdir).rglob("*.py"):
config_file = test_file.with_suffix(".yaml")
launcher_args = ""
if config_file.exists():
configs = yaml.safe_load(config_file.read_text())
launcher_args = configs.get("launcher_args", "")
test_file_relpath = str(test_file.relative_to(tmpdir))
print(f"Running {test_file_relpath}", end="", flush=True)
try:
run_fluent_test(test_file, launcher_args)
print(
f"{(MAX_TEST_PATH_LENGTH + 10 - len(test_file_relpath)) * '·'}PASSED"
)
except FluentRuntimeError as e:
print(
f"{(MAX_TEST_PATH_LENGTH + 10 - len(test_file_relpath)) * '·'}FAILED"
)
print(e)
exception_occurred = True
if exception_occurred:
exit(1)
79 changes: 79 additions & 0 deletions .github/workflows/test-fluent-tests.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
name: Test Fluent tests with PyFluent changes

on:
pull_request:
workflow_dispatch:

env:
ANSYSLMD_LICENSE_FILE: ${{ format('1055@{0}', secrets.LICENSE_SERVER) }}
PYFLUENT_TIMEOUT_FORCE_EXIT: 30
PYFLUENT_LAUNCH_CONTAINER: 1
PYFLUENT_LOGGING: 'DEBUG'
PYFLUENT_WATCHDOG_DEBUG: 'OFF'
PYFLUENT_HIDE_LOG_SECRETS: 1
MAIN_PYTHON_VERSION: '3.10'

jobs:
test:
name: Fluent Testing
runs-on: [self-hosted, pyfluent]
timeout-minutes: 120

steps:
- uses: actions/checkout@v4

- name: Setup Python
uses: actions/setup-python@v5
with:
python-version: ${{ env.MAIN_PYTHON_VERSION }}

- name: Cache pip
uses: actions/cache@v4
with:
path: ~/.cache/pip
key: Python-${{ runner.os }}-${{ matrix.python-version }}-${{ hashFiles('pyproject.toml') }}
restore-keys: |
Python-${{ runner.os }}-${{ matrix.python-version }}
- name: Add version information
run: make version-info

- name: Install pyfluent
run: make install

- name: Retrieve PyFluent version
run: |
echo "PYFLUENT_VERSION=$(python -c "from ansys.fluent.core import __version__; print(); print(__version__)" | tail -1)" >> $GITHUB_OUTPUT
echo "PYFLUENT version is: $(python -c "from ansys.fluent.core import __version__; print(); print(__version__)" | tail -1)"
id: version

- name: Login to GitHub Container Registry
uses: docker/login-action@v3
with:
registry: ghcr.io
username: ansys-bot
password: ${{ secrets.GITHUB_TOKEN }}

- name: Pull 25.1 Fluent docker image
run: make docker-pull
env:
FLUENT_IMAGE_TAG: v25.1.0

- name: Run 25.1 API codegen
run: make api-codegen
env:
FLUENT_IMAGE_TAG: v25.1.0

- name: Print 25.1 Fluent version info
run: |
cat src/ansys/fluent/core/generated/fluent_version_251.py
python -c "from ansys.fluent.core.generated.solver.settings_251 import SHASH; print(f'SETTINGS_HASH = {SHASH}')"
- name: Install again after codegen
run: |
rm -rf dist
make install > /dev/null
- name: Run Fluent tests
run: |
python .ci/fluent_test_runner.py tests/fluent
1 change: 1 addition & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,7 @@ tests = ["pytest", "pytest-cov", "pytest-mock", "pytest-xdist"]
[tool.pytest.ini_options]
testpaths = ["tests"]
addopts = """
--ignore=tests/fluent
-v
--durations=0
--show-capture=all
Expand Down
2 changes: 2 additions & 0 deletions tests/fluent/test_assert/test.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
assert False, "Expected exception"
exit()
21 changes: 21 additions & 0 deletions tests/fluent/test_meshing_workflow/test.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
from ansys.fluent.core.examples import download_file

geometry_file = download_file("mixing_elbow.pmdb", "pyfluent/mixing_elbow")
watertight = meshing.watertight()
watertight.import_geometry.file_name.set_state(geometry_file)
assert watertight.import_geometry.length_unit() == "mm"
watertight.import_geometry.length_unit = "in"
assert watertight.import_geometry.length_unit() == "in"
assert watertight.import_geometry.cad_import_options.feature_angle() == 40.0
watertight.import_geometry.cad_import_options.feature_angle.set_state(25.0)
assert watertight.import_geometry.cad_import_options.feature_angle() == 25.0
assert watertight.import_geometry.cad_import_options.one_zone_per.allowed_values() == [
"body",
"face",
"object",
]
assert watertight.import_geometry.cad_import_options.one_zone_per() == "body"
watertight.import_geometry.cad_import_options.one_zone_per = "face"
assert watertight.import_geometry.cad_import_options.one_zone_per() == "face"
watertight.import_geometry()
exit()
1 change: 1 addition & 0 deletions tests/fluent/test_meshing_workflow/test.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
launcher_args: -meshing
12 changes: 12 additions & 0 deletions tests/fluent/test_settings_api/test.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
from ansys.fluent.core.examples import download_file

case_name = download_file("mixing_elbow.cas.h5", "pyfluent/mixing_elbow")
solver.settings.file.read_case(file_name=case_name)
viscous_settings = solver.settings.setup.models.viscous
assert viscous_settings.model() == "k-omega"
allowed_values = viscous_settings.model.allowed_values()
assert "k-epsilon" in allowed_values
assert len(allowed_values) > 5
viscous_settings.model = "k-epsilon"
assert viscous_settings.model() == "k-epsilon"
exit()
2 changes: 2 additions & 0 deletions tests/fluent/test_version/test.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
assert ansys.fluent.core.__version__ == "0.27.dev0"
exit()

0 comments on commit 48b3a5f

Please sign in to comment.