2 * QTest migration helpers
4 * Copyright (c) 2016-2018 Red Hat, Inc. and/or its affiliates
5 * based on the vhost-user-test.c that is:
6 * Copyright (c) 2014 Virtual Open Systems Sarl.
8 * This work is licensed under the terms of the GNU GPL, version 2 or later.
9 * See the COPYING file in the top-level directory.
13 #include "qemu/osdep.h"
14 #include "qapi/qmp/qjson.h"
16 #include "migration-helpers.h"
20 static void check_stop_event(QTestState
*who
)
22 QDict
*event
= qtest_qmp_event_ref(who
, "STOP");
30 * Events can get in the way of responses we are actually waiting for.
32 QDict
*wait_command_fd(QTestState
*who
, int fd
, const char *command
, ...)
37 va_start(ap
, command
);
38 qtest_qmp_vsend_fds(who
, &fd
, 1, command
, ap
);
41 resp
= qtest_qmp_receive(who
);
42 check_stop_event(who
);
44 g_assert(!qdict_haskey(resp
, "error"));
45 g_assert(qdict_haskey(resp
, "return"));
47 ret
= qdict_get_qdict(resp
, "return");
55 * Events can get in the way of responses we are actually waiting for.
57 QDict
*wait_command(QTestState
*who
, const char *command
, ...)
62 va_start(ap
, command
);
63 resp
= qtest_vqmp(who
, command
, ap
);
66 check_stop_event(who
);
68 g_assert(!qdict_haskey(resp
, "error"));
69 g_assert(qdict_haskey(resp
, "return"));
71 ret
= qdict_get_qdict(resp
, "return");
79 * Send QMP command "migrate".
80 * Arguments are built from @fmt... (formatted like
81 * qobject_from_jsonf_nofail()) with "uri": @uri spliced in.
83 void migrate_qmp(QTestState
*who
, const char *uri
, const char *fmt
, ...)
89 args
= qdict_from_vjsonf_nofail(fmt
, ap
);
92 g_assert(!qdict_haskey(args
, "uri"));
93 qdict_put_str(args
, "uri", uri
);
95 rsp
= qtest_qmp(who
, "{ 'execute': 'migrate', 'arguments': %p}", args
);
97 g_assert(qdict_haskey(rsp
, "return"));
102 * Note: caller is responsible to free the returned object via
103 * qobject_unref() after use
105 QDict
*migrate_query(QTestState
*who
)
107 return wait_command(who
, "{ 'execute': 'query-migrate' }");
111 * Note: caller is responsible to free the returned object via
114 static gchar
*migrate_query_status(QTestState
*who
)
116 QDict
*rsp_return
= migrate_query(who
);
117 gchar
*status
= g_strdup(qdict_get_str(rsp_return
, "status"));
120 qobject_unref(rsp_return
);
125 static bool check_migration_status(QTestState
*who
, const char *goal
,
126 const char **ungoals
)
129 char *current_status
;
132 current_status
= migrate_query_status(who
);
133 ready
= strcmp(current_status
, goal
) == 0;
135 g_assert_cmpstr(current_status
, !=, "failed");
137 * If looking for a state other than completed,
138 * completion of migration would cause the test to
141 if (strcmp(goal
, "completed") != 0) {
142 g_assert_cmpstr(current_status
, !=, "completed");
145 for (ungoal
= ungoals
; *ungoal
; ungoal
++) {
146 g_assert_cmpstr(current_status
, !=, *ungoal
);
149 g_free(current_status
);
153 void wait_for_migration_status(QTestState
*who
,
154 const char *goal
, const char **ungoals
)
156 while (!check_migration_status(who
, goal
, ungoals
)) {
161 void wait_for_migration_complete(QTestState
*who
)
163 wait_for_migration_status(who
, "completed", NULL
);
166 void wait_for_migration_fail(QTestState
*from
, bool allow_active
)
173 status
= migrate_query_status(from
);
174 bool result
= !strcmp(status
, "setup") || !strcmp(status
, "failed") ||
175 (allow_active
&& !strcmp(status
, "active"));
177 fprintf(stderr
, "%s: unexpected status status=%s allow_active=%d\n",
178 __func__
, status
, allow_active
);
181 failed
= !strcmp(status
, "failed");
185 /* Is the machine currently running? */
186 rsp_return
= wait_command(from
, "{ 'execute': 'query-status' }");
187 g_assert(qdict_haskey(rsp_return
, "running"));
188 g_assert(qdict_get_bool(rsp_return
, "running"));
189 qobject_unref(rsp_return
);