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");