The qobject_from_jsonv() function implements a pseudo-printf language for creating a QObject through the extension of dynamic JSON; however, it is hard-coded to only parse a subset of formats understood by -Wformat and is not a straight synonym to bare printf(). During a recent cleanup due to problems caused by PRId64, it was questioned whether the maintenance burden of keeping the dynamic JSON extension can be counterbalanced by converting code to use alternative ways of describing QObject.
This particular patch just adds a couple of convenience methods, based on the observation that most testsuite use of dynamic JSON is nested within the arguments portion of a larger command dictionary. Separating the task of generating the arguments from the boilerplate of generating the outer dictionary reduces the conversion effort needed in the various clients. Because the hand-built QObject might contain '%' characters embedded in strings, we can't directly convert the QObject to string and pass that as a format argument. So for now, we just use a hack of a format string of "%p" to pass the resulting QObject through various varargs calls and into the dynamic JSON parser, where it will then be regurgitated as the QObject that gets converted into the final string to send over the wire. A later patch will clean up libqtest to accept direct string commands, at which point we can tweak qmp_cmd() to avoid the extra no-op trip through the JSON parser. Signed-off-by: Eric Blake <ebl...@redhat.com> --- tests/libqtest.h | 31 +++++++++++++++++++++++++++++++ tests/libqtest.c | 26 ++++++++++++++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/tests/libqtest.h b/tests/libqtest.h index 90f182e..07ddaa2 100644 --- a/tests/libqtest.h +++ b/tests/libqtest.h @@ -58,6 +58,17 @@ void qtest_qmp_discard_response(QTestState *s, const char *fmt, ...); QDict *qtest_qmp(QTestState *s, const char *fmt, ...); /** + * qtest_qmp_cmd: + * @s: #QTestState instance to operate on. + * @cmd: Command name to send + * @args: Arguments to transfer to the command, or NULL. + * + * Sends a QMP message to QEMU and returns the response. Calling this will + * reduce the reference count of @args. + */ +QDict *qtest_qmp_cmd(QTestState *s, const char *cmd, QDict *args); + +/** * qtest_async_qmp: * @s: #QTestState instance to operate on. * @fmt...: QMP message to send to qemu @@ -532,6 +543,16 @@ static inline void qtest_end(void) QDict *qmp(const char *fmt, ...); /** + * qmp_cmd: + * @cmd: Command name to send + * @args: Arguments to transfer to the command, or NULL. + * + * Sends a QMP message to QEMU and returns the response. Calling this will + * reduce the reference count of @args. + */ +QDict *qmp_cmd(const char *cmd, QDict *args); + +/** * qmp_async: * @fmt...: QMP message to send to qemu * @@ -548,6 +569,16 @@ void qmp_async(const char *fmt, ...); void qmp_discard_response(const char *fmt, ...); /** + * qmp_cmd_discard_response: + * @cmd: Command name to send + * @args: Arguments to transfer to the command, or NULL. + * + * Sends a QMP message to QEMU and consumes the response. Calling this will + * reduce the reference count of @args. + */ +void qmp_cmd_discard_response(const char *cmd, QDict *args); + +/** * qmp_receive: * * Reads a QMP message from QEMU and returns the response. diff --git a/tests/libqtest.c b/tests/libqtest.c index 429aaec..0796bb0 100644 --- a/tests/libqtest.c +++ b/tests/libqtest.c @@ -515,6 +515,18 @@ QDict *qtest_qmp(QTestState *s, const char *fmt, ...) return response; } +QDict *qtest_qmp_cmd(QTestState *s, const char *cmd, QDict *args) +{ + QDict *dict = qdict_new(); + + if (!args) { + args = qdict_new(); + } + qdict_put_str(dict, "execute", cmd); + qdict_put(dict, "arguments", args); + return qtest_qmp(s, "%p", QOBJECT(dict)); +} + void qtest_async_qmp(QTestState *s, const char *fmt, ...) { va_list ap; @@ -894,6 +906,11 @@ QDict *qmp(const char *fmt, ...) return response; } +QDict *qmp_cmd(const char *cmd, QDict *args) +{ + return qtest_qmp_cmd(global_qtest, cmd, args); +} + void qmp_async(const char *fmt, ...) { va_list ap; @@ -911,6 +928,15 @@ void qmp_discard_response(const char *fmt, ...) qtest_qmpv_discard_response(global_qtest, fmt, ap); va_end(ap); } + +void qmp_cmd_discard_response(const char *cmd, QDict *args) +{ + QDict *response; + + response = qmp_cmd(cmd, args); + QDECREF(response); +} + char *hmp(const char *fmt, ...) { va_list ap; -- 2.7.4