aboutsummaryrefslogtreecommitdiff
path: root/tests
diff options
context:
space:
mode:
authorPeter Maydell <peter.maydell@linaro.org>2018-05-31 11:12:36 +0100
committerPeter Maydell <peter.maydell@linaro.org>2018-05-31 11:12:36 +0100
commita3ac12fba028df90f7b3dbec924995c126c41022 (patch)
treed2b1846376a79fb5e6546910059365af2752e2dc /tests
parentfe817a8a0d4a2face895f692a7e061f0c98412b9 (diff)
parentc35665e1ee3d4344cd5156430ebc92310635f9bd (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.include1
-rw-r--r--tests/libqtest.c7
-rw-r--r--tests/libqtest.h9
-rw-r--r--tests/numa-test.c61
-rw-r--r--tests/qapi-schema/allow-preconfig-test.err1
-rw-r--r--tests/qapi-schema/allow-preconfig-test.exit1
-rw-r--r--tests/qapi-schema/allow-preconfig-test.json2
-rw-r--r--tests/qapi-schema/allow-preconfig-test.out0
-rw-r--r--tests/qapi-schema/doc-good.out4
-rw-r--r--tests/qapi-schema/ident-with-escape.out2
-rw-r--r--tests/qapi-schema/indented-expr.out4
-rw-r--r--tests/qapi-schema/qapi-schema-test.json4
-rw-r--r--tests/qapi-schema/qapi-schema-test.out22
-rw-r--r--tests/qapi-schema/test-qapi.py8
-rw-r--r--tests/qmp-test.c40
-rw-r--r--tests/test-qmp-cmds.c2
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)
{
}