Run the test suite from its own venv

As root on Ubuntu, pip into the system Python cannot replace apt's
typing_extensions, so pytest was never installed and the 5.0.0
release gate failed. run_tests.sh now installs into tests/.venv and
stops on a failed install.
This commit is contained in:
Domingo Dirutigliano 2026-10-16 18:17:18 +02:00
parent 21e3027f0b
commit 79a2e1aacb
No known key found for this signature in database
3 changed files with 17 additions and 5 deletions

1
.gitignore vendored
View File

@ -67,3 +67,4 @@
/fgex-lib/firegex/_llhttp*.so
/fgex-lib/firegex/_llhttp*.pyd
/fgex-lib/build/
tests/.venv/

View File

@ -64,7 +64,9 @@ it work at all: `pip install --user` put every dependency in the invoking user's
site-packages, which a root process does not read, and the editable `firegex` is a `.pth`
there — a file only processed for *site* directories, so putting that path in `PYTHONPATH`
imports pytest and still leaves `pyworker.py --check` unable to find the filter library.
The script installs into the environment it is running in, which resolves all of it. Two
The script installs into a venv of its own (`tests/.venv`), which resolves all of it — and
not into the system interpreter, where a root pip on Ubuntu cannot replace what apt
installed (`typing_extensions`, no RECORD file) and stopped the 5.0.0 release gate. Two
things that trip a root run were found by trying it, and both are fixed rather than worked
around: the `test` group in `tests/pyproject.toml` was missing `fastapi` (see the file for why one unit test
needs the backend's own dependency, and why its absence stops the *whole* run rather than

View File

@ -47,14 +47,23 @@ fi
ADDRESS="${FIREGEX_ADDRESS:-http://127.0.0.1:4444/}"
ADDRESS="${ADDRESS%/}/"
# Into a venv of its own, never the system interpreter. As root on Ubuntu, pip into the
# system Python has to replace packages apt installed, and it cannot: `typing_extensions`
# has no RECORD file, the install stops, and the run went on to report "No module named
# pytest" — which is how the 5.0.0 release gate failed. A venv is also a site directory,
# so the editable `firegex` below is found by `sys.executable` subprocesses too.
VENV="${FIREGEX_TEST_VENV:-.venv}"
[[ -x "$VENV/bin/python3" ]] || python3 -m venv "$VENV" || exit 1
PY="$VENV/bin/python3"
# The `test` group of pyproject.toml, read here rather than with `pip install --group`,
# which needs pip 25.1 — older than what CI's runners ship.
python3 -c 'import tomllib; print("\n".join(tomllib.load(open("pyproject.toml", "rb"))["dependency-groups"]["test"]))' \
| pip3 install -q -r /dev/stdin
"$PY" -c 'import tomllib; print("\n".join(tomllib.load(open("pyproject.toml", "rb"))["dependency-groups"]["test"]))' \
| "$PY" -m pip install -q -r /dev/stdin || exit 1
# The filter library is imported straight out of the source tree, and it carries a C
# extension — the llhttp binding that parses HTTP — which therefore has to be built. An
# editable install builds it in place; without this `unit/` cannot even be collected.
pip3 install -q -e ../fgex-lib
"$PY" -m pip install -q -e ../fgex-lib || exit 1
printf 'Waiting for firegex at %s' "$ADDRESS"
until curl --output /dev/null --silent --fail "${ADDRESS}api/status"; do
@ -69,4 +78,4 @@ if [[ "$SET_PASSWORD" == "1" ]]; then
echo "Password set."
fi
exec python3 -m pytest --fg-address "$ADDRESS" --fg-password "$PASSWORD" "$@"
exec "$PY" -m pytest --fg-address "$ADDRESS" --fg-password "$PASSWORD" "$@"