Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: migrate to nox, run tests in parallel, revamp test infra #632

Open
wants to merge 35 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 32 commits
Commits
Show all changes
35 commits
Select commit Hold shift + click to select a range
4e86511
Ignore `.nox` folder
agriyakhetarpal Aug 24, 2024
7c77f3c
Create an initial draft for the Noxfile
agriyakhetarpal Aug 24, 2024
1d08e46
Add a `[test]` extra, add parallel testing
agriyakhetarpal Aug 24, 2024
1a31a22
Use `nox`, setup `uv`, bump actions' versions
agriyakhetarpal Aug 24, 2024
b8f1210
Use `uv tool` runner for tests
agriyakhetarpal Aug 24, 2024
5825a1d
Add `tests-scipy` session
agriyakhetarpal Aug 24, 2024
ade79ef
Modify condition for SciPy-Linux-PyPy
agriyakhetarpal Aug 24, 2024
39b7e33
Bump `pytest`'s verbosity
agriyakhetarpal Aug 24, 2024
6dd5109
Make tests deterministic
agriyakhetarpal Aug 24, 2024
bcd01bb
Add Fortran compiler for SciPy on macOS
agriyakhetarpal Aug 24, 2024
f2e11f3
Remove `tests-scipy` session, make it simpler
agriyakhetarpal Aug 24, 2024
6189449
Fix `PIP_DISABLE_PIP_VERSION_CHECK`
agriyakhetarpal Aug 24, 2024
8d0ebc9
Cancel tests when new commits are pushed
agriyakhetarpal Aug 24, 2024
70f63ca
Refactor tests and prerequisites job steps order
agriyakhetarpal Aug 24, 2024
a60facd
Fix a typo for macOS installations
agriyakhetarpal Aug 24, 2024
8d89d69
Install `pkg-config` for macOS OpenBLAS detection
agriyakhetarpal Aug 24, 2024
f1e4a7d
Retain the original testing configuration
agriyakhetarpal Aug 24, 2024
ebf3d2f
Allow passing custom files to test
agriyakhetarpal Aug 24, 2024
503a637
Comment out some lines, add some comments
agriyakhetarpal Aug 28, 2024
3886083
Add back Python 3.8
agriyakhetarpal Aug 28, 2024
0844201
Replace `checks.yml` with `nox` equivalents
agriyakhetarpal Aug 28, 2024
b797a91
Delete tox configuration file
agriyakhetarpal Aug 28, 2024
bb3067d
Replace all instances of `tox` with `nox`
agriyakhetarpal Aug 28, 2024
667b405
Add `--cov-append` to update coverage
agriyakhetarpal Aug 28, 2024
19dab2a
Split out CPython and PyPy tests
agriyakhetarpal Aug 28, 2024
ca8faef
Cancel intermediate jobs
agriyakhetarpal Aug 28, 2024
694517f
Fix `nox` invocation for PyPy
agriyakhetarpal Aug 28, 2024
414f8ef
Fix `pytest -k` invocation
agriyakhetarpal Aug 28, 2024
ad98e43
Un-silence dependency installations
agriyakhetarpal Aug 28, 2024
5eb25be
Re-create fresh environments every time
agriyakhetarpal Aug 28, 2024
3df0f28
Implement testing against NumPy, SciPy nightlies
agriyakhetarpal Aug 28, 2024
236e2be
Document how to run nightly tests
agriyakhetarpal Aug 28, 2024
391b976
Merge master
agriyakhetarpal Aug 30, 2024
c39b1b0
Use `pre-commit` for a "lint" nox session
agriyakhetarpal Aug 30, 2024
d602a5e
Fix style failures
agriyakhetarpal Aug 30, 2024
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
28 changes: 16 additions & 12 deletions .github/workflows/check.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
name: Checks
name: Style and package checks

on:
pull_request:
Expand All @@ -7,27 +7,31 @@ on:
push:
branches:
- master
workflow_dispatch:

env:
PIP_DISABLE_PIP_VERSION_CHECK: '1'
PY_COLORS: '1'
PIP_DISABLE_PIP_VERSION_CHECK: "1"
FORCE_COLOR: "3"

concurrency:
group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }}
cancel-in-progress: true

jobs:
check:
name: ${{ matrix.env }}
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
env:
#- ruff
- package
session:
# - lint
- validate-package
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5.1.1
with:
python-version: '3.10'
- name: Install build tools
run: |
python -m pip install tox wheel

- uses: yezz123/setup-uv@v4

- name: Run ${{ matrix.env }}
run: python -m tox -e ${{ matrix.env }}
run: uvx nox -s ${{ matrix.env }}
61 changes: 27 additions & 34 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
@@ -1,53 +1,46 @@
name: Tests
name: CI

on:
pull_request:
branches:
- master
- master
push:
branches:
- master
- master
workflow_dispatch:
schedule:
- cron: '0 4 * * *'
- cron: "0 4 * * *"

env:
PIP_DISABLE_PIP_VERSION_CHECK: '1'
PY_COLORS: '1'
PIP_DISABLE_PIP_VERSION_CHECK: "1"
FORCE_COLOR: "3"

concurrency:
group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }}
cancel-in-progress: true

jobs:
test:
name: Test / ${{ matrix.platform }} / Nightly ${{ matrix.nightly[0] }} / Python ${{ matrix.python-version }}
runs-on: ${{ matrix.platform }}
strategy:
fail-fast: false
matrix:
platform:
- ubuntu-latest
- macos-latest
- windows-latest
platform: [ubuntu-latest, macos-13, macos-latest, windows-latest]
python-version:
- '3.9'
- '3.10'
- '3.11'
- '3.12'
- pypy-3.9
- pypy-3.10
# TODO: bring this back later
exclude:
- platform: windows-latest
python-version: 'pypy-3.10'
["3.8", "3.9", "3.10", "3.11", "3.12", "pypy-3.9", "pypy-3.10"]
nightly: [[True, "nightly-"], [False, ""]]
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5.1.1
with:
python-version: ${{ matrix.python-version }}
- name: Install Python build tools
run: python -m pip install tox wheel
- name: Run tests
run: python -m tox run -e py
- name: Install Scipy prerequisites for Ubuntu
if: startsWith(matrix.platform, 'ubuntu')
run: sudo apt-get install libopenblas-dev
- name: Run tests with scipy
if: startsWith(matrix.platform, 'ubuntu') || startsWith(matrix.python-version, 'pypy') != true
run: python -m tox run -e py-scipy
- uses: actions/checkout@v4.1.7
- uses: actions/setup-python@v5.1.1
with:
python-version: ${{ matrix.python-version }}
- uses: yezz123/setup-uv@v4

- name: Run CPython tests
if: ${{ !startsWith(matrix.python-version, 'pypy') }}
run: uvx nox -s ${{ matrix.nightly[1] }}tests

- name: Run PyPy tests
if: ${{ startsWith(matrix.python-version, 'pypy') }}
run: uvx nox -s ${{ matrix.nightly[1] }}tests
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ pip-delete-this-directory.txt
# Unit test / coverage reports
htmlcov/
.tox/
.nox/
.coverage
.coverage.*
.cache
Expand Down
44 changes: 20 additions & 24 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
@@ -1,38 +1,34 @@
# Contributing

Use Tox to run tests and linting, e.g.
Use [Nox](https://nox.thea.codes/en/stable/) to run tests and linting, e.g.,

```shell
pip install tox
pip install nox
```

`nox` will run all checks in an isolated virtual environment with Autograd and its dependencies, including its optional dependencies, installed.

## Run tests, linting, packaging checks

```shell
tox list # list all Tox environments
tox run -e ruff # run code style checks
tox run -e py # run tests with your default Python
tox run -e package # verify packaging
tox # run all Tox environments
```
| Command | Description |
| ------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `nox --list` | Lists all available Nox sessions, including selected ones |
| `nox -s lint` | Runs code style checks with pre-commit and pre-commit hooks as listed in `.pre-commit-config.yaml`. Accepts posargs to pass additional arguments to the linter. |
| `nox -s tests` | Runs tests with your default Python interpreter. Accepts posargs to pass additional arguments and configuration to `pytest`. |
| `nox -s nightly-tests` | Similar to `nox -s tests`, except that it runs tests with nightly versions of dependencies (NumPy, SciPy, etc.). |
| `nox -s validate-package` | Builds a source distribution and a wheel using `pypa/build` and checks the package with `twine` in strict mode. |
| `nox` | Runs all selected sessions, as listed in `nox.options.sessions` in `noxfile.py`. |

Additionally, `nox` supports tags to run specific sessions, e.g., `nox --tags tests` runs all sessions tagged with `tests`.

Make sure all tests pass before you push your changes to GitHub.
GH Actions will run the tests across all supported Python versions.

## Using arguments (reformat, upload package, help)

You can use additional arguments for the tools called by Tox by
separating them from the Tox arguments by a double-dash `--`, e.g.

```shell
tox run -e ruff -- autograd/core.py --show-source
tox run -e ruff -- autograd/core.py --fix
```
## Using positional arguments (reformat, upload package, help)

```shell
tox run -e package -- upload
```
You can use additional arguments for the tools (`pytest`, `pre-commit`, etc.) called by Nox by
separating them from the Nox arguments by a double-hyphen `--`, e.g.,

```shell
tox run -e py -- --help
```
- `nox -s tests -- --tests/test_tuple.py` runs just the tests listed `tests/test_tuple.py`.
- `nox -s lint -- --fix` runs the linter with the `--fix` flag.
- and so on.
60 changes: 60 additions & 0 deletions noxfile.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
import platform

import nox

NIGHTLY_INDEX_URL = "https://pypi.anaconda.org/scientific-python-nightly-wheels/simple"
UV_NIGHTLY_ENV_VARS = {
"UV_INDEX_URL": NIGHTLY_INDEX_URL,
"UV_PRERELEASE": "allow",
"UV_INDEX_STRATEGY": "first-index",
"UV_NO_CACHE": "true"
}

nox.needs_version = ">=2024.4.15"
nox.options.default_venv_backend = "uv|virtualenv"
nox.options.reuse_existing_virtualenvs = False
nox.options.error_on_external_run = True
# nox.options.sessions = ["lint", "validate-package", "tests"]
nox.options.sessions = ["tests"]


@nox.session(name="validate-package")
def check(session):
"""Build source distribution, wheel, and check their metadata"""
session.install("build", "twine", silent=False)
session.run("python", "-m", "build")
session.run("twine", "check", "--strict", "dist/*")


@nox.session(name="tests", tags=["tests"])
def run_tests(session):
"""Run unit tests and generate a coverage report"""
# SciPy doesn't have wheels on PyPy
if platform.python_implementation() == "PyPy":
session.install("-e", ".[test]", silent=False)
else:
session.install("-e", ".[test,scipy]", silent=False)
session.run("pytest", "--cov=autograd", "--cov-report=xml", "--cov-append", *session.posargs)


# TODO: Replace with pre-commit and pre-commit.ci once
# https://github.com/HIPS/autograd/pull/634 is merged
@nox.session(name="lint")
def ruff(session):
"""Lightning-fast linting for Python"""
session.install("ruff", silent=False)
session.run("ruff", "check", ".")
session.notify("tests")


@nox.session(name="nightly-tests", tags=["tests"])
def run_nightly_tests(session):
"""Run tests against nightly versions of dependencies"""
session.install("-e", ".[test]", silent=False)
# SciPy doesn't have wheels on PyPy
if platform.python_implementation() == "PyPy":
session.install("numpy", "--upgrade", silent=False, env=UV_NIGHTLY_ENV_VARS)
else:
session.install(
"numpy", "scipy", "--upgrade", silent=False, env=UV_NIGHTLY_ENV_VARS)
session.run("pytest", "--cov=autograd", "--cov-report=xml", "--cov-append", *session.posargs)
9 changes: 8 additions & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,11 @@ Source = "https://github.com/HIPS/autograd"
scipy = [
"scipy",
]
test = [
"pytest",
"pytest-cov",
"pytest-xdist",
]

[tool.coverage.run]
source = ["autograd"]
Expand All @@ -63,7 +68,9 @@ source = ["autograd"]
show_missing = true

[tool.pytest.ini_options]
addopts = "--color=yes --junitxml=junit-report.xml"
required_plugins = ["pytest-cov", "pytest-xdist"]
# TODO: generate HTML report, upload to CodeCov
addopts = "--color=yes -sra -n auto --cov=autograd --cov-report=xml --cov-report=term"

[tool.ruff]
extend-exclude = []
Expand Down
7 changes: 7 additions & 0 deletions tests/conftest.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import numpy as np
import pytest


@pytest.fixture(autouse=True)
def random_seed():
np.random.seed(42)
60 changes: 0 additions & 60 deletions tox.ini

This file was deleted.

Loading