mirror of
https://github.com/apache/httpd.git
synced 2026-10-23 22:49:01 +03:00
git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@1938683 13f79535-47bb-0310-9956-ffa450edef68
110 lines
3.6 KiB
Bash
Executable File
110 lines
3.6 KiB
Bash
Executable File
#!/bin/sh
|
|
#
|
|
# run-one-test.sh -- re-run a single test (file, directory or ::nodeid) via
|
|
# run-all-tests.sh, picking the right suite from the path.
|
|
#
|
|
# Usage:
|
|
# ./run-one-test.sh PATH[::nodeid] [pytest args...]
|
|
#
|
|
# PATH may be given as printed in the run-all-tests.sh output, or as a real
|
|
# filesystem path from anywhere, e.g.:
|
|
# ./run-one-test.sh tests/t/apache/test_404.py # pytest_suite
|
|
# ./run-one-test.sh tests/t/apache/test_404.py::test_x -v
|
|
# ./run-one-test.sh modules/http2/test_003_get.py # pyhttpd
|
|
# ./run-one-test.sh test/modules/http2/test_003_get.py
|
|
#
|
|
# With no arguments, lists all test files (one PATH per line) for grepping;
|
|
# with -l, lists every individual test (PATH::nodeid) instead:
|
|
# ./run-one-test.sh | grep -i status
|
|
# ./run-one-test.sh -l | grep -i status
|
|
#
|
|
set -eu
|
|
|
|
here="$(cd "$(dirname "$0")" && pwd)"
|
|
|
|
if [ "${1:-}" = "-h" ] || [ "${1:-}" = "--help" ]; then
|
|
sed -n '3,19p' "$0" | sed 's/^# \{0,1\}//'
|
|
exit 2
|
|
fi
|
|
|
|
# No arguments: list every test file as a PATH accepted above; -l: list every
|
|
# test as PATH::nodeid. This is a static scan (no pytest collection, so no
|
|
# built httpd needed); parametrized tests are listed once, without their
|
|
# [param] suffix.
|
|
if [ $# -eq 0 ] || { [ $# -eq 1 ] && [ "$1" = "-l" ]; }; then
|
|
cd "$here"
|
|
exec python3 - "${1:-}" pytest_suite modules <<'EOF'
|
|
import ast, os, sys, warnings
|
|
warnings.simplefilter("ignore", SyntaxWarning)
|
|
|
|
def tests(body, prefix):
|
|
for n in body:
|
|
if isinstance(n, ast.ClassDef) and n.name.startswith("Test"):
|
|
yield from tests(n.body, prefix + n.name + "::")
|
|
elif (isinstance(n, (ast.FunctionDef, ast.AsyncFunctionDef))
|
|
and n.name.startswith("test")):
|
|
yield prefix + n.name
|
|
|
|
per_test = sys.argv[1] == "-l"
|
|
for root in sys.argv[2:]:
|
|
paths = []
|
|
for d, dirs, files in os.walk(root):
|
|
dirs[:] = [x for x in dirs if not x.startswith((".", "__"))]
|
|
paths += [os.path.join(d, f) for f in files
|
|
if f.startswith("test_") and f.endswith(".py")]
|
|
for p in sorted(paths):
|
|
rel = os.path.relpath(p, root) if root == "pytest_suite" else p
|
|
if not per_test:
|
|
print(rel)
|
|
continue
|
|
try:
|
|
with open(p) as f:
|
|
tree = ast.parse(f.read(), p)
|
|
except (OSError, SyntaxError) as e:
|
|
print(f"run-one-test.sh: skipping {p}: {e}", file=sys.stderr)
|
|
continue
|
|
for t in tests(tree.body, rel + "::"):
|
|
print(t)
|
|
EOF
|
|
fi
|
|
|
|
arg="$1"; shift
|
|
file="${arg%%::*}"
|
|
node=""
|
|
[ "$file" != "$arg" ] && node="::${arg#*::}"
|
|
|
|
# Absolute path of an existing file or directory.
|
|
abspath() {
|
|
d=$(cd "$(dirname "$1")" 2>/dev/null && pwd) || return 1
|
|
echo "$d/$(basename "$1")"
|
|
}
|
|
|
|
# Try the path as given, then relative to each suite's root (how the test
|
|
# output prints them), then relative to the source tree root (test/...).
|
|
abs=""
|
|
for cand in "$file" "$here/pytest_suite/$file" "$here/$file" \
|
|
"$(dirname "$here")/$file"; do
|
|
if [ -e "$cand" ]; then abs=$(abspath "$cand"); break; fi
|
|
done
|
|
if [ -z "$abs" ]; then
|
|
echo "run-one-test.sh: no such test path: $file" >&2
|
|
exit 2
|
|
fi
|
|
|
|
case "$abs" in
|
|
"$here/pytest_suite/"*)
|
|
exec "$here/run-all-tests.sh" --only=pysuite "$@" \
|
|
"${abs#"$here/pytest_suite/"}$node"
|
|
;;
|
|
"$here/modules/"*)
|
|
# pyhttpd paths are taken from PYHTTPD_TARGETS, relative to test/.
|
|
PYHTTPD_TARGETS="${abs#"$here/"}$node"
|
|
export PYHTTPD_TARGETS
|
|
exec "$here/run-all-tests.sh" --only=pyhttpd "$@"
|
|
;;
|
|
*)
|
|
echo "run-one-test.sh: $abs is not under pytest_suite/ or modules/" >&2
|
|
exit 2
|
|
;;
|
|
esac
|