]> git.proxmox.com Git - mirror_qemu.git/blame - tests/test-qmp-output-visitor.c
tests: Factor out common code in qapi output tests
[mirror_qemu.git] / tests / test-qmp-output-visitor.c
CommitLineData
f294f82a
LC
1/*
2 * QMP Output Visitor unit-tests.
3 *
68d07839 4 * Copyright (C) 2011-2016 Red Hat Inc.
f294f82a
LC
5 *
6 * Authors:
7 * Luiz Capitulino <lcapitulino@redhat.com>
8 *
9 * This work is licensed under the terms of the GNU GPL, version 2 or later.
10 * See the COPYING file in the top-level directory.
11 */
12
681c28a3 13#include "qemu/osdep.h"
f294f82a 14
79ee7df8 15#include "qemu-common.h"
da34e65c 16#include "qapi/error.h"
f294f82a
LC
17#include "qapi/qmp-output-visitor.h"
18#include "test-qapi-types.h"
19#include "test-qapi-visit.h"
7b1b5d19 20#include "qapi/qmp/types.h"
c7eb39cb 21#include "qapi/qmp/qjson.h"
f294f82a
LC
22
23typedef struct TestOutputVisitorData {
24 QmpOutputVisitor *qov;
25 Visitor *ov;
23d1705f 26 QObject *obj;
f294f82a
LC
27} TestOutputVisitorData;
28
29static void visitor_output_setup(TestOutputVisitorData *data,
30 const void *unused)
31{
32 data->qov = qmp_output_visitor_new();
33 g_assert(data->qov != NULL);
34
35 data->ov = qmp_output_get_visitor(data->qov);
36 g_assert(data->ov != NULL);
37}
38
39static void visitor_output_teardown(TestOutputVisitorData *data,
40 const void *unused)
41{
1830f22a 42 visit_free(data->ov);
f294f82a
LC
43 data->qov = NULL;
44 data->ov = NULL;
23d1705f
EB
45 qobject_decref(data->obj);
46 data->obj = NULL;
47}
48
49static QObject *visitor_get(TestOutputVisitorData *data)
50{
51 data->obj = qmp_output_get_qobject(data->qov);
52 g_assert(data->obj);
53 return data->obj;
f294f82a
LC
54}
55
f2ff429b
EB
56static void visitor_reset(TestOutputVisitorData *data)
57{
58 visitor_output_teardown(data, NULL);
59 visitor_output_setup(data, NULL);
60}
61
f294f82a
LC
62static void test_visitor_out_int(TestOutputVisitorData *data,
63 const void *unused)
64{
65 int64_t value = -42;
f294f82a
LC
66 QObject *obj;
67
51e72bc1 68 visit_type_int(data->ov, NULL, &value, &error_abort);
f294f82a 69
23d1705f 70 obj = visitor_get(data);
f294f82a
LC
71 g_assert(qobject_type(obj) == QTYPE_QINT);
72 g_assert_cmpint(qint_get_int(qobject_to_qint(obj)), ==, value);
f294f82a
LC
73}
74
75static void test_visitor_out_bool(TestOutputVisitorData *data,
76 const void *unused)
77{
f294f82a
LC
78 bool value = true;
79 QObject *obj;
80
51e72bc1 81 visit_type_bool(data->ov, NULL, &value, &error_abort);
f294f82a 82
23d1705f 83 obj = visitor_get(data);
f294f82a 84 g_assert(qobject_type(obj) == QTYPE_QBOOL);
fc48ffc3 85 g_assert(qbool_get_bool(qobject_to_qbool(obj)) == value);
f294f82a
LC
86}
87
88static void test_visitor_out_number(TestOutputVisitorData *data,
89 const void *unused)
90{
91 double value = 3.14;
f294f82a
LC
92 QObject *obj;
93
51e72bc1 94 visit_type_number(data->ov, NULL, &value, &error_abort);
f294f82a 95
23d1705f 96 obj = visitor_get(data);
f294f82a
LC
97 g_assert(qobject_type(obj) == QTYPE_QFLOAT);
98 g_assert(qfloat_get_double(qobject_to_qfloat(obj)) == value);
f294f82a
LC
99}
100
101static void test_visitor_out_string(TestOutputVisitorData *data,
102 const void *unused)
103{
104 char *string = (char *) "Q E M U";
f294f82a
LC
105 QObject *obj;
106
51e72bc1 107 visit_type_str(data->ov, NULL, &string, &error_abort);
f294f82a 108
23d1705f 109 obj = visitor_get(data);
f294f82a
LC
110 g_assert(qobject_type(obj) == QTYPE_QSTRING);
111 g_assert_cmpstr(qstring_get_str(qobject_to_qstring(obj)), ==, string);
f294f82a
LC
112}
113
114static void test_visitor_out_no_string(TestOutputVisitorData *data,
115 const void *unused)
116{
117 char *string = NULL;
f294f82a
LC
118 QObject *obj;
119
120 /* A null string should return "" */
51e72bc1 121 visit_type_str(data->ov, NULL, &string, &error_abort);
f294f82a 122
23d1705f 123 obj = visitor_get(data);
f294f82a
LC
124 g_assert(qobject_type(obj) == QTYPE_QSTRING);
125 g_assert_cmpstr(qstring_get_str(qobject_to_qstring(obj)), ==, "");
f294f82a
LC
126}
127
128static void test_visitor_out_enum(TestOutputVisitorData *data,
129 const void *unused)
130{
f294f82a
LC
131 QObject *obj;
132 EnumOne i;
133
7fb1cf16 134 for (i = 0; i < ENUM_ONE__MAX; i++) {
51e72bc1 135 visit_type_EnumOne(data->ov, "unused", &i, &error_abort);
f294f82a 136
23d1705f 137 obj = visitor_get(data);
f294f82a
LC
138 g_assert(qobject_type(obj) == QTYPE_QSTRING);
139 g_assert_cmpstr(qstring_get_str(qobject_to_qstring(obj)), ==,
140 EnumOne_lookup[i]);
f2ff429b 141 visitor_reset(data);
f294f82a
LC
142 }
143}
144
145static void test_visitor_out_enum_errors(TestOutputVisitorData *data,
146 const void *unused)
147{
7fb1cf16 148 EnumOne i, bad_values[] = { ENUM_ONE__MAX, -1 };
e940f543 149 Error *err;
f294f82a
LC
150
151 for (i = 0; i < ARRAY_SIZE(bad_values) ; i++) {
e940f543 152 err = NULL;
51e72bc1 153 visit_type_EnumOne(data->ov, "unused", &bad_values[i], &err);
e940f543
MA
154 g_assert(err);
155 error_free(err);
f2ff429b 156 visitor_reset(data);
f294f82a
LC
157 }
158}
159
f294f82a
LC
160
161static void test_visitor_out_struct(TestOutputVisitorData *data,
162 const void *unused)
163{
164 TestStruct test_struct = { .integer = 42,
165 .boolean = false,
166 .string = (char *) "foo"};
167 TestStruct *p = &test_struct;
f294f82a
LC
168 QObject *obj;
169 QDict *qdict;
170
51e72bc1 171 visit_type_TestStruct(data->ov, NULL, &p, &error_abort);
f294f82a 172
23d1705f 173 obj = visitor_get(data);
f294f82a
LC
174 g_assert(qobject_type(obj) == QTYPE_QDICT);
175
176 qdict = qobject_to_qdict(obj);
177 g_assert_cmpint(qdict_size(qdict), ==, 3);
178 g_assert_cmpint(qdict_get_int(qdict, "integer"), ==, 42);
34acbc95 179 g_assert_cmpint(qdict_get_bool(qdict, "boolean"), ==, false);
f294f82a 180 g_assert_cmpstr(qdict_get_str(qdict, "string"), ==, "foo");
f294f82a
LC
181}
182
183static void test_visitor_out_struct_nested(TestOutputVisitorData *data,
184 const void *unused)
185{
186 int64_t value = 42;
b6fcf32d 187 UserDefTwo *ud2;
f294f82a
LC
188 QObject *obj;
189 QDict *qdict, *dict1, *dict2, *dict3, *userdef;
190 const char *string = "user def string";
beae9d79
SW
191 const char *strings[] = { "forty two", "forty three", "forty four",
192 "forty five" };
f294f82a
LC
193
194 ud2 = g_malloc0(sizeof(*ud2));
195 ud2->string0 = g_strdup(strings[0]);
196
6446a592
EB
197 ud2->dict1 = g_malloc0(sizeof(*ud2->dict1));
198 ud2->dict1->string1 = g_strdup(strings[1]);
199
200 ud2->dict1->dict2 = g_malloc0(sizeof(*ud2->dict1->dict2));
201 ud2->dict1->dict2->userdef = g_new0(UserDefOne, 1);
202 ud2->dict1->dict2->userdef->string = g_strdup(string);
ddf21908 203 ud2->dict1->dict2->userdef->integer = value;
6446a592
EB
204 ud2->dict1->dict2->string = g_strdup(strings[2]);
205
206 ud2->dict1->dict3 = g_malloc0(sizeof(*ud2->dict1->dict3));
207 ud2->dict1->has_dict3 = true;
208 ud2->dict1->dict3->userdef = g_new0(UserDefOne, 1);
209 ud2->dict1->dict3->userdef->string = g_strdup(string);
ddf21908 210 ud2->dict1->dict3->userdef->integer = value;
6446a592 211 ud2->dict1->dict3->string = g_strdup(strings[3]);
f294f82a 212
51e72bc1 213 visit_type_UserDefTwo(data->ov, "unused", &ud2, &error_abort);
f294f82a 214
23d1705f 215 obj = visitor_get(data);
f294f82a
LC
216 g_assert(qobject_type(obj) == QTYPE_QDICT);
217
218 qdict = qobject_to_qdict(obj);
219 g_assert_cmpint(qdict_size(qdict), ==, 2);
220 g_assert_cmpstr(qdict_get_str(qdict, "string0"), ==, strings[0]);
221
222 dict1 = qdict_get_qdict(qdict, "dict1");
223 g_assert_cmpint(qdict_size(dict1), ==, 3);
224 g_assert_cmpstr(qdict_get_str(dict1, "string1"), ==, strings[1]);
225
226 dict2 = qdict_get_qdict(dict1, "dict2");
227 g_assert_cmpint(qdict_size(dict2), ==, 2);
b6fcf32d
EB
228 g_assert_cmpstr(qdict_get_str(dict2, "string"), ==, strings[2]);
229 userdef = qdict_get_qdict(dict2, "userdef");
f294f82a
LC
230 g_assert_cmpint(qdict_size(userdef), ==, 2);
231 g_assert_cmpint(qdict_get_int(userdef, "integer"), ==, value);
232 g_assert_cmpstr(qdict_get_str(userdef, "string"), ==, string);
233
234 dict3 = qdict_get_qdict(dict1, "dict3");
235 g_assert_cmpint(qdict_size(dict3), ==, 2);
b6fcf32d
EB
236 g_assert_cmpstr(qdict_get_str(dict3, "string"), ==, strings[3]);
237 userdef = qdict_get_qdict(dict3, "userdef");
f294f82a
LC
238 g_assert_cmpint(qdict_size(userdef), ==, 2);
239 g_assert_cmpint(qdict_get_int(userdef, "integer"), ==, value);
240 g_assert_cmpstr(qdict_get_str(userdef, "string"), ==, string);
241
b6fcf32d 242 qapi_free_UserDefTwo(ud2);
f294f82a
LC
243}
244
9e9eace8
PB
245static void test_visitor_out_struct_errors(TestOutputVisitorData *data,
246 const void *unused)
247{
7fb1cf16 248 EnumOne bad_values[] = { ENUM_ONE__MAX, -1 };
ddf21908
EB
249 UserDefOne u = {0};
250 UserDefOne *pu = &u;
e940f543 251 Error *err;
9e9eace8
PB
252 int i;
253
254 for (i = 0; i < ARRAY_SIZE(bad_values) ; i++) {
e940f543 255 err = NULL;
9e9eace8
PB
256 u.has_enum1 = true;
257 u.enum1 = bad_values[i];
51e72bc1 258 visit_type_UserDefOne(data->ov, "unused", &pu, &err);
e940f543
MA
259 g_assert(err);
260 error_free(err);
f2ff429b 261 visitor_reset(data);
9e9eace8
PB
262 }
263}
264
f294f82a
LC
265
266static void test_visitor_out_list(TestOutputVisitorData *data,
267 const void *unused)
268{
bd20588d 269 const char *value_str = "list value";
f294f82a
LC
270 TestStructList *p, *head = NULL;
271 const int max_items = 10;
272 bool value_bool = true;
273 int value_int = 10;
f294f82a
LC
274 QListEntry *entry;
275 QObject *obj;
276 QList *qlist;
277 int i;
278
bd20588d 279 /* Build the list in reverse order... */
f294f82a
LC
280 for (i = 0; i < max_items; i++) {
281 p = g_malloc0(sizeof(*p));
282 p->value = g_malloc0(sizeof(*p->value));
bd20588d 283 p->value->integer = value_int + (max_items - i - 1);
f294f82a 284 p->value->boolean = value_bool;
bd20588d 285 p->value->string = g_strdup(value_str);
f294f82a
LC
286
287 p->next = head;
288 head = p;
289 }
290
51e72bc1 291 visit_type_TestStructList(data->ov, NULL, &head, &error_abort);
f294f82a 292
23d1705f 293 obj = visitor_get(data);
f294f82a
LC
294 g_assert(qobject_type(obj) == QTYPE_QLIST);
295
296 qlist = qobject_to_qlist(obj);
297 g_assert(!qlist_empty(qlist));
298
bd20588d 299 /* ...and ensure that the visitor sees it in order */
f294f82a
LC
300 i = 0;
301 QLIST_FOREACH_ENTRY(qlist, entry) {
302 QDict *qdict;
303
304 g_assert(qobject_type(entry->value) == QTYPE_QDICT);
305 qdict = qobject_to_qdict(entry->value);
306 g_assert_cmpint(qdict_size(qdict), ==, 3);
bd20588d 307 g_assert_cmpint(qdict_get_int(qdict, "integer"), ==, value_int + i);
f294f82a
LC
308 g_assert_cmpint(qdict_get_bool(qdict, "boolean"), ==, value_bool);
309 g_assert_cmpstr(qdict_get_str(qdict, "string"), ==, value_str);
310 i++;
311 }
312 g_assert_cmpint(i, ==, max_items);
313
bd20588d 314 qapi_free_TestStructList(head);
f294f82a
LC
315}
316
317static void test_visitor_out_list_qapi_free(TestOutputVisitorData *data,
318 const void *unused)
319{
b6fcf32d 320 UserDefTwoList *p, *head = NULL;
f294f82a
LC
321 const char string[] = "foo bar";
322 int i, max_count = 1024;
323
324 for (i = 0; i < max_count; i++) {
325 p = g_malloc0(sizeof(*p));
326 p->value = g_malloc0(sizeof(*p->value));
327
328 p->value->string0 = g_strdup(string);
6446a592
EB
329 p->value->dict1 = g_new0(UserDefTwoDict, 1);
330 p->value->dict1->string1 = g_strdup(string);
331 p->value->dict1->dict2 = g_new0(UserDefTwoDictDict, 1);
332 p->value->dict1->dict2->userdef = g_new0(UserDefOne, 1);
333 p->value->dict1->dict2->userdef->string = g_strdup(string);
ddf21908 334 p->value->dict1->dict2->userdef->integer = 42;
6446a592
EB
335 p->value->dict1->dict2->string = g_strdup(string);
336 p->value->dict1->has_dict3 = false;
f294f82a
LC
337
338 p->next = head;
339 head = p;
340 }
341
b6fcf32d 342 qapi_free_UserDefTwoList(head);
f294f82a
LC
343}
344
28770e05
MA
345static void test_visitor_out_any(TestOutputVisitorData *data,
346 const void *unused)
347{
348 QObject *qobj;
28770e05
MA
349 QInt *qint;
350 QBool *qbool;
351 QString *qstring;
352 QDict *qdict;
353 QObject *obj;
354
355 qobj = QOBJECT(qint_from_int(-42));
51e72bc1 356 visit_type_any(data->ov, NULL, &qobj, &error_abort);
23d1705f 357 obj = visitor_get(data);
28770e05
MA
358 g_assert(qobject_type(obj) == QTYPE_QINT);
359 g_assert_cmpint(qint_get_int(qobject_to_qint(obj)), ==, -42);
28770e05
MA
360 qobject_decref(qobj);
361
f2ff429b 362 visitor_reset(data);
28770e05
MA
363 qdict = qdict_new();
364 qdict_put(qdict, "integer", qint_from_int(-42));
365 qdict_put(qdict, "boolean", qbool_from_bool(true));
366 qdict_put(qdict, "string", qstring_from_str("foo"));
367 qobj = QOBJECT(qdict);
51e72bc1 368 visit_type_any(data->ov, NULL, &qobj, &error_abort);
b18f1141 369 qobject_decref(qobj);
23d1705f 370 obj = visitor_get(data);
28770e05
MA
371 qdict = qobject_to_qdict(obj);
372 g_assert(qdict);
373 qobj = qdict_get(qdict, "integer");
374 g_assert(qobj);
375 qint = qobject_to_qint(qobj);
376 g_assert(qint);
377 g_assert_cmpint(qint_get_int(qint), ==, -42);
378 qobj = qdict_get(qdict, "boolean");
379 g_assert(qobj);
380 qbool = qobject_to_qbool(qobj);
381 g_assert(qbool);
382 g_assert(qbool_get_bool(qbool) == true);
383 qobj = qdict_get(qdict, "string");
384 g_assert(qobj);
385 qstring = qobject_to_qstring(qobj);
386 g_assert(qstring);
387 g_assert_cmpstr(qstring_get_str(qstring), ==, "foo");
28770e05
MA
388}
389
2fc00432
MA
390static void test_visitor_out_union_flat(TestOutputVisitorData *data,
391 const void *unused)
392{
393 QObject *arg;
394 QDict *qdict;
395
2fc00432 396 UserDefFlatUnion *tmp = g_malloc0(sizeof(UserDefFlatUnion));
0f61af3e 397 tmp->enum1 = ENUM_ONE_VALUE1;
5223070c 398 tmp->string = g_strdup("str");
c363acef 399 tmp->integer = 41;
544a3731 400 tmp->u.value1.boolean = true;
2fc00432 401
51e72bc1 402 visit_type_UserDefFlatUnion(data->ov, NULL, &tmp, &error_abort);
23d1705f 403 arg = visitor_get(data);
2fc00432
MA
404
405 g_assert(qobject_type(arg) == QTYPE_QDICT);
406 qdict = qobject_to_qdict(arg);
407
5223070c
WX
408 g_assert_cmpstr(qdict_get_str(qdict, "enum1"), ==, "value1");
409 g_assert_cmpstr(qdict_get_str(qdict, "string"), ==, "str");
c363acef 410 g_assert_cmpint(qdict_get_int(qdict, "integer"), ==, 41);
2fc00432
MA
411 g_assert_cmpint(qdict_get_bool(qdict, "boolean"), ==, true);
412
413 qapi_free_UserDefFlatUnion(tmp);
2fc00432
MA
414}
415
ab045267
EB
416static void test_visitor_out_alternate(TestOutputVisitorData *data,
417 const void *unused)
2c38b600
MA
418{
419 QObject *arg;
12fafd7c 420 UserDefAlternate *tmp;
68d07839 421 QDict *qdict;
2c38b600 422
12fafd7c 423 tmp = g_new0(UserDefAlternate, 1);
0426d53c 424 tmp->type = QTYPE_QINT;
c363acef 425 tmp->u.i = 42;
2c38b600 426
51e72bc1 427 visit_type_UserDefAlternate(data->ov, NULL, &tmp, &error_abort);
23d1705f 428 arg = visitor_get(data);
2c38b600
MA
429
430 g_assert(qobject_type(arg) == QTYPE_QINT);
431 g_assert_cmpint(qint_get_int(qobject_to_qint(arg)), ==, 42);
432
ab045267 433 qapi_free_UserDefAlternate(tmp);
12fafd7c 434
f2ff429b 435 visitor_reset(data);
12fafd7c 436 tmp = g_new0(UserDefAlternate, 1);
0426d53c 437 tmp->type = QTYPE_QSTRING;
12fafd7c
EB
438 tmp->u.s = g_strdup("hello");
439
51e72bc1 440 visit_type_UserDefAlternate(data->ov, NULL, &tmp, &error_abort);
23d1705f 441 arg = visitor_get(data);
12fafd7c
EB
442
443 g_assert(qobject_type(arg) == QTYPE_QSTRING);
444 g_assert_cmpstr(qstring_get_str(qobject_to_qstring(arg)), ==, "hello");
445
446 qapi_free_UserDefAlternate(tmp);
68d07839 447
f2ff429b 448 visitor_reset(data);
68d07839
EB
449 tmp = g_new0(UserDefAlternate, 1);
450 tmp->type = QTYPE_QDICT;
becceedc
EB
451 tmp->u.udfu.integer = 1;
452 tmp->u.udfu.string = g_strdup("str");
453 tmp->u.udfu.enum1 = ENUM_ONE_VALUE1;
544a3731 454 tmp->u.udfu.u.value1.boolean = true;
68d07839
EB
455
456 visit_type_UserDefAlternate(data->ov, NULL, &tmp, &error_abort);
23d1705f 457 arg = visitor_get(data);
68d07839
EB
458
459 g_assert_cmpint(qobject_type(arg), ==, QTYPE_QDICT);
460 qdict = qobject_to_qdict(arg);
461 g_assert_cmpint(qdict_size(qdict), ==, 4);
462 g_assert_cmpint(qdict_get_int(qdict, "integer"), ==, 1);
463 g_assert_cmpstr(qdict_get_str(qdict, "string"), ==, "str");
464 g_assert_cmpstr(qdict_get_str(qdict, "enum1"), ==, "value1");
465 g_assert_cmpint(qdict_get_bool(qdict, "boolean"), ==, true);
466
467 qapi_free_UserDefAlternate(tmp);
2c38b600
MA
468}
469
3df016f1
EB
470static void test_visitor_out_null(TestOutputVisitorData *data,
471 const void *unused)
a199b2b6
MA
472{
473 QObject *arg;
3df016f1
EB
474 QDict *qdict;
475 QObject *nil;
a199b2b6 476
3df016f1
EB
477 visit_start_struct(data->ov, NULL, NULL, 0, &error_abort);
478 visit_type_null(data->ov, "a", &error_abort);
15c2f669 479 visit_check_struct(data->ov, &error_abort);
1158bb2a 480 visit_end_struct(data->ov, NULL);
23d1705f 481 arg = visitor_get(data);
3df016f1
EB
482 g_assert(qobject_type(arg) == QTYPE_QDICT);
483 qdict = qobject_to_qdict(arg);
484 g_assert_cmpint(qdict_size(qdict), ==, 1);
485 nil = qdict_get(qdict, "a");
486 g_assert(nil);
487 g_assert(qobject_type(nil) == QTYPE_QNULL);
a199b2b6
MA
488}
489
83c84667
MR
490static void init_native_list(UserDefNativeListUnion *cvalue)
491{
492 int i;
c363acef 493 switch (cvalue->type) {
83c84667 494 case USER_DEF_NATIVE_LIST_UNION_KIND_INTEGER: {
32bafa8f 495 intList **list = &cvalue->u.integer.data;
83c84667
MR
496 for (i = 0; i < 32; i++) {
497 *list = g_new0(intList, 1);
498 (*list)->value = i;
499 (*list)->next = NULL;
500 list = &(*list)->next;
501 }
502 break;
503 }
504 case USER_DEF_NATIVE_LIST_UNION_KIND_S8: {
32bafa8f 505 int8List **list = &cvalue->u.s8.data;
83c84667
MR
506 for (i = 0; i < 32; i++) {
507 *list = g_new0(int8List, 1);
508 (*list)->value = i;
509 (*list)->next = NULL;
510 list = &(*list)->next;
511 }
512 break;
513 }
514 case USER_DEF_NATIVE_LIST_UNION_KIND_S16: {
32bafa8f 515 int16List **list = &cvalue->u.s16.data;
83c84667
MR
516 for (i = 0; i < 32; i++) {
517 *list = g_new0(int16List, 1);
518 (*list)->value = i;
519 (*list)->next = NULL;
520 list = &(*list)->next;
521 }
522 break;
523 }
524 case USER_DEF_NATIVE_LIST_UNION_KIND_S32: {
32bafa8f 525 int32List **list = &cvalue->u.s32.data;
83c84667
MR
526 for (i = 0; i < 32; i++) {
527 *list = g_new0(int32List, 1);
528 (*list)->value = i;
529 (*list)->next = NULL;
530 list = &(*list)->next;
531 }
532 break;
533 }
534 case USER_DEF_NATIVE_LIST_UNION_KIND_S64: {
32bafa8f 535 int64List **list = &cvalue->u.s64.data;
83c84667
MR
536 for (i = 0; i < 32; i++) {
537 *list = g_new0(int64List, 1);
538 (*list)->value = i;
539 (*list)->next = NULL;
540 list = &(*list)->next;
541 }
542 break;
543 }
544 case USER_DEF_NATIVE_LIST_UNION_KIND_U8: {
32bafa8f 545 uint8List **list = &cvalue->u.u8.data;
83c84667
MR
546 for (i = 0; i < 32; i++) {
547 *list = g_new0(uint8List, 1);
548 (*list)->value = i;
549 (*list)->next = NULL;
550 list = &(*list)->next;
551 }
552 break;
553 }
554 case USER_DEF_NATIVE_LIST_UNION_KIND_U16: {
32bafa8f 555 uint16List **list = &cvalue->u.u16.data;
83c84667
MR
556 for (i = 0; i < 32; i++) {
557 *list = g_new0(uint16List, 1);
558 (*list)->value = i;
559 (*list)->next = NULL;
560 list = &(*list)->next;
561 }
562 break;
563 }
564 case USER_DEF_NATIVE_LIST_UNION_KIND_U32: {
32bafa8f 565 uint32List **list = &cvalue->u.u32.data;
83c84667
MR
566 for (i = 0; i < 32; i++) {
567 *list = g_new0(uint32List, 1);
568 (*list)->value = i;
569 (*list)->next = NULL;
570 list = &(*list)->next;
571 }
572 break;
573 }
574 case USER_DEF_NATIVE_LIST_UNION_KIND_U64: {
32bafa8f 575 uint64List **list = &cvalue->u.u64.data;
83c84667
MR
576 for (i = 0; i < 32; i++) {
577 *list = g_new0(uint64List, 1);
578 (*list)->value = i;
579 (*list)->next = NULL;
580 list = &(*list)->next;
581 }
582 break;
583 }
584 case USER_DEF_NATIVE_LIST_UNION_KIND_BOOLEAN: {
32bafa8f 585 boolList **list = &cvalue->u.boolean.data;
83c84667
MR
586 for (i = 0; i < 32; i++) {
587 *list = g_new0(boolList, 1);
588 (*list)->value = (i % 3 == 0);
589 (*list)->next = NULL;
590 list = &(*list)->next;
591 }
592 break;
593 }
594 case USER_DEF_NATIVE_LIST_UNION_KIND_STRING: {
32bafa8f 595 strList **list = &cvalue->u.string.data;
83c84667
MR
596 for (i = 0; i < 32; i++) {
597 *list = g_new0(strList, 1);
598 (*list)->value = g_strdup_printf("%d", i);
599 (*list)->next = NULL;
600 list = &(*list)->next;
601 }
602 break;
603 }
604 case USER_DEF_NATIVE_LIST_UNION_KIND_NUMBER: {
32bafa8f 605 numberList **list = &cvalue->u.number.data;
83c84667
MR
606 for (i = 0; i < 32; i++) {
607 *list = g_new0(numberList, 1);
608 (*list)->value = (double)i / 3;
609 (*list)->next = NULL;
610 list = &(*list)->next;
611 }
612 break;
613 }
614 default:
dfc6f865 615 g_assert_not_reached();
83c84667
MR
616 }
617}
618
619static void check_native_list(QObject *qobj,
620 UserDefNativeListUnionKind kind)
621{
622 QDict *qdict;
623 QList *qlist;
624 int i;
625
626 g_assert(qobj);
627 g_assert(qobject_type(qobj) == QTYPE_QDICT);
628 qdict = qobject_to_qdict(qobj);
629 g_assert(qdict);
630 g_assert(qdict_haskey(qdict, "data"));
631 qlist = qlist_copy(qobject_to_qlist(qdict_get(qdict, "data")));
632
633 switch (kind) {
634 case USER_DEF_NATIVE_LIST_UNION_KIND_S8:
635 case USER_DEF_NATIVE_LIST_UNION_KIND_S16:
636 case USER_DEF_NATIVE_LIST_UNION_KIND_S32:
637 case USER_DEF_NATIVE_LIST_UNION_KIND_S64:
638 case USER_DEF_NATIVE_LIST_UNION_KIND_U8:
639 case USER_DEF_NATIVE_LIST_UNION_KIND_U16:
640 case USER_DEF_NATIVE_LIST_UNION_KIND_U32:
641 case USER_DEF_NATIVE_LIST_UNION_KIND_U64:
642 /* all integer elements in JSON arrays get stored into QInts when
643 * we convert to QObjects, so we can check them all in the same
644 * fashion, so simply fall through here
645 */
646 case USER_DEF_NATIVE_LIST_UNION_KIND_INTEGER:
647 for (i = 0; i < 32; i++) {
648 QObject *tmp;
649 QInt *qvalue;
650 tmp = qlist_peek(qlist);
651 g_assert(tmp);
652 qvalue = qobject_to_qint(tmp);
653 g_assert_cmpint(qint_get_int(qvalue), ==, i);
654 qobject_decref(qlist_pop(qlist));
655 }
656 break;
657 case USER_DEF_NATIVE_LIST_UNION_KIND_BOOLEAN:
658 for (i = 0; i < 32; i++) {
659 QObject *tmp;
660 QBool *qvalue;
661 tmp = qlist_peek(qlist);
662 g_assert(tmp);
663 qvalue = qobject_to_qbool(tmp);
fc48ffc3 664 g_assert_cmpint(qbool_get_bool(qvalue), ==, i % 3 == 0);
83c84667
MR
665 qobject_decref(qlist_pop(qlist));
666 }
667 break;
668 case USER_DEF_NATIVE_LIST_UNION_KIND_STRING:
669 for (i = 0; i < 32; i++) {
670 QObject *tmp;
671 QString *qvalue;
672 gchar str[8];
673 tmp = qlist_peek(qlist);
674 g_assert(tmp);
675 qvalue = qobject_to_qstring(tmp);
676 sprintf(str, "%d", i);
677 g_assert_cmpstr(qstring_get_str(qvalue), ==, str);
678 qobject_decref(qlist_pop(qlist));
679 }
680 break;
681 case USER_DEF_NATIVE_LIST_UNION_KIND_NUMBER:
682 for (i = 0; i < 32; i++) {
683 QObject *tmp;
684 QFloat *qvalue;
685 GString *double_expected = g_string_new("");
686 GString *double_actual = g_string_new("");
687
688 tmp = qlist_peek(qlist);
689 g_assert(tmp);
690 qvalue = qobject_to_qfloat(tmp);
691 g_string_printf(double_expected, "%.6f", (double)i / 3);
692 g_string_printf(double_actual, "%.6f", qfloat_get_double(qvalue));
693 g_assert_cmpstr(double_actual->str, ==, double_expected->str);
694
695 qobject_decref(qlist_pop(qlist));
696 g_string_free(double_expected, true);
697 g_string_free(double_actual, true);
698 }
699 break;
700 default:
dfc6f865 701 g_assert_not_reached();
83c84667
MR
702 }
703 QDECREF(qlist);
704}
705
706static void test_native_list(TestOutputVisitorData *data,
707 const void *unused,
708 UserDefNativeListUnionKind kind)
709{
710 UserDefNativeListUnion *cvalue = g_new0(UserDefNativeListUnion, 1);
83c84667
MR
711 QObject *obj;
712
c363acef 713 cvalue->type = kind;
83c84667
MR
714 init_native_list(cvalue);
715
51e72bc1 716 visit_type_UserDefNativeListUnion(data->ov, NULL, &cvalue, &error_abort);
83c84667 717
23d1705f 718 obj = visitor_get(data);
c363acef 719 check_native_list(obj, cvalue->type);
83c84667 720 qapi_free_UserDefNativeListUnion(cvalue);
83c84667
MR
721}
722
723static void test_visitor_out_native_list_int(TestOutputVisitorData *data,
724 const void *unused)
725{
726 test_native_list(data, unused, USER_DEF_NATIVE_LIST_UNION_KIND_INTEGER);
727}
728
729static void test_visitor_out_native_list_int8(TestOutputVisitorData *data,
730 const void *unused)
731{
732 test_native_list(data, unused, USER_DEF_NATIVE_LIST_UNION_KIND_S8);
733}
734
735static void test_visitor_out_native_list_int16(TestOutputVisitorData *data,
736 const void *unused)
737{
738 test_native_list(data, unused, USER_DEF_NATIVE_LIST_UNION_KIND_S16);
739}
740
741static void test_visitor_out_native_list_int32(TestOutputVisitorData *data,
742 const void *unused)
743{
744 test_native_list(data, unused, USER_DEF_NATIVE_LIST_UNION_KIND_S32);
745}
746
747static void test_visitor_out_native_list_int64(TestOutputVisitorData *data,
748 const void *unused)
749{
750 test_native_list(data, unused, USER_DEF_NATIVE_LIST_UNION_KIND_S64);
751}
752
753static void test_visitor_out_native_list_uint8(TestOutputVisitorData *data,
754 const void *unused)
755{
756 test_native_list(data, unused, USER_DEF_NATIVE_LIST_UNION_KIND_U8);
757}
758
759static void test_visitor_out_native_list_uint16(TestOutputVisitorData *data,
760 const void *unused)
761{
762 test_native_list(data, unused, USER_DEF_NATIVE_LIST_UNION_KIND_U16);
763}
764
765static void test_visitor_out_native_list_uint32(TestOutputVisitorData *data,
766 const void *unused)
767{
768 test_native_list(data, unused, USER_DEF_NATIVE_LIST_UNION_KIND_U32);
769}
770
771static void test_visitor_out_native_list_uint64(TestOutputVisitorData *data,
772 const void *unused)
773{
774 test_native_list(data, unused, USER_DEF_NATIVE_LIST_UNION_KIND_U64);
775}
776
777static void test_visitor_out_native_list_bool(TestOutputVisitorData *data,
778 const void *unused)
779{
780 test_native_list(data, unused, USER_DEF_NATIVE_LIST_UNION_KIND_BOOLEAN);
781}
782
783static void test_visitor_out_native_list_str(TestOutputVisitorData *data,
784 const void *unused)
785{
786 test_native_list(data, unused, USER_DEF_NATIVE_LIST_UNION_KIND_STRING);
787}
788
789static void test_visitor_out_native_list_number(TestOutputVisitorData *data,
790 const void *unused)
791{
792 test_native_list(data, unused, USER_DEF_NATIVE_LIST_UNION_KIND_NUMBER);
793}
794
f294f82a
LC
795static void output_visitor_test_add(const char *testpath,
796 TestOutputVisitorData *data,
797 void (*test_func)(TestOutputVisitorData *data, const void *user_data))
798{
799 g_test_add(testpath, TestOutputVisitorData, data, visitor_output_setup,
800 test_func, visitor_output_teardown);
801}
802
803int main(int argc, char **argv)
804{
805 TestOutputVisitorData out_visitor_data;
806
807 g_test_init(&argc, &argv, NULL);
808
809 output_visitor_test_add("/visitor/output/int",
810 &out_visitor_data, test_visitor_out_int);
811 output_visitor_test_add("/visitor/output/bool",
812 &out_visitor_data, test_visitor_out_bool);
813 output_visitor_test_add("/visitor/output/number",
814 &out_visitor_data, test_visitor_out_number);
815 output_visitor_test_add("/visitor/output/string",
816 &out_visitor_data, test_visitor_out_string);
817 output_visitor_test_add("/visitor/output/no-string",
818 &out_visitor_data, test_visitor_out_no_string);
819 output_visitor_test_add("/visitor/output/enum",
820 &out_visitor_data, test_visitor_out_enum);
821 output_visitor_test_add("/visitor/output/enum-errors",
822 &out_visitor_data, test_visitor_out_enum_errors);
823 output_visitor_test_add("/visitor/output/struct",
824 &out_visitor_data, test_visitor_out_struct);
825 output_visitor_test_add("/visitor/output/struct-nested",
826 &out_visitor_data, test_visitor_out_struct_nested);
9e9eace8
PB
827 output_visitor_test_add("/visitor/output/struct-errors",
828 &out_visitor_data, test_visitor_out_struct_errors);
f294f82a
LC
829 output_visitor_test_add("/visitor/output/list",
830 &out_visitor_data, test_visitor_out_list);
28770e05
MA
831 output_visitor_test_add("/visitor/output/any",
832 &out_visitor_data, test_visitor_out_any);
f294f82a
LC
833 output_visitor_test_add("/visitor/output/list-qapi-free",
834 &out_visitor_data, test_visitor_out_list_qapi_free);
2fc00432
MA
835 output_visitor_test_add("/visitor/output/union-flat",
836 &out_visitor_data, test_visitor_out_union_flat);
ab045267
EB
837 output_visitor_test_add("/visitor/output/alternate",
838 &out_visitor_data, test_visitor_out_alternate);
3df016f1
EB
839 output_visitor_test_add("/visitor/output/null",
840 &out_visitor_data, test_visitor_out_null);
83c84667 841 output_visitor_test_add("/visitor/output/native_list/int",
805017b7
EB
842 &out_visitor_data,
843 test_visitor_out_native_list_int);
83c84667 844 output_visitor_test_add("/visitor/output/native_list/int8",
805017b7
EB
845 &out_visitor_data,
846 test_visitor_out_native_list_int8);
83c84667 847 output_visitor_test_add("/visitor/output/native_list/int16",
805017b7
EB
848 &out_visitor_data,
849 test_visitor_out_native_list_int16);
83c84667 850 output_visitor_test_add("/visitor/output/native_list/int32",
805017b7
EB
851 &out_visitor_data,
852 test_visitor_out_native_list_int32);
83c84667 853 output_visitor_test_add("/visitor/output/native_list/int64",
805017b7
EB
854 &out_visitor_data,
855 test_visitor_out_native_list_int64);
83c84667 856 output_visitor_test_add("/visitor/output/native_list/uint8",
805017b7
EB
857 &out_visitor_data,
858 test_visitor_out_native_list_uint8);
83c84667 859 output_visitor_test_add("/visitor/output/native_list/uint16",
805017b7
EB
860 &out_visitor_data,
861 test_visitor_out_native_list_uint16);
83c84667 862 output_visitor_test_add("/visitor/output/native_list/uint32",
805017b7
EB
863 &out_visitor_data,
864 test_visitor_out_native_list_uint32);
83c84667 865 output_visitor_test_add("/visitor/output/native_list/uint64",
805017b7
EB
866 &out_visitor_data,
867 test_visitor_out_native_list_uint64);
83c84667 868 output_visitor_test_add("/visitor/output/native_list/bool",
805017b7
EB
869 &out_visitor_data,
870 test_visitor_out_native_list_bool);
83c84667 871 output_visitor_test_add("/visitor/output/native_list/string",
805017b7
EB
872 &out_visitor_data,
873 test_visitor_out_native_list_str);
83c84667 874 output_visitor_test_add("/visitor/output/native_list/number",
805017b7
EB
875 &out_visitor_data,
876 test_visitor_out_native_list_number);
f294f82a
LC
877
878 g_test_run();
879
880 return 0;
881}