[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[PATCH v6 09/10] iotests: add support for capturing and matching QMP eve
From: |
Daniel P . Berrangé |
Subject: |
[PATCH v6 09/10] iotests: add support for capturing and matching QMP events |
Date: |
Thu, 8 Oct 2020 16:50:00 +0100 |
When using the _launch_qemu and _send_qemu_cmd functions from
common.qemu, any QMP events get mixed in with the output from
the commands and responses.
This makes it difficult to write a test case as the ordering
of events in the output is not stable.
This introduces a variable 'capture_events' which can be set
to a list of event names. Any events listed in this variable
will not be printed, instead collected in the $QEMU_EVENTS
environment variable.
A new '_wait_event' function can be invoked to collect events
at a fixed point in time. The function will first pull events
cached in $QEMU_EVENTS variable, and if none are found, will
then read more from QMP.
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
---
tests/qemu-iotests/common.qemu | 107 ++++++++++++++++++++++++++++++++-
1 file changed, 106 insertions(+), 1 deletion(-)
diff --git a/tests/qemu-iotests/common.qemu b/tests/qemu-iotests/common.qemu
index de680cf1c7..87d7a54001 100644
--- a/tests/qemu-iotests/common.qemu
+++ b/tests/qemu-iotests/common.qemu
@@ -53,6 +53,15 @@ _in_fd=4
# If $mismatch_only is set, only non-matching responses will
# be echoed.
#
+# If $capture_events is non-empty, then any QMP event names it lists
+# will not be echoed out, but instead collected in the $QEMU_EVENTS
+# variable. The _wait_event function can later be used to received
+# the cached events.
+#
+# If $only_capture_events is set to anything but an empty string,
+# when an error will be raised if a QMP message is seen which is
+# not an event listed in $capture_events.
+#
# If $success_or_failure is set, the meaning of the arguments is
# changed as follows:
# $2: A string to search for in the response; if found, this indicates
@@ -78,6 +87,32 @@ _timed_wait_for()
QEMU_STATUS[$h]=0
while IFS= read -t ${QEMU_COMM_TIMEOUT} resp <&${QEMU_OUT[$h]}
do
+ if [ -n "$capture_events" ]; then
+ capture=0
+ local evname
+ for evname in $capture_events
+ do
+ grep -q "\"event\": \"${evname}\"" < <(echo "${resp}")
+ if [ $? -eq 0 ]; then
+ capture=1
+ fi
+ done
+ if [ $capture = 1 ];
+ then
+ ev=$(echo "${resp}" | tr -d '\r' | tr % .)
+ QEMU_EVENTS="${QEMU_EVENTS:+${QEMU_EVENTS}%}${ev}"
+ if [ -n "$only_capture_events" ]; then
+ return
+ else
+ continue
+ fi
+ fi
+ fi
+ if [ -n "$only_capture_events" ]; then
+ echo "Only expected $capture_events but got ${resp}"
+ exit 1
+ fi
+
if [ -z "${silent}" ] && [ -z "${mismatch_only}" ]; then
echo "${resp}" | _filter_testdir | _filter_qemu \
| _filter_qemu_io | _filter_qmp | _filter_hmp
@@ -177,12 +212,82 @@ _send_qemu_cmd()
let count--;
done
if [ ${QEMU_STATUS[$h]} -ne 0 ] && [ -z "${qemu_error_no_exit}" ]; then
- echo "Timeout waiting for ${1} on handle ${h}"
+ echo "Timeout waiting for command ${1} response on handle ${h}"
exit 1 #Timeout means the test failed
fi
}
+# Check event cache for a named QMP event
+#
+# Input parameters:
+# $1: Name of the QMP event to check for
+#
+# Checks if the named QMP event that was previously captured
+# into $QEMU_EVENTS. When matched, the QMP event will be echoed
+# and the $matched variable set to 1.
+#
+# _wait_event is more suitable for test usage in most cases
+_check_cached_events()
+{
+ local evname=${1}
+
+ local match="\"event\": \"$evname\""
+
+ matched=0
+ if [ -n "$QEMU_EVENTS" ]; then
+ CURRENT_QEMU_EVENTS=$QEMU_EVENTS
+ QEMU_EVENTS=
+ old_IFS=$IFS
+ IFS="%"
+ for ev in $CURRENT_QEMU_EVENTS
+ do
+ grep -q "$match" < <(echo "${ev}")
+ if [ $? -eq 0 -a $matched = 0 ]; then
+ echo "${ev}" | _filter_testdir | _filter_qemu \
+ | _filter_qemu_io | _filter_qmp | _filter_hmp
+ matched=1
+ else
+ QEMU_EVENTS="${QEMU_EVENTS:+${QEMU_EVENTS}%}${ev}"
+ fi
+ done
+ IFS=$old_IFS
+ fi
+}
+
+# Wait for a named QMP event
+#
+# Input parameters:
+# $1: QEMU handle to use
+# $2: Name of the QMP event to wait for
+#
+# Checks if the named QMP event that was previously captured
+# into $QEMU_EVENTS. If none are present, then waits for the
+# event to arrive on the QMP channel. When matched, the QMP
+# event will be echoed
+_wait_event()
+{
+ local h=${1}
+ local evname=${2}
+
+ while true
+ do
+ _check_cached_events $evname
+
+ if [ $matched = 1 ];
+ then
+ return
+ fi
+
+ only_capture_events=1 qemu_error_no_exit=1 _timed_wait_for ${h}
+
+ if [ ${QEMU_STATUS[$h]} -ne 0 ] ; then
+ echo "Timeout waiting for event ${evname} on handle ${h}"
+ exit 1 #Timeout means the test failed
+ fi
+ done
+}
+
# Launch a QEMU process.
#
# Input parameters:
--
2.26.2
- Re: [PATCH v6 01/10] block: push error reporting into bdrv_all_*_snapshot functions, (continued)
- [PATCH v6 05/10] block: rename and alter bdrv_all_find_snapshot semantics, Daniel P . Berrangé, 2020/10/08
- [PATCH v6 02/10] migration: stop returning errno from load_snapshot(), Daniel P . Berrangé, 2020/10/08
- [PATCH v6 06/10] migration: control whether snapshots are ovewritten, Daniel P . Berrangé, 2020/10/08
- [PATCH v6 07/10] migration: wire up support for snapshot device selection, Daniel P . Berrangé, 2020/10/08
- [PATCH v6 08/10] migration: introduce a delete_snapshot wrapper, Daniel P . Berrangé, 2020/10/08
- [PATCH v6 09/10] iotests: add support for capturing and matching QMP events,
Daniel P . Berrangé <=
- [PATCH v6 10/10] migration: introduce snapshot-{save, load, delete} QMP commands, Daniel P . Berrangé, 2020/10/08
- Re: [PATCH v6 00/10] migration: bring improved savevm/loadvm/delvm to QMP, Daniel P . Berrangé, 2020/10/15