-#!/bin/bash
+#!/usr/bin/env bash
#
# Copyright (C) 2009 Red Hat, Inc.
# Copyright (c) 2000-2002,2006 Silicon Graphics, Inc. All Rights Reserved.
n_bad=0
bad=""
notrun=""
+casenotrun=""
interrupt=true
-
-# by default don't output timestamps
-timestamp=${TIMESTAMP:=false}
+makecheck=false
_init_error()
{
_full_platform_details()
{
- os=`uname -s`
- host=`hostname -s`
- kernel=`uname -r`
- platform=`uname -m`
+ os=$(uname -s)
+ host=$(hostname -s)
+ kernel=$(uname -r)
+ platform=$(uname -m)
echo "$os/$platform $host $kernel"
}
+_full_env_details()
+{
+ cat <<EOF
+QEMU -- "$QEMU_PROG" $QEMU_OPTIONS
+QEMU_IMG -- "$QEMU_IMG_PROG" $QEMU_IMG_OPTIONS
+QEMU_IO -- "$QEMU_IO_PROG" $QEMU_IO_OPTIONS
+QEMU_NBD -- "$QEMU_NBD_PROG" $QEMU_NBD_OPTIONS
+IMGFMT -- $FULL_IMGFMT_DETAILS
+IMGPROTO -- $IMGPROTO
+PLATFORM -- $FULL_HOST_DETAILS
+TEST_DIR -- $TEST_DIR
+SOCK_DIR -- $SOCK_DIR
+SOCKET_SCM_HELPER -- $SOCKET_SCM_HELPER
+
+EOF
+}
+
# $1 = prog to look for
set_prog_path()
{
- p=`command -v $1 2> /dev/null`
+ p=$(command -v $1 2> /dev/null)
if [ -n "$p" -a -x "$p" ]; then
type -p "$p"
else
if [ -z "$TEST_DIR" ]; then
TEST_DIR=$PWD/scratch
fi
+mkdir -p "$TEST_DIR" || _init_error 'Failed to create TEST_DIR'
-if [ ! -e "$TEST_DIR" ]; then
- mkdir "$TEST_DIR"
+tmp_sock_dir=false
+if [ -z "$SOCK_DIR" ]; then
+ SOCK_DIR=$(mktemp -d)
+ tmp_sock_dir=true
fi
+mkdir -p "$SOCK_DIR" || _init_error 'Failed to create SOCK_DIR'
diff="diff -u"
verbose=false
expunge=true
have_test_arg=false
cachemode=false
+aiomode=false
tmp="${TEST_DIR}"/$$
rm -f $tmp.list $tmp.tmp $tmp.sed
export IMGPROTO=file
export IMGOPTS=""
export CACHEMODE="writeback"
+export AIOMODE="threads"
export QEMU_IO_OPTIONS=""
export QEMU_IO_OPTIONS_NO_FMT=""
export CACHEMODE_IS_DEFAULT=true
-export QEMU_OPTIONS="-nodefaults -machine accel=qtest"
export VALGRIND_QEMU=
export IMGKEYSECRET=
export IMGOPTSSYNTAX=false
if $group
then
# arg after -g
- group_list=`sed -n <"$source_iotests/group" -e 's/$/ /' -e "/^[0-9][0-9][0-9].* $r /"'{
+ group_list=$(sed -n <"$source_iotests/group" -e 's/$/ /' -e "/^[0-9][0-9][0-9].* $r /"'{
s/ .*//p
-}'`
+}')
if [ -z "$group_list" ]
then
echo "Group \"$r\" is empty or not defined?"
# arg after -x
# Populate $tmp.list with all tests
awk '/^[0-9]{3,}/ {print $1}' "${source_iotests}/group" > $tmp.list 2>/dev/null
- group_list=`sed -n <"$source_iotests/group" -e 's/$/ /' -e "/^[0-9][0-9][0-9].* $r /"'{
+ group_list=$(sed -n <"$source_iotests/group" -e 's/$/ /' -e "/^[0-9][0-9][0-9].* $r /"'{
s/ .*//p
-}'`
+}')
if [ -z "$group_list" ]
then
echo "Group \"$r\" is empty or not defined?"
rm -f $tmp.sed
fi
echo "/^$t\$/d" >>$tmp.sed
- numsed=`expr $numsed + 1`
+ numsed=$(expr $numsed + 1)
done
sed -f $tmp.sed <$tmp.list >$tmp.tmp
mv $tmp.tmp $tmp.list
CACHEMODE_IS_DEFAULT=false
cachemode=false
continue
+ elif $aiomode
+ then
+ AIOMODE="$r"
+ aiomode=false
+ continue
fi
xpand=true
-vhdx test vhdx
-vmdk test vmdk
-luks test luks
+ -dmg test dmg
image protocol options
-file test file (default)
-misalign misalign memory allocations
-n show me, do not run tests
-o options -o options to pass to qemu-img create/convert
- -T output timestamps
-c mode cache mode
+ -i mode AIO mode
+ -makecheck pretty print output for make check
testlist options
-g group[,group...] include tests from these groups
xpand=false
;;
+ -dmg)
+ IMGFMT=dmg
+ IMGFMT_GENERIC=false
+ xpand=false
+ ;;
+
-qed)
IMGFMT=qed
xpand=false
command -v xxdiff >/dev/null 2>&1 && diff=xxdiff
fi
;;
-
+ -makecheck) # makecheck friendly output
+ makecheck=true
+ xpand=false
+ ;;
-n) # show me, don't do it
showme=true
xpand=false
cachemode=true
xpand=false
;;
- -T) # turn on timestamp output
- timestamp=true
+ -i)
+ aiomode=true
+ xpand=false
+ ;;
+ -T) # deprecated timestamp option
xpand=false
;;
-
-v)
verbose=true
xpand=false
;;
[0-9]*-[0-9]*)
- eval `echo $r | sed -e 's/^/start=/' -e 's/-/ end=/'`
+ eval $(echo $r | sed -e 's/^/start=/' -e 's/-/ end=/')
;;
[0-9]*-)
- eval `echo $r | sed -e 's/^/start=/' -e 's/-//'`
- end=`echo [0-9][0-9][0-9] [0-9][0-9][0-9][0-9] | sed -e 's/\[0-9]//g' -e 's/ *$//' -e 's/.* //'`
+ eval $(echo $r | sed -e 's/^/start=/' -e 's/-//')
+ end=$(echo [0-9][0-9][0-9] [0-9][0-9][0-9][0-9] | sed -e 's/\[0-9]//g' -e 's/ *$//' -e 's/.* //')
if [ -z "$end" ]
then
echo "No tests in range \"$r\"?"
esac
# get rid of leading 0s as can be interpreted as octal
- start=`echo $start | sed 's/^0*//'`
- end=`echo $end | sed 's/^0*//'`
+ start=$(echo $start | sed 's/^0*//')
+ end=$(echo $end | sed 's/^0*//')
if $xpand
then
BEGIN { for (t='$start'; t<='$end'; t++) printf "%03d\n",t }' \
| while read id
do
- if grep -s "^$id " "$source_iotests/group" >/dev/null
+ if grep -s "^$id\( \|\$\)" "$source_iotests/group" >/dev/null
then
# in group file ... OK
echo $id >>$tmp.list
# Set qemu-io cache mode with $CACHEMODE we have
QEMU_IO_OPTIONS="$QEMU_IO_OPTIONS --cache $CACHEMODE"
+# Set qemu-io aio mode with $AIOMODE we have
+QEMU_IO_OPTIONS="$QEMU_IO_OPTIONS --aio $AIOMODE"
QEMU_IO_OPTIONS_NO_FMT="$QEMU_IO_OPTIONS"
if [ "$IMGOPTSSYNTAX" != "true" ]; then
fi
export TEST_DIR
+export SOCK_DIR
export SAMPLE_IMG_DIR
if [ -s $tmp.list ]
touch $tmp.list
else
# no test numbers, do everything from group file
- sed -n -e '/^[0-9][0-9][0-9]*/s/[ ].*//p' <"$source_iotests/group" >$tmp.list
+ sed -n -e '/^[0-9][0-9][0-9]*/s/^\([0-9]*\).*/\1/p' <"$source_iotests/group" >$tmp.list
fi
fi
# should be sort -n, but this did not work for Linux when this
# was ported from IRIX
#
-list=`sort $tmp.list`
+list=$(sort $tmp.list)
rm -f $tmp.list $tmp.tmp $tmp.sed
if [ -z "$QEMU_PROG" ]
fi
export QEMU_PROG="$(type -p "$QEMU_PROG")"
+case "$QEMU_PROG" in
+ *qemu-system-arm|*qemu-system-aarch64)
+ export QEMU_OPTIONS="-nodefaults -display none -machine virt -accel qtest"
+ ;;
+ *qemu-system-tricore)
+ export QEMU_OPTIONS="-nodefaults -display none -machine tricore_testboard -accel qtest"
+ ;;
+ *)
+ export QEMU_OPTIONS="-nodefaults -display none -accel qtest"
+ ;;
+esac
+
if [ -z "$QEMU_IMG_PROG" ]; then
if [ -x "$build_iotests/qemu-img" ]; then
export QEMU_IMG_PROG="$build_iotests/qemu-img"
export QEMU_NBD_PROG="$(type -p "$QEMU_NBD_PROG")"
if [ -z "$QEMU_VXHS_PROG" ]; then
- export QEMU_VXHS_PROG="`set_prog_path qnio_server`"
+ export QEMU_VXHS_PROG="$(set_prog_path qnio_server)"
fi
if [ -x "$build_iotests/socket_scm_helper" ]
export SOCKET_SCM_HELPER="$build_iotests/socket_scm_helper"
fi
+python_usable=false
+if $PYTHON -c 'import sys; sys.exit(0 if sys.version_info >= (3,6) else 1)'
+then
+ # Our python framework also requires virtio-blk
+ if "$QEMU_PROG" -M none -device help | grep -q virtio-blk >/dev/null 2>&1
+ then
+ python_usable=true
+ else
+ python_unusable_because="Missing virtio-blk in QEMU binary"
+ fi
+else
+ python_unusable_because="Unsupported Python version"
+fi
+
default_machine=$($QEMU_PROG -machine help | sed -n '/(default)/ s/ .*//p')
default_alias_machine=$($QEMU_PROG -machine help | \
sed -n "/(alias of $default_machine)/ { s/ .*//p; q; }")
date "+%H %M %S" | awk '{ print $1*3600 + $2*60 + $3 }'
}
-_timestamp()
-{
- now=`date "+%T"`
- printf %s " [$now]"
-}
-
_wrapup()
{
if $showme
if [ -f $tmp.expunged ]
then
- notrun=`wc -l <$tmp.expunged | sed -e 's/ *//g'`
- try=`expr $try - $notrun`
- list=`echo "$list" | sed -f $tmp.expunged`
+ notrun=$(wc -l <$tmp.expunged | sed -e 's/ *//g')
+ try=$(expr $try - $notrun)
+ list=$(echo "$list" | sed -f $tmp.expunged)
fi
echo "" >>check.log
echo "Not run:$notrun"
echo "Not run:$notrun" >>check.log
fi
+ if [ ! -z "$casenotrun" ]
+ then
+ echo "Some cases not run in:$casenotrun"
+ echo "Some cases not run in:$casenotrun" >>check.log
+ fi
if [ ! -z "$n_bad" -a $n_bad != 0 ]
then
echo "Failures:$bad"
- echo "Failed $n_bad of $try tests"
+ echo "Failed $n_bad of $try iotests"
echo "Failures:$bad" | fmt >>check.log
- echo "Failed $n_bad of $try tests" >>check.log
+ echo "Failed $n_bad of $try iotests" >>check.log
else
- echo "Passed all $try tests"
- echo "Passed all $try tests" >>check.log
+ echo "Passed all $try iotests"
+ echo "Passed all $try iotests" >>check.log
fi
needwrap=false
fi
rm -f "${TEST_DIR}"/*.out "${TEST_DIR}"/*.err "${TEST_DIR}"/*.time
rm -f "${TEST_DIR}"/check.pid "${TEST_DIR}"/check.sts
rm -f $tmp.*
+
+ if $tmp_sock_dir
+ then
+ rm -rf "$SOCK_DIR"
+ fi
}
trap "_wrapup; exit \$status" 0 1 2 3 15
-[ -f $TIMESTAMP_FILE ] || touch $TIMESTAMP_FILE
+# Report the test start and results. For makecheck we want to pretty
+# print the whole report at the end of the execution.
+# args: $seq, $starttime, $lasttime
+_report_test_start()
+{
+ if ! $makecheck; then
+ if [ -n "$3" ]; then
+ local lasttime=" (last: $3s)"
+ fi
+ printf "%-8s %-10s [%s] %4s%-14s\r" "$1" "..." "$2" "..." "$lasttime"
+ fi
+}
+# args:$seq $status $starttime $lasttime $thistime $details
+_report_test_result()
+{
+ local status lasttime thistime
+ if $makecheck; then
+ if [ -n "$2" ] && [ "$2" != "pass" ]; then
+ status=" [$2]"
+ fi
+ printf " TEST iotest-$IMGFMT: %s%s\n" "$1" "$status"
+ return
+ fi
-FULL_IMGFMT_DETAILS=`_full_imgfmt_details`
-FULL_HOST_DETAILS=`_full_platform_details`
+ if [ -n "$4" ]; then
+ lasttime=" (last: $4s)"
+ fi
+ if [ -n "$5" ]; then
+ thistime=" $5s"
+ fi
+ case "$2" in
+ "pass") status=$(printf "\e[32m%-10s\e[0m" "$2") ;;
+ "fail") status=$(printf "\e[1m\e[31m%-10s\e[0m" "$2") ;;
+ "not run") status=$(printf "\e[33m%-10s\e[0m" "$2") ;;
+ *) status=$(printf "%-10s" "$2") ;;
+ esac
-cat <<EOF
-QEMU -- "$QEMU_PROG" $QEMU_OPTIONS
-QEMU_IMG -- "$QEMU_IMG_PROG" $QEMU_IMG_OPTIONS
-QEMU_IO -- "$QEMU_IO_PROG" $QEMU_IO_OPTIONS
-QEMU_NBD -- "$QEMU_NBD_PROG" $QEMU_NBD_OPTIONS
-IMGFMT -- $FULL_IMGFMT_DETAILS
-IMGPROTO -- $IMGPROTO
-PLATFORM -- $FULL_HOST_DETAILS
-TEST_DIR -- $TEST_DIR
-SOCKET_SCM_HELPER -- $SOCKET_SCM_HELPER
+ printf "%-8s %s [%s] [%s] %4s%-14s %s\n" "$1" "$status" "$3" "$(date '+%T')" "$thistime" "$lasttime" "$6"
+}
-EOF
+[ -f $TIMESTAMP_FILE ] || touch $TIMESTAMP_FILE
+
+FULL_IMGFMT_DETAILS=$(_full_imgfmt_details)
+FULL_HOST_DETAILS=$(_full_platform_details)
+
+if ! $makecheck; then
+ _full_env_details
+fi
seq="check"
for seq in $list
do
- err=false
- printf %s "$seq"
+ err=false # error flag
+ printdiff=false # show diff to reference output?
+ status="" # test result summary
+ results="" # test result details
+ thistime="" # time the test took
+
if [ -n "$TESTS_REMAINING_LOG" ] ; then
sed -e "s/$seq//" -e 's/ / /' -e 's/^ *//' $TESTS_REMAINING_LOG > $TESTS_REMAINING_LOG.tmp
mv $TESTS_REMAINING_LOG.tmp $TESTS_REMAINING_LOG
sync
fi
+ lasttime=$(sed -n -e "/^$seq /s/.* //p" <$TIMESTAMP_FILE)
+ starttime=$(date "+%T")
+ _report_test_start $seq $starttime $lasttime
+
if $showme
then
- echo
- continue
+ status="not run"
elif [ -f expunged ] && $expunge && egrep "^$seq([ ]|\$)" expunged >/dev/null
then
- echo " - expunged"
+ status="not run"
+ results="expunged"
rm -f $seq.out.bad
echo "/^$seq\$/d" >>$tmp.expunged
elif [ ! -f "$source_iotests/$seq" ]
then
- echo " - no such test?"
+ status="not run"
+ results="no such test?"
echo "/^$seq\$/d" >>$tmp.expunged
else
# really going to try and run this one
#
rm -f $seq.out.bad
- lasttime=`sed -n -e "/^$seq /s/.* //p" <$TIMESTAMP_FILE`
- if [ "X$lasttime" != X ]; then
- printf %s " ${lasttime}s ..."
- else
- printf " " # prettier output with timestamps.
- fi
rm -f core $seq.notrun
+ rm -f $seq.casenotrun
- start=`_wallclock`
- $timestamp && printf %s " [$(date "+%T")]"
+ start=$(_wallclock)
- if [ "$(head -n 1 "$source_iotests/$seq")" == "#!/usr/bin/env python" ]; then
- run_command="$PYTHON $seq"
+ if [ "$(head -n 1 "$source_iotests/$seq")" == "#!/usr/bin/env python3" ]; then
+ if $python_usable; then
+ run_command="$PYTHON $seq"
+ else
+ run_command="false"
+ echo "$python_unusable_because" > $seq.notrun
+ fi
else
run_command="./$seq"
fi
$run_command >$tmp.out 2>&1)
fi
sts=$?
- $timestamp && _timestamp
- stop=`_wallclock`
+ stop=$(_wallclock)
if [ -f core ]
then
- printf " [dumped core]"
mv core $seq.core
+ status="fail"
+ results="[dumped core] $seq.core"
err=true
fi
if [ -f $seq.notrun ]
then
- $timestamp || printf " [not run] "
- $timestamp && echo " [not run]" && printf %s " $seq -- "
- cat $seq.notrun
- notrun="$notrun $seq"
+ # overwrites timestamp output
+ status="not run"
+ results="$(cat $seq.notrun)"
else
if [ $sts -ne 0 ]
then
- printf %s " [failed, exit status $sts]"
+ status="fail"
+ results=$(printf %s "[failed, exit status $sts]")
err=true
fi
if [ ! -f "$reference" ]
then
- echo " - no qualified output"
+ status="fail"
+ results="no qualified output"
err=true
else
if diff -w "$reference" $tmp.out >/dev/null 2>&1
then
- echo ""
- if $err
- then
- :
- else
- echo "$seq `expr $stop - $start`" >>$tmp.time
+ if ! $err; then
+ status="pass"
+ thistime=$(expr $stop - $start)
+ echo "$seq $thistime" >>$tmp.time
fi
else
- echo " - output mismatch (see $seq.out.bad)"
mv $tmp.out $seq.out.bad
- $diff -w "$reference" "$PWD"/$seq.out.bad
+ status="fail"
+ results="output mismatch (see $seq.out.bad)"
+ printdiff=true
err=true
fi
fi
fi
-
+ if [ -f $seq.casenotrun ]
+ then
+ cat $seq.casenotrun
+ casenotrun="$casenotrun $seq"
+ fi
fi
# come here for each test, except when $showme is true
#
- if $err
- then
- bad="$bad $seq"
- n_bad=`expr $n_bad + 1`
- quick=false
- fi
- [ -f $seq.notrun ] || try=`expr $try + 1`
+ _report_test_result $seq "$status" "$starttime" "$lasttime" "$thistime" "$results"
+ case "$status" in
+ "pass")
+ try=$(expr $try + 1)
+ ;;
+ "fail")
+ try=$(expr $try + 1)
+ if $makecheck; then
+ _full_env_details
+ fi
+ if $printdiff; then
+ $diff -w "$reference" "$PWD"/$seq.out.bad
+ fi
+ bad="$bad $seq"
+ n_bad=$(expr $n_bad + 1)
+ quick=false
+ ;;
+ "not run")
+ notrun="$notrun $seq"
+ ;;
+ esac
seq="after_$seq"
done
interrupt=false
-status=`expr $n_bad`
+status=$(expr $n_bad)
exit