@samitouri / QOSamiQemu / commits / 5e72f2fa30

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 }