From: Denis V. Lunev <[email protected]> The destination must not report postcopy-active or completed while it is still in RUN_STATE_INMIGRATE. The destination autostarts in these tests, so the run state change emits RESUME and the order is visible in the event stream: record a MIGRATION postcopy-active or completed event seen before RESUME and fail the postcopy tests on it once the destination has completed.
migrate_postcopy_start() waited for the destination's RESUME with qtest_qmp_eventwait(), which reads events past the event callback and drops the ones it does not want. Poll query-status instead, so every destination event reaches the callback. Signed-off-by: Denis V. Lunev <[email protected]> Cc: Peter Xu <[email protected]> Cc: Fabiano Rosas <[email protected]> Cc: Juraj Marcin <[email protected]> --- tests/qtest/migration/framework.c | 6 ++++-- tests/qtest/migration/migration-qmp.c | 10 ++++++++-- tests/qtest/migration/migration-qmp.h | 3 ++- tests/qtest/migration/migration-util.c | 8 ++++++++ tests/qtest/migration/migration-util.h | 2 ++ 5 files changed, 24 insertions(+), 5 deletions(-) diff --git a/tests/qtest/migration/framework.c b/tests/qtest/migration/framework.c index b7aef6b21c..1cf18233f7 100644 --- a/tests/qtest/migration/framework.c +++ b/tests/qtest/migration/framework.c @@ -667,6 +667,8 @@ static void migrate_postcopy_complete(QTestState *from, QTestState *to, MigrationTestEnv *env = migration_get_env(); wait_for_migration_complete(from); + wait_for_migration_complete(to); + g_assert(!dst_state.migrated_before_resume); if (args->start.suspend_me) { /* wakeup succeeds only if guest is suspended */ @@ -695,7 +697,7 @@ void test_postcopy_common(MigrateCommon *args) if (migrate_postcopy_prepare(&from, &to, &hook_data, args)) { return; } - migrate_postcopy_start(from, to, &src_state); + migrate_postcopy_start(from, to, &src_state, &dst_state); migrate_postcopy_complete(from, to, hook_data, args); } @@ -842,7 +844,7 @@ void test_postcopy_recovery_common(MigrateCommon *args, migrate_set_parameter_int(from, "max-postcopy-bandwidth", 4096); /* Now we start the postcopy */ - migrate_postcopy_start(from, to, &src_state); + migrate_postcopy_start(from, to, &src_state, &dst_state); /* * Wait until postcopy is really started; we can only run the diff --git a/tests/qtest/migration/migration-qmp.c b/tests/qtest/migration/migration-qmp.c index 437b5eaeff..77befe1027 100644 --- a/tests/qtest/migration/migration-qmp.c +++ b/tests/qtest/migration/migration-qmp.c @@ -549,10 +549,16 @@ void migrate_cancel(QTestState *who) } void migrate_postcopy_start(QTestState *from, QTestState *to, - QTestMigrationState *src_state) + QTestMigrationState *src_state, + QTestMigrationState *dst_state) { qtest_qmp_assert_success(from, "{ 'execute': 'migrate-start-postcopy' }"); wait_for_stop(from, src_state); - qtest_qmp_eventwait(to, "RESUME"); + + /* Poll so that every destination event passes the event callback */ + while (!dst_state->resume_seen) { + qtest_qmp_assert_success(to, "{ 'execute': 'query-status' }"); + g_usleep(1000); + } } diff --git a/tests/qtest/migration/migration-qmp.h b/tests/qtest/migration/migration-qmp.h index 940ffd5950..f275cd7692 100644 --- a/tests/qtest/migration/migration-qmp.h +++ b/tests/qtest/migration/migration-qmp.h @@ -46,6 +46,7 @@ void migrate_continue(QTestState *who, const char *state); void migrate_recover(QTestState *who, const char *uri); void migrate_cancel(QTestState *who); void migrate_postcopy_start(QTestState *from, QTestState *to, - QTestMigrationState *src_state); + QTestMigrationState *src_state, + QTestMigrationState *dst_state); #endif /* MIGRATION_QMP_H */ diff --git a/tests/qtest/migration/migration-util.c b/tests/qtest/migration/migration-util.c index db66d8b24f..4b5663c5a6 100644 --- a/tests/qtest/migration/migration-util.c +++ b/tests/qtest/migration/migration-util.c @@ -178,6 +178,14 @@ bool migrate_watch_for_events(QTestState *who, const char *name, } else if (g_str_equal(name, "RESUME")) { state->resume_seen = true; return true; + } else if (g_str_equal(name, "MIGRATION") && !state->resume_seen) { + const char *status = qdict_get_str(qdict_get_qdict(event, "data"), + "status"); + + if (g_str_equal(status, "postcopy-active") || + g_str_equal(status, "completed")) { + state->migrated_before_resume = true; + } } return false; diff --git a/tests/qtest/migration/migration-util.h b/tests/qtest/migration/migration-util.h index 694773e594..f195aeea48 100644 --- a/tests/qtest/migration/migration-util.h +++ b/tests/qtest/migration/migration-util.h @@ -22,6 +22,8 @@ typedef struct QTestMigrationState { bool resume_seen; bool suspend_seen; bool suspend_me; + /* postcopy-active or completed reported before RESUME */ + bool migrated_before_resume; } QTestMigrationState; bool migrate_watch_for_events(QTestState *who, const char *name, -- 2.53.0
