@@ -26,6 +26,8 @@ typedef struct QTestState QTestState;
struct QTestMigrationState {
bool stop_seen;
bool resume_seen;
+ bool setup_seen;
+ bool active_seen;
};
typedef struct QTestMigrationState QTestMigrationState;
@@ -34,6 +34,22 @@ bool migrate_watch_for_events(QTestState *who, const char *name,
return true;
} else if (g_str_equal(name, "RESUME")) {
state->resume_seen = true;
+ return true;
+ } else if (g_str_equal(name, "MIGRATION")) {
+ QDict *data;
+ g_assert(qdict_haskey(event, "data"));
+
+ data = qdict_get_qdict(event, "data");
+ g_assert(qdict_haskey(data, "status"));
+
+ if (g_str_equal(qdict_get_str(data, "status"), "setup")) {
+ state->setup_seen = true;
+ } else if (g_str_equal(qdict_get_str(data, "status"), "active")) {
+ state->active_seen = true;
+ } else {
+ return false;
+ }
+
return true;
}
@@ -110,10 +126,49 @@ void wait_for_resume(QTestState *who)
}
}
+static void wait_for_migration_state(QTestState *who, const char* state)
+{
+ QDict *rsp, *data;
+
+ for (;;) {
+ rsp = qtest_qmp_eventwait_ref(who, "MIGRATION");
+ g_assert(qdict_haskey(rsp, "data"));
+
+ data = qdict_get_qdict(rsp, "data");
+ g_assert(qdict_haskey(data, "status"));
+
+ if (g_str_equal(qdict_get_str(data, "status"), state)) {
+ break;
+ }
+ qobject_unref(rsp);
+ }
+
+ qobject_unref(rsp);
+ return;
+}
+
+void wait_for_setup(QTestState *who)
+{
+ QTestMigrationState *state = qtest_migration_state(who);
+
+ if (!state->setup_seen) {
+ wait_for_migration_state(who, "setup");
+ }
+}
+
+void wait_for_active(QTestState *who)
+{
+ QTestMigrationState *state = qtest_migration_state(who);
+
+ if (!state->active_seen) {
+ wait_for_migration_state(who, "active");
+ }
+}
+
void migrate_incoming_qmp(QTestState *to, const char *uri, const char *fmt, ...)
{
va_list ap;
- QDict *args, *rsp, *data;
+ QDict *args, *rsp;
va_start(ap, fmt);
args = qdict_from_vjsonf_nofail(fmt, ap);
@@ -129,14 +184,7 @@ void migrate_incoming_qmp(QTestState *to, const char *uri, const char *fmt, ...)
g_assert(qdict_haskey(rsp, "return"));
qobject_unref(rsp);
- rsp = qtest_qmp_eventwait_ref(to, "MIGRATION");
- g_assert(qdict_haskey(rsp, "data"));
-
- data = qdict_get_qdict(rsp, "data");
- g_assert(qdict_haskey(data, "status"));
- g_assert_cmpstr(qdict_get_str(data, "status"), ==, "setup");
-
- qobject_unref(rsp);
+ wait_for_setup(to);
}
/*
@@ -21,6 +21,8 @@ bool migrate_watch_for_events(QTestState *who, const char *name,
void wait_for_stop(QTestState *who);
void wait_for_resume(QTestState *who);
+void wait_for_setup(QTestState *who);
+void wait_for_active(QTestState *who);
G_GNUC_PRINTF(3, 4)
void migrate_qmp(QTestState *who, const char *uri, const char *fmt, ...);
Add support for waiting for a migration state change event to happen. This can help disambiguate between runstate changes that happen during VM lifecycle. Specifically, the next couple of patches want to know whether STOP events happened at the migration start or end. Add the "setup" and "active" migration states for that purpose. Signed-off-by: Fabiano Rosas <farosas@suse.de> --- tests/qtest/libqtest.h | 2 + tests/qtest/migration-helpers.c | 66 ++++++++++++++++++++++++++++----- tests/qtest/migration-helpers.h | 2 + 3 files changed, 61 insertions(+), 9 deletions(-)