selftests/nolibc: add script to run testsuite
authorThomas Weißschuh <linux@weissschuh.net>
Sun, 5 Nov 2023 09:23:05 +0000 (10:23 +0100)
committerThomas Weißschuh <linux@weissschuh.net>
Mon, 11 Dec 2023 21:38:17 +0000 (22:38 +0100)
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
tools/testing/selftests/nolibc/.gitignore
tools/testing/selftests/nolibc/run-tests.sh [new file with mode: 0755]

index 5119f9f7afd2eff439e1289348cd55faad00ece9..35d247a0d5bd1bc9ab1e35bdcf6a1fcd2a76f970 100644 (file)
@@ -3,4 +3,5 @@
 /libc-test
 /nolibc-test
 /run.out
+/run.out.*
 /sysroot/
diff --git a/tools/testing/selftests/nolibc/run-tests.sh b/tools/testing/selftests/nolibc/run-tests.sh
new file mode 100755 (executable)
index 0000000..1bf020d
--- /dev/null
@@ -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