@ -1,4 +1,4 @@
#!/ bin/bash
#!/ usr/ bin/env bash
#set -o errexit
set -o pipefail
@ -24,18 +24,21 @@ EOF
fi
help_and_exit( ) {
echo "Usage: ./tests.sh [-p|--pdb] [-c|--cov] [<test-name-filter>]"
echo " -p, --pdb enable pdb (Python debugger) post mortem debugger on failed tests"
echo " -c, --cov enable codecov"
echo " -v, --verbose display all test output instead of just failing test output"
echo " --collect-only only show the output of test collection, don't run any tests"
echo " <test-name-filter> run only tests that match the regex"
echo "Usage: ./tests.sh [-p|--pdb] [-c|--cov] [--gdb-port=<port>] [-Q|--preserve-qemu-image] [<test-name-filter>]"
echo " -p, --pdb enable pdb (Python debugger) post mortem debugger on failed tests"
echo " -c, --cov enable codecov"
echo " -v, --verbose display all test output instead of just failing test output"
echo " --gdb-port=<port> specify debug port for gdb/QEMU (Default: 1234)"
echo " --collect-only only show the output of test collection, don't run any tests"
echo " -Q, --preserve-qemu-image don't kill QEMU image after failed tests"
echo " <test-name-filter> run only tests that match the regex"
exit 1
}
handle_sigint( ) {
echo "Exiting..." >& 2
pkill qemu-system
echo " Killing QEMU process $QEMU_PID " ... >& 2
pkill -P $QEMU_PID
exit 1
}
trap handle_sigint SIGINT
@ -49,26 +52,30 @@ TEST_NAME_FILTER=""
RUN_CODECOV = 0
VERBOSE = 0
COLLECT_ONLY = 0
PRESERVE_QEMU_IMAGE = 0
GDB_PORT = 1234
while [ [ $# -gt 0 ] ] ; do
case $1 in
-p | --pdb)
USE_PDB = 1
echo "Will run tests with Python debugger"
shift
; ;
-c | --cov)
echo "Will run codecov"
RUN_CODECOV = 1
shift
; ;
-v | --verbose)
VERBOSE = 1
shift
; ;
--collect-only)
COLLECT_ONLY = 1
shift
; ;
-Q | --preserve-qemu-image)
PRESERVE_QEMU_IMAGE = 1
; ;
--gdb-port= *)
GDB_PORT = " ${ 1 #--gdb-port= } "
; ;
-h | --help)
help_and_exit
@ -78,11 +85,27 @@ while [[ $# -gt 0 ]]; do
help_and_exit
fi
TEST_NAME_FILTER = " $1 "
shift
; ;
esac
shift
done
# Test if the port is already listening, possibly by other qemu instance. This
# can cause unexpected test failures.
NETSTAT = $( which netstat)
if [ [ -z " ${ NETSTAT } " ] ] ; then
NETSTAT = $( which ss)
fi
if [ [ -z " ${ NETSTAT } " ] ] ; then
echo " WARNING: netstat/ss not found. Cannot check if port ${ GDB_PORT } is already bound. " >& 2
exit 1
else
if [ [ $( ${ NETSTAT } -tuln 2> /dev/null | grep " : ${ GDB_PORT } " | grep -c LISTEN) -ne 0 ] ] ; then
echo " WARNING: Port ${ GDB_PORT } appears already bound. Please specify a different port with --gdb-port=<port> " >& 2
exit 1
fi
fi
gdb_load_pwndbg = ( --command " $GDB_INIT_PATH " -ex "set exception-verbose on" )
run_gdb( ) {
local arch = " $1 "
@ -118,7 +141,7 @@ init_gdb() {
local kernel_version = " $2 "
local arch = " $3 "
gdb_connect_qemu = ( -ex " file ${ IMAGE_DIR } /vmlinux- ${ kernel_type } - ${ kernel_version } - ${ arch } " -ex " target remote :1234 ")
gdb_connect_qemu = ( -ex " file ${ IMAGE_DIR } /vmlinux- ${ kernel_type } - ${ kernel_version } - ${ arch } " -ex " target remote : ${ GDB_PORT } ")
# using 'rest_init' instead of 'start_kernel' to make sure that kernel
# initialization has progressed sufficiently for testing purposes
gdb_args = ( " ${ gdb_connect_qemu [@] } " -ex 'break *rest_init' -ex 'continue' )
@ -131,11 +154,12 @@ run_test() {
local kernel_version = " $3 "
local arch = " $4 "
gdb_connect_qemu = ( -ex " file ${ IMAGE_DIR } /vmlinux- ${ kernel_type } - ${ kernel_version } - ${ arch } " -ex " target remote :1234 ")
gdb_connect_qemu = ( -ex " file ${ IMAGE_DIR } /vmlinux- ${ kernel_type } - ${ kernel_version } - ${ arch } " -ex " target remote : ${ GDB_PORT } ")
gdb_args = ( " ${ gdb_connect_qemu [@] } " --command pytests_launcher.py)
if [ ${ RUN_CODECOV } -ne 0 ] ; then
gdb_args = ( -ex 'py import coverage;coverage.process_startup()' " ${ gdb_args [@] } " )
fi
SRC_DIR = $ROOT_DIR \
COVERAGE_FILE = $ROOT_DIR /.cov/coverage \
COVERAGE_PROCESS_START = $COVERAGERC_PATH \
@ -151,6 +175,9 @@ run_test() {
process_output( ) {
output = " $1 "
if [ [ -z " $output " ] ] ; then
return
fi
read -r testname result < <(
echo " $output " | grep -Po '(^tests/[^ ]+)|(\x1b\[3.m(PASSED|FAILED|SKIPPED|XPASS|XFAIL)\x1b\[0m)' \
@ -189,8 +216,10 @@ test_system() {
fi
echo ""
" ${ CWD } /run_qemu_system.sh " --kernel= " ${ kernel_type } - ${ kernel_version } - ${ arch } " -- " ${ qemu_args [@] } " > /dev/null 2>& 1 &
# NOTE: If you run simultaneous tests or left an image lying around via -Q, this
# will hang due to failure to obtain lock. But will see the error message...
" ${ CWD } /run_qemu_system.sh " --kernel= " ${ kernel_type } - ${ kernel_version } - ${ arch } " --gdb-port= " ${ GDB_PORT } " -- " ${ qemu_args [@] } " > /dev/null &
QEMU_PID = $!
init_gdb " ${ kernel_type } " " ${ kernel_version } " " ${ arch } "
start = $( date +%s)
@ -217,10 +246,16 @@ test_system() {
echo ""
echo " Failing tests: ${ FAILED_TESTS [@] } "
echo ""
if [ ${ PRESERVE_QEMU_IMAGE } -eq 0 ] ; then
pkill -P $QEMU_PID
else
echo " Preserving qemu image for debugging purposes. Kill with 'pkill -P $QEMU_PID ' "
fi
exit 1
fi
pkill qemu-system
pkill -P $QEMU_PID
}
for vmlinux in " ${ VMLINUX_LIST [@] } " ; do