Skip to content

Commit

Permalink
Add basic testing automation against all version of Python using nox (#…
Browse files Browse the repository at this point in the history
…2536)

### What

This PR introduces basic support to run tests and examples against all
supported version of Python (currently 3.8 to 3.11). Currently, running
tests and `run_all.py` is supported.

Usage:
```
nox --help
nox -s tests
nox -s run_all -- --save
```

For discoverability and convenience, I added a couple of `just`
commands:

```
just py-tests-allpy
just py-run-all-allpy --save
```

On the way, I added the capability to install example requirements to
`run_all.py`:

```
python scripts/run_all.py --install-requirements
```

Decisions:
- I used [nox](https://nox.thea.codes/en/stable/). The alternative is
the older, more widespread [tox](https://tox.wiki/en/latest/). Reasons:
`noxfile.py` is an actual Python script (as are most of our scripts
already) and `nox` is battle-tested enough to be used in some large
projects, including pip itself.
- Nox is best installed globally on the dev machine (as it manages its
own venvs for running stuff). I updated `setup_dev.sh` accordingly, by
installing `pipx` using the OS package manager, and then using pipx to
install nox. (This is The Right Way™️ to globally install Python CLIs.)

Note: this requires all version of python to be installed and available
on the dev machine. Can't recommend MacPorts enough: `sudo port install
python38 python39 python310 python311`.

Relates to:
- #2445

### Checklist
* [x] I have read and agree to [Contributor
Guide](https://github.com/rerun-io/rerun/blob/main/CONTRIBUTING.md) and
the [Code of
Conduct](https://github.com/rerun-io/rerun/blob/main/CODE_OF_CONDUCT.md)
* [x] I've included a screenshot or gif (if applicable)

<!-- This line will get updated when the PR build summary job finishes.
-->
PR Build Summary: https://build.rerun.io/pr/2536

<!-- pr-link-docs:start -->
Docs preview: https://rerun.io/preview/2d89edf/docs
Examples preview: https://rerun.io/preview/2d89edf/examples
<!-- pr-link-docs:end -->

---------

Co-authored-by: Emil Ernerfeldt <emil.ernerfeldt@gmail.com>
  • Loading branch information
abey79 and emilk authored Jun 30, 2023
1 parent 4b9ff53 commit afeaa91
Show file tree
Hide file tree
Showing 5 changed files with 73 additions and 4 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -23,3 +23,5 @@ screenshot*.png

# Web demo app build
web_demo

.nox/
8 changes: 8 additions & 0 deletions justfile
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,10 @@ py-run-all-web:
py-run-all-rrd *ARGS:
just py-run-all --save {{ARGS}}

# Run all examples with all supported Python versions (through nox)
py-run-all-allpy *ARGS:
nox -s run_all -- {{ARGS}}

# Build and install the package into the venv
py-build *ARGS:
#!/usr/bin/env bash
Expand Down Expand Up @@ -86,6 +90,10 @@ py-lint:
py-test:
python -m pytest -vv rerun_py/tests/unit/

# Run tests on all supported Python versions (through nox)
py-test-allpy:
nox -s tests

# Serve the python docs locally
py-docs-serve:
mkdocs serve -f rerun_py/mkdocs.yml -w rerun_py
Expand Down
26 changes: 26 additions & 0 deletions noxfile.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
"""Nox sessions.
This file is used by `nox` to run tests and examples against multiple Python versions.
See: http://nox.thea.codes
"""

from __future__ import annotations

import nox # type: ignore


@nox.session(python=["3.8", "3.9", "3.10", "3.11"])
def tests(session: nox.Session) -> None:
"""Run the Python test suite"""
session.install("-r", "rerun_py/requirements-build.txt")
session.install("./rerun_py")
session.run("just", "py-test", external=True)


@nox.session(python=["3.8", "3.9", "3.10", "3.11"])
def run_all(session: nox.Session) -> None:
"""Run all examples through the run_all.py script (pass args with: "-- <args>")"""
# Note: the run_all.py scripts installs all dependencies itself. In particular, we can install from
# examples/python/requirements.txt because it includes pyrealsense2, which is not available for mac.
session.run("python", "scripts/run_all.py", "--install-requirements", *session.posargs)
26 changes: 26 additions & 0 deletions scripts/run_all.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
import subprocess
import time
from glob import glob
from pathlib import Path
from types import TracebackType
from typing import Any

Expand Down Expand Up @@ -185,6 +186,25 @@ def run_viewer_build(web: bool) -> None:
assert returncode == 0, f"process exited with error code {returncode}"


def run_install_requirements(examples: list[str]) -> None:
"""Install dependencies for the provided list of examples if they have a requirements.txt file."""
args = []
for example in examples:
req = Path(example) / "requirements.txt"
if req.exists():
args.extend(["-r", req])

print("Installing examples requirements…")
returncode = subprocess.Popen(
[
"pip",
"install",
*args,
]
).wait()
assert returncode == 0, f"process exited with error code {returncode}"


def run_web(examples: list[str], separate: bool) -> None:
if separate:
entries: list[tuple[str, Any, Any]] = []
Expand Down Expand Up @@ -283,6 +303,9 @@ def run_native(examples: list[str], separate: bool, close: bool) -> None:
def main() -> None:
parser = argparse.ArgumentParser(description="Runs all examples.")
parser.add_argument("--skip-build", action="store_true", help="Skip building the Python SDK.")
parser.add_argument(
"--install-requirements", action="store_true", help="Install Python requirements for each example."
)
parser.add_argument("--web", action="store_true", help="Run examples in a web viewer.")
parser.add_argument(
"--save",
Expand All @@ -306,6 +329,9 @@ def main() -> None:
if not args.save:
run_viewer_build(args.web)

if args.install_requirements:
run_install_requirements(examples)

if args.web:
run_web(examples, separate=args.separate)
return
Expand Down
15 changes: 11 additions & 4 deletions scripts/setup_dev.sh
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,12 @@ set -x

cargo install cargo-cranky # Uses lints defined in Cranky.toml. See https://github.com/ericseppanen/cargo-cranky
cargo install --locked cargo-deny # https://github.com/EmbarkStudios/cargo-deny
cargo install just # Just a command runner
cargo install taplo-cli --locked # toml formatter/linter/lsp
cargo install typos-cli
cargo install just # https://github.com/casey/just - a command runner
cargo install taplo-cli --locked # https://github.com/tamasfe/taplo - toml formatter/linter/lsp
cargo install typos-cli # https://github.com/crate-ci/typos - typo detector


packagesNeeded='pngcrush'
packagesNeeded='pngcrush pipx'
if [ -x "$(command -v brew)" ]; then brew install $packagesNeeded
elif [ -x "$(command -v port)" ]; then sudo port install $packagesNeeded
elif [ -x "$(command -v apt-get)" ]; then sudo apt-get -y install $packagesNeeded
Expand All @@ -29,4 +29,11 @@ else
exit 1
fi

# ensure pipx is on the path
pipx ensurepath

# install nox for python testing automation
# https://nox.thea.codes/en/stable/
pipx install nox

echo "setup_dev.sh completed!"

0 comments on commit afeaa91

Please sign in to comment.