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 */