Skip to content

Test

Test #320

Workflow file for this run

name: Test
on:
pull_request:
branches:
- main
push:
branches:
- main
workflow_dispatch:
schedule:
- cron: "42 01 * * SUN"
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
defaults:
run:
shell: bash
env:
PYTEST: python -m pytest -v -n auto --color=yes --log-image-diffs
jobs:
pre-commit:
name: pre-commit
if: github.event_name != 'schedule' || github.repository_owner == 'contourpy'
runs-on: ubuntu-latest
steps:
- name: Checkout source
uses: actions/checkout@v4
- name: Setup Python
uses: actions/setup-python@v5
with:
python-version: "3.12"
- name: Run pre-commit
uses: pre-commit/[email protected]
codebase:
name: codebase
if: github.event_name != 'schedule' || github.repository_owner == 'contourpy'
runs-on: ubuntu-latest
strategy:
matrix:
python-version: ["3.12"]
steps:
- name: Checkout source
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Setup Python ${{ matrix.python-version }}
uses: actions/setup-python@v5
with:
python-version: ${{ matrix.python-version }}
- name: Install contourpy
run: |
python -m pip install --upgrade pip
python -m pip install -v .[mypy,test]
- name: Install cppcheck
run: |
CPPCHECK_VERSION=2.13.0
CPPCHECK_TGZ=$CPPCHECK_VERSION.tar.gz
cd $RUNNER_TEMP
wget --no-verbose https://github.com/danmar/cppcheck/archive/refs/tags/$CPPCHECK_TGZ
tar xzf $CPPCHECK_TGZ
cd cppcheck-$CPPCHECK_VERSION
sudo make install MATCHCOMPILER=yes FILESDIR=/usr/share/cppcheck CXXFLAGS="-O2 -DNDEBUG" -j 2
- name: Smoke test
run: |
python -m pip list
python -c "from contourpy.util import build_config; from pprint import pprint; pprint(build_config())"
python -c "import contourpy as c; print('NDEBUG', c._contourpy.NDEBUG)"
- name: Run tests
run: |
${PYTEST} tests/test_codebase.py
test:
name: "${{ matrix.name }} ${{ matrix.python-version }} ${{ matrix.os }}"
if: github.event_name != 'schedule' || github.repository_owner == 'contourpy'
runs-on: ${{ matrix.os }}
env:
# Required version of chromium used for Bokeh image tests.
CHROME_VER: "118.0.5993.88"
CHROME_REV: "chromium_2670"
strategy:
fail-fast: false
matrix:
os: [ubuntu-latest, macos-13, macos-14, windows-latest] # macos-14 is ARM
python-version: ["3.9", "3.10", "3.11", "3.12", "3.13-dev"]
name: ["Test"]
short-name: ["test"]
include:
# Debug build including Python and C++ coverage.
- os: ubuntu-latest
python-version: "3.12"
name: "Test debug with coverage"
short-name: "test-debug"
coverage-files: "coverage.lcov,coverage.cpp"
debug: true
# Bokeh and text tests with Python (not C++) coverage.
- os: ubuntu-latest
python-version: "3.12"
name: "Test bokeh and text tests with coverage"
short-name: "test-bokeh"
coverage-files: "coverage.lcov"
test-text: true
# Test against numpy debug build.
- os: ubuntu-latest
python-version: "3.12"
name: "Test numpy debug"
short-name: "test-numpy-debug"
build-numpy-debug: true
# Test against earliest supported numpy
- os: ubuntu-latest
python-version: "3.9"
name: "Test earliest numpy"
short-name: "test-earliest-numpy"
extra-install-args: "numpy==1.23"
# Compile using C++11.
- os: ubuntu-latest
python-version: "3.12"
name: "Test C++11"
short-name: "test-c++11"
extra-install-args: "-Csetup-args=-Dcpp_std=c++11"
# PyPy 3.9 only tested on ubuntu for speed, exclude big tests.
- os: ubuntu-latest
python-version: "pypy3.9"
name: "Test"
short-name: "test"
test-no-big: true
# PyPy 3.10.
- os: ubuntu-latest
python-version: "pypy3.10"
name: "Test"
short-name: "test"
test-no-images: true
numpy-nightly: true
# Win32 test.
- os: windows-latest
python-version: "3.12"
name: "Win32"
short-name: "test-win32"
win32: true
test-no-images: true
# Test against matplotlib and numpy nightly wheels.
- os: ubuntu-latest
python-version: "3.12"
name: "Nightly wheels"
short-name: "test-nightlies"
nightly-wheels: true
- os: macos-13
python-version: "3.12"
name: "Nightly wheels"
short-name: "test-nightlies"
nightly-wheels: true
- os: windows-latest
python-version: "3.12"
name: "Nightly wheels"
short-name: "test-nightlies"
nightly-wheels: true
- os: ubuntu-latest
python-version: "3.13-dev-freethreading"
name: "Test"
short-name: "test"
steps:
- name: Checkout source
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Setup Python ${{ matrix.python-version }}
if: ${{ !matrix.win32 && !endsWith(matrix.python-version, 'freethreading') }}
uses: actions/setup-python@v5
with:
python-version: ${{ matrix.python-version }}
- name: Setup Python ${{ matrix.python-version }} win32
if: matrix.win32
uses: actions/setup-python@v5
with:
python-version: ${{ matrix.python-version }}
architecture: x86
- name: Setup Python ${{ matrix.python-version }}
if: ${{ endsWith(matrix.python-version, 'freethreading') }}
uses: deadsnakes/[email protected]
with:
python-version: '3.13-dev'
nogil: true
- name: Setup MSVC (32-bit)
if: matrix.win32
uses: bus1/cabuild/action/msdevshell@v1
with:
architecture: 'x86'
- name: Fix PATH on win32
# Avoid this in GHA: "ERROR: Found GNU link.exe instead of MSVC link.exe"
if: matrix.win32
run: |
rm /c/Program\ Files/Git/usr/bin/link.EXE
- name: Install OS dependencies
if: matrix.debug
run: |
sudo apt update -yy
sudo apt install -yy lcov
- name: Install chromium for Bokeh tests
if: matrix.test-text
run: |
if [[ "$(chromium --version | cut -d' ' -f2)" = "$CHROME_VER" ]]; then
echo "Using pre-installed version of chromium"
else
URL=https://github.com/bokeh/chromium/raw/main/linux/$CHROME_VER
wget --no-verbose $URL/$CHROME_REV.assert
wget --no-verbose $URL/$CHROME_REV.snap
ls -l $CHROME_REV.*
sudo snap ack $CHROME_REV.assert
sudo snap install $CHROME_REV.snap
snap list chromium
snap info chromium
fi
which chromium
chromium --version
which chromedriver
chromedriver --version
- name: Build and install numpy from sdist
if: matrix.build-numpy
run: |
python -m pip install -v --no-binary=numpy numpy
- name: Build and install numpy from sdist with debug asserts enabled
if: matrix.build-numpy-debug
run: |
python -m pip install -v --no-binary=numpy numpy -Csetup-args=-Dbuildtype=debug
- name: Install numpy from nightly wheels
if: matrix.numpy-nightly
run: |
python -m pip install --only-binary=:all: --pre --extra-index-url https://pypi.anaconda.org/scientific-python-nightly-wheels/simple numpy
- name: Pre-install Python dependencies
run: |
python -m pip install --upgrade pip
if [[ "${{ matrix.debug }}" != "" ]] || [[ "${{ matrix.coverage-files }}" != "" ]]
then
# Install requirements when not using build isolation.
python -m pip install --only-binary=:all: -r build_requirements.txt ninja
fi
python -m pip list
- name: Install contourpy
run: |
if [[ "${{ matrix.debug }}" != "" ]]
then
echo "Install contourpy in debug editable mode with coverage"
python -m pip install -ve .[test] --no-build-isolation -Csetup-args=-Dbuildtype=debug -Csetup-args=-Db_coverage=true -Cbuilddir=build
elif [[ "${{ matrix.coverage-files }}" != "" ]]
then
echo "Install contourpy in editable mode with bokeh dependencies"
python -m pip install -ve .[bokeh,test] --no-build-isolation -Cbuilddir=build
elif [[ "${{ matrix.test-no-images }}" != "" ]]
then
echo "Install contourpy with non-image-generating test dependencies"
python -m pip install -v .[test-no-images]
else
echo "Install contourpy with standard test dependencies"
python -m pip install -v .[test] ${{ matrix.extra-install-args }}
fi
- name: Upgrade mpl and numpy nightly wheels
if: matrix.nightly-wheels
run: |
python -m pip install --only-binary=:all: --pre --upgrade --no-deps --extra-index-url https://pypi.anaconda.org/scientific-python-nightly-wheels/simple matplotlib numpy
- name: Smoke test
run: |
python -m pip list
python -c "from contourpy.util import build_config; from pprint import pprint; pprint(build_config())"
python -c "import contourpy as c; print('NDEBUG', c._contourpy.NDEBUG)"
- name: Run tests
run: |
if [[ "${{ matrix.debug }}" != "" ]]
then
echo "Run normal tests with coverage"
${PYTEST} tests/ --cov=lib --cov-report=lcov
elif [[ "${{ matrix.test-text }}" != "" ]]
then
echo "Run normal and text tests with coverage"
${PYTEST} -rP tests/test_bokeh_renderer.py tests/test_renderer.py --runtext --driver-path=/snap/bin/chromium.chromedriver --cov=lib --cov-report=lcov
elif [[ "${{ matrix.test-no-images }}" != "" ]]
then
echo "Run only tests that do not generate images"
${PYTEST} tests/ -k "not image"
elif [[ "${{ matrix.test-no-big }}" != "" ]]
then
echo "Run all tests except big ones"
${PYTEST} tests/ -k "not big"
else
echo "Run all tests"
${PYTEST} tests/
fi
- name: Collect C++ coverage
if: matrix.debug
run: |
lcov --output-file coverage.cpp --capture --directory build
lcov --output-file coverage.cpp --extract coverage.cpp $PWD/src/"*"
- name: Upload coverage
if: matrix.coverage-files
uses: codecov/codecov-action@v4
with:
files: ${{ matrix.coverage-files }}
token: ${{ secrets.CODECOV_TOKEN }}
verbose: true
- name: Upload test artifacts
if: always()
uses: actions/upload-artifact@v4
with:
name: ${{ matrix.short-name }}_${{ matrix.os }}_${{ matrix.python-version }}
path: result_images/
test-in-docker:
# In-docker tests are either emulated hardware or musllinux
name: In docker ${{ matrix.arch }} ${{ matrix.manylinux_version }}
if: github.event_name != 'schedule' || github.repository_owner == 'contourpy'
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
include:
# musllinux x86_64.
- arch: x86_64
manylinux_version: musllinux
image: musllinux_1_2_x86_64
venv: venv
test: test
# musllinux aarch64.
- arch: aarch64
manylinux_version: musllinux
image: musllinux_1_2_aarch64
venv: venv
test: test-no-images
# ppc64le and s390x: dependencies are conda packages.
- arch: ppc64le
manylinux_version: manylinux2014
image: manylinux2014_ppc64le
venv: conda
test: test
- arch: s390x
manylinux_version: manylinux2014
image: manylinux2014_s390x
venv: conda
test: test
steps:
- name: Checkout source
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Set up QEMU
if: ${{ matrix.arch }} != "x86_64"
uses: docker/setup-qemu-action@v3
with:
platforms: all
- name: Run inside docker
uses: addnab/docker-run-action@v3
with:
image: quay.io/pypa/${{ matrix.image }}:latest
options: -v ${{ github.workspace }}:/work -e ARCH=${{ matrix.arch }} -e VENV=${{ matrix.venv}} -e TEST=${{ matrix.test }}
shell: bash
run: |
echo "-------------------- start --------------------"
set -eu
uname -a
cd /work
if [[ $VENV == "venv" ]]
then
echo "==> Create virtual environment"
/opt/python/cp312-cp312/bin/python -m venv venv
. venv/bin/activate
which python
python --version
else
echo "==> Install conda"
cd /tmp
curl -LO "http://repo.continuum.io/miniconda/Miniconda3-latest-Linux-$ARCH.sh"
bash Miniconda3-latest-Linux-$ARCH.sh -p /work/venv -b
rm Miniconda3-latest-Linux-$ARCH.sh
cd /work
echo "==> Activate conda in this shell"
. /work/venv/etc/profile.d/conda.sh
echo "==> Create and activate conda environment"
conda create -n my_env -q python=3.12
conda activate my_env
echo "==> Install conda dependencies"
conda install -q -c conda-forge -c nodefaults numpy matplotlib Pillow
conda list
fi
echo "==> Upgrade pip"
python -m pip install --upgrade pip
echo "==> Install contourpy with test dependencies"
python -m pip install -v .[$TEST] --only-binary=numpy
echo "==> Smoke test"
python -m pip list
python -c "from contourpy.util import build_config; from pprint import pprint; pprint(build_config())"
python -c "import contourpy as c; print('NDEBUG', c._contourpy.NDEBUG)"
PYTEST="python -m pytest -v -n auto --color=yes --log-image-diffs"
if [[ $TEST == "test-no-images" ]]
then
echo "==> Run non-image and non-big tests"
${PYTEST} tests/ -k "not (big or image)"
else
echo "==> Run tests except 'big' ones as on emulated hardware"
${PYTEST} tests/ -k "not big"
fi
echo "-------------------- end --------------------"
- name: Upload test artifacts
if: always()
uses: actions/upload-artifact@v4
with:
name: docker_${{ matrix.arch }}_${{ matrix.manylinux_version }}
path: result_images/
merge:
name: Merge test artifacts
if: github.event_name != 'schedule' || github.repository_owner == 'contourpy'
runs-on: ubuntu-latest
needs: [test, test-in-docker]
steps:
- name: Merge Artifacts
uses: actions/upload-artifact/merge@v4
with:
name: test-artifacts
separate-directories: true
delete-merged: true