[Qemu-devel] [PATCH v7 11/11] tests: functional tests for QMP command set-numa-node

Igor Mammedov posted 11 patches 7 years, 9 months ago
[Qemu-devel] [PATCH v7 11/11] tests: functional tests for QMP command set-numa-node
Posted by Igor Mammedov 7 years, 9 months ago
 * 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>
---
v6:
  * replace 'cont' with 'exit-preconfig' command
v5:
  * s/qobject_to_qdict(/qobject_to(QDict,/
  * s/-preconfig/--preconfig/
v4:
  * drop duplicate is_err() and reuse qmp_rsp_is_err() wich is moved
    to generic file libqtest.c. (Eric Blake <eblake@redhat.com>)

FIXUP! tests: functional tests for QMP command  set-numa-node
---
 tests/libqtest.h  |  9 ++++++++
 tests/libqtest.c  |  7 +++++++
 tests/numa-test.c | 61 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
 tests/qmp-test.c  |  7 -------
 4 files changed, 77 insertions(+), 7 deletions(-)

diff --git a/tests/libqtest.h b/tests/libqtest.h
index cbe8df4..ac52872 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/libqtest.c b/tests/libqtest.c
index 6f33a37..33426d5 100644
--- a/tests/libqtest.c
+++ b/tests/libqtest.c
@@ -1098,3 +1098,10 @@ void qtest_qmp_device_del(const char *id)
     QDECREF(response1);
     QDECREF(response2);
 }
+
+bool qmp_rsp_is_err(QDict *rsp)
+{
+    QDict *error = qdict_get_qdict(rsp, "error");
+    QDECREF(rsp);
+    return !!error;
+}
diff --git a/tests/numa-test.c b/tests/numa-test.c
index 0f861d8..0135a0c 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_decref(e);
+    }
+    QDECREF(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/qmp-test.c b/tests/qmp-test.c
index c49837a..4d5f198 100644
--- a/tests/qmp-test.c
+++ b/tests/qmp-test.c
@@ -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");
-    QDECREF(rsp);
-    return !!error;
-}
-
 static void test_qmp_preconfig(void)
 {
     QDict *rsp, *ret;
-- 
2.7.4


Re: [Qemu-devel] [PATCH v7 11/11] tests: functional tests for QMP command set-numa-node
Posted by Eduardo Habkost 7 years, 8 months ago
On Fri, May 04, 2018 at 10:37:49AM +0200, Igor Mammedov wrote:
>  * 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>

Nice, this is the test case I asked for in previous patches.  :)

Reviewed-by: Eduardo Habkost <ehabkost@redhat.com>

-- 
Eduardo

Re: [Qemu-devel] [PATCH v7 11/11] tests: functional tests for QMP command set-numa-node
Posted by Eduardo Habkost 7 years, 8 months ago
On Fri, May 04, 2018 at 10:37:49AM +0200, Igor Mammedov wrote:
>  * 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>
> ---
> v6:
>   * replace 'cont' with 'exit-preconfig' command
> v5:
>   * s/qobject_to_qdict(/qobject_to(QDict,/
>   * s/-preconfig/--preconfig/
> v4:
>   * drop duplicate is_err() and reuse qmp_rsp_is_err() wich is moved
>     to generic file libqtest.c. (Eric Blake <eblake@redhat.com>)
> 
> FIXUP! tests: functional tests for QMP command  set-numa-node
> ---
>  tests/libqtest.h  |  9 ++++++++
>  tests/libqtest.c  |  7 +++++++
>  tests/numa-test.c | 61 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
>  tests/qmp-test.c  |  7 -------
>  4 files changed, 77 insertions(+), 7 deletions(-)
> 
> diff --git a/tests/libqtest.h b/tests/libqtest.h
> index cbe8df4..ac52872 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/libqtest.c b/tests/libqtest.c
> index 6f33a37..33426d5 100644
> --- a/tests/libqtest.c
> +++ b/tests/libqtest.c
> @@ -1098,3 +1098,10 @@ void qtest_qmp_device_del(const char *id)
>      QDECREF(response1);
>      QDECREF(response2);
>  }
> +
> +bool qmp_rsp_is_err(QDict *rsp)
> +{
> +    QDict *error = qdict_get_qdict(rsp, "error");
> +    QDECREF(rsp);


Oops:

  tests/libqtest.c: In function ‘qmp_rsp_is_err’:
  tests/libqtest.c:1105:5: error: implicit declaration of function ‘QDECREF’ [-Werror=implicit-function-declaration]
       QDECREF(rsp);
       ^
  tests/libqtest.c:1105:5: error: nested extern declaration of ‘QDECREF’ [-Werror=nested-externs]

I've fixed this on numa-next, replaced QDECREF with object_unref.

-- 
Eduardo

Re: [Qemu-devel] [PATCH v7 11/11] tests: functional tests for QMP command set-numa-node
Posted by Igor Mammedov 7 years, 8 months ago
On Wed, 16 May 2018 19:12:30 -0300
Eduardo Habkost <ehabkost@redhat.com> wrote:

> On Fri, May 04, 2018 at 10:37:49AM +0200, Igor Mammedov wrote:
> >  * 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>
> > ---
> > v6:
> >   * replace 'cont' with 'exit-preconfig' command
> > v5:
> >   * s/qobject_to_qdict(/qobject_to(QDict,/
> >   * s/-preconfig/--preconfig/
> > v4:
> >   * drop duplicate is_err() and reuse qmp_rsp_is_err() wich is moved
> >     to generic file libqtest.c. (Eric Blake <eblake@redhat.com>)
> > 
> > FIXUP! tests: functional tests for QMP command  set-numa-node
> > ---
> >  tests/libqtest.h  |  9 ++++++++
> >  tests/libqtest.c  |  7 +++++++
> >  tests/numa-test.c | 61 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
> >  tests/qmp-test.c  |  7 -------
> >  4 files changed, 77 insertions(+), 7 deletions(-)
> > 
> > diff --git a/tests/libqtest.h b/tests/libqtest.h
> > index cbe8df4..ac52872 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/libqtest.c b/tests/libqtest.c
> > index 6f33a37..33426d5 100644
> > --- a/tests/libqtest.c
> > +++ b/tests/libqtest.c
> > @@ -1098,3 +1098,10 @@ void qtest_qmp_device_del(const char *id)
> >      QDECREF(response1);
> >      QDECREF(response2);
> >  }
> > +
> > +bool qmp_rsp_is_err(QDict *rsp)
> > +{
> > +    QDict *error = qdict_get_qdict(rsp, "error");
> > +    QDECREF(rsp);  
> 
> 
> Oops:
> 
>   tests/libqtest.c: In function ‘qmp_rsp_is_err’:
>   tests/libqtest.c:1105:5: error: implicit declaration of function ‘QDECREF’ [-Werror=implicit-function-declaration]
>        QDECREF(rsp);
>        ^
>   tests/libqtest.c:1105:5: error: nested extern declaration of ‘QDECREF’ [-Werror=nested-externs]
> 
> I've fixed this on numa-next, replaced QDECREF with object_unref.
I guess QDECREF was removed while patch were sitting on the list.


Re: [Qemu-devel] [PATCH v7 11/11] tests: functional tests for QMP command set-numa-node
Posted by Igor Mammedov 7 years, 8 months ago
On Thu, 17 May 2018 10:01:34 +0200
Igor Mammedov <imammedo@redhat.com> wrote:

> On Wed, 16 May 2018 19:12:30 -0300
> Eduardo Habkost <ehabkost@redhat.com> wrote:
> 
> > On Fri, May 04, 2018 at 10:37:49AM +0200, Igor Mammedov wrote:  
> > >  * 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>
> > > ---
> > > v6:
> > >   * replace 'cont' with 'exit-preconfig' command
> > > v5:
> > >   * s/qobject_to_qdict(/qobject_to(QDict,/
> > >   * s/-preconfig/--preconfig/
> > > v4:
> > >   * drop duplicate is_err() and reuse qmp_rsp_is_err() wich is moved
> > >     to generic file libqtest.c. (Eric Blake <eblake@redhat.com>)
> > > 
> > > FIXUP! tests: functional tests for QMP command  set-numa-node
> > > ---
> > >  tests/libqtest.h  |  9 ++++++++
> > >  tests/libqtest.c  |  7 +++++++
> > >  tests/numa-test.c | 61 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
> > >  tests/qmp-test.c  |  7 -------
> > >  4 files changed, 77 insertions(+), 7 deletions(-)
> > > 
> > > diff --git a/tests/libqtest.h b/tests/libqtest.h
> > > index cbe8df4..ac52872 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/libqtest.c b/tests/libqtest.c
> > > index 6f33a37..33426d5 100644
> > > --- a/tests/libqtest.c
> > > +++ b/tests/libqtest.c
> > > @@ -1098,3 +1098,10 @@ void qtest_qmp_device_del(const char *id)
> > >      QDECREF(response1);
> > >      QDECREF(response2);
> > >  }
> > > +
> > > +bool qmp_rsp_is_err(QDict *rsp)
> > > +{
> > > +    QDict *error = qdict_get_qdict(rsp, "error");
> > > +    QDECREF(rsp);    
> > 
> > 
> > Oops:
> > 
> >   tests/libqtest.c: In function ‘qmp_rsp_is_err’:
> >   tests/libqtest.c:1105:5: error: implicit declaration of function ‘QDECREF’ [-Werror=implicit-function-declaration]
> >        QDECREF(rsp);
> >        ^
> >   tests/libqtest.c:1105:5: error: nested extern declaration of ‘QDECREF’ [-Werror=nested-externs]
> > 
> > I've fixed this on numa-next, replaced QDECREF with object_unref.  
> I guess QDECREF was removed while patch were sitting on the list.
change affected 8th and 11th patches make the last depended on 8th.
I'll post rebased v8 8,11th patches here so it would still bisectable
and include into 8th Eric's request for negative exit-preconfig testcase (+3LOC)

[Qemu-devel] [PATCH v8 11/11] tests: functional tests for QMP command set-numa-node
Posted by Igor Mammedov 7 years, 8 months ago
 * 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>
---
v8:
  * there isn't QDECREF/qobject_decref anymore use qobject_unref instead
---
 tests/libqtest.h  |  9 ++++++++
 tests/libqtest.c  |  7 +++++++
 tests/numa-test.c | 61 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
 tests/qmp-test.c  |  7 -------
 4 files changed, 77 insertions(+), 7 deletions(-)

diff --git a/tests/libqtest.h b/tests/libqtest.h
index cbe8df4..ac52872 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/libqtest.c b/tests/libqtest.c
index 43fb97e..e0ca19d 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/numa-test.c b/tests/numa-test.c
index 169213f..b7a6ef8 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/qmp-test.c b/tests/qmp-test.c
index 2ee441c..a49cbc6 100644
--- a/tests/qmp-test.c
+++ b/tests/qmp-test.c
@@ -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;
-- 
2.7.4