Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Merge branch 'for-6.18/selftests' into for-linus

- update vmtest.sh (Benjamin Tissoires)

+446 -268
+446 -268
tools/testing/selftests/hid/vmtest.sh
··· 1 1 #!/bin/bash 2 2 # SPDX-License-Identifier: GPL-2.0 3 + # 4 + # Copyright (c) 2025 Red Hat 5 + # Copyright (c) 2025 Meta Platforms, Inc. and affiliates 6 + # 7 + # Dependencies: 8 + # * virtme-ng 9 + # * busybox-static (used by virtme-ng) 10 + # * qemu (used by virtme-ng) 3 11 4 - set -u 5 - set -e 12 + readonly SCRIPT_DIR="$(cd -P -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd -P)" 13 + readonly KERNEL_CHECKOUT=$(realpath "${SCRIPT_DIR}"/../../../../) 6 14 7 - # This script currently only works for x86_64 8 - ARCH="$(uname -m)" 9 - case "${ARCH}" in 10 - x86_64) 11 - QEMU_BINARY=qemu-system-x86_64 12 - BZIMAGE="arch/x86/boot/bzImage" 13 - ;; 14 - *) 15 - echo "Unsupported architecture" 16 - exit 1 17 - ;; 18 - esac 19 - SCRIPT_DIR="$(dirname $(realpath $0))" 20 - OUTPUT_DIR="$SCRIPT_DIR/results" 21 - KCONFIG_REL_PATHS=("${SCRIPT_DIR}/config" "${SCRIPT_DIR}/config.common" "${SCRIPT_DIR}/config.${ARCH}") 22 - B2C_URL="https://gitlab.freedesktop.org/gfx-ci/boot2container/-/raw/main/vm2c.py" 23 - NUM_COMPILE_JOBS="$(nproc)" 24 - LOG_FILE_BASE="$(date +"hid_selftests.%Y-%m-%d_%H-%M-%S")" 25 - LOG_FILE="${LOG_FILE_BASE}.log" 26 - EXIT_STATUS_FILE="${LOG_FILE_BASE}.exit_status" 27 - CONTAINER_IMAGE="registry.freedesktop.org/bentiss/hid/fedora/39:2023-11-22.1" 15 + source "${SCRIPT_DIR}"/../kselftest/ktap_helpers.sh 28 16 29 - TARGETS="${TARGETS:=$(basename ${SCRIPT_DIR})}" 30 - DEFAULT_COMMAND="pip3 install hid-tools; make -C tools/testing/selftests TARGETS=${TARGETS} run_tests" 17 + readonly HID_BPF_TEST="${SCRIPT_DIR}"/hid_bpf 18 + readonly HIDRAW_TEST="${SCRIPT_DIR}"/hidraw 19 + readonly HID_BPF_PROGS="${KERNEL_CHECKOUT}/drivers/hid/bpf/progs" 20 + readonly SSH_GUEST_PORT=22 21 + readonly WAIT_PERIOD=3 22 + readonly WAIT_PERIOD_MAX=60 23 + readonly WAIT_TOTAL=$(( WAIT_PERIOD * WAIT_PERIOD_MAX )) 24 + readonly QEMU_PIDFILE=$(mktemp /tmp/qemu_hid_vmtest_XXXX.pid) 31 25 32 - usage() 33 - { 34 - cat <<EOF 35 - Usage: $0 [-j N] [-s] [-b] [-d <output_dir>] -- [<command>] 26 + readonly QEMU_OPTS="\ 27 + --pidfile ${QEMU_PIDFILE} \ 28 + " 29 + readonly KERNEL_CMDLINE="" 30 + readonly LOG=$(mktemp /tmp/hid_vmtest_XXXX.log) 31 + readonly TEST_NAMES=(vm_hid_bpf vm_hidraw vm_pytest) 32 + readonly TEST_DESCS=( 33 + "Run hid_bpf tests in the VM." 34 + "Run hidraw tests in the VM." 35 + "Run the hid-tools test-suite in the VM." 36 + ) 36 37 37 - <command> is the command you would normally run when you are in 38 - the source kernel direcory. e.g: 38 + VERBOSE=0 39 + SHELL_MODE=0 40 + BUILD_HOST="" 41 + BUILD_HOST_PODMAN_CONTAINER_NAME="" 39 42 40 - $0 -- ./tools/testing/selftests/hid/hid_bpf 43 + usage() { 44 + local name 45 + local desc 46 + local i 41 47 42 - If no command is specified and a debug shell (-s) is not requested, 43 - "${DEFAULT_COMMAND}" will be run by default. 48 + echo 49 + echo "$0 [OPTIONS] [TEST]... [-- tests-args]" 50 + echo "If no TEST argument is given, all tests will be run." 51 + echo 52 + echo "Options" 53 + echo " -b: build the kernel from the current source tree and use it for guest VMs" 54 + echo " -H: hostname for remote build host (used with -b)" 55 + echo " -p: podman container name for remote build host (used with -b)" 56 + echo " Example: -H beefyserver -p vng" 57 + echo " -q: set the path to or name of qemu binary" 58 + echo " -s: start a shell in the VM instead of running tests" 59 + echo " -v: more verbose output (can be repeated multiple times)" 60 + echo 61 + echo "Available tests" 44 62 45 - If you build your kernel using KBUILD_OUTPUT= or O= options, these 46 - can be passed as environment variables to the script: 47 - 48 - O=<kernel_build_path> $0 -- ./tools/testing/selftests/hid/hid_bpf 49 - 50 - or 51 - 52 - KBUILD_OUTPUT=<kernel_build_path> $0 -- ./tools/testing/selftests/hid/hid_bpf 53 - 54 - Options: 55 - 56 - -u) Update the boot2container script to a newer version. 57 - -d) Update the output directory (default: ${OUTPUT_DIR}) 58 - -b) Run only the build steps for the kernel and the selftests 59 - -j) Number of jobs for compilation, similar to -j in make 60 - (default: ${NUM_COMPILE_JOBS}) 61 - -s) Instead of powering off the VM, start an interactive 62 - shell. If <command> is specified, the shell runs after 63 - the command finishes executing 64 - EOF 65 - } 66 - 67 - download() 68 - { 69 - local file="$1" 70 - 71 - echo "Downloading $file..." >&2 72 - curl -Lsf "$file" -o "${@:2}" 73 - } 74 - 75 - recompile_kernel() 76 - { 77 - local kernel_checkout="$1" 78 - local make_command="$2" 79 - 80 - cd "${kernel_checkout}" 81 - 82 - ${make_command} olddefconfig 83 - ${make_command} headers 84 - ${make_command} 85 - } 86 - 87 - update_selftests() 88 - { 89 - local kernel_checkout="$1" 90 - local selftests_dir="${kernel_checkout}/tools/testing/selftests/hid" 91 - 92 - cd "${selftests_dir}" 93 - ${make_command} 94 - } 95 - 96 - run_vm() 97 - { 98 - local run_dir="$1" 99 - local b2c="$2" 100 - local kernel_bzimage="$3" 101 - local command="$4" 102 - local post_command="" 103 - 104 - cd "${run_dir}" 105 - 106 - if ! which "${QEMU_BINARY}" &> /dev/null; then 107 - cat <<EOF 108 - Could not find ${QEMU_BINARY} 109 - Please install qemu or set the QEMU_BINARY environment variable. 110 - EOF 111 - exit 1 112 - fi 113 - 114 - # alpine (used in post-container requires the PATH to have /bin 115 - export PATH=$PATH:/bin 116 - 117 - if [[ "${debug_shell}" != "yes" ]] 118 - then 119 - touch ${OUTPUT_DIR}/${LOG_FILE} 120 - command="mount bpffs -t bpf /sys/fs/bpf/; set -o pipefail ; ${command} 2>&1 | tee ${OUTPUT_DIR}/${LOG_FILE}" 121 - post_command="cat ${OUTPUT_DIR}/${LOG_FILE}" 122 - else 123 - command="mount bpffs -t bpf /sys/fs/bpf/; ${command}" 124 - fi 125 - 126 - set +e 127 - $b2c --command "${command}" \ 128 - --kernel ${kernel_bzimage} \ 129 - --workdir ${OUTPUT_DIR} \ 130 - --image ${CONTAINER_IMAGE} 131 - 132 - echo $? > ${OUTPUT_DIR}/${EXIT_STATUS_FILE} 133 - 134 - set -e 135 - 136 - ${post_command} 137 - } 138 - 139 - is_rel_path() 140 - { 141 - local path="$1" 142 - 143 - [[ ${path:0:1} != "/" ]] 144 - } 145 - 146 - do_update_kconfig() 147 - { 148 - local kernel_checkout="$1" 149 - local kconfig_file="$2" 150 - 151 - rm -f "$kconfig_file" 2> /dev/null 152 - 153 - for config in "${KCONFIG_REL_PATHS[@]}"; do 154 - local kconfig_src="${config}" 155 - cat "$kconfig_src" >> "$kconfig_file" 63 + for ((i = 0; i < ${#TEST_NAMES[@]}; i++)); do 64 + name=${TEST_NAMES[${i}]} 65 + desc=${TEST_DESCS[${i}]} 66 + printf "\t%-35s%-35s\n" "${name}" "${desc}" 156 67 done 68 + echo 69 + 70 + exit 1 157 71 } 158 72 159 - update_kconfig() 160 - { 161 - local kernel_checkout="$1" 162 - local kconfig_file="$2" 73 + die() { 74 + echo "$*" >&2 75 + exit "${KSFT_FAIL}" 76 + } 163 77 164 - if [[ -f "${kconfig_file}" ]]; then 165 - local local_modified="$(stat -c %Y "${kconfig_file}")" 78 + vm_ssh() { 79 + # vng --ssh-client keeps shouting "Warning: Permanently added 'virtme-ng%22' 80 + # (ED25519) to the list of known hosts.", 81 + # So replace the command with what's actually called and add the "-q" option 82 + stdbuf -oL ssh -q \ 83 + -F ${HOME}/.cache/virtme-ng/.ssh/virtme-ng-ssh.conf \ 84 + -l root virtme-ng%${SSH_GUEST_PORT} \ 85 + "$@" 86 + return $? 87 + } 166 88 167 - for config in "${KCONFIG_REL_PATHS[@]}"; do 168 - local kconfig_src="${config}" 169 - local src_modified="$(stat -c %Y "${kconfig_src}")" 170 - # Only update the config if it has been updated after the 171 - # previously cached config was created. This avoids 172 - # unnecessarily compiling the kernel and selftests. 173 - if [[ "${src_modified}" -gt "${local_modified}" ]]; then 174 - do_update_kconfig "$kernel_checkout" "$kconfig_file" 175 - # Once we have found one outdated configuration 176 - # there is no need to check other ones. 89 + cleanup() { 90 + if [[ -s "${QEMU_PIDFILE}" ]]; then 91 + pkill -SIGTERM -F "${QEMU_PIDFILE}" > /dev/null 2>&1 92 + fi 93 + 94 + # If failure occurred during or before qemu start up, then we need 95 + # to clean this up ourselves. 96 + if [[ -e "${QEMU_PIDFILE}" ]]; then 97 + rm "${QEMU_PIDFILE}" 98 + fi 99 + } 100 + 101 + check_args() { 102 + local found 103 + 104 + for arg in "$@"; do 105 + found=0 106 + for name in "${TEST_NAMES[@]}"; do 107 + if [[ "${name}" = "${arg}" ]]; then 108 + found=1 177 109 break 178 110 fi 179 111 done 180 - else 181 - do_update_kconfig "$kernel_checkout" "$kconfig_file" 182 - fi 183 - } 184 112 185 - main() 186 - { 187 - local script_dir="$(cd -P -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd -P)" 188 - local kernel_checkout=$(realpath "${script_dir}"/../../../../) 189 - # By default the script searches for the kernel in the checkout directory but 190 - # it also obeys environment variables O= and KBUILD_OUTPUT= 191 - local kernel_bzimage="${kernel_checkout}/${BZIMAGE}" 192 - local command="${DEFAULT_COMMAND}" 193 - local update_b2c="no" 194 - local debug_shell="no" 195 - local build_only="no" 196 - 197 - while getopts ':hsud:j:b' opt; do 198 - case ${opt} in 199 - u) 200 - update_b2c="yes" 201 - ;; 202 - d) 203 - OUTPUT_DIR="$OPTARG" 204 - ;; 205 - j) 206 - NUM_COMPILE_JOBS="$OPTARG" 207 - ;; 208 - s) 209 - command="/bin/sh" 210 - debug_shell="yes" 211 - ;; 212 - b) 213 - build_only="yes" 214 - ;; 215 - h) 113 + if [[ "${found}" -eq 0 ]]; then 114 + echo "${arg} is not an available test" >&2 216 115 usage 217 - exit 0 218 - ;; 219 - \? ) 220 - echo "Invalid Option: -$OPTARG" 221 - usage 222 - exit 1 223 - ;; 224 - : ) 225 - echo "Invalid Option: -$OPTARG requires an argument" 226 - usage 227 - exit 1 228 - ;; 229 - esac 116 + fi 230 117 done 231 - shift $((OPTIND -1)) 232 118 233 - # trap 'catch "$?"' EXIT 234 - if [[ "${build_only}" == "no" && "${debug_shell}" == "no" ]]; then 235 - if [[ $# -eq 0 ]]; then 236 - echo "No command specified, will run ${DEFAULT_COMMAND} in the vm" 237 - else 238 - command="$@" 239 - 240 - if [[ "${command}" == "/bin/bash" || "${command}" == "bash" ]] 241 - then 242 - debug_shell="yes" 243 - fi 119 + for arg in "$@"; do 120 + if ! command -v > /dev/null "test_${arg}"; then 121 + echo "Test ${arg} not found" >&2 122 + usage 244 123 fi 124 + done 125 + } 126 + 127 + check_deps() { 128 + for dep in vng ${QEMU} busybox pkill ssh pytest; do 129 + if [[ ! -x $(command -v "${dep}") ]]; then 130 + echo -e "skip: dependency ${dep} not found!\n" 131 + exit "${KSFT_SKIP}" 132 + fi 133 + done 134 + 135 + if [[ ! -x $(command -v "${HID_BPF_TEST}") ]]; then 136 + printf "skip: %s not found!" "${HID_BPF_TEST}" 137 + printf " Please build the kselftest hid_bpf target.\n" 138 + exit "${KSFT_SKIP}" 245 139 fi 246 140 247 - local kconfig_file="${OUTPUT_DIR}/latest.config" 248 - local make_command="make -j ${NUM_COMPILE_JOBS} KCONFIG_CONFIG=${kconfig_file}" 249 - 250 - # Figure out where the kernel is being built. 251 - # O takes precedence over KBUILD_OUTPUT. 252 - if [[ "${O:=""}" != "" ]]; then 253 - if is_rel_path "${O}"; then 254 - O="$(realpath "${PWD}/${O}")" 255 - fi 256 - kernel_bzimage="${O}/${BZIMAGE}" 257 - make_command="${make_command} O=${O}" 258 - elif [[ "${KBUILD_OUTPUT:=""}" != "" ]]; then 259 - if is_rel_path "${KBUILD_OUTPUT}"; then 260 - KBUILD_OUTPUT="$(realpath "${PWD}/${KBUILD_OUTPUT}")" 261 - fi 262 - kernel_bzimage="${KBUILD_OUTPUT}/${BZIMAGE}" 263 - make_command="${make_command} KBUILD_OUTPUT=${KBUILD_OUTPUT}" 264 - fi 265 - 266 - local b2c="${OUTPUT_DIR}/vm2c.py" 267 - 268 - echo "Output directory: ${OUTPUT_DIR}" 269 - 270 - mkdir -p "${OUTPUT_DIR}" 271 - update_kconfig "${kernel_checkout}" "${kconfig_file}" 272 - 273 - recompile_kernel "${kernel_checkout}" "${make_command}" 274 - update_selftests "${kernel_checkout}" "${make_command}" 275 - 276 - if [[ "${build_only}" == "no" ]]; then 277 - if [[ "${update_b2c}" == "no" && ! -f "${b2c}" ]]; then 278 - echo "vm2c script not found in ${b2c}" 279 - update_b2c="yes" 280 - fi 281 - 282 - if [[ "${update_b2c}" == "yes" ]]; then 283 - download $B2C_URL $b2c 284 - chmod +x $b2c 285 - fi 286 - 287 - run_vm "${kernel_checkout}" $b2c "${kernel_bzimage}" "${command}" 288 - if [[ "${debug_shell}" != "yes" ]]; then 289 - echo "Logs saved in ${OUTPUT_DIR}/${LOG_FILE}" 290 - fi 291 - 292 - exit $(cat ${OUTPUT_DIR}/${EXIT_STATUS_FILE}) 141 + if [[ ! -x $(command -v "${HIDRAW_TEST}") ]]; then 142 + printf "skip: %s not found!" "${HIDRAW_TEST}" 143 + printf " Please build the kselftest hidraw target.\n" 144 + exit "${KSFT_SKIP}" 293 145 fi 294 146 } 295 147 296 - main "$@" 148 + check_vng() { 149 + local tested_versions 150 + local version 151 + local ok 152 + 153 + tested_versions=("1.36" "1.37") 154 + version="$(vng --version)" 155 + 156 + ok=0 157 + for tv in "${tested_versions[@]}"; do 158 + if [[ "${version}" == *"${tv}"* ]]; then 159 + ok=1 160 + break 161 + fi 162 + done 163 + 164 + if [[ ! "${ok}" -eq 1 ]]; then 165 + printf "warning: vng version '%s' has not been tested and may " "${version}" >&2 166 + printf "not function properly.\n\tThe following versions have been tested: " >&2 167 + echo "${tested_versions[@]}" >&2 168 + fi 169 + } 170 + 171 + handle_build() { 172 + if [[ ! "${BUILD}" -eq 1 ]]; then 173 + return 174 + fi 175 + 176 + if [[ ! -d "${KERNEL_CHECKOUT}" ]]; then 177 + echo "-b requires vmtest.sh called from the kernel source tree" >&2 178 + exit 1 179 + fi 180 + 181 + pushd "${KERNEL_CHECKOUT}" &>/dev/null 182 + 183 + if ! vng --kconfig --config "${SCRIPT_DIR}"/config; then 184 + die "failed to generate .config for kernel source tree (${KERNEL_CHECKOUT})" 185 + fi 186 + 187 + local vng_args=("-v" "--config" "${SCRIPT_DIR}/config" "--build") 188 + 189 + if [[ -n "${BUILD_HOST}" ]]; then 190 + vng_args+=("--build-host" "${BUILD_HOST}") 191 + fi 192 + 193 + if [[ -n "${BUILD_HOST_PODMAN_CONTAINER_NAME}" ]]; then 194 + vng_args+=("--build-host-exec-prefix" \ 195 + "podman exec -ti ${BUILD_HOST_PODMAN_CONTAINER_NAME}") 196 + fi 197 + 198 + if ! vng "${vng_args[@]}"; then 199 + die "failed to build kernel from source tree (${KERNEL_CHECKOUT})" 200 + fi 201 + 202 + if ! make -j$(nproc) -C "${HID_BPF_PROGS}"; then 203 + die "failed to build HID bpf objects from source tree (${HID_BPF_PROGS})" 204 + fi 205 + 206 + if ! make -j$(nproc) -C "${SCRIPT_DIR}"; then 207 + die "failed to build HID selftests from source tree (${SCRIPT_DIR})" 208 + fi 209 + 210 + popd &>/dev/null 211 + } 212 + 213 + vm_start() { 214 + local logfile=/dev/null 215 + local verbose_opt="" 216 + local kernel_opt="" 217 + local qemu 218 + 219 + qemu=$(command -v "${QEMU}") 220 + 221 + if [[ "${VERBOSE}" -eq 2 ]]; then 222 + verbose_opt="--verbose" 223 + logfile=/dev/stdout 224 + fi 225 + 226 + # If we are running from within the kernel source tree, use the kernel source tree 227 + # as the kernel to boot, otherwise use the currently running kernel. 228 + if [[ "$(realpath "$(pwd)")" == "${KERNEL_CHECKOUT}"* ]]; then 229 + kernel_opt="${KERNEL_CHECKOUT}" 230 + fi 231 + 232 + vng \ 233 + --run \ 234 + ${kernel_opt} \ 235 + ${verbose_opt} \ 236 + --qemu-opts="${QEMU_OPTS}" \ 237 + --qemu="${qemu}" \ 238 + --user root \ 239 + --append "${KERNEL_CMDLINE}" \ 240 + --ssh "${SSH_GUEST_PORT}" \ 241 + --rw &> ${logfile} & 242 + 243 + local vng_pid=$! 244 + local elapsed=0 245 + 246 + while [[ ! -s "${QEMU_PIDFILE}" ]]; do 247 + if ! kill -0 "${vng_pid}" 2>/dev/null; then 248 + echo "vng process (PID ${vng_pid}) exited early, check logs for details" >&2 249 + die "failed to boot VM" 250 + fi 251 + 252 + if [[ ${elapsed} -ge ${WAIT_TOTAL} ]]; then 253 + echo "Timed out after ${WAIT_TOTAL} seconds waiting for VM to boot" >&2 254 + die "failed to boot VM" 255 + fi 256 + 257 + sleep 1 258 + elapsed=$((elapsed + 1)) 259 + done 260 + } 261 + 262 + vm_wait_for_ssh() { 263 + local i 264 + 265 + i=0 266 + while true; do 267 + if [[ ${i} -gt ${WAIT_PERIOD_MAX} ]]; then 268 + die "Timed out waiting for guest ssh" 269 + fi 270 + if vm_ssh -- true; then 271 + break 272 + fi 273 + i=$(( i + 1 )) 274 + sleep ${WAIT_PERIOD} 275 + done 276 + } 277 + 278 + vm_mount_bpffs() { 279 + vm_ssh -- mount bpffs -t bpf /sys/fs/bpf 280 + } 281 + 282 + __log_stdin() { 283 + stdbuf -oL awk '{ printf "%s:\t%s\n","'"${prefix}"'", $0; fflush() }' 284 + } 285 + 286 + __log_args() { 287 + echo "$*" | awk '{ printf "%s:\t%s\n","'"${prefix}"'", $0 }' 288 + } 289 + 290 + log() { 291 + local verbose="$1" 292 + shift 293 + 294 + local prefix="$1" 295 + 296 + shift 297 + local redirect= 298 + if [[ ${verbose} -le 0 ]]; then 299 + redirect=/dev/null 300 + else 301 + redirect=/dev/stdout 302 + fi 303 + 304 + if [[ "$#" -eq 0 ]]; then 305 + __log_stdin | tee -a "${LOG}" > ${redirect} 306 + else 307 + __log_args "$@" | tee -a "${LOG}" > ${redirect} 308 + fi 309 + } 310 + 311 + log_setup() { 312 + log $((VERBOSE-1)) "setup" "$@" 313 + } 314 + 315 + log_host() { 316 + local testname=$1 317 + 318 + shift 319 + log $((VERBOSE-1)) "test:${testname}:host" "$@" 320 + } 321 + 322 + log_guest() { 323 + local testname=$1 324 + 325 + shift 326 + log ${VERBOSE} "# test:${testname}" "$@" 327 + } 328 + 329 + test_vm_hid_bpf() { 330 + local testname="${FUNCNAME[0]#test_}" 331 + 332 + vm_ssh -- "${HID_BPF_TEST}" \ 333 + 2>&1 | log_guest "${testname}" 334 + 335 + return ${PIPESTATUS[0]} 336 + } 337 + 338 + test_vm_hidraw() { 339 + local testname="${FUNCNAME[0]#test_}" 340 + 341 + vm_ssh -- "${HIDRAW_TEST}" \ 342 + 2>&1 | log_guest "${testname}" 343 + 344 + return ${PIPESTATUS[0]} 345 + } 346 + 347 + test_vm_pytest() { 348 + local testname="${FUNCNAME[0]#test_}" 349 + 350 + shift 351 + 352 + vm_ssh -- pytest ${SCRIPT_DIR}/tests --color=yes "$@" \ 353 + 2>&1 | log_guest "${testname}" 354 + 355 + return ${PIPESTATUS[0]} 356 + } 357 + 358 + run_test() { 359 + local vm_oops_cnt_before 360 + local vm_warn_cnt_before 361 + local vm_oops_cnt_after 362 + local vm_warn_cnt_after 363 + local name 364 + local rc 365 + 366 + vm_oops_cnt_before=$(vm_ssh -- dmesg | grep -c -i 'Oops') 367 + vm_error_cnt_before=$(vm_ssh -- dmesg --level=err | wc -l) 368 + 369 + name=$(echo "${1}" | awk '{ print $1 }') 370 + eval test_"${name}" "$@" 371 + rc=$? 372 + 373 + vm_oops_cnt_after=$(vm_ssh -- dmesg | grep -i 'Oops' | wc -l) 374 + if [[ ${vm_oops_cnt_after} -gt ${vm_oops_cnt_before} ]]; then 375 + echo "FAIL: kernel oops detected on vm" | log_host "${name}" 376 + rc=$KSFT_FAIL 377 + fi 378 + 379 + vm_error_cnt_after=$(vm_ssh -- dmesg --level=err | wc -l) 380 + if [[ ${vm_error_cnt_after} -gt ${vm_error_cnt_before} ]]; then 381 + echo "FAIL: kernel error detected on vm" | log_host "${name}" 382 + vm_ssh -- dmesg --level=err | log_host "${name}" 383 + rc=$KSFT_FAIL 384 + fi 385 + 386 + return "${rc}" 387 + } 388 + 389 + QEMU="qemu-system-$(uname -m)" 390 + 391 + while getopts :hvsbq:H:p: o 392 + do 393 + case $o in 394 + v) VERBOSE=$((VERBOSE+1));; 395 + s) SHELL_MODE=1;; 396 + b) BUILD=1;; 397 + q) QEMU=$OPTARG;; 398 + H) BUILD_HOST=$OPTARG;; 399 + p) BUILD_HOST_PODMAN_CONTAINER_NAME=$OPTARG;; 400 + h|*) usage;; 401 + esac 402 + done 403 + shift $((OPTIND-1)) 404 + 405 + trap cleanup EXIT 406 + 407 + PARAMS="" 408 + 409 + if [[ ${#} -eq 0 ]]; then 410 + ARGS=("${TEST_NAMES[@]}") 411 + else 412 + ARGS=() 413 + COUNT=0 414 + for arg in $@; do 415 + COUNT=$((COUNT+1)) 416 + if [[ x"$arg" == x"--" ]]; then 417 + break 418 + fi 419 + ARGS+=($arg) 420 + done 421 + shift $COUNT 422 + PARAMS="$@" 423 + fi 424 + 425 + if [[ "${SHELL_MODE}" -eq 0 ]]; then 426 + check_args "${ARGS[@]}" 427 + echo "1..${#ARGS[@]}" 428 + fi 429 + check_deps 430 + check_vng 431 + handle_build 432 + 433 + log_setup "Booting up VM" 434 + vm_start 435 + vm_wait_for_ssh 436 + vm_mount_bpffs 437 + log_setup "VM booted up" 438 + 439 + if [[ "${SHELL_MODE}" -eq 1 ]]; then 440 + log_setup "Starting interactive shell in VM" 441 + echo "Starting shell in VM. Use 'exit' to quit and shutdown the VM." 442 + CURRENT_DIR="$(pwd)" 443 + vm_ssh -t -- "cd '${CURRENT_DIR}' && exec bash -l" 444 + exit "$KSFT_PASS" 445 + fi 446 + 447 + cnt_pass=0 448 + cnt_fail=0 449 + cnt_skip=0 450 + cnt_total=0 451 + for arg in "${ARGS[@]}"; do 452 + run_test "${arg}" "${PARAMS}" 453 + rc=$? 454 + if [[ ${rc} -eq $KSFT_PASS ]]; then 455 + cnt_pass=$(( cnt_pass + 1 )) 456 + echo "ok ${cnt_total} ${arg}" 457 + elif [[ ${rc} -eq $KSFT_SKIP ]]; then 458 + cnt_skip=$(( cnt_skip + 1 )) 459 + echo "ok ${cnt_total} ${arg} # SKIP" 460 + elif [[ ${rc} -eq $KSFT_FAIL ]]; then 461 + cnt_fail=$(( cnt_fail + 1 )) 462 + echo "not ok ${cnt_total} ${arg} # exit=$rc" 463 + fi 464 + cnt_total=$(( cnt_total + 1 )) 465 + done 466 + 467 + echo "SUMMARY: PASS=${cnt_pass} SKIP=${cnt_skip} FAIL=${cnt_fail}" 468 + echo "Log: ${LOG}" 469 + 470 + if [ $((cnt_pass + cnt_skip)) -eq ${cnt_total} ]; then 471 + exit "$KSFT_PASS" 472 + else 473 + exit "$KSFT_FAIL" 474 + fi