selftests/nolibc: add script to run testsuite

The script can run the testsuite for multiple architectures and provides
an overall test report.

Furthermore it can automatically download crosstools from
mirrors.kernel.org if requested by the user.

Example execution:

$ ./run-tests.sh
i386:          162 test(s): 162 passed,   0 skipped,   0 failed => status: success
x86_64:        162 test(s): 162 passed,   0 skipped,   0 failed => status: success
arm64:         162 test(s): 162 passed,   0 skipped,   0 failed => status: success
arm:           162 test(s): 162 passed,   0 skipped,   0 failed => status: success
mips:          162 test(s): 161 passed,   1 skipped,   0 failed => status: warning
ppc:           162 test(s): 162 passed,   0 skipped,   0 failed => status: success
ppc64:         162 test(s): 162 passed,   0 skipped,   0 failed => status: success
ppc64le:       162 test(s): 162 passed,   0 skipped,   0 failed => status: success
riscv:         162 test(s): 162 passed,   0 skipped,   0 failed => status: success
s390:          162 test(s): 161 passed,   1 skipped,   0 failed => status: warning
loongarch:     162 test(s): 161 passed,   1 skipped,   0 failed => status: warning

Signed-off-by: Thomas Weißschuh <linux@weissschuh.net>
Acked-by: Willy Tarreau <w@1wt.eu>
Link: https://lore.kernel.org/r/20231105-nolibc-run-tests-v1-1-b59ff770a978@weissschuh.net
This commit is contained in:
Thomas Weißschuh 2023-11-05 10:23:05 +01:00
parent 69620b3a5b
commit 91f1645159
2 changed files with 154 additions and 0 deletions

View file

@ -3,4 +3,5 @@
/libc-test
/nolibc-test
/run.out
/run.out.*
/sysroot/

View file

@ -0,0 +1,153 @@
#!/bin/bash
# SPDX-License-Identifier: GPL-2.0
# Test runner for nolibc tests
set -e
trap 'echo Aborting...' 'ERR'
crosstool_version=13.2.0
hostarch=x86_64
nproc=$(( $(nproc) + 2))
cache_dir="${XDG_CACHE_HOME:-"$HOME"/.cache}"
download_location="${cache_dir}/crosstools/"
build_location="$(realpath "${cache_dir}"/nolibc-tests/)"
perform_download=0
archs="i386 x86_64 arm64 arm mips ppc ppc64 ppc64le riscv s390 loongarch"
TEMP=$(getopt -o 'j:d:c:b:a:ph' -n "$0" -- "$@")
eval set -- "$TEMP"
unset TEMP
print_usage() {
cat <<EOF
Run nolibc testsuite for multiple architectures with crosstools
Usage:
$0 [options] <architectures>
Known architectures:
${archs}
Options:
-j [N] Allow N jobs at once (default: ${nproc})
-p Allow download of toolchains
-d [DIR] Download location for toolchains (default: ${download_location})
-c [VERSION] Version of toolchains to use (default: ${crosstool_version})
-a [ARCH] Host architecture of toolchains to use (default: ${hostarch})
-b [DIR] Build location (default: ${build_location})
EOF
}
while true; do
case "$1" in
'-j')
nproc="$2"
shift 2; continue ;;
'-p')
perform_download=1
shift; continue ;;
'-d')
download_location="$2"
shift 2; continue ;;
'-c')
crosstool_version="$2"
shift 2; continue ;;
'-a')
hostarch="$2"
shift 2; continue ;;
'-b')
build_location="$(realpath "$2")"
shift 2; continue ;;
'-h')
print_usage
exit 0
;;
'--')
shift; break ;;
*)
echo 'Internal error!' >&2; exit 1 ;;
esac
done
if [[ -n "$*" ]]; then
archs="$*"
fi
crosstool_arch() {
case "$1" in
arm64) echo aarch64;;
ppc) echo powerpc;;
ppc64) echo powerpc64;;
ppc64le) echo powerpc64;;
riscv) echo riscv64;;
loongarch) echo loongarch64;;
mips*) echo mips;;
*) echo "$1";;
esac
}
crosstool_abi() {
case "$1" in
arm) echo linux-gnueabi;;
*) echo linux;;
esac
}
download_crosstool() {
arch="$(crosstool_arch "$1")"
abi="$(crosstool_abi "$1")"
archive_name="${hostarch}-gcc-${crosstool_version}-nolibc-${arch}-${abi}.tar.gz"
url="https://mirrors.edge.kernel.org/pub/tools/crosstool/files/bin/${hostarch}/${crosstool_version}/${archive_name}"
archive="${download_location}${archive_name}"
stamp="${archive}.stamp"
[ -f "${stamp}" ] && return
echo "Downloading crosstools ${arch} ${crosstool_version}"
mkdir -p "${download_location}"
curl -o "${archive}" --fail --continue-at - "${url}"
tar -C "${download_location}" -xf "${archive}"
touch "${stamp}"
}
# capture command output, print it on failure
# mimics chronic(1) from moreutils
function swallow_output() {
if ! OUTPUT="$("$@" 2>&1)"; then
echo "$OUTPUT"
return 1
fi
return 0
}
test_arch() {
arch=$1
ct_arch=$(crosstool_arch "$arch")
ct_abi=$(crosstool_abi "$1")
cross_compile=$(realpath "${download_location}gcc-${crosstool_version}-nolibc/${ct_arch}-${ct_abi}/bin/${ct_arch}-${ct_abi}-")
build_dir="${build_location}/${arch}"
MAKE=(make -j"${nproc}" XARCH="${arch}" CROSS_COMPILE="${cross_compile}" O="${build_dir}")
mkdir -p "$build_dir"
if [ ! -f "${build_dir}/.config" ]; then
swallow_output "${MAKE[@]}" defconfig
fi
printf '%-15s' "$arch:"
swallow_output "${MAKE[@]}" run V=1
cp run.out run.out."${arch}"
"${MAKE[@]}" report | grep passed
}
if [ "$perform_download" -ne 0 ]; then
for arch in $archs; do
download_crosstool "$arch"
done
fi
for arch in $archs; do
test_arch "$arch"
done