From fa15cf8b5c77fc5837bbd67066735b6da5b00ee2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= Date: Mon, 26 Mar 2018 19:20:41 +0200 Subject: qmp-test: fix response leak MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Apparently introduced in commit a4f90923b520f1dc0a768634877eb412e5052c26. Signed-off-by: Marc-André Lureau Message-Id: <20180326172041.21009-1-marcandre.lureau@redhat.com> Reviewed-by: Eric Blake Signed-off-by: Eric Blake --- tests/qmp-test.c | 1 + 1 file changed, 1 insertion(+) (limited to 'tests') diff --git a/tests/qmp-test.c b/tests/qmp-test.c index 558e83540c..8de99a4727 100644 --- a/tests/qmp-test.c +++ b/tests/qmp-test.c @@ -90,6 +90,7 @@ static void test_qmp_protocol(void) test_version(qdict_get(q, "version")); capabilities = qdict_get_qlist(q, "capabilities"); g_assert(capabilities && qlist_empty(capabilities)); + QDECREF(resp); /* Test valid command before handshake */ resp = qtest_qmp(qts, "{ 'execute': 'query-version' }"); -- cgit v1.2.1 From fdf235ba15167faa05fedb838562fc06e238f400 Mon Sep 17 00:00:00 2001 From: Eric Blake Date: Fri, 23 Mar 2018 15:43:41 -0500 Subject: tests: Silence false positive warning on generated test name MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Running 'make check' on rawhide with gcc 8.0.1 fails: tests/test-visitor-serialization.c: In function 'main': tests/test-visitor-serialization.c:1127:34: error: '/primitives/' directive writing 12 bytes into a region of size between 1 and 128 [-Werror=format-overflow=] The warning is a false positive (we have two buffers of size 128, so yes, if we FULLY used the first buffer, then sprint'ing it into the second will overflow the second). But in practice, our first buffer will not be longer than "/visitor/serialization/String", so sizing it smaller is enough to let gcc see that we don't overflow the second. Signed-off-by: Eric Blake Message-Id: <20180323204341.1501664-1-eblake@redhat.com> Reviewed-by: Marc-André Lureau --- tests/test-visitor-serialization.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'tests') diff --git a/tests/test-visitor-serialization.c b/tests/test-visitor-serialization.c index 438c18a0d6..d18d90db2c 100644 --- a/tests/test-visitor-serialization.c +++ b/tests/test-visitor-serialization.c @@ -1115,7 +1115,7 @@ static const SerializeOps visitors[] = { static void add_visitor_type(const SerializeOps *ops) { - char testname_prefix[128]; + char testname_prefix[32]; char testname[128]; TestArgs *args; int i = 0; -- cgit v1.2.1 From 4bebca1e429a276bf9553dc2221862d2ea23a939 Mon Sep 17 00:00:00 2001 From: Peter Xu Date: Mon, 26 Mar 2018 14:38:58 +0800 Subject: tests: let qapi-schema tests detect oob MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The allow_oob parameter was passed in but not used in tests. Now reflect that in the tests, so we need to touch up other command testers with that new change. Reviewed-by: Eric Blake Signed-off-by: Peter Xu Message-Id: <20180326063901.27425-6-peterx@redhat.com> Reviewed-by: Marc-André Lureau Signed-off-by: Eric Blake --- tests/qapi-schema/doc-good.out | 4 ++-- tests/qapi-schema/ident-with-escape.out | 2 +- tests/qapi-schema/indented-expr.out | 4 ++-- tests/qapi-schema/qapi-schema-test.out | 18 +++++++++--------- tests/qapi-schema/test-qapi.py | 4 ++-- 5 files changed, 16 insertions(+), 16 deletions(-) (limited to 'tests') diff --git a/tests/qapi-schema/doc-good.out b/tests/qapi-schema/doc-good.out index 430b5a87db..63058b1590 100644 --- a/tests/qapi-schema/doc-good.out +++ b/tests/qapi-schema/doc-good.out @@ -28,9 +28,9 @@ object q_obj_cmd-arg member arg2: str optional=True member arg3: bool optional=False command cmd q_obj_cmd-arg -> Object - gen=True success_response=True boxed=False + gen=True success_response=True boxed=False oob=False command cmd-boxed Object -> None - gen=True success_response=True boxed=True + gen=True success_response=True boxed=True oob=False doc freeform body= = Section diff --git a/tests/qapi-schema/ident-with-escape.out b/tests/qapi-schema/ident-with-escape.out index ee3b34e623..82213aa51d 100644 --- a/tests/qapi-schema/ident-with-escape.out +++ b/tests/qapi-schema/ident-with-escape.out @@ -5,4 +5,4 @@ module ident-with-escape.json object q_obj_fooA-arg member bar1: str optional=False command fooA q_obj_fooA-arg -> None - gen=True success_response=True boxed=False + gen=True success_response=True boxed=False oob=False diff --git a/tests/qapi-schema/indented-expr.out b/tests/qapi-schema/indented-expr.out index a79935e8c3..862678f8f4 100644 --- a/tests/qapi-schema/indented-expr.out +++ b/tests/qapi-schema/indented-expr.out @@ -3,6 +3,6 @@ enum QType ['none', 'qnull', 'qnum', 'qstring', 'qdict', 'qlist', 'qbool'] prefix QTYPE module indented-expr.json command eins None -> None - gen=True success_response=True boxed=False + gen=True success_response=True boxed=False oob=False command zwei None -> None - gen=True success_response=True boxed=False + gen=True success_response=True boxed=False oob=False diff --git a/tests/qapi-schema/qapi-schema-test.out b/tests/qapi-schema/qapi-schema-test.out index 012e7fc06a..4f43370017 100644 --- a/tests/qapi-schema/qapi-schema-test.out +++ b/tests/qapi-schema/qapi-schema-test.out @@ -16,7 +16,7 @@ object Empty1 object Empty2 base Empty1 command user_def_cmd0 Empty2 -> Empty2 - gen=True success_response=True boxed=False + gen=True success_response=True boxed=False oob=False enum QEnumTwo ['value1', 'value2'] prefix QENUM_TWO object UserDefOne @@ -143,29 +143,29 @@ object UserDefNativeListUnion case sizes: q_obj_sizeList-wrapper case any: q_obj_anyList-wrapper command user_def_cmd None -> None - gen=True success_response=True boxed=False + gen=True success_response=True boxed=False oob=False object q_obj_user_def_cmd1-arg member ud1a: UserDefOne optional=False command user_def_cmd1 q_obj_user_def_cmd1-arg -> None - gen=True success_response=True boxed=False + gen=True success_response=True boxed=False oob=False object q_obj_user_def_cmd2-arg member ud1a: UserDefOne optional=False member ud1b: UserDefOne optional=True command user_def_cmd2 q_obj_user_def_cmd2-arg -> UserDefTwo - gen=True success_response=True boxed=False + gen=True success_response=True boxed=False oob=False object q_obj_guest-get-time-arg member a: int optional=False member b: int optional=True command guest-get-time q_obj_guest-get-time-arg -> int - gen=True success_response=True boxed=False + gen=True success_response=True boxed=False oob=False object q_obj_guest-sync-arg member arg: any optional=False command guest-sync q_obj_guest-sync-arg -> any - gen=True success_response=True boxed=False + gen=True success_response=True boxed=False oob=False command boxed-struct UserDefZero -> None - gen=True success_response=True boxed=True + gen=True success_response=True boxed=True oob=False command boxed-union UserDefNativeListUnion -> None - gen=True success_response=True boxed=True + gen=True success_response=True boxed=True oob=False object UserDefOptions member i64: intList optional=True member u64: uint64List optional=True @@ -229,4 +229,4 @@ object q_obj___org.qemu_x-command-arg member c: __org.qemu_x-Union2 optional=False member d: __org.qemu_x-Alt optional=False command __org.qemu_x-command q_obj___org.qemu_x-command-arg -> __org.qemu_x-Union1 - gen=True success_response=True boxed=False + gen=True success_response=True boxed=False oob=False diff --git a/tests/qapi-schema/test-qapi.py b/tests/qapi-schema/test-qapi.py index 10e68b01d9..c1a144ba29 100644 --- a/tests/qapi-schema/test-qapi.py +++ b/tests/qapi-schema/test-qapi.py @@ -45,8 +45,8 @@ class QAPISchemaTestVisitor(QAPISchemaVisitor): gen, success_response, boxed, allow_oob): print('command %s %s -> %s' % \ (name, arg_type and arg_type.name, ret_type and ret_type.name)) - print(' gen=%s success_response=%s boxed=%s' % \ - (gen, success_response, boxed)) + print(' gen=%s success_response=%s boxed=%s oob=%s' % \ + (gen, success_response, boxed, allow_oob)) def visit_event(self, name, info, arg_type, boxed): print('event %s %s' % (name, arg_type and arg_type.name)) -- cgit v1.2.1 From 1a1b11dc0fb519f6dbc420925bde032e772fd610 Mon Sep 17 00:00:00 2001 From: Peter Xu Date: Mon, 26 Mar 2018 14:38:59 +0800 Subject: tests: add oob-test for qapi-schema MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit It simply tests the new OOB capability, and make sure the QAPISchema can parse it correctly. Signed-off-by: Peter Xu Message-Id: <20180326063901.27425-7-peterx@redhat.com> Reviewed-by: Marc-André Lureau Reviewed-by: Eric Blake Signed-off-by: Eric Blake --- tests/Makefile.include | 1 + tests/qapi-schema/oob-test.err | 1 + tests/qapi-schema/oob-test.exit | 1 + tests/qapi-schema/oob-test.json | 2 ++ tests/qapi-schema/oob-test.out | 0 tests/qapi-schema/qapi-schema-test.json | 3 +++ tests/qapi-schema/qapi-schema-test.out | 2 ++ tests/test-qmp-cmds.c | 4 ++++ 8 files changed, 14 insertions(+) create mode 100644 tests/qapi-schema/oob-test.err create mode 100644 tests/qapi-schema/oob-test.exit create mode 100644 tests/qapi-schema/oob-test.json create mode 100644 tests/qapi-schema/oob-test.out (limited to 'tests') diff --git a/tests/Makefile.include b/tests/Makefile.include index eb218a9539..3b9a5e31a2 100644 --- a/tests/Makefile.include +++ b/tests/Makefile.include @@ -523,6 +523,7 @@ qapi-schema += missing-comma-object.json qapi-schema += missing-type.json qapi-schema += nested-struct-data.json qapi-schema += non-objects.json +qapi-schema += oob-test.json qapi-schema += pragma-doc-required-crap.json qapi-schema += pragma-extra-junk.json qapi-schema += pragma-name-case-whitelist-crap.json diff --git a/tests/qapi-schema/oob-test.err b/tests/qapi-schema/oob-test.err new file mode 100644 index 0000000000..35b60f7480 --- /dev/null +++ b/tests/qapi-schema/oob-test.err @@ -0,0 +1 @@ +tests/qapi-schema/oob-test.json:2: 'allow-oob' of command 'oob-command-1' should only use true value diff --git a/tests/qapi-schema/oob-test.exit b/tests/qapi-schema/oob-test.exit new file mode 100644 index 0000000000..d00491fd7e --- /dev/null +++ b/tests/qapi-schema/oob-test.exit @@ -0,0 +1 @@ +1 diff --git a/tests/qapi-schema/oob-test.json b/tests/qapi-schema/oob-test.json new file mode 100644 index 0000000000..da9635920f --- /dev/null +++ b/tests/qapi-schema/oob-test.json @@ -0,0 +1,2 @@ +# Check against oob illegal value +{ 'command': 'oob-command-1', 'allow-oob': 'some-string' } diff --git a/tests/qapi-schema/oob-test.out b/tests/qapi-schema/oob-test.out new file mode 100644 index 0000000000..e69de29bb2 diff --git a/tests/qapi-schema/qapi-schema-test.json b/tests/qapi-schema/qapi-schema-test.json index c72dbd8050..06e30f452e 100644 --- a/tests/qapi-schema/qapi-schema-test.json +++ b/tests/qapi-schema/qapi-schema-test.json @@ -139,6 +139,9 @@ { 'command': 'boxed-struct', 'boxed': true, 'data': 'UserDefZero' } { 'command': 'boxed-union', 'data': 'UserDefNativeListUnion', 'boxed': true } +# Smoke test on Out-Of-Band +{ 'command': 'an-oob-command', 'allow-oob': true } + # For testing integer range flattening in opts-visitor. The following schema # corresponds to the option format: # diff --git a/tests/qapi-schema/qapi-schema-test.out b/tests/qapi-schema/qapi-schema-test.out index 4f43370017..467577d770 100644 --- a/tests/qapi-schema/qapi-schema-test.out +++ b/tests/qapi-schema/qapi-schema-test.out @@ -166,6 +166,8 @@ command boxed-struct UserDefZero -> None gen=True success_response=True boxed=True oob=False command boxed-union UserDefNativeListUnion -> None gen=True success_response=True boxed=True oob=False +command an-oob-command None -> None + gen=True success_response=True boxed=False oob=True object UserDefOptions member i64: intList optional=True member u64: uint64List optional=True diff --git a/tests/test-qmp-cmds.c b/tests/test-qmp-cmds.c index 93fbbb1b73..db690cc5ae 100644 --- a/tests/test-qmp-cmds.c +++ b/tests/test-qmp-cmds.c @@ -16,6 +16,10 @@ void qmp_user_def_cmd(Error **errp) { } +void qmp_an_oob_command(Error **errp) +{ +} + Empty2 *qmp_user_def_cmd0(Error **errp) { return g_new0(Empty2, 1); -- cgit v1.2.1 From ddee57e0176f6ab53b13c6c97605b62737a8fd7a Mon Sep 17 00:00:00 2001 From: Eric Blake Date: Mon, 26 Mar 2018 20:36:19 -0500 Subject: tests: Add parameter to qtest_init_without_qmp_handshake MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Allow callers to choose whether to allow OOB support during a test; for now, all existing callers pass false, but the next patch will add a new caller. Also, rewrite the monitor setup to be generic (using the -qmp shorthand is insufficient for honoring the parameter). Based on an idea by Peter Xu, in <20180326063901.27425-8-peterx@redhat.com> Signed-off-by: Eric Blake Message-Id: <20180327013620.1644387-4-eblake@redhat.com> Tested-by: Christian Borntraeger Acked-by: Peter Xu Reviewed-by: Marc-André Lureau --- tests/libqtest.c | 10 ++++++---- tests/libqtest.h | 7 +++++-- tests/qmp-test.c | 2 +- 3 files changed, 12 insertions(+), 7 deletions(-) (limited to 'tests') diff --git a/tests/libqtest.c b/tests/libqtest.c index 200b2b9e92..6f33a37667 100644 --- a/tests/libqtest.c +++ b/tests/libqtest.c @@ -166,7 +166,8 @@ static const char *qtest_qemu_binary(void) return qemu_bin; } -QTestState *qtest_init_without_qmp_handshake(const char *extra_args) +QTestState *qtest_init_without_qmp_handshake(bool use_oob, + const char *extra_args) { QTestState *s; int sock, qmpsock, i; @@ -199,12 +200,13 @@ QTestState *qtest_init_without_qmp_handshake(const char *extra_args) command = g_strdup_printf("exec %s " "-qtest unix:%s,nowait " "-qtest-log %s " - "-qmp unix:%s,nowait " + "-chardev socket,path=%s,nowait,id=char0 " + "-mon chardev=char0,mode=control%s " "-machine accel=qtest " "-display none " "%s", qemu_binary, socket_path, getenv("QTEST_LOG") ? "/dev/fd/2" : "/dev/null", - qmp_socket_path, + qmp_socket_path, use_oob ? ",x-oob=on" : "", extra_args ?: ""); execlp("/bin/sh", "sh", "-c", command, NULL); exit(1); @@ -239,7 +241,7 @@ QTestState *qtest_init_without_qmp_handshake(const char *extra_args) QTestState *qtest_init(const char *extra_args) { - QTestState *s = qtest_init_without_qmp_handshake(extra_args); + QTestState *s = qtest_init_without_qmp_handshake(false, extra_args); /* Read the QMP greeting and then do the handshake */ qtest_qmp_discard_response(s, ""); diff --git a/tests/libqtest.h b/tests/libqtest.h index 811169453a..cbe8df4473 100644 --- a/tests/libqtest.h +++ b/tests/libqtest.h @@ -56,11 +56,14 @@ QTestState *qtest_init(const char *extra_args); /** * qtest_init_without_qmp_handshake: - * @extra_args: other arguments to pass to QEMU. + * @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. * * Returns: #QTestState instance. */ -QTestState *qtest_init_without_qmp_handshake(const char *extra_args); +QTestState *qtest_init_without_qmp_handshake(bool use_oob, + const char *extra_args); /** * qtest_quit: diff --git a/tests/qmp-test.c b/tests/qmp-test.c index 8de99a4727..2134d95db9 100644 --- a/tests/qmp-test.c +++ b/tests/qmp-test.c @@ -81,7 +81,7 @@ static void test_qmp_protocol(void) QList *capabilities; QTestState *qts; - qts = qtest_init_without_qmp_handshake(common_args); + qts = qtest_init_without_qmp_handshake(false, common_args); /* Test greeting */ resp = qtest_qmp_receive(qts); -- cgit v1.2.1 From fa198ad9bdef7303d4e3613c69ea00eece6b3a75 Mon Sep 17 00:00:00 2001 From: Peter Xu Date: Mon, 26 Mar 2018 14:39:01 +0800 Subject: tests: qmp-test: add test for new "x-oob" MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Test the new OOB capability. It's mostly the reverted OOB test (see commit 4fd78ad7), but differs in that: - It uses the new qtest_init_without_qmp_handshake() parameter to create the monitor with "x-oob" - Squashed the capability tests on greeting message - Don't use qtest_global any more, instead use self-maintained QTestState, which is the trend Signed-off-by: Peter Xu Message-Id: <20180326063901.27425-9-peterx@redhat.com> Reviewed-by: Eric Blake [eblake: rebase to qtest_init changes] Reviewed-by: Marc-André Lureau Tested-by: Christian Borntraeger Signed-off-by: Eric Blake --- tests/qmp-test.c | 82 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 82 insertions(+) (limited to 'tests') diff --git a/tests/qmp-test.c b/tests/qmp-test.c index 2134d95db9..772058fc4c 100644 --- a/tests/qmp-test.c +++ b/tests/qmp-test.c @@ -135,6 +135,87 @@ static void test_qmp_protocol(void) qtest_quit(qts); } +/* Tests for Out-Of-Band support. */ +static void test_qmp_oob(void) +{ + QTestState *qts; + QDict *resp, *q; + int acks = 0; + const QListEntry *entry; + QList *capabilities; + QString *qstr; + const char *cmd_id; + + qts = qtest_init_without_qmp_handshake(true, common_args); + + /* Check the greeting message. */ + resp = qtest_qmp_receive(qts); + q = qdict_get_qdict(resp, "QMP"); + g_assert(q); + capabilities = qdict_get_qlist(q, "capabilities"); + g_assert(capabilities && !qlist_empty(capabilities)); + entry = qlist_first(capabilities); + g_assert(entry); + qstr = qobject_to(QString, entry->value); + g_assert(qstr); + g_assert_cmpstr(qstring_get_str(qstr), ==, "oob"); + QDECREF(resp); + + /* Try a fake capability, it should fail. */ + resp = qtest_qmp(qts, + "{ 'execute': 'qmp_capabilities', " + " 'arguments': { 'enable': [ 'cap-does-not-exist' ] } }"); + g_assert(qdict_haskey(resp, "error")); + QDECREF(resp); + + /* Now, enable OOB in current QMP session, it should succeed. */ + resp = qtest_qmp(qts, + "{ 'execute': 'qmp_capabilities', " + " 'arguments': { 'enable': [ 'oob' ] } }"); + g_assert(qdict_haskey(resp, "return")); + QDECREF(resp); + + /* + * Try any command that does not support OOB but with OOB flag. We + * should get failure. + */ + resp = qtest_qmp(qts, + "{ 'execute': 'query-cpus'," + " 'control': { 'run-oob': true } }"); + g_assert(qdict_haskey(resp, "error")); + QDECREF(resp); + + /* + * First send the "x-oob-test" command with lock=true and + * oob=false, it should hang the dispatcher and main thread; + * later, we send another lock=false with oob=true to continue + * that thread processing. Finally we should receive replies from + * both commands. + */ + qtest_async_qmp(qts, + "{ 'execute': 'x-oob-test'," + " 'arguments': { 'lock': true }, " + " 'id': 'lock-cmd'}"); + qtest_async_qmp(qts, + "{ 'execute': 'x-oob-test', " + " 'arguments': { 'lock': false }, " + " 'control': { 'run-oob': true }, " + " 'id': 'unlock-cmd' }"); + + /* Ignore all events. Wait for 2 acks */ + while (acks < 2) { + resp = qtest_qmp_receive(qts); + cmd_id = qdict_get_str(resp, "id"); + if (!g_strcmp0(cmd_id, "lock-cmd") || + !g_strcmp0(cmd_id, "unlock-cmd")) { + acks++; + } + QDECREF(resp); + } + + qtest_quit(qts); +} + static int query_error_class(const char *cmd) { static struct { @@ -319,6 +400,7 @@ int main(int argc, char *argv[]) g_test_init(&argc, &argv, NULL); qtest_add_func("qmp/protocol", test_qmp_protocol); + qtest_add_func("qmp/oob", test_qmp_oob); qmp_schema_init(&schema); add_query_tests(&schema); -- cgit v1.2.1