From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-7.5 required=3.0 tests=BAYES_00,DKIM_ADSP_CUSTOM_MED, DKIM_INVALID,DKIM_SIGNED,FREEMAIL_FORGED_FROMDOMAIN,FREEMAIL_FROM, HEADER_FROM_DIFFERENT_DOMAINS,HTML_MESSAGE,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS autolearn=no autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id C8889C433DB for ; Fri, 26 Mar 2021 21:12:08 +0000 (UTC) Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 5F111619B8 for ; Fri, 26 Mar 2021 21:12:08 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 5F111619B8 Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=gmail.com Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Received: from localhost ([::1]:48142 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1lPtkV-0001Wq-4C for qemu-devel@archiver.kernel.org; Fri, 26 Mar 2021 17:12:07 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:45538) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1lPtjV-0000ID-OQ for qemu-devel@nongnu.org; Fri, 26 Mar 2021 17:11:05 -0400 Received: from mail-ed1-x52d.google.com ([2a00:1450:4864:20::52d]:33369) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1lPtjT-00042A-54 for qemu-devel@nongnu.org; Fri, 26 Mar 2021 17:11:05 -0400 Received: by mail-ed1-x52d.google.com with SMTP id w18so7904656edc.0 for ; Fri, 26 Mar 2021 14:11:02 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=mime-version:references:in-reply-to:from:date:message-id:subject:to :cc; bh=+DIS4/RMXROZSW7G9YWHmzqGo4If6DaLuzFLqal031U=; b=RoQwj1uMhPXWl1KsM3kXz+093JYKdUwuHdCrjfa4iRflpAHbX4xO9Imm/HMkpknEeT niZTjzZYrcNBlqrZK6ayUvxgeK6zSR3w3jPTB0uNZVVU5PJY3K/i+Tmd8t60iq48ki/s c5bspe5+3Lyfnlhie2cYk3w/A/SP/nwlDsyCqyBt1Stn9b+Rai76KSaAsWJDM3reiZBO /xf1F22exOTRIfkxaYygeBPOPPW9Z9HS08KfnJxF77j6W9cxC6qx5hEsPMj6iu7829Oz gcIvv6+II2XS7RwedJ1t09ve8gUeNXHr/UFmz0r//qTR7jA8Yn0eYjdsK83hTZPFMqep H68w== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:mime-version:references:in-reply-to:from:date :message-id:subject:to:cc; bh=+DIS4/RMXROZSW7G9YWHmzqGo4If6DaLuzFLqal031U=; b=adf6KltvLchTPPWfycStbw1iKpeQrKYAUuDG/jnSnSpY9W7rrX803JKM0EFbRtEunN QLFV9Txv+aCavfuq2aZj46h2kwstKUiAIklfpKlS5PrrIm76/Q0GYrLUODwT0V3uGvJ/ Xg2ksMfSnQ+X0SwWfo6TgY47d5NxqS1xz5SGPBmN5mjaYI4dVrV0N5TFU3NTNCjWmAEG uhPxTggmQ2jXcE5ne4SAVHAilU8/ZgDDd8KTwt/ubJb5q8HWB19FqZR/J5X8ooVeqbP6 gWZl6xbYdAZiSRxfYaiWfPwSkMYiIq0FVCbO9v464Jjd1sH93N/uvkMC+3qMlnZ+JnuP LSoQ== X-Gm-Message-State: AOAM531NacR3/H1bge10q5LG2E/1Q9ivIOMmsZ09BvuPLeGRrJXQ8PD+ b4IbX7/l8aNtmr069NSANqnsLMvCcBMtDq5DlO4= X-Google-Smtp-Source: ABdhPJzBpNtoVNKhfrNBSHaHYfJX/grt5FpAKAYhkBfr7+qCQvgJgKZgzPBW4kSmv3L1BwZe3/2vThycYA/u/RHyOzA= X-Received: by 2002:aa7:dd4d:: with SMTP id o13mr17740407edw.53.1616793061624; Fri, 26 Mar 2021 14:11:01 -0700 (PDT) MIME-Version: 1.0 References: In-Reply-To: From: =?UTF-8?B?TWFyYy1BbmRyw6kgTHVyZWF1?= Date: Sat, 27 Mar 2021 01:10:50 +0400 Message-ID: Subject: Re: [PATCH v4 4/4] tests: Add tests for yank with the chardev-change case To: Lukas Straub Content-Type: multipart/alternative; boundary="0000000000001d0eec05be76f888" Received-SPF: pass client-ip=2a00:1450:4864:20::52d; envelope-from=marcandre.lureau@gmail.com; helo=mail-ed1-x52d.google.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, FREEMAIL_FROM=0.001, HTML_MESSAGE=0.001, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Laurent Vivier , Paolo Bonzini , Thomas Huth , Li Zhang , qemu-devel Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: "Qemu-devel" --0000000000001d0eec05be76f888 Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable Hi Lukas On Fri, Mar 26, 2021 at 11:48 AM Lukas Straub wrote: > Add tests for yank with the chardev-change case. > > Signed-off-by: Lukas Straub > --- > MAINTAINERS | 1 + > tests/unit/meson.build | 3 +- > tests/unit/test-yank.c | 199 +++++++++++++++++++++++++++++++++++++++++ > 3 files changed, 202 insertions(+), 1 deletion(-) > create mode 100644 tests/unit/test-yank.c > > Please run the tests with ASAN. Can you resend with the leaks fixed? thanks diff --git a/MAINTAINERS b/MAINTAINERS > index 77259c031d..accb683a55 100644 > --- a/MAINTAINERS > +++ b/MAINTAINERS > @@ -2821,6 +2821,7 @@ M: Lukas Straub > S: Odd fixes > F: util/yank.c > F: migration/yank_functions* > +F: tests/unit/test-yank.c > F: include/qemu/yank.h > F: qapi/yank.json > > diff --git a/tests/unit/meson.build b/tests/unit/meson.build > index 4bfe4627ba..b3bc2109da 100644 > --- a/tests/unit/meson.build > +++ b/tests/unit/meson.build > @@ -123,7 +123,8 @@ if have_system > 'test-util-sockets': ['socket-helpers.c'], > 'test-base64': [], > 'test-bufferiszero': [], > - 'test-vmstate': [migration, io] > + 'test-vmstate': [migration, io], > + 'test-yank': ['socket-helpers.c', qom, io, chardev] > } > if 'CONFIG_INOTIFY1' in config_host > tests +=3D {'test-util-filemonitor': []} > diff --git a/tests/unit/test-yank.c b/tests/unit/test-yank.c > new file mode 100644 > index 0000000000..8bc8291a82 > --- /dev/null > +++ b/tests/unit/test-yank.c > @@ -0,0 +1,199 @@ > +/* > + * Tests for QEMU yank feature > + * > + * Copyright (c) Lukas Straub > + * > + * This work is licensed under the terms of the GNU GPL, version 2 or > later. > + * See the COPYING file in the top-level directory. > + */ > + > +#include "qemu/osdep.h" > +#include > + > +#include "qemu/config-file.h" > +#include "qemu/module.h" > +#include "qemu/option.h" > +#include "chardev/char-fe.h" > +#include "sysemu/sysemu.h" > +#include "qapi/error.h" > +#include "qapi/qapi-commands-char.h" > +#include "qapi/qapi-types-char.h" > +#include "qapi/qapi-commands-yank.h" > +#include "qapi/qapi-types-yank.h" > +#include "io/channel-socket.h" > +#include "socket-helpers.h" > + > +typedef struct { > + SocketAddress *addr; > + bool old_yank; > + bool new_yank; > + bool fail; > +} CharChangeTestConfig; > + > +static int chardev_change(void *opaque) > +{ > + return 0; > +} > + > +static bool is_yank_instance_registered(void) > +{ > + YankInstanceList *list; > + bool ret; > + > + list =3D qmp_query_yank(&error_abort); > + > + ret =3D !!list; > + > + qapi_free_YankInstanceList(list); > + > + return ret; > +} > + > +static void char_change_test(gconstpointer opaque) > +{ > + CharChangeTestConfig *conf =3D (gpointer) opaque; > + SocketAddress *addr; > + Chardev *chr; > + CharBackend be; > + ChardevReturn *ret; > + QIOChannelSocket *ioc; > + > + /* > + * Setup a listener socket and determine its address > + * so we know the TCP port for the client later > + */ > + ioc =3D qio_channel_socket_new(); > + g_assert_nonnull(ioc); > + qio_channel_socket_listen_sync(ioc, conf->addr, 1, &error_abort); > + addr =3D qio_channel_socket_get_local_address(ioc, &error_abort); > + g_assert_nonnull(addr); > + > + ChardevBackend backend[2] =3D { > + /* doesn't support yank */ > + { .type =3D CHARDEV_BACKEND_KIND_NULL }, > + /* supports yank */ > + { > + .type =3D CHARDEV_BACKEND_KIND_SOCKET, > + .u.socket.data =3D &(ChardevSocket) { > + .addr =3D &(SocketAddressLegacy) { > + .type =3D SOCKET_ADDRESS_LEGACY_KIND_INET, > + .u.inet.data =3D &addr->u.inet > + }, > + .has_server =3D true, > + .server =3D false > + } > + } }; > + > + ChardevBackend fail_backend[2] =3D { > + /* doesn't support yank */ > + { > + .type =3D CHARDEV_BACKEND_KIND_UDP, > + .u.udp.data =3D &(ChardevUdp) { > + .remote =3D &(SocketAddressLegacy) { > + .type =3D SOCKET_ADDRESS_LEGACY_KIND_UNIX, > + .u.q_unix.data =3D &(UnixSocketAddress) { > + .path =3D (char *)"" > + } > + } > + } > + }, > + /* supports yank */ > + { > + .type =3D CHARDEV_BACKEND_KIND_SOCKET, > + .u.socket.data =3D &(ChardevSocket) { > + .addr =3D &(SocketAddressLegacy) { > + .type =3D SOCKET_ADDRESS_LEGACY_KIND_INET, > + .u.inet.data =3D &(InetSocketAddress) { > + .host =3D (char *)"127.0.0.1", > + .port =3D (char *)"0" > + } > + }, > + .has_server =3D true, > + .server =3D false > + } > + } }; > + > + g_assert(!is_yank_instance_registered()); > + > + ret =3D qmp_chardev_add("chardev", &backend[conf->old_yank], > &error_abort); > + qapi_free_ChardevReturn(ret); > + chr =3D qemu_chr_find("chardev"); > + g_assert_nonnull(chr); > + > + g_assert(is_yank_instance_registered() =3D=3D conf->old_yank); > + > + qemu_chr_wait_connected(chr, &error_abort); > + qemu_chr_fe_init(&be, chr, &error_abort); > + /* allow chardev-change */ > + qemu_chr_fe_set_handlers(&be, NULL, NULL, > + NULL, chardev_change, NULL, NULL, true); > + > + if (conf->fail) { > + g_setenv("QTEST_SILENT_ERRORS", "1", 1); > + ret =3D qmp_chardev_change("chardev", &fail_backend[conf->new_ya= nk], > + NULL); > + g_assert_null(ret); > + g_assert(be.chr =3D=3D chr); > + g_assert(is_yank_instance_registered() =3D=3D conf->old_yank); > + g_unsetenv("QTEST_SILENT_ERRORS"); > + } else { > + ret =3D qmp_chardev_change("chardev", &backend[conf->new_yank], > + &error_abort); > + g_assert_nonnull(ret); > + g_assert(be.chr !=3D chr); > + g_assert(is_yank_instance_registered() =3D=3D conf->new_yank); > + } > + > + object_unparent(OBJECT(be.chr)); > + object_unref(OBJECT(ioc)); > + qapi_free_ChardevReturn(ret); > +} > + > +static SocketAddress tcpaddr =3D { > + .type =3D SOCKET_ADDRESS_TYPE_INET, > + .u.inet.host =3D (char *)"127.0.0.1", > + .u.inet.port =3D (char *)"0", > +}; > + > +int main(int argc, char **argv) > +{ > + bool has_ipv4, has_ipv6; > + > + qemu_init_main_loop(&error_abort); > + socket_init(); > + > + g_test_init(&argc, &argv, NULL); > + > + if (socket_check_protocol_support(&has_ipv4, &has_ipv6) < 0) { > + g_printerr("socket_check_protocol_support() failed\n"); > + goto end; > + } > + > + if (!has_ipv4) { > + goto end; > + } > + > + module_call_init(MODULE_INIT_QOM); > + qemu_add_opts(&qemu_chardev_opts); > + > +#define CHAR_CHANGE_TEST(name, _old_yank, _new_yank) > \ > + g_test_add_data_func("/yank/char_change/success/" # name, > \ > + &(CharChangeTestConfig) { .addr =3D &tcpadd= r, > \ > + .old_yank =3D > (_old_yank),\ > + .new_yank =3D > (_new_yank),\ > + .fail =3D false }= , > \ > + char_change_test); > \ > + g_test_add_data_func("/yank/char_change/fail/" # name, > \ > + &(CharChangeTestConfig) { .addr =3D &tcpadd= r, > \ > + .old_yank =3D > (_old_yank),\ > + .new_yank =3D > (_new_yank),\ > + .fail =3D true }, > \ > + char_change_test); > + > + CHAR_CHANGE_TEST(to_yank, false, true); > + CHAR_CHANGE_TEST(yank_to_yank, true, true); > + CHAR_CHANGE_TEST(from_yank, true, false); > + > +end: > + return g_test_run(); > +} > -- > 2.30.2 > --=20 Marc-Andr=C3=A9 Lureau --0000000000001d0eec05be76f888 Content-Type: text/html; charset="UTF-8" Content-Transfer-Encoding: quoted-printable
=C2=A0Hi Lukas

On Fri, Mar 26, 2021 at= 11:48 AM Lukas Straub <lukasstra= ub2@web.de> wrote:
Add tests for yank with the chardev-change case.

Signed-off-by: Lukas Straub <lukasstraub2@web.de>
---
=C2=A0MAINTAINERS=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 |=C2=A0 =C2=A01 = +
=C2=A0tests/unit/meson.build |=C2=A0 =C2=A03 +-
=C2=A0tests/unit/test-yank.c | 199 ++++++++++++++++++++++++++++++++++++++++= +
=C2=A03 files changed, 202 insertions(+), 1 deletion(-)
=C2=A0create mode 100644 tests/unit/test-yank.c


Please run the tests with ASAN. Can yo= u resend with the leaks fixed?
thanks

diff --git a/MAINTAINERS b/MAINTAINERS
index 77259c031d..accb683a55 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -2821,6 +2821,7 @@ M: Lukas Straub <lukasstraub2@web.de>
=C2=A0S: Odd fixes
=C2=A0F: util/yank.c
=C2=A0F: migration/yank_functions*
+F: tests/unit/test-yank.c
=C2=A0F: include/qemu/yank.h
=C2=A0F: qapi/yank.json

diff --git a/tests/unit/meson.build b/tests/unit/meson.build
index 4bfe4627ba..b3bc2109da 100644
--- a/tests/unit/meson.build
+++ b/tests/unit/meson.build
@@ -123,7 +123,8 @@ if have_system
=C2=A0 =C2=A0 =C2=A0'test-util-sockets': ['socket-helpers.c'= ;],
=C2=A0 =C2=A0 =C2=A0'test-base64': [],
=C2=A0 =C2=A0 =C2=A0'test-bufferiszero': [],
-=C2=A0 =C2=A0 'test-vmstate': [migration, io]
+=C2=A0 =C2=A0 'test-vmstate': [migration, io],
+=C2=A0 =C2=A0 'test-yank': ['socket-helpers.c', qom, io, c= hardev]
=C2=A0 =C2=A0}
=C2=A0 =C2=A0if 'CONFIG_INOTIFY1' in config_host
=C2=A0 =C2=A0 =C2=A0tests +=3D {'test-util-filemonitor': []}
diff --git a/tests/unit/test-yank.c b/tests/unit/test-yank.c
new file mode 100644
index 0000000000..8bc8291a82
--- /dev/null
+++ b/tests/unit/test-yank.c
@@ -0,0 +1,199 @@
+/*
+ * Tests for QEMU yank feature
+ *
+ * Copyright (c) Lukas Straub <lukasstraub2@web.de>
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or late= r.
+ * See the COPYING file in the top-level directory.
+ */
+
+#include "qemu/osdep.h"
+#include <glib/gstdio.h>
+
+#include "qemu/config-file.h"
+#include "qemu/module.h"
+#include "qemu/option.h"
+#include "chardev/char-fe.h"
+#include "sysemu/sysemu.h"
+#include "qapi/error.h"
+#include "qapi/qapi-commands-char.h"
+#include "qapi/qapi-types-char.h"
+#include "qapi/qapi-commands-yank.h"
+#include "qapi/qapi-types-yank.h"
+#include "io/channel-socket.h"
+#include "socket-helpers.h"
+
+typedef struct {
+=C2=A0 =C2=A0 SocketAddress *addr;
+=C2=A0 =C2=A0 bool old_yank;
+=C2=A0 =C2=A0 bool new_yank;
+=C2=A0 =C2=A0 bool fail;
+} CharChangeTestConfig;
+
+static int chardev_change(void *opaque)
+{
+=C2=A0 =C2=A0 return 0;
+}
+
+static bool is_yank_instance_registered(void)
+{
+=C2=A0 =C2=A0 YankInstanceList *list;
+=C2=A0 =C2=A0 bool ret;
+
+=C2=A0 =C2=A0 list =3D qmp_query_yank(&error_abort);
+
+=C2=A0 =C2=A0 ret =3D !!list;
+
+=C2=A0 =C2=A0 qapi_free_YankInstanceList(list);
+
+=C2=A0 =C2=A0 return ret;
+}
+
+static void char_change_test(gconstpointer opaque)
+{
+=C2=A0 =C2=A0 CharChangeTestConfig *conf =3D (gpointer) opaque;
+=C2=A0 =C2=A0 SocketAddress *addr;
+=C2=A0 =C2=A0 Chardev *chr;
+=C2=A0 =C2=A0 CharBackend be;
+=C2=A0 =C2=A0 ChardevReturn *ret;
+=C2=A0 =C2=A0 QIOChannelSocket *ioc;
+
+=C2=A0 =C2=A0 /*
+=C2=A0 =C2=A0 =C2=A0* Setup a listener socket and determine its address +=C2=A0 =C2=A0 =C2=A0* so we know the TCP port for the client later
+=C2=A0 =C2=A0 =C2=A0*/
+=C2=A0 =C2=A0 ioc =3D qio_channel_socket_new();
+=C2=A0 =C2=A0 g_assert_nonnull(ioc);
+=C2=A0 =C2=A0 qio_channel_socket_listen_sync(ioc, conf->addr, 1, &e= rror_abort);
+=C2=A0 =C2=A0 addr =3D qio_channel_socket_get_local_address(ioc, &erro= r_abort);
+=C2=A0 =C2=A0 g_assert_nonnull(addr);
+
+=C2=A0 =C2=A0 ChardevBackend backend[2] =3D {
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 /* doesn't support yank */
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 { .type =3D CHARDEV_BACKEND_KIND_NULL },
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 /* supports yank */
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 {
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 .type =3D CHARDEV_BACKEND_KIND_S= OCKET,
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 .u.socket.data =3D &(Chardev= Socket) {
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 .addr =3D &(So= cketAddressLegacy) {
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 .typ= e =3D SOCKET_ADDRESS_LEGACY_KIND_INET,
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 .u.i= net.data =3D &addr->u.inet
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 },
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 .has_server =3D tr= ue,
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 .server =3D false<= br> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 }
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 } };
+
+=C2=A0 =C2=A0 ChardevBackend fail_backend[2] =3D {
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 /* doesn't support yank */
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 {
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 .type =3D CHARDEV_BACKEND_KIND_U= DP,
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 .u.udp.data =3D &(ChardevUdp= ) {
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 .remote =3D &(= SocketAddressLegacy) {
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 .typ= e =3D SOCKET_ADDRESS_LEGACY_KIND_UNIX,
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 .u.q= _unix.data =3D &(UnixSocketAddress) {
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 .path =3D (char *)""
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 } +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 }
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 }
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 },
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 /* supports yank */
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 {
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 .type =3D CHARDEV_BACKEND_KIND_S= OCKET,
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 .u.socket.data =3D &(Chardev= Socket) {
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 .addr =3D &(So= cketAddressLegacy) {
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 .typ= e =3D SOCKET_ADDRESS_LEGACY_KIND_INET,
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 .u.i= net.data =3D &(InetSocketAddress) {
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 .host =3D (char *)"127.0.0.1",
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 .port =3D (char *)"0"
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 } +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 },
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 .has_server =3D tr= ue,
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 .server =3D false<= br> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 }
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 } };
+
+=C2=A0 =C2=A0 g_assert(!is_yank_instance_registered());
+
+=C2=A0 =C2=A0 ret =3D qmp_chardev_add("chardev", &backend[co= nf->old_yank], &error_abort);
+=C2=A0 =C2=A0 qapi_free_ChardevReturn(ret);
+=C2=A0 =C2=A0 chr =3D qemu_chr_find("chardev");
+=C2=A0 =C2=A0 g_assert_nonnull(chr);
+
+=C2=A0 =C2=A0 g_assert(is_yank_instance_registered() =3D=3D conf->old_y= ank);
+
+=C2=A0 =C2=A0 qemu_chr_wait_connected(chr, &error_abort);
+=C2=A0 =C2=A0 qemu_chr_fe_init(&be, chr, &error_abort);
+=C2=A0 =C2=A0 /* allow chardev-change */
+=C2=A0 =C2=A0 qemu_chr_fe_set_handlers(&be, NULL, NULL,
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0NULL, chardev_change, NULL, NULL, true);
+
+=C2=A0 =C2=A0 if (conf->fail) {
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 g_setenv("QTEST_SILENT_ERRORS", &quo= t;1", 1);
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 ret =3D qmp_chardev_change("chardev"= , &fail_backend[conf->new_yank],
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0NULL);
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 g_assert_null(ret);
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 g_assert(be.chr =3D=3D chr);
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 g_assert(is_yank_instance_registered() =3D=3D = conf->old_yank);
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 g_unsetenv("QTEST_SILENT_ERRORS"); +=C2=A0 =C2=A0 } else {
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 ret =3D qmp_chardev_change("chardev"= , &backend[conf->new_yank],
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0&error_abort);
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 g_assert_nonnull(ret);
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 g_assert(be.chr !=3D chr);
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 g_assert(is_yank_instance_registered() =3D=3D = conf->new_yank);
+=C2=A0 =C2=A0 }
+
+=C2=A0 =C2=A0 object_unparent(OBJECT(be.chr));
+=C2=A0 =C2=A0 object_unref(OBJECT(ioc));
+=C2=A0 =C2=A0 qapi_free_ChardevReturn(ret);
+}
+
+static SocketAddress tcpaddr =3D {
+=C2=A0 =C2=A0 .type =3D SOCKET_ADDRESS_TYPE_INET,
+=C2=A0 =C2=A0 .u.inet.host =3D (char *)"127.0.0.1",
+=C2=A0 =C2=A0 .u.inet.port =3D (char *)"0",
+};
+
+int main(int argc, char **argv)
+{
+=C2=A0 =C2=A0 bool has_ipv4, has_ipv6;
+
+=C2=A0 =C2=A0 qemu_init_main_loop(&error_abort);
+=C2=A0 =C2=A0 socket_init();
+
+=C2=A0 =C2=A0 g_test_init(&argc, &argv, NULL);
+
+=C2=A0 =C2=A0 if (socket_check_protocol_support(&has_ipv4, &has_ip= v6) < 0) {
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 g_printerr("socket_check_protocol_support= () failed\n");
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 goto end;
+=C2=A0 =C2=A0 }
+
+=C2=A0 =C2=A0 if (!has_ipv4) {
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 goto end;
+=C2=A0 =C2=A0 }
+
+=C2=A0 =C2=A0 module_call_init(MODULE_INIT_QOM);
+=C2=A0 =C2=A0 qemu_add_opts(&qemu_chardev_opts);
+
+#define CHAR_CHANGE_TEST(name, _old_yank, _new_yank)=C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0\
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 g_test_add_data_func("/yank/char_change/s= uccess/" # name,=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 \
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0&(CharChangeTestConfig) { .addr =3D &= ;tcpaddr,=C2=A0 =C2=A0 =C2=A0 =C2=A0\
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0.old_yank =3D (_old_yank),\=
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0.new_yank =3D (_new_yank),\=
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0.fail =3D false },=C2=A0 = =C2=A0 =C2=A0 =C2=A0 \
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0char_change_test);=C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 \
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 g_test_add_data_func("/yank/char_change/f= ail/" # name,=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0\
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0&(CharChangeTestConfig) { .addr =3D &= ;tcpaddr,=C2=A0 =C2=A0 =C2=A0 =C2=A0\
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0.old_yank =3D (_old_yank),\=
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0.new_yank =3D (_new_yank),\=
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0.fail =3D true },=C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0\
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0char_change_test);
+
+=C2=A0 =C2=A0 CHAR_CHANGE_TEST(to_yank, false, true);
+=C2=A0 =C2=A0 CHAR_CHANGE_TEST(yank_to_yank, true, true);
+=C2=A0 =C2=A0 CHAR_CHANGE_TEST(from_yank, true, false);
+
+end:
+=C2=A0 =C2=A0 return g_test_run();
+}
--
2.30.2


--
Marc-Andr=C3=A9 Lureau
--0000000000001d0eec05be76f888--