Repository navigation
Merge pull request #1021 from lanl/fix/tests-follow-bngsim-017-atol #885
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: [main] | |
| pull_request: | |
| jobs: | |
| pytest: | |
| runs-on: ubuntu-latest | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| # Every supported version (requires-python >= 3.12; classifiers list | |
| # through 3.14). CI is free on this public repo, so we test each claimed | |
| # version rather than just the endpoints. 3.11 left with the petab 0.9 | |
| # floor (#591): petab 0.9.0 requires >= 3.12. | |
| include: | |
| - python-version: '3.12' | |
| - python-version: '3.13' | |
| # bngsim publishes cp310-cp313 wheels, so 3.14 would fall back to | |
| # building the sdist (C++17 toolchain, CMake >= 3.20, Ninja) inside | |
| # the pytest job. Keep this leg deliberately bngsim-less instead: it | |
| # is the guard that the bngsim-free code paths still work (a bare | |
| # `pip install pybnf` on a machine with no wheel), which is worth a | |
| # leg of its own regardless. Drop `no-bngsim` here the day a cp314 | |
| # wheel ships. | |
| - python-version: '3.14' | |
| no-bngsim: '1' | |
| name: pytest (py${{ matrix.python-version }}${{ matrix.no-bngsim == '1' && ', bngsim-less' || '' }}) | |
| steps: | |
| - uses: actions/checkout@v6 | |
| - uses: ./.github/actions/setup-pybnf | |
| with: | |
| python-version: ${{ matrix.python-version }} | |
| bngsim: ${{ matrix.no-bngsim == '1' && 'false' || 'true' }} | |
| - name: Warm the arviz version-check stamp | |
| # arviz < 1.0 prints a daily refactor warning on import and | |
| # records the date through a helper it calls atomic, which it is not: the temp file has | |
| # a FIXED name, `daily_warning.tmp`, so every process shares it. | |
| # | |
| # tmp = path.with_suffix(path.suffix + ".tmp") | |
| # tmp.write_text(text) | |
| # tmp.replace(path) | |
| # | |
| # Under `-n auto` the xdist workers import arviz at once, the first replace() renames | |
| # the shared temp away, and the rest raise FileNotFoundError -- which surfaces as | |
| # test_inference_data.py failing to collect on some workers but not others, i.e. | |
| # "Different tests were collected between gw0 and gw1", not as an arviz error. | |
| # | |
| # Importing once here, serially, writes today's date so arviz's own `last_date != today` | |
| # guard short-circuits in every worker and the racing write never happens. Tolerant of | |
| # arviz being absent (the bngsim-less leg resolves a different set) and of arviz >= 1.0, | |
| # which dropped the stamp entirely. | |
| run: | | |
| uv run --no-sync python -c " | |
| try: | |
| import arviz # noqa: F401 | |
| except ImportError: | |
| pass | |
| " | |
| - name: Run unit tests (parallel) | |
| env: | |
| # Empty except on the bngsim-less leg, where it is '1'. An empty value | |
| # reads as unset (pybnf/_bngsim_caps.py tests truthiness), so bngsim | |
| # is imported and the bngsim/nfsim/rulemonkey/sbml/antimony-marked | |
| # tests run for real; with '1' conftest.py auto-skips them. | |
| PYBNF_NO_BNGSIM: ${{ matrix.no-bngsim }} | |
| # -m: the default addopts expression is `not slow and not recovery`, and | |
| # naming -m here REPLACES it -- so both tiers must be restated. Omitting | |
| # `not recovery` used to be harmless because 129 of the 130 recovery | |
| # tests skip without bngsim; with bngsim installed they are real | |
| # parameter-recovery fits through the backend and the job would run for | |
| # over an hour. (The cost of deselecting: the 130th, a roadrunner-backed | |
| # Boehm oracle in test_petab_sbml_layer.py, is bngsim-free and no longer | |
| # runs here.) -n auto parallelizes across the runner's cores. | |
| # | |
| # --no-sync: do NOT let `uv run` re-resolve the project env from | |
| # pyproject.toml -- the composite action already populated .venv with an | |
| # exact dependency set (and on the bngsim-less leg a re-resolve would | |
| # pull bngsim right back in). | |
| run: uv run --no-sync pytest -m "not slow and not recovery" -n auto | |
| # The gradient path (ADR-0059): the HMC reference sampler and the jax-gated | |
| # gradient-assembly tests need the optional pybnf[jax] extra (jax + jaxlib + | |
| # blackjax). jaxlib is a large install relative to the rest of the dep set, so | |
| # rather than pay it on all four matrix legs above this one dedicated job turns | |
| # the `jax` input on and runs exactly the two files that exercise the gradient | |
| # path: tests/test_hmc.py (the whole ADR-0059 HMC oracle, skipif-gated on the | |
| # extra) and tests/test_gradient_assembly.py (its jax tests importorskip). Those | |
| # gradient tests include the fd-acceptance-gate cases, which are ALSO | |
| # bngsim-marked -- they check the analytic jax gradient against a | |
| # finite-difference through a real bngsim model -- so this leg keeps bngsim | |
| # installed (the default) and PYBNF_NO_BNGSIM unset. One Python version is | |
| # enough: the oracle is about numerical correctness, not version-compat. Before | |
| # this job, tests/test_hmc.py had never run on a hosted runner (#516). | |
| pytest-jax: | |
| runs-on: ubuntu-latest | |
| name: pytest (jax / HMC) | |
| steps: | |
| - uses: actions/checkout@v6 | |
| - uses: ./.github/actions/setup-pybnf | |
| with: | |
| python-version: '3.12' | |
| jax: 'true' | |
| # This job also runs 3.12 through setup-pybnf, so give it its own cache | |
| # namespace to avoid racing the matrix py3.12 job's save (see the | |
| # cache-suffix input). | |
| cache-suffix: pybnf-jax | |
| - name: Run the HMC + jax gradient tests | |
| # Deselect slow/recovery exactly as the matrix legs do (the one slow HMC | |
| # cross-check in test_hmc.py stays out of the default run). -n auto | |
| # parallelizes across the runner's cores. | |
| run: uv run --no-sync pytest -m "not slow and not recovery" tests/test_hmc.py tests/test_gradient_assembly.py -n auto |