#ifndef LIBQTEST_H
#define LIBQTEST_H
-#include "qapi/qmp/qdict.h"
-
typedef struct QTestState QTestState;
extern QTestState *global_qtest;
+/**
+ * qtest_initf:
+ * @fmt...: Format for creating other arguments to pass to QEMU, formatted
+ * like sprintf().
+ *
+ * Convenience wrapper around qtest_start().
+ *
+ * Returns: #QTestState instance.
+ */
+QTestState *qtest_initf(const char *fmt, ...) GCC_FMT_ATTR(1, 2);
+
+/**
+ * qtest_vinitf:
+ * @fmt: Format for creating other arguments to pass to QEMU, formatted
+ * like vsprintf().
+ * @ap: Format arguments.
+ *
+ * Convenience wrapper around qtest_start().
+ *
+ * Returns: #QTestState instance.
+ */
+QTestState *qtest_vinitf(const char *fmt, va_list ap) GCC_FMT_ATTR(1, 0);
+
/**
* qtest_init:
- * @extra_args: other arguments to pass to QEMU.
+ * @extra_args: other arguments to pass to QEMU. CAUTION: these
+ * arguments are subject to word splitting and shell evaluation.
*
* Returns: #QTestState instance.
*/
QTestState *qtest_init(const char *extra_args);
/**
- * qtest_quit:
- * @s: #QTestState instance to operate on.
+ * qtest_init_without_qmp_handshake:
+ * @use_oob: true to have the server advertise OOB support
+ * @extra_args: other arguments to pass to QEMU. CAUTION: these
+ * arguments are subject to word splitting and shell evaluation.
*
- * Shut down the QEMU process associated to @s.
+ * Returns: #QTestState instance.
*/
-void qtest_quit(QTestState *s);
+QTestState *qtest_init_without_qmp_handshake(bool use_oob,
+ const char *extra_args);
/**
- * qtest_qmp_discard_response:
+ * qtest_quit:
* @s: #QTestState instance to operate on.
- * @fmt...: QMP message to send to qemu
*
- * Sends a QMP message to QEMU and consumes the response.
+ * Shut down the QEMU process associated to @s.
*/
-void qtest_qmp_discard_response(QTestState *s, const char *fmt, ...);
+void qtest_quit(QTestState *s);
/**
* qtest_qmp:
* @s: #QTestState instance to operate on.
- * @fmt...: QMP message to send to qemu
+ * @fmt...: QMP message to send to qemu, formatted like
+ * qobject_from_jsonf_nofail(). See parse_escape() for what's
+ * supported after '%'.
*
* Sends a QMP message to QEMU and returns the response.
*/
-QDict *qtest_qmp(QTestState *s, const char *fmt, ...);
+QDict *qtest_qmp(QTestState *s, const char *fmt, ...)
+ GCC_FMT_ATTR(2, 3);
/**
- * qtest_async_qmp:
+ * qtest_qmp_send:
* @s: #QTestState instance to operate on.
- * @fmt...: QMP message to send to qemu
+ * @fmt...: QMP message to send to qemu, formatted like
+ * qobject_from_jsonf_nofail(). See parse_escape() for what's
+ * supported after '%'.
*
* Sends a QMP message to QEMU and leaves the response in the stream.
*/
-void qtest_async_qmp(QTestState *s, const char *fmt, ...);
+void qtest_qmp_send(QTestState *s, const char *fmt, ...)
+ GCC_FMT_ATTR(2, 3);
/**
- * qtest_qmpv_discard_response:
+ * qtest_qmp_send_raw:
* @s: #QTestState instance to operate on.
- * @fmt: QMP message to send to QEMU
- * @ap: QMP message arguments
+ * @fmt...: text to send, formatted like sprintf()
*
- * Sends a QMP message to QEMU and consumes the response.
+ * Sends text to the QMP monitor verbatim. Need not be valid JSON;
+ * this is useful for negative tests.
*/
-void qtest_qmpv_discard_response(QTestState *s, const char *fmt, va_list ap);
+void qtest_qmp_send_raw(QTestState *s, const char *fmt, ...)
+ GCC_FMT_ATTR(2, 3);
/**
* qtest_qmpv:
* @s: #QTestState instance to operate on.
- * @fmt: QMP message to send to QEMU
+ * @fmt: QMP message to send to QEMU, formatted like
+ * qobject_from_jsonf_nofail(). See parse_escape() for what's
+ * supported after '%'.
* @ap: QMP message arguments
*
* Sends a QMP message to QEMU and returns the response.
*/
-QDict *qtest_qmpv(QTestState *s, const char *fmt, va_list ap);
+QDict *qtest_vqmp(QTestState *s, const char *fmt, va_list ap)
+ GCC_FMT_ATTR(2, 0);
/**
- * qtest_async_qmpv:
+ * qtest_qmp_vsend:
* @s: #QTestState instance to operate on.
- * @fmt: QMP message to send to QEMU
+ * @fmt: QMP message to send to QEMU, formatted like
+ * qobject_from_jsonf_nofail(). See parse_escape() for what's
+ * supported after '%'.
* @ap: QMP message arguments
*
* Sends a QMP message to QEMU and leaves the response in the stream.
*/
-void qtest_async_qmpv(QTestState *s, const char *fmt, va_list ap);
+void qtest_qmp_vsend(QTestState *s, const char *fmt, va_list ap)
+ GCC_FMT_ATTR(2, 0);
/**
* qtest_receive:
* @s: #QTestState instance to operate on.
* @s: #event event to wait for.
*
- * Continuosly polls for QMP responses until it receives the desired event.
+ * Continuously polls for QMP responses until it receives the desired event.
*/
void qtest_qmp_eventwait(QTestState *s, const char *event);
/**
- * qtest_hmpv:
+ * qtest_qmp_eventwait_ref:
* @s: #QTestState instance to operate on.
- * @fmt...: HMP command to send to QEMU
+ * @s: #event event to wait for.
+ *
+ * Continuously polls for QMP responses until it receives the desired event.
+ * Returns a copy of the event for further investigation.
+ */
+QDict *qtest_qmp_eventwait_ref(QTestState *s, const char *event);
+
+/**
+ * qtest_qmp_receive_success:
+ * @s: #QTestState instance to operate on
+ * @event_cb: Event callback
+ * @opaque: Argument for @event_cb
+ *
+ * Poll QMP messages until a command success response is received.
+ * If @event_cb, call it for each event received, passing @opaque,
+ * the event's name and data.
+ * Return the success response's "return" member.
+ */
+QDict *qtest_qmp_receive_success(QTestState *s,
+ void (*event_cb)(void *opaque,
+ const char *name,
+ QDict *data),
+ void *opaque);
+
+/**
+ * qtest_hmp:
+ * @s: #QTestState instance to operate on.
+ * @fmt...: HMP command to send to QEMU, formats arguments like sprintf().
*
* Send HMP command to QEMU via QMP's human-monitor-command.
+ * QMP events are discarded.
*
* Returns: the command's output. The caller should g_free() it.
*/
-char *qtest_hmp(QTestState *s, const char *fmt, ...);
+char *qtest_hmp(QTestState *s, const char *fmt, ...) GCC_FMT_ATTR(2, 3);
/**
* qtest_hmpv:
* @s: #QTestState instance to operate on.
- * @fmt: HMP command to send to QEMU
+ * @fmt: HMP command to send to QEMU, formats arguments like vsprintf().
* @ap: HMP command arguments
*
* Send HMP command to QEMU via QMP's human-monitor-command.
+ * QMP events are discarded.
*
* Returns: the command's output. The caller should g_free() it.
*/
-char *qtest_hmpv(QTestState *s, const char *fmt, va_list ap);
+char *qtest_vhmp(QTestState *s, const char *fmt, va_list ap)
+ GCC_FMT_ATTR(2, 0);
/**
* qtest_get_irq:
*/
void qtest_memread(QTestState *s, uint64_t addr, void *data, size_t size);
+/**
+ * qtest_rtas_call:
+ * @s: #QTestState instance to operate on.
+ * @name: name of the command to call.
+ * @nargs: Number of args.
+ * @args: Guest address to read args from.
+ * @nret: Number of return value.
+ * @ret: Guest address to write return values to.
+ *
+ * Call an RTAS function
+ */
+uint64_t qtest_rtas_call(QTestState *s, const char *name,
+ uint32_t nargs, uint64_t args,
+ uint32_t nret, uint64_t ret);
+
/**
* qtest_bufread:
* @s: #QTestState instance to operate on.
*/
int64_t qtest_clock_set(QTestState *s, int64_t val);
+/**
+ * qtest_big_endian:
+ * @s: QTestState instance to operate on.
+ *
+ * Returns: True if the architecture under test has a big endian configuration.
+ */
+bool qtest_big_endian(QTestState *s);
+
/**
* qtest_get_arch:
*
/**
* qmp:
- * @fmt...: QMP message to send to qemu
+ * @fmt...: QMP message to send to qemu, formatted like
+ * qobject_from_jsonf_nofail(). See parse_escape() for what's
+ * supported after '%'.
*
* Sends a QMP message to QEMU and returns the response.
*/
-QDict *qmp(const char *fmt, ...);
+QDict *qmp(const char *fmt, ...) GCC_FMT_ATTR(1, 2);
/**
- * qmp_async:
- * @fmt...: QMP message to send to qemu
+ * qmp_send:
+ * @fmt...: QMP message to send to qemu, formatted like
+ * qobject_from_jsonf_nofail(). See parse_escape() for what's
+ * supported after '%'.
*
* Sends a QMP message to QEMU and leaves the response in the stream.
*/
-void qmp_async(const char *fmt, ...);
-
-/**
- * qmp_discard_response:
- * @fmt...: QMP message to send to qemu
- *
- * Sends a QMP message to QEMU and consumes the response.
- */
-void qmp_discard_response(const char *fmt, ...);
+void qmp_send(const char *fmt, ...) GCC_FMT_ATTR(1, 2);
/**
* qmp_receive:
* qmp_eventwait:
* @s: #event event to wait for.
*
- * Continuosly polls for QMP responses until it receives the desired event.
+ * Continuously polls for QMP responses until it receives the desired event.
*/
static inline void qmp_eventwait(const char *event)
{
return qtest_qmp_eventwait(global_qtest, event);
}
+/**
+ * qmp_eventwait_ref:
+ * @s: #event event to wait for.
+ *
+ * Continuously polls for QMP responses until it receives the desired event.
+ * Returns a copy of the event for further investigation.
+ */
+static inline QDict *qmp_eventwait_ref(const char *event)
+{
+ return qtest_qmp_eventwait_ref(global_qtest, event);
+}
+
/**
* hmp:
- * @fmt...: HMP command to send to QEMU
+ * @fmt...: HMP command to send to QEMU, formats arguments like sprintf().
*
* Send HMP command to QEMU via QMP's human-monitor-command.
*
* Returns: the command's output. The caller should g_free() it.
*/
-char *hmp(const char *fmt, ...);
+char *hmp(const char *fmt, ...) GCC_FMT_ATTR(1, 2);
/**
* get_irq:
return qtest_clock_set(global_qtest, val);
}
+QDict *qmp_fd_receive(int fd);
+void qmp_fd_vsend(int fd, const char *fmt, va_list ap) GCC_FMT_ATTR(2, 0);
+void qmp_fd_send(int fd, const char *fmt, ...) GCC_FMT_ATTR(2, 3);
+void qmp_fd_send_raw(int fd, const char *fmt, ...) GCC_FMT_ATTR(2, 3);
+void qmp_fd_vsend_raw(int fd, const char *fmt, va_list ap) GCC_FMT_ATTR(2, 0);
+QDict *qmp_fdv(int fd, const char *fmt, va_list ap) GCC_FMT_ATTR(2, 0);
+QDict *qmp_fd(int fd, const char *fmt, ...) GCC_FMT_ATTR(2, 3);
+
/**
- * qtest_big_endian:
+ * qtest_cb_for_every_machine:
+ * @cb: Pointer to the callback function
+ * @skip_old_versioned: true if versioned old machine types should be skipped
*
- * Returns: True if the architecture under test has a big endian configuration.
+ * Call a callback function for every name of all available machines.
*/
-bool qtest_big_endian(void);
+void qtest_cb_for_every_machine(void (*cb)(const char *machine),
+ bool skip_old_versioned);
+/**
+ * qtest_qmp_device_add:
+ * @driver: Name of the device that should be added
+ * @id: Identification string
+ * @fmt...: QMP message to send to qemu, formatted like
+ * qobject_from_jsonf_nofail(). See parse_escape() for what's
+ * supported after '%'.
+ *
+ * Generic hot-plugging test via the device_add QMP command.
+ */
+void qtest_qmp_device_add(const char *driver, const char *id, const char *fmt,
+ ...) GCC_FMT_ATTR(3, 4);
-QDict *qmp_fd_receive(int fd);
-void qmp_fd_sendv(int fd, const char *fmt, va_list ap);
-void qmp_fd_send(int fd, const char *fmt, ...);
-QDict *qmp_fdv(int fd, const char *fmt, va_list ap);
-QDict *qmp_fd(int fd, const char *fmt, ...);
+/**
+ * qtest_qmp_device_del:
+ * @id: Identification string
+ *
+ * Generic hot-unplugging test via the device_del QMP command.
+ */
+void qtest_qmp_device_del(const char *id);
+
+/**
+ * qmp_rsp_is_err:
+ * @rsp: QMP response to check for error
+ *
+ * Test @rsp for error and discard @rsp.
+ * Returns 'true' if there is error in @rsp and 'false' otherwise.
+ */
+bool qmp_rsp_is_err(QDict *rsp);
+
+/**
+ * qmp_assert_error_class:
+ * @rsp: QMP response to check for error
+ * @class: an error class
+ *
+ * Assert the response has the given error class and discard @rsp.
+ */
+void qmp_assert_error_class(QDict *rsp, const char *class);
#endif