gtsocial-umbx

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | README | LICENSE

run-tests.sh (3910B)


      1 #!/usr/bin/env bash
      2 # Test the current package under a different kernel.
      3 # Requires virtme and qemu to be installed.
      4 # Examples:
      5 #     Run all tests on a 5.4 kernel
      6 #     $ ./run-tests.sh 5.4
      7 #     Run a subset of tests:
      8 #     $ ./run-tests.sh 5.4 ./link
      9 
     10 set -euo pipefail
     11 
     12 script="$(realpath "$0")"
     13 readonly script
     14 
     15 # This script is a bit like a Matryoshka doll since it keeps re-executing itself
     16 # in various different contexts:
     17 #
     18 #   1. invoked by the user like run-tests.sh 5.4
     19 #   2. invoked by go test like run-tests.sh --exec-vm
     20 #   3. invoked by init in the vm like run-tests.sh --exec-test
     21 #
     22 # This allows us to use all available CPU on the host machine to compile our
     23 # code, and then only use the VM to execute the test. This is because the VM
     24 # is usually slower at compiling than the host.
     25 if [[ "${1:-}" = "--exec-vm" ]]; then
     26   shift
     27 
     28   input="$1"
     29   shift
     30 
     31   # Use sudo if /dev/kvm isn't accessible by the current user.
     32   sudo=""
     33   if [[ ! -r /dev/kvm || ! -w /dev/kvm ]]; then
     34     sudo="sudo"
     35   fi
     36   readonly sudo
     37 
     38   testdir="$(dirname "$1")"
     39   output="$(mktemp -d)"
     40   printf -v cmd "%q " "$@"
     41 
     42   if [[ "$(stat -c '%t:%T' -L /proc/$$/fd/0)" == "1:3" ]]; then
     43     # stdin is /dev/null, which doesn't play well with qemu. Use a fifo as a
     44     # blocking substitute.
     45     mkfifo "${output}/fake-stdin"
     46     # Open for reading and writing to avoid blocking.
     47     exec 0<> "${output}/fake-stdin"
     48     rm "${output}/fake-stdin"
     49   fi
     50 
     51   for ((i = 0; i < 3; i++)); do
     52     if ! $sudo virtme-run --kimg "${input}/bzImage" --memory 768M --pwd \
     53       --rwdir="${testdir}=${testdir}" \
     54       --rodir=/run/input="${input}" \
     55       --rwdir=/run/output="${output}" \
     56       --script-sh "PATH=\"$PATH\" CI_MAX_KERNEL_VERSION="${CI_MAX_KERNEL_VERSION:-}" \"$script\" --exec-test $cmd" \
     57       --kopt possible_cpus=2; then # need at least two CPUs for some tests
     58       exit 23
     59     fi
     60 
     61     if [[ -e "${output}/status" ]]; then
     62       break
     63     fi
     64 
     65     if [[ -v CI ]]; then
     66       echo "Retrying test run due to qemu crash"
     67       continue
     68     fi
     69 
     70     exit 42
     71   done
     72 
     73   rc=$(<"${output}/status")
     74   $sudo rm -r "$output"
     75   exit $rc
     76 elif [[ "${1:-}" = "--exec-test" ]]; then
     77   shift
     78 
     79   mount -t bpf bpf /sys/fs/bpf
     80   mount -t tracefs tracefs /sys/kernel/debug/tracing
     81 
     82   if [[ -d "/run/input/bpf" ]]; then
     83     export KERNEL_SELFTESTS="/run/input/bpf"
     84   fi
     85 
     86   if [[ -f "/run/input/bpf/bpf_testmod/bpf_testmod.ko" ]]; then
     87     insmod "/run/input/bpf/bpf_testmod/bpf_testmod.ko"
     88   fi
     89 
     90   dmesg --clear
     91   rc=0
     92   "$@" || rc=$?
     93   dmesg
     94   echo $rc > "/run/output/status"
     95   exit $rc # this return code is "swallowed" by qemu
     96 fi
     97 
     98 readonly kernel_version="${1:-}"
     99 if [[ -z "${kernel_version}" ]]; then
    100   echo "Expecting kernel version as first argument"
    101   exit 1
    102 fi
    103 shift
    104 
    105 readonly kernel="linux-${kernel_version}.bz"
    106 readonly selftests="linux-${kernel_version}-selftests-bpf.tgz"
    107 readonly input="$(mktemp -d)"
    108 readonly tmp_dir="${TMPDIR:-/tmp}"
    109 readonly branch="${BRANCH:-master}"
    110 
    111 fetch() {
    112     echo Fetching "${1}"
    113     pushd "${tmp_dir}" > /dev/null
    114     curl -s -L -O --fail --etag-compare "${1}.etag" --etag-save "${1}.etag" "https://github.com/cilium/ci-kernels/raw/${branch}/${1}"
    115     local ret=$?
    116     popd > /dev/null
    117     return $ret
    118 }
    119 
    120 fetch "${kernel}"
    121 cp "${tmp_dir}/${kernel}" "${input}/bzImage"
    122 
    123 if fetch "${selftests}"; then
    124   echo "Decompressing selftests"
    125   mkdir "${input}/bpf"
    126   tar --strip-components=4 -xf "${tmp_dir}/${selftests}" -C "${input}/bpf"
    127 else
    128   echo "No selftests found, disabling"
    129 fi
    130 
    131 args=(-short -coverpkg=./... -coverprofile=coverage.out -count 1 ./...)
    132 if (( $# > 0 )); then
    133   args=("$@")
    134 fi
    135 
    136 export GOFLAGS=-mod=readonly
    137 export CGO_ENABLED=0
    138 # LINUX_VERSION_CODE test compares this to discovered value.
    139 export KERNEL_VERSION="${kernel_version}"
    140 
    141 echo Testing on "${kernel_version}"
    142 go test -exec "$script --exec-vm $input" "${args[@]}"
    143 echo "Test successful on ${kernel_version}"
    144 
    145 rm -r "${input}"