From: Steve Sistare <steven.sist...@oracle.com> Add a unit test for qom-list-get.
Signed-off-by: Steve Sistare <steven.sist...@oracle.com> Reviewed-by: Philippe Mathieu-Daudé <phi...@linaro.org> Reviewed-by: Markus Armbruster <arm...@redhat.com> Message-ID: <1752248703-217318-4-git-send-email-steven.sist...@oracle.com> Signed-off-by: Markus Armbruster <arm...@redhat.com> --- 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 27d70bc11c..4ade1c728c 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))); + 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); -- 2.49.0