whatcanGOwrong
This commit is contained in:
@@ -0,0 +1,152 @@
|
||||
#!/usr/bin/env bash
|
||||
# Test the current package under a different kernel.
|
||||
# Requires virtme and qemu to be installed.
|
||||
# Examples:
|
||||
# Run all tests on a 5.4 kernel
|
||||
# $ ./run-tests.sh 5.4
|
||||
# Run a subset of tests:
|
||||
# $ ./run-tests.sh 5.4 ./link
|
||||
# Run using a local kernel image
|
||||
# $ ./run-tests.sh /path/to/bzImage
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
script="$(realpath "$0")"
|
||||
readonly script
|
||||
|
||||
# This script is a bit like a Matryoshka doll since it keeps re-executing itself
|
||||
# in various different contexts:
|
||||
#
|
||||
# 1. invoked by the user like run-tests.sh 5.4
|
||||
# 2. invoked by go test like run-tests.sh --exec-vm
|
||||
# 3. invoked by init in the vm like run-tests.sh --exec-test
|
||||
#
|
||||
# This allows us to use all available CPU on the host machine to compile our
|
||||
# code, and then only use the VM to execute the test. This is because the VM
|
||||
# is usually slower at compiling than the host.
|
||||
if [[ "${1:-}" = "--exec-vm" ]]; then
|
||||
shift
|
||||
|
||||
input="$1"
|
||||
shift
|
||||
|
||||
# Use sudo if /dev/kvm isn't accessible by the current user.
|
||||
sudo=""
|
||||
if [[ ! -r /dev/kvm || ! -w /dev/kvm ]]; then
|
||||
sudo="sudo"
|
||||
fi
|
||||
readonly sudo
|
||||
|
||||
testdir="$(dirname "$1")"
|
||||
output="$(mktemp -d)"
|
||||
printf -v cmd "%q " "$@"
|
||||
|
||||
if [[ "$(stat -c '%t:%T' -L /proc/$$/fd/0)" == "1:3" ]]; then
|
||||
# stdin is /dev/null, which doesn't play well with qemu. Use a fifo as a
|
||||
# blocking substitute.
|
||||
mkfifo "${output}/fake-stdin"
|
||||
# Open for reading and writing to avoid blocking.
|
||||
exec 0<> "${output}/fake-stdin"
|
||||
rm "${output}/fake-stdin"
|
||||
fi
|
||||
|
||||
for ((i = 0; i < 3; i++)); do
|
||||
if ! $sudo virtme-run --kimg "${input}/bzImage" --memory 768M --pwd \
|
||||
--rwdir="${testdir}=${testdir}" \
|
||||
--rodir=/run/input="${input}" \
|
||||
--rwdir=/run/output="${output}" \
|
||||
--script-sh "PATH=\"$PATH\" CI_MAX_KERNEL_VERSION="${CI_MAX_KERNEL_VERSION:-}" \"$script\" --exec-test $cmd" \
|
||||
--kopt possible_cpus=2; then # need at least two CPUs for some tests
|
||||
exit 23
|
||||
fi
|
||||
|
||||
if [[ -e "${output}/status" ]]; then
|
||||
break
|
||||
fi
|
||||
|
||||
if [[ -v CI ]]; then
|
||||
echo "Retrying test run due to qemu crash"
|
||||
continue
|
||||
fi
|
||||
|
||||
exit 42
|
||||
done
|
||||
|
||||
rc=$(<"${output}/status")
|
||||
$sudo rm -r "$output"
|
||||
exit $rc
|
||||
elif [[ "${1:-}" = "--exec-test" ]]; then
|
||||
shift
|
||||
|
||||
mount -t bpf bpf /sys/fs/bpf
|
||||
mount -t tracefs tracefs /sys/kernel/debug/tracing
|
||||
|
||||
if [[ -d "/run/input/bpf" ]]; then
|
||||
export KERNEL_SELFTESTS="/run/input/bpf"
|
||||
fi
|
||||
|
||||
if [[ -f "/run/input/bpf/bpf_testmod/bpf_testmod.ko" ]]; then
|
||||
insmod "/run/input/bpf/bpf_testmod/bpf_testmod.ko"
|
||||
fi
|
||||
|
||||
dmesg --clear
|
||||
rc=0
|
||||
"$@" || rc=$?
|
||||
dmesg
|
||||
echo $rc > "/run/output/status"
|
||||
exit $rc # this return code is "swallowed" by qemu
|
||||
fi
|
||||
|
||||
if [[ -z "${1:-}" ]]; then
|
||||
echo "Expecting kernel version or path as first argument"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
readonly input="$(mktemp -d)"
|
||||
readonly tmp_dir="${TMPDIR:-/tmp}"
|
||||
|
||||
fetch() {
|
||||
echo Fetching "${1}"
|
||||
pushd "${tmp_dir}" > /dev/null
|
||||
curl --no-progress-meter -L -O --fail --etag-compare "${1}.etag" --etag-save "${1}.etag" "https://github.com/cilium/ci-kernels/raw/${BRANCH:-master}/${1}"
|
||||
local ret=$?
|
||||
popd > /dev/null
|
||||
return $ret
|
||||
}
|
||||
|
||||
if [[ -f "${1}" ]]; then
|
||||
readonly kernel="${1}"
|
||||
cp "${1}" "${input}/bzImage"
|
||||
else
|
||||
# LINUX_VERSION_CODE test compares this to discovered value.
|
||||
export KERNEL_VERSION="${1}"
|
||||
|
||||
readonly kernel="linux-${1}.bz"
|
||||
readonly selftests="linux-${1}-selftests-bpf.tgz"
|
||||
|
||||
fetch "${kernel}"
|
||||
cp "${tmp_dir}/${kernel}" "${input}/bzImage"
|
||||
|
||||
if fetch "${selftests}"; then
|
||||
echo "Decompressing selftests"
|
||||
mkdir "${input}/bpf"
|
||||
tar --strip-components=4 -xf "${tmp_dir}/${selftests}" -C "${input}/bpf"
|
||||
else
|
||||
echo "No selftests found, disabling"
|
||||
fi
|
||||
fi
|
||||
shift
|
||||
|
||||
args=(-short -coverpkg=./... -coverprofile=coverage.out -count 1 ./...)
|
||||
if (( $# > 0 )); then
|
||||
args=("$@")
|
||||
fi
|
||||
|
||||
export GOFLAGS=-mod=readonly
|
||||
export CGO_ENABLED=0
|
||||
|
||||
echo Testing on "${kernel}"
|
||||
go test -exec "$script --exec-vm $input" "${args[@]}"
|
||||
echo "Test successful on ${kernel}"
|
||||
|
||||
rm -r "${input}"
|
||||
Reference in New Issue
Block a user