From patchwork Wed May 31 13:23:52 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Daniel_P=2E_Berrang=C3=A9?= X-Patchwork-Id: 1788358 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=nongnu.org (client-ip=209.51.188.17; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: legolas.ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=redhat.com header.i=@redhat.com header.a=rsa-sha256 header.s=mimecast20190719 header.b=CGFKYoeT; dkim-atps=neutral Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-ECDSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4QWVNb3dSJz20Py for ; Wed, 31 May 2023 23:24:31 +1000 (AEST) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1q4LoG-0005kI-F2; Wed, 31 May 2023 09:24:16 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1q4LoE-0005cK-3k for qemu-devel@nongnu.org; Wed, 31 May 2023 09:24:14 -0400 Received: from us-smtp-delivery-124.mimecast.com ([170.10.129.124]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1q4Lo9-0004Lw-Pu for qemu-devel@nongnu.org; Wed, 31 May 2023 09:24:12 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1685539448; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=Og53zO2oDpZYfwC+DsBUoXwKDCBdok0FLhJi5Kg+Tbo=; b=CGFKYoeT1aiiSxWUur8+qRIrtB0iBJ5gd1VCYaJqjrJwhPzKai679NsysCy+xwshFWBgmK /vdvkGNZfFc9tDzTzVr4xrtBJQB5gS4o9+JKaWHUm4CSxQ8HSzN+Py7qucS2ULEdp2oPqP gZ5ujPnZu1YwL3LUWpUqR3D+Dsx14ss= Received: from mimecast-mx02.redhat.com (mimecast-mx02.redhat.com [66.187.233.88]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id us-mta-515-PjSL0xrOPN-m5UzlTpdPTQ-1; Wed, 31 May 2023 09:24:05 -0400 X-MC-Unique: PjSL0xrOPN-m5UzlTpdPTQ-1 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 mimecast-mx02.redhat.com (Postfix) with ESMTPS id 9556C802E58 for ; Wed, 31 May 2023 13:24:05 +0000 (UTC) Received: from localhost.localdomain.com (unknown [10.42.28.177]) by smtp.corp.redhat.com (Postfix) with ESMTP id 0727E420AA; Wed, 31 May 2023 13:24:03 +0000 (UTC) From: =?utf-8?q?Daniel_P=2E_Berrang=C3=A9?= To: qemu-devel@nongnu.org Cc: Laurent Vivier , Peter Xu , Juan Quintela , Leonardo Bras , Thomas Huth , Paolo Bonzini , =?utf-8?q?Daniel_P=2E_Berrang=C3=A9?= Subject: [PATCH v3 1/9] tests/qtest: add various qtest_qmp_assert_success() variants Date: Wed, 31 May 2023 14:23:52 +0100 Message-Id: <20230531132400.1129576-2-berrange@redhat.com> In-Reply-To: <20230531132400.1129576-1-berrange@redhat.com> References: <20230531132400.1129576-1-berrange@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.1 on 10.11.54.5 Received-SPF: pass client-ip=170.10.129.124; envelope-from=berrange@redhat.com; helo=us-smtp-delivery-124.mimecast.com X-Spam_score_int: -22 X-Spam_score: -2.3 X-Spam_bar: -- X-Spam_report: (-2.3 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.163, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001, T_SCC_BODY_TEXT_LINE=-0.01 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Add several counterparts of qtest_qmp_assert_success() that can * Use va_list instead of ... * Accept a list of FDs to send * Return the response data Signed-off-by: Daniel P. Berrangé Reviewed-by: Thomas Huth --- tests/qtest/libqtest.c | 99 +++++++++++++++++++++++++++++++++-- tests/qtest/libqtest.h | 115 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 209 insertions(+), 5 deletions(-) diff --git a/tests/qtest/libqtest.c b/tests/qtest/libqtest.c index c3a0ef5bb4..603c26d955 100644 --- a/tests/qtest/libqtest.c +++ b/tests/qtest/libqtest.c @@ -1229,14 +1229,23 @@ void qtest_memset(QTestState *s, uint64_t addr, uint8_t pattern, size_t size) qtest_rsp(s); } -void qtest_qmp_assert_success(QTestState *qts, const char *fmt, ...) +void qtest_vqmp_assert_success(QTestState *qts, + const char *fmt, va_list args) { - va_list ap; QDict *response; - va_start(ap, fmt); - response = qtest_vqmp(qts, fmt, ap); - va_end(ap); + response = qtest_vqmp_assert_success_ref(qts, fmt, args); + + qobject_unref(response); +} + +QDict *qtest_vqmp_assert_success_ref(QTestState *qts, + const char *fmt, va_list args) +{ + QDict *response; + QDict *ret; + + response = qtest_vqmp(qts, fmt, args); g_assert(response); if (!qdict_haskey(response, "return")) { @@ -1245,8 +1254,88 @@ void qtest_qmp_assert_success(QTestState *qts, const char *fmt, ...) g_string_free(s, true); } g_assert(qdict_haskey(response, "return")); + ret = qdict_get_qdict(response, "return"); + qobject_ref(ret); + qobject_unref(response); + + return ret; +} + +#ifndef _WIN32 +QDict *qtest_vqmp_fds_assert_success_ref(QTestState *qts, int *fds, size_t nfds, + const char *fmt, va_list args) +{ + QDict *response; + QDict *ret; + + response = qtest_vqmp_fds(qts, fds, nfds, fmt, args); + + g_assert(response); + if (!qdict_haskey(response, "return")) { + GString *s = qobject_to_json_pretty(QOBJECT(response), true); + g_test_message("%s", s->str); + g_string_free(s, true); + } + g_assert(qdict_haskey(response, "return")); + ret = qdict_get_qdict(response, "return"); + qobject_ref(ret); + qobject_unref(response); + + return ret; +} + +void qtest_vqmp_fds_assert_success(QTestState *qts, int *fds, size_t nfds, + const char *fmt, va_list args) +{ + QDict *response; + response = qtest_vqmp_fds_assert_success_ref(qts, fds, nfds, fmt, args); qobject_unref(response); } +#endif /* !_WIN32 */ + +void qtest_qmp_assert_success(QTestState *qts, const char *fmt, ...) +{ + QDict *response; + va_list ap; + va_start(ap, fmt); + response = qtest_vqmp_assert_success_ref(qts, fmt, ap); + va_end(ap); + qobject_unref(response); +} + +QDict *qtest_qmp_assert_success_ref(QTestState *qts, const char *fmt, ...) +{ + QDict *response; + va_list ap; + va_start(ap, fmt); + response = qtest_vqmp_assert_success_ref(qts, fmt, ap); + va_end(ap); + return response; +} + +#ifndef _WIN32 +void qtest_qmp_fds_assert_success(QTestState *qts, int *fds, size_t nfds, + const char *fmt, ...) +{ + QDict *response; + va_list ap; + va_start(ap, fmt); + response = qtest_vqmp_fds_assert_success_ref(qts, fds, nfds, fmt, ap); + va_end(ap); + qobject_unref(response); +} + +QDict *qtest_qmp_fds_assert_success_ref(QTestState *qts, int *fds, size_t nfds, + const char *fmt, ...) +{ + QDict *response; + va_list ap; + va_start(ap, fmt); + response = qtest_vqmp_fds_assert_success_ref(qts, fds, nfds, fmt, ap); + va_end(ap); + return response; +} +#endif /* !_WIN32 */ bool qtest_big_endian(QTestState *s) { diff --git a/tests/qtest/libqtest.h b/tests/qtest/libqtest.h index 8d7d450963..41bc6633bd 100644 --- a/tests/qtest/libqtest.h +++ b/tests/qtest/libqtest.h @@ -693,6 +693,73 @@ void qtest_add_abrt_handler(GHookFunc fn, const void *data); */ void qtest_remove_abrt_handler(void *data); +/** + * qtest_vqmp_assert_success: + * @qts: QTestState instance to operate on + * @fmt: QMP message to send to qemu, formatted like + * qobject_from_jsonf_nofail(). See parse_interpolation() for what's + * supported after '%'. + * @args: variable arguments for @fmt + * + * Sends a QMP message to QEMU and asserts that a 'return' key is present in + * the response. + */ +void qtest_vqmp_assert_success(QTestState *qts, + const char *fmt, va_list args) + G_GNUC_PRINTF(2, 0); + +/** + * qtest_vqmp_assert_success_ref: + * @qts: QTestState instance to operate on + * @fmt: QMP message to send to qemu, formatted like + * qobject_from_jsonf_nofail(). See parse_interpolation() for what's + * supported after '%'. + * @args: variable arguments for @fmt + * + * Sends a QMP message to QEMU, asserts that a 'return' key is present in + * the response, and returns the response. + */ +QDict *qtest_vqmp_assert_success_ref(QTestState *qts, + const char *fmt, va_list args) + G_GNUC_PRINTF(2, 0); + +#ifndef _WIN32 +/** + * qtest_vqmp_fds_assert_success: + * @qts: QTestState instance to operate on + * @fds: the file descriptors to send + * @nfds: number of @fds to send + * @fmt: QMP message to send to qemu, formatted like + * qobject_from_jsonf_nofail(). See parse_interpolation() for what's + * supported after '%'. + * @args: variable arguments for @fmt + * + * Sends a QMP message with file descriptors to QEMU and + * asserts that a 'return' key is present in the response. + */ +void qtest_vqmp_fds_assert_success(QTestState *qts, int *fds, size_t nfds, + const char *fmt, va_list args) + G_GNUC_PRINTF(4, 0); + +/** + * qtest_vqmp_fds_assert_success_ref: + * @qts: QTestState instance to operate on + * @fds: the file descriptors to send + * @nfds: number of @fds to send + * @fmt: QMP message to send to qemu, formatted like + * qobject_from_jsonf_nofail(). See parse_interpolation() for what's + * supported after '%'. + * @args: variable arguments for @fmt + * + * Sends a QMP message with file descriptors to QEMU, + * asserts that a 'return' key is present in the response, + * and returns the response. + */ +QDict *qtest_vqmp_fds_assert_success_ref(QTestState *qts, int *fds, size_t nfds, + const char *fmt, va_list args) + G_GNUC_PRINTF(4, 0); +#endif /* !_WIN32 */ + /** * qtest_qmp_assert_success: * @qts: QTestState instance to operate on @@ -706,6 +773,54 @@ void qtest_remove_abrt_handler(void *data); void qtest_qmp_assert_success(QTestState *qts, const char *fmt, ...) G_GNUC_PRINTF(2, 3); +/** + * qtest_qmp_assert_success_ref: + * @qts: QTestState instance to operate on + * @fmt: QMP message to send to qemu, formatted like + * qobject_from_jsonf_nofail(). See parse_interpolation() for what's + * supported after '%'. + * + * Sends a QMP message to QEMU, asserts that a 'return' key is present in + * the response, and returns the response. + */ +QDict *qtest_qmp_assert_success_ref(QTestState *qts, const char *fmt, ...) + G_GNUC_PRINTF(2, 3); + +#ifndef _WIN32 +/** + * qtest_qmp_fd_assert_success: + * @qts: QTestState instance to operate on + * @fds: the file descriptors to send + * @nfds: number of @fds to send + * @fmt: QMP message to send to qemu, formatted like + * qobject_from_jsonf_nofail(). See parse_interpolation() for what's + * supported after '%'. + * + * Sends a QMP message with file descriptors to QEMU and + * asserts that a 'return' key is present in the response. + */ +void qtest_qmp_fds_assert_success(QTestState *qts, int *fds, size_t nfds, + const char *fmt, ...) + G_GNUC_PRINTF(4, 5); + +/** + * qtest_qmp_fd_assert_success_ref: + * @qts: QTestState instance to operate on + * @fds: the file descriptors to send + * @nfds: number of @fds to send + * @fmt: QMP message to send to qemu, formatted like + * qobject_from_jsonf_nofail(). See parse_interpolation() for what's + * supported after '%'. + * + * Sends a QMP message with file descriptors to QEMU, + * asserts that a 'return' key is present in the response, + * and returns the response. + */ +QDict *qtest_qmp_fds_assert_success_ref(QTestState *qts, int *fds, size_t nfds, + const char *fmt, ...) + G_GNUC_PRINTF(4, 5); +#endif /* !_WIN32 */ + /** * qtest_cb_for_every_machine: * @cb: Pointer to the callback function From patchwork Wed May 31 13:23:53 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Daniel_P=2E_Berrang=C3=A9?= X-Patchwork-Id: 1788360 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=nongnu.org (client-ip=209.51.188.17; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: legolas.ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=redhat.com header.i=@redhat.com header.a=rsa-sha256 header.s=mimecast20190719 header.b=BaNnyNzC; dkim-atps=neutral Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-ECDSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4QWVNr0B1Yz20Py for ; Wed, 31 May 2023 23:24:44 +1000 (AEST) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1q4LoK-0005w4-Ed; Wed, 31 May 2023 09:24:20 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1q4LoF-0005jt-7f for qemu-devel@nongnu.org; Wed, 31 May 2023 09:24:15 -0400 Received: from us-smtp-delivery-124.mimecast.com ([170.10.133.124]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1q4LoC-0004MG-9t for qemu-devel@nongnu.org; Wed, 31 May 2023 09:24:14 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1685539451; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=76mbrlJFbOf3a8izJ/pMLGPkL6i/wfEhVypqWzlKs4s=; b=BaNnyNzCC9xPuKMvuMEWI1Lb4u6I9Ti37SQFeGGNrd1CkfJuJnHyOCYGVYnn4W6uFJmMIW 1XoBiN11Z+eJCX6jVlrHPcaOHUpFzmBAppbMVNzG/kXFe1T+gCEahq8NwMjszLLmk0WdMX oO5lj/IE7ln6ynVMl+cGyuf8A9kwXuM= Received: from mimecast-mx02.redhat.com (mimecast-mx02.redhat.com [66.187.233.88]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id us-mta-460-7UvaUmidOSOPdY3j0wgP9Q-1; Wed, 31 May 2023 09:24:08 -0400 X-MC-Unique: 7UvaUmidOSOPdY3j0wgP9Q-1 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 mimecast-mx02.redhat.com (Postfix) with ESMTPS id C7C8E811761 for ; Wed, 31 May 2023 13:24:07 +0000 (UTC) Received: from localhost.localdomain.com (unknown [10.42.28.177]) by smtp.corp.redhat.com (Postfix) with ESMTP id CC85B170ED; Wed, 31 May 2023 13:24:05 +0000 (UTC) From: =?utf-8?q?Daniel_P=2E_Berrang=C3=A9?= To: qemu-devel@nongnu.org Cc: Laurent Vivier , Peter Xu , Juan Quintela , Leonardo Bras , Thomas Huth , Paolo Bonzini , =?utf-8?q?Daniel_P=2E_Berrang=C3=A9?= Subject: [PATCH v3 2/9] tests/qtest: add support for callback to receive QMP events Date: Wed, 31 May 2023 14:23:53 +0100 Message-Id: <20230531132400.1129576-3-berrange@redhat.com> In-Reply-To: <20230531132400.1129576-1-berrange@redhat.com> References: <20230531132400.1129576-1-berrange@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.1 on 10.11.54.5 Received-SPF: pass client-ip=170.10.133.124; envelope-from=berrange@redhat.com; helo=us-smtp-delivery-124.mimecast.com X-Spam_score_int: -22 X-Spam_score: -2.3 X-Spam_bar: -- X-Spam_report: (-2.3 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.163, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001, T_SCC_BODY_TEXT_LINE=-0.01 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Currently code must call one of the qtest_qmp_event* functions to fetch events. These are only usable if the immediate caller knows the particular event they want to capture, and are only interested in one specific event type. Adding ability to register an event callback lets the caller capture a range of events over any period of time. Signed-off-by: Daniel P. Berrangé Reviewed-by: Thomas Huth --- tests/qtest/libqtest.c | 20 ++++++++++++++++++-- tests/qtest/libqtest.h | 37 +++++++++++++++++++++++++++++++++++-- 2 files changed, 53 insertions(+), 4 deletions(-) diff --git a/tests/qtest/libqtest.c b/tests/qtest/libqtest.c index 603c26d955..1534177fc1 100644 --- a/tests/qtest/libqtest.c +++ b/tests/qtest/libqtest.c @@ -82,6 +82,8 @@ struct QTestState GString *rx; QTestTransportOps ops; GList *pending_events; + QTestQMPEventCallback eventCB; + void *eventData; }; static GHookList abrt_hooks; @@ -703,8 +705,14 @@ QDict *qtest_qmp_receive(QTestState *s) if (!qdict_get_try_str(response, "event")) { return response; } - /* Stash the event for a later consumption */ - s->pending_events = g_list_append(s->pending_events, response); + + if (s->eventCB) { + s->eventCB(s, qdict_get_str(response, "event"), + response, s->eventData); + } else { + /* Stash the event for a later consumption */ + s->pending_events = g_list_append(s->pending_events, response); + } } } @@ -808,6 +816,14 @@ void qtest_qmp_send_raw(QTestState *s, const char *fmt, ...) va_end(ap); } +void qtest_qmp_set_event_callback(QTestState *s, + QTestQMPEventCallback cb, void *opaque) +{ + s->eventCB = cb; + s->eventData = opaque; +} + + QDict *qtest_qmp_event_ref(QTestState *s, const char *event) { while (s->pending_events) { diff --git a/tests/qtest/libqtest.h b/tests/qtest/libqtest.h index 41bc6633bd..67ec4db43e 100644 --- a/tests/qtest/libqtest.h +++ b/tests/qtest/libqtest.h @@ -238,17 +238,46 @@ QDict *qtest_qmp_receive_dict(QTestState *s); * @s: #QTestState instance to operate on. * * Reads a QMP message from QEMU and returns the response. - * Buffers all the events received meanwhile, until a - * call to qtest_qmp_eventwait + * + * If a callback is registered with qtest_qmp_set_event_callback, + * it will be invoked for every event seen, otherwise events + * will be buffered until a call to one of the qtest_qmp_eventwait + * family of functions. */ QDict *qtest_qmp_receive(QTestState *s); +/* + * QTestQMPEventCallback: + * @s: #QTestState instance event was received on + * @name: name of the event type + * @event: #QDict for the event details + * @opaque: opaque data from time of callback registration + * + * This callback will be invoked whenever an event is received + */ +typedef bool (*QTestQMPEventCallback)(QTestState *s, const char *name, + QDict *event, void *opaque); + +/** + * qtest_qmp_set_event_callback: + * @s: #QTestSTate instance to operate on + * @cb: callback to invoke for events + * @opaque: data to pass to @cb + * + * Register a callback to be invoked whenever an event arrives + */ +void qtest_qmp_set_event_callback(QTestState *s, + QTestQMPEventCallback cb, void *opaque); + /** * qtest_qmp_eventwait: * @s: #QTestState instance to operate on. * @event: event to wait for. * * Continuously polls for QMP responses until it receives the desired event. + * + * Any callback registered with qtest_qmp_set_event_callback will + * be invoked for every event seen. */ void qtest_qmp_eventwait(QTestState *s, const char *event); @@ -258,6 +287,10 @@ void qtest_qmp_eventwait(QTestState *s, const char *event); * @event: event to wait for. * * Continuously polls for QMP responses until it receives the desired event. + * + * Any callback registered with qtest_qmp_set_event_callback will + * be invoked for every event seen. + * * Returns a copy of the event for further investigation. */ QDict *qtest_qmp_eventwait_ref(QTestState *s, const char *event); From patchwork Wed May 31 13:23:54 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Daniel_P=2E_Berrang=C3=A9?= X-Patchwork-Id: 1788364 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=nongnu.org (client-ip=209.51.188.17; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: legolas.ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=redhat.com header.i=@redhat.com header.a=rsa-sha256 header.s=mimecast20190719 header.b=KsvB6FHy; dkim-atps=neutral Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-ECDSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4QWVP85rpPz20Py for ; Wed, 31 May 2023 23:25:00 +1000 (AEST) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1q4LoI-0005pa-AN; Wed, 31 May 2023 09:24:18 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1q4LoE-0005iR-V8 for qemu-devel@nongnu.org; Wed, 31 May 2023 09:24:14 -0400 Received: from us-smtp-delivery-124.mimecast.com ([170.10.133.124]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1q4LoD-0004Ma-8A for qemu-devel@nongnu.org; Wed, 31 May 2023 09:24:14 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1685539452; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=1cWRz0yjLpnC5qwvV/C5VDMBLtvPsEmvO5tMGdE/rP4=; b=KsvB6FHyD7A5r6sdCnDMoNoPF3GQF915lv/pGS/MjKV6KE3KlJNn9mhu0kjUq1en1Ck0Ts +BYyvyPCWIUEsQzlT3vpm49jtQ2HPcg2D4z0s3Rnf6DhMOzVYzOGM1K9ZKWhqpV+VVp00R 4Z0APaC5H/oOEq9LPjd9DWRdve2IL4Y= Received: from mimecast-mx02.redhat.com (mx3-rdu2.redhat.com [66.187.233.73]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id us-mta-416-h0vLRuH7NqqomkYWpwXV7Q-1; Wed, 31 May 2023 09:24:09 -0400 X-MC-Unique: h0vLRuH7NqqomkYWpwXV7Q-1 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 mimecast-mx02.redhat.com (Postfix) with ESMTPS id A13423C11C7C for ; Wed, 31 May 2023 13:24:09 +0000 (UTC) Received: from localhost.localdomain.com (unknown [10.42.28.177]) by smtp.corp.redhat.com (Postfix) with ESMTP id 471C6170ED; Wed, 31 May 2023 13:24:08 +0000 (UTC) From: =?utf-8?q?Daniel_P=2E_Berrang=C3=A9?= To: qemu-devel@nongnu.org Cc: Laurent Vivier , Peter Xu , Juan Quintela , Leonardo Bras , Thomas Huth , Paolo Bonzini , =?utf-8?q?Daniel_P=2E_Berrang=C3=A9?= Subject: [PATCH v3 3/9] tests/qtest: get rid of 'qmp_command' helper in migration test Date: Wed, 31 May 2023 14:23:54 +0100 Message-Id: <20230531132400.1129576-4-berrange@redhat.com> In-Reply-To: <20230531132400.1129576-1-berrange@redhat.com> References: <20230531132400.1129576-1-berrange@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.1 on 10.11.54.5 Received-SPF: pass client-ip=170.10.133.124; envelope-from=berrange@redhat.com; helo=us-smtp-delivery-124.mimecast.com X-Spam_score_int: -22 X-Spam_score: -2.3 X-Spam_bar: -- X-Spam_report: (-2.3 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.163, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001, T_SCC_BODY_TEXT_LINE=-0.01 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org This function duplicates logic of qtest_qmp_assert_success_ref Signed-off-by: Daniel P. Berrangé Reviewed-by: Juan Quintela --- tests/qtest/migration-helpers.c | 22 ---------------------- tests/qtest/migration-helpers.h | 3 --- tests/qtest/migration-test.c | 29 +++++++++++++++-------------- 3 files changed, 15 insertions(+), 39 deletions(-) diff --git a/tests/qtest/migration-helpers.c b/tests/qtest/migration-helpers.c index f6f3c6680f..bddf3f8d4d 100644 --- a/tests/qtest/migration-helpers.c +++ b/tests/qtest/migration-helpers.c @@ -85,28 +85,6 @@ QDict *wait_command(QTestState *who, const char *command, ...) return ret; } -/* - * Execute the qmp command only - */ -QDict *qmp_command(QTestState *who, const char *command, ...) -{ - va_list ap; - QDict *resp, *ret; - - va_start(ap, command); - resp = qtest_vqmp(who, command, ap); - va_end(ap); - - g_assert(!qdict_haskey(resp, "error")); - g_assert(qdict_haskey(resp, "return")); - - ret = qdict_get_qdict(resp, "return"); - qobject_ref(ret); - qobject_unref(resp); - - return ret; -} - /* * Send QMP command "migrate". * Arguments are built from @fmt... (formatted like diff --git a/tests/qtest/migration-helpers.h b/tests/qtest/migration-helpers.h index a188b62787..2e51a6e195 100644 --- a/tests/qtest/migration-helpers.h +++ b/tests/qtest/migration-helpers.h @@ -25,9 +25,6 @@ QDict *wait_command_fd(QTestState *who, int fd, const char *command, ...); G_GNUC_PRINTF(2, 3) QDict *wait_command(QTestState *who, const char *command, ...); -G_GNUC_PRINTF(2, 3) -QDict *qmp_command(QTestState *who, const char *command, ...); - G_GNUC_PRINTF(3, 4) void migrate_qmp(QTestState *who, const char *uri, const char *fmt, ...); diff --git a/tests/qtest/migration-test.c b/tests/qtest/migration-test.c index b99b49a314..9ce27f89ec 100644 --- a/tests/qtest/migration-test.c +++ b/tests/qtest/migration-test.c @@ -2322,32 +2322,33 @@ static void test_multifd_tcp_cancel(void) static void calc_dirty_rate(QTestState *who, uint64_t calc_time) { - qobject_unref(qmp_command(who, - "{ 'execute': 'calc-dirty-rate'," - "'arguments': { " - "'calc-time': %" PRIu64 "," - "'mode': 'dirty-ring' }}", - calc_time)); + qtest_qmp_assert_success(who, + "{ 'execute': 'calc-dirty-rate'," + "'arguments': { " + "'calc-time': %" PRIu64 "," + "'mode': 'dirty-ring' }}", + calc_time); } static QDict *query_dirty_rate(QTestState *who) { - return qmp_command(who, "{ 'execute': 'query-dirty-rate' }"); + return qtest_qmp_assert_success_ref(who, + "{ 'execute': 'query-dirty-rate' }"); } static void dirtylimit_set_all(QTestState *who, uint64_t dirtyrate) { - qobject_unref(qmp_command(who, - "{ 'execute': 'set-vcpu-dirty-limit'," - "'arguments': { " - "'dirty-rate': %" PRIu64 " } }", - dirtyrate)); + qtest_qmp_assert_success(who, + "{ 'execute': 'set-vcpu-dirty-limit'," + "'arguments': { " + "'dirty-rate': %" PRIu64 " } }", + dirtyrate); } static void cancel_vcpu_dirty_limit(QTestState *who) { - qobject_unref(qmp_command(who, - "{ 'execute': 'cancel-vcpu-dirty-limit' }")); + qtest_qmp_assert_success(who, + "{ 'execute': 'cancel-vcpu-dirty-limit' }"); } static QDict *query_vcpu_dirty_limit(QTestState *who) From patchwork Wed May 31 13:23:55 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Daniel_P=2E_Berrang=C3=A9?= X-Patchwork-Id: 1788365 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=nongnu.org (client-ip=209.51.188.17; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: legolas.ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=redhat.com header.i=@redhat.com header.a=rsa-sha256 header.s=mimecast20190719 header.b=CH7oV5/T; dkim-atps=neutral Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-ECDSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4QWVPM3pJnz20QB for ; Wed, 31 May 2023 23:25:11 +1000 (AEST) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1q4LoP-00069Y-J1; Wed, 31 May 2023 09:24:25 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1q4LoG-0005kw-C9 for qemu-devel@nongnu.org; Wed, 31 May 2023 09:24:16 -0400 Received: from us-smtp-delivery-124.mimecast.com ([170.10.133.124]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1q4LoE-0004Ml-K4 for qemu-devel@nongnu.org; Wed, 31 May 2023 09:24:16 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1685539453; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=OKVzMqfeXc54FLd3SXV1bcr0C2220MRSp+7SiUV5YuA=; b=CH7oV5/TUbPuhW8Quh8/AQHCvCvAAa4+SV1iNW2k1tItgS1KQS5DUoP+Pr33hMw99Ox7JL HD8/jjt5zbRthcXGwJPxbf8cTDe70GkdrGR00JMlhgSv8es2NJZnW1ULJwLZ5F8XrnarQU 6+e3P5f33v16JSWDe16m9q1v+UJfCqs= Received: from mimecast-mx02.redhat.com (mimecast-mx02.redhat.com [66.187.233.88]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id us-mta-630-_DOUrlYoPvmPbC9mbD7dbw-1; Wed, 31 May 2023 09:24:11 -0400 X-MC-Unique: _DOUrlYoPvmPbC9mbD7dbw-1 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 mimecast-mx02.redhat.com (Postfix) with ESMTPS id 4DC2D85A5B5 for ; Wed, 31 May 2023 13:24:11 +0000 (UTC) Received: from localhost.localdomain.com (unknown [10.42.28.177]) by smtp.corp.redhat.com (Postfix) with ESMTP id 0A984170ED; Wed, 31 May 2023 13:24:09 +0000 (UTC) From: =?utf-8?q?Daniel_P=2E_Berrang=C3=A9?= To: qemu-devel@nongnu.org Cc: Laurent Vivier , Peter Xu , Juan Quintela , Leonardo Bras , Thomas Huth , Paolo Bonzini , =?utf-8?q?Daniel_P=2E_Berrang=C3=A9?= Subject: [PATCH v3 4/9] tests/qtest: get rid of some 'qtest_qmp' usage in migration test Date: Wed, 31 May 2023 14:23:55 +0100 Message-Id: <20230531132400.1129576-5-berrange@redhat.com> In-Reply-To: <20230531132400.1129576-1-berrange@redhat.com> References: <20230531132400.1129576-1-berrange@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.1 on 10.11.54.5 Received-SPF: pass client-ip=170.10.133.124; envelope-from=berrange@redhat.com; helo=us-smtp-delivery-124.mimecast.com X-Spam_score_int: -22 X-Spam_score: -2.3 X-Spam_bar: -- X-Spam_report: (-2.3 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.163, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001, T_SCC_BODY_TEXT_LINE=-0.01 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Some of the usage is just a verbose way of re-inventing the qtest_qmp_assert_success(_ref) methods. Signed-off-by: Daniel P. Berrangé Reviewed-by: Thomas Huth Reviewed-by: Juan Quintela --- tests/qtest/migration-helpers.c | 8 ++--- tests/qtest/migration-test.c | 52 ++++++++++++--------------------- 2 files changed, 21 insertions(+), 39 deletions(-) diff --git a/tests/qtest/migration-helpers.c b/tests/qtest/migration-helpers.c index bddf3f8d4d..e26fdcb132 100644 --- a/tests/qtest/migration-helpers.c +++ b/tests/qtest/migration-helpers.c @@ -93,7 +93,7 @@ QDict *wait_command(QTestState *who, const char *command, ...) void migrate_qmp(QTestState *who, const char *uri, const char *fmt, ...) { va_list ap; - QDict *args, *rsp; + QDict *args; va_start(ap, fmt); args = qdict_from_vjsonf_nofail(fmt, ap); @@ -102,10 +102,8 @@ void migrate_qmp(QTestState *who, const char *uri, const char *fmt, ...) g_assert(!qdict_haskey(args, "uri")); qdict_put_str(args, "uri", uri); - rsp = qtest_qmp(who, "{ 'execute': 'migrate', 'arguments': %p}", args); - - g_assert(qdict_haskey(rsp, "return")); - qobject_unref(rsp); + qtest_qmp_assert_success(who, + "{ 'execute': 'migrate', 'arguments': %p}", args); } /* diff --git a/tests/qtest/migration-test.c b/tests/qtest/migration-test.c index 9ce27f89ec..822516286d 100644 --- a/tests/qtest/migration-test.c +++ b/tests/qtest/migration-test.c @@ -359,14 +359,10 @@ static void migrate_check_parameter_int(QTestState *who, const char *parameter, static void migrate_set_parameter_int(QTestState *who, const char *parameter, long long value) { - QDict *rsp; - - rsp = qtest_qmp(who, - "{ 'execute': 'migrate-set-parameters'," - "'arguments': { %s: %lld } }", - parameter, value); - g_assert(qdict_haskey(rsp, "return")); - qobject_unref(rsp); + qtest_qmp_assert_success(who, + "{ 'execute': 'migrate-set-parameters'," + "'arguments': { %s: %lld } }", + parameter, value); migrate_check_parameter_int(who, parameter, value); } @@ -392,14 +388,10 @@ static void migrate_check_parameter_str(QTestState *who, const char *parameter, static void migrate_set_parameter_str(QTestState *who, const char *parameter, const char *value) { - QDict *rsp; - - rsp = qtest_qmp(who, - "{ 'execute': 'migrate-set-parameters'," - "'arguments': { %s: %s } }", - parameter, value); - g_assert(qdict_haskey(rsp, "return")); - qobject_unref(rsp); + qtest_qmp_assert_success(who, + "{ 'execute': 'migrate-set-parameters'," + "'arguments': { %s: %s } }", + parameter, value); migrate_check_parameter_str(who, parameter, value); } @@ -427,14 +419,10 @@ static void migrate_check_parameter_bool(QTestState *who, const char *parameter, static void migrate_set_parameter_bool(QTestState *who, const char *parameter, int value) { - QDict *rsp; - - rsp = qtest_qmp(who, - "{ 'execute': 'migrate-set-parameters'," - "'arguments': { %s: %i } }", - parameter, value); - g_assert(qdict_haskey(rsp, "return")); - qobject_unref(rsp); + qtest_qmp_assert_success(who, + "{ 'execute': 'migrate-set-parameters'," + "'arguments': { %s: %i } }", + parameter, value); migrate_check_parameter_bool(who, parameter, value); } @@ -494,16 +482,12 @@ static void migrate_cancel(QTestState *who) static void migrate_set_capability(QTestState *who, const char *capability, bool value) { - QDict *rsp; - - rsp = qtest_qmp(who, - "{ 'execute': 'migrate-set-capabilities'," - "'arguments': { " - "'capabilities': [ { " - "'capability': %s, 'state': %i } ] } }", - capability, value); - g_assert(qdict_haskey(rsp, "return")); - qobject_unref(rsp); + qtest_qmp_assert_success(who, + "{ 'execute': 'migrate-set-capabilities'," + "'arguments': { " + "'capabilities': [ { " + "'capability': %s, 'state': %i } ] } }", + capability, value); } static void migrate_postcopy_start(QTestState *from, QTestState *to) From patchwork Wed May 31 13:23:56 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Daniel_P=2E_Berrang=C3=A9?= X-Patchwork-Id: 1788359 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=nongnu.org (client-ip=209.51.188.17; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: legolas.ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=redhat.com header.i=@redhat.com header.a=rsa-sha256 header.s=mimecast20190719 header.b=O2WG6yLB; dkim-atps=neutral Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-ECDSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4QWVNr0Jd3z20QD for ; Wed, 31 May 2023 23:24:44 +1000 (AEST) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1q4LoM-000604-73; Wed, 31 May 2023 09:24:22 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1q4LoG-0005od-RO for qemu-devel@nongnu.org; Wed, 31 May 2023 09:24:17 -0400 Received: from us-smtp-delivery-124.mimecast.com ([170.10.133.124]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1q4LoF-0004Mz-81 for qemu-devel@nongnu.org; Wed, 31 May 2023 09:24:16 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1685539454; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=6ydg4E0c9t8H5C7pZpw5lHwZfzpFaqPlxrLcxUisYKo=; b=O2WG6yLBFe/FIVm35k59YypeFN7SKhmBbyo98eG3COg9JIDPfUKaPbNx4eaNxK1M29MjFy 2/SwI4gI6cbwtH85f7fP7bG1yN/XnkwQe/Slh3u44BrjF6wJ017QjQ2JUSymrz42ef9Bct g6WXVIYYL+ZfAqlqe8gW6CD0Kwfi+zs= Received: from mimecast-mx02.redhat.com (mimecast-mx02.redhat.com [66.187.233.88]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id us-mta-114-M6QcwKjwMSeGw5867uRfqA-1; Wed, 31 May 2023 09:24:13 -0400 X-MC-Unique: M6QcwKjwMSeGw5867uRfqA-1 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 mimecast-mx02.redhat.com (Postfix) with ESMTPS id D5BC1811E7F for ; Wed, 31 May 2023 13:24:12 +0000 (UTC) Received: from localhost.localdomain.com (unknown [10.42.28.177]) by smtp.corp.redhat.com (Postfix) with ESMTP id 8212B420AA; Wed, 31 May 2023 13:24:11 +0000 (UTC) From: =?utf-8?q?Daniel_P=2E_Berrang=C3=A9?= To: qemu-devel@nongnu.org Cc: Laurent Vivier , Peter Xu , Juan Quintela , Leonardo Bras , Thomas Huth , Paolo Bonzini , =?utf-8?q?Daniel_P=2E_Berrang=C3=A9?= Subject: [PATCH v3 5/9] tests/qtest: switch to using event callbacks for STOP event Date: Wed, 31 May 2023 14:23:56 +0100 Message-Id: <20230531132400.1129576-6-berrange@redhat.com> In-Reply-To: <20230531132400.1129576-1-berrange@redhat.com> References: <20230531132400.1129576-1-berrange@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.1 on 10.11.54.5 Received-SPF: pass client-ip=170.10.133.124; envelope-from=berrange@redhat.com; helo=us-smtp-delivery-124.mimecast.com X-Spam_score_int: -22 X-Spam_score: -2.3 X-Spam_bar: -- X-Spam_report: (-2.3 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.163, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001, T_SCC_BODY_TEXT_LINE=-0.01 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Change the migration test to use the new qtest event callback to watch for the stop event. This ensures that we only watch for the STOP event on the source QEMU. The previous code would set the single 'got_stop' flag when either source or dest QEMU got the STOP event. Signed-off-by: Daniel P. Berrangé Acked-by: Thomas Huth Reviewed-by: Juan Quintela --- tests/qtest/migration-helpers.c | 18 ++++++++---------- tests/qtest/migration-helpers.h | 3 ++- tests/qtest/migration-test.c | 4 ++++ 3 files changed, 14 insertions(+), 11 deletions(-) diff --git a/tests/qtest/migration-helpers.c b/tests/qtest/migration-helpers.c index e26fdcb132..936a27a944 100644 --- a/tests/qtest/migration-helpers.c +++ b/tests/qtest/migration-helpers.c @@ -23,15 +23,16 @@ */ #define MIGRATION_STATUS_WAIT_TIMEOUT 120 -bool got_stop; - -static void check_stop_event(QTestState *who) +bool migrate_watch_for_stop(QTestState *who, const char *name, + QDict *event, void *opaque) { - QDict *event = qtest_qmp_event_ref(who, "STOP"); - if (event) { - got_stop = true; - qobject_unref(event); + bool *seen = opaque; + + if (g_str_equal(name, "STOP")) { + *seen = true; } + + return false; } #ifndef _WIN32 @@ -48,7 +49,6 @@ QDict *wait_command_fd(QTestState *who, int fd, const char *command, ...) va_end(ap); resp = qtest_qmp_receive(who); - check_stop_event(who); g_assert(!qdict_haskey(resp, "error")); g_assert(qdict_haskey(resp, "return")); @@ -73,8 +73,6 @@ QDict *wait_command(QTestState *who, const char *command, ...) resp = qtest_vqmp(who, command, ap); va_end(ap); - check_stop_event(who); - g_assert(!qdict_haskey(resp, "error")); g_assert(qdict_haskey(resp, "return")); diff --git a/tests/qtest/migration-helpers.h b/tests/qtest/migration-helpers.h index 2e51a6e195..fa69d1780a 100644 --- a/tests/qtest/migration-helpers.h +++ b/tests/qtest/migration-helpers.h @@ -15,7 +15,8 @@ #include "libqtest.h" -extern bool got_stop; +bool migrate_watch_for_stop(QTestState *who, const char *name, + QDict *event, void *opaque); #ifndef _WIN32 G_GNUC_PRINTF(3, 4) diff --git a/tests/qtest/migration-test.c b/tests/qtest/migration-test.c index 822516286d..0af72c37c2 100644 --- a/tests/qtest/migration-test.c +++ b/tests/qtest/migration-test.c @@ -43,6 +43,7 @@ unsigned start_address; unsigned end_address; static bool uffd_feature_thread_id; +static bool got_stop; /* * Dirtylimit stop working if dirty page rate error @@ -703,6 +704,9 @@ static int test_migrate_start(QTestState **from, QTestState **to, ignore_stderr); if (!args->only_target) { *from = qtest_init(cmd_source); + qtest_qmp_set_event_callback(*from, + migrate_watch_for_stop, + &got_stop); } cmd_target = g_strdup_printf("-accel kvm%s -accel tcg%s%s " From patchwork Wed May 31 13:23:57 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Daniel_P=2E_Berrang=C3=A9?= X-Patchwork-Id: 1788366 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=nongnu.org (client-ip=209.51.188.17; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: legolas.ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=redhat.com header.i=@redhat.com header.a=rsa-sha256 header.s=mimecast20190719 header.b=Kv/+VRik; dkim-atps=neutral Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-ECDSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4QWVPR40mPz20QB for ; Wed, 31 May 2023 23:25:15 +1000 (AEST) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1q4LoQ-0006Lg-W7; Wed, 31 May 2023 09:24:27 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1q4LoK-0005zB-Pv for qemu-devel@nongnu.org; Wed, 31 May 2023 09:24:20 -0400 Received: from us-smtp-delivery-124.mimecast.com ([170.10.133.124]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1q4LoH-0004NM-1d for qemu-devel@nongnu.org; Wed, 31 May 2023 09:24:20 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1685539456; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=Ax9zatSniEce5EheZNR52ukeRPOm+//cDon8LhsxKLE=; b=Kv/+VRikGa0dLbXYXPiFeBqcm8q+8LsSLvStNz4YHhAPh44mRhZe69viYZ6wZjBkusZNzl ECCfrVeBOzlCKKptPrrAmNnP57Oqvzd1UZ95o0STbaZA05/PNi8G/Q4/74E7BI3KGgMKTB Q6n8lrQ272Ua2JtCq9bMoZKrciOuaP0= Received: from mimecast-mx02.redhat.com (mx3-rdu2.redhat.com [66.187.233.73]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id us-mta-152-H4RYsWEBNumMGTQFXo5PDw-1; Wed, 31 May 2023 09:24:14 -0400 X-MC-Unique: H4RYsWEBNumMGTQFXo5PDw-1 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 mimecast-mx02.redhat.com (Postfix) with ESMTPS id 8E25828EA6E1 for ; Wed, 31 May 2023 13:24:14 +0000 (UTC) Received: from localhost.localdomain.com (unknown [10.42.28.177]) by smtp.corp.redhat.com (Postfix) with ESMTP id 4FF98420AA; Wed, 31 May 2023 13:24:13 +0000 (UTC) From: =?utf-8?q?Daniel_P=2E_Berrang=C3=A9?= To: qemu-devel@nongnu.org Cc: Laurent Vivier , Peter Xu , Juan Quintela , Leonardo Bras , Thomas Huth , Paolo Bonzini , =?utf-8?q?Daniel_P=2E_Berrang=C3=A9?= Subject: [PATCH v3 6/9] tests/qtest: replace wait_command() with qtest_qmp_assert_success Date: Wed, 31 May 2023 14:23:57 +0100 Message-Id: <20230531132400.1129576-7-berrange@redhat.com> In-Reply-To: <20230531132400.1129576-1-berrange@redhat.com> References: <20230531132400.1129576-1-berrange@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.1 on 10.11.54.5 Received-SPF: pass client-ip=170.10.133.124; envelope-from=berrange@redhat.com; helo=us-smtp-delivery-124.mimecast.com X-Spam_score_int: -22 X-Spam_score: -2.3 X-Spam_bar: -- X-Spam_report: (-2.3 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.163, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001, T_SCC_BODY_TEXT_LINE=-0.01 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Most usage of wait_command() is followed by qobject_unref(), which is just a verbose re-implementation of qtest_qmp_assert_success(). Signed-off-by: Daniel P. Berrangé Reviewed-by: Thomas Huth Reviewed-by: Juan Quintela --- tests/qtest/migration-helpers.c | 53 +--------- tests/qtest/migration-helpers.h | 8 -- tests/qtest/migration-test.c | 170 +++++++++++++------------------- 3 files changed, 74 insertions(+), 157 deletions(-) diff --git a/tests/qtest/migration-helpers.c b/tests/qtest/migration-helpers.c index 936a27a944..884d8a2e07 100644 --- a/tests/qtest/migration-helpers.c +++ b/tests/qtest/migration-helpers.c @@ -35,54 +35,6 @@ bool migrate_watch_for_stop(QTestState *who, const char *name, return false; } -#ifndef _WIN32 -/* - * Events can get in the way of responses we are actually waiting for. - */ -QDict *wait_command_fd(QTestState *who, int fd, const char *command, ...) -{ - va_list ap; - QDict *resp, *ret; - - va_start(ap, command); - qtest_qmp_vsend_fds(who, &fd, 1, command, ap); - va_end(ap); - - resp = qtest_qmp_receive(who); - - g_assert(!qdict_haskey(resp, "error")); - g_assert(qdict_haskey(resp, "return")); - - ret = qdict_get_qdict(resp, "return"); - qobject_ref(ret); - qobject_unref(resp); - - return ret; -} -#endif - -/* - * Events can get in the way of responses we are actually waiting for. - */ -QDict *wait_command(QTestState *who, const char *command, ...) -{ - va_list ap; - QDict *resp, *ret; - - va_start(ap, command); - resp = qtest_vqmp(who, command, ap); - va_end(ap); - - g_assert(!qdict_haskey(resp, "error")); - g_assert(qdict_haskey(resp, "return")); - - ret = qdict_get_qdict(resp, "return"); - qobject_ref(ret); - qobject_unref(resp); - - return ret; -} - /* * Send QMP command "migrate". * Arguments are built from @fmt... (formatted like @@ -110,7 +62,7 @@ void migrate_qmp(QTestState *who, const char *uri, const char *fmt, ...) */ QDict *migrate_query(QTestState *who) { - return wait_command(who, "{ 'execute': 'query-migrate' }"); + return qtest_qmp_assert_success_ref(who, "{ 'execute': 'query-migrate' }"); } QDict *migrate_query_not_failed(QTestState *who) @@ -208,7 +160,8 @@ void wait_for_migration_fail(QTestState *from, bool allow_active) } while (!failed); /* Is the machine currently running? */ - rsp_return = wait_command(from, "{ 'execute': 'query-status' }"); + rsp_return = qtest_qmp_assert_success_ref(from, + "{ 'execute': 'query-status' }"); g_assert(qdict_haskey(rsp_return, "running")); g_assert(qdict_get_bool(rsp_return, "running")); qobject_unref(rsp_return); diff --git a/tests/qtest/migration-helpers.h b/tests/qtest/migration-helpers.h index fa69d1780a..aab0745cfe 100644 --- a/tests/qtest/migration-helpers.h +++ b/tests/qtest/migration-helpers.h @@ -18,14 +18,6 @@ bool migrate_watch_for_stop(QTestState *who, const char *name, QDict *event, void *opaque); -#ifndef _WIN32 -G_GNUC_PRINTF(3, 4) -QDict *wait_command_fd(QTestState *who, int fd, const char *command, ...); -#endif - -G_GNUC_PRINTF(2, 3) -QDict *wait_command(QTestState *who, const char *command, ...); - G_GNUC_PRINTF(3, 4) void migrate_qmp(QTestState *who, const char *uri, const char *fmt, ...); diff --git a/tests/qtest/migration-test.c b/tests/qtest/migration-test.c index 0af72c37c2..d8b4282abc 100644 --- a/tests/qtest/migration-test.c +++ b/tests/qtest/migration-test.c @@ -342,7 +342,8 @@ static long long migrate_get_parameter_int(QTestState *who, QDict *rsp; long long result; - rsp = wait_command(who, "{ 'execute': 'query-migrate-parameters' }"); + rsp = qtest_qmp_assert_success_ref( + who, "{ 'execute': 'query-migrate-parameters' }"); result = qdict_get_int(rsp, parameter); qobject_unref(rsp); return result; @@ -373,7 +374,8 @@ static char *migrate_get_parameter_str(QTestState *who, QDict *rsp; char *result; - rsp = wait_command(who, "{ 'execute': 'query-migrate-parameters' }"); + rsp = qtest_qmp_assert_success_ref( + who, "{ 'execute': 'query-migrate-parameters' }"); result = g_strdup(qdict_get_str(rsp, parameter)); qobject_unref(rsp); return result; @@ -402,7 +404,8 @@ static long long migrate_get_parameter_bool(QTestState *who, QDict *rsp; int result; - rsp = wait_command(who, "{ 'execute': 'query-migrate-parameters' }"); + rsp = qtest_qmp_assert_success_ref( + who, "{ 'execute': 'query-migrate-parameters' }"); result = qdict_get_bool(rsp, parameter); qobject_unref(rsp); return !!result; @@ -443,41 +446,29 @@ static void migrate_ensure_converge(QTestState *who) static void migrate_pause(QTestState *who) { - QDict *rsp; - - rsp = wait_command(who, "{ 'execute': 'migrate-pause' }"); - qobject_unref(rsp); + qtest_qmp_assert_success(who, "{ 'execute': 'migrate-pause' }"); } static void migrate_continue(QTestState *who, const char *state) { - QDict *rsp; - - rsp = wait_command(who, - "{ 'execute': 'migrate-continue'," - " 'arguments': { 'state': %s } }", - state); - qobject_unref(rsp); + qtest_qmp_assert_success(who, + "{ 'execute': 'migrate-continue'," + " 'arguments': { 'state': %s } }", + state); } static void migrate_recover(QTestState *who, const char *uri) { - QDict *rsp; - - rsp = wait_command(who, - "{ 'execute': 'migrate-recover', " - " 'id': 'recover-cmd', " - " 'arguments': { 'uri': %s } }", - uri); - qobject_unref(rsp); + qtest_qmp_assert_success(who, + "{ 'execute': 'migrate-recover', " + " 'id': 'recover-cmd', " + " 'arguments': { 'uri': %s } }", + uri); } static void migrate_cancel(QTestState *who) { - QDict *rsp; - - rsp = wait_command(who, "{ 'execute': 'migrate_cancel' }"); - qobject_unref(rsp); + qtest_qmp_assert_success(who, "{ 'execute': 'migrate_cancel' }"); } static void migrate_set_capability(QTestState *who, const char *capability, @@ -493,10 +484,7 @@ static void migrate_set_capability(QTestState *who, const char *capability, static void migrate_postcopy_start(QTestState *from, QTestState *to) { - QDict *rsp; - - rsp = wait_command(from, "{ 'execute': 'migrate-start-postcopy' }"); - qobject_unref(rsp); + qtest_qmp_assert_success(from, "{ 'execute': 'migrate-start-postcopy' }"); if (!got_stop) { qtest_qmp_eventwait(from, "STOP"); @@ -785,7 +773,6 @@ test_migrate_tls_psk_start_common(QTestState *from, { struct TestMigrateTLSPSKData *data = g_new0(struct TestMigrateTLSPSKData, 1); - QDict *rsp; data->workdir = g_strdup_printf("%s/tlscredspsk0", tmpfs); data->pskfile = g_strdup_printf("%s/%s", data->workdir, @@ -801,24 +788,22 @@ test_migrate_tls_psk_start_common(QTestState *from, test_tls_psk_init_alt(data->pskfilealt); } - rsp = wait_command(from, - "{ 'execute': 'object-add'," - " 'arguments': { 'qom-type': 'tls-creds-psk'," - " 'id': 'tlscredspsk0'," - " 'endpoint': 'client'," - " 'dir': %s," - " 'username': 'qemu'} }", - data->workdir); - qobject_unref(rsp); + qtest_qmp_assert_success(from, + "{ 'execute': 'object-add'," + " 'arguments': { 'qom-type': 'tls-creds-psk'," + " 'id': 'tlscredspsk0'," + " 'endpoint': 'client'," + " 'dir': %s," + " 'username': 'qemu'} }", + data->workdir); - rsp = wait_command(to, - "{ 'execute': 'object-add'," - " 'arguments': { 'qom-type': 'tls-creds-psk'," - " 'id': 'tlscredspsk0'," - " 'endpoint': 'server'," - " 'dir': %s } }", - mismatch ? data->workdiralt : data->workdir); - qobject_unref(rsp); + qtest_qmp_assert_success(to, + "{ 'execute': 'object-add'," + " 'arguments': { 'qom-type': 'tls-creds-psk'," + " 'id': 'tlscredspsk0'," + " 'endpoint': 'server'," + " 'dir': %s } }", + mismatch ? data->workdiralt : data->workdir); migrate_set_parameter_str(from, "tls-creds", "tlscredspsk0"); migrate_set_parameter_str(to, "tls-creds", "tlscredspsk0"); @@ -889,7 +874,6 @@ test_migrate_tls_x509_start_common(QTestState *from, TestMigrateTLSX509 *args) { TestMigrateTLSX509Data *data = g_new0(TestMigrateTLSX509Data, 1); - QDict *rsp; data->workdir = g_strdup_printf("%s/tlscredsx5090", tmpfs); data->keyfile = g_strdup_printf("%s/key.pem", data->workdir); @@ -932,40 +916,38 @@ test_migrate_tls_x509_start_common(QTestState *from, args->certhostname, args->certipaddr); - rsp = wait_command(from, - "{ 'execute': 'object-add'," - " 'arguments': { 'qom-type': 'tls-creds-x509'," - " 'id': 'tlscredsx509client0'," - " 'endpoint': 'client'," - " 'dir': %s," - " 'sanity-check': true," - " 'verify-peer': true} }", - data->workdir); - qobject_unref(rsp); + qtest_qmp_assert_success(from, + "{ 'execute': 'object-add'," + " 'arguments': { 'qom-type': 'tls-creds-x509'," + " 'id': 'tlscredsx509client0'," + " 'endpoint': 'client'," + " 'dir': %s," + " 'sanity-check': true," + " 'verify-peer': true} }", + data->workdir); migrate_set_parameter_str(from, "tls-creds", "tlscredsx509client0"); if (args->certhostname) { migrate_set_parameter_str(from, "tls-hostname", args->certhostname); } - rsp = wait_command(to, - "{ 'execute': 'object-add'," - " 'arguments': { 'qom-type': 'tls-creds-x509'," - " 'id': 'tlscredsx509server0'," - " 'endpoint': 'server'," - " 'dir': %s," - " 'sanity-check': true," - " 'verify-peer': %i} }", - data->workdir, args->verifyclient); - qobject_unref(rsp); + qtest_qmp_assert_success(to, + "{ 'execute': 'object-add'," + " 'arguments': { 'qom-type': 'tls-creds-x509'," + " 'id': 'tlscredsx509server0'," + " 'endpoint': 'server'," + " 'dir': %s," + " 'sanity-check': true," + " 'verify-peer': %i} }", + data->workdir, args->verifyclient); migrate_set_parameter_str(to, "tls-creds", "tlscredsx509server0"); if (args->authzclient) { - rsp = wait_command(to, - "{ 'execute': 'object-add'," - " 'arguments': { 'qom-type': 'authz-simple'," - " 'id': 'tlsauthz0'," - " 'identity': %s} }", - "CN=" QCRYPTO_TLS_TEST_CLIENT_NAME); + qtest_qmp_assert_success(to, + "{ 'execute': 'object-add'," + " 'arguments': { 'qom-type': 'authz-simple'," + " 'id': 'tlsauthz0'," + " 'identity': %s} }", + "CN=" QCRYPTO_TLS_TEST_CLIENT_NAME); migrate_set_parameter_str(to, "tls-authz", "tlsauthz0"); } @@ -1759,7 +1741,6 @@ static void test_precopy_tcp_tls_x509_reject_anon_client(void) static void *test_migrate_fd_start_hook(QTestState *from, QTestState *to) { - QDict *rsp; int ret; int pair[2]; @@ -1768,22 +1749,19 @@ static void *test_migrate_fd_start_hook(QTestState *from, g_assert_cmpint(ret, ==, 0); /* Send the 1st socket to the target */ - rsp = wait_command_fd(to, pair[0], - "{ 'execute': 'getfd'," - " 'arguments': { 'fdname': 'fd-mig' }}"); - qobject_unref(rsp); + qtest_qmp_fds_assert_success(to, &(pair[0]), 1, + "{ 'execute': 'getfd'," + " 'arguments': { 'fdname': 'fd-mig' }}"); close(pair[0]); /* Start incoming migration from the 1st socket */ - rsp = wait_command(to, "{ 'execute': 'migrate-incoming'," - " 'arguments': { 'uri': 'fd:fd-mig' }}"); - qobject_unref(rsp); + qtest_qmp_assert_success(to, "{ 'execute': 'migrate-incoming'," + " 'arguments': { 'uri': 'fd:fd-mig' }}"); /* Send the 2nd socket to the target */ - rsp = wait_command_fd(from, pair[1], - "{ 'execute': 'getfd'," - " 'arguments': { 'fdname': 'fd-mig' }}"); - qobject_unref(rsp); + qtest_qmp_fds_assert_success(from, &(pair[1]), 1, + "{ 'execute': 'getfd'," + " 'arguments': { 'fdname': 'fd-mig' }}"); close(pair[1]); return NULL; @@ -1990,8 +1968,6 @@ test_migrate_precopy_tcp_multifd_start_common(QTestState *from, QTestState *to, const char *method) { - QDict *rsp; - migrate_set_parameter_int(from, "multifd-channels", 16); migrate_set_parameter_int(to, "multifd-channels", 16); @@ -2002,9 +1978,8 @@ test_migrate_precopy_tcp_multifd_start_common(QTestState *from, migrate_set_capability(to, "multifd", true); /* Start incoming migration from the 1st socket */ - rsp = wait_command(to, "{ 'execute': 'migrate-incoming'," - " 'arguments': { 'uri': 'tcp:127.0.0.1:0' }}"); - qobject_unref(rsp); + qtest_qmp_assert_success(to, "{ 'execute': 'migrate-incoming'," + " 'arguments': { 'uri': 'tcp:127.0.0.1:0' }}"); return NULL; } @@ -2235,7 +2210,6 @@ static void test_multifd_tcp_cancel(void) .hide_stderr = true, }; QTestState *from, *to, *to2; - QDict *rsp; g_autofree char *uri = NULL; if (test_migrate_start(&from, &to, "defer", &args)) { @@ -2251,9 +2225,8 @@ static void test_multifd_tcp_cancel(void) migrate_set_capability(to, "multifd", true); /* Start incoming migration from the 1st socket */ - rsp = wait_command(to, "{ 'execute': 'migrate-incoming'," - " 'arguments': { 'uri': 'tcp:127.0.0.1:0' }}"); - qobject_unref(rsp); + qtest_qmp_assert_success(to, "{ 'execute': 'migrate-incoming'," + " 'arguments': { 'uri': 'tcp:127.0.0.1:0' }}"); /* Wait for the first serial output from the source */ wait_for_serial("src_serial"); @@ -2283,9 +2256,8 @@ static void test_multifd_tcp_cancel(void) migrate_set_capability(to2, "multifd", true); /* Start incoming migration from the 1st socket */ - rsp = wait_command(to2, "{ 'execute': 'migrate-incoming'," - " 'arguments': { 'uri': 'tcp:127.0.0.1:0' }}"); - qobject_unref(rsp); + qtest_qmp_assert_success(to2, "{ 'execute': 'migrate-incoming'," + " 'arguments': { 'uri': 'tcp:127.0.0.1:0' }}"); g_free(uri); uri = migrate_get_socket_address(to2, "socket-address"); From patchwork Wed May 31 13:23:58 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Daniel_P=2E_Berrang=C3=A9?= X-Patchwork-Id: 1788362 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=nongnu.org (client-ip=209.51.188.17; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: legolas.ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=redhat.com header.i=@redhat.com header.a=rsa-sha256 header.s=mimecast20190719 header.b=GYJ17wVP; dkim-atps=neutral Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-ECDSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4QWVP153dJz20Py for ; Wed, 31 May 2023 23:24:53 +1000 (AEST) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1q4LoS-0006aO-MZ; Wed, 31 May 2023 09:24:28 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1q4LoL-000603-6p for qemu-devel@nongnu.org; Wed, 31 May 2023 09:24:21 -0400 Received: from us-smtp-delivery-124.mimecast.com ([170.10.129.124]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1q4LoI-0004P0-J2 for qemu-devel@nongnu.org; Wed, 31 May 2023 09:24:20 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1685539458; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=sOrUaPNpSVD5xXyb8UpqTIukdYG0PeDR6aW1HjT2184=; b=GYJ17wVPLjy+GXrLC/dR7mhqYO5hjqEGyk0jCgjQWMbqwuUj1kM88abD4qNqpntugbhFkR /k0aNHgSXLxXt1uX+riOUCbagxjDAmEhbznOjWyTVnfg7lw9N3AE8NfUaFDJXrpxJ9AGpq svXOU2ZwqZlPYlPmLgZh9UV7TTDzIoA= Received: from mimecast-mx02.redhat.com (mimecast-mx02.redhat.com [66.187.233.88]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id us-mta-471-Ll91XvHnNr2ZU-20ivyYRA-1; Wed, 31 May 2023 09:24:16 -0400 X-MC-Unique: Ll91XvHnNr2ZU-20ivyYRA-1 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 mimecast-mx02.redhat.com (Postfix) with ESMTPS id 2BB968039A9 for ; Wed, 31 May 2023 13:24:16 +0000 (UTC) Received: from localhost.localdomain.com (unknown [10.42.28.177]) by smtp.corp.redhat.com (Postfix) with ESMTP id CA798420AA; Wed, 31 May 2023 13:24:14 +0000 (UTC) From: =?utf-8?q?Daniel_P=2E_Berrang=C3=A9?= To: qemu-devel@nongnu.org Cc: Laurent Vivier , Peter Xu , Juan Quintela , Leonardo Bras , Thomas Huth , Paolo Bonzini , =?utf-8?q?Daniel_P=2E_Berrang=C3=A9?= Subject: [PATCH v3 7/9] tests/qtest: capture RESUME events during migration Date: Wed, 31 May 2023 14:23:58 +0100 Message-Id: <20230531132400.1129576-8-berrange@redhat.com> In-Reply-To: <20230531132400.1129576-1-berrange@redhat.com> References: <20230531132400.1129576-1-berrange@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.1 on 10.11.54.5 Received-SPF: pass client-ip=170.10.129.124; envelope-from=berrange@redhat.com; helo=us-smtp-delivery-124.mimecast.com X-Spam_score_int: -22 X-Spam_score: -2.3 X-Spam_bar: -- X-Spam_report: (-2.3 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.163, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001, T_SCC_BODY_TEXT_LINE=-0.01 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org When running migration tests we monitor for a STOP event so we can skip redundant waits. This will be needed for the RESUME event too shortly. Signed-off-by: Daniel P. Berrangé Acked-by: Thomas Huth --- tests/qtest/migration-helpers.c | 12 ++++++++++++ tests/qtest/migration-helpers.h | 2 ++ tests/qtest/migration-test.c | 5 +++++ 3 files changed, 19 insertions(+) diff --git a/tests/qtest/migration-helpers.c b/tests/qtest/migration-helpers.c index 884d8a2e07..d50b565967 100644 --- a/tests/qtest/migration-helpers.c +++ b/tests/qtest/migration-helpers.c @@ -35,6 +35,18 @@ bool migrate_watch_for_stop(QTestState *who, const char *name, return false; } +bool migrate_watch_for_resume(QTestState *who, const char *name, + QDict *event, void *opaque) +{ + bool *seen = opaque; + + if (g_str_equal(name, "RESUME")) { + *seen = true; + } + + return false; +} + /* * Send QMP command "migrate". * Arguments are built from @fmt... (formatted like diff --git a/tests/qtest/migration-helpers.h b/tests/qtest/migration-helpers.h index aab0745cfe..009e250e90 100644 --- a/tests/qtest/migration-helpers.h +++ b/tests/qtest/migration-helpers.h @@ -17,6 +17,8 @@ bool migrate_watch_for_stop(QTestState *who, const char *name, QDict *event, void *opaque); +bool migrate_watch_for_resume(QTestState *who, const char *name, + QDict *event, void *opaque); G_GNUC_PRINTF(3, 4) void migrate_qmp(QTestState *who, const char *uri, const char *fmt, ...); diff --git a/tests/qtest/migration-test.c b/tests/qtest/migration-test.c index d8b4282abc..aee25e1c4f 100644 --- a/tests/qtest/migration-test.c +++ b/tests/qtest/migration-test.c @@ -44,6 +44,7 @@ unsigned start_address; unsigned end_address; static bool uffd_feature_thread_id; static bool got_stop; +static bool got_resume; /* * Dirtylimit stop working if dirty page rate error @@ -607,6 +608,7 @@ static int test_migrate_start(QTestState **from, QTestState **to, } got_stop = false; + got_resume = false; bootpath = g_strdup_printf("%s/bootsect", tmpfs); if (strcmp(arch, "i386") == 0 || strcmp(arch, "x86_64") == 0) { /* the assembled x86 boot sector should be exactly one sector large */ @@ -712,6 +714,9 @@ static int test_migrate_start(QTestState **from, QTestState **to, args->opts_target ? args->opts_target : "", ignore_stderr); *to = qtest_init(cmd_target); + qtest_qmp_set_event_callback(*to, + migrate_watch_for_resume, + &got_resume); /* * Remove shmem file immediately to avoid memory leak in test failed case. From patchwork Wed May 31 13:23:59 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Daniel_P=2E_Berrang=C3=A9?= X-Patchwork-Id: 1788361 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=nongnu.org (client-ip=209.51.188.17; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: legolas.ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=redhat.com header.i=@redhat.com header.a=rsa-sha256 header.s=mimecast20190719 header.b=cWo3k6YK; dkim-atps=neutral Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-ECDSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4QWVNx5fxnz20Py for ; Wed, 31 May 2023 23:24:49 +1000 (AEST) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1q4LoS-0006bj-Tt; Wed, 31 May 2023 09:24:29 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1q4LoN-00063y-Gp for qemu-devel@nongnu.org; Wed, 31 May 2023 09:24:24 -0400 Received: from us-smtp-delivery-124.mimecast.com ([170.10.129.124]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1q4LoK-0004PF-NV for qemu-devel@nongnu.org; Wed, 31 May 2023 09:24:22 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1685539460; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=uyQ52qc2eK0gkF/Q5szsBf2rvbOHttLLtQ+7QPHTW7A=; b=cWo3k6YKjJfCi/zii0lyq488KApn7XpFcn1lpYQC2Kb0G83BGujlS7tIiNFCkM2A4vMDcl /Emm9LT9wi1m0qQ8IuiwLRfH1h8jkJ8D9m1TQIarDHeLiWkYucc0gi9vMT65BNZSiM2Gyp 9ZxU4/5FKKluenTkzRiJ5Mf/zava/50= Received: from mimecast-mx02.redhat.com (mimecast-mx02.redhat.com [66.187.233.88]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id us-mta-295-0QiEVM9DNkiRvkFYwoXVZA-1; Wed, 31 May 2023 09:24:18 -0400 X-MC-Unique: 0QiEVM9DNkiRvkFYwoXVZA-1 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 mimecast-mx02.redhat.com (Postfix) with ESMTPS id 2B418101A531 for ; Wed, 31 May 2023 13:24:18 +0000 (UTC) Received: from localhost.localdomain.com (unknown [10.42.28.177]) by smtp.corp.redhat.com (Postfix) with ESMTP id 60EB6170ED; Wed, 31 May 2023 13:24:16 +0000 (UTC) From: =?utf-8?q?Daniel_P=2E_Berrang=C3=A9?= To: qemu-devel@nongnu.org Cc: Laurent Vivier , Peter Xu , Juan Quintela , Leonardo Bras , Thomas Huth , Paolo Bonzini , =?utf-8?q?Daniel_P=2E_Berrang=C3=A9?= Subject: [PATCH v3 8/9] tests/qtest: make more migration pre-copy scenarios run non-live Date: Wed, 31 May 2023 14:23:59 +0100 Message-Id: <20230531132400.1129576-9-berrange@redhat.com> In-Reply-To: <20230531132400.1129576-1-berrange@redhat.com> References: <20230531132400.1129576-1-berrange@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.1 on 10.11.54.5 Received-SPF: pass client-ip=170.10.129.124; envelope-from=berrange@redhat.com; helo=us-smtp-delivery-124.mimecast.com X-Spam_score_int: -22 X-Spam_score: -2.3 X-Spam_bar: -- X-Spam_report: (-2.3 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.163, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001, T_SCC_BODY_TEXT_LINE=-0.01 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org There are 27 pre-copy live migration scenarios being tested. In all of these we force non-convergance and run for one iteration, then let it converge and wait for completion during the second (or following) iterations. At 3 mbps bandwidth limit the first iteration takes a very long time (~30 seconds). While it is important to test the migration passes and convergance logic, it is overkill to do this for all 27 pre-copy scenarios. The TLS migration scenarios in particular are merely exercising different code paths during connection establishment. To optimize time taken, switch most of the test scenarios to run non-live (ie guest CPUs paused) with no bandwidth limits. This gives a massive speed up for most of the test scenarios. For test coverage the following scenarios are unchanged * Precopy with UNIX sockets * Precopy with UNIX sockets and dirty ring tracking * Precopy with XBZRLE * Precopy with UNIX compress * Precopy with UNIX compress (nowait) * Precopy with multifd On a test machine this reduces execution time from 13 minutes to 8 minutes. Signed-off-by: Daniel P. Berrangé Tested-by: Thomas Huth Reviewed-by: Peter Xu --- tests/qtest/migration-test.c | 81 +++++++++++++++++++++++++++++------- 1 file changed, 66 insertions(+), 15 deletions(-) diff --git a/tests/qtest/migration-test.c b/tests/qtest/migration-test.c index aee25e1c4f..e033d9f0c1 100644 --- a/tests/qtest/migration-test.c +++ b/tests/qtest/migration-test.c @@ -577,9 +577,12 @@ typedef struct { MIG_TEST_FAIL_DEST_QUIT_ERR, } result; - /* Optional: set number of migration passes to wait for */ + /* Optional: set number of migration passes to wait for, if live==true */ unsigned int iterations; + /* Optional: whether the guest CPUs should be running during migration */ + bool live; + /* Postcopy specific fields */ void *postcopy_data; bool postcopy_preempt; @@ -1385,8 +1388,6 @@ static void test_precopy_common(MigrateCommon *args) return; } - migrate_ensure_non_converge(from); - if (args->start_hook) { data_hook = args->start_hook(from, to); } @@ -1396,6 +1397,31 @@ static void test_precopy_common(MigrateCommon *args) wait_for_serial("src_serial"); } + if (args->live) { + /* + * Testing live migration, we want to ensure that some + * memory is re-dirtied after being transferred, so that + * we exercise logic for dirty page handling. We achieve + * this with a ridiculosly low bandwidth that guarantees + * non-convergance. + */ + migrate_ensure_non_converge(from); + } else { + /* + * Testing non-live migration, we allow it to run at + * full speed to ensure short test case duration. + * For tests expected to fail, we don't need to + * change anything. + */ + if (args->result == MIG_TEST_SUCCEED) { + qtest_qmp_assert_success(from, "{ 'execute' : 'stop'}"); + if (!got_stop) { + qtest_qmp_eventwait(from, "STOP"); + } + migrate_ensure_converge(from); + } + } + if (!args->connect_uri) { g_autofree char *local_connect_uri = migrate_get_socket_address(to, "socket-address"); @@ -1413,25 +1439,41 @@ static void test_precopy_common(MigrateCommon *args) qtest_set_expected_status(to, EXIT_FAILURE); } } else { - if (args->iterations) { - while (args->iterations--) { + if (args->live) { + if (args->iterations) { + while (args->iterations--) { + wait_for_migration_pass(from); + } + } else { wait_for_migration_pass(from); } - } else { - wait_for_migration_pass(from); - } - migrate_ensure_converge(from); + migrate_ensure_converge(from); - /* We do this first, as it has a timeout to stop us - * hanging forever if migration didn't converge */ - wait_for_migration_complete(from); + /* + * We do this first, as it has a timeout to stop us + * hanging forever if migration didn't converge + */ + wait_for_migration_complete(from); - if (!got_stop) { - qtest_qmp_eventwait(from, "STOP"); + if (!got_stop) { + qtest_qmp_eventwait(from, "STOP"); + } + } else { + wait_for_migration_complete(from); + /* + * Must wait for dst to finish reading all incoming + * data on the socket before issuing 'cont' otherwise + * it'll be ignored + */ + wait_for_migration_complete(to); + + qtest_qmp_assert_success(to, "{ 'execute' : 'cont'}"); } - qtest_qmp_eventwait(to, "RESUME"); + if (!got_resume) { + qtest_qmp_eventwait(to, "RESUME"); + } wait_for_serial("dest_serial"); } @@ -1449,6 +1491,8 @@ static void test_precopy_unix_plain(void) MigrateCommon args = { .listen_uri = uri, .connect_uri = uri, + + .live = true, }; test_precopy_common(&args); @@ -1464,6 +1508,8 @@ static void test_precopy_unix_dirty_ring(void) }, .listen_uri = uri, .connect_uri = uri, + + .live = true, }; test_precopy_common(&args); @@ -1575,6 +1621,7 @@ static void test_precopy_unix_xbzrle(void) .start_hook = test_migrate_xbzrle_start, .iterations = 2, + .live = true, }; test_precopy_common(&args); @@ -1592,6 +1639,7 @@ static void test_precopy_unix_compress(void) * the previous iteration. */ .iterations = 2, + .live = true, }; test_precopy_common(&args); @@ -1609,6 +1657,7 @@ static void test_precopy_unix_compress_nowait(void) * the previous iteration. */ .iterations = 2, + .live = true, }; test_precopy_common(&args); @@ -2017,6 +2066,8 @@ static void test_multifd_tcp_none(void) MigrateCommon args = { .listen_uri = "defer", .start_hook = test_migrate_precopy_tcp_multifd_start, + + .live = true, }; test_precopy_common(&args); } From patchwork Wed May 31 13:24:00 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Daniel_P=2E_Berrang=C3=A9?= X-Patchwork-Id: 1788367 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=nongnu.org (client-ip=209.51.188.17; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: legolas.ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=redhat.com header.i=@redhat.com header.a=rsa-sha256 header.s=mimecast20190719 header.b=LiyozRXH; dkim-atps=neutral Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-ECDSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4QWVPg6cltz20QB for ; Wed, 31 May 2023 23:25:27 +1000 (AEST) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1q4LoV-0006uz-6T; Wed, 31 May 2023 09:24:31 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1q4LoS-0006cH-Vj for qemu-devel@nongnu.org; Wed, 31 May 2023 09:24:29 -0400 Received: from us-smtp-delivery-124.mimecast.com ([170.10.133.124]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1q4LoO-0004Pk-29 for qemu-devel@nongnu.org; Wed, 31 May 2023 09:24:27 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1685539461; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=/qMba7xF8pMZ9z4zjW/BIAH9YPUMgn60/2PSOYS393E=; b=LiyozRXHs+Wc0m+HGUdom6qGBPX9hCv5qVp4YDPHU8sO05K66AAmQVdYrem3Osbr70pGBE 0YivIETXncVUz6qtUIm0dbuBD3ynMt9AGuT+F0cFUOUBmo1llqT1GgUDfWe2kHqA8/v8V9 s/4QcsEMuzXkQnZHmQOW3hYqO9cGY3s= Received: from mimecast-mx02.redhat.com (mimecast-mx02.redhat.com [66.187.233.88]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id us-mta-584-4L1GvtYmNfeck9bpWUuiNQ-1; Wed, 31 May 2023 09:24:20 -0400 X-MC-Unique: 4L1GvtYmNfeck9bpWUuiNQ-1 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 mimecast-mx02.redhat.com (Postfix) with ESMTPS id 4545F185A78B for ; Wed, 31 May 2023 13:24:20 +0000 (UTC) Received: from localhost.localdomain.com (unknown [10.42.28.177]) by smtp.corp.redhat.com (Postfix) with ESMTP id 9F03F170ED; Wed, 31 May 2023 13:24:18 +0000 (UTC) From: =?utf-8?q?Daniel_P=2E_Berrang=C3=A9?= To: qemu-devel@nongnu.org Cc: Laurent Vivier , Peter Xu , Juan Quintela , Leonardo Bras , Thomas Huth , Paolo Bonzini , =?utf-8?q?Daniel_P=2E_Berrang=C3=A9?= Subject: [PATCH v3 9/9] tests/qtest: massively speed up migration-test Date: Wed, 31 May 2023 14:24:00 +0100 Message-Id: <20230531132400.1129576-10-berrange@redhat.com> In-Reply-To: <20230531132400.1129576-1-berrange@redhat.com> References: <20230531132400.1129576-1-berrange@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.1 on 10.11.54.5 Received-SPF: pass client-ip=170.10.133.124; envelope-from=berrange@redhat.com; helo=us-smtp-delivery-124.mimecast.com X-Spam_score_int: -22 X-Spam_score: -2.3 X-Spam_bar: -- X-Spam_report: (-2.3 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.163, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001, T_SCC_BODY_TEXT_LINE=-0.01 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org The migration test cases that actually exercise live migration want to ensure there is a minimum of two iterations of pre-copy, in order to exercise the dirty tracking code. Historically we've queried the migration status, looking for the 'dirty-sync-count' value to increment to track iterations. This was not entirely reliable because often all the data would get transferred quickly enough that the migration would finish before we wanted it to. So we massively dropped the bandwidth and max downtime to guarantee non-convergance. This had the unfortunate side effect that every migration took at least 30 seconds to run (100 MB of dirty pages / 3 MB/sec). This optimization takes a different approach to ensuring that a mimimum of two iterations. Rather than waiting for dirty-sync-count to increment, directly look for an indication that the source VM has dirtied RAM that has already been transferred. On the source VM a magic marker is written just after the 3 MB offset. The destination VM is now montiored to detect when the magic marker is transferred. This gives a guarantee that the first 3 MB of memory have been transferred. Now the source VM memory is monitored at exactly the 3MB offset until we observe a flip in its value. This gives us a guaranteed that the guest workload has dirtied a byte that has already been transferred. Since we're looking at a place that is only 3 MB from the start of memory, with the 3 MB/sec bandwidth, this test should complete in 1 second, instead of 30 seconds. Once we've proved there is some dirty memory, migration can be set back to full speed for the remainder of the 1st iteration, and the entire of the second iteration at which point migration should be complete. On a test machine this further reduces the migration test time from 8 minutes to 1 minute 40. Signed-off-by: Daniel P. Berrangé Tested-by: Thomas Huth --- tests/qtest/migration-test.c | 143 ++++++++++++++++++++++++++++++----- 1 file changed, 125 insertions(+), 18 deletions(-) diff --git a/tests/qtest/migration-test.c b/tests/qtest/migration-test.c index e033d9f0c1..6ea9011423 100644 --- a/tests/qtest/migration-test.c +++ b/tests/qtest/migration-test.c @@ -46,6 +46,20 @@ static bool uffd_feature_thread_id; static bool got_stop; static bool got_resume; +/* + * An initial 3 MB offset is used as that corresponds + * to ~1 sec of data transfer with our bandwidth setting. + */ +#define MAGIC_OFFSET_BASE (3 * 1024 * 1024) +/* + * A further 1k is added to ensure we're not a multiple + * of TEST_MEM_PAGE_SIZE, thus avoid clash with writes + * from the migration guest workload. + */ +#define MAGIC_OFFSET_SHUFFLE 1024 +#define MAGIC_OFFSET (MAGIC_OFFSET_BASE + MAGIC_OFFSET_SHUFFLE) +#define MAGIC_MARKER 0xFEED12345678CAFEULL + /* * Dirtylimit stop working if dirty page rate error * value less than DIRTYLIMIT_TOLERANCE_RANGE @@ -445,6 +459,91 @@ static void migrate_ensure_converge(QTestState *who) migrate_set_parameter_int(who, "downtime-limit", 30 * 1000); } +/* + * Our goal is to ensure that we run a single full migration + * iteration, and also dirty memory, ensuring that at least + * one further iteration is required. + * + * We can't directly synchronize with the start of a migration + * so we have to apply some tricks monitoring memory that is + * transferred. + * + * Initially we set the migration bandwidth to an insanely + * low value, with tiny max downtime too. This basically + * guarantees migration will never complete. + * + * This will result in a test that is unacceptably slow though, + * so we can't let the entire migration pass run at this speed. + * Our intent is to let it run just long enough that we can + * prove data prior to the marker has been transferred *AND* + * also prove this transferred data is dirty again. + * + * Before migration starts, we write a 64-bit magic marker + * into a fixed location in the src VM RAM. + * + * Then watch dst memory until the marker appears. This is + * proof that start_address -> MAGIC_OFFSET_BASE has been + * transferred. + * + * Finally we go back to the source and read a byte just + * before the marker untill we see it flip in value. This + * is proof that start_address -> MAGIC_OFFSET_BASE + * is now dirty again. + * + * IOW, we're guaranteed at least a 2nd migration pass + * at this point. + * + * We can now let migration run at full speed to finish + * the test + */ +static void migrate_prepare_for_dirty_mem(QTestState *from) +{ + /* + * The guest workflow iterates from start_address to + * end_address, writing 1 byte every TEST_MEM_PAGE_SIZE + * bytes. + * + * IOW, if we write to mem at a point which is NOT + * a multiple of TEST_MEM_PAGE_SIZE, our write won't + * conflict with the migration workflow. + * + * We put in a marker here, that we'll use to determine + * when the data has been transferred to the dst. + */ + qtest_writeq(from, start_address + MAGIC_OFFSET, MAGIC_MARKER); +} + +static void migrate_wait_for_dirty_mem(QTestState *from, + QTestState *to) +{ + uint64_t watch_address = start_address + MAGIC_OFFSET_BASE; + uint64_t marker_address = start_address + MAGIC_OFFSET; + uint8_t watch_byte; + + /* + * Wait for the MAGIC_MARKER to get transferred, as an + * indicator that a migration pass has made some known + * amount of progress. + */ + do { + usleep(1000 * 10); + } while (qtest_readq(to, marker_address) != MAGIC_MARKER); + + /* + * Now ensure that already transferred bytes are + * dirty again from the guest workload. Note the + * guest byte value will wrap around and by chance + * match the original watch_byte. This is harmless + * as we'll eventually see a different value if we + * keep watching + */ + watch_byte = qtest_readb(from, watch_address); + do { + usleep(1000 * 10); + } while (qtest_readb(from, watch_address) == watch_byte); +} + + static void migrate_pause(QTestState *who) { qtest_qmp_assert_success(who, "{ 'execute': 'migrate-pause' }"); @@ -577,7 +676,10 @@ typedef struct { MIG_TEST_FAIL_DEST_QUIT_ERR, } result; - /* Optional: set number of migration passes to wait for, if live==true */ + /* + * Optional: set number of migration passes to wait for, if live==true. + * If zero, then merely wait for a few MB of dirty data + */ unsigned int iterations; /* Optional: whether the guest CPUs should be running during migration */ @@ -1158,12 +1260,14 @@ static int migrate_postcopy_prepare(QTestState **from_ptr, migrate_ensure_non_converge(from); + migrate_prepare_for_dirty_mem(from); + /* Wait for the first serial output from the source */ wait_for_serial("src_serial"); migrate_qmp(from, uri, "{}"); - wait_for_migration_pass(from); + migrate_wait_for_dirty_mem(from, to); *from_ptr = from; *to_ptr = to; @@ -1398,14 +1502,8 @@ static void test_precopy_common(MigrateCommon *args) } if (args->live) { - /* - * Testing live migration, we want to ensure that some - * memory is re-dirtied after being transferred, so that - * we exercise logic for dirty page handling. We achieve - * this with a ridiculosly low bandwidth that guarantees - * non-convergance. - */ migrate_ensure_non_converge(from); + migrate_prepare_for_dirty_mem(from); } else { /* * Testing non-live migration, we allow it to run at @@ -1440,13 +1538,16 @@ static void test_precopy_common(MigrateCommon *args) } } else { if (args->live) { - if (args->iterations) { - while (args->iterations--) { - wait_for_migration_pass(from); - } - } else { + /* + * For initial iteration(s) we must do a full pass, + * but for the final iteration, we need only wait + * for some dirty mem before switching to converge + */ + while (args->iterations > 1) { wait_for_migration_pass(from); + args->iterations--; } + migrate_wait_for_dirty_mem(from, to); migrate_ensure_converge(from); @@ -1573,6 +1674,9 @@ static void test_ignore_shared(void) return; } + migrate_ensure_non_converge(from); + migrate_prepare_for_dirty_mem(from); + migrate_set_capability(from, "x-ignore-shared", true); migrate_set_capability(to, "x-ignore-shared", true); @@ -1581,7 +1685,7 @@ static void test_ignore_shared(void) migrate_qmp(from, uri, "{}"); - wait_for_migration_pass(from); + migrate_wait_for_dirty_mem(from, to); if (!got_stop) { qtest_qmp_eventwait(from, "STOP"); @@ -2273,6 +2377,7 @@ static void test_multifd_tcp_cancel(void) } migrate_ensure_non_converge(from); + migrate_prepare_for_dirty_mem(from); migrate_set_parameter_int(from, "multifd-channels", 16); migrate_set_parameter_int(to, "multifd-channels", 16); @@ -2291,7 +2396,7 @@ static void test_multifd_tcp_cancel(void) migrate_qmp(from, uri, "{}"); - wait_for_migration_pass(from); + migrate_wait_for_dirty_mem(from, to); migrate_cancel(from); @@ -2320,11 +2425,13 @@ static void test_multifd_tcp_cancel(void) wait_for_migration_status(from, "cancelled", NULL); - migrate_ensure_converge(from); + migrate_ensure_non_converge(from); migrate_qmp(from, uri, "{}"); - wait_for_migration_pass(from); + migrate_wait_for_dirty_mem(from, to); + + migrate_ensure_converge(from); if (!got_stop) { qtest_qmp_eventwait(from, "STOP");