qmp-test: Cover syntax and lexical errors
qmp-test neglects to cover QMP input that isn't valid JSON. libqtest doesn't let us send such input. Add qtest_qmp_send_raw() for this purpose, and put it to use in qmp-test. Signed-off-by: Markus Armbruster <armbru@redhat.com> Reviewed-by: Eric Blake <eblake@redhat.com> Message-Id: <20180823164025.12553-7-armbru@redhat.com> [Commit message typo fixed]
This commit is contained in:
parent
d93bb9d5c3
commit
aed877c53b
@ -604,6 +604,23 @@ void qtest_qmp_send(QTestState *s, const char *fmt, ...)
|
|||||||
va_end(ap);
|
va_end(ap);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void qtest_qmp_send_raw(QTestState *s, const char *fmt, ...)
|
||||||
|
{
|
||||||
|
bool log = getenv("QTEST_LOG") != NULL;
|
||||||
|
va_list ap;
|
||||||
|
char *str;
|
||||||
|
|
||||||
|
va_start(ap, fmt);
|
||||||
|
str = g_strdup_vprintf(fmt, ap);
|
||||||
|
va_end(ap);
|
||||||
|
|
||||||
|
if (log) {
|
||||||
|
fprintf(stderr, "%s", str);
|
||||||
|
}
|
||||||
|
socket_send(s->qmp_fd, str, strlen(str));
|
||||||
|
g_free(str);
|
||||||
|
}
|
||||||
|
|
||||||
QDict *qtest_qmp_eventwait_ref(QTestState *s, const char *event)
|
QDict *qtest_qmp_eventwait_ref(QTestState *s, const char *event)
|
||||||
{
|
{
|
||||||
QDict *response;
|
QDict *response;
|
||||||
|
@ -96,6 +96,17 @@ QDict *qtest_qmp(QTestState *s, const char *fmt, ...)
|
|||||||
void qtest_qmp_send(QTestState *s, const char *fmt, ...)
|
void qtest_qmp_send(QTestState *s, const char *fmt, ...)
|
||||||
GCC_FMT_ATTR(2, 3);
|
GCC_FMT_ATTR(2, 3);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* qtest_qmp_send_raw:
|
||||||
|
* @s: #QTestState instance to operate on.
|
||||||
|
* @fmt...: text to send, formatted like sprintf()
|
||||||
|
*
|
||||||
|
* Sends text to the QMP monitor verbatim. Need not be valid JSON;
|
||||||
|
* this is useful for negative tests.
|
||||||
|
*/
|
||||||
|
void qtest_qmp_send_raw(QTestState *s, const char *fmt, ...)
|
||||||
|
GCC_FMT_ATTR(2, 3);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* qtest_qmpv:
|
* qtest_qmpv:
|
||||||
* @s: #QTestState instance to operate on.
|
* @s: #QTestState instance to operate on.
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* QMP protocol test cases
|
* QMP protocol test cases
|
||||||
*
|
*
|
||||||
* Copyright (c) 2017 Red Hat Inc.
|
* Copyright (c) 2017-2018 Red Hat Inc.
|
||||||
*
|
*
|
||||||
* Authors:
|
* Authors:
|
||||||
* Markus Armbruster <armbru@redhat.com>
|
* Markus Armbruster <armbru@redhat.com>
|
||||||
@ -42,10 +42,49 @@ static void test_version(QObject *version)
|
|||||||
visit_free(v);
|
visit_free(v);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool recovered(QTestState *qts)
|
||||||
|
{
|
||||||
|
QDict *resp;
|
||||||
|
bool ret;
|
||||||
|
|
||||||
|
resp = qtest_qmp(qts, "{ 'execute': 'no-such-cmd' }");
|
||||||
|
ret = !strcmp(get_error_class(resp), "CommandNotFound");
|
||||||
|
qobject_unref(resp);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
static void test_malformed(QTestState *qts)
|
static void test_malformed(QTestState *qts)
|
||||||
{
|
{
|
||||||
QDict *resp;
|
QDict *resp;
|
||||||
|
|
||||||
|
/* syntax error */
|
||||||
|
qtest_qmp_send_raw(qts, "{]\n");
|
||||||
|
resp = qtest_qmp_receive(qts);
|
||||||
|
g_assert_cmpstr(get_error_class(resp), ==, "GenericError");
|
||||||
|
qobject_unref(resp);
|
||||||
|
g_assert(recovered(qts));
|
||||||
|
|
||||||
|
/* lexical error: impossible byte outside string */
|
||||||
|
qtest_qmp_send_raw(qts, "{\xFF");
|
||||||
|
resp = qtest_qmp_receive(qts);
|
||||||
|
g_assert_cmpstr(get_error_class(resp), ==, "GenericError");
|
||||||
|
qobject_unref(resp);
|
||||||
|
g_assert(recovered(qts));
|
||||||
|
|
||||||
|
/* lexical error: impossible byte in string */
|
||||||
|
qtest_qmp_send_raw(qts, "{'bad \xFF");
|
||||||
|
resp = qtest_qmp_receive(qts);
|
||||||
|
g_assert_cmpstr(get_error_class(resp), ==, "GenericError");
|
||||||
|
qobject_unref(resp);
|
||||||
|
g_assert(recovered(qts));
|
||||||
|
|
||||||
|
/* lexical error: interpolation */
|
||||||
|
qtest_qmp_send_raw(qts, "%%p\n");
|
||||||
|
resp = qtest_qmp_receive(qts);
|
||||||
|
g_assert_cmpstr(get_error_class(resp), ==, "GenericError");
|
||||||
|
qobject_unref(resp);
|
||||||
|
g_assert(recovered(qts));
|
||||||
|
|
||||||
/* Not even a dictionary */
|
/* Not even a dictionary */
|
||||||
resp = qtest_qmp(qts, "null");
|
resp = qtest_qmp(qts, "null");
|
||||||
g_assert_cmpstr(get_error_class(resp), ==, "GenericError");
|
g_assert_cmpstr(get_error_class(resp), ==, "GenericError");
|
||||||
|
Loading…
Reference in New Issue
Block a user