| /* |
| * Copyright (C) 2015 Red Hat, Inc. |
| * |
| * This library is free software; you can redistribute it and/or |
| * modify it under the terms of the GNU Lesser General Public |
| * License as published by the Free Software Foundation; either |
| * version 2.1 of the License, or (at your option) any later version. |
| * |
| * This library is distributed in the hope that it will be useful, |
| * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
| * Lesser General Public License for more details. |
| * |
| * You should have received a copy of the GNU Lesser General Public |
| * License along with this library. If not, see |
| * <http://www.gnu.org/licenses/>. |
| * |
| * Author: Daniel P. Berrange <berrange@redhat.com> |
| */ |
| |
| #include <glib.h> |
| |
| #include "qom/object.h" |
| #include "qemu/module.h" |
| |
| |
| #define TYPE_DUMMY "qemu-dummy" |
| |
| typedef struct DummyObject DummyObject; |
| typedef struct DummyObjectClass DummyObjectClass; |
| |
| #define DUMMY_OBJECT(obj) \ |
| OBJECT_CHECK(DummyObject, (obj), TYPE_DUMMY) |
| |
| typedef enum DummyAnimal DummyAnimal; |
| |
| enum DummyAnimal { |
| DUMMY_FROG, |
| DUMMY_ALLIGATOR, |
| DUMMY_PLATYPUS, |
| |
| DUMMY_LAST, |
| }; |
| |
| static const char *const dummy_animal_map[DUMMY_LAST + 1] = { |
| [DUMMY_FROG] = "frog", |
| [DUMMY_ALLIGATOR] = "alligator", |
| [DUMMY_PLATYPUS] = "platypus", |
| [DUMMY_LAST] = NULL, |
| }; |
| |
| struct DummyObject { |
| Object parent_obj; |
| |
| bool bv; |
| DummyAnimal av; |
| char *sv; |
| }; |
| |
| struct DummyObjectClass { |
| ObjectClass parent_class; |
| }; |
| |
| |
| static void dummy_set_bv(Object *obj, |
| bool value, |
| Error **errp) |
| { |
| DummyObject *dobj = DUMMY_OBJECT(obj); |
| |
| dobj->bv = value; |
| } |
| |
| static bool dummy_get_bv(Object *obj, |
| Error **errp) |
| { |
| DummyObject *dobj = DUMMY_OBJECT(obj); |
| |
| return dobj->bv; |
| } |
| |
| |
| static void dummy_set_av(Object *obj, |
| int value, |
| Error **errp) |
| { |
| DummyObject *dobj = DUMMY_OBJECT(obj); |
| |
| dobj->av = value; |
| } |
| |
| static int dummy_get_av(Object *obj, |
| Error **errp) |
| { |
| DummyObject *dobj = DUMMY_OBJECT(obj); |
| |
| return dobj->av; |
| } |
| |
| |
| static void dummy_set_sv(Object *obj, |
| const char *value, |
| Error **errp) |
| { |
| DummyObject *dobj = DUMMY_OBJECT(obj); |
| |
| g_free(dobj->sv); |
| dobj->sv = g_strdup(value); |
| } |
| |
| static char *dummy_get_sv(Object *obj, |
| Error **errp) |
| { |
| DummyObject *dobj = DUMMY_OBJECT(obj); |
| |
| return g_strdup(dobj->sv); |
| } |
| |
| |
| static void dummy_init(Object *obj) |
| { |
| object_property_add_bool(obj, "bv", |
| dummy_get_bv, |
| dummy_set_bv, |
| NULL); |
| object_property_add_str(obj, "sv", |
| dummy_get_sv, |
| dummy_set_sv, |
| NULL); |
| object_property_add_enum(obj, "av", |
| "DummyAnimal", |
| dummy_animal_map, |
| dummy_get_av, |
| dummy_set_av, |
| NULL); |
| } |
| |
| static void dummy_finalize(Object *obj) |
| { |
| DummyObject *dobj = DUMMY_OBJECT(obj); |
| |
| g_free(dobj->sv); |
| } |
| |
| |
| static const TypeInfo dummy_info = { |
| .name = TYPE_DUMMY, |
| .parent = TYPE_OBJECT, |
| .instance_size = sizeof(DummyObject), |
| .instance_init = dummy_init, |
| .instance_finalize = dummy_finalize, |
| .class_size = sizeof(DummyObjectClass), |
| }; |
| |
| static void test_dummy_createv(void) |
| { |
| Error *err = NULL; |
| Object *parent = object_get_objects_root(); |
| DummyObject *dobj = DUMMY_OBJECT( |
| object_new_with_props(TYPE_DUMMY, |
| parent, |
| "dummy0", |
| &err, |
| "bv", "yes", |
| "sv", "Hiss hiss hiss", |
| "av", "platypus", |
| NULL)); |
| |
| g_assert(err == NULL); |
| g_assert_cmpstr(dobj->sv, ==, "Hiss hiss hiss"); |
| g_assert(dobj->bv == true); |
| g_assert(dobj->av == DUMMY_PLATYPUS); |
| |
| g_assert(object_resolve_path_component(parent, "dummy0") |
| == OBJECT(dobj)); |
| |
| object_unparent(OBJECT(dobj)); |
| } |
| |
| |
| static Object *new_helper(Error **errp, |
| Object *parent, |
| ...) |
| { |
| va_list vargs; |
| Object *obj; |
| |
| va_start(vargs, parent); |
| obj = object_new_with_propv(TYPE_DUMMY, |
| parent, |
| "dummy0", |
| errp, |
| vargs); |
| va_end(vargs); |
| return obj; |
| } |
| |
| static void test_dummy_createlist(void) |
| { |
| Error *err = NULL; |
| Object *parent = object_get_objects_root(); |
| DummyObject *dobj = DUMMY_OBJECT( |
| new_helper(&err, |
| parent, |
| "bv", "yes", |
| "sv", "Hiss hiss hiss", |
| "av", "platypus", |
| NULL)); |
| |
| g_assert(err == NULL); |
| g_assert_cmpstr(dobj->sv, ==, "Hiss hiss hiss"); |
| g_assert(dobj->bv == true); |
| g_assert(dobj->av == DUMMY_PLATYPUS); |
| |
| g_assert(object_resolve_path_component(parent, "dummy0") |
| == OBJECT(dobj)); |
| |
| object_unparent(OBJECT(dobj)); |
| } |
| |
| static void test_dummy_badenum(void) |
| { |
| Error *err = NULL; |
| Object *parent = object_get_objects_root(); |
| Object *dobj = |
| object_new_with_props(TYPE_DUMMY, |
| parent, |
| "dummy0", |
| &err, |
| "bv", "yes", |
| "sv", "Hiss hiss hiss", |
| "av", "yeti", |
| NULL); |
| |
| g_assert(dobj == NULL); |
| g_assert(err != NULL); |
| g_assert_cmpstr(error_get_pretty(err), ==, |
| "Invalid parameter 'yeti'"); |
| |
| g_assert(object_resolve_path_component(parent, "dummy0") |
| == NULL); |
| |
| error_free(err); |
| } |
| |
| |
| static void test_dummy_getenum(void) |
| { |
| Error *err = NULL; |
| int val; |
| Object *parent = object_get_objects_root(); |
| DummyObject *dobj = DUMMY_OBJECT( |
| object_new_with_props(TYPE_DUMMY, |
| parent, |
| "dummy0", |
| &err, |
| "av", "platypus", |
| NULL)); |
| |
| g_assert(err == NULL); |
| g_assert(dobj->av == DUMMY_PLATYPUS); |
| |
| val = object_property_get_enum(OBJECT(dobj), |
| "av", |
| "DummyAnimal", |
| &err); |
| g_assert(err == NULL); |
| g_assert(val == DUMMY_PLATYPUS); |
| |
| /* A bad enum type name */ |
| val = object_property_get_enum(OBJECT(dobj), |
| "av", |
| "BadAnimal", |
| &err); |
| g_assert(err != NULL); |
| error_free(err); |
| err = NULL; |
| |
| /* A non-enum property name */ |
| val = object_property_get_enum(OBJECT(dobj), |
| "iv", |
| "DummyAnimal", |
| &err); |
| g_assert(err != NULL); |
| error_free(err); |
| } |
| |
| |
| int main(int argc, char **argv) |
| { |
| g_test_init(&argc, &argv, NULL); |
| |
| module_call_init(MODULE_INIT_QOM); |
| type_register_static(&dummy_info); |
| |
| g_test_add_func("/qom/proplist/createlist", test_dummy_createlist); |
| g_test_add_func("/qom/proplist/createv", test_dummy_createv); |
| g_test_add_func("/qom/proplist/badenum", test_dummy_badenum); |
| g_test_add_func("/qom/proplist/getenum", test_dummy_getenum); |
| |
| return g_test_run(); |
| } |