Introduce support for adding a 'channels' argument to migrate_qmp_fail, migrate_incoming_qmp and migrate_qmp functions within the migration qtest framework, enabling enhanced control over migration scenarios.
Signed-off-by: Het Gala <het.g...@nutanix.com> --- tests/qtest/dbus-vmstate-test.c | 2 +- tests/qtest/migration-helpers.c | 78 +++++++++++++++++++++++++++---- tests/qtest/migration-helpers.h | 15 +++--- tests/qtest/migration-test.c | 43 ++++++++--------- tests/qtest/virtio-net-failover.c | 8 ++-- 5 files changed, 105 insertions(+), 41 deletions(-) diff --git a/tests/qtest/dbus-vmstate-test.c b/tests/qtest/dbus-vmstate-test.c index 6c990864e3..0ca572e29b 100644 --- a/tests/qtest/dbus-vmstate-test.c +++ b/tests/qtest/dbus-vmstate-test.c @@ -229,7 +229,7 @@ test_dbus_vmstate(Test *test) thread = g_thread_new("dbus-vmstate-thread", dbus_vmstate_thread, loop); - migrate_qmp(src_qemu, uri, "{}"); + migrate_qmp(src_qemu, uri, NULL, "{}"); test->src_qemu = src_qemu; if (test->migrate_fail) { wait_for_migration_fail(src_qemu, true); diff --git a/tests/qtest/migration-helpers.c b/tests/qtest/migration-helpers.c index e451dbdbed..15c3650b55 100644 --- a/tests/qtest/migration-helpers.c +++ b/tests/qtest/migration-helpers.c @@ -13,6 +13,7 @@ #include "qemu/osdep.h" #include "qemu/ctype.h" #include "qapi/qmp/qjson.h" +#include "qapi/qmp/qlist.h" #include "migration-helpers.h" @@ -43,7 +44,67 @@ bool migrate_watch_for_events(QTestState *who, const char *name, return false; } -void migrate_qmp_fail(QTestState *who, const char *uri, const char *fmt, ...) +static QList *MigrationChannelList_to_QList(MigrationChannelList *channels) +{ + MigrationChannel *channel = NULL; + MigrationAddress *addr = NULL; + SocketAddress *saddr = NULL; + QList *channelList = qlist_new(); + QDict *channelDict = qdict_new(); + QDict *addrDict = qdict_new(); + + channel = channels->value; + if (!channel || channel->channel_type == MIGRATION_CHANNEL_TYPE__MAX) { + fprintf(stderr, "%s: Channel or its type is NULL\n", + __func__); + } + g_assert(channel); + if (channel->channel_type == MIGRATION_CHANNEL_TYPE_MAIN) { + qdict_put_str(channelDict, "channel-type", g_strdup("main")); + } + + addr = channel->addr; + if (!addr || addr->transport == MIGRATION_ADDRESS_TYPE__MAX) { + fprintf(stderr, "%s: addr or its transport is NULL\n", + __func__); + } + g_assert(addr); + if (addr->transport == MIGRATION_ADDRESS_TYPE_SOCKET) { + qdict_put_str(addrDict, "transport", g_strdup("socket")); + } + + saddr = &addr->u.socket; + if (!saddr) { + fprintf(stderr, "%s: saddr is NULL\n", __func__); + } + g_assert(saddr); + qdict_put_str(addrDict, "type", SocketAddressType_str(saddr->type)); + qdict_put_str(addrDict, "port", saddr->u.inet.port); + qdict_put_str(addrDict, "host", saddr->u.inet.host); + + qdict_put_obj(channelDict, "addr", QOBJECT(addrDict)); + qlist_append_obj(channelList, QOBJECT(channelDict)); + + return channelList; +} + +static void migrate_qmp_attach_ports(QDict *args, const char *uri, + MigrationChannelList *channels) +{ + if (uri) { + g_assert(!qdict_haskey(args, "uri")); + qdict_put_str(args, "uri", uri); + } + + if (channels) { + g_assert(!qdict_haskey(args, "channels")); + QList *channelList = MigrationChannelList_to_QList(channels); + qdict_put_obj(args, "channels", QOBJECT(channelList)); + } +} + +void migrate_qmp_fail(QTestState *who, const char *uri, + MigrationChannelList *channels, const char *fmt, ...) { va_list ap; QDict *args, *err; @@ -52,8 +113,7 @@ void migrate_qmp_fail(QTestState *who, const char *uri, const char *fmt, ...) args = qdict_from_vjsonf_nofail(fmt, ap); va_end(ap); - g_assert(!qdict_haskey(args, "uri")); - qdict_put_str(args, "uri", uri); + migrate_qmp_attach_ports(args, uri, channels); err = qtest_qmp_assert_failure_ref( who, "{ 'execute': 'migrate', 'arguments': %p}", args); @@ -68,7 +128,8 @@ void migrate_qmp_fail(QTestState *who, const char *uri, const char *fmt, ...) * Arguments are built from @fmt... (formatted like * qobject_from_jsonf_nofail()) with "uri": @uri spliced in. */ -void migrate_qmp(QTestState *who, const char *uri, const char *fmt, ...) +void migrate_qmp(QTestState *who, const char *uri, + MigrationChannelList *channels, const char *fmt, ...) { va_list ap; QDict *args; @@ -77,8 +138,7 @@ void migrate_qmp(QTestState *who, const char *uri, const char *fmt, ...) args = qdict_from_vjsonf_nofail(fmt, ap); va_end(ap); - g_assert(!qdict_haskey(args, "uri")); - qdict_put_str(args, "uri", uri); + migrate_qmp_attach_ports(args, uri, channels); qtest_qmp_assert_success(who, "{ 'execute': 'migrate', 'arguments': %p}", args); @@ -95,7 +155,8 @@ void migrate_set_capability(QTestState *who, const char *capability, capability, value); } -void migrate_incoming_qmp(QTestState *to, const char *uri, const char *fmt, ...) +void migrate_incoming_qmp(QTestState *to, const char *uri, + MigrationChannelList *channels, const char *fmt, ...) { va_list ap; QDict *args, *rsp, *data; @@ -104,8 +165,7 @@ void migrate_incoming_qmp(QTestState *to, const char *uri, const char *fmt, ...) args = qdict_from_vjsonf_nofail(fmt, ap); va_end(ap); - g_assert(!qdict_haskey(args, "uri")); - qdict_put_str(args, "uri", uri); + migrate_qmp_attach_ports(args, uri, channels); migrate_set_capability(to, "events", true); diff --git a/tests/qtest/migration-helpers.h b/tests/qtest/migration-helpers.h index 3bf7ded1b9..390e386274 100644 --- a/tests/qtest/migration-helpers.h +++ b/tests/qtest/migration-helpers.h @@ -14,6 +14,7 @@ #define MIGRATION_HELPERS_H #include "libqtest.h" +#include "migration/migration.h" typedef struct QTestMigrationState { bool stop_seen; @@ -25,15 +26,17 @@ typedef struct QTestMigrationState { bool migrate_watch_for_events(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, ...); +G_GNUC_PRINTF(4, 5) +void migrate_qmp(QTestState *who, const char *uri, + MigrationChannelList *channels, const char *fmt, ...); -G_GNUC_PRINTF(3, 4) +G_GNUC_PRINTF(4, 5) void migrate_incoming_qmp(QTestState *who, const char *uri, - const char *fmt, ...); + MigrationChannelList *channels, const char *fmt, ...); -G_GNUC_PRINTF(3, 4) -void migrate_qmp_fail(QTestState *who, const char *uri, const char *fmt, ...); +G_GNUC_PRINTF(4, 5) +void migrate_qmp_fail(QTestState *who, const char *uri, + MigrationChannelList *channels, const char *fmt, ...); void migrate_set_capability(QTestState *who, const char *capability, bool value); diff --git a/tests/qtest/migration-test.c b/tests/qtest/migration-test.c index 8a5bb1752e..e5547b8746 100644 --- a/tests/qtest/migration-test.c +++ b/tests/qtest/migration-test.c @@ -18,6 +18,7 @@ #include "qemu/module.h" #include "qemu/option.h" #include "qemu/range.h" +#include "migration/migration.h" #include "qemu/sockets.h" #include "chardev/char.h" #include "qapi/qapi-visit-sockets.h" @@ -1350,7 +1351,7 @@ static int migrate_postcopy_prepare(QTestState **from_ptr, wait_for_suspend(from, &src_state); g_autofree char *uri = migrate_get_socket_address(to, "socket-address"); - migrate_qmp(from, uri, "{}"); + migrate_qmp(from, uri, NULL, "{}"); migrate_wait_for_dirty_mem(from, to); @@ -1500,7 +1501,7 @@ static void postcopy_recover_fail(QTestState *from, QTestState *to) g_assert_cmpint(ret, ==, 1); migrate_recover(to, "fd:fd-mig"); - migrate_qmp(from, "fd:fd-mig", "{'resume': true}"); + migrate_qmp(from, "fd:fd-mig", NULL, "{'resume': true}"); /* * Make sure both QEMU instances will go into RECOVER stage, then test @@ -1588,7 +1589,7 @@ static void test_postcopy_recovery_common(MigrateCommon *args) * Try to rebuild the migration channel using the resume flag and * the newly created channel */ - migrate_qmp(from, uri, "{'resume': true}"); + migrate_qmp(from, uri, NULL, "{'resume': true}"); /* Restore the postcopy bandwidth to unlimited */ migrate_set_parameter_int(from, "max-postcopy-bandwidth", 0); @@ -1669,7 +1670,7 @@ static void test_baddest(void) if (test_migrate_start(&from, &to, "tcp:127.0.0.1:0", &args)) { return; } - migrate_qmp(from, "tcp:127.0.0.1:0", "{}"); + migrate_qmp(from, "tcp:127.0.0.1:0", NULL, "{}"); wait_for_migration_fail(from, false); test_migrate_end(from, to, false); } @@ -1708,7 +1709,7 @@ static void test_analyze_script(void) uri = g_strdup_printf("exec:cat > %s", file); migrate_ensure_converge(from); - migrate_qmp(from, uri, "{}"); + migrate_qmp(from, uri, NULL, "{}"); wait_for_migration_complete(from); pid = fork(); @@ -1773,11 +1774,11 @@ static void test_precopy_common(MigrateCommon *args) } if (args->result == MIG_TEST_QMP_ERROR) { - migrate_qmp_fail(from, connect_uri, "{}"); + migrate_qmp_fail(from, connect_uri, NULL, "{}"); goto finish; } - migrate_qmp(from, connect_uri, "{}"); + migrate_qmp(from, connect_uri, NULL, "{}"); if (args->result != MIG_TEST_SUCCEED) { bool allow_active = args->result == MIG_TEST_FAIL; @@ -1869,18 +1870,18 @@ static void test_file_common(MigrateCommon *args, bool stop_src) } if (args->result == MIG_TEST_QMP_ERROR) { - migrate_qmp_fail(from, connect_uri, "{}"); + migrate_qmp_fail(from, connect_uri, NULL, "{}"); goto finish; } - migrate_qmp(from, connect_uri, "{}"); + migrate_qmp(from, connect_uri, NULL, "{}"); wait_for_migration_complete(from); /* * We need to wait for the source to finish before starting the * destination. */ - migrate_incoming_qmp(to, connect_uri, "{}"); + migrate_incoming_qmp(to, connect_uri, NULL, "{}"); wait_for_migration_complete(to); if (stop_src) { @@ -2029,7 +2030,7 @@ static void test_ignore_shared(void) /* Wait for the first serial output from the source */ wait_for_serial("src_serial"); - migrate_qmp(from, uri, "{}"); + migrate_qmp(from, uri, NULL, "{}"); migrate_wait_for_dirty_mem(from, to); @@ -2387,7 +2388,7 @@ static void *test_migrate_fd_start_hook(QTestState *from, close(pair[0]); /* Start incoming migration from the 1st socket */ - migrate_incoming_qmp(to, "fd:fd-mig", "{}"); + migrate_incoming_qmp(to, "fd:fd-mig", NULL, "{}"); /* Send the 2nd socket to the target */ qtest_qmp_fds_assert_success(from, &pair[1], 1, @@ -2455,7 +2456,7 @@ static void do_test_validate_uuid(MigrateStart *args, bool should_fail) /* Wait for the first serial output from the source */ wait_for_serial("src_serial"); - migrate_qmp(from, uri, "{}"); + migrate_qmp(from, uri, NULL, "{}"); if (should_fail) { qtest_set_expected_status(to, EXIT_FAILURE); @@ -2558,7 +2559,7 @@ static void test_migrate_auto_converge(void) /* Wait for the first serial output from the source */ wait_for_serial("src_serial"); - migrate_qmp(from, uri, "{}"); + migrate_qmp(from, uri, NULL, "{}"); /* Wait for throttling begins */ percentage = 0; @@ -2609,7 +2610,7 @@ test_migrate_precopy_tcp_multifd_start_common(QTestState *from, migrate_set_capability(to, "multifd", true); /* Start incoming migration from the 1st socket */ - migrate_incoming_qmp(to, "tcp:127.0.0.1:0", "{}"); + migrate_incoming_qmp(to, "tcp:127.0.0.1:0", NULL, "{}"); return NULL; } @@ -2862,14 +2863,14 @@ static void test_multifd_tcp_cancel(void) migrate_set_capability(to, "multifd", true); /* Start incoming migration from the 1st socket */ - migrate_incoming_qmp(to, "tcp:127.0.0.1:0", "{}"); + migrate_incoming_qmp(to, "tcp:127.0.0.1:0", NULL, "{}"); /* Wait for the first serial output from the source */ wait_for_serial("src_serial"); uri = migrate_get_socket_address(to, "socket-address"); - migrate_qmp(from, uri, "{}"); + migrate_qmp(from, uri, NULL, "{}"); migrate_wait_for_dirty_mem(from, to); @@ -2892,7 +2893,7 @@ static void test_multifd_tcp_cancel(void) migrate_set_capability(to2, "multifd", true); /* Start incoming migration from the 1st socket */ - migrate_incoming_qmp(to2, "tcp:127.0.0.1:0", "{}"); + migrate_incoming_qmp(to2, "tcp:127.0.0.1:0", NULL, "{}"); g_free(uri); uri = migrate_get_socket_address(to2, "socket-address"); @@ -2901,7 +2902,7 @@ static void test_multifd_tcp_cancel(void) migrate_ensure_non_converge(from); - migrate_qmp(from, uri, "{}"); + migrate_qmp(from, uri, NULL, "{}"); migrate_wait_for_dirty_mem(from, to2); @@ -3234,7 +3235,7 @@ static void test_migrate_dirty_limit(void) migrate_dirty_limit_wait_showup(from, dirtylimit_period, dirtylimit_value); /* Start migrate */ - migrate_qmp(from, uri, "{}"); + migrate_qmp(from, uri, NULL, "{}"); /* Wait for dirty limit throttle begin */ throttle_us_per_full = 0; @@ -3275,7 +3276,7 @@ static void test_migrate_dirty_limit(void) } /* Start migrate */ - migrate_qmp(from, uri, "{}"); + migrate_qmp(from, uri, NULL, "{}"); /* Wait for dirty limit throttle begin */ throttle_us_per_full = 0; diff --git a/tests/qtest/virtio-net-failover.c b/tests/qtest/virtio-net-failover.c index 73dfabc272..e263ecd80e 100644 --- a/tests/qtest/virtio-net-failover.c +++ b/tests/qtest/virtio-net-failover.c @@ -772,7 +772,7 @@ static void test_migrate_in(gconstpointer opaque) check_one_card(qts, true, "standby0", MAC_STANDBY0); check_one_card(qts, false, "primary0", MAC_PRIMARY0); - migrate_incoming_qmp(qts, uri, "{}"); + migrate_incoming_qmp(qts, uri, NULL, "{}"); resp = get_failover_negociated_event(qts); g_assert_cmpstr(qdict_get_str(resp, "device-id"), ==, "standby0"); @@ -894,7 +894,7 @@ static void test_off_migrate_in(gconstpointer opaque) check_one_card(qts, true, "standby0", MAC_STANDBY0); check_one_card(qts, true, "primary0", MAC_PRIMARY0); - migrate_incoming_qmp(qts, uri, "{}"); + migrate_incoming_qmp(qts, uri, NULL, "{}"); check_one_card(qts, true, "standby0", MAC_STANDBY0); check_one_card(qts, true, "primary0", MAC_PRIMARY0); @@ -1021,7 +1021,7 @@ static void test_guest_off_migrate_in(gconstpointer opaque) check_one_card(qts, true, "standby0", MAC_STANDBY0); check_one_card(qts, false, "primary0", MAC_PRIMARY0); - migrate_incoming_qmp(qts, uri, "{}"); + migrate_incoming_qmp(qts, uri, NULL, "{}"); check_one_card(qts, true, "standby0", MAC_STANDBY0); check_one_card(qts, false, "primary0", MAC_PRIMARY0); @@ -1746,7 +1746,7 @@ static void test_multi_in(gconstpointer opaque) check_one_card(qts, true, "standby1", MAC_STANDBY1); check_one_card(qts, false, "primary1", MAC_PRIMARY1); - migrate_incoming_qmp(qts, uri, "{}"); + migrate_incoming_qmp(qts, uri, NULL, "{}"); resp = get_failover_negociated_event(qts); g_assert_cmpstr(qdict_get_str(resp, "device-id"), ==, "standby0"); -- 2.22.3