-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathrun_tests.sh
More file actions
executable file
·137 lines (126 loc) · 5.45 KB
/
Copy pathrun_tests.sh
File metadata and controls
executable file
·137 lines (126 loc) · 5.45 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
#!/bin/bash
# Build Java + run the pytest conformance suite + summarise.
#
# Usage:
# ./run_tests.sh # full suite against all transports
# ./run_tests.sh pipe # only pipe transport
# ./run_tests.sh "echo_point" # keyword filter (pytest -k)
# ./run_tests.sh --no-build … # skip gradle rebuild
# ./run_tests.sh --coverage … # attach JaCoCo to each worker + emit report
#
# Full output lands in /tmp/pytest_java.txt; the summary is printed here.
# With --coverage, every spawned conformance worker runs under the JaCoCo agent
# (one .exec per process), then a merged HTML/XML report for the vgirpc library
# is produced and its headline numbers printed.
set -u
# JDK 25 matches the build toolchain. The worker (a non-published module) is
# compiled at release 25, so it must run on a >= 25 runtime; the FFM shared-
# memory overlay is active here. (Java-21 baseline degradation is covered by
# the JUnit `-PtestJdk=21` lane, not this Python conformance suite.)
#
# Honor an existing JAVA_HOME (CI's setup-java sets it); else pick JDK 25 via
# macOS java_home; else fall back to whatever `java` is on PATH.
if [[ -z "${JAVA_HOME:-}" ]] && [[ -x /usr/libexec/java_home ]]; then
JAVA_HOME=$(/usr/libexec/java_home -v 25 2>/dev/null) && export JAVA_HOME
fi
cd "$(dirname "$0")"
OUT=/tmp/pytest_java.txt
# Python with the vgi_rpc reference package importable. Override with
# VGI_RPC_PYTHON; else prefer a local reference venv, else system python3.
PY="${VGI_RPC_PYTHON:-}"
if [[ -z "$PY" ]]; then
if [[ -x "$HOME/Development/vgi-rpc/.venv/bin/python" ]]; then
PY="$HOME/Development/vgi-rpc/.venv/bin/python"
else
PY="python3"
fi
fi
BUILD=1
COVERAGE=0
while [[ $# -gt 0 ]]; do
case "${1:-}" in
--no-build) BUILD=0; shift ;;
--coverage) COVERAGE=1; shift ;;
*) break ;;
esac
done
FILTER="${1:-}"
if [[ $BUILD -eq 1 ]]; then
./gradlew -q installDist || { echo "BUILD FAILED"; exit 1; }
fi
# --- Coverage: front-load a wrapper that runs each worker under the JaCoCo
# agent. The Python suite spawns every transport's worker via the
# JAVA_CONFORMANCE_WORKER path, so swapping that for a wrapper instruments the
# entire subprocess lane without touching the suite. Each worker writes its own
# worker-<pid>.exec (unique name → no append contention); the report merges them.
if [[ $COVERAGE -eq 1 ]]; then
./gradlew -q :vgirpc:extractJacocoAgent || { echo "AGENT STAGE FAILED"; exit 1; }
AGENT="$PWD/vgirpc/build/jacoco-agent/jacocoagent.jar"
EXECDIR="$PWD/vgirpc/build/jacoco-conformance"
REAL_WORKER="$PWD/conformance-worker/build/install/conformance-worker/bin/conformance-worker"
rm -rf "$EXECDIR" && mkdir -p "$EXECDIR"
WRAPPER="$PWD/vgirpc/build/jacoco-agent/worker-wrapper.sh"
cat > "$WRAPPER" <<EOF
#!/bin/bash
# Generated by run_tests.sh --coverage. Prepends the JaCoCo agent (unique
# .exec per process) and execs the real worker start script unchanged.
export JAVA_OPTS="-javaagent:$AGENT=destfile=$EXECDIR/worker-\$\$.exec,append=false,output=file \${JAVA_OPTS:-}"
exec "$REAL_WORKER" "\$@"
EOF
chmod +x "$WRAPPER"
export JAVA_CONFORMANCE_WORKER="$WRAPPER"
echo "=== coverage: workers instrumented; .exec → $EXECDIR ==="
fi
# Kill stragglers from a previous run (HTTP/unix workers persist).
pkill -f conformance-worker 2>/dev/null
sleep 0.3
# -p no:cacheprovider keeps .pytest_cache out of the tree; --tb=line gives
# one-line tracebacks; -q keeps progress dots compact.
if [[ -n "$FILTER" ]]; then
"$PY" -m pytest tests/test_java_conformance.py \
-p no:cacheprovider --tb=short -q -k "$FILTER" \
> "$OUT" 2>&1
else
"$PY" -m pytest tests/test_java_conformance.py \
-p no:cacheprovider --tb=line -q \
> "$OUT" 2>&1
fi
PYTEST_EXIT=$?
echo "=== totals ==="
# Pytest final summary line like "X failed, Y passed, Z skipped in T s".
# Search the whole file since extra lines can follow in noisy runs.
grep -E '^[0-9]+ (failed|passed|error)' "$OUT" | tail -n 1
echo
echo "=== failures by test (deduped, first 30) ==="
grep -E '^FAILED' "$OUT" | sed -E 's/\[.*//' | sort | uniq -c | sort -rn | head -30
echo
echo "=== failures by transport ==="
grep -E '^FAILED' "$OUT" | sed -E 's/.*\[([^]]+)\].*/\1/' | sort | uniq -c
echo
echo "(full output: $OUT — use ./inspect.sh <test_id> for details)"
if [[ $COVERAGE -eq 1 ]]; then
echo
echo "=== coverage (vgirpc, conformance subprocess lane) ==="
n_exec=$(ls -1 "$EXECDIR"/*.exec 2>/dev/null | wc -l | tr -d ' ')
if [[ "$n_exec" == "0" ]]; then
echo "no .exec files captured — workers may have been SIGKILLed before the agent dumped"
else
./gradlew -q :vgirpc:jacocoConformanceReport || echo "(report generation failed)"
XML="$PWD/vgirpc/build/reports/jacoco/jacocoConformanceReport/jacocoConformanceReport.xml"
if [[ -f "$XML" ]]; then
"$PY" - "$XML" <<'PYEOF'
import sys, xml.etree.ElementTree as ET
root = ET.parse(sys.argv[1]).getroot()
# Grand totals are the <counter> elements that are direct children of <report>.
for c in root.findall("counter"):
covered = int(c.get("covered")); missed = int(c.get("missed"))
total = covered + missed
pct = (100.0 * covered / total) if total else 0.0
print(f" {c.get('type'):<12} {pct:6.2f}% ({covered}/{total})")
PYEOF
echo " HTML: vgirpc/build/reports/jacoco/jacocoConformanceReport/html/index.html"
fi
echo " merged $n_exec worker .exec file(s)"
fi
fi
exit $PYTEST_EXIT