From nobody Wed Nov 5 05:07:26 2025 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail(p=none dis=none) header.from=redhat.com Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1532940447991955.2247637850895; Mon, 30 Jul 2018 01:47:27 -0700 (PDT) Received: from localhost ([::1]:51243 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1fk3po-0006fQ-0w for importer@patchew.org; Mon, 30 Jul 2018 04:47:20 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:39486) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1fk3cN-0003PR-A1 for qemu-devel@nongnu.org; Mon, 30 Jul 2018 04:33:29 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1fk3cJ-0004Zo-MR for qemu-devel@nongnu.org; Mon, 30 Jul 2018 04:33:27 -0400 Received: from mx3-rdu2.redhat.com ([66.187.233.73]:45086 helo=mx1.redhat.com) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1fk3cJ-0004YZ-GR for qemu-devel@nongnu.org; Mon, 30 Jul 2018 04:33:23 -0400 Received: from smtp.corp.redhat.com (int-mx05.intmail.prod.int.rdu2.redhat.com [10.11.54.5]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 121D540214E2; Mon, 30 Jul 2018 08:33:23 +0000 (UTC) Received: from blackfin.pond.sub.org (ovpn-116-135.ams2.redhat.com [10.36.116.135]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 4C4CFFF5B; Mon, 30 Jul 2018 08:33:21 +0000 (UTC) Received: by blackfin.pond.sub.org (Postfix, from userid 1000) id B136D1133040; Mon, 30 Jul 2018 10:33:17 +0200 (CEST) From: Markus Armbruster To: qemu-devel@nongnu.org Date: Mon, 30 Jul 2018 10:33:09 +0200 Message-Id: <20180730083317.11765-16-armbru@redhat.com> In-Reply-To: <20180730083317.11765-1-armbru@redhat.com> References: <20180730083317.11765-1-armbru@redhat.com> X-Scanned-By: MIMEDefang 2.79 on 10.11.54.5 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.11.55.7]); Mon, 30 Jul 2018 08:33:23 +0000 (UTC) X-Greylist: inspected by milter-greylist-4.5.16 (mx1.redhat.com [10.11.55.7]); Mon, 30 Jul 2018 08:33:23 +0000 (UTC) for IP:'10.11.54.5' DOMAIN:'int-mx05.intmail.prod.int.rdu2.redhat.com' HELO:'smtp.corp.redhat.com' FROM:'armbru@redhat.com' RCPT:'' X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 66.187.233.73 Subject: [Qemu-devel] [PATCH v3 15/23] tests: New helper qtest_qmp_receive_success() X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: thuth@redhat.com, Stefan Berger , Juan Quintela , f4bug@amsat.org, "Dr . David Alan Gilbert" Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail: RSF_0 Z_629925259 SPT_0 Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Commit b21373d0713 copied wait_command() from tests/migration-test.c to tests/tpm-util.c. Replace both copies by new libqtest helper qtest_qmp_receive_success(). Also use it to simplify qtest_qmp_device_del(). Bonus: gets rid of a non-literal format string. A step towards compile-time format string checking without triggering -Wformat-nonliteral. Cc: Thomas Huth Cc: Juan Quintela Cc: Dr. David Alan Gilbert Cc: Stefan Berger Signed-off-by: Markus Armbruster Reviewed-by: Juan Quintela Reviewed-by: Stefan Berger Reviewed-by: Eric Blake --- tests/libqtest.c | 69 ++++++++++++++++++++++++++++++------------ tests/libqtest.h | 17 +++++++++++ tests/migration-test.c | 29 ++++++------------ tests/tpm-util.c | 32 +++----------------- 4 files changed, 80 insertions(+), 67 deletions(-) diff --git a/tests/libqtest.c b/tests/libqtest.c index dfca3af89d..ed832cd8e6 100644 --- a/tests/libqtest.c +++ b/tests/libqtest.c @@ -1029,6 +1029,35 @@ void qtest_cb_for_every_machine(void (*cb)(const cha= r *machine)) qobject_unref(response); } =20 +QDict *qtest_qmp_receive_success(QTestState *s, + void (*event_cb)(void *opaque, + const char *event, + QDict *data), + void *opaque) +{ + QDict *response, *ret, *data; + const char *event; + + for (;;) { + response =3D qtest_qmp_receive(s); + g_assert(!qdict_haskey(response, "error")); + ret =3D qdict_get_qdict(response, "return"); + if (ret) { + break; + } + event =3D qdict_get_str(response, "event"); + data =3D qdict_get_qdict(response, "data"); + if (event_cb) { + event_cb(opaque, event, data); + } + qobject_unref(response); + } + + qobject_ref(ret); + qobject_unref(response); + return ret; +} + /* * Generic hot-plugging test via the device_add QMP command. */ @@ -1053,6 +1082,14 @@ void qtest_qmp_device_add(const char *driver, const = char *id, qobject_unref(response); } =20 +static void device_deleted_cb(void *opaque, const char *name, QDict *data) +{ + bool *got_event =3D opaque; + + g_assert_cmpstr(name, =3D=3D, "DEVICE_DELETED"); + *got_event =3D true; +} + /* * Generic hot-unplugging test via the device_del QMP command. * Device deletion will get one response and one event. For example: @@ -1073,27 +1110,21 @@ void qtest_qmp_device_add(const char *driver, const= char *id, */ void qtest_qmp_device_del(const char *id) { - QDict *response1, *response2, *event =3D NULL; + bool got_event =3D false; + QDict *rsp; =20 - response1 =3D qmp("{'execute': 'device_del', 'arguments': {'id': %s}}", - id); - g_assert(response1); - g_assert(!qdict_haskey(response1, "error")); - - response2 =3D qmp_receive(); - g_assert(response2); - g_assert(!qdict_haskey(response2, "error")); - - if (qdict_haskey(response1, "event")) { - event =3D response1; - } else if (qdict_haskey(response2, "event")) { - event =3D response2; + qtest_qmp_send(global_qtest, + "{'execute': 'device_del', 'arguments': {'id': %s}}", + id); + rsp =3D qtest_qmp_receive_success(global_qtest, device_deleted_cb, + &got_event); + qobject_unref(rsp); + if (!got_event) { + rsp =3D qmp_receive(); + g_assert_cmpstr(qdict_get_try_str(rsp, "event"), + =3D=3D, "DEVICE_DELETED"); + qobject_unref(rsp); } - g_assert(event); - g_assert_cmpstr(qdict_get_str(event, "event"), =3D=3D, "DEVICE_DELETED= "); - - qobject_unref(response1); - qobject_unref(response2); } =20 bool qmp_rsp_is_err(QDict *rsp) diff --git a/tests/libqtest.h b/tests/libqtest.h index ce6c092fc9..ee58fcdf6d 100644 --- a/tests/libqtest.h +++ b/tests/libqtest.h @@ -169,6 +169,23 @@ void qtest_qmp_eventwait(QTestState *s, const char *ev= ent); */ QDict *qtest_qmp_eventwait_ref(QTestState *s, const char *event); =20 +/** + * qtest_qmp_receive_success: + * @s: #QTestState instance to operate on + * @event_cb: Event callback + * @opaque: Argument for @event_cb + * + * Poll QMP messages until a command success response is received. + * If @event_cb, call it for each event received, passing @opaque, + * the event's name and data. + * Return the success response's "return" member. + */ +QDict *qtest_qmp_receive_success(QTestState *s, + void (*event_cb)(void *opaque, + const char *name, + QDict *data), + void *opaque); + /** * qtest_hmp: * @s: #QTestState instance to operate on. diff --git a/tests/migration-test.c b/tests/migration-test.c index e336399a71..860b8aa0b9 100644 --- a/tests/migration-test.c +++ b/tests/migration-test.c @@ -146,31 +146,20 @@ static void wait_for_serial(const char *side) } while (true); } =20 +static void stop_cb(void *opaque, const char *name, QDict *data) +{ + if (!strcmp(name, "STOP")) { + got_stop =3D true; + } +} + /* * Events can get in the way of responses we are actually waiting for. */ static QDict *wait_command(QTestState *who, const char *command) { - const char *event_string; - QDict *response, *ret; - - response =3D qtest_qmp(who, command); - - while (qdict_haskey(response, "event")) { - /* OK, it was an event */ - event_string =3D qdict_get_str(response, "event"); - if (!strcmp(event_string, "STOP")) { - got_stop =3D true; - } - qobject_unref(response); - response =3D qtest_qmp_receive(who); - } - - ret =3D qdict_get_qdict(response, "return"); - g_assert(ret); - qobject_ref(ret); - qobject_unref(response); - return ret; + qtest_qmp_send(who, command); + return qtest_qmp_receive_success(who, stop_cb, NULL); } =20 /* diff --git a/tests/tpm-util.c b/tests/tpm-util.c index 3bd2887f1e..9f3f156e42 100644 --- a/tests/tpm-util.c +++ b/tests/tpm-util.c @@ -22,8 +22,6 @@ #define TIS_REG(LOCTY, REG) \ (TPM_TIS_ADDR_BASE + ((LOCTY) << 12) + REG) =20 -static bool got_stop; - void tpm_util_crb_transfer(QTestState *s, const unsigned char *req, size_t req_size, unsigned char *rsp, size_t rsp_size) @@ -247,41 +245,19 @@ void tpm_util_migrate(QTestState *who, const char *ur= i) qobject_unref(rsp); } =20 -/* - * Events can get in the way of responses we are actually waiting for. - */ -static QDict *tpm_util_wait_command(QTestState *who, const char *command) -{ - const char *event_string; - QDict *response; - - response =3D qtest_qmp(who, command); - - while (qdict_haskey(response, "event")) { - /* OK, it was an event */ - event_string =3D qdict_get_str(response, "event"); - if (!strcmp(event_string, "STOP")) { - got_stop =3D true; - } - qobject_unref(response); - response =3D qtest_qmp_receive(who); - } - return response; -} - void tpm_util_wait_for_migration_complete(QTestState *who) { while (true) { - QDict *rsp, *rsp_return; + QDict *rsp_return; bool completed; const char *status; =20 - rsp =3D tpm_util_wait_command(who, "{ 'execute': 'query-migrate' }= "); - rsp_return =3D qdict_get_qdict(rsp, "return"); + qtest_qmp_send(who, "{ 'execute': 'query-migrate' }"); + rsp_return =3D qtest_qmp_receive_success(who, NULL, NULL); status =3D qdict_get_str(rsp_return, "status"); completed =3D strcmp(status, "completed") =3D=3D 0; g_assert_cmpstr(status, !=3D, "failed"); - qobject_unref(rsp); + qobject_unref(rsp_return); if (completed) { return; } --=20 2.17.1