qemu/tests/qemu-iotests/083
Max Reitz ddc7093eec iotests: Make 083 less flaky
083 has (at least) two issues:

1. By launching the nbd-fault-injector in background, it may not be
   scheduled until the first grep on its output file is executed.
   However, until then, that file may not have been created yet -- so it
   either does not exist yet (thus making the grep emit an error), or it
   does exist but contains stale data (thus making the rest of the test
   case work connect to a wrong address).
   Fix this by explicitly overwriting the output file before executing
   nbd-fault-injector.

2. The nbd-fault-injector prints things other than "Listening on...".
   It also prints a "Closing connection" message from time to time.  We
   currently invoke sed on the whole file in the hope of it only
   containing the "Listening on..." line yet.  That hope is sometimes
   shattered by the brutal reality of race conditions, so make the sed
   script more robust.

Signed-off-by: Max Reitz <mreitz@redhat.com>
Message-id: 20171109203025.27493-5-mreitz@redhat.com
Reviewed-by: Eric Blake <eblake@redhat.com>
Signed-off-by: Max Reitz <mreitz@redhat.com>
2017-11-14 18:06:25 +01:00

153 lines
3.3 KiB
Bash
Executable File

#!/bin/bash
#
# Test NBD client unexpected disconnect
#
# Copyright Red Hat, Inc. 2014
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
# creator
owner=stefanha@redhat.com
seq=`basename $0`
echo "QA output created by $seq"
here=`pwd`
status=1 # failure is the default!
_cleanup()
{
rm -f nbd.sock
rm -f nbd-fault-injector.out
rm -f nbd-fault-injector.conf
}
trap "_cleanup; exit \$status" 0 1 2 3 15
# get standard environment, filters and checks
. ./common.rc
. ./common.filter
_supported_fmt generic
_supported_proto nbd
_supported_os Linux
check_disconnect() {
local event export_name=foo extra_args nbd_addr nbd_url proto when
while true; do
case $1 in
--classic-negotiation)
shift
extra_args=--classic-negotiation
export_name=
;;
--tcp)
shift
proto=tcp
;;
--unix)
shift
proto=unix
;;
*)
break
;;
esac
done
event=$1
when=$2
echo "=== Check disconnect $when $event ==="
echo
cat > "$TEST_DIR/nbd-fault-injector.conf" <<EOF
[inject-error]
event=$event
when=$when
EOF
if [ "$proto" = "tcp" ]; then
nbd_addr="127.0.0.1:0"
else
nbd_addr="$TEST_DIR/nbd.sock"
fi
rm -f "$TEST_DIR/nbd.sock"
echo > "$TEST_DIR/nbd-fault-injector.out"
$PYTHON nbd-fault-injector.py $extra_args "$nbd_addr" "$TEST_DIR/nbd-fault-injector.conf" >"$TEST_DIR/nbd-fault-injector.out" 2>&1 &
# Wait for server to be ready
while ! grep -q 'Listening on ' "$TEST_DIR/nbd-fault-injector.out"; do
sleep 0.1
done
# Extract the final address (port number has now been assigned in tcp case)
nbd_addr=$(sed -n 's/^Listening on //p' \
"$TEST_DIR/nbd-fault-injector.out")
if [ "$proto" = "tcp" ]; then
nbd_url="nbd+tcp://$nbd_addr/$export_name"
else
nbd_url="nbd+unix:///$export_name?socket=$nbd_addr"
fi
$QEMU_IO -c "read 0 512" "$nbd_url" 2>&1 | _filter_qemu_io | _filter_nbd
echo
}
for proto in tcp unix; do
for event in neg1 "export" neg2 request reply data; do
for when in before after; do
check_disconnect "--$proto" "$event" "$when"
done
# Also inject short replies from the NBD server
case "$event" in
neg1)
for when in 8 16; do
check_disconnect "--$proto" "$event" "$when"
done
;;
"export")
for when in 4 12 16; do
check_disconnect "--$proto" "$event" "$when"
done
;;
neg2)
for when in 8 10; do
check_disconnect "--$proto" "$event" "$when"
done
;;
reply)
for when in 4 8; do
check_disconnect "--$proto" "$event" "$when"
done
;;
esac
done
# Also check classic negotiation without export information
for when in before 8 16 24 28 after; do
check_disconnect "--$proto" --classic-negotiation "neg-classic" "$when"
done
done
# success, all done
echo "*** done"
rm -f $seq.full
status=0