qbe/tools/test.sh
Antonio Terceiro f7ab20680b tools/test.sh: allow running against installed package
If $bin is set in the environment, use it instead of using `qbe` from
the source tree. The same for $binref. This supports the following use
cases:

- I have a qbe package installed, and I want to test my local changes
  with the installed packages as a reference:

  $ binref=/usr/bin/qbe ./tools/test.sh all

- I want to test the installed qbe against new tests that I have
  written, to reproduce a bug:

  $ bin=/usr/bin/qbe ./tools/test.sh test/newtest.ssa

In Debian, we also run tests against the installed package when
dependencies change, etc. We will also run on several architectures
where the necessary cross compilers might not be available. So make
tests that cannot be run because of a missing compiler exit with 77,
signaling to Debian's autopkgtest that the test is skipped.
2025-03-15 14:43:00 +01:00

249 lines
3.4 KiB
Bash
Executable File

#!/bin/sh
dir=`dirname "$0"`
if [ -z "${bin:-}" ]; then
bin=$dir/../qbe
fi
if [ -z "${binref:-}" ]; then
binref=${bin}.ref
fi
tmp=/tmp/qbe.zzzz
drv=$tmp.c
asm=$tmp.s
asmref=$tmp.ref.s
exe=$tmp.exe
out=$tmp.out
init() {
case "$TARGET" in
arm64)
for p in aarch64-linux-musl aarch64-linux-gnu
do
cc="$p-gcc -no-pie -static"
qemu="qemu-aarch64"
if
$cc -v >/dev/null 2>&1 &&
$qemu -version >/dev/null 2>&1
then
if sysroot=$($cc -print-sysroot) && test -n "$sysroot"
then
qemu="$qemu -L $sysroot"
fi
break
fi
cc=
done
if test -z "$cc"
then
echo "Cannot find arm64 compiler or qemu."
exit 77
fi
bin="$bin -t arm64"
;;
rv64)
for p in riscv64-linux-musl riscv64-linux-gnu
do
cc="$p-gcc -no-pie -static"
qemu="qemu-riscv64"
if
$cc -v >/dev/null 2>&1 &&
$qemu -version >/dev/null 2>&1
then
if sysroot=$($cc -print-sysroot) && test -n "$sysroot"
then
qemu="$qemu -L $sysroot"
fi
break
fi
cc=
done
if test -z "$cc"
then
echo "Cannot find riscv64 compiler or qemu."
exit 77
fi
bin="$bin -t rv64"
;;
x86_64)
for p in x86_64-linux-musl x86_64-linux-gnu
do
cc="$p-gcc -no-pie -static"
qemu="qemu-x86_64"
if
$cc -v >/dev/null 2>&1 &&
$qemu -version >/dev/null 2>&1
then
if sysroot=$($cc -print-sysroot) && test -n "$sysroot"
then
qemu="$qemu -L $sysroot"
fi
break
fi
cc=
done
if test -z "$cc"
then
echo "Cannot find x86_64 compiler or qemu."
exit 77
fi
bin="$bin -t amd64_sysv"
;;
"")
case `uname` in
*Darwin*)
cc="cc"
;;
*OpenBSD*)
cc="cc -nopie -lpthread"
;;
*FreeBSD*)
cc="cc -lpthread"
;;
*)
cc="${CC:-cc}"
ccpost="-lpthread"
;;
esac
TARGET=`$bin -t?`
;;
*)
echo "Unknown target '$TARGET'."
exit 77
;;
esac
}
cleanup() {
rm -f $drv $asm $exe $out
}
extract() {
WHAT="$1"
FILE="$2"
awk "
/^# >>> $WHAT/ {
p = 1
next
}
/^# <<</ {
p = 0
}
p
" $FILE \
| sed -e 's/# //' \
| sed -e 's/#$//'
}
once() {
t="$1"
if ! test -f $t
then
echo "invalid test file $t" >&2
exit 1
fi
if
sed -e 1q $t |
grep "skip.* $TARGET\( .*\)\?$" \
>/dev/null
then
return 0
fi
printf "%-45s" "$(basename $t)..."
if ! $bin -o $asm $t
then
echo "[qbe fail]"
return 1
fi
if test -x $binref
then
$binref -o $asmref $t 2>/dev/null
fi
extract driver $t > $drv
extract output $t > $out
if test -s $drv
then
src="$drv $asm"
else
src="$asm"
fi
if ! $cc -g -o $exe $src $ccpost
then
echo "[cc fail]"
return 1
fi
if test -s $out
then
$qemu $exe a b c | diff -u - $out
ret=$?
reason="output"
else
$qemu $exe a b c
ret=$?
reason="returned $ret"
fi
if test $ret -ne 0
then
echo "[$reason fail]"
return 1
fi
echo "[ok]"
if test -f $asmref && ! cmp -s $asm $asmref
then
loc0=`wc -l $asm | cut -d' ' -f1`
loc1=`wc -l $asmref | cut -d' ' -f1`
printf " asm diff: %+d\n" $(($loc0 - $loc1))
return 0
fi
}
#trap cleanup TERM QUIT
init
if test -z "$1"
then
echo "usage: tools/test.sh {all, SSAFILE}" 2>&1
exit 1
fi
case "$1" in
"all")
fail=0
count=0
for t in $dir/../test/[!_]*.ssa
do
once $t
fail=`expr $fail + $?`
count=`expr $count + 1`
done
if test $fail -ge 1
then
echo
echo "$fail of $count tests failed!"
else
echo
echo "All is fine!"
fi
exit $fail
;;
*)
once $1
exit $?
;;
esac