Files

66 lines
3.5 KiB
Bash
Executable File

#!/usr/bin/env bash
# Runs the whole hibernate-demo suite (../src) against a chosen Hibernate / Jakarta Persistence pair in a
# scratch copy, and writes a plain-text summary. The original tree is never touched.
#
# ./scripts/run-suite.sh <label> [hibernate.version jakarta-persistence.version]
# ./scripts/run-suite.sh h7 # what Spring Boot 4.1.1 manages
# ./scripts/run-suite.sh h8 8.0.0.Beta3 4.0.0-M7 # Hibernate 8 beta
set -uo pipefail
HERE="$(cd "$(dirname "$0")/.." && pwd)"
LABEL="${1:?label}"; HV="${2:-}"; PV="${3:-}"; PIN="${4:-}"; BOOT="${5:-}" # PIN=yes adds the hibernate-models / jandex pins below
W="$(mktemp -d)"
mkdir -p "$W/src" && cp -r "$HERE/../src/." "$W/src/" && cp "$HERE/../pom.xml" "$W/pom.xml"
cd "$W"
[ -n "$BOOT" ] && sed -i "0,/<version>4.1.1<\/version>/s//<version>$BOOT<\/version>/" pom.xml
if [ "$PIN" = yes ]; then
# Maven's nearest-wins rule picks hibernate-models 1.1.1 (through hibernate-search-mapper-orm) over the 1.3.4
# hibernate-core 8 asks for. Pinning is the whole fix for the classpath problem.
python3 - <<'PY'
p=open('pom.xml').read()
pin=""" <dependencyManagement><dependencies>
<dependency><groupId>org.hibernate.models</groupId><artifactId>hibernate-models</artifactId><version>1.3.4</version></dependency>
<dependency><groupId>io.smallrye</groupId><artifactId>jandex</artifactId><version>3.6.0</version></dependency>
</dependencies></dependencyManagement>
"""
open('pom.xml','w').write(p.replace('</project>',pin+'</project>'))
PY
fi
ARGS=(-B -Dmaven.test.failure.ignore=true)
[ -n "$HV" ] && ARGS+=("-Dhibernate.version=$HV")
[ -n "$PV" ] && ARGS+=("-Djakarta-persistence.version=$PV")
OUT="$HERE/output"
mvn "${ARGS[@]}" test-compile > "$W/compile.log" 2>&1; CRC=$?
{
echo "# suite on ${LABEL} hibernate=${HV:-managed by Boot 4.1.1} persistence-api=${PV:-managed by Boot 4.1.1}"
echo "spring boot parent: ${BOOT:-4.1.1}"
echo "pins (hibernate-models 1.3.4, jandex 3.6.0): ${PIN:-no}"
echo "test-compile exit code: $CRC"
} > "$OUT/suite-$LABEL.txt"
if [ $CRC -ne 0 ]; then
grep -E '^\[ERROR\] /' "$W/compile.log" | sed "s#$W/src/##" | sed 's/^\[ERROR\] //' | sort -u > "$OUT/compile-errors-$LABEL.txt"
echo "compile errors: $(wc -l < "$OUT/compile-errors-$LABEL.txt")" >> "$OUT/suite-$LABEL.txt"
else
mvn "${ARGS[@]}" test > "$W/test.log" 2>&1
python3 - "$W" >> "$OUT/suite-$LABEL.txt" <<'PY'
import glob,re,sys,collections
w=sys.argv[1]; t=f=e=s=0; causes=collections.Counter(); classes=set()
for p in sorted(glob.glob(w+'/target/surefire-reports/*.txt')):
x=open(p).read()
m=re.search(r'Tests run: (\d+), Failures: (\d+), Errors: (\d+), Skipped: (\d+)',x)
if not m: continue
a,b,c,d=map(int,m.groups()); t+=a;f+=b;e+=c;s+=d
for blk in re.split(r'\n(?=\S+ -- Time elapsed: [\d.]+ s <<< (?:ERROR|FAILURE)!)',x)[1:]:
cb=re.findall(r'Caused by: ([^\n]*)',blk)
first=blk.split('\n')[1] if '\n' in blk else ''
msg=(cb[-1] if cb else first)
msg=re.sub(r'@[0-9a-f]{5,}','@..',msg)[:170]
if 'failure threshold' in first and not cb: msg='(context failed earlier in the same JVM; see the first failure of that context)'
causes[msg]+=1; classes.add(p.split('/')[-1][:-4].split('.')[-1])
print(f'tests run: {t} failures: {f} errors: {e} skipped: {s}')
print(f'test classes with a problem: {len(classes)}')
print('distinct final causes (count = failing test methods):')
for msg,n in causes.most_common(): print(f' {n:>4} {msg}')
PY
fi
cat "$OUT/suite-$LABEL.txt"