On Thu, Jun 14, 2012 at 6:55 AM, Anthony Liguori <aligu...@us.ibm.com> wrote: > Signed-off-by: Anthony Liguori <aligu...@us.ibm.com>
Reviewed-by: Peter A.G. Crosthwaite <peter.crosthwa...@petalogix.com> > --- > tests/Makefile | 5 +- > tests/test-object.c | 222 > +++++++++++++++++++++++++++++++++++++++++++++++++++ > 2 files changed, 226 insertions(+), 1 deletions(-) > create mode 100644 tests/test-object.c > > diff --git a/tests/Makefile b/tests/Makefile > index d66ab19..d1f979d 100644 > --- a/tests/Makefile > +++ b/tests/Makefile > @@ -14,6 +14,7 @@ check-unit-y += tests/test-string-input-visitor$(EXESUF) > check-unit-y += tests/test-string-output-visitor$(EXESUF) > check-unit-y += tests/test-coroutine$(EXESUF) > check-unit-y += tests/test-visitor-serialization$(EXESUF) > +check-unit-y += tests/test-object$(EXESUF) > > check-block-$(CONFIG_POSIX) += tests/qemu-iotests-quick.sh > > @@ -32,7 +33,8 @@ test-obj-y = tests/check-qint.o tests/check-qstring.o > tests/check-qdict.o \ > tests/test-coroutine.o tests/test-string-output-visitor.o \ > tests/test-string-input-visitor.o tests/test-qmp-output-visitor.o \ > tests/test-qmp-input-visitor.o tests/test-qmp-input-strict.o \ > - tests/test-qmp-commands.o tests/test-visitor-serialization.o > + tests/test-qmp-commands.o tests/test-visitor-serialization.o \ > + tests/test-object.o > > test-qapi-obj-y = $(qobject-obj-y) $(qapi-obj-y) $(tools-obj-y) > test-qapi-obj-y += tests/test-qapi-visit.o tests/test-qapi-types.o > @@ -66,6 +68,7 @@ tests/test-qmp-input-visitor$(EXESUF): > tests/test-qmp-input-visitor.o $(test-qap > tests/test-qmp-input-strict$(EXESUF): tests/test-qmp-input-strict.o > $(test-qapi-obj-y) > tests/test-qmp-commands$(EXESUF): tests/test-qmp-commands.o > tests/test-qmp-marshal.o $(test-qapi-obj-y) > tests/test-visitor-serialization$(EXESUF): > tests/test-visitor-serialization.o $(test-qapi-obj-y) > +tests/test-object$(EXESUF): tests/test-object.o $(qom-obj-y) > $(test-qapi-obj-y) > > tests/rtc-test$(EXESUF): tests/rtc-test.o $(trace-obj-y) > tests/m48t59-test$(EXESUF): tests/m48t59-test.o $(trace-obj-y) > diff --git a/tests/test-object.c b/tests/test-object.c > new file mode 100644 > index 0000000..9f41da0 > --- /dev/null > +++ b/tests/test-object.c > @@ -0,0 +1,222 @@ > +/* > + * QEMU Object Model unit test > + * > + * Copyright IBM, Corp. 2012 > + * > + * Authors: > + * Anthony Liguori <aligu...@us.ibm.com> > + * > + * This work is licensed under the terms of the GNU GPL, version 2 or later. > + * See the COPYING file in the top-level directory. > + * > + */ > +#include "qemu/object.h" > +#include "module.h" > + > +#define TYPE_HERBIVORE "herbivore" > + > +#define HERBIVORE_CLASS(klass) \ > + OBJECT_CLASS_CHECK(HerbivoreClass, (klass), TYPE_HERBIVORE) > +#define HERBIVORE_GET_CLASS(obj) \ > + OBJECT_GET_CLASS(HerbivoreClass, (obj), TYPE_HERBIVORE) > +#define HERBIVORE(obj) \ > + INTERFACE_CHECK(Herbivore, (obj), TYPE_HERBIVORE) > + > +typedef struct Herbivore > +{ > + Object obj; > +} Herbivore; All this is doing is saying Herbivores are Objects right? A user cant add anything to this struct given that interfaces are stateless so could this be simplified to typedef Object Herbivore; ? > + > +typedef struct HerbivoreClass > +{ > + InterfaceClass parent; > + > + void (*feed_greens)(Herbivore *obj); > +} HerbivoreClass; > + > +static void herbivore_feed_greens(Herbivore *herbie) > +{ > + HerbivoreClass *k = HERBIVORE_GET_CLASS(herbie); > + > + k->feed_greens(herbie); > +} > + > +static TypeInfo herbivore_info = { > + .name = TYPE_HERBIVORE, > + .parent = TYPE_INTERFACE, > + .class_size = sizeof(HerbivoreClass), > +}; > + > +#define TYPE_CARNIVORE "carnivore" > +#define CARNIVORE_CLASS(klass) \ > + OBJECT_CLASS_CHECK(CarnivoreClass, (klass), TYPE_CARNIVORE) > +#define CARNIVORE_GET_CLASS(obj) \ > + OBJECT_GET_CLASS(CarnivoreClass, (obj), TYPE_CARNIVORE) > +#define CARNIVORE(obj) \ > + INTERFACE_CHECK(Carnivore, (obj), TYPE_CARNIVORE) > + > +typedef struct Carnivore > +{ > + Object parent; > +} Carnivore; > + > +typedef struct CarnivoreClass > +{ > + InterfaceClass parent; > + > + void (*feed_bugs)(Carnivore *obj); > +} CarnivoreClass; > + > +static void carnivore_feed_bugs(Carnivore *carnie) > +{ > + CarnivoreClass *k = CARNIVORE_GET_CLASS(carnie); > + > + k->feed_bugs(carnie); > +} > + > +static TypeInfo carnivore_info = { > + .name = TYPE_CARNIVORE, > + .parent = TYPE_INTERFACE, > + .class_size = sizeof(CarnivoreClass), > +}; > + > +#define TYPE_REPTILE "reptile" > +#define REPTILE(obj) OBJECT_CHECK(Reptile, (obj), TYPE_REPTILE) > + > +typedef struct Reptile > +{ > + Object parent; > +} Reptile; > + > +static TypeInfo reptile_info = { > + .name = TYPE_REPTILE, > + .instance_size = sizeof(Reptile), > + .abstract = true, > + .class_size = sizeof(ObjectClass), > +}; > + > +#define TYPE_LIZARD "lizard" > +#define LIZARD(obj) OBJECT_CHECK(Lizard, (obj), TYPE_LIZARD) > + > +typedef struct Lizard > +{ > + Reptile parent; > +} Lizard; > + > +static TypeInfo lizard_info = { > + .name = TYPE_LIZARD, > + .parent = TYPE_REPTILE, > + .instance_size = sizeof(Lizard), > + .abstract = true, > +}; > + > +#define TYPE_IGUANA "iguana" > +#define IGUANA(obj) OBJECT_CHECK(Iguana, (obj), TYPE_IGUANA) > + > +typedef struct Iguana > +{ > + Lizard parent; > + int greens; > +} Iguana; > + > +static void iguana_feed(Herbivore *herbie) > +{ > + Iguana *iggie = IGUANA(herbie); > + > + iggie->greens++; > +} > + > +static void iguana_class_initfn(ObjectClass *klass, void *data) > +{ > + HerbivoreClass *iface = HERBIVORE_CLASS(klass); > + > + iface->feed_greens = iguana_feed; > +} > + > +static TypeInfo iguana_info = { > + .name = TYPE_IGUANA, > + .parent = TYPE_LIZARD, > + .instance_size = sizeof(Iguana), > + .class_init = iguana_class_initfn, > + .interfaces = (InterfaceInfo[]) { > + { TYPE_HERBIVORE }, > + { } > + }, > +}; > + > +#define TYPE_BEARDED_DRAGON "bearded-dragon" > +#define BEARDED_DRAGON(obj) OBJECT_CHECK(BeardedDragon, (obj), > TYPE_BEARDED_DRAGON) > + > +typedef struct BeardedDragon > +{ > + Lizard parent; > + int bugs; > +} BeardedDragon; > + > +static void bearded_dragon_feed(Carnivore *carnie) > +{ > + BeardedDragon *dragon = BEARDED_DRAGON(carnie); > + > + dragon->bugs++; > +} > + > +static void bearded_dragon_class_initfn(ObjectClass *klass, void *data) > +{ > + CarnivoreClass *iface = CARNIVORE_CLASS(klass); > + > + iface->feed_bugs = bearded_dragon_feed; > +} > + > +static TypeInfo bearded_dragon_info = { > + .name = TYPE_BEARDED_DRAGON, > + .parent = TYPE_LIZARD, > + .instance_size = sizeof(BeardedDragon), > + .class_init = bearded_dragon_class_initfn, > + .interfaces = (InterfaceInfo[]) { > + { TYPE_CARNIVORE }, > + { } > + }, > +}; > + > +static void basic_init(void) > +{ > + BeardedDragon dragon; > + Iguana iguana; > + > + object_initialize(&dragon, TYPE_BEARDED_DRAGON); > + > + g_assert_cmpint(dragon.bugs, ==, 0); > + carnivore_feed_bugs(CARNIVORE(&dragon)); > + g_assert_cmpint(dragon.bugs, ==, 1); > + > + object_finalize(&dragon); > + > + object_initialize(&iguana, TYPE_IGUANA); > + > + g_assert_cmpint(iguana.greens, ==, 0); > + herbivore_feed_greens(HERBIVORE(&iguana)); > + g_assert_cmpint(iguana.greens, ==, 1); > + > + object_finalize(&iguana); > +} > + > +int main(int argc, char **argv) > +{ > + g_test_init(&argc, &argv, NULL); > + > + module_call_init(MODULE_INIT_QOM); > + > + type_register_static(&carnivore_info); > + type_register_static(&herbivore_info); > + > + type_register_static(&reptile_info); > + type_register_static(&lizard_info); > + type_register_static(&iguana_info); > + type_register_static(&bearded_dragon_info); > + > + g_test_add_func("/basic/init", basic_init); > + > + g_test_run(); > + > + return 0; > +} > -- > 1.7.5.4 >