diff options
Diffstat (limited to 'tests/qtest/libqtest.c')
-rw-r--r-- | tests/qtest/libqtest.c | 205 |
1 files changed, 1 insertions, 204 deletions
diff --git a/tests/qtest/libqtest.c b/tests/qtest/libqtest.c index aaf5ab0ca5..228357f1ea 100644 --- a/tests/qtest/libqtest.c +++ b/tests/qtest/libqtest.c @@ -21,10 +21,9 @@ #include <sys/un.h> #include "libqtest.h" +#include "libqmp.h" #include "qemu/ctype.h" #include "qemu/cutils.h" -#include "qapi/error.h" -#include "qapi/qmp/json-parser.h" #include "qapi/qmp/qdict.h" #include "qapi/qmp/qjson.h" #include "qapi/qmp/qlist.h" @@ -32,8 +31,6 @@ #define MAX_IRQ 256 #define SOCKET_TIMEOUT 50 -#define SOCKET_MAX_FDS 16 - typedef void (*QTestSendFn)(QTestState *s, const char *buf); typedef void (*ExternalSendFn)(void *s, const char *buf); @@ -440,40 +437,6 @@ static void G_GNUC_PRINTF(2, 3) qtest_sendf(QTestState *s, const char *fmt, ...) g_free(str); } -/* Sends a message and file descriptors to the socket. - * It's needed for qmp-commands like getfd/add-fd */ -static void socket_send_fds(int socket_fd, int *fds, size_t fds_num, - const char *buf, size_t buf_size) -{ - ssize_t ret; - struct msghdr msg = { 0 }; - char control[CMSG_SPACE(sizeof(int) * SOCKET_MAX_FDS)] = { 0 }; - size_t fdsize = sizeof(int) * fds_num; - struct cmsghdr *cmsg; - struct iovec iov = { .iov_base = (char *)buf, .iov_len = buf_size }; - - msg.msg_iov = &iov; - msg.msg_iovlen = 1; - - if (fds && fds_num > 0) { - g_assert_cmpuint(fds_num, <, SOCKET_MAX_FDS); - - msg.msg_control = control; - msg.msg_controllen = CMSG_SPACE(fdsize); - - cmsg = CMSG_FIRSTHDR(&msg); - cmsg->cmsg_len = CMSG_LEN(fdsize); - cmsg->cmsg_level = SOL_SOCKET; - cmsg->cmsg_type = SCM_RIGHTS; - memcpy(CMSG_DATA(cmsg), fds, fdsize); - } - - do { - ret = sendmsg(socket_fd, &msg, 0); - } while (ret < 0 && errno == EINTR); - g_assert_cmpint(ret, >, 0); -} - static GString *qtest_client_socket_recv_line(QTestState *s) { GString *line; @@ -568,62 +531,6 @@ static int qtest_query_target_endianness(QTestState *s) return big_endian; } -typedef struct { - JSONMessageParser parser; - QDict *response; -} QMPResponseParser; - -static void qmp_response(void *opaque, QObject *obj, Error *err) -{ - QMPResponseParser *qmp = opaque; - - assert(!obj != !err); - - if (err) { - error_prepend(&err, "QMP JSON response parsing failed: "); - error_report_err(err); - abort(); - } - - g_assert(!qmp->response); - qmp->response = qobject_to(QDict, obj); - g_assert(qmp->response); -} - -QDict *qmp_fd_receive(int fd) -{ - QMPResponseParser qmp; - bool log = getenv("QTEST_LOG") != NULL; - - qmp.response = NULL; - json_message_parser_init(&qmp.parser, qmp_response, &qmp, NULL); - while (!qmp.response) { - ssize_t len; - char c; - - len = read(fd, &c, 1); - if (len == -1 && errno == EINTR) { - continue; - } - - if (len == -1 || len == 0) { - fprintf(stderr, "Broken pipe\n"); - abort(); - } - - if (log) { - g_assert(write(2, &c, 1) == 1); - } - json_message_parser_feed(&qmp.parser, &c, 1); - } - if (log) { - g_assert(write(2, "\n", 1) == 1); - } - json_message_parser_destroy(&qmp.parser); - - return qmp.response; -} - QDict *qtest_qmp_receive(QTestState *s) { while (true) { @@ -664,50 +571,6 @@ int qtest_socket_server(const char *socket_path) return sock; } -/** - * 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 qmp_fd_vsend_fds(int fd, int *fds, size_t fds_num, - const char *fmt, va_list ap) -{ - QObject *qobj; - - /* Going through qobject ensures we escape strings properly */ - qobj = qobject_from_vjsonf_nofail(fmt, ap); - - /* No need to send anything for an empty QObject. */ - if (qobj) { - int log = getenv("QTEST_LOG") != NULL; - GString *str = qobject_to_json(qobj); - - /* - * BUG: QMP doesn't react to input until it sees a newline, an - * object, or an array. Work-around: give it a newline. - */ - g_string_append_c(str, '\n'); - - if (log) { - fprintf(stderr, "%s", str->str); - } - /* Send QMP request */ - if (fds && fds_num > 0) { - socket_send_fds(fd, fds, fds_num, str->str, str->len); - } else { - socket_send(fd, str->str, str->len); - } - - g_string_free(str, true); - qobject_unref(qobj); - } -} - -void qmp_fd_vsend(int fd, const char *fmt, va_list ap) -{ - qmp_fd_vsend_fds(fd, NULL, 0, fmt, ap); -} - void qtest_qmp_vsend_fds(QTestState *s, int *fds, size_t fds_num, const char *fmt, va_list ap) { @@ -719,13 +582,6 @@ void qtest_qmp_vsend(QTestState *s, const char *fmt, va_list ap) qmp_fd_vsend_fds(s->qmp_fd, NULL, 0, fmt, ap); } -QDict *qmp_fdv(int fd, const char *fmt, va_list ap) -{ - qmp_fd_vsend_fds(fd, NULL, 0, fmt, ap); - - return qmp_fd_receive(fd); -} - QDict *qtest_vqmp_fds(QTestState *s, int *fds, size_t fds_num, const char *fmt, va_list ap) { @@ -743,26 +599,6 @@ QDict *qtest_vqmp(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_vsend(fd, fmt, ap); - va_end(ap); -} - QDict *qtest_qmp_fds(QTestState *s, int *fds, size_t fds_num, const char *fmt, ...) { @@ -795,27 +631,6 @@ void qtest_qmp_send(QTestState *s, const char *fmt, ...) va_end(ap); } -void qmp_fd_vsend_raw(int fd, const char *fmt, va_list ap) -{ - bool log = getenv("QTEST_LOG") != NULL; - char *str = g_strdup_vprintf(fmt, ap); - - if (log) { - fprintf(stderr, "%s", str); - } - socket_send(fd, str, strlen(str)); - g_free(str); -} - -void qmp_fd_send_raw(int fd, const char *fmt, ...) -{ - va_list ap; - - va_start(ap, fmt); - qmp_fd_vsend_raw(fd, fmt, ap); - va_end(ap); -} - void qtest_qmp_send_raw(QTestState *s, const char *fmt, ...) { va_list ap; @@ -1539,24 +1354,6 @@ void qtest_qmp_device_del(QTestState *qts, const char *id) qtest_qmp_eventwait(qts, "DEVICE_DELETED"); } -bool qmp_rsp_is_err(QDict *rsp) -{ - QDict *error = qdict_get_qdict(rsp, "error"); - qobject_unref(rsp); - return !!error; -} - -void qmp_expect_error_and_unref(QDict *rsp, const char *class) -{ - QDict *error = qdict_get_qdict(rsp, "error"); - - g_assert_cmpstr(qdict_get_try_str(error, "class"), ==, class); - g_assert_nonnull(qdict_get_try_str(error, "desc")); - g_assert(!qdict_haskey(rsp, "return")); - - qobject_unref(rsp); -} - static void qtest_client_set_tx_handler(QTestState *s, QTestSendFn send) { |