aboutsummaryrefslogtreecommitdiff
path: root/tests/qtest/libqtest.c
diff options
context:
space:
mode:
Diffstat (limited to 'tests/qtest/libqtest.c')
-rw-r--r--tests/qtest/libqtest.c120
1 files changed, 82 insertions, 38 deletions
diff --git a/tests/qtest/libqtest.c b/tests/qtest/libqtest.c
index 94526b7..933d085 100644
--- a/tests/qtest/libqtest.c
+++ b/tests/qtest/libqtest.c
@@ -357,7 +357,7 @@ void qtest_remove_abrt_handler(void *data)
}
}
-static const char *qtest_qemu_binary(const char *var)
+const char *qtest_qemu_binary(const char *var)
{
const char *qemu_bin;
@@ -409,30 +409,30 @@ static pid_t qtest_create_process(char *cmd)
}
#endif /* _WIN32 */
-static QTestState *G_GNUC_PRINTF(2, 3) qtest_spawn_qemu(const char *qemu_bin,
- const char *fmt, ...)
+static QTestState *qtest_create_test_state(int pid)
{
- va_list ap;
QTestState *s = g_new0(QTestState, 1);
- const char *trace = g_getenv("QTEST_TRACE");
- g_autofree char *tracearg = trace ?
- g_strdup_printf("-trace %s ", trace) : g_strdup("");
- g_autoptr(GString) command = g_string_new("");
-
- va_start(ap, fmt);
- g_string_append_printf(command, CMD_EXEC "%s %s", qemu_bin, tracearg);
- g_string_append_vprintf(command, fmt, ap);
- va_end(ap);
+ s->qemu_pid = pid;
qtest_add_abrt_handler(kill_qemu_hook_func, s);
+ return s;
+}
+
+static QTestState *qtest_spawn_qemu(const char *qemu_bin, const char *args,
+ void *opaque)
+{
+ int pid;
+ g_autoptr(GString) command = g_string_new("");
+
+ g_string_printf(command, CMD_EXEC "%s %s", qemu_bin, args);
if (!silence_spawn_log) {
g_test_message("starting QEMU: %s", command->str);
}
#ifndef _WIN32
- s->qemu_pid = fork();
- if (s->qemu_pid == 0) {
+ pid = fork();
+ if (pid == 0) {
#ifdef __linux__
/*
* Although we register a ABRT handler to kill off QEMU
@@ -455,10 +455,10 @@ static QTestState *G_GNUC_PRINTF(2, 3) qtest_spawn_qemu(const char *qemu_bin,
exit(1);
}
#else
- s->qemu_pid = qtest_create_process(command->str);
+ pid = qtest_create_process(command->str);
#endif /* _WIN32 */
- return s;
+ return qtest_create_test_state(pid);
}
static char *qtest_socket_path(const char *suffix)
@@ -466,14 +466,48 @@ static char *qtest_socket_path(const char *suffix)
return g_strdup_printf("%s/qtest-%d.%s", g_get_tmp_dir(), getpid(), suffix);
}
+gchar *qtest_qemu_args(const char *extra_args)
+{
+ g_autofree gchar *socket_path = qtest_socket_path("sock");
+ g_autofree gchar *qmp_socket_path = qtest_socket_path("qmp");
+ const char *trace = g_getenv("QTEST_TRACE");
+ g_autofree char *tracearg = trace ? g_strdup_printf("-trace %s ", trace) :
+ g_strdup("");
+ gchar *args = g_strdup_printf(
+ "%s"
+ "-qtest unix:%s "
+ "-qtest-log %s "
+ "-chardev socket,path=%s,id=char0 "
+ "-mon chardev=char0,mode=control "
+ "-display none "
+ "-audio none "
+ "%s"
+ " -accel qtest",
+
+ tracearg,
+ socket_path,
+ getenv("QTEST_LOG") ? DEV_STDERR : DEV_NULL,
+ qmp_socket_path,
+ extra_args ?: "");
+
+ return args;
+}
+
+typedef QTestState *(*qtest_qemu_spawn_func)(const char *qemu_bin,
+ const char *extra_args,
+ void *opaque);
+
static QTestState *qtest_init_internal(const char *qemu_bin,
const char *extra_args,
- bool do_connect)
+ bool do_connect,
+ qtest_qemu_spawn_func spawn,
+ void *opaque)
{
QTestState *s;
int sock, qmpsock, i;
g_autofree gchar *socket_path = qtest_socket_path("sock");
g_autofree gchar *qmp_socket_path = qtest_socket_path("qmp");
+ g_autofree gchar *args = qtest_qemu_args(extra_args);
/*
* It's possible that if an earlier test run crashed it might
@@ -488,19 +522,7 @@ static QTestState *qtest_init_internal(const char *qemu_bin,
sock = init_socket(socket_path);
qmpsock = init_socket(qmp_socket_path);
- s = qtest_spawn_qemu(qemu_bin,
- "-qtest unix:%s "
- "-qtest-log %s "
- "-chardev socket,path=%s,id=char0 "
- "-mon chardev=char0,mode=control "
- "-display none "
- "-audio none "
- "%s"
- " -accel qtest",
- socket_path,
- getenv("QTEST_LOG") ? DEV_STDERR : DEV_NULL,
- qmp_socket_path,
- extra_args ?: "");
+ s = spawn(qemu_bin, args, opaque);
qtest_client_set_rx_handler(s, qtest_client_socket_recv_line);
qtest_client_set_tx_handler(s, qtest_client_socket_send);
@@ -555,7 +577,8 @@ void qtest_connect(QTestState *s)
QTestState *qtest_init_without_qmp_handshake(const char *extra_args)
{
- return qtest_init_internal(qtest_qemu_binary(NULL), extra_args, true);
+ return qtest_init_internal(qtest_qemu_binary(NULL), extra_args, true,
+ qtest_spawn_qemu, NULL);
}
void qtest_qmp_handshake(QTestState *s, QList *capabilities)
@@ -578,7 +601,7 @@ QTestState *qtest_init_ext(const char *var, const char *extra_args,
QList *capabilities, bool do_connect)
{
QTestState *s = qtest_init_internal(qtest_qemu_binary(var), extra_args,
- do_connect);
+ do_connect, qtest_spawn_qemu, NULL);
if (do_connect) {
qtest_qmp_handshake(s, capabilities);
@@ -592,6 +615,25 @@ QTestState *qtest_init_ext(const char *var, const char *extra_args,
return s;
}
+static QTestState *qtest_attach_qemu(const char *qemu_bin,
+ const char *extra_args,
+ void *opaque)
+{
+ int pid = *(int *)opaque;
+ return qtest_create_test_state(pid);
+}
+
+QTestState *qtest_init_after_exec(QTestState *qts)
+{
+ void *opaque = (void *)&qts->qemu_pid;
+ QTestState *s;
+
+ s = qtest_init_internal(NULL, NULL, true, qtest_attach_qemu, opaque);
+ qts->qemu_pid = -1;
+ qtest_qmp_handshake(s, NULL);
+ return s;
+}
+
QTestState *qtest_init(const char *extra_args)
{
return qtest_init_ext(NULL, extra_args, NULL, true);
@@ -1630,7 +1672,8 @@ static void qtest_free_machine_list(struct MachInfo *machines)
static struct MachInfo *qtest_get_machines(const char *var)
{
static struct MachInfo *machines;
- static char *qemu_var;
+ static char *qemu_bin;
+ const char *new_qemu_bin;
QDict *response, *minfo;
QList *list;
const QListEntry *p;
@@ -1639,9 +1682,10 @@ static struct MachInfo *qtest_get_machines(const char *var)
QTestState *qts;
int idx;
- if (g_strcmp0(qemu_var, var)) {
- g_free(qemu_var);
- qemu_var = g_strdup(var);
+ new_qemu_bin = qtest_qemu_binary(var);
+ if (g_strcmp0(qemu_bin, new_qemu_bin)) {
+ g_free(qemu_bin);
+ qemu_bin = g_strdup(new_qemu_bin);
/* new qemu, clear the cache */
qtest_free_machine_list(machines);
@@ -1654,7 +1698,7 @@ static struct MachInfo *qtest_get_machines(const char *var)
silence_spawn_log = !g_test_verbose();
- qts = qtest_init_ext(qemu_var, "-machine none", NULL, true);
+ qts = qtest_init_ext(var, "-machine none", NULL, true);
response = qtest_qmp(qts, "{ 'execute': 'query-machines' }");
g_assert(response);
list = qdict_get_qlist(response, "return");