@samitouri / QOSamiQemu / commits / 5048ca53b1

tests/qtest/migration: Move cpr transfer logic into cpr-tests.c

There's some amount of cpr-transfer logic at precopy_common, which in retrospect was a bad idea. For just two tests, that's too much code to be in the common function. Move it to the cpr file. We'll need this cleanup for subsequent improvements. Signed-off-by: Fabiano Rosas <farosas@suse.de> Reviewed-by: Peter Xu <peterx@redhat.com> Link: https://lore.kernel.org/r/20260505160915.25558-2-farosas@suse.de Signed-off-by: Peter Xu <peterx@redhat.com>

Fabiano Rosas committed May 5, 2026 at 13:09 UTC 5048ca53b1334797d027a8867c0b16219bb22cb3
3 files changed +56 -40
tests/qtest/migration/cpr-tests.c
+52 -5
@@ -15,6 +15,9 @@
15 #include "migration/framework.h"
16 #include "migration/migration-qmp.h"
17 #include "migration/migration-util.h"
18 +#include "qapi/error.h"
19 +#include "qobject/qjson.h"
20 +#include "qobject/qlist.h"
21
22
23 static char *tmpfs;
@@ -42,10 +45,56 @@ static void test_mode_reboot(char *name, MigrateCommon *args)
45 test_file_common(args, true);
46 }
47
45 -static void *test_mode_transfer_start(QTestState *from, QTestState *to)
48 +static int test_transfer(MigrateCommon *args, const char *cpr_channel,
49 + bool incoming_defer)
50 {
51 + QTestState *from, *to;
52 + QObject *obj, *out_channels = qobject_from_json(args->connect_channels,
53 + &error_abort);
54 + QList *channels_list;
55 +
56 + /*
57 + * The cpr channel must be included in outgoing channels, but not in
58 + * migrate-incoming channels.
59 + */
60 + channels_list = qobject_to(QList, out_channels);
61 + obj = migrate_str_to_channel(cpr_channel);
62 + qlist_append(channels_list, obj);
63 +
64 + if (migrate_start(&from, &to, args->listen_uri, &args->start)) {
65 + return -1;
66 + }
67 +
68 migrate_set_parameter_str(from, "mode", "cpr-transfer");
48 - return NULL;
69 +
70 + wait_for_serial("src_serial");
71 +
72 + qtest_qmp_assert_success(from, "{ 'execute' : 'stop'}");
73 + wait_for_stop(from, get_src());
74 + migrate_ensure_converge(from);
75 +
76 + migrate_qmp(from, to, NULL, out_channels, "{}");
77 +
78 + qtest_connect(to);
79 + qtest_qmp_handshake(to, NULL);
80 + if (incoming_defer) {
81 + QObject *in_channels = qobject_from_json(args->connect_channels,
82 + &error_abort);
83 +
84 + migrate_incoming_qmp(to, NULL, in_channels, "{}");
85 + }
86 +
87 + wait_for_migration_complete(from);
88 + wait_for_migration_complete(to);
89 +
90 + qtest_qmp_assert_success(to, "{ 'execute' : 'cont'}");
91 +
92 + wait_for_resume(to, get_dst());
93 + wait_for_serial("dest_serial");
94 +
95 + migrate_end(from, to, true);
96 +
97 + return 0;
98 }
99
100 /*
@@ -86,15 +135,13 @@ static void test_mode_transfer_common(MigrateCommon *args, bool incoming_defer)
135
136 args->listen_uri = incoming_defer ? "defer" : uri;
137 args->connect_channels = connect_channels;
89 - args->cpr_channel = cpr_channel;
90 - args->start_hook = test_mode_transfer_start;
138
139 args->start.opts_source = opts;
140 args->start.opts_target = opts_target;
141 args->start.defer_target_connect = true;
142 args->start.mem_type = MEM_TYPE_MEMFD;
143
97 - if (test_precopy_common(args) < 0) {
144 + if (test_transfer(args, cpr_channel, incoming_defer) < 0) {
145 close(cpr_sockfd);
146 unlink(cpr_path);
147 }
tests/qtest/migration/framework.c
+4 -32
@@ -20,7 +20,6 @@
20 #include "ppc-util.h"
21 #include "qapi/error.h"
22 #include "qobject/qjson.h"
23 -#include "qobject/qlist.h"
23 #include "qemu/bswap.h"
24 #include "qemu/module.h"
25 #include "qemu/option.h"
@@ -833,10 +832,7 @@ int test_precopy_common(MigrateCommon *args)
832 {
833 QTestState *from, *to;
834 void *data_hook = NULL;
836 - QObject *in_channels = NULL;
837 - QObject *out_channels = NULL;
838 -
839 - g_assert(!args->cpr_channel || args->connect_channels);
835 + QObject *channels = NULL;
836
837 if (migrate_start(&from, &to, args->listen_uri, &args->start)) {
838 return -1;
@@ -869,40 +865,16 @@ int test_precopy_common(MigrateCommon *args)
865 }
866 }
867
872 - /*
873 - * The cpr channel must be included in outgoing channels, but not in
874 - * migrate-incoming channels.
875 - */
868 if (args->connect_channels) {
877 - if (args->start.defer_target_connect &&
878 - !strcmp(args->listen_uri, "defer")) {
879 - in_channels = qobject_from_json(args->connect_channels,
880 - &error_abort);
881 - }
882 - out_channels = qobject_from_json(args->connect_channels, &error_abort);
883 -
884 - if (args->cpr_channel) {
885 - QList *channels_list = qobject_to(QList, out_channels);
886 - QObject *obj = migrate_str_to_channel(args->cpr_channel);
887 -
888 - qlist_append(channels_list, obj);
889 - }
869 + channels = qobject_from_json(args->connect_channels, &error_abort);
870 }
871
872 if (args->result == MIG_TEST_QMP_ERROR) {
893 - migrate_qmp_fail(from, args->connect_uri, out_channels, "{}");
873 + migrate_qmp_fail(from, args->connect_uri, channels, "{}");
874 goto finish;
875 }
876
897 - migrate_qmp(from, to, args->connect_uri, out_channels, "{}");
898 -
899 - if (args->start.defer_target_connect) {
900 - qtest_connect(to);
901 - qtest_qmp_handshake(to, NULL);
902 - if (!strcmp(args->listen_uri, "defer")) {
903 - migrate_incoming_qmp(to, args->connect_uri, in_channels, "{}");
904 - }
905 - }
877 + migrate_qmp(from, to, args->connect_uri, channels, "{}");
878
879 if (args->result != MIG_TEST_SUCCEED) {
880 bool allow_active = args->result == MIG_TEST_FAIL;
tests/qtest/migration/framework.h
-3
@@ -181,9 +181,6 @@ typedef struct {
181 */
182 const char *connect_channels;
183
184 - /* Optional: the cpr migration channel, in JSON or dotted keys format */
185 - const char *cpr_channel;
186 -
184 /* Optional: callback to run at start to set migration parameters */
185 TestMigrateStartHook start_hook;
186 /* Optional: callback to run at finish to cleanup */