diff options
Diffstat (limited to 'tests/qtest/libqtest.c')
-rw-r--r-- | tests/qtest/libqtest.c | 120 |
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"); |