tests/qtest/migration: Add mapped-ram/postcopy validation test
The migration capability checks reject enabling postcopy-ram together with mapped-ram, but there is no qtest covering this incompatibility. Add a validation test that verifies QMP rejects the combination in both capability ordering cases and returns the expected error. This keeps the existing capability boundary covered without changing migration behavior. Signed-off-by: Takeru Hayasaka <hayatake396@gmail.com> Link: https://lore.kernel.org/qemu-devel/20260327164705.1990226-1-hayatake396@gmail.com [unlink src_serial] Signed-off-by: Fabiano Rosas <farosas@suse.de>
Takeru Hayasaka committed
Mar 27, 2026 at 16:46 UTC
5e72f2fa30bc720471a15d16c9222f2ed3171c86
1 file changed
+52
tests/qtest/migration/misc-tests.c
+52
@@ -215,6 +215,55 @@ static void do_test_validate_uri_channel(MigrateCommon *args)
215
migrate_end(from, to, false);
216
}
217
218
+static void validate_caps_pair(QTestState *from,
219
+ const char *first_capability,
220
+ const char *second_capability,
221
+ const char *expected_error)
222
+{
223
+ QDict *rsp;
224
+ const char *error_desc;
225
+
226
+ migrate_set_capability(from, first_capability, true);
227
+
228
+ rsp = qtest_qmp_assert_failure_ref(
229
+ from,
230
+ "{ 'execute': 'migrate-set-capabilities',"
231
+ " 'arguments': { 'capabilities': [ { "
232
+ " 'capability': %s, 'state': true } ] } }",
233
+ second_capability);
234
+
235
+ error_desc = qdict_get_str(rsp, "desc");
236
+ g_assert_cmpstr(error_desc, ==, expected_error);
237
+ qobject_unref(rsp);
238
+
239
+ migrate_set_capability(from, first_capability, false);
240
+}
241
+
242
+static void test_validate_caps_pair(char *test_path, MigrateCommon *args)
243
+{
244
+ g_autofree char *serial_path = g_strconcat(tmpfs, "/src_serial", NULL);
245
+ g_autofree char *cap_pair = g_path_get_basename(test_path);
246
+ QTestState *from, *to;
247
+
248
+ args->start.hide_stderr = true;
249
+ args->start.only_source = true;
250
+
251
+ if (migrate_start(&from, &to, "defer", &args->start)) {
252
+ return;
253
+ }
254
+
255
+ if (g_str_equal(cap_pair, "mapped_ram_postcopy")) {
256
+ const char *error =
257
+ "Mapped-ram migration is incompatible with postcopy";
258
+
259
+ validate_caps_pair(from, "mapped-ram", "postcopy-ram", error);
260
+ validate_caps_pair(from, "postcopy-ram", "mapped-ram", error);
261
+ }
262
+
263
+ qtest_quit(from);
264
+ unlink(serial_path);
265
+}
266
+
267
static void test_validate_uri_channels_both_set(char *name, MigrateCommon *args)
268
{
269
args->listen_uri = "defer",
@@ -276,4 +325,7 @@ void migration_test_add_misc(MigrationTestEnv *env)
325
test_validate_uri_channels_both_set);
326
migration_test_add("/migration/validate_uri/channels/none_set",
327
test_validate_uri_channels_none_set);
328
+ migration_test_add_suffix("/migration/validate_caps/",
329
+ "mapped_ram_postcopy",
330
+ test_validate_caps_pair);
331
}