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