@ -45,6 +45,40 @@ 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 )
{
@ -103,6 +137,30 @@ 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 ;
@ -125,6 +183,10 @@ static void test_qom_list_fields(void)
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 ( ) ;
@ -167,23 +229,25 @@ static void test_device_intro_concrete(void)
static void test_abstract_interfaces ( void )
{
QList * all_types ;
QList * obj_types ;
QListEntry * e ;
QDict * index ;
qtest_start ( common_args ) ;
/*
* qom - list - types implements = interface returns all types that
* implement _any_ interface ( not just interface types ) , but
* we can filter them out because interfaces don ' t implement
* the " object " type .
*/
all_types = qom_list_types ( " interface " , true ) ;
obj_types = qom_list_types ( " object " , 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 " ) ;
if ( type_list_find ( obj_types , 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 ;
}
@ -192,7 +256,7 @@ static void test_abstract_interfaces(void)
}
QDECREF ( all_types ) ;
QDECREF ( obj_types ) ;
QDECREF ( index ) ;
qtest_end ( ) ;
}