qom: Make all interface types abstract
"qom-list-types abstract=false" currently returns all interface types, as if they were not abstract. Fix this by making sure all interface types are abstract. All interface types have instance_size == 0, so we can use it to set abstract=true on type_initialize(). Signed-off-by: Eduardo Habkost <ehabkost@redhat.com> Message-Id: <1481567461-2341-1-git-send-email-ehabkost@redhat.com> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
This commit is contained in:
		
							parent
							
								
									765a707000
								
							
						
					
					
						commit
						1c6d75d5f7
					
				@ -272,6 +272,12 @@ static void type_initialize(TypeImpl *ti)
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    ti->class_size = type_class_get_size(ti);
 | 
					    ti->class_size = type_class_get_size(ti);
 | 
				
			||||||
    ti->instance_size = type_object_get_size(ti);
 | 
					    ti->instance_size = type_object_get_size(ti);
 | 
				
			||||||
 | 
					    /* Any type with zero instance_size is implicitly abstract.
 | 
				
			||||||
 | 
					     * This means interface types are all abstract.
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    if (ti->instance_size == 0) {
 | 
				
			||||||
 | 
					        ti->abstract = true;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    ti->class = g_malloc0(ti->class_size);
 | 
					    ti->class = g_malloc0(ti->class_size);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -20,18 +20,24 @@
 | 
				
			|||||||
#include "qemu/osdep.h"
 | 
					#include "qemu/osdep.h"
 | 
				
			||||||
#include "qemu-common.h"
 | 
					#include "qemu-common.h"
 | 
				
			||||||
#include "qapi/qmp/qstring.h"
 | 
					#include "qapi/qmp/qstring.h"
 | 
				
			||||||
 | 
					#include "qapi/qmp/qbool.h"
 | 
				
			||||||
 | 
					#include "qapi/qmp/qdict.h"
 | 
				
			||||||
#include "libqtest.h"
 | 
					#include "libqtest.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const char common_args[] = "-nodefaults -machine none";
 | 
					const char common_args[] = "-nodefaults -machine none";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static QList *device_type_list(bool abstract)
 | 
					static QList *qom_list_types(const char *implements, bool abstract)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    QDict *resp;
 | 
					    QDict *resp;
 | 
				
			||||||
    QList *ret;
 | 
					    QList *ret;
 | 
				
			||||||
 | 
					    QDict *args = qdict_new();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    qdict_put(args, "abstract", qbool_from_bool(abstract));
 | 
				
			||||||
 | 
					    if (implements) {
 | 
				
			||||||
 | 
					        qdict_put(args, "implements", qstring_from_str(implements));
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
    resp = qmp("{'execute': 'qom-list-types',"
 | 
					    resp = qmp("{'execute': 'qom-list-types',"
 | 
				
			||||||
               " 'arguments': {'implements': 'device', 'abstract': %i}}",
 | 
					               " 'arguments': %p }", args);
 | 
				
			||||||
               abstract);
 | 
					 | 
				
			||||||
    g_assert(qdict_haskey(resp, "return"));
 | 
					    g_assert(qdict_haskey(resp, "return"));
 | 
				
			||||||
    ret = qdict_get_qlist(resp, "return");
 | 
					    ret = qdict_get_qlist(resp, "return");
 | 
				
			||||||
    QINCREF(ret);
 | 
					    QINCREF(ret);
 | 
				
			||||||
@ -39,6 +45,11 @@ static QList *device_type_list(bool abstract)
 | 
				
			|||||||
    return ret;
 | 
					    return ret;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static QList *device_type_list(bool abstract)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    return qom_list_types("device", abstract);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void test_one_device(const char *type)
 | 
					static void test_one_device(const char *type)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    QDict *resp;
 | 
					    QDict *resp;
 | 
				
			||||||
@ -110,6 +121,48 @@ static void test_device_intro_concrete(void)
 | 
				
			|||||||
    qtest_end();
 | 
					    qtest_end();
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void test_abstract_interfaces(void)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    QList *all_types;
 | 
				
			||||||
 | 
					    QList *obj_types;
 | 
				
			||||||
 | 
					    QListEntry *ae;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    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;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        /* Using g_assert_cmpstr() will give more useful failure
 | 
				
			||||||
 | 
					         * messages than g_assert(found) */
 | 
				
			||||||
 | 
					        g_assert_cmpstr(aname, ==, found);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    QDECREF(all_types);
 | 
				
			||||||
 | 
					    QDECREF(obj_types);
 | 
				
			||||||
 | 
					    qtest_end();
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int main(int argc, char **argv)
 | 
					int main(int argc, char **argv)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    g_test_init(&argc, &argv, NULL);
 | 
					    g_test_init(&argc, &argv, NULL);
 | 
				
			||||||
@ -118,6 +171,7 @@ int main(int argc, char **argv)
 | 
				
			|||||||
    qtest_add_func("device/introspect/none", test_device_intro_none);
 | 
					    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/abstract", test_device_intro_abstract);
 | 
				
			||||||
    qtest_add_func("device/introspect/concrete", test_device_intro_concrete);
 | 
					    qtest_add_func("device/introspect/concrete", test_device_intro_concrete);
 | 
				
			||||||
 | 
					    qtest_add_func("device/introspect/abstract-interfaces", test_abstract_interfaces);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    return g_test_run();
 | 
					    return g_test_run();
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user