Statistics
| Branch: | Revision:

root / test-visitor.c @ 73f5e313

History | View | Annotate | Download (9.1 kB)

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