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 stop_cb(void *opaque
, const char *name
, QDict
*data
)
22 if (!strcmp(name
, "STOP")) {
28 * Events can get in the way of responses we are actually waiting for.
30 QDict
*wait_command_fd(QTestState
*who
, int fd
, const char *command
, ...)
34 va_start(ap
, command
);
35 qtest_qmp_vsend_fds(who
, &fd
, 1, command
, ap
);
38 return qtest_qmp_receive_success(who
, stop_cb
, NULL
);
42 * Events can get in the way of responses we are actually waiting for.
44 QDict
*wait_command(QTestState
*who
, const char *command
, ...)
48 va_start(ap
, command
);
49 qtest_qmp_vsend(who
, command
, ap
);
52 return qtest_qmp_receive_success(who
, stop_cb
, NULL
);
56 * Send QMP command "migrate".
57 * Arguments are built from @fmt... (formatted like
58 * qobject_from_jsonf_nofail()) with "uri": @uri spliced in.
60 void migrate_qmp(QTestState
*who
, const char *uri
, const char *fmt
, ...)
66 args
= qdict_from_vjsonf_nofail(fmt
, ap
);
69 g_assert(!qdict_haskey(args
, "uri"));
70 qdict_put_str(args
, "uri", uri
);
72 rsp
= qtest_qmp(who
, "{ 'execute': 'migrate', 'arguments': %p}", args
);
74 g_assert(qdict_haskey(rsp
, "return"));
79 * Note: caller is responsible to free the returned object via
80 * qobject_unref() after use
82 QDict
*migrate_query(QTestState
*who
)
84 return wait_command(who
, "{ 'execute': 'query-migrate' }");
88 * Note: caller is responsible to free the returned object via
91 static gchar
*migrate_query_status(QTestState
*who
)
93 QDict
*rsp_return
= migrate_query(who
);
94 gchar
*status
= g_strdup(qdict_get_str(rsp_return
, "status"));
97 qobject_unref(rsp_return
);
102 static bool check_migration_status(QTestState
*who
, const char *goal
,
103 const char **ungoals
)
106 char *current_status
;
109 current_status
= migrate_query_status(who
);
110 ready
= strcmp(current_status
, goal
) == 0;
112 g_assert_cmpstr(current_status
, !=, "failed");
114 * If looking for a state other than completed,
115 * completion of migration would cause the test to
118 if (strcmp(goal
, "completed") != 0) {
119 g_assert_cmpstr(current_status
, !=, "completed");
122 for (ungoal
= ungoals
; *ungoal
; ungoal
++) {
123 g_assert_cmpstr(current_status
, !=, *ungoal
);
126 g_free(current_status
);
130 void wait_for_migration_status(QTestState
*who
,
131 const char *goal
, const char **ungoals
)
133 while (!check_migration_status(who
, goal
, ungoals
)) {
138 void wait_for_migration_complete(QTestState
*who
)
140 wait_for_migration_status(who
, "completed", NULL
);
143 void wait_for_migration_fail(QTestState
*from
, bool allow_active
)
150 status
= migrate_query_status(from
);
151 bool result
= !strcmp(status
, "setup") || !strcmp(status
, "failed") ||
152 (allow_active
&& !strcmp(status
, "active"));
154 fprintf(stderr
, "%s: unexpected status status=%s allow_active=%d\n",
155 __func__
, status
, allow_active
);
158 failed
= !strcmp(status
, "failed");
162 /* Is the machine currently running? */
163 rsp_return
= wait_command(from
, "{ 'execute': 'query-status' }");
164 g_assert(qdict_haskey(rsp_return
, "running"));
165 g_assert(qdict_get_bool(rsp_return
, "running"));
166 qobject_unref(rsp_return
);