diff mbox series

[v2,05/60] qmp-test: Cover syntax and lexical errors

Message ID 20180817150559.16243-6-armbru@redhat.com
State New
Headers show
Series json: Fixes, error reporting improvements, cleanups | expand

Commit Message

Markus Armbruster Aug. 17, 2018, 3:05 p.m. UTC
Signed-off-by: Markus Armbruster <armbru@redhat.com>
---
 tests/libqtest.c | 17 +++++++++++++++++
 tests/libqtest.h | 11 +++++++++++
 tests/qmp-test.c | 41 ++++++++++++++++++++++++++++++++++++++++-
 3 files changed, 68 insertions(+), 1 deletion(-)

Comments

Eric Blake Aug. 17, 2018, 3:51 p.m. UTC | #1
On 08/17/2018 10:05 AM, Markus Armbruster wrote:
> Signed-off-by: Markus Armbruster <armbru@redhat.com>
> ---

Might be worth mentioning the addition of qtest_qmp_send_raw() in the 
commit message body.

>   tests/libqtest.c | 17 +++++++++++++++++
>   tests/libqtest.h | 11 +++++++++++
>   tests/qmp-test.c | 41 ++++++++++++++++++++++++++++++++++++++++-
>   3 files changed, 68 insertions(+), 1 deletion(-)
> 

> +/**
> + * 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);
> +

Reviewed-by: Eric Blake <eblake@redhat.com>
Markus Armbruster Aug. 20, 2018, 8:34 a.m. UTC | #2
Eric Blake <eblake@redhat.com> writes:

> On 08/17/2018 10:05 AM, Markus Armbruster wrote:
>> Signed-off-by: Markus Armbruster <armbru@redhat.com>
>> ---
>
> Might be worth mentioning the addition of qtest_qmp_send_raw() in the
> commit message body.

I'm adding:

    qmp-test neglects to cover QMP input that isn't valid JSON.  libqtest
    doesn't let us such input.  Add qtest_qmp_send_raw() for this purpose,
    and put it to use in qmp-test.

>>   tests/libqtest.c | 17 +++++++++++++++++
>>   tests/libqtest.h | 11 +++++++++++
>>   tests/qmp-test.c | 41 ++++++++++++++++++++++++++++++++++++++++-
>>   3 files changed, 68 insertions(+), 1 deletion(-)
>>
>
>> +/**
>> + * 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);
>> +
>
> Reviewed-by: Eric Blake <eblake@redhat.com>

Thanks!
diff mbox series

Patch

diff --git a/tests/libqtest.c b/tests/libqtest.c
index 852ccff1ce..dc42347da3 100644
--- a/tests/libqtest.c
+++ b/tests/libqtest.c
@@ -604,6 +604,23 @@  void qtest_qmp_send(QTestState *s, const char *fmt, ...)
     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 *response;
diff --git a/tests/libqtest.h b/tests/libqtest.h
index def1edaafa..1e831973ff 100644
--- a/tests/libqtest.h
+++ b/tests/libqtest.h
@@ -96,6 +96,17 @@  QDict *qtest_qmp(QTestState *s, const char *fmt, ...)
 void qtest_qmp_send(QTestState *s, const char *fmt, ...)
     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:
  * @s: #QTestState instance to operate on.
diff --git a/tests/qmp-test.c b/tests/qmp-test.c
index dbc8f6c16e..17153192fe 100644
--- a/tests/qmp-test.c
+++ b/tests/qmp-test.c
@@ -1,7 +1,7 @@ 
 /*
  * QMP protocol test cases
  *
- * Copyright (c) 2017 Red Hat Inc.
+ * Copyright (c) 2017-2018 Red Hat Inc.
  *
  * Authors:
  *  Markus Armbruster <armbru@redhat.com>
@@ -42,10 +42,49 @@  static void test_version(QObject *version)
     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)
 {
     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 */
     resp = qtest_qmp(qts, "null");
     g_assert_cmpstr(get_error_class(resp), ==, "GenericError");