diff --git a/.github/workflows/continuous-integration.yml b/.github/workflows/continuous-integration.yml index ae8d0ab61..d46d9e10d 100644 --- a/.github/workflows/continuous-integration.yml +++ b/.github/workflows/continuous-integration.yml @@ -15,7 +15,7 @@ jobs: strategy: fail-fast: false matrix: - os: [ ubuntu-latest ] + os: [ ubuntu-24.04 ] python-version: [ 3.9, '3.10', '3.11', '3.12' ] isMerge: - ${{ github.event_name == 'push' && github.ref == 'refs/heads/devel' }} @@ -23,13 +23,17 @@ jobs: - { isMerge: false, python-version: '3.10' } - { isMerge: false, python-version: '3.11' } include: - - os: macos-latest + - os: macos-14 python-version: '3.10' - - os: macos-latest + - os: macos-14 python-version: '3.11' name: ${{ matrix.os }} / Python ${{ matrix.python-version }} + env: + PSYDAC_MESH_DIR: ${{ github.workspace }}/mesh + OMP_NUM_THREADS: 2 + steps: - uses: actions/checkout@v4 @@ -44,7 +48,7 @@ jobs: requirements_extra.txt - name: Install non-Python dependencies on Ubuntu - if: matrix.os == 'ubuntu-latest' + if: matrix.os == 'ubuntu-24.04' uses: awalsh128/cache-apt-pkgs-action@latest with: packages: gfortran openmpi-bin libopenmpi-dev libhdf5-openmpi-dev @@ -55,14 +59,14 @@ jobs: # Workaround is to 'reinstall' openmpi-bin, which doesn't actually perform # installation (since openmpi-bin already exists), but instead reruns # `update-alternatives` which fixes the symlinks to mpicc/mpif90. - - name: Set default MPI and HDF5 C compilers on Ubuntu - if: matrix.os == 'ubuntu-latest' + - name: Reconfigure non-Python dependencies on Ubuntu + if: matrix.os == 'ubuntu-24.04' run: | sudo apt-get update - sudo apt-get install --reinstall openmpi-bin libhdf5-openmpi-dev + sudo apt-get install --reinstall openmpi-bin libhdf5-openmpi-dev liblapack-dev libblas-dev - name: Install non-Python dependencies on macOS - if: matrix.os == 'macos-latest' + if: matrix.os == 'macos-14' run: | brew install open-mpi brew install hdf5-mpi @@ -89,9 +93,9 @@ jobs: - name: Determine directory of parallel HDF5 library run: | - if [[ "${{ matrix.os }}" == "ubuntu-latest" ]]; then + if [[ "${{ matrix.os }}" == "ubuntu-24.04" ]]; then HDF5_DIR=$(dpkg -L libhdf5-openmpi-dev | grep libhdf5.so | xargs dirname) - elif [[ "${{ matrix.os }}" == "macos-latest" ]]; then + elif [[ "${{ matrix.os }}" == "macos-14" ]]; then HDF5_DIR=$(brew list hdf5-mpi | grep "libhdf5.dylib" | xargs dirname | xargs dirname) fi echo $HDF5_DIR @@ -104,12 +108,12 @@ jobs: cache-name: cache-PETSc with: path: "./petsc" - key: cache-${{ matrix.os }}-${{ matrix.python-version }} + key: petsc-${{ matrix.os }}-${{ matrix.python-version }} - if: steps.cache-petsc.outputs.cache-hit != 'true' name: Download a specific release of PETSc run: | - git clone --depth 1 --branch v3.21.4 https://gitlab.com/petsc/petsc.git + git clone --depth 1 --branch v3.22.2 https://gitlab.com/petsc/petsc.git - if: steps.cache-petsc.outputs.cache-hit != 'true' name: Install PETSc with complex support @@ -157,7 +161,7 @@ jobs: - name: Install project run: | - python -m pip install . + python -m pip install .[test] python -m pip freeze - name: Test Pyccel optimization flags @@ -169,35 +173,51 @@ jobs: mkdir pytest cp mpi_tester.py pytest - - name: Run single-process tests with Pytest + - name: Run coverage tests on macOS + if: matrix.os == 'macos-14' + working-directory: ./pytest + run: >- + python -m pytest -n auto + --cov psydac + --cov-config $GITHUB_WORKSPACE/pyproject.toml + --cov-report xml + --pyargs psydac -m "not parallel and not petsc" + + - name: Run single-process tests with Pytest on Ubuntu + if: matrix.os == 'ubuntu-24.04' working-directory: ./pytest run: | - export PSYDAC_MESH_DIR=$GITHUB_WORKSPACE/mesh - export OMP_NUM_THREADS=2 python -m pytest -n auto --pyargs psydac -m "not parallel and not petsc" + - name: Upload coverage report to Codacy + if: matrix.os == 'macos-14' + uses: codacy/codacy-coverage-reporter-action@v1.3.0 + with: + project-token: ${{ secrets.CODACY_PROJECT_TOKEN }} + coverage-reports: ./pytest/coverage.xml + + - name: Print detailed coverage results on macOS + if: matrix.os == 'macos-14' + working-directory: ./pytest + run: | + coverage report --ignore-errors --show-missing --sort=cover + - name: Run MPI tests with Pytest working-directory: ./pytest run: | - export PSYDAC_MESH_DIR=$GITHUB_WORKSPACE/mesh - export OMP_NUM_THREADS=2 python mpi_tester.py --mpirun="mpiexec -n 4 ${MPI_OPTS}" --pyargs psydac -m "parallel and not petsc" - name: Run single-process PETSc tests with Pytest working-directory: ./pytest run: | - export PSYDAC_MESH_DIR=$GITHUB_WORKSPACE/mesh - export OMP_NUM_THREADS=2 python -m pytest -n auto --pyargs psydac -m "not parallel and petsc" - name: Run MPI PETSc tests with Pytest working-directory: ./pytest run: | - export PSYDAC_MESH_DIR=$GITHUB_WORKSPACE/mesh - export OMP_NUM_THREADS=2 python mpi_tester.py --mpirun="mpiexec -n 4 ${MPI_OPTS}" --pyargs psydac -m "parallel and petsc" - name: Remove test directory - if: ${{ always() }} + if: always() run: | rm -rf pytest diff --git a/pyproject.toml b/pyproject.toml index 032ea1dda..9441e6be5 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -26,8 +26,6 @@ dependencies = [ 'scipy >= 1.12', 'sympy >= 1.5', 'matplotlib', - 'pytest >= 4.5', - 'pytest-xdist >= 1.16', 'pyyaml >= 5.1', 'packaging', 'pyevtk', @@ -53,6 +51,13 @@ dependencies = [ 'igakit @ https://github.com/dalcinl/igakit/archive/refs/heads/master.zip' ] +[project.optional-dependencies] +test = [ + "pytest-cov >= 5.0.0", + 'pytest >= 4.5', + 'pytest-xdist >= 1.16', +] + [project.urls] Homepage = "https://github.com/pyccel/psydac" Documentation = "https://pyccel.github.io/psydac" @@ -68,3 +73,41 @@ namespaces = false [tool.setuptools.package-data] "*" = ["*.txt"] + +[tool.coverage.run] +branch = true +omit = [ + # Exclude pyccelised kernels + "*/__psydac__/*", + + # Examples don't need to be covered + "*/examples/*", + + # Unit tests shouldn't be included + "*/tests/*", + ] + +[tool.coverage.report] +# Regexes for lines to exclude from consideration +exclude_also = [ + # Don't complain about missing debug-only code: + "def __repr__", + "if self\\.debug", + + # Don't complain if tests don't hit defensive assertion code: + "raise AssertionError", + "raise NotImplementedError", + + # Don't complain if non-runnable code isn't run: + "if False:", + "if __name__ == .__main__.:", + + # Don't complain about abstract methods, they aren't run: + "@(abc\\.)?abstractmethod", + ] + +# Ignore source code that can’t be found, emitting a warning instead of an exception. +ignore_errors = true + +[tool.coverage.html] +directory = "coverage_html_report"