Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
64 commits
Select commit Hold shift + click to select a range
cd0cbd2
fix: add codecove
Revathyvenugopal162 Sep 17, 2025
e17ab22
fix: add codecov secrets
Revathyvenugopal162 Sep 17, 2025
64513b5
fix: combine coverage
Revathyvenugopal162 Sep 18, 2025
f1083cc
fix: combine coverage
Revathyvenugopal162 Sep 18, 2025
b934919
fix: cicd
Revathyvenugopal162 Sep 18, 2025
d13f88d
chore: adding changelog file 909.added.md [dependabot-skip]
pyansys-ci-bot Sep 18, 2025
a2093d0
fix: comment preline now
Revathyvenugopal162 Sep 18, 2025
cde942e
Merge branch 'feat/codecov' of https://github.com/ansys/pydyna into f…
Revathyvenugopal162 Sep 18, 2025
09a23fb
fix: update the python
Revathyvenugopal162 Sep 18, 2025
bf24bda
fix: update the python
Revathyvenugopal162 Sep 18, 2025
608f277
fix: update the image
Revathyvenugopal162 Sep 18, 2025
8657c42
fix: update the actions
Revathyvenugopal162 Sep 18, 2025
5e129d5
fix: update the actions
Revathyvenugopal162 Sep 18, 2025
60f143a
fix: update the cicd
Revathyvenugopal162 Sep 18, 2025
4698cf2
fix: update the cicd
Revathyvenugopal162 Sep 18, 2025
0af52f0
fix: update the cicd
Revathyvenugopal162 Sep 18, 2025
c8650b0
fix: update the cicd for keyword matrix
Revathyvenugopal162 Sep 18, 2025
99c9c05
fix: update the cicd for keyword matrix
Revathyvenugopal162 Sep 18, 2025
c86bb99
fix: update the cicd for keyword matrix
Revathyvenugopal162 Sep 18, 2025
7b3151a
fix: update the cicd for al tests
Revathyvenugopal162 Sep 18, 2025
2a30856
Merge branch 'main' into feat/codecov
Revathyvenugopal162 Sep 18, 2025
670caf0
fix: test viz
Revathyvenugopal162 Sep 19, 2025
5b73796
fix: coverage results
Revathyvenugopal162 Sep 19, 2025
8d72371
fix: test early
Revathyvenugopal162 Sep 19, 2025
671272f
fix: test early
Revathyvenugopal162 Sep 19, 2025
f163bfb
fix: test early
Revathyvenugopal162 Sep 19, 2025
a61671d
fix: coverage files
Revathyvenugopal162 Sep 19, 2025
19b6970
fix: coverage files
Revathyvenugopal162 Sep 19, 2025
7e894d1
fix: coverage files
Revathyvenugopal162 Sep 19, 2025
7cffe17
fix: coverage files
Revathyvenugopal162 Sep 19, 2025
e5705ed
fix: coverage files and results
Revathyvenugopal162 Sep 19, 2025
af1ff53
fix: coverage files and results
Revathyvenugopal162 Sep 19, 2025
4c626a5
fix: coverage files and results
Revathyvenugopal162 Sep 19, 2025
fcfc2ef
fix: coverage files without keywords
Revathyvenugopal162 Sep 19, 2025
09f1956
fix: coverage files without keywords
Revathyvenugopal162 Sep 19, 2025
75d5706
fix: coverage files without keywords
Revathyvenugopal162 Sep 19, 2025
9e5b6f9
fix: coverage files without keywords
Revathyvenugopal162 Sep 19, 2025
c1589b0
fix: coverage files without keywords
Revathyvenugopal162 Sep 19, 2025
92bd673
fix: coverage files
Revathyvenugopal162 Sep 19, 2025
aab7908
fix: overage files name
Revathyvenugopal162 Sep 22, 2025
679d269
fix: overage files name
Revathyvenugopal162 Sep 22, 2025
e8ca676
fix: overage files name
Revathyvenugopal162 Sep 22, 2025
5471826
fix: coverage files
Revathyvenugopal162 Sep 22, 2025
1e78092
fix: coverage files
Revathyvenugopal162 Sep 22, 2025
76fb2f8
fix: coverage files
Revathyvenugopal162 Sep 22, 2025
ecf7e6d
fix: coverage files
Revathyvenugopal162 Sep 22, 2025
c018952
fix: coverage files
Revathyvenugopal162 Sep 22, 2025
ecd3fbb
fix: coverage files
Revathyvenugopal162 Sep 22, 2025
9a32b2d
fix: coverage files
Revathyvenugopal162 Sep 22, 2025
fb67ead
fix: coverage files
Revathyvenugopal162 Sep 22, 2025
6c1d65e
fix: coverage files zip
Revathyvenugopal162 Sep 23, 2025
a4d3036
fix: coverage files zip
Revathyvenugopal162 Sep 23, 2025
257601d
fix: coverage files zip files
Revathyvenugopal162 Sep 23, 2025
bdba626
fix: coverage files zip files
Revathyvenugopal162 Sep 23, 2025
347df57
fix: coverage to codecov
Revathyvenugopal162 Sep 23, 2025
2460d4c
fix: different coveage
Revathyvenugopal162 Sep 23, 2025
f1f3ad8
fix: different coveage to codecov
Revathyvenugopal162 Sep 23, 2025
9059bd7
Merge branch 'main' into feat/codecov
Revathyvenugopal162 Sep 23, 2025
cfc9424
fix: different coveage to codecov
Revathyvenugopal162 Sep 23, 2025
3b8a9dc
Merge branch 'feat/codecov' of https://github.com/ansys/pydyna into f…
Revathyvenugopal162 Sep 23, 2025
6990a8b
fix: different coveage flag settings
Revathyvenugopal162 Sep 24, 2025
f40a203
fix: update the cicd
Revathyvenugopal162 Sep 24, 2025
c65de8e
fix: update the indent
Revathyvenugopal162 Sep 24, 2025
04d9c78
fix: update the test for windows runner
Revathyvenugopal162 Sep 24, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 26 additions & 8 deletions .github/actions/unit-test/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,18 @@ inputs:
default: ""
type: string

codecov-token:
description: Token for Codecov upload
required: false
default: ""
type: string

coverage-file:
description: Coverage file path
required: false
default: ""
type: string

runs:
using: "composite"
steps:
Expand Down Expand Up @@ -72,9 +84,9 @@ runs:
- name: Run pytest
run: |
if [ "${{ inputs.pytest-markers }}" = "" ]; then
pytest
pytest -ra --cov=ansys.dyna.core --cov-report html:.cov/html --cov-report xml:.cov/xml --cov-report term -vv
else
pytest -m "${{ inputs.pytest-markers }}"
pytest -m "${{ inputs.pytest-markers }}" -ra --cov=ansys.dyna.core --cov-report html:.cov/html --cov-report xml:.cov/xml --cov-report term -vv
fi
shell: bash
env:
Expand All @@ -96,10 +108,16 @@ runs:
name: server_output_tests.txt
path: server_output.txt

- name: Upload coverage results
if: ${{ inputs.server-logs == 'true' }}
uses: actions/upload-artifact@v4
- name: Upload coverage to Codecov
uses: codecov/codecov-action@5a1091511ad55cbe89839c7260b706298ca349f7 # v5.5.1
env:
CODECOV_TOKEN: ${{ inputs.codecov-token }}
with:
name: coverage-html
path: .cov/html
retention-days: 7
flags: ${{ inputs.coverage-file }}

- name: Stop container
if: ${{ inputs.docker-image != '' && inputs.pytest-markers != 'keywords' }}
run: |
docker stop kw_server
docker rm kw_server
shell: bash
48 changes: 27 additions & 21 deletions .github/workflows/ci_cd_pr.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ env:
PACKAGE_NAMESPACE: 'ansys.dyna.core'
DOCUMENTATION_CNAME: "dyna.docs.pyansys.com"
PYDYNA_RUN_CONTAINER: ${{ github.event.inputs.PyDynaRunContainer || 'ghcr.io/ansys/pydyna-run:latest'}}
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}

concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
Expand Down Expand Up @@ -148,13 +149,32 @@ jobs:
library-name: ${{ env.PACKAGE_NAME }}
operating-system: ${{ matrix.os }}
python-version: ${{ matrix.python-version }}


keyword-testing:
name: "Keyword testing for matrix"
needs: [smoke-tests]
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
os: [ubuntu-latest, windows-latest]
python-version: ['3.10', '3.11', '3.12', '3.13']
steps:
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0

- name: Run test with "keywords" marker
uses: ./.github/actions/unit-test
with:
python-version: ${{ matrix.python-version }}
github-token: ${{ secrets.GITHUB_TOKEN }}
pytest-markers: keywords
coverage-file: keywords

run-testing:
name: Test the "run" subpackage
runs-on: ubuntu-latest
needs: [smoke-tests]

steps:
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0

Expand All @@ -166,36 +186,22 @@ jobs:
docker-image: ${{ env.PYDYNA_RUN_CONTAINER }}
pytest-markers: run
license-server: ${{ secrets.LICENSE_SERVER }}

keyword-testing:
name: "Keyword testing"
runs-on: ${{ matrix.os }}
needs: [smoke-tests]
strategy:
fail-fast: false
matrix:
os: [ubuntu-latest, windows-latest]
python-version: ['3.10', '3.11', '3.12', '3.13']
steps:
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0

- uses: ./.github/actions/unit-test
with:
python-version: ${{ matrix.python-version }}
github-token: ${{ secrets.GITHUB_TOKEN }}
pytest-markers: keywords
coverage-file: run

unit-tests:
name: "Testing"
runs-on: ubuntu-latest
needs: [run-testing, keyword-testing]
needs: [keyword-testing, run-testing, codegen-testing]
steps:
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
- uses: ./.github/actions/unit-test
- name: Run test without marker
uses: ./.github/actions/unit-test
with:
python-version: ${{ env.MAIN_PYTHON_VERSION }}
github-token: ${{ secrets.GITHUB_TOKEN }}
server-logs: true
codecov-token: ${{ env.CODECOV_TOKEN }}
coverage-file: unittests

build-library:
name: "Build library"
Expand Down
43 changes: 43 additions & 0 deletions codecov.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
coverage:
range: 75..100
round: down
precision: 2
status:
project:
default:
target: 90%
patch: off


codecov:
notify:
wait_for_ci: yes

flag_management:
default_rules: # the rules that will be followed for any flag added, generally
carryforward: true
statuses:
- type: project
target: auto
threshold: 1%
- type: patch
target: 90%
individual_flags: # exceptions to the default rules above, stated flag by flag
- name: run
paths:
- src/ansys/dyna/core/run
carryforward: true
statuses:
- type: project
target: 20%
- type: patch
target: 100%
- name: keywords
paths:
- src/ansys/dyna/core/keywords #fill in your own path. Note, accepts globs, not regexes
carryforward: true
statuses:
- type: project
target: 20%
- type: patch
target: 100%
1 change: 1 addition & 0 deletions doc/changelog/909.added.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Add coverage
3 changes: 3 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,9 @@ src_paths = ["doc", "src", "tests"]

[tool.coverage.run]
source = ["ansys.dyna.core"]
omit = [
"src/ansys/dyna/core/keywords/keyword_classes/auto/*"
]

[tool.coverage.report]
show_missing = true
Expand Down
136 changes: 136 additions & 0 deletions tests/test_windows_runner.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,136 @@
import pytest
from pathlib import Path
from unittest.mock import MagicMock, patch

import ansys.dyna.core.run.windows_runner as windows_runner
from ansys.dyna.core.run.options import MpiOption, Precision


@pytest.fixture
def tmp_workdir(tmp_path):
return tmp_path


def make_runner(tmp_workdir, mpi=MpiOption.SMP, precision=Precision.SINGLE):
# create dummy solver executable
exe = tmp_workdir / "lsdyna.exe"
exe.write_text("dummy")

runner = windows_runner.WindowsRunner(executable=str(exe))
runner.mpi_option = mpi
runner.precision = precision
runner.input_file = "input.k"
runner.working_directory = str(tmp_workdir)
runner.ncpu = 4
runner.get_memory_string = MagicMock(return_value="2000m")
return runner


def test_find_solver_with_explicit_executable(tmp_workdir):
exe = tmp_workdir / "lsdyna.exe"
exe.write_text("dummy")

runner = windows_runner.WindowsRunner(executable=str(exe))
assert runner.solver_location == str(tmp_workdir)
assert runner.solver.endswith("lsdyna.exe\"")


@patch("ansys.dyna.core.run.windows_runner._get_unified_install_base_for_version")
def test_find_solver_with_version(mock_install_base, tmp_workdir):
exe = tmp_workdir / "ansys" / "bin" / "winx64" / "lsdyna_sp.exe"
exe.parent.mkdir(parents=True)
exe.write_text("dummy")

mock_install_base.return_value = (tmp_workdir, None)
runner = windows_runner.WindowsRunner(version=241, precision=Precision.SINGLE)
assert runner.solver.endswith("lsdyna_sp.exe\"")

def test_find_solver_executable_not_found(tmp_workdir):
with pytest.raises(FileNotFoundError):
windows_runner.WindowsRunner(executable=str(tmp_workdir / "missing.exe"))


@pytest.mark.parametrize(
"mpi,prec,expected",
[
(MpiOption.SMP, Precision.SINGLE, "lsdyna_sp.exe"),
(MpiOption.SMP, Precision.DOUBLE, "lsdyna_dp.exe"),
(MpiOption.MPP_INTEL_MPI, Precision.SINGLE, "lsdyna_mpp_sp_impi.exe"),
(MpiOption.MPP_INTEL_MPI, Precision.DOUBLE, "lsdyna_mpp_dp_impi.exe"),
(MpiOption.MPP_MS_MPI, Precision.SINGLE, "lsdyna_mpp_sp_msmpi.exe"),
(MpiOption.MPP_MS_MPI, Precision.DOUBLE, "lsdyna_mpp_dp_msmpi.exe"),
],
)
def test_get_exe_name_variants(tmp_workdir, mpi, prec, expected):
runner = make_runner(tmp_workdir, mpi, prec)
assert runner._get_exe_name() == expected


def test_get_env_script_intel(tmp_workdir):
runner = make_runner(tmp_workdir, MpiOption.MPP_INTEL_MPI)
(tmp_workdir / "lsprepost_foo").mkdir()
script = runner._get_env_script()
assert script.endswith("lsdynaintelvar.bat")


def test_write_runscript(tmp_workdir):
runner = make_runner(tmp_workdir)
runner._get_command_line = MagicMock(return_value="echo hello")
runner._write_runscript()
script_path = tmp_workdir / runner._scriptname
assert "echo hello" in script_path.read_text()


@patch("ansys.dyna.core.run.windows_runner.subprocess.Popen")
def test_run_success(mock_popen, tmp_workdir):
runner = make_runner(tmp_workdir)
runner._get_command_line = MagicMock(return_value="echo hello")

process = MagicMock()
process.poll.side_effect = [None, 0]
process.wait.return_value = 0
process.returncode = 0
mock_popen.return_value = process

# fake log file
log_file = tmp_workdir / "lsrun.out.txt"
log_file.write_text("all good\n")

runner.run()
assert process.wait.called


@patch("ansys.dyna.core.run.windows_runner.subprocess.Popen")
def test_run_with_warning_logs(mock_popen, tmp_workdir, caplog):
runner = make_runner(tmp_workdir)
runner._get_command_line = MagicMock(return_value="echo hello")

process = MagicMock()
process.poll.side_effect = [None, 0]
process.wait.return_value = 0
process.returncode = 0
mock_popen.return_value = process

log_file = tmp_workdir / "lsrun.out.txt"
log_file.write_text("Warning: something\n")

runner.run()
assert "completed with warnings" in caplog.text


@patch("ansys.dyna.core.run.windows_runner.subprocess.Popen")
def test_run_failure(mock_popen, tmp_workdir):
runner = make_runner(tmp_workdir)
runner._get_command_line = MagicMock(return_value="echo hello")

process = MagicMock()
process.poll.side_effect = [0]
process.wait.return_value = 1
process.returncode = 1
mock_popen.return_value = process

log_file = tmp_workdir / "lsrun.out.txt"
log_file.write_text("Error: fail\n")

with pytest.raises(RuntimeError):
runner.run()
Loading