a3590dacce
Now that properties can be explicitly registered as an enum type, there is no need to pass the string table to the object_get_enum() function. The object property registration already has a pointer to the string table. In changing this method signature, the hostmem backend object has to be converted to use the new enum property registration code, which simplifies it somewhat. Signed-off-by: Daniel P. Berrange <berrange@redhat.com> Reviewed-by: Eric Blake <eblake@redhat.com> Signed-off-by: Andreas Färber <afaerber@suse.de>
303 lines
7.7 KiB
C
303 lines
7.7 KiB
C
/*
|
|
* 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();
|
|
}
|