]> git.proxmox.com Git - mirror_qemu.git/blob - tests/check-qom-proplist.c
qom: Introduce ObjectPropertyIterator struct for iteration
[mirror_qemu.git] / tests / check-qom-proplist.c
1 /*
2 * Copyright (C) 2015 Red Hat, Inc.
3 *
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
8 *
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
13 *
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library. If not, see
16 * <http://www.gnu.org/licenses/>.
17 *
18 * Author: Daniel P. Berrange <berrange@redhat.com>
19 */
20
21 #include <glib.h>
22
23 #include "qom/object.h"
24 #include "qemu/module.h"
25
26
27 #define TYPE_DUMMY "qemu-dummy"
28
29 typedef struct DummyObject DummyObject;
30 typedef struct DummyObjectClass DummyObjectClass;
31
32 #define DUMMY_OBJECT(obj) \
33 OBJECT_CHECK(DummyObject, (obj), TYPE_DUMMY)
34
35 typedef enum DummyAnimal DummyAnimal;
36
37 enum DummyAnimal {
38 DUMMY_FROG,
39 DUMMY_ALLIGATOR,
40 DUMMY_PLATYPUS,
41
42 DUMMY_LAST,
43 };
44
45 static const char *const dummy_animal_map[DUMMY_LAST + 1] = {
46 [DUMMY_FROG] = "frog",
47 [DUMMY_ALLIGATOR] = "alligator",
48 [DUMMY_PLATYPUS] = "platypus",
49 [DUMMY_LAST] = NULL,
50 };
51
52 struct DummyObject {
53 Object parent_obj;
54
55 bool bv;
56 DummyAnimal av;
57 char *sv;
58 };
59
60 struct DummyObjectClass {
61 ObjectClass parent_class;
62 };
63
64
65 static void dummy_set_bv(Object *obj,
66 bool value,
67 Error **errp)
68 {
69 DummyObject *dobj = DUMMY_OBJECT(obj);
70
71 dobj->bv = value;
72 }
73
74 static bool dummy_get_bv(Object *obj,
75 Error **errp)
76 {
77 DummyObject *dobj = DUMMY_OBJECT(obj);
78
79 return dobj->bv;
80 }
81
82
83 static void dummy_set_av(Object *obj,
84 int value,
85 Error **errp)
86 {
87 DummyObject *dobj = DUMMY_OBJECT(obj);
88
89 dobj->av = value;
90 }
91
92 static int dummy_get_av(Object *obj,
93 Error **errp)
94 {
95 DummyObject *dobj = DUMMY_OBJECT(obj);
96
97 return dobj->av;
98 }
99
100
101 static void dummy_set_sv(Object *obj,
102 const char *value,
103 Error **errp)
104 {
105 DummyObject *dobj = DUMMY_OBJECT(obj);
106
107 g_free(dobj->sv);
108 dobj->sv = g_strdup(value);
109 }
110
111 static char *dummy_get_sv(Object *obj,
112 Error **errp)
113 {
114 DummyObject *dobj = DUMMY_OBJECT(obj);
115
116 return g_strdup(dobj->sv);
117 }
118
119
120 static void dummy_init(Object *obj)
121 {
122 object_property_add_bool(obj, "bv",
123 dummy_get_bv,
124 dummy_set_bv,
125 NULL);
126 object_property_add_str(obj, "sv",
127 dummy_get_sv,
128 dummy_set_sv,
129 NULL);
130 object_property_add_enum(obj, "av",
131 "DummyAnimal",
132 dummy_animal_map,
133 dummy_get_av,
134 dummy_set_av,
135 NULL);
136 }
137
138 static void dummy_finalize(Object *obj)
139 {
140 DummyObject *dobj = DUMMY_OBJECT(obj);
141
142 g_free(dobj->sv);
143 }
144
145
146 static const TypeInfo dummy_info = {
147 .name = TYPE_DUMMY,
148 .parent = TYPE_OBJECT,
149 .instance_size = sizeof(DummyObject),
150 .instance_init = dummy_init,
151 .instance_finalize = dummy_finalize,
152 .class_size = sizeof(DummyObjectClass),
153 };
154
155 static void test_dummy_createv(void)
156 {
157 Error *err = NULL;
158 Object *parent = object_get_objects_root();
159 DummyObject *dobj = DUMMY_OBJECT(
160 object_new_with_props(TYPE_DUMMY,
161 parent,
162 "dummy0",
163 &err,
164 "bv", "yes",
165 "sv", "Hiss hiss hiss",
166 "av", "platypus",
167 NULL));
168
169 g_assert(err == NULL);
170 g_assert_cmpstr(dobj->sv, ==, "Hiss hiss hiss");
171 g_assert(dobj->bv == true);
172 g_assert(dobj->av == DUMMY_PLATYPUS);
173
174 g_assert(object_resolve_path_component(parent, "dummy0")
175 == OBJECT(dobj));
176
177 object_unparent(OBJECT(dobj));
178 }
179
180
181 static Object *new_helper(Error **errp,
182 Object *parent,
183 ...)
184 {
185 va_list vargs;
186 Object *obj;
187
188 va_start(vargs, parent);
189 obj = object_new_with_propv(TYPE_DUMMY,
190 parent,
191 "dummy0",
192 errp,
193 vargs);
194 va_end(vargs);
195 return obj;
196 }
197
198 static void test_dummy_createlist(void)
199 {
200 Error *err = NULL;
201 Object *parent = object_get_objects_root();
202 DummyObject *dobj = DUMMY_OBJECT(
203 new_helper(&err,
204 parent,
205 "bv", "yes",
206 "sv", "Hiss hiss hiss",
207 "av", "platypus",
208 NULL));
209
210 g_assert(err == NULL);
211 g_assert_cmpstr(dobj->sv, ==, "Hiss hiss hiss");
212 g_assert(dobj->bv == true);
213 g_assert(dobj->av == DUMMY_PLATYPUS);
214
215 g_assert(object_resolve_path_component(parent, "dummy0")
216 == OBJECT(dobj));
217
218 object_unparent(OBJECT(dobj));
219 }
220
221 static void test_dummy_badenum(void)
222 {
223 Error *err = NULL;
224 Object *parent = object_get_objects_root();
225 Object *dobj =
226 object_new_with_props(TYPE_DUMMY,
227 parent,
228 "dummy0",
229 &err,
230 "bv", "yes",
231 "sv", "Hiss hiss hiss",
232 "av", "yeti",
233 NULL);
234
235 g_assert(dobj == NULL);
236 g_assert(err != NULL);
237 g_assert_cmpstr(error_get_pretty(err), ==,
238 "Invalid parameter 'yeti'");
239
240 g_assert(object_resolve_path_component(parent, "dummy0")
241 == NULL);
242
243 error_free(err);
244 }
245
246
247 static void test_dummy_getenum(void)
248 {
249 Error *err = NULL;
250 int val;
251 Object *parent = object_get_objects_root();
252 DummyObject *dobj = DUMMY_OBJECT(
253 object_new_with_props(TYPE_DUMMY,
254 parent,
255 "dummy0",
256 &err,
257 "av", "platypus",
258 NULL));
259
260 g_assert(err == NULL);
261 g_assert(dobj->av == DUMMY_PLATYPUS);
262
263 val = object_property_get_enum(OBJECT(dobj),
264 "av",
265 "DummyAnimal",
266 &err);
267 g_assert(err == NULL);
268 g_assert(val == DUMMY_PLATYPUS);
269
270 /* A bad enum type name */
271 val = object_property_get_enum(OBJECT(dobj),
272 "av",
273 "BadAnimal",
274 &err);
275 g_assert(err != NULL);
276 error_free(err);
277 err = NULL;
278
279 /* A non-enum property name */
280 val = object_property_get_enum(OBJECT(dobj),
281 "iv",
282 "DummyAnimal",
283 &err);
284 g_assert(err != NULL);
285 error_free(err);
286
287 object_unparent(OBJECT(dobj));
288 }
289
290
291 static void test_dummy_iterator(void)
292 {
293 Object *parent = object_get_objects_root();
294 DummyObject *dobj = DUMMY_OBJECT(
295 object_new_with_props(TYPE_DUMMY,
296 parent,
297 "dummy0",
298 &error_abort,
299 "bv", "yes",
300 "sv", "Hiss hiss hiss",
301 "av", "platypus",
302 NULL));
303
304 ObjectProperty *prop;
305 ObjectPropertyIterator *iter;
306 bool seenbv = false, seensv = false, seenav = false, seentype;
307
308 iter = object_property_iter_init(OBJECT(dobj));
309 while ((prop = object_property_iter_next(iter))) {
310 if (g_str_equal(prop->name, "bv")) {
311 seenbv = true;
312 } else if (g_str_equal(prop->name, "sv")) {
313 seensv = true;
314 } else if (g_str_equal(prop->name, "av")) {
315 seenav = true;
316 } else if (g_str_equal(prop->name, "type")) {
317 /* This prop comes from the base Object class */
318 seentype = true;
319 } else {
320 g_printerr("Found prop '%s'\n", prop->name);
321 g_assert_not_reached();
322 }
323 }
324 object_property_iter_free(iter);
325 g_assert(seenbv);
326 g_assert(seenav);
327 g_assert(seensv);
328 g_assert(seentype);
329
330 object_unparent(OBJECT(dobj));
331 }
332
333
334 int main(int argc, char **argv)
335 {
336 g_test_init(&argc, &argv, NULL);
337
338 module_call_init(MODULE_INIT_QOM);
339 type_register_static(&dummy_info);
340
341 g_test_add_func("/qom/proplist/createlist", test_dummy_createlist);
342 g_test_add_func("/qom/proplist/createv", test_dummy_createv);
343 g_test_add_func("/qom/proplist/badenum", test_dummy_badenum);
344 g_test_add_func("/qom/proplist/getenum", test_dummy_getenum);
345 g_test_add_func("/qom/proplist/iterator", test_dummy_iterator);
346
347 return g_test_run();
348 }