~ubuntu-branches/ubuntu/wily/qemu-kvm-spice/wily

« back to all changes in this revision

Viewing changes to test-visitor.c

  • Committer: Bazaar Package Importer
  • Author(s): Serge Hallyn
  • Date: 2011-10-19 10:44:56 UTC
  • Revision ID: james.westby@ubuntu.com-20111019104456-xgvskumk3sxi97f4
Tags: upstream-0.15.0+noroms
ImportĀ upstreamĀ versionĀ 0.15.0+noroms

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