]> Git Repo - qemu.git/blob - test-visitor.c
syborg_pointer: convert to memory API
[qemu.git] / test-visitor.c
1 #include <glib.h>
2 #include "qapi/qmp-output-visitor.h"
3 #include "qapi/qmp-input-visitor.h"
4 #include "test-qapi-types.h"
5 #include "test-qapi-visit.h"
6 #include "qemu-objects.h"
7
8 typedef struct TestStruct
9 {
10     int64_t x;
11     int64_t y;
12 } TestStruct;
13
14 typedef struct TestStructList
15 {
16     TestStruct *value;
17     struct TestStructList *next;
18 } TestStructList;
19
20 static void visit_type_TestStruct(Visitor *v, TestStruct **obj, const char *name, Error **errp)
21 {
22     visit_start_struct(v, (void **)obj, "TestStruct", name, sizeof(TestStruct), errp);
23     visit_type_int(v, &(*obj)->x, "x", errp);
24     visit_type_int(v, &(*obj)->y, "y", errp);
25     visit_end_struct(v, errp);
26 }
27
28 static void visit_type_TestStructList(Visitor *m, TestStructList ** obj, const char *name, Error **errp)
29 {
30     GenericList *i, **head = (GenericList **)obj;
31
32     visit_start_list(m, name, errp);
33
34     for (*head = i = visit_next_list(m, head, errp); i; i = visit_next_list(m, &i, errp)) {
35         TestStructList *native_i = (TestStructList *)i;
36         visit_type_TestStruct(m, &native_i->value, NULL, errp);
37     }
38
39     visit_end_list(m, errp);
40 }
41
42 /* test core visitor methods */
43 static void test_visitor_core(void)
44 {
45     QmpOutputVisitor *mo;
46     QmpInputVisitor *mi;
47     Visitor *v;
48     TestStruct ts = { 42, 82 };
49     TestStruct *pts = &ts;
50     TestStructList *lts = NULL;
51     Error *err = NULL;
52     QObject *obj;
53     QList *qlist;
54     QDict *qdict;
55     QString *str;
56     int64_t value = 0;
57
58     mo = qmp_output_visitor_new();
59     v = qmp_output_get_visitor(mo);
60
61     visit_type_TestStruct(v, &pts, NULL, &err);
62
63     obj = qmp_output_get_qobject(mo);
64
65     str = qobject_to_json(obj);
66
67     printf("%s\n", qstring_get_str(str));
68
69     QDECREF(str);
70
71     obj = QOBJECT(qint_from_int(0x42));
72
73     mi = qmp_input_visitor_new(obj);
74     v = qmp_input_get_visitor(mi);
75
76     visit_type_int(v, &value, NULL, &err);
77     if (err) {
78         g_error("%s", error_get_pretty(err));
79     }
80
81     g_assert(value == 0x42);
82
83     qobject_decref(obj);
84
85     obj = qobject_from_json("{'x': 42, 'y': 84}");
86     mi = qmp_input_visitor_new(obj);
87     v = qmp_input_get_visitor(mi);
88
89     pts = NULL;
90
91     visit_type_TestStruct(v, &pts, NULL, &err);
92     if (err) {
93         g_error("%s", error_get_pretty(err));
94     }
95
96     g_assert(pts != NULL);
97     g_assert(pts->x == 42);
98     g_assert(pts->y == 84);
99
100     qobject_decref(obj);
101     g_free(pts);
102
103     /* test list input visitor */
104     obj = qobject_from_json("[{'x': 42, 'y': 84}, {'x': 12, 'y': 24}]");
105     mi = qmp_input_visitor_new(obj);
106     v = qmp_input_get_visitor(mi);
107
108     visit_type_TestStructList(v, &lts, NULL, &err);
109     if (err) {
110         g_error("%s", error_get_pretty(err));
111     }
112
113     g_assert(lts != NULL);
114     g_assert(lts->value->x == 42);
115     g_assert(lts->value->y == 84);
116
117     g_assert(lts->next != NULL);
118     g_assert(lts->next->value->x == 12);
119     g_assert(lts->next->value->y == 24);
120     g_assert(lts->next->next == NULL);
121
122     qobject_decref(obj);
123
124     /* test list output visitor */
125     mo = qmp_output_visitor_new();
126     v = qmp_output_get_visitor(mo);
127     visit_type_TestStructList(v, &lts, NULL, &err);
128     if (err) {
129         g_error("%s", error_get_pretty(err));
130     }
131     obj = qmp_output_get_qobject(mo);
132     g_print("obj: %s\n", qstring_get_str(qobject_to_json(obj)));
133
134     qlist = qobject_to_qlist(obj);
135     assert(qlist);
136     obj = qlist_pop(qlist);
137     qdict = qobject_to_qdict(obj);
138     assert(qdict);
139     assert(qdict_get_int(qdict, "x") == 42);
140     assert(qdict_get_int(qdict, "y") == 84);
141     qobject_decref(obj);
142
143     obj = qlist_pop(qlist);
144     qdict = qobject_to_qdict(obj);
145     assert(qdict);
146     assert(qdict_get_int(qdict, "x") == 12);
147     assert(qdict_get_int(qdict, "y") == 24);
148     qobject_decref(obj);
149
150     qmp_output_visitor_cleanup(mo);
151     QDECREF(qlist);
152 }
153
154 /* test deep nesting with refs to other user-defined types */
155 static void test_nested_structs(void)
156 {
157     QmpOutputVisitor *mo;
158     QmpInputVisitor *mi;
159     Visitor *v;
160     UserDefOne ud1;
161     UserDefOne *ud1_p = &ud1, *ud1c_p = NULL;
162     UserDefTwo ud2;
163     UserDefTwo *ud2_p = &ud2, *ud2c_p = NULL;
164     Error *err = NULL;
165     QObject *obj;
166     QString *str;
167
168     ud1.integer = 42;
169     ud1.string = strdup("fourty two");
170
171     /* sanity check */
172     mo = qmp_output_visitor_new();
173     v = qmp_output_get_visitor(mo);
174     visit_type_UserDefOne(v, &ud1_p, "o_O", &err);
175     if (err) {
176         g_error("%s", error_get_pretty(err));
177     }
178     obj = qmp_output_get_qobject(mo);
179     g_assert(obj);
180     qobject_decref(obj);
181
182     ud2.string = strdup("fourty three");
183     ud2.dict.string = strdup("fourty four");
184     ud2.dict.dict.userdef = ud1_p;
185     ud2.dict.dict.string = strdup("fourty five");
186     ud2.dict.has_dict2 = true;
187     ud2.dict.dict2.userdef = ud1_p;
188     ud2.dict.dict2.string = strdup("fourty six");
189
190     /* c type -> qobject */
191     mo = qmp_output_visitor_new();
192     v = qmp_output_get_visitor(mo);
193     visit_type_UserDefTwo(v, &ud2_p, "unused", &err);
194     if (err) {
195         g_error("%s", error_get_pretty(err));
196     }
197     obj = qmp_output_get_qobject(mo);
198     g_assert(obj);
199     str = qobject_to_json_pretty(obj);
200     g_print("%s\n", qstring_get_str(str));
201     QDECREF(str);
202
203     /* qobject -> c type, should match original struct */
204     mi = qmp_input_visitor_new(obj);
205     v = qmp_input_get_visitor(mi);
206     visit_type_UserDefTwo(v, &ud2c_p, NULL, &err);
207     if (err) {
208         g_error("%s", error_get_pretty(err));
209     }
210
211     g_assert(!g_strcmp0(ud2c_p->string, ud2.string));
212     g_assert(!g_strcmp0(ud2c_p->dict.string, ud2.dict.string));
213
214     ud1c_p = ud2c_p->dict.dict.userdef;
215     g_assert(ud1c_p->integer == ud1_p->integer);
216     g_assert(!g_strcmp0(ud1c_p->string, ud1_p->string));
217
218     g_assert(!g_strcmp0(ud2c_p->dict.dict.string, ud2.dict.dict.string));
219
220     ud1c_p = ud2c_p->dict.dict2.userdef;
221     g_assert(ud1c_p->integer == ud1_p->integer);
222     g_assert(!g_strcmp0(ud1c_p->string, ud1_p->string));
223
224     g_assert(!g_strcmp0(ud2c_p->dict.dict2.string, ud2.dict.dict2.string));
225     g_free(ud1.string);
226     g_free(ud2.string);
227     g_free(ud2.dict.string);
228     g_free(ud2.dict.dict.string);
229     g_free(ud2.dict.dict2.string);
230
231     qapi_free_UserDefTwo(ud2c_p);
232
233     qobject_decref(obj);
234 }
235
236 /* test enum values */
237 static void test_enums(void)
238 {
239     QmpOutputVisitor *mo;
240     QmpInputVisitor *mi;
241     Visitor *v;
242     EnumOne enum1 = ENUM_ONE_VALUE2, enum1_cpy = ENUM_ONE_VALUE1;
243     Error *err = NULL;
244     QObject *obj;
245     QString *str;
246
247     /* C type -> QObject */
248     mo = qmp_output_visitor_new();
249     v = qmp_output_get_visitor(mo);
250     visit_type_EnumOne(v, &enum1, "unused", &err);
251     if (err) {
252         g_error("%s", error_get_pretty(err));
253     }
254     obj = qmp_output_get_qobject(mo);
255     g_assert(obj);
256     str = qobject_to_json_pretty(obj);
257     g_print("%s\n", qstring_get_str(str));
258     QDECREF(str);
259     g_assert(g_strcmp0(qstring_get_str(qobject_to_qstring(obj)), "value2") == 0);
260
261     /* QObject -> C type */
262     mi = qmp_input_visitor_new(obj);
263     v = qmp_input_get_visitor(mi);
264     visit_type_EnumOne(v, &enum1_cpy, "unused", &err);
265     if (err) {
266         g_error("%s", error_get_pretty(err));
267     }
268     g_debug("enum1_cpy, enum1: %d, %d", enum1_cpy, enum1);
269     g_assert(enum1_cpy == enum1);
270
271     qobject_decref(obj);
272 }
273
274 /* test enum values nested in schema-defined structs */
275 static void test_nested_enums(void)
276 {
277     QmpOutputVisitor *mo;
278     QmpInputVisitor *mi;
279     Visitor *v;
280     NestedEnumsOne *nested_enums, *nested_enums_cpy = NULL;
281     Error *err = NULL;
282     QObject *obj;
283     QString *str;
284
285     nested_enums = g_malloc0(sizeof(NestedEnumsOne));
286     nested_enums->enum1 = ENUM_ONE_VALUE1;
287     nested_enums->enum2 = ENUM_ONE_VALUE2;
288     nested_enums->enum3 = ENUM_ONE_VALUE3;
289     nested_enums->enum4 = ENUM_ONE_VALUE3;
290     nested_enums->has_enum2 = false;
291     nested_enums->has_enum4 = true;
292
293     /* C type -> QObject */
294     mo = qmp_output_visitor_new();
295     v = qmp_output_get_visitor(mo);
296     visit_type_NestedEnumsOne(v, &nested_enums, NULL, &err);
297     if (err) {
298         g_error("%s", error_get_pretty(err));
299     }
300     obj = qmp_output_get_qobject(mo);
301     g_assert(obj);
302     str = qobject_to_json_pretty(obj);
303     g_print("%s\n", qstring_get_str(str));
304     QDECREF(str);
305
306     /* QObject -> C type */
307     mi = qmp_input_visitor_new(obj);
308     v = qmp_input_get_visitor(mi);
309     visit_type_NestedEnumsOne(v, &nested_enums_cpy, NULL, &err);
310     if (err) {
311         g_error("%s", error_get_pretty(err));
312     }
313     g_assert(nested_enums_cpy);
314     g_assert(nested_enums_cpy->enum1 == nested_enums->enum1);
315     g_assert(nested_enums_cpy->enum3 == nested_enums->enum3);
316     g_assert(nested_enums_cpy->enum4 == nested_enums->enum4);
317     g_assert(nested_enums_cpy->has_enum2 == false);
318     g_assert(nested_enums_cpy->has_enum4 == true);
319
320     qmp_output_visitor_cleanup(mo);
321     qmp_input_visitor_cleanup(mi);
322     qapi_free_NestedEnumsOne(nested_enums);
323     qapi_free_NestedEnumsOne(nested_enums_cpy);
324 }
325
326 int main(int argc, char **argv)
327 {
328     g_test_init(&argc, &argv, NULL);
329
330     g_test_add_func("/0.15/visitor_core", test_visitor_core);
331     g_test_add_func("/0.15/nested_structs", test_nested_structs);
332     g_test_add_func("/0.15/enums", test_enums);
333     g_test_add_func("/0.15/nested_enums", test_nested_enums);
334
335     g_test_run();
336
337     return 0;
338 }
This page took 0.042786 seconds and 4 git commands to generate.