tests: functional tests for QMP command set-numa-node

* start QEMU with 2 unmapped cpus,
 * while in preconfig state
    * add 2 numa nodes
    * assign cpus to them
 * exit preconfig and in running state check that cpus
   are mapped correctly.

Signed-off-by: Igor Mammedov <imammedo@redhat.com>
Message-Id: <1526556607-268163-1-git-send-email-imammedo@redhat.com>
Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
This commit is contained in:
Igor Mammedov 2018-05-17 13:30:07 +02:00 committed by Eduardo Habkost
parent f3be67812c
commit c35665e1ee
4 changed files with 77 additions and 7 deletions

View File

@ -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;
}

View File

@ -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

View File

@ -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")) {

View File

@ -392,13 +392,6 @@ static void add_query_tests(QmpSchema *schema)
}
}
static bool qmp_rsp_is_err(QDict *rsp)
{
QDict *error = qdict_get_qdict(rsp, "error");
qobject_unref(rsp);
return !!error;
}
static void test_qmp_preconfig(void)
{
QDict *rsp, *ret;