github.com/cilium/ebpf@v0.15.0/run-tests.sh (about) 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 # Run using a local kernel image 10 # $ ./run-tests.sh /path/to/bzImage 11 12 set -euo pipefail 13 14 script="$(realpath "$0")" 15 readonly script 16 17 source "$(dirname "$script")/testdata/sh/lib.sh" 18 19 quote_env() { 20 for var in "$@"; do 21 if [ -v "$var" ]; then 22 printf "%s=%q " "$var" "${!var}" 23 fi 24 done 25 } 26 27 declare -a preserved_env=( 28 PATH 29 CI_MAX_KERNEL_VERSION 30 TEST_SEED 31 KERNEL_VERSION 32 ) 33 34 # This script is a bit like a Matryoshka doll since it keeps re-executing itself 35 # in various different contexts: 36 # 37 # 1. invoked by the user like run-tests.sh 5.4 38 # 2. invoked by go test like run-tests.sh --exec-vm 39 # 3. invoked by init in the vm like run-tests.sh --exec-test 40 # 41 # This allows us to use all available CPU on the host machine to compile our 42 # code, and then only use the VM to execute the test. This is because the VM 43 # is usually slower at compiling than the host. 44 if [[ "${1:-}" = "--exec-vm" ]]; then 45 shift 46 47 input="$1" 48 shift 49 50 # Use sudo if /dev/kvm isn't accessible by the current user. 51 sudo="" 52 if [[ ! -r /dev/kvm || ! -w /dev/kvm ]]; then 53 sudo="sudo" 54 fi 55 readonly sudo 56 57 testdir="$(dirname "$1")" 58 output="$(mktemp -d)" 59 printf -v cmd "%q " "$@" 60 61 if [[ "$(stat -c '%t:%T' -L /proc/$$/fd/0)" == "1:3" ]]; then 62 # stdin is /dev/null, which doesn't play well with qemu. Use a fifo as a 63 # blocking substitute. 64 mkfifo "${output}/fake-stdin" 65 # Open for reading and writing to avoid blocking. 66 exec 0<> "${output}/fake-stdin" 67 rm "${output}/fake-stdin" 68 fi 69 70 if ! $sudo virtme-run --kimg "${input}/boot/vmlinuz" --cpus 2 --memory 1G --pwd \ 71 --rwdir="${testdir}=${testdir}" \ 72 --rodir=/run/input="${input}" \ 73 --rwdir=/run/output="${output}" \ 74 --script-sh "$(quote_env "${preserved_env[@]}") \"$script\" \ 75 --exec-test $cmd"; then 76 exit 23 77 fi 78 79 if ! [[ -e "${output}/status" ]]; then 80 exit 42 81 fi 82 83 rc=$(<"${output}/status") 84 $sudo rm -r "$output" 85 exit "$rc" 86 elif [[ "${1:-}" = "--exec-test" ]]; then 87 shift 88 89 mount -t bpf bpf /sys/fs/bpf 90 mount -t tracefs tracefs /sys/kernel/debug/tracing 91 92 if [[ -d "/run/input/usr/src/linux/tools/testing/selftests/bpf" ]]; then 93 export KERNEL_SELFTESTS="/run/input/usr/src/linux/tools/testing/selftests/bpf" 94 fi 95 96 if [[ -d "/run/input/lib/modules" ]]; then 97 find /run/input/lib/modules -type f -name bpf_testmod.ko -exec insmod {} \; 98 fi 99 100 dmesg --clear 101 rc=0 102 "$@" || rc=$? 103 dmesg 104 echo $rc > "/run/output/status" 105 exit $rc # this return code is "swallowed" by qemu 106 fi 107 108 if [[ -z "${1:-}" ]]; then 109 echo "Expecting kernel version or path as first argument" 110 exit 1 111 fi 112 113 input="$(mktemp -d)" 114 readonly input 115 116 if [[ -f "${1}" ]]; then 117 # First argument is a local file. 118 readonly kernel="${1}" 119 cp "${1}" "${input}/boot/vmlinuz" 120 else 121 readonly kernel="${1}" 122 123 # LINUX_VERSION_CODE test compares this to discovered value. 124 export KERNEL_VERSION="${1}" 125 126 if ! extract_oci_image "ghcr.io/cilium/ci-kernels:${kernel}-selftests" "${input}"; then 127 extract_oci_image "ghcr.io/cilium/ci-kernels:${kernel}" "${input}" 128 fi 129 fi 130 shift 131 132 args=(-short -coverpkg=./... -coverprofile=coverage.out -count 1 ./...) 133 if (( $# > 0 )); then 134 args=("$@") 135 fi 136 137 export GOFLAGS=-mod=readonly 138 export CGO_ENABLED=0 139 140 echo Testing on "${kernel}" 141 go test -exec "$script --exec-vm $input" "${args[@]}" 142 echo "Test successful on ${kernel}" 143 144 rm -r "${input}"