#include <sys/wait.h>
#include <sys/un.h>
+#include "qapi/error.h"
#include "qapi/qmp/json-parser.h"
#include "qapi/qmp/json-streamer.h"
#include "qapi/qmp/qjson.h"
const char *qemu_binary;
qemu_binary = getenv("QTEST_QEMU_BINARY");
- g_assert(qemu_binary != NULL);
+ if (!qemu_binary) {
+ fprintf(stderr, "Environment variable QTEST_QEMU_BINARY required\n");
+ exit(1);
+ }
s = g_malloc(sizeof(*s));
socket_path = g_strdup_printf("/tmp/qtest-%d.sock", getpid());
qmp_socket_path = g_strdup_printf("/tmp/qtest-%d.qmp", getpid());
+ /* It's possible that if an earlier test run crashed it might
+ * have left a stale unix socket lying around. Delete any
+ * stale old socket to avoid spurious test failures with
+ * tests/libqtest.c:70:init_socket: assertion failed (ret != -1): (-1 != -1)
+ */
+ unlink(socket_path);
+ unlink(qmp_socket_path);
+
sock = init_socket(socket_path);
qmpsock = init_socket(qmp_socket_path);
va_list ap_copy;
QObject *qobj;
+ /* qobject_from_jsonv() silently eats leading 0xff as invalid
+ * JSON, but we want to test sending them over the wire to force
+ * resyncs */
+ if (*fmt == '\377') {
+ socket_send(fd, fmt, 1);
+ fmt++;
+ }
+
/* Going through qobject ensures we escape strings properly.
* This seemingly unnecessary copy is required in case va_list
* is an array type.
*/
va_copy(ap_copy, ap);
- qobj = qobject_from_jsonv(fmt, &ap_copy);
+ qobj = qobject_from_jsonv(fmt, &ap_copy, &error_abort);
va_end(ap_copy);
/* No need to send anything for an empty QObject. */
" 'arguments': {'command-line': %s}}",
cmd);
ret = g_strdup(qdict_get_try_str(resp, "return"));
+ while (ret == NULL && qdict_get_try_str(resp, "event")) {
+ /* Ignore asynchronous QMP events */
+ QDECREF(resp);
+ resp = qtest_qmp_receive(s);
+ ret = g_strdup(qdict_get_try_str(resp, "return"));
+ }
g_assert(ret);
QDECREF(resp);
g_free(cmd);
{
return s->big_endian;
}
+
+void qtest_cb_for_every_machine(void (*cb)(const char *machine))
+{
+ QDict *response, *minfo;
+ QList *list;
+ const QListEntry *p;
+ QObject *qobj;
+ QString *qstr;
+ const char *mname;
+
+ qtest_start("-machine none");
+ response = qmp("{ 'execute': 'query-machines' }");
+ g_assert(response);
+ list = qdict_get_qlist(response, "return");
+ g_assert(list);
+
+ for (p = qlist_first(list); p; p = qlist_next(p)) {
+ minfo = qobject_to_qdict(qlist_entry_obj(p));
+ g_assert(minfo);
+ qobj = qdict_get(minfo, "name");
+ g_assert(qobj);
+ qstr = qobject_to_qstring(qobj);
+ g_assert(qstr);
+ mname = qstring_get_str(qstr);
+ cb(mname);
+ }
+
+ qtest_end();
+ QDECREF(response);
+}