diff options
author | Peter Maydell <peter.maydell@linaro.org> | 2017-07-18 15:24:11 +0100 |
---|---|---|
committer | Peter Maydell <peter.maydell@linaro.org> | 2017-07-18 15:24:11 +0100 |
commit | 368e708b4c95501574ab11632c7a0b8bb3ddc7e8 (patch) | |
tree | 3f0a487b338ca6d6ddb1abf17f193c38255666cc /tests | |
parent | e9277a19a1a50ab5662c16795531bac332f142f9 (diff) | |
parent | f86285c571c49e781d3fa46f3bef3835b8e6f393 (diff) |
Merge remote-tracking branch 'remotes/ehabkost/tags/x86-and-machine-pull-request' into staging
x86 and machine queue, 2017-07-17
# gpg: Signature made Mon 17 Jul 2017 19:46:14 BST
# gpg: using RSA key 0x2807936F984DC5A6
# gpg: Good signature from "Eduardo Habkost <ehabkost@redhat.com>"
# Primary key fingerprint: 5A32 2FD5 ABC4 D3DB ACCF D1AA 2807 936F 984D C5A6
* remotes/ehabkost/tags/x86-and-machine-pull-request:
qmp: Include parent type on 'qom-list-types' output
qmp: Include 'abstract' field on 'qom-list-types' output
tests: Simplify abstract-interfaces check with a helper
i386: add Skylake-Server cpu model
i386: Update comment about XSAVES on Skylake-Client
i386: expose "TCGTCGTCGTCG" in the 0x40000000 CPUID leaf
fw_cfg: move QOM type defines and fw_cfg types into fw_cfg.h
fw_cfg: move qdev_init_nofail() from fw_cfg_init1() to callers
fw_cfg: switch fw_cfg_find() to locate the fw_cfg device by type rather than path
qom: Fix ambiguous path detection when ambiguous=NULL
Revert "machine: Convert abstract typename on compat_props to subclass names"
test-qdev-global-props: Test global property ordering
qdev: fix the order compat and global properties are applied
tests: Test case for object_resolve_path*()
device-crash-test: Fix regexp on whitelist
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Diffstat (limited to 'tests')
-rw-r--r-- | tests/check-qom-proplist.c | 42 | ||||
-rw-r--r-- | tests/device-introspect-test.c | 156 | ||||
-rw-r--r-- | tests/test-qdev-global-props.c | 33 |
3 files changed, 202 insertions, 29 deletions
diff --git a/tests/check-qom-proplist.c b/tests/check-qom-proplist.c index 8e432e9ab6..432b66585f 100644 --- a/tests/check-qom-proplist.c +++ b/tests/check-qom-proplist.c @@ -568,6 +568,47 @@ static void test_dummy_delchild(void) object_unparent(OBJECT(dev)); } +static void test_qom_partial_path(void) +{ + Object *root = object_get_objects_root(); + Object *cont1 = container_get(root, "/cont1"); + Object *obj1 = object_new(TYPE_DUMMY); + Object *obj2a = object_new(TYPE_DUMMY); + Object *obj2b = object_new(TYPE_DUMMY); + bool ambiguous; + + /* Objects created: + * /cont1 + * /cont1/obj1 + * /cont1/obj2 (obj2a) + * /obj2 (obj2b) + */ + object_property_add_child(cont1, "obj1", obj1, &error_abort); + object_unref(obj1); + object_property_add_child(cont1, "obj2", obj2a, &error_abort); + object_unref(obj2a); + object_property_add_child(root, "obj2", obj2b, &error_abort); + object_unref(obj2b); + + ambiguous = false; + g_assert(!object_resolve_path_type("", TYPE_DUMMY, &ambiguous)); + g_assert(ambiguous); + g_assert(!object_resolve_path_type("", TYPE_DUMMY, NULL)); + + ambiguous = false; + g_assert(!object_resolve_path("obj2", &ambiguous)); + g_assert(ambiguous); + g_assert(!object_resolve_path("obj2", NULL)); + + ambiguous = false; + g_assert(object_resolve_path("obj1", &ambiguous) == obj1); + g_assert(!ambiguous); + g_assert(object_resolve_path("obj1", NULL) == obj1); + + object_unparent(obj2b); + object_unparent(cont1); +} + int main(int argc, char **argv) { g_test_init(&argc, &argv, NULL); @@ -585,6 +626,7 @@ int main(int argc, char **argv) g_test_add_func("/qom/proplist/getenum", test_dummy_getenum); g_test_add_func("/qom/proplist/iterator", test_dummy_iterator); g_test_add_func("/qom/proplist/delchild", test_dummy_delchild); + g_test_add_func("/qom/resolve/partial", test_qom_partial_path); return g_test_run(); } 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); diff --git a/tests/test-qdev-global-props.c b/tests/test-qdev-global-props.c index b25fe892ed..d81b0862d5 100644 --- a/tests/test-qdev-global-props.c +++ b/tests/test-qdev-global-props.c @@ -33,6 +33,8 @@ #define STATIC_TYPE(obj) \ OBJECT_CHECK(MyType, (obj), TYPE_STATIC_PROPS) +#define TYPE_SUBCLASS "static_prop_subtype" + #define PROP_DEFAULT 100 typedef struct MyType { @@ -63,6 +65,11 @@ static const TypeInfo static_prop_type = { .class_init = static_prop_class_init, }; +static const TypeInfo subclass_type = { + .name = TYPE_SUBCLASS, + .parent = TYPE_STATIC_PROPS, +}; + /* Test simple static property setting to default value */ static void test_static_prop_subprocess(void) { @@ -279,12 +286,35 @@ static void test_dynamic_globalprop_nouser(void) g_test_trap_assert_stdout(""); } +/* Test if global props affecting subclasses are applied in the right order */ +static void test_subclass_global_props(void) +{ + MyType *mt; + /* Global properties must be applied in the order they were registered */ + static GlobalProperty props[] = { + { TYPE_STATIC_PROPS, "prop1", "101" }, + { TYPE_SUBCLASS, "prop1", "102" }, + { TYPE_SUBCLASS, "prop2", "103" }, + { TYPE_STATIC_PROPS, "prop2", "104" }, + {} + }; + + qdev_prop_register_global_list(props); + + mt = STATIC_TYPE(object_new(TYPE_SUBCLASS)); + qdev_init_nofail(DEVICE(mt)); + + g_assert_cmpuint(mt->prop1, ==, 102); + g_assert_cmpuint(mt->prop2, ==, 104); +} + int main(int argc, char **argv) { g_test_init(&argc, &argv, NULL); module_call_init(MODULE_INIT_QOM); type_register_static(&static_prop_type); + type_register_static(&subclass_type); type_register_static(&dynamic_prop_type); type_register_static(&hotplug_type); type_register_static(&nohotplug_type); @@ -310,6 +340,9 @@ int main(int argc, char **argv) g_test_add_func("/qdev/properties/dynamic/global/nouser", test_dynamic_globalprop_nouser); + g_test_add_func("/qdev/properties/global/subclass", + test_subclass_global_props); + g_test_run(); return 0; |