diff options
Diffstat (limited to 'tests/device-introspect-test.c')
| -rw-r--r-- | tests/device-introspect-test.c | 156 |
1 files changed, 127 insertions, 29 deletions
diff --git a/tests/device-introspect-test.c b/tests/device-introspect-test.c index b1abb2ad89..f7162c023f 100644 --- a/tests/device-introspect-test.c +++ b/tests/device-introspect-test.c @@ -45,6 +45,56 @@ static QList *qom_list_types(const char *implements, bool abstract) return ret; } +/* Build a name -> ObjectTypeInfo index from a ObjectTypeInfo list */ +static QDict *qom_type_index(QList *types) +{ + QDict *index = qdict_new(); + QListEntry *e; + + QLIST_FOREACH_ENTRY(types, e) { + QDict *d = qobject_to_qdict(qlist_entry_obj(e)); + const char *name = qdict_get_str(d, "name"); + QINCREF(d); + qdict_put(index, name, d); + } + return index; +} + +/* Check if @parent is present in the parent chain of @type */ +static bool qom_has_parent(QDict *index, const char *type, const char *parent) +{ + while (type) { + QDict *d = qdict_get_qdict(index, type); + const char *p = d && qdict_haskey(d, "parent") ? + qdict_get_str(d, "parent") : + NULL; + + if (!strcmp(type, parent)) { + return true; + } + + type = p; + } + + return false; +} + +/* Find an entry on a list returned by qom-list-types */ +static QDict *type_list_find(QList *types, const char *name) +{ + QListEntry *e; + + QLIST_FOREACH_ENTRY(types, e) { + QDict *d = qobject_to_qdict(qlist_entry_obj(e)); + const char *ename = qdict_get_str(d, "name"); + if (!strcmp(ename, name)) { + return d; + } + } + + return NULL; +} + static QList *device_type_list(bool abstract) { return qom_list_types("device", abstract); @@ -87,6 +137,61 @@ static void test_device_intro_list(void) qtest_end(); } +/* + * Ensure all entries returned by qom-list-types implements=<parent> + * have <parent> as a parent. + */ +static void test_qom_list_parents(const char *parent) +{ + QList *types; + QListEntry *e; + QDict *index; + + types = qom_list_types(parent, true); + index = qom_type_index(types); + + QLIST_FOREACH_ENTRY(types, e) { + QDict *d = qobject_to_qdict(qlist_entry_obj(e)); + const char *name = qdict_get_str(d, "name"); + + g_assert(qom_has_parent(index, name, parent)); + } + + QDECREF(types); + QDECREF(index); +} + +static void test_qom_list_fields(void) +{ + QList *all_types; + QList *non_abstract; + QListEntry *e; + + qtest_start(common_args); + + all_types = qom_list_types(NULL, true); + non_abstract = qom_list_types(NULL, false); + + QLIST_FOREACH_ENTRY(all_types, e) { + QDict *d = qobject_to_qdict(qlist_entry_obj(e)); + const char *name = qdict_get_str(d, "name"); + bool abstract = qdict_haskey(d, "abstract") ? + qdict_get_bool(d, "abstract") : + false; + bool expected_abstract = !type_list_find(non_abstract, name); + + g_assert(abstract == expected_abstract); + } + + test_qom_list_parents("object"); + test_qom_list_parents("device"); + test_qom_list_parents("sys-bus-device"); + + QDECREF(all_types); + QDECREF(non_abstract); + qtest_end(); +} + static void test_device_intro_none(void) { qtest_start(common_args); @@ -124,42 +229,34 @@ static void test_device_intro_concrete(void) static void test_abstract_interfaces(void) { QList *all_types; - QList *obj_types; - QListEntry *ae; + QListEntry *e; + QDict *index; qtest_start(common_args); - /* qom-list-types implements=interface would return any type - * that implements _any_ interface (not just interface types), - * so use a trick to find the interface type names: - * - list all object types - * - list all types, and look for items that are not - * on the first list - */ - all_types = qom_list_types(NULL, false); - obj_types = qom_list_types("object", false); - - QLIST_FOREACH_ENTRY(all_types, ae) { - QDict *at = qobject_to_qdict(qlist_entry_obj(ae)); - const char *aname = qdict_get_str(at, "name"); - QListEntry *oe; - const char *found = NULL; - - QLIST_FOREACH_ENTRY(obj_types, oe) { - QDict *ot = qobject_to_qdict(qlist_entry_obj(oe)); - const char *oname = qdict_get_str(ot, "name"); - if (!strcmp(aname, oname)) { - found = oname; - break; - } + + all_types = qom_list_types("interface", true); + index = qom_type_index(all_types); + + QLIST_FOREACH_ENTRY(all_types, e) { + QDict *d = qobject_to_qdict(qlist_entry_obj(e)); + const char *name = qdict_get_str(d, "name"); + + /* + * qom-list-types implements=interface returns all types + * that implement _any_ interface (not just interface + * types), so skip the ones that don't have "interface" + * on the parent type chain. + */ + if (!qom_has_parent(index, name, "interface")) { + /* Not an interface type */ + continue; } - /* Using g_assert_cmpstr() will give more useful failure - * messages than g_assert(found) */ - g_assert_cmpstr(aname, ==, found); + g_assert(qdict_haskey(d, "abstract") && qdict_get_bool(d, "abstract")); } QDECREF(all_types); - QDECREF(obj_types); + QDECREF(index); qtest_end(); } @@ -168,6 +265,7 @@ int main(int argc, char **argv) g_test_init(&argc, &argv, NULL); qtest_add_func("device/introspect/list", test_device_intro_list); + qtest_add_func("device/introspect/list-fields", test_qom_list_fields); qtest_add_func("device/introspect/none", test_device_intro_none); qtest_add_func("device/introspect/abstract", test_device_intro_abstract); qtest_add_func("device/introspect/concrete", test_device_intro_concrete); |