Statistics
| Branch: | Revision:

root / test-visitor.c @ 640e5404

History | View | Annotate | Download (8.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 640e5404 Michael Roth
    GenericList *i;
31 640e5404 Michael Roth
32 640e5404 Michael Roth
    visit_start_list(m, name, errp);
33 640e5404 Michael Roth
34 640e5404 Michael Roth
    for (i = visit_next_list(m, (GenericList **)obj, 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 640e5404 Michael Roth
    QString *str;
54 640e5404 Michael Roth
    int64_t value = 0;
55 640e5404 Michael Roth
56 640e5404 Michael Roth
    mo = qmp_output_visitor_new();
57 640e5404 Michael Roth
    v = qmp_output_get_visitor(mo);
58 640e5404 Michael Roth
59 640e5404 Michael Roth
    visit_type_TestStruct(v, &pts, NULL, &err);
60 640e5404 Michael Roth
61 640e5404 Michael Roth
    obj = qmp_output_get_qobject(mo);
62 640e5404 Michael Roth
63 640e5404 Michael Roth
    str = qobject_to_json(obj);
64 640e5404 Michael Roth
65 640e5404 Michael Roth
    printf("%s\n", qstring_get_str(str));
66 640e5404 Michael Roth
67 640e5404 Michael Roth
    QDECREF(str);
68 640e5404 Michael Roth
69 640e5404 Michael Roth
    obj = QOBJECT(qint_from_int(0x42));
70 640e5404 Michael Roth
71 640e5404 Michael Roth
    mi = qmp_input_visitor_new(obj);
72 640e5404 Michael Roth
    v = qmp_input_get_visitor(mi);
73 640e5404 Michael Roth
74 640e5404 Michael Roth
    visit_type_int(v, &value, NULL, &err);
75 640e5404 Michael Roth
    if (err) {
76 640e5404 Michael Roth
        g_error("%s", error_get_pretty(err));
77 640e5404 Michael Roth
    }
78 640e5404 Michael Roth
79 640e5404 Michael Roth
    g_assert(value == 0x42);
80 640e5404 Michael Roth
81 640e5404 Michael Roth
    qobject_decref(obj);
82 640e5404 Michael Roth
83 640e5404 Michael Roth
    obj = qobject_from_json("{'x': 42, 'y': 84}");
84 640e5404 Michael Roth
    mi = qmp_input_visitor_new(obj);
85 640e5404 Michael Roth
    v = qmp_input_get_visitor(mi);
86 640e5404 Michael Roth
87 640e5404 Michael Roth
    pts = NULL;
88 640e5404 Michael Roth
89 640e5404 Michael Roth
    visit_type_TestStruct(v, &pts, NULL, &err);
90 640e5404 Michael Roth
    if (err) {
91 640e5404 Michael Roth
        g_error("%s", error_get_pretty(err));
92 640e5404 Michael Roth
    }
93 640e5404 Michael Roth
94 640e5404 Michael Roth
    g_assert(pts != NULL);
95 640e5404 Michael Roth
    g_assert(pts->x == 42);
96 640e5404 Michael Roth
    g_assert(pts->y == 84);
97 640e5404 Michael Roth
98 640e5404 Michael Roth
    qobject_decref(obj);
99 640e5404 Michael Roth
100 640e5404 Michael Roth
    obj = qobject_from_json("[{'x': 42, 'y': 84}, {'x': 12, 'y': 24}]");
101 640e5404 Michael Roth
    mi = qmp_input_visitor_new(obj);
102 640e5404 Michael Roth
    v = qmp_input_get_visitor(mi);
103 640e5404 Michael Roth
104 640e5404 Michael Roth
    visit_type_TestStructList(v, &lts, NULL, &err);
105 640e5404 Michael Roth
    if (err) {
106 640e5404 Michael Roth
        g_error("%s", error_get_pretty(err));
107 640e5404 Michael Roth
    }
108 640e5404 Michael Roth
109 640e5404 Michael Roth
    g_assert(lts != NULL);
110 640e5404 Michael Roth
    g_assert(lts->value->x == 42);
111 640e5404 Michael Roth
    g_assert(lts->value->y == 84);
112 640e5404 Michael Roth
113 640e5404 Michael Roth
    lts = lts->next;
114 640e5404 Michael Roth
    g_assert(lts != NULL);
115 640e5404 Michael Roth
    g_assert(lts->value->x == 12);
116 640e5404 Michael Roth
    g_assert(lts->value->y == 24);
117 640e5404 Michael Roth
118 640e5404 Michael Roth
    g_assert(lts->next == NULL);
119 640e5404 Michael Roth
120 640e5404 Michael Roth
    qobject_decref(obj);
121 640e5404 Michael Roth
}
122 640e5404 Michael Roth
123 640e5404 Michael Roth
/* test deep nesting with refs to other user-defined types */
124 640e5404 Michael Roth
static void test_nested_structs(void)
125 640e5404 Michael Roth
{
126 640e5404 Michael Roth
    QmpOutputVisitor *mo;
127 640e5404 Michael Roth
    QmpInputVisitor *mi;
128 640e5404 Michael Roth
    Visitor *v;
129 640e5404 Michael Roth
    UserDefOne ud1;
130 640e5404 Michael Roth
    UserDefOne *ud1_p = &ud1, *ud1c_p = NULL;
131 640e5404 Michael Roth
    UserDefTwo ud2;
132 640e5404 Michael Roth
    UserDefTwo *ud2_p = &ud2, *ud2c_p = NULL;
133 640e5404 Michael Roth
    Error *err = NULL;
134 640e5404 Michael Roth
    QObject *obj;
135 640e5404 Michael Roth
    QString *str;
136 640e5404 Michael Roth
137 640e5404 Michael Roth
    ud1.integer = 42;
138 640e5404 Michael Roth
    ud1.string = strdup("fourty two");
139 640e5404 Michael Roth
140 640e5404 Michael Roth
    /* sanity check */
141 640e5404 Michael Roth
    mo = qmp_output_visitor_new();
142 640e5404 Michael Roth
    v = qmp_output_get_visitor(mo);
143 640e5404 Michael Roth
    visit_type_UserDefOne(v, &ud1_p, "o_O", &err);
144 640e5404 Michael Roth
    if (err) {
145 640e5404 Michael Roth
        g_error("%s", error_get_pretty(err));
146 640e5404 Michael Roth
    }
147 640e5404 Michael Roth
    obj = qmp_output_get_qobject(mo);
148 640e5404 Michael Roth
    g_assert(obj);
149 640e5404 Michael Roth
    qobject_decref(obj);
150 640e5404 Michael Roth
151 640e5404 Michael Roth
    ud2.string = strdup("fourty three");
152 640e5404 Michael Roth
    ud2.dict.string = strdup("fourty four");
153 640e5404 Michael Roth
    ud2.dict.dict.userdef = ud1_p;
154 640e5404 Michael Roth
    ud2.dict.dict.string = strdup("fourty five");
155 640e5404 Michael Roth
    ud2.dict.has_dict2 = true;
156 640e5404 Michael Roth
    ud2.dict.dict2.userdef = ud1_p;
157 640e5404 Michael Roth
    ud2.dict.dict2.string = strdup("fourty six");
158 640e5404 Michael Roth
159 640e5404 Michael Roth
    /* c type -> qobject */
160 640e5404 Michael Roth
    mo = qmp_output_visitor_new();
161 640e5404 Michael Roth
    v = qmp_output_get_visitor(mo);
162 640e5404 Michael Roth
    visit_type_UserDefTwo(v, &ud2_p, "unused", &err);
163 640e5404 Michael Roth
    if (err) {
164 640e5404 Michael Roth
        g_error("%s", error_get_pretty(err));
165 640e5404 Michael Roth
    }
166 640e5404 Michael Roth
    obj = qmp_output_get_qobject(mo);
167 640e5404 Michael Roth
    g_assert(obj);
168 640e5404 Michael Roth
    str = qobject_to_json_pretty(obj);
169 640e5404 Michael Roth
    g_print("%s\n", qstring_get_str(str));
170 640e5404 Michael Roth
    QDECREF(str);
171 640e5404 Michael Roth
172 640e5404 Michael Roth
    /* qobject -> c type, should match original struct */
173 640e5404 Michael Roth
    mi = qmp_input_visitor_new(obj);
174 640e5404 Michael Roth
    v = qmp_input_get_visitor(mi);
175 640e5404 Michael Roth
    visit_type_UserDefTwo(v, &ud2c_p, NULL, &err);
176 640e5404 Michael Roth
    if (err) {
177 640e5404 Michael Roth
        g_error("%s", error_get_pretty(err));
178 640e5404 Michael Roth
    }
179 640e5404 Michael Roth
180 640e5404 Michael Roth
    g_assert(!g_strcmp0(ud2c_p->string, ud2.string));
181 640e5404 Michael Roth
    g_assert(!g_strcmp0(ud2c_p->dict.string, ud2.dict.string));
182 640e5404 Michael Roth
183 640e5404 Michael Roth
    ud1c_p = ud2c_p->dict.dict.userdef;
184 640e5404 Michael Roth
    g_assert(ud1c_p->integer == ud1_p->integer);
185 640e5404 Michael Roth
    g_assert(!g_strcmp0(ud1c_p->string, ud1_p->string));
186 640e5404 Michael Roth
187 640e5404 Michael Roth
    g_assert(!g_strcmp0(ud2c_p->dict.dict.string, ud2.dict.dict.string));
188 640e5404 Michael Roth
189 640e5404 Michael Roth
    ud1c_p = ud2c_p->dict.dict2.userdef;
190 640e5404 Michael Roth
    g_assert(ud1c_p->integer == ud1_p->integer);
191 640e5404 Michael Roth
    g_assert(!g_strcmp0(ud1c_p->string, ud1_p->string));
192 640e5404 Michael Roth
193 640e5404 Michael Roth
    g_assert(!g_strcmp0(ud2c_p->dict.dict2.string, ud2.dict.dict2.string));
194 640e5404 Michael Roth
    qemu_free(ud1.string);
195 640e5404 Michael Roth
    qemu_free(ud2.string);
196 640e5404 Michael Roth
    qemu_free(ud2.dict.string);
197 640e5404 Michael Roth
    qemu_free(ud2.dict.dict.string);
198 640e5404 Michael Roth
    qemu_free(ud2.dict.dict2.string);
199 640e5404 Michael Roth
200 640e5404 Michael Roth
    qapi_free_UserDefTwo(ud2c_p);
201 640e5404 Michael Roth
202 640e5404 Michael Roth
    qobject_decref(obj);
203 640e5404 Michael Roth
}
204 640e5404 Michael Roth
205 640e5404 Michael Roth
/* test enum values */
206 640e5404 Michael Roth
static void test_enums(void)
207 640e5404 Michael Roth
{
208 640e5404 Michael Roth
    QmpOutputVisitor *mo;
209 640e5404 Michael Roth
    QmpInputVisitor *mi;
210 640e5404 Michael Roth
    Visitor *v;
211 640e5404 Michael Roth
    EnumOne enum1 = ENUM_ONE_VALUE2, enum1_cpy = ENUM_ONE_VALUE1;
212 640e5404 Michael Roth
    Error *err = NULL;
213 640e5404 Michael Roth
    QObject *obj;
214 640e5404 Michael Roth
    QString *str;
215 640e5404 Michael Roth
216 640e5404 Michael Roth
    /* C type -> QObject */
217 640e5404 Michael Roth
    mo = qmp_output_visitor_new();
218 640e5404 Michael Roth
    v = qmp_output_get_visitor(mo);
219 640e5404 Michael Roth
    visit_type_EnumOne(v, &enum1, "unused", &err);
220 640e5404 Michael Roth
    if (err) {
221 640e5404 Michael Roth
        g_error("%s", error_get_pretty(err));
222 640e5404 Michael Roth
    }
223 640e5404 Michael Roth
    obj = qmp_output_get_qobject(mo);
224 640e5404 Michael Roth
    g_assert(obj);
225 640e5404 Michael Roth
    str = qobject_to_json_pretty(obj);
226 640e5404 Michael Roth
    g_print("%s\n", qstring_get_str(str));
227 640e5404 Michael Roth
    QDECREF(str);
228 640e5404 Michael Roth
    g_assert(g_strcmp0(qstring_get_str(qobject_to_qstring(obj)), "value2") == 0);
229 640e5404 Michael Roth
230 640e5404 Michael Roth
    /* QObject -> C type */
231 640e5404 Michael Roth
    mi = qmp_input_visitor_new(obj);
232 640e5404 Michael Roth
    v = qmp_input_get_visitor(mi);
233 640e5404 Michael Roth
    visit_type_EnumOne(v, &enum1_cpy, "unused", &err);
234 640e5404 Michael Roth
    if (err) {
235 640e5404 Michael Roth
        g_error("%s", error_get_pretty(err));
236 640e5404 Michael Roth
    }
237 640e5404 Michael Roth
    g_debug("enum1_cpy, enum1: %d, %d", enum1_cpy, enum1);
238 640e5404 Michael Roth
    g_assert(enum1_cpy == enum1);
239 640e5404 Michael Roth
240 640e5404 Michael Roth
    qobject_decref(obj);
241 640e5404 Michael Roth
}
242 640e5404 Michael Roth
243 640e5404 Michael Roth
/* test enum values nested in schema-defined structs */
244 640e5404 Michael Roth
static void test_nested_enums(void)
245 640e5404 Michael Roth
{
246 640e5404 Michael Roth
    QmpOutputVisitor *mo;
247 640e5404 Michael Roth
    QmpInputVisitor *mi;
248 640e5404 Michael Roth
    Visitor *v;
249 640e5404 Michael Roth
    NestedEnumsOne *nested_enums, *nested_enums_cpy = NULL;
250 640e5404 Michael Roth
    Error *err = NULL;
251 640e5404 Michael Roth
    QObject *obj;
252 640e5404 Michael Roth
    QString *str;
253 640e5404 Michael Roth
254 640e5404 Michael Roth
    nested_enums = qemu_mallocz(sizeof(NestedEnumsOne));
255 640e5404 Michael Roth
    nested_enums->enum1 = ENUM_ONE_VALUE1;
256 640e5404 Michael Roth
    nested_enums->enum2 = ENUM_ONE_VALUE2;
257 640e5404 Michael Roth
    nested_enums->enum3 = ENUM_ONE_VALUE3;
258 640e5404 Michael Roth
    nested_enums->enum4 = ENUM_ONE_VALUE3;
259 640e5404 Michael Roth
    nested_enums->has_enum2 = false;
260 640e5404 Michael Roth
    nested_enums->has_enum4 = true;
261 640e5404 Michael Roth
262 640e5404 Michael Roth
    /* C type -> QObject */
263 640e5404 Michael Roth
    mo = qmp_output_visitor_new();
264 640e5404 Michael Roth
    v = qmp_output_get_visitor(mo);
265 640e5404 Michael Roth
    visit_type_NestedEnumsOne(v, &nested_enums, NULL, &err);
266 640e5404 Michael Roth
    if (err) {
267 640e5404 Michael Roth
        g_error("%s", error_get_pretty(err));
268 640e5404 Michael Roth
    }
269 640e5404 Michael Roth
    obj = qmp_output_get_qobject(mo);
270 640e5404 Michael Roth
    g_assert(obj);
271 640e5404 Michael Roth
    str = qobject_to_json_pretty(obj);
272 640e5404 Michael Roth
    g_print("%s\n", qstring_get_str(str));
273 640e5404 Michael Roth
    QDECREF(str);
274 640e5404 Michael Roth
275 640e5404 Michael Roth
    /* QObject -> C type */
276 640e5404 Michael Roth
    mi = qmp_input_visitor_new(obj);
277 640e5404 Michael Roth
    v = qmp_input_get_visitor(mi);
278 640e5404 Michael Roth
    visit_type_NestedEnumsOne(v, &nested_enums_cpy, NULL, &err);
279 640e5404 Michael Roth
    if (err) {
280 640e5404 Michael Roth
        g_error("%s", error_get_pretty(err));
281 640e5404 Michael Roth
    }
282 640e5404 Michael Roth
    g_assert(nested_enums_cpy);
283 640e5404 Michael Roth
    g_assert(nested_enums_cpy->enum1 == nested_enums->enum1);
284 640e5404 Michael Roth
    g_assert(nested_enums_cpy->enum3 == nested_enums->enum3);
285 640e5404 Michael Roth
    g_assert(nested_enums_cpy->enum4 == nested_enums->enum4);
286 640e5404 Michael Roth
    g_assert(nested_enums_cpy->has_enum2 == false);
287 640e5404 Michael Roth
    g_assert(nested_enums_cpy->has_enum4 == true);
288 640e5404 Michael Roth
289 640e5404 Michael Roth
    qobject_decref(obj);
290 640e5404 Michael Roth
    qapi_free_NestedEnumsOne(nested_enums);
291 640e5404 Michael Roth
    qapi_free_NestedEnumsOne(nested_enums_cpy);
292 640e5404 Michael Roth
}
293 640e5404 Michael Roth
294 640e5404 Michael Roth
int main(int argc, char **argv)
295 640e5404 Michael Roth
{
296 640e5404 Michael Roth
    g_test_init(&argc, &argv, NULL);
297 640e5404 Michael Roth
298 640e5404 Michael Roth
    g_test_add_func("/0.15/visitor_core", test_visitor_core);
299 640e5404 Michael Roth
    g_test_add_func("/0.15/nested_structs", test_nested_structs);
300 640e5404 Michael Roth
    g_test_add_func("/0.15/enums", test_enums);
301 640e5404 Michael Roth
    g_test_add_func("/0.15/nested_enums", test_nested_enums);
302 640e5404 Michael Roth
303 640e5404 Michael Roth
    g_test_run();
304 640e5404 Michael Roth
305 640e5404 Michael Roth
    return 0;
306 640e5404 Michael Roth
}