Repository navigation
Fix Windows corpus transport and CI test dependencies #4354
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: Tests | |
| on: | |
| push: | |
| branches: | |
| - '**' | |
| pull_request: | |
| branches: | |
| - main | |
| jobs: | |
| build_wheels: | |
| name: Build and test on ${{ matrix.os }}${{ matrix.numpy-version && format(' (numpy {0})', matrix.numpy-version) || matrix.python-version && format(' (python {0})', matrix.python-version) || '' }} | |
| runs-on: ${{ matrix.os }} | |
| env: | |
| CMAKE_GENERATOR: Ninja | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| os: [ubuntu-latest, windows-latest, macos-latest] | |
| python-version: ["3.12"] | |
| numpy-version: [null] | |
| include: | |
| - os: ubuntu-latest | |
| python-version: "3.12" | |
| numpy-version: "1.26" | |
| - os: ubuntu-latest | |
| python-version: "3.14" | |
| numpy-version: null | |
| steps: | |
| - uses: actions/checkout@v7 | |
| # Experimental tests require the explicit native pair, not the unchanged | |
| # release dependency. Keep this source override local to numpy-compat CI. | |
| - name: Select experimental native revision | |
| if: github.ref == 'refs/heads/numpy-compat' | |
| id: native_ref | |
| shell: bash | |
| run: echo "sha=$(cat .github/menudet-native-ref)" >> "$GITHUB_OUTPUT" | |
| - uses: actions/checkout@v7 | |
| if: github.ref == 'refs/heads/numpy-compat' | |
| with: | |
| repository: Blosc/miniexpr | |
| ref: ${{ steps.native_ref.outputs.sha }} | |
| path: ci-native | |
| - name: Override experimental native source | |
| if: github.ref == 'refs/heads/numpy-compat' | |
| shell: bash | |
| run: | | |
| source_path="$PWD/ci-native" | |
| if [ "$RUNNER_OS" = Windows ]; then | |
| source_path=$(cygpath -m "$source_path") | |
| fi | |
| echo "CMAKE_ARGS=-DFETCHCONTENT_SOURCE_DIR_MINIEXPR=$source_path" >> "$GITHUB_ENV" | |
| - name: Set up Python ${{ matrix.python-version }} | |
| uses: actions/setup-python@v7 | |
| with: | |
| python-version: ${{ matrix.python-version }} | |
| - name: Install sccache (Windows) | |
| if: runner.os == 'Windows' | |
| run: choco install sccache --yes | |
| - name: Cache sccache (Windows) | |
| if: runner.os == 'Windows' | |
| uses: actions/cache@v6 | |
| with: | |
| path: C:\Users\runneradmin\AppData\Local\sccache | |
| key: sccache-${{ runner.os }}-${{ github.sha }} | |
| restore-keys: | | |
| sccache-${{ runner.os }}- | |
| - name: Cache pip (Windows) | |
| if: runner.os == 'Windows' | |
| uses: actions/cache@v6 | |
| with: | |
| path: C:\Users\runneradmin\AppData\Local\pip\Cache | |
| key: pip-${{ runner.os }}-${{ hashFiles('pyproject.toml') }} | |
| restore-keys: | | |
| pip-${{ runner.os }}- | |
| - name: Install Ninja | |
| run: pip install ninja | |
| - name: Add LLVM to PATH (Windows) | |
| if: runner.os == 'Windows' | |
| run: echo "C:\\Program Files\\LLVM\\bin" >> $env:GITHUB_PATH | |
| - name: Build (Windows) | |
| if: runner.os == 'Windows' | |
| id: build_windows | |
| run: pip install -e . --group test | |
| env: | |
| CMAKE_C_COMPILER_LAUNCHER: sccache | |
| CMAKE_CXX_COMPILER_LAUNCHER: sccache | |
| SCCACHE_DIR: C:\Users\runneradmin\AppData\Local\sccache | |
| CC: clang-cl | |
| CXX: clang-cl | |
| CMAKE_BUILD_PARALLEL_LEVEL: 8 | |
| SKBUILD_PARALLEL_LEVEL: 8 | |
| - name: Build (non-Windows) | |
| if: runner.os != 'Windows' | |
| id: build_non_windows | |
| run: pip install -e . --group test | |
| - name: Install Arrow dictionary test dependency | |
| # Pandas is already a dev dependency; Arrow's dictionary conversions now | |
| # import it even when the test does not construct a pandas object. | |
| run: python -m pip install pandas | |
| # Build isolation uses NumPy 2 headers for the dual-ABI extension. Optional | |
| # test dependencies may upgrade the runtime too, so pin it AFTER installing. | |
| - name: Install NumPy 1.26-compatible test runtime | |
| if: matrix.numpy-version == '1.26' | |
| # PyArrow 26 dropped the NumPy 1 ABI without encoding it in Requires-Dist. | |
| # Keep this host-compatibility job on a known dual-ABI Arrow release. | |
| run: pip install "numpy==1.26.*" "zarr>=3.1.5,<3.2" "pyarrow==21.0.0" pandas | |
| - name: Verify requested NumPy runtime | |
| if: matrix.numpy-version | |
| run: python -c "import numpy as np; assert np.__version__.startswith('${{ matrix.numpy-version }}.'), np.__version__" | |
| - name: Test (Windows) | |
| if: runner.os == 'Windows' | |
| run: python -m pytest -m "not heavy and not network and not tui" --durations=25 | |
| env: | |
| # A test over this many seconds is a deadlock, not a slow test (the | |
| # slowest is ~7 s): dump stacks and kill the worker so xdist names it | |
| # instead of the job hanging until the 6-hour cap. The session budget | |
| # catches the same hang in teardown or interpreter exit, where no test | |
| # is running to be named. | |
| PYTEST_DEADMAN_SECONDS: "300" | |
| PYTEST_DEADMAN_SESSION_SECONDS: "1500" | |
| # BLOSC_NTHREADS: "1" | |
| # NUMEXPR_NUM_THREADS: "1" | |
| # OMP_NUM_THREADS: "1" | |
| - name: Test (non-Windows) | |
| if: runner.os != 'Windows' | |
| run: python -m pytest -m "not heavy and not network and not tui" --durations=25 | |
| env: | |
| PYTEST_DEADMAN_SECONDS: "300" | |
| PYTEST_DEADMAN_SESSION_SECONDS: "1500" | |
| - name: Verify experimental safe-graph corpus | |
| if: always() && (steps.build_windows.outcome == 'success' || steps.build_non_windows.outcome == 'success') | |
| run: python scripts/verify_safe_lazyexpr.py --report safe-lazyexpr.json | |
| - name: Upload safe-graph platform evidence | |
| if: always() | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: safe-lazyexpr-${{ matrix.os }}-py${{ matrix.python-version }}-np${{ matrix.numpy-version || 'default' }} | |
| path: safe-lazyexpr.json | |
| if-no-files-found: ignore | |
| - name: Certify bounded Menudet math against independent references | |
| run: python scripts/certify_menudet_math.py --report menudet-math.json | |
| - name: Upload Menudet math certification | |
| if: always() | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: menudet-math-${{ matrix.os }}-py${{ matrix.python-version }}-np${{ matrix.numpy-version || 'default' }} | |
| path: menudet-math.json | |
| if-no-files-found: ignore | |
| # TUIs are timing-sensitive and only boot a headless terminal: one OS is | |
| # enough, and a flake here is feedback, not a release blocker. | |
| - name: Test TUI (non-blocking) | |
| if: matrix.os == 'ubuntu-latest' && matrix.python-version == '3.12' && !matrix.numpy-version | |
| continue-on-error: true | |
| run: python -m pytest -m "tui and not heavy and not network" -n 4 --dist loadfile --durations=10 | |
| env: | |
| PYTEST_DEADMAN_SECONDS: "300" | |
| PYTEST_DEADMAN_SESSION_SECONDS: "900" | |
| - name: Deadlock stacks, if a worker had to be killed | |
| if: always() | |
| shell: bash | |
| run: | | |
| if [ -s deadman-stacks.log ]; then | |
| echo "::group::Deadlock stacks" | |
| cat deadman-stacks.log | |
| echo "::endgroup::" | |
| fi | |
| # The network tests talk to a live Caterva2 server and were 24 of the 25 | |
| # slowest tests in *both* the Windows and Linux jobs, with near-identical | |
| # times -- so what they measure is server round-trip latency, not anything | |
| # about the OS. Running them on Linux alone therefore loses no signal, and | |
| # stops five jobs per push hammering a third-party service. | |
| # | |
| # --dist load, not the loadfile default: these are latency-bound and | |
| # independent, so per-file pinning parks ~165 s of test_c2array_expr.py on | |
| # one worker while the rest idle. `load` is unsafe for the suite at large | |
| # (see pytest.ini) but the modules it breaks are not network-marked, so | |
| # they are not in this selection at all. | |
| # | |
| # -n 8 on a 4-core runner: these tests wait on sockets rather than compute, | |
| # so workers well past the core count still help. 8 is the point of | |
| # diminishing returns, not a round number -- the floor is the single | |
| # slowest test (test_mix_operands, ~42 s), which no amount of workers beats. | |
| # | |
| # The condition names one matrix entry rather than testing `runner.os`: | |
| # three of the five jobs are ubuntu, so `runner.os == 'Linux'` ran this | |
| # three times per push. | |
| - name: Test network access | |
| if: matrix.os == 'ubuntu-latest' && matrix.python-version == '3.12' && !matrix.numpy-version | |
| run: python -m pytest -m "network and not heavy" -n 8 --dist load --durations=10 |