/* * 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 * . * * Author: Daniel P. Berrange */ #include #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(); }