Steve Sistare <steven.sist...@oracle.com> writes: > Add a unit test for qom-list-getv.
qom-list-get here and in subject. Could scratch this line, subject suffices. > > Signed-off-by: Steve Sistare <steven.sist...@oracle.com> > Reviewed-by: Philippe Mathieu-Daudé <phi...@linaro.org> > --- > tests/qtest/qom-test.c | 116 > ++++++++++++++++++++++++++++++++++++++++++++++++- > 1 file changed, 115 insertions(+), 1 deletion(-) > > diff --git a/tests/qtest/qom-test.c b/tests/qtest/qom-test.c > index 27d70bc..4ade1c7 100644 > --- a/tests/qtest/qom-test.c > +++ b/tests/qtest/qom-test.c > @@ -11,11 +11,119 @@ > > #include "qobject/qdict.h" > #include "qobject/qlist.h" > +#include "qobject/qstring.h" > #include "qemu/cutils.h" > #include "libqtest.h" > > +#define RAM_NAME "node0" > +#define RAM_SIZE 65536 > + > static int verbosity_level; > > +/* > + * Verify that the /object/RAM_NAME 'size' property is RAM_SIZE. > + */ > +static void test_list_get_value(QTestState *qts) > +{ > + QDict *args = qdict_new(); > + g_autoptr(QDict) response = NULL; > + g_autoptr(QList) paths = qlist_new(); > + QListEntry *entry, *prop_entry; > + const char *prop_name; > + QList *properties, *return_list; > + QDict *obj; > + > + qlist_append_str(paths, "/objects/" RAM_NAME); > + qdict_put_obj(args, "paths", QOBJECT(qlist_copy(paths))); Could probably avoid copying @paths. Good enough. > + response = qtest_qmp(qts, "{ 'execute': 'qom-list-get'," > + " 'arguments': %p }", args); > + g_assert(response); > + g_assert(qdict_haskey(response, "return")); > + return_list = qobject_to(QList, qdict_get(response, "return")); > + > + entry = QTAILQ_FIRST(&return_list->head); > + obj = qobject_to(QDict, qlist_entry_obj(entry)); > + g_assert(qdict_haskey(obj, "properties")); > + properties = qobject_to(QList, qdict_get(obj, "properties")); > + > + QLIST_FOREACH_ENTRY(properties, prop_entry) { > + QDict *prop = qobject_to(QDict, qlist_entry_obj(prop_entry)); > + > + g_assert(qdict_haskey(prop, "name")); > + g_assert(qdict_haskey(prop, "value")); > + > + prop_name = qdict_get_str(prop, "name"); > + if (!strcmp(prop_name, "type")) { > + g_assert_cmpstr(qdict_get_str(prop, "value"), ==, > + "memory-backend-ram"); > + > + } else if (!strcmp(prop_name, "size")) { > + g_assert_cmpint(qdict_get_int(prop, "value"), ==, RAM_SIZE); > + } > + } > +} > + > +static void test_list_get(QTestState *qts, QList *paths) > +{ > + QListEntry *entry, *prop_entry, *path_entry; > + g_autoptr(QDict) response = NULL; > + QDict *args = qdict_new(); > + QDict *prop; > + QList *return_list; > + > + if (verbosity_level >= 2) { > + g_test_message("Obtaining properties for paths:"); > + QLIST_FOREACH_ENTRY(paths, path_entry) { > + QString *qstr = qobject_to(QString, qlist_entry_obj(path_entry)); > + g_test_message(" %s", qstring_get_str(qstr)); > + } > + } > + > + qdict_put_obj(args, "paths", QOBJECT(qlist_copy(paths))); > + response = qtest_qmp(qts, "{ 'execute': 'qom-list-get'," > + " 'arguments': %p }", args); > + g_assert(response); > + g_assert(qdict_haskey(response, "return")); > + return_list = qobject_to(QList, qdict_get(response, "return")); > + g_assert(!qlist_empty(return_list)); > + > + path_entry = QTAILQ_FIRST(&paths->head); > + QLIST_FOREACH_ENTRY(return_list, entry) { > + QDict *obj = qobject_to(QDict, qlist_entry_obj(entry)); > + g_assert(qdict_haskey(obj, "properties")); > + QList *properties = qobject_to(QList, qdict_get(obj, "properties")); > + bool has_child = false; > + > + QLIST_FOREACH_ENTRY(properties, prop_entry) { > + prop = qobject_to(QDict, qlist_entry_obj(prop_entry)); > + g_assert(qdict_haskey(prop, "name")); > + g_assert(qdict_haskey(prop, "type")); > + has_child |= strstart(qdict_get_str(prop, "type"), "child<", > NULL); > + } > + > + if (has_child) { > + /* build a list of child paths */ > + QString *qstr = qobject_to(QString, qlist_entry_obj(path_entry)); > + const char *path = qstring_get_str(qstr); > + g_autoptr(QList) child_paths = qlist_new(); > + > + QLIST_FOREACH_ENTRY(properties, prop_entry) { > + prop = qobject_to(QDict, qlist_entry_obj(prop_entry)); > + if (strstart(qdict_get_str(prop, "type"), "child<", NULL)) { > + g_autofree char *child_path = g_strdup_printf( > + "%s/%s", path, qdict_get_str(prop, "name")); > + qlist_append_str(child_paths, child_path); > + } > + } > + > + /* fetch props for all children with one qom-list-get call */ > + test_list_get(qts, child_paths); > + } > + > + path_entry = QTAILQ_NEXT(path_entry, next); > + } > +} > + > static void test_properties(QTestState *qts, const char *path, bool recurse) > { > char *child_path; > @@ -85,8 +193,10 @@ static void test_machine(gconstpointer data) > const char *machine = data; > QDict *response; > QTestState *qts; > + g_autoptr(QList) paths = qlist_new(); > > - qts = qtest_initf("-machine %s", machine); > + qts = qtest_initf("-machine %s -object memory-backend-ram,id=%s,size=%d", > + machine, RAM_NAME, RAM_SIZE); > > if (g_test_slow()) { > /* Make sure we can get the machine class properties: */ > @@ -101,6 +211,10 @@ static void test_machine(gconstpointer data) > > test_properties(qts, "/machine", true); > > + qlist_append_str(paths, "/machine"); > + test_list_get(qts, paths); > + test_list_get_value(qts); > + > response = qtest_qmp(qts, "{ 'execute': 'quit' }"); > g_assert(qdict_haskey(response, "return")); > qobject_unref(response); Reviewed-by: Markus Armbruster <arm...@redhat.com>