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
>

Reply via email to