...

Text file src/github.com/cilium/ebpf/run-tests.sh

Documentation: github.com/cilium/ebpf

     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
    10set -euo pipefail
    11
    12script="$(realpath "$0")"
    13readonly 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.
    25if [[ "${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
    76elif [[ "${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
    96fi
    97
    98readonly kernel_version="${1:-}"
    99if [[ -z "${kernel_version}" ]]; then
   100  echo "Expecting kernel version as first argument"
   101  exit 1
   102fi
   103shift
   104
   105readonly kernel="linux-${kernel_version}.bz"
   106readonly selftests="linux-${kernel_version}-selftests-bpf.tgz"
   107readonly input="$(mktemp -d)"
   108readonly tmp_dir="${TMPDIR:-/tmp}"
   109readonly branch="${BRANCH:-master}"
   110
   111fetch() {
   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
   120fetch "${kernel}"
   121cp "${tmp_dir}/${kernel}" "${input}/bzImage"
   122
   123if fetch "${selftests}"; then
   124  echo "Decompressing selftests"
   125  mkdir "${input}/bpf"
   126  tar --strip-components=4 -xf "${tmp_dir}/${selftests}" -C "${input}/bpf"
   127else
   128  echo "No selftests found, disabling"
   129fi
   130
   131args=(-short -coverpkg=./... -coverprofile=coverage.out -count 1 ./...)
   132if (( $# > 0 )); then
   133  args=("$@")
   134fi
   135
   136export GOFLAGS=-mod=readonly
   137export CGO_ENABLED=0
   138# LINUX_VERSION_CODE test compares this to discovered value.
   139export KERNEL_VERSION="${kernel_version}"
   140
   141echo Testing on "${kernel_version}"
   142go test -exec "$script --exec-vm $input" "${args[@]}"
   143echo "Test successful on ${kernel_version}"
   144
   145rm -r "${input}"

View as plain text