Commit c35665e1 authored by Igor Mammedov's avatar Igor Mammedov Committed by Eduardo Habkost
Browse files

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: default avatarIgor Mammedov <imammedo@redhat.com>
Message-Id: <1526556607-268163-1-git-send-email-imammedo@redhat.com>
Signed-off-by: default avatarEduardo Habkost <ehabkost@redhat.com>
parent f3be6781
Loading
Loading
Loading
Loading
+7 −0
Original line number Diff line number Diff line
@@ -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;
}
+9 −0
Original line number Diff line number Diff line
@@ -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
+61 −0
Original line number Diff line number Diff line
@@ -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")) {
+0 −7
Original line number Diff line number Diff line
@@ -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;