diff options
author | Peter Maydell <peter.maydell@linaro.org> | 2018-05-31 11:12:36 +0100 |
---|---|---|
committer | Peter Maydell <peter.maydell@linaro.org> | 2018-05-31 11:12:36 +0100 |
commit | a3ac12fba028df90f7b3dbec924995c126c41022 (patch) | |
tree | d2b1846376a79fb5e6546910059365af2752e2dc /tests | |
parent | fe817a8a0d4a2face895f692a7e061f0c98412b9 (diff) | |
parent | c35665e1ee3d4344cd5156430ebc92310635f9bd (diff) |
Merge remote-tracking branch 'remotes/ehabkost/tags/numa-next-pull-request' into staging
NUMA queue, 2018-05-30
* New command-line option: --preconfig
This option allows pausing QEMU and allow the configuration
using QMP commands before running board initialization code.
* New QMP set-numa-node, now made possible because of --preconfig
* Small update on -numa error messages
# gpg: Signature made Thu 31 May 2018 00:02:59 BST
# gpg: using RSA key 2807936F984DC5A6
# gpg: Good signature from "Eduardo Habkost <ehabkost@redhat.com>"
# Primary key fingerprint: 5A32 2FD5 ABC4 D3DB ACCF D1AA 2807 936F 984D C5A6
* remotes/ehabkost/tags/numa-next-pull-request:
tests: functional tests for QMP command set-numa-node
qmp: add set-numa-node command
qmp: permit query-hotpluggable-cpus in preconfig state
tests: extend qmp test with preconfig checks
cli: add --preconfig option
tests: qapi-schema tests for allow-preconfig
qapi: introduce new cmd option "allow-preconfig"
hmp: disable monitor in preconfig state
qapi: introduce preconfig runstate
numa: split out NumaOptions parsing into set_numa_options()
numa: postpone options post-processing till machine_run_board_init()
numa: clarify error message when node index is out of range in -numa dist, ...
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Diffstat (limited to 'tests')
-rw-r--r-- | tests/Makefile.include | 1 | ||||
-rw-r--r-- | tests/libqtest.c | 7 | ||||
-rw-r--r-- | tests/libqtest.h | 9 | ||||
-rw-r--r-- | tests/numa-test.c | 61 | ||||
-rw-r--r-- | tests/qapi-schema/allow-preconfig-test.err | 1 | ||||
-rw-r--r-- | tests/qapi-schema/allow-preconfig-test.exit | 1 | ||||
-rw-r--r-- | tests/qapi-schema/allow-preconfig-test.json | 2 | ||||
-rw-r--r-- | tests/qapi-schema/allow-preconfig-test.out | 0 | ||||
-rw-r--r-- | tests/qapi-schema/doc-good.out | 4 | ||||
-rw-r--r-- | tests/qapi-schema/ident-with-escape.out | 2 | ||||
-rw-r--r-- | tests/qapi-schema/indented-expr.out | 4 | ||||
-rw-r--r-- | tests/qapi-schema/qapi-schema-test.json | 4 | ||||
-rw-r--r-- | tests/qapi-schema/qapi-schema-test.out | 22 | ||||
-rw-r--r-- | tests/qapi-schema/test-qapi.py | 8 | ||||
-rw-r--r-- | tests/qmp-test.c | 40 | ||||
-rw-r--r-- | tests/test-qmp-cmds.c | 2 |
16 files changed, 145 insertions, 23 deletions
diff --git a/tests/Makefile.include b/tests/Makefile.include index b499ba1813..86f90c0cb0 100644 --- a/tests/Makefile.include +++ b/tests/Makefile.include @@ -525,6 +525,7 @@ qapi-schema += missing-type.json qapi-schema += nested-struct-data.json qapi-schema += non-objects.json qapi-schema += oob-test.json +qapi-schema += allow-preconfig-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/libqtest.c b/tests/libqtest.c index 43fb97e035..e0ca19dbfe 100644 --- a/tests/libqtest.c +++ b/tests/libqtest.c @@ -1098,3 +1098,10 @@ void qtest_qmp_device_del(const char *id) qobject_unref(response1); qobject_unref(response2); } + +bool qmp_rsp_is_err(QDict *rsp) +{ + QDict *error = qdict_get_qdict(rsp, "error"); + qobject_unref(rsp); + return !!error; +} diff --git a/tests/libqtest.h b/tests/libqtest.h index cbe8df4473..ac52872cbe 100644 --- a/tests/libqtest.h +++ b/tests/libqtest.h @@ -972,4 +972,13 @@ void qtest_qmp_device_add(const char *driver, const char *id, const char *fmt, */ 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); + #endif diff --git a/tests/numa-test.c b/tests/numa-test.c index 169213fc1c..b7a6ef8815 100644 --- a/tests/numa-test.c +++ b/tests/numa-test.c @@ -260,6 +260,66 @@ static void aarch64_numa_cpu(const void *data) g_free(cli); } +static void pc_dynamic_cpu_cfg(const void *data) +{ + QObject *e; + QDict *resp; + QList *cpus; + QTestState *qs; + + qs = qtest_startf("%s %s", data ? (char *)data : "", + "-nodefaults --preconfig -smp 2"); + + /* create 2 numa nodes */ + g_assert(!qmp_rsp_is_err(qtest_qmp(qs, "{ 'execute': 'set-numa-node'," + " 'arguments': { 'type': 'node', 'nodeid': 0 } }"))); + g_assert(!qmp_rsp_is_err(qtest_qmp(qs, "{ 'execute': 'set-numa-node'," + " 'arguments': { 'type': 'node', 'nodeid': 1 } }"))); + + /* map 2 cpus in non default reverse order + * i.e socket1->node0, socket0->node1 + */ + g_assert(!qmp_rsp_is_err(qtest_qmp(qs, "{ 'execute': 'set-numa-node'," + " 'arguments': { 'type': 'cpu', 'node-id': 0, 'socket-id': 1 } }"))); + g_assert(!qmp_rsp_is_err(qtest_qmp(qs, "{ 'execute': 'set-numa-node'," + " 'arguments': { 'type': 'cpu', 'node-id': 1, 'socket-id': 0 } }"))); + + /* let machine initialization to complete and run */ + g_assert(!qmp_rsp_is_err(qtest_qmp(qs, "{ 'execute': 'exit-preconfig' }"))); + qtest_qmp_eventwait(qs, "RESUME"); + + /* check that CPUs are mapped as expected */ + resp = qtest_qmp(qs, "{ 'execute': 'query-hotpluggable-cpus'}"); + g_assert(qdict_haskey(resp, "return")); + cpus = qdict_get_qlist(resp, "return"); + g_assert(cpus); + while ((e = qlist_pop(cpus))) { + const QDict *cpu, *props; + int64_t socket, node; + + cpu = qobject_to(QDict, e); + g_assert(qdict_haskey(cpu, "props")); + props = qdict_get_qdict(cpu, "props"); + + g_assert(qdict_haskey(props, "node-id")); + node = qdict_get_int(props, "node-id"); + g_assert(qdict_haskey(props, "socket-id")); + socket = qdict_get_int(props, "socket-id"); + + if (socket == 0) { + g_assert_cmpint(node, ==, 1); + } else if (socket == 1) { + g_assert_cmpint(node, ==, 0); + } else { + g_assert(false); + } + qobject_unref(e); + } + qobject_unref(resp); + + qtest_quit(qs); +} + int main(int argc, char **argv) { const char *args = NULL; @@ -278,6 +338,7 @@ int main(int argc, char **argv) if (!strcmp(arch, "i386") || !strcmp(arch, "x86_64")) { qtest_add_data_func("/numa/pc/cpu/explicit", args, pc_numa_cpu); + qtest_add_data_func("/numa/pc/dynamic/cpu", args, pc_dynamic_cpu_cfg); } if (!strcmp(arch, "ppc64")) { diff --git a/tests/qapi-schema/allow-preconfig-test.err b/tests/qapi-schema/allow-preconfig-test.err new file mode 100644 index 0000000000..700d583306 --- /dev/null +++ b/tests/qapi-schema/allow-preconfig-test.err @@ -0,0 +1 @@ +tests/qapi-schema/allow-preconfig-test.json:2: 'allow-preconfig' of command 'allow-preconfig-test' should only use true value diff --git a/tests/qapi-schema/allow-preconfig-test.exit b/tests/qapi-schema/allow-preconfig-test.exit new file mode 100644 index 0000000000..d00491fd7e --- /dev/null +++ b/tests/qapi-schema/allow-preconfig-test.exit @@ -0,0 +1 @@ +1 diff --git a/tests/qapi-schema/allow-preconfig-test.json b/tests/qapi-schema/allow-preconfig-test.json new file mode 100644 index 0000000000..d9f0e914df --- /dev/null +++ b/tests/qapi-schema/allow-preconfig-test.json @@ -0,0 +1,2 @@ +# Check against allow-preconfig illegal value +{ 'command': 'allow-preconfig-test', 'allow-preconfig': 'some-string' } diff --git a/tests/qapi-schema/allow-preconfig-test.out b/tests/qapi-schema/allow-preconfig-test.out new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/tests/qapi-schema/allow-preconfig-test.out diff --git a/tests/qapi-schema/doc-good.out b/tests/qapi-schema/doc-good.out index 63058b1590..9c8a4838e1 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 oob=False + gen=True success_response=True boxed=False oob=False preconfig=False command cmd-boxed Object -> None - gen=True success_response=True boxed=True oob=False + gen=True success_response=True boxed=True oob=False preconfig=False doc freeform body= = Section diff --git a/tests/qapi-schema/ident-with-escape.out b/tests/qapi-schema/ident-with-escape.out index 82213aa51d..24c976f473 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 oob=False + gen=True success_response=True boxed=False oob=False preconfig=False diff --git a/tests/qapi-schema/indented-expr.out b/tests/qapi-schema/indented-expr.out index 862678f8f4..bd8a48630e 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 oob=False + gen=True success_response=True boxed=False oob=False preconfig=False command zwei None -> None - gen=True success_response=True boxed=False oob=False + gen=True success_response=True boxed=False oob=False preconfig=False diff --git a/tests/qapi-schema/qapi-schema-test.json b/tests/qapi-schema/qapi-schema-test.json index 06e30f452e..46c7282945 100644 --- a/tests/qapi-schema/qapi-schema-test.json +++ b/tests/qapi-schema/qapi-schema-test.json @@ -139,8 +139,8 @@ { '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 } +# Smoke test on Out-Of-Band and allow-preconfig-test +{ 'command': 'test-flags-command', 'allow-oob': true, 'allow-preconfig': 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 467577d770..542a19c407 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 oob=False + gen=True success_response=True boxed=False oob=False preconfig=False enum QEnumTwo ['value1', 'value2'] prefix QENUM_TWO object UserDefOne @@ -143,31 +143,31 @@ 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 oob=False + gen=True success_response=True boxed=False oob=False preconfig=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 oob=False + gen=True success_response=True boxed=False oob=False preconfig=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 oob=False + gen=True success_response=True boxed=False oob=False preconfig=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 oob=False + gen=True success_response=True boxed=False oob=False preconfig=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 oob=False + gen=True success_response=True boxed=False oob=False preconfig=False command boxed-struct UserDefZero -> None - gen=True success_response=True boxed=True oob=False + gen=True success_response=True boxed=True oob=False preconfig=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 + gen=True success_response=True boxed=True oob=False preconfig=False +command test-flags-command None -> None + gen=True success_response=True boxed=False oob=True preconfig=True object UserDefOptions member i64: intList optional=True member u64: uint64List optional=True @@ -231,4 +231,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 oob=False + gen=True success_response=True boxed=False oob=False preconfig=False diff --git a/tests/qapi-schema/test-qapi.py b/tests/qapi-schema/test-qapi.py index c1a144ba29..4512a41504 100644 --- a/tests/qapi-schema/test-qapi.py +++ b/tests/qapi-schema/test-qapi.py @@ -41,12 +41,12 @@ class QAPISchemaTestVisitor(QAPISchemaVisitor): print('alternate %s' % name) self._print_variants(variants) - def visit_command(self, name, info, arg_type, ret_type, - gen, success_response, boxed, allow_oob): + def visit_command(self, name, info, arg_type, ret_type, gen, + success_response, boxed, allow_oob, allow_preconfig): 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 oob=%s' % \ - (gen, success_response, boxed, allow_oob)) + print(' gen=%s success_response=%s boxed=%s oob=%s preconfig=%s' % \ + (gen, success_response, boxed, allow_oob, allow_preconfig)) def visit_event(self, name, info, arg_type, boxed): print('event %s %s' % (name, arg_type and arg_type.name)) diff --git a/tests/qmp-test.c b/tests/qmp-test.c index 88f867f8c0..a49cbc6fde 100644 --- a/tests/qmp-test.c +++ b/tests/qmp-test.c @@ -392,6 +392,45 @@ static void add_query_tests(QmpSchema *schema) } } +static void test_qmp_preconfig(void) +{ + QDict *rsp, *ret; + QTestState *qs = qtest_startf("%s --preconfig", common_args); + + /* preconfig state */ + /* enabled commands, no error expected */ + g_assert(!qmp_rsp_is_err(qtest_qmp(qs, "{ 'execute': 'query-commands' }"))); + + /* forbidden commands, expected error */ + g_assert(qmp_rsp_is_err(qtest_qmp(qs, "{ 'execute': 'query-cpus' }"))); + + /* check that query-status returns preconfig state */ + rsp = qtest_qmp(qs, "{ 'execute': 'query-status' }"); + ret = qdict_get_qdict(rsp, "return"); + g_assert(ret); + g_assert_cmpstr(qdict_get_try_str(ret, "status"), ==, "preconfig"); + qobject_unref(rsp); + + /* exit preconfig state */ + g_assert(!qmp_rsp_is_err(qtest_qmp(qs, "{ 'execute': 'exit-preconfig' }"))); + qtest_qmp_eventwait(qs, "RESUME"); + + /* check that query-status returns running state */ + rsp = qtest_qmp(qs, "{ 'execute': 'query-status' }"); + ret = qdict_get_qdict(rsp, "return"); + g_assert(ret); + g_assert_cmpstr(qdict_get_try_str(ret, "status"), ==, "running"); + qobject_unref(rsp); + + /* check that exit-preconfig returns error after exiting preconfig */ + g_assert(qmp_rsp_is_err(qtest_qmp(qs, "{ 'execute': 'exit-preconfig' }"))); + + /* enabled commands, no error expected */ + g_assert(!qmp_rsp_is_err(qtest_qmp(qs, "{ 'execute': 'query-cpus' }"))); + + qtest_quit(qs); +} + int main(int argc, char *argv[]) { QmpSchema schema; @@ -403,6 +442,7 @@ int main(int argc, char *argv[]) qtest_add_func("qmp/oob", test_qmp_oob); qmp_schema_init(&schema); add_query_tests(&schema); + qtest_add_func("qmp/preconfig", test_qmp_preconfig); ret = g_test_run(); diff --git a/tests/test-qmp-cmds.c b/tests/test-qmp-cmds.c index e0ed461f58..491b0c4a44 100644 --- a/tests/test-qmp-cmds.c +++ b/tests/test-qmp-cmds.c @@ -16,7 +16,7 @@ void qmp_user_def_cmd(Error **errp) { } -void qmp_an_oob_command(Error **errp) +void qmp_test_flags_command(Error **errp) { } |