blob: c34600620f98b420468ec11fb45483e29b99adf5 [file]
#!/bin/sh
#
# run-all-tests.sh -- unified runner for the two Python test suites under test/.
#
# Runs both pytest-based suites against the same built httpd:
# 1. pytest_suite/ -- the self-contained port of the classic Apache::Test
# suite (core HTTP, modules, security CVEs, SSL, PHP). Run FIRST.
# 2. pyhttpd tests under modules/ -- httpd's own HTTP/2, mod_md, HTTP/1,
# proxy and core tests (uses curl/nghttp/h2load; configured via
# pyhttpd/config.ini).
#
# Both run against the same httpd; pytest_suite locates it via --apxs, while
# the pyhttpd tests read pyhttpd/config.ini (generated by httpd's configure).
#
# Usage:
# ./run-all-tests.sh # run both suites (pytest_suite first)
# ./run-all-tests.sh --only=pysuite # run only pytest_suite
# ./run-all-tests.sh --only=pyhttpd # run only the pyhttpd modules/ tests
# ./run-all-tests.sh --apxs /path/to/apxs # override the httpd build
# ./run-all-tests.sh -k status -v # extra args pass through to BOTH pytests
# ./run-all-tests.sh --clean-modules # wipe compiled C-module artifacts before
# # building (emulate make clean; pytest_suite only)
#
# Environment overrides:
# APXS path to apxs (default: read from pyhttpd/config.ini, else $PATH)
# PHP_FPM path to php-fpm for pytest_suite's PHP tests (optional)
# PYHTTPD_TARGETS pyhttpd test paths (default: "modules")
#
set -eu
usage() {
cat <<'EOF'
Usage: run-all-tests.sh [OPTIONS] [PATHS...]
Run both Python test suites against a built httpd.
Suites (run in order):
1. pytest_suite/ -- classic Apache::Test port (HTTP, modules, SSL, CVEs)
2. modules/ -- pyhttpd tests (HTTP/2, mod_md, proxy, core)
Options:
--only=pysuite run only pytest_suite
--only=pyhttpd run only the pyhttpd modules/ tests
--apxs=PATH path to apxs for the pytest_suite build
--clean-modules wipe compiled C-module artifacts before building
(emulate make clean; pytest_suite only)
-k EXPR pytest keyword filter (passed to both suites)
-m EXPR pytest marker filter (passed to both suites)
-v, -x, ... other pytest flags (passed to both suites)
-h, --help show this help and exit
Positional PATHS are forwarded to pytest_suite only (e.g. tests/t/modules/foo).
The pyhttpd suite selects tests via PYHTTPD_TARGETS or auto-detection.
Environment:
APXS path to apxs (default: config.ini, then \$PATH)
PHP_FPM path to php-fpm for PHP tests in pytest_suite (optional)
PYHTTPD_TARGETS space-separated list of pyhttpd test paths (default: modules/*)
EOF
}
here="$(cd "$(dirname "$0")" && pwd)"
suite_dir="$here/pytest_suite"
config_ini="$here/pyhttpd/config.ini"
# Parse args once. Pull out --only and --apxs (space and = forms). Remaining
# arguments are split into:
# flags (start with '-', e.g. -v -k NAME -x): passed to BOTH pytests.
# paths (positional, e.g. tests/t/modules/...): these are pytest_suite
# paths and go ONLY to pytest_suite. The pyhttpd side selects its
# tests via PYHTTPD_TARGETS (or its auto-detected default), since a
# pytest_suite path is meaningless there.
# A flag that takes a separate-word value (-k NAME) keeps the value as a flag.
only=""
apxs_opt=""
flags=""
pysuite_flags=""
paths=""
expect_apxs=0
expect_flagval=0
for arg in "$@"; do
if [ "$expect_apxs" = "1" ]; then apxs_opt="$arg"; expect_apxs=0; continue; fi
if [ "$expect_flagval" = "1" ]; then flags="$flags $arg"; expect_flagval=0; continue; fi
case "$arg" in
-h|--help) usage; exit 0 ;;
--only=*) only="${arg#--only=}" ;;
--apxs) expect_apxs=1 ;;
--apxs=*) apxs_opt="${arg#--apxs=}" ;;
--clean-modules) pysuite_flags="$pysuite_flags $arg" ;; # pysuite-only; pyhttpd has no C modules
-k|-m|-p) flags="$flags $arg"; expect_flagval=1 ;; # take a value next
-*) flags="$flags $arg" ;;
*) paths="$paths $arg" ;;
esac
done
# --- locate apxs (for pytest_suite) -----------------------------------------
if [ -z "$apxs_opt" ]; then
if [ -n "${APXS:-}" ]; then
apxs_opt="$APXS"
elif [ -f "$config_ini" ]; then
# Resolve apxs = ${exec_prefix}/bin/apxs from config.ini (simple expand).
prefix=$(sed -n 's/^prefix = //p' "$config_ini" | head -1)
apxs_opt="$prefix/bin/apxs"
elif command -v apxs >/dev/null 2>&1; then
apxs_opt="$(command -v apxs)"
fi
fi
php_args=""
[ -n "${PHP_FPM:-}" ] && php_args="--php-fpm=$PHP_FPM"
rc=0
run_pysuite() {
echo "=========================================================="
echo "[1/2] pytest_suite (classic Apache::Test port)"
echo "=========================================================="
if [ -z "$apxs_opt" ]; then
echo "run-all-tests.sh: ERROR: no apxs found for pytest_suite." >&2
echo " Pass --apxs=/path/to/apxs or set APXS=..." >&2
return 2
fi
# runtests.sh handles venv + cgisock cleanup + flag assembly.
# pytest_suite gets both the shared flags and any positional paths.
# pysuite_flags holds options only meaningful to this suite (e.g. --clean-modules).
# shellcheck disable=SC2086
( cd "$suite_dir" && ./runtests.sh --apxs="$apxs_opt" $php_args $flags $pysuite_flags $paths ) || return $?
}
run_pyhttpd() {
echo "=========================================================="
echo "[2/2] pyhttpd suites (modules/: http2, md, http1, proxy, core)"
echo "=========================================================="
if [ ! -f "$config_ini" ]; then
echo "run-all-tests.sh: note: pyhttpd/config.ini not found;" >&2
echo " build httpd with its test config (configure) to run these." >&2
return 0
fi
# runtests.sh manages the venv, prepends its bin/ to PATH (so CGI
# scripts forked by httpd also use the venv's Python), and runs pytest.
# PYHTTPD_TARGETS can override which modules/ subdirs are run.
# shellcheck disable=SC2086
( cd "$here/pyhttpd" && ./runtests.sh $flags ) || return $?
}
case "$only" in
pysuite) run_pysuite || rc=$? ;;
pyhttpd) run_pyhttpd || rc=$? ;;
"")
# Both, pytest_suite first. Keep going if the first fails so we get
# results from both; report a non-zero overall rc if either failed.
run_pysuite || rc=$?
run_pyhttpd || rc=$?
;;
*)
echo "run-all-tests.sh: unknown --only=$only (use pysuite|pyhttpd)" >&2
exit 2
;;
esac
echo "=========================================================="
[ "$rc" -eq 0 ] && echo "ALL SUITES PASSED" || echo "SOME TESTS FAILED (rc=$rc)"
echo "=========================================================="
exit "$rc"