qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Qemu-devel] [PATCH 3/3] qom: add unit test for Interfaces


From: Anthony Liguori
Subject: Re: [Qemu-devel] [PATCH 3/3] qom: add unit test for Interfaces
Date: Mon, 18 Jun 2012 08:26:03 -0500
User-agent: Mozilla/5.0 (X11; Linux x86_64; rv:11.0) Gecko/20120329 Thunderbird/11.0.1

On 06/16/2012 05:31 AM, Peter Crosthwaite wrote:
On Thu, Jun 14, 2012 at 6:55 AM, Anthony Liguori<address@hidden>  wrote:
Signed-off-by: Anthony Liguori<address@hidden>

Reviewed-by: Peter A.G. Crosthwaite<address@hidden>

---
  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<address@hidden>
+ *
+ * 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;

This is admittedly a little wierd...

Interfaces don't exist as Objects in QOM. They are just classes. But it's very handy to be able to have a Herbivore type that you can cast objects to.

I probably need to respin this though. INTERFACE_CHECK() asserts that an object implements the interface class and then just returns the obj and casts it to the dummy Interface object type.

A better approach would be to just teach object_dynamic_cast to do this for anythign that's an interface type. That would fix the link problem you pointed out too. I'll spin a v2.

Regards,

Anthony Liguori


?

+
+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

[Prev in Thread] Current Thread [Next in Thread]