summaryrefslogtreecommitdiff
path: root/tests/libqtest.c
diff options
context:
space:
mode:
authorSeokYeon Hwang <syeon.hwang@samsung.com>2015-12-21 18:00:30 +0900
committerSeokYeon Hwang <syeon.hwang@samsung.com>2015-12-21 18:16:33 +0900
commit7864519e39b0f45ebcb4be913439a03d5a962b70 (patch)
tree6460d6050bd423a50318ed149f2835a7c358e6c0 /tests/libqtest.c
parent4758dec416c733f4fa0e32563a28e7dc843aba02 (diff)
parenta8c40fa2d667e585382080db36ac44e216b37a1c (diff)
downloadqemu-7864519e39b0f45ebcb4be913439a03d5a962b70.tar.gz
qemu-7864519e39b0f45ebcb4be913439a03d5a962b70.tar.bz2
qemu-7864519e39b0f45ebcb4be913439a03d5a962b70.zip
Merge tag 'v2.5.0' into tizen_3.0_qemu_2.5
v2.5.0 release Signed-off-by: SeokYeon Hwang <syeon.hwang@samsung.com>
Diffstat (limited to 'tests/libqtest.c')
-rw-r--r--tests/libqtest.c95
1 files changed, 74 insertions, 21 deletions
diff --git a/tests/libqtest.c b/tests/libqtest.c
index f1b8206c3c..fa314e1ee7 100644
--- a/tests/libqtest.c
+++ b/tests/libqtest.c
@@ -46,9 +46,9 @@ struct QTestState
bool irq_level[MAX_IRQ];
GString *rx;
pid_t qemu_pid; /* our child QEMU process */
- struct sigaction sigact_old; /* restored on exit */
};
+static GHookList abrt_hooks;
static GList *qtest_instances;
static struct sigaction sigact_old;
@@ -110,12 +110,14 @@ static void kill_qemu(QTestState *s)
}
}
+static void kill_qemu_hook_func(void *s)
+{
+ kill_qemu(s);
+}
+
static void sigabrt_handler(int signo)
{
- GList *elem;
- for (elem = qtest_instances; elem; elem = elem->next) {
- kill_qemu(elem->data);
- }
+ g_hook_list_invoke(&abrt_hooks, FALSE);
}
static void setup_sigabrt_handler(void)
@@ -136,6 +138,23 @@ static void cleanup_sigabrt_handler(void)
sigaction(SIGABRT, &sigact_old, NULL);
}
+void qtest_add_abrt_handler(GHookFunc fn, const void *data)
+{
+ GHook *hook;
+
+ /* Only install SIGABRT handler once */
+ if (!abrt_hooks.is_setup) {
+ g_hook_list_init(&abrt_hooks, sizeof(GHook));
+ setup_sigabrt_handler();
+ }
+
+ hook = g_hook_alloc(&abrt_hooks);
+ hook->func = fn;
+ hook->data = (void *)data;
+
+ g_hook_prepend(&abrt_hooks, hook);
+}
+
QTestState *qtest_init(const char *extra_args)
{
QTestState *s;
@@ -156,12 +175,7 @@ QTestState *qtest_init(const char *extra_args)
sock = init_socket(socket_path);
qmpsock = init_socket(qmp_socket_path);
- /* Only install SIGABRT handler once */
- if (!qtest_instances) {
- setup_sigabrt_handler();
- }
-
- qtest_instances = g_list_prepend(qtest_instances, s);
+ qtest_add_abrt_handler(kill_qemu_hook_func, s);
s->qemu_pid = fork();
if (s->qemu_pid == 0) {
@@ -209,13 +223,14 @@ QTestState *qtest_init(const char *extra_args)
void qtest_quit(QTestState *s)
{
+ qtest_instances = g_list_remove(qtest_instances, s);
+ g_hook_destroy_link(&abrt_hooks, g_hook_find_data(&abrt_hooks, TRUE, s));
+
/* Uninstall SIGABRT handler on last instance */
- if (qtest_instances && !qtest_instances->next) {
+ if (!qtest_instances) {
cleanup_sigabrt_handler();
}
- qtest_instances = g_list_remove(qtest_instances, s);
-
kill_qemu(s);
close(s->fd);
close(s->qmp_fd);
@@ -341,7 +356,7 @@ typedef struct {
QDict *response;
} QMPResponseParser;
-static void qmp_response(JSONMessageParser *parser, QList *tokens)
+static void qmp_response(JSONMessageParser *parser, GQueue *tokens)
{
QMPResponseParser *qmp = container_of(parser, QMPResponseParser, parser);
QObject *obj;
@@ -357,7 +372,7 @@ static void qmp_response(JSONMessageParser *parser, QList *tokens)
qmp->response = (QDict *)obj;
}
-QDict *qtest_qmp_receive(QTestState *s)
+QDict *qmp_fd_receive(int fd)
{
QMPResponseParser qmp;
bool log = getenv("QTEST_LOG") != NULL;
@@ -368,7 +383,7 @@ QDict *qtest_qmp_receive(QTestState *s)
ssize_t len;
char c;
- len = read(s->qmp_fd, &c, 1);
+ len = read(fd, &c, 1);
if (len == -1 && errno == EINTR) {
continue;
}
@@ -388,12 +403,17 @@ QDict *qtest_qmp_receive(QTestState *s)
return qmp.response;
}
+QDict *qtest_qmp_receive(QTestState *s)
+{
+ return qmp_fd_receive(s->qmp_fd);
+}
+
/**
* Allow users to send a message without waiting for the reply,
* in the case that they choose to discard all replies up until
* a particular EVENT is received.
*/
-void qtest_async_qmpv(QTestState *s, const char *fmt, va_list ap)
+void qmp_fd_sendv(int fd, const char *fmt, va_list ap)
{
va_list ap_copy;
QObject *qobj;
@@ -417,13 +437,25 @@ void qtest_async_qmpv(QTestState *s, const char *fmt, va_list ap)
fprintf(stderr, "%s", str);
}
/* Send QMP request */
- socket_send(s->qmp_fd, str, size);
+ socket_send(fd, str, size);
QDECREF(qstr);
qobject_decref(qobj);
}
}
+void qtest_async_qmpv(QTestState *s, const char *fmt, va_list ap)
+{
+ qmp_fd_sendv(s->qmp_fd, fmt, ap);
+}
+
+QDict *qmp_fdv(int fd, const char *fmt, va_list ap)
+{
+ qmp_fd_sendv(fd, fmt, ap);
+
+ return qmp_fd_receive(fd);
+}
+
QDict *qtest_qmpv(QTestState *s, const char *fmt, va_list ap)
{
qtest_async_qmpv(s, fmt, ap);
@@ -432,6 +464,26 @@ QDict *qtest_qmpv(QTestState *s, const char *fmt, va_list ap)
return qtest_qmp_receive(s);
}
+QDict *qmp_fd(int fd, const char *fmt, ...)
+{
+ va_list ap;
+ QDict *response;
+
+ va_start(ap, fmt);
+ response = qmp_fdv(fd, fmt, ap);
+ va_end(ap);
+ return response;
+}
+
+void qmp_fd_send(int fd, const char *fmt, ...)
+{
+ va_list ap;
+
+ va_start(ap, fmt);
+ qmp_fd_sendv(fd, fmt, ap);
+ va_end(ap);
+}
+
QDict *qtest_qmp(QTestState *s, const char *fmt, ...)
{
va_list ap;
@@ -708,14 +760,15 @@ void qtest_memread(QTestState *s, uint64_t addr, void *data, size_t size)
g_strfreev(args);
}
-void qtest_add_func(const char *str, void (*fn))
+void qtest_add_func(const char *str, void (*fn)(void))
{
gchar *path = g_strdup_printf("/%s/%s", qtest_get_arch(), str);
g_test_add_func(path, fn);
g_free(path);
}
-void qtest_add_data_func(const char *str, const void *data, void (*fn))
+void qtest_add_data_func(const char *str, const void *data,
+ void (*fn)(const void *))
{
gchar *path = g_strdup_printf("/%s/%s", qtest_get_arch(), str);
g_test_add_data_func(path, data, fn);