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


Reply via email to