~ahs3/+junk/cq-qemu

« back to all changes in this revision

Viewing changes to test-visitor.c

  • Committer: Al Stone
  • Date: 2012-02-09 01:17:20 UTC
  • Revision ID: albert.stone@canonical.com-20120209011720-tztl7ik3qayz80p4
first commit to bzr for qemu

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
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
}