ae23c9
From e56b23f0bbf8c9c1149cfb4f0a1a3b002b5aec1b Mon Sep 17 00:00:00 2001
ae23c9
From: John Snow <jsnow@redhat.com>
ae23c9
Date: Wed, 10 Oct 2018 20:50:59 +0100
ae23c9
Subject: [PATCH 2/3] iotests: Add failure matching to common.qemu
ae23c9
ae23c9
RH-Author: John Snow <jsnow@redhat.com>
ae23c9
Message-id: <20181010205100.17689-3-jsnow@redhat.com>
ae23c9
Patchwork-id: 82633
ae23c9
O-Subject: [RHEL8/rhel qemu-kvm PATCH 2/3] iotests: Add failure matching to common.qemu
ae23c9
Bugzilla: 1635583
ae23c9
RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
ae23c9
RH-Acked-by: Max Reitz <mreitz@redhat.com>
ae23c9
RH-Acked-by: Kevin Wolf <kwolf@redhat.com>
ae23c9
ae23c9
From: Max Reitz <mreitz@redhat.com>
ae23c9
ae23c9
Currently, common.qemu only allows to match for results indicating
ae23c9
success.  The only way to fail is by provoking a timeout.  However,
ae23c9
sometimes we do have a defined failure output and can match for that,
ae23c9
which saves us from having to wait for the timeout in case of failure.
ae23c9
Because failure can sometimes just result in a _notrun in the test, it
ae23c9
is actually important to care about being able to fail quickly.
ae23c9
ae23c9
Also, sometimes we simply do not get any specific output in case of
ae23c9
success.  The only way to handle this currently would be to define an
ae23c9
error message as the string to look for, which means that actual success
ae23c9
results in a timeout.  This is really bad because it unnecessarily slows
ae23c9
down a succeeding test.
ae23c9
ae23c9
Therefore, this patch adds a new parameter $success_or_failure to
ae23c9
_timed_wait_for and _send_qemu_cmd.  Setting this to a non-empty string
ae23c9
makes both commands expect two match parameters: If the first matches,
ae23c9
the function succeeds.  If the second matches, the function fails.
ae23c9
ae23c9
Signed-off-by: Max Reitz <mreitz@redhat.com>
ae23c9
Message-id: 20180406151731.4285-2-mreitz@redhat.com
ae23c9
Signed-off-by: Max Reitz <mreitz@redhat.com>
ae23c9
(cherry picked from commit 81c6ddf49a76a663cea16c07a07d51b67c853209)
ae23c9
Signed-off-by: John Snow <jsnow@redhat.com>
ae23c9
Signed-off-by: Danilo C. L. de Paula <ddepaula@redhat.com>
ae23c9
---
ae23c9
 tests/qemu-iotests/common.qemu | 58 +++++++++++++++++++++++++++++++++++++-----
ae23c9
 1 file changed, 51 insertions(+), 7 deletions(-)
ae23c9
ae23c9
diff --git a/tests/qemu-iotests/common.qemu b/tests/qemu-iotests/common.qemu
ae23c9
index 85f66b8..f285484 100644
ae23c9
--- a/tests/qemu-iotests/common.qemu
ae23c9
+++ b/tests/qemu-iotests/common.qemu
ae23c9
@@ -52,11 +52,29 @@ _in_fd=4
ae23c9
 # response is not echoed out.
ae23c9
 # If $mismatch_only is set, only non-matching responses will
ae23c9
 # be echoed.
ae23c9
+#
ae23c9
+# If $success_or_failure is set, the meaning of the arguments is
ae23c9
+# changed as follows:
ae23c9
+# $2: A string to search for in the response; if found, this indicates
ae23c9
+#     success and ${QEMU_STATUS[$1]} is set to 0.
ae23c9
+# $3: A string to search for in the response; if found, this indicates
ae23c9
+#     failure and the test is either aborted (if $qemu_error_no_exit
ae23c9
+#     is not set) or ${QEMU_STATUS[$1]} is set to -1 (otherwise).
ae23c9
 function _timed_wait_for()
ae23c9
 {
ae23c9
     local h=${1}
ae23c9
     shift
ae23c9
 
ae23c9
+    if [ -z "${success_or_failure}" ]; then
ae23c9
+        success_match=${*}
ae23c9
+        failure_match=
ae23c9
+    else
ae23c9
+        success_match=${1}
ae23c9
+        failure_match=${2}
ae23c9
+    fi
ae23c9
+
ae23c9
+    timeout=yes
ae23c9
+
ae23c9
     QEMU_STATUS[$h]=0
ae23c9
     while IFS= read -t ${QEMU_COMM_TIMEOUT} resp <&${QEMU_OUT[$h]}
ae23c9
     do
ae23c9
@@ -64,10 +82,18 @@ function _timed_wait_for()
ae23c9
             echo "${resp}" | _filter_testdir | _filter_qemu \
ae23c9
                            | _filter_qemu_io | _filter_qmp | _filter_hmp
ae23c9
         fi
ae23c9
-        grep -q "${*}" < <(echo "${resp}")
ae23c9
+        if [ -n "${failure_match}" ]; then
ae23c9
+            grep -q "${failure_match}" < <(echo "${resp}")
ae23c9
+            if [ $? -eq 0 ]; then
ae23c9
+                timeout=
ae23c9
+                break
ae23c9
+            fi
ae23c9
+        fi
ae23c9
+        grep -q "${success_match}" < <(echo "${resp}")
ae23c9
         if [ $? -eq 0 ]; then
ae23c9
             return
ae23c9
-        elif [ -z "${silent}" ] && [ -n "${mismatch_only}" ]; then
ae23c9
+        fi
ae23c9
+        if [ -z "${silent}" ] && [ -n "${mismatch_only}" ]; then
ae23c9
             echo "${resp}" | _filter_testdir | _filter_qemu \
ae23c9
                            | _filter_qemu_io | _filter_qmp | _filter_hmp
ae23c9
         fi
ae23c9
@@ -75,8 +101,12 @@ function _timed_wait_for()
ae23c9
     done
ae23c9
     QEMU_STATUS[$h]=-1
ae23c9
     if [ -z "${qemu_error_no_exit}" ]; then
ae23c9
-        echo "Timeout waiting for ${*} on handle ${h}"
ae23c9
-        exit 1  # Timeout means the test failed
ae23c9
+        if [ -n "${timeout}" ]; then
ae23c9
+            echo "Timeout waiting for ${success_match} on handle ${h}"
ae23c9
+        else
ae23c9
+            echo "Wrong response matching ${failure_match} on handle ${h}"
ae23c9
+        fi
ae23c9
+        exit 1  # Timeout or wrong match mean the test failed
ae23c9
     fi
ae23c9
 }
ae23c9
 
ae23c9
@@ -96,6 +126,11 @@ function _timed_wait_for()
ae23c9
 # If $qemu_error_no_exit is set, then even if the expected response
ae23c9
 # is not seen, we will not exit.  $QEMU_STATUS[$1] will be set it -1 in
ae23c9
 # that case.
ae23c9
+#
ae23c9
+# If $success_or_failure is set, then the last two strings are the
ae23c9
+# strings the response will be scanned for.  The first of the two
ae23c9
+# indicates success, the latter indicates failure.  Failure is handled
ae23c9
+# like a timeout.
ae23c9
 function _send_qemu_cmd()
ae23c9
 {
ae23c9
     local h=${1}
ae23c9
@@ -109,14 +144,23 @@ function _send_qemu_cmd()
ae23c9
         use_error="no"
ae23c9
     fi
ae23c9
     # This array element extraction is done to accommodate pathnames with spaces
ae23c9
-    cmd=${@: 1:${#@}-1}
ae23c9
-    shift $(($# - 1))
ae23c9
+    if [ -z "${success_or_failure}" ]; then
ae23c9
+        cmd=${@: 1:${#@}-1}
ae23c9
+        shift $(($# - 1))
ae23c9
+    else
ae23c9
+        cmd=${@: 1:${#@}-2}
ae23c9
+        shift $(($# - 2))
ae23c9
+    fi
ae23c9
 
ae23c9
     while [ ${count} -gt 0 ]
ae23c9
     do
ae23c9
         echo "${cmd}" >&${QEMU_IN[${h}]}
ae23c9
         if [ -n "${1}" ]; then
ae23c9
-            qemu_error_no_exit=${use_error} _timed_wait_for ${h} "${1}"
ae23c9
+            if [ -z "${success_or_failure}" ]; then
ae23c9
+                qemu_error_no_exit=${use_error} _timed_wait_for ${h} "${1}"
ae23c9
+            else
ae23c9
+                qemu_error_no_exit=${use_error} _timed_wait_for ${h} "${1}" "${2}"
ae23c9
+            fi
ae23c9
             if [ ${QEMU_STATUS[$h]} -eq 0 ]; then
ae23c9
                 return
ae23c9
             fi
ae23c9
-- 
ae23c9
1.8.3.1
ae23c9