]> git.proxmox.com Git - mirror_qemu.git/blame - tests/test-qobject-output-visitor.c
Merge remote-tracking branch 'remotes/kraxel/tags/opengl-20171017-pull-request' into...
[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
LC
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 {
f294f82a 24 Visitor *ov;
23d1705f 25 QObject *obj;
f294f82a
LC
26} TestOutputVisitorData;
27
28static void visitor_output_setup(TestOutputVisitorData *data,
29 const void *unused)
30{
7d5e199a 31 data->ov = qobject_output_visitor_new(&data->obj);
3b098d56 32 g_assert(data->ov);
f294f82a
LC
33}
34
35static void visitor_output_teardown(TestOutputVisitorData *data,
36 const void *unused)
37{
1830f22a 38 visit_free(data->ov);
f294f82a 39 data->ov = NULL;
23d1705f
EB
40 qobject_decref(data->obj);
41 data->obj = NULL;
42}
43
44static QObject *visitor_get(TestOutputVisitorData *data)
45{
3b098d56 46 visit_complete(data->ov, &data->obj);
23d1705f
EB
47 g_assert(data->obj);
48 return data->obj;
f294f82a
LC
49}
50
f2ff429b
EB
51static void visitor_reset(TestOutputVisitorData *data)
52{
53 visitor_output_teardown(data, NULL);
54 visitor_output_setup(data, NULL);
55}
56
f294f82a
LC
57static void test_visitor_out_int(TestOutputVisitorData *data,
58 const void *unused)
59{
60 int64_t value = -42;
01b2ffce
MAL
61 int64_t val;
62 QNum *qnum;
f294f82a 63
51e72bc1 64 visit_type_int(data->ov, NULL, &value, &error_abort);
f294f82a 65
01b2ffce
MAL
66 qnum = qobject_to_qnum(visitor_get(data));
67 g_assert(qnum);
68 g_assert(qnum_get_try_int(qnum, &val));
69 g_assert_cmpint(val, ==, value);
f294f82a
LC
70}
71
72static void test_visitor_out_bool(TestOutputVisitorData *data,
73 const void *unused)
74{
f294f82a 75 bool value = true;
dfad9ec4 76 QBool *qbool;
f294f82a 77
51e72bc1 78 visit_type_bool(data->ov, NULL, &value, &error_abort);
f294f82a 79
dfad9ec4
MA
80 qbool = qobject_to_qbool(visitor_get(data));
81 g_assert(qbool);
82 g_assert(qbool_get_bool(qbool) == value);
f294f82a
LC
83}
84
85static void test_visitor_out_number(TestOutputVisitorData *data,
86 const void *unused)
87{
88 double value = 3.14;
01b2ffce 89 QNum *qnum;
f294f82a 90
51e72bc1 91 visit_type_number(data->ov, NULL, &value, &error_abort);
f294f82a 92
01b2ffce
MAL
93 qnum = qobject_to_qnum(visitor_get(data));
94 g_assert(qnum);
95 g_assert(qnum_get_double(qnum) == value);
f294f82a
LC
96}
97
98static void test_visitor_out_string(TestOutputVisitorData *data,
99 const void *unused)
100{
101 char *string = (char *) "Q E M U";
363e13f8 102 QString *qstr;
f294f82a 103
51e72bc1 104 visit_type_str(data->ov, NULL, &string, &error_abort);
f294f82a 105
363e13f8
MA
106 qstr = qobject_to_qstring(visitor_get(data));
107 g_assert(qstr);
108 g_assert_cmpstr(qstring_get_str(qstr), ==, string);
f294f82a
LC
109}
110
111static void test_visitor_out_no_string(TestOutputVisitorData *data,
112 const void *unused)
113{
114 char *string = NULL;
363e13f8 115 QString *qstr;
f294f82a
LC
116
117 /* A null string should return "" */
51e72bc1 118 visit_type_str(data->ov, NULL, &string, &error_abort);
f294f82a 119
363e13f8
MA
120 qstr = qobject_to_qstring(visitor_get(data));
121 g_assert(qstr);
122 g_assert_cmpstr(qstring_get_str(qstr), ==, "");
f294f82a
LC
123}
124
125static void test_visitor_out_enum(TestOutputVisitorData *data,
126 const void *unused)
127{
f294f82a 128 EnumOne i;
363e13f8 129 QString *qstr;
f294f82a 130
7fb1cf16 131 for (i = 0; i < ENUM_ONE__MAX; i++) {
51e72bc1 132 visit_type_EnumOne(data->ov, "unused", &i, &error_abort);
f294f82a 133
363e13f8
MA
134 qstr = qobject_to_qstring(visitor_get(data));
135 g_assert(qstr);
977c736f 136 g_assert_cmpstr(qstring_get_str(qstr), ==, EnumOne_str(i));
f2ff429b 137 visitor_reset(data);
f294f82a
LC
138 }
139}
140
141static void test_visitor_out_enum_errors(TestOutputVisitorData *data,
142 const void *unused)
143{
7fb1cf16 144 EnumOne i, bad_values[] = { ENUM_ONE__MAX, -1 };
e940f543 145 Error *err;
f294f82a
LC
146
147 for (i = 0; i < ARRAY_SIZE(bad_values) ; i++) {
e940f543 148 err = NULL;
51e72bc1 149 visit_type_EnumOne(data->ov, "unused", &bad_values[i], &err);
157db293 150 error_free_or_abort(&err);
f2ff429b 151 visitor_reset(data);
f294f82a
LC
152 }
153}
154
f294f82a
LC
155
156static void test_visitor_out_struct(TestOutputVisitorData *data,
157 const void *unused)
158{
159 TestStruct test_struct = { .integer = 42,
160 .boolean = false,
161 .string = (char *) "foo"};
162 TestStruct *p = &test_struct;
f294f82a
LC
163 QDict *qdict;
164
51e72bc1 165 visit_type_TestStruct(data->ov, NULL, &p, &error_abort);
f294f82a 166
ca6b6e1e
MA
167 qdict = qobject_to_qdict(visitor_get(data));
168 g_assert(qdict);
f294f82a
LC
169 g_assert_cmpint(qdict_size(qdict), ==, 3);
170 g_assert_cmpint(qdict_get_int(qdict, "integer"), ==, 42);
34acbc95 171 g_assert_cmpint(qdict_get_bool(qdict, "boolean"), ==, false);
f294f82a 172 g_assert_cmpstr(qdict_get_str(qdict, "string"), ==, "foo");
f294f82a
LC
173}
174
175static void test_visitor_out_struct_nested(TestOutputVisitorData *data,
176 const void *unused)
177{
178 int64_t value = 42;
b6fcf32d 179 UserDefTwo *ud2;
f294f82a
LC
180 QDict *qdict, *dict1, *dict2, *dict3, *userdef;
181 const char *string = "user def string";
beae9d79
SW
182 const char *strings[] = { "forty two", "forty three", "forty four",
183 "forty five" };
f294f82a
LC
184
185 ud2 = g_malloc0(sizeof(*ud2));
186 ud2->string0 = g_strdup(strings[0]);
187
6446a592
EB
188 ud2->dict1 = g_malloc0(sizeof(*ud2->dict1));
189 ud2->dict1->string1 = g_strdup(strings[1]);
190
191 ud2->dict1->dict2 = g_malloc0(sizeof(*ud2->dict1->dict2));
192 ud2->dict1->dict2->userdef = g_new0(UserDefOne, 1);
193 ud2->dict1->dict2->userdef->string = g_strdup(string);
ddf21908 194 ud2->dict1->dict2->userdef->integer = value;
6446a592
EB
195 ud2->dict1->dict2->string = g_strdup(strings[2]);
196
197 ud2->dict1->dict3 = g_malloc0(sizeof(*ud2->dict1->dict3));
198 ud2->dict1->has_dict3 = true;
199 ud2->dict1->dict3->userdef = g_new0(UserDefOne, 1);
200 ud2->dict1->dict3->userdef->string = g_strdup(string);
ddf21908 201 ud2->dict1->dict3->userdef->integer = value;
6446a592 202 ud2->dict1->dict3->string = g_strdup(strings[3]);
f294f82a 203
51e72bc1 204 visit_type_UserDefTwo(data->ov, "unused", &ud2, &error_abort);
f294f82a 205
ca6b6e1e
MA
206 qdict = qobject_to_qdict(visitor_get(data));
207 g_assert(qdict);
f294f82a
LC
208 g_assert_cmpint(qdict_size(qdict), ==, 2);
209 g_assert_cmpstr(qdict_get_str(qdict, "string0"), ==, strings[0]);
210
211 dict1 = qdict_get_qdict(qdict, "dict1");
212 g_assert_cmpint(qdict_size(dict1), ==, 3);
213 g_assert_cmpstr(qdict_get_str(dict1, "string1"), ==, strings[1]);
214
215 dict2 = qdict_get_qdict(dict1, "dict2");
216 g_assert_cmpint(qdict_size(dict2), ==, 2);
b6fcf32d
EB
217 g_assert_cmpstr(qdict_get_str(dict2, "string"), ==, strings[2]);
218 userdef = qdict_get_qdict(dict2, "userdef");
f294f82a
LC
219 g_assert_cmpint(qdict_size(userdef), ==, 2);
220 g_assert_cmpint(qdict_get_int(userdef, "integer"), ==, value);
221 g_assert_cmpstr(qdict_get_str(userdef, "string"), ==, string);
222
223 dict3 = qdict_get_qdict(dict1, "dict3");
224 g_assert_cmpint(qdict_size(dict3), ==, 2);
b6fcf32d
EB
225 g_assert_cmpstr(qdict_get_str(dict3, "string"), ==, strings[3]);
226 userdef = qdict_get_qdict(dict3, "userdef");
f294f82a
LC
227 g_assert_cmpint(qdict_size(userdef), ==, 2);
228 g_assert_cmpint(qdict_get_int(userdef, "integer"), ==, value);
229 g_assert_cmpstr(qdict_get_str(userdef, "string"), ==, string);
230
b6fcf32d 231 qapi_free_UserDefTwo(ud2);
f294f82a
LC
232}
233
9e9eace8
PB
234static void test_visitor_out_struct_errors(TestOutputVisitorData *data,
235 const void *unused)
236{
7fb1cf16 237 EnumOne bad_values[] = { ENUM_ONE__MAX, -1 };
ddf21908
EB
238 UserDefOne u = {0};
239 UserDefOne *pu = &u;
e940f543 240 Error *err;
9e9eace8
PB
241 int i;
242
243 for (i = 0; i < ARRAY_SIZE(bad_values) ; i++) {
e940f543 244 err = NULL;
9e9eace8
PB
245 u.has_enum1 = true;
246 u.enum1 = bad_values[i];
51e72bc1 247 visit_type_UserDefOne(data->ov, "unused", &pu, &err);
157db293 248 error_free_or_abort(&err);
f2ff429b 249 visitor_reset(data);
9e9eace8
PB
250 }
251}
252
f294f82a
LC
253
254static void test_visitor_out_list(TestOutputVisitorData *data,
255 const void *unused)
256{
bd20588d 257 const char *value_str = "list value";
f294f82a
LC
258 TestStructList *p, *head = NULL;
259 const int max_items = 10;
260 bool value_bool = true;
261 int value_int = 10;
f294f82a 262 QListEntry *entry;
f294f82a
LC
263 QList *qlist;
264 int i;
265
bd20588d 266 /* Build the list in reverse order... */
f294f82a
LC
267 for (i = 0; i < max_items; i++) {
268 p = g_malloc0(sizeof(*p));
269 p->value = g_malloc0(sizeof(*p->value));
bd20588d 270 p->value->integer = value_int + (max_items - i - 1);
f294f82a 271 p->value->boolean = value_bool;
bd20588d 272 p->value->string = g_strdup(value_str);
f294f82a
LC
273
274 p->next = head;
275 head = p;
276 }
277
51e72bc1 278 visit_type_TestStructList(data->ov, NULL, &head, &error_abort);
f294f82a 279
cd17ba51
MA
280 qlist = qobject_to_qlist(visitor_get(data));
281 g_assert(qlist);
f294f82a
LC
282 g_assert(!qlist_empty(qlist));
283
bd20588d 284 /* ...and ensure that the visitor sees it in order */
f294f82a
LC
285 i = 0;
286 QLIST_FOREACH_ENTRY(qlist, entry) {
287 QDict *qdict;
288
f294f82a 289 qdict = qobject_to_qdict(entry->value);
ca6b6e1e 290 g_assert(qdict);
f294f82a 291 g_assert_cmpint(qdict_size(qdict), ==, 3);
bd20588d 292 g_assert_cmpint(qdict_get_int(qdict, "integer"), ==, value_int + i);
f294f82a
LC
293 g_assert_cmpint(qdict_get_bool(qdict, "boolean"), ==, value_bool);
294 g_assert_cmpstr(qdict_get_str(qdict, "string"), ==, value_str);
295 i++;
296 }
297 g_assert_cmpint(i, ==, max_items);
298
bd20588d 299 qapi_free_TestStructList(head);
f294f82a
LC
300}
301
302static void test_visitor_out_list_qapi_free(TestOutputVisitorData *data,
303 const void *unused)
304{
b6fcf32d 305 UserDefTwoList *p, *head = NULL;
f294f82a
LC
306 const char string[] = "foo bar";
307 int i, max_count = 1024;
308
309 for (i = 0; i < max_count; i++) {
310 p = g_malloc0(sizeof(*p));
311 p->value = g_malloc0(sizeof(*p->value));
312
313 p->value->string0 = g_strdup(string);
6446a592
EB
314 p->value->dict1 = g_new0(UserDefTwoDict, 1);
315 p->value->dict1->string1 = g_strdup(string);
316 p->value->dict1->dict2 = g_new0(UserDefTwoDictDict, 1);
317 p->value->dict1->dict2->userdef = g_new0(UserDefOne, 1);
318 p->value->dict1->dict2->userdef->string = g_strdup(string);
ddf21908 319 p->value->dict1->dict2->userdef->integer = 42;
6446a592
EB
320 p->value->dict1->dict2->string = g_strdup(string);
321 p->value->dict1->has_dict3 = false;
f294f82a
LC
322
323 p->next = head;
324 head = p;
325 }
326
b6fcf32d 327 qapi_free_UserDefTwoList(head);
f294f82a
LC
328}
329
28770e05
MA
330static void test_visitor_out_any(TestOutputVisitorData *data,
331 const void *unused)
332{
333 QObject *qobj;
01b2ffce 334 QNum *qnum;
28770e05
MA
335 QBool *qbool;
336 QString *qstring;
337 QDict *qdict;
01b2ffce 338 int64_t val;
28770e05 339
01b2ffce 340 qobj = QOBJECT(qnum_from_int(-42));
51e72bc1 341 visit_type_any(data->ov, NULL, &qobj, &error_abort);
01b2ffce
MAL
342 qnum = qobject_to_qnum(visitor_get(data));
343 g_assert(qnum);
344 g_assert(qnum_get_try_int(qnum, &val));
345 g_assert_cmpint(val, ==, -42);
28770e05
MA
346 qobject_decref(qobj);
347
f2ff429b 348 visitor_reset(data);
28770e05 349 qdict = qdict_new();
46f5ac20
EB
350 qdict_put_int(qdict, "integer", -42);
351 qdict_put_bool(qdict, "boolean", true);
352 qdict_put_str(qdict, "string", "foo");
28770e05 353 qobj = QOBJECT(qdict);
51e72bc1 354 visit_type_any(data->ov, NULL, &qobj, &error_abort);
b18f1141 355 qobject_decref(qobj);
ca6b6e1e 356 qdict = qobject_to_qdict(visitor_get(data));
28770e05 357 g_assert(qdict);
01b2ffce
MAL
358 qnum = qobject_to_qnum(qdict_get(qdict, "integer"));
359 g_assert(qnum);
360 g_assert(qnum_get_try_int(qnum, &val));
361 g_assert_cmpint(val, ==, -42);
dfad9ec4 362 qbool = qobject_to_qbool(qdict_get(qdict, "boolean"));
28770e05
MA
363 g_assert(qbool);
364 g_assert(qbool_get_bool(qbool) == true);
363e13f8 365 qstring = qobject_to_qstring(qdict_get(qdict, "string"));
28770e05
MA
366 g_assert(qstring);
367 g_assert_cmpstr(qstring_get_str(qstring), ==, "foo");
28770e05
MA
368}
369
2fc00432
MA
370static void test_visitor_out_union_flat(TestOutputVisitorData *data,
371 const void *unused)
372{
2fc00432
MA
373 QDict *qdict;
374
2fc00432 375 UserDefFlatUnion *tmp = g_malloc0(sizeof(UserDefFlatUnion));
0f61af3e 376 tmp->enum1 = ENUM_ONE_VALUE1;
5223070c 377 tmp->string = g_strdup("str");
c363acef 378 tmp->integer = 41;
544a3731 379 tmp->u.value1.boolean = true;
2fc00432 380
51e72bc1 381 visit_type_UserDefFlatUnion(data->ov, NULL, &tmp, &error_abort);
ca6b6e1e
MA
382 qdict = qobject_to_qdict(visitor_get(data));
383 g_assert(qdict);
5223070c
WX
384 g_assert_cmpstr(qdict_get_str(qdict, "enum1"), ==, "value1");
385 g_assert_cmpstr(qdict_get_str(qdict, "string"), ==, "str");
c363acef 386 g_assert_cmpint(qdict_get_int(qdict, "integer"), ==, 41);
2fc00432
MA
387 g_assert_cmpint(qdict_get_bool(qdict, "boolean"), ==, true);
388
389 qapi_free_UserDefFlatUnion(tmp);
2fc00432
MA
390}
391
ab045267
EB
392static void test_visitor_out_alternate(TestOutputVisitorData *data,
393 const void *unused)
2c38b600 394{
12fafd7c 395 UserDefAlternate *tmp;
01b2ffce 396 QNum *qnum;
363e13f8 397 QString *qstr;
68d07839 398 QDict *qdict;
01b2ffce 399 int64_t val;
2c38b600 400
12fafd7c 401 tmp = g_new0(UserDefAlternate, 1);
01b2ffce 402 tmp->type = QTYPE_QNUM;
c363acef 403 tmp->u.i = 42;
2c38b600 404
51e72bc1 405 visit_type_UserDefAlternate(data->ov, NULL, &tmp, &error_abort);
01b2ffce
MAL
406 qnum = qobject_to_qnum(visitor_get(data));
407 g_assert(qnum);
408 g_assert(qnum_get_try_int(qnum, &val));
409 g_assert_cmpint(val, ==, 42);
2c38b600 410
ab045267 411 qapi_free_UserDefAlternate(tmp);
12fafd7c 412
f2ff429b 413 visitor_reset(data);
12fafd7c 414 tmp = g_new0(UserDefAlternate, 1);
0426d53c 415 tmp->type = QTYPE_QSTRING;
8168ca8e 416 tmp->u.e = ENUM_ONE_VALUE1;
12fafd7c 417
51e72bc1 418 visit_type_UserDefAlternate(data->ov, NULL, &tmp, &error_abort);
363e13f8
MA
419 qstr = qobject_to_qstring(visitor_get(data));
420 g_assert(qstr);
8168ca8e 421 g_assert_cmpstr(qstring_get_str(qstr), ==, "value1");
12fafd7c
EB
422
423 qapi_free_UserDefAlternate(tmp);
68d07839 424
4d2d5c41
MA
425 visitor_reset(data);
426 tmp = g_new0(UserDefAlternate, 1);
427 tmp->type = QTYPE_QNULL;
428 tmp->u.n = qnull();
429
430 visit_type_UserDefAlternate(data->ov, NULL, &tmp, &error_abort);
431 g_assert_cmpint(qobject_type(visitor_get(data)), ==, QTYPE_QNULL);
432
433 qapi_free_UserDefAlternate(tmp);
434
f2ff429b 435 visitor_reset(data);
68d07839
EB
436 tmp = g_new0(UserDefAlternate, 1);
437 tmp->type = QTYPE_QDICT;
becceedc
EB
438 tmp->u.udfu.integer = 1;
439 tmp->u.udfu.string = g_strdup("str");
440 tmp->u.udfu.enum1 = ENUM_ONE_VALUE1;
544a3731 441 tmp->u.udfu.u.value1.boolean = true;
68d07839
EB
442
443 visit_type_UserDefAlternate(data->ov, NULL, &tmp, &error_abort);
ca6b6e1e
MA
444 qdict = qobject_to_qdict(visitor_get(data));
445 g_assert(qdict);
68d07839
EB
446 g_assert_cmpint(qdict_size(qdict), ==, 4);
447 g_assert_cmpint(qdict_get_int(qdict, "integer"), ==, 1);
448 g_assert_cmpstr(qdict_get_str(qdict, "string"), ==, "str");
449 g_assert_cmpstr(qdict_get_str(qdict, "enum1"), ==, "value1");
450 g_assert_cmpint(qdict_get_bool(qdict, "boolean"), ==, true);
451
452 qapi_free_UserDefAlternate(tmp);
2c38b600
MA
453}
454
3df016f1
EB
455static void test_visitor_out_null(TestOutputVisitorData *data,
456 const void *unused)
a199b2b6 457{
d2f95f4d 458 QNull *null = NULL;
3df016f1
EB
459 QDict *qdict;
460 QObject *nil;
a199b2b6 461
3df016f1 462 visit_start_struct(data->ov, NULL, NULL, 0, &error_abort);
d2f95f4d 463 visit_type_null(data->ov, "a", &null, &error_abort);
15c2f669 464 visit_check_struct(data->ov, &error_abort);
1158bb2a 465 visit_end_struct(data->ov, NULL);
ca6b6e1e
MA
466 qdict = qobject_to_qdict(visitor_get(data));
467 g_assert(qdict);
3df016f1
EB
468 g_assert_cmpint(qdict_size(qdict), ==, 1);
469 nil = qdict_get(qdict, "a");
470 g_assert(nil);
471 g_assert(qobject_type(nil) == QTYPE_QNULL);
a199b2b6
MA
472}
473
83c84667
MR
474static void init_native_list(UserDefNativeListUnion *cvalue)
475{
476 int i;
c363acef 477 switch (cvalue->type) {
83c84667 478 case USER_DEF_NATIVE_LIST_UNION_KIND_INTEGER: {
32bafa8f 479 intList **list = &cvalue->u.integer.data;
83c84667
MR
480 for (i = 0; i < 32; i++) {
481 *list = g_new0(intList, 1);
482 (*list)->value = i;
483 (*list)->next = NULL;
484 list = &(*list)->next;
485 }
486 break;
487 }
488 case USER_DEF_NATIVE_LIST_UNION_KIND_S8: {
32bafa8f 489 int8List **list = &cvalue->u.s8.data;
83c84667
MR
490 for (i = 0; i < 32; i++) {
491 *list = g_new0(int8List, 1);
492 (*list)->value = i;
493 (*list)->next = NULL;
494 list = &(*list)->next;
495 }
496 break;
497 }
498 case USER_DEF_NATIVE_LIST_UNION_KIND_S16: {
32bafa8f 499 int16List **list = &cvalue->u.s16.data;
83c84667
MR
500 for (i = 0; i < 32; i++) {
501 *list = g_new0(int16List, 1);
502 (*list)->value = i;
503 (*list)->next = NULL;
504 list = &(*list)->next;
505 }
506 break;
507 }
508 case USER_DEF_NATIVE_LIST_UNION_KIND_S32: {
32bafa8f 509 int32List **list = &cvalue->u.s32.data;
83c84667
MR
510 for (i = 0; i < 32; i++) {
511 *list = g_new0(int32List, 1);
512 (*list)->value = i;
513 (*list)->next = NULL;
514 list = &(*list)->next;
515 }
516 break;
517 }
518 case USER_DEF_NATIVE_LIST_UNION_KIND_S64: {
32bafa8f 519 int64List **list = &cvalue->u.s64.data;
83c84667
MR
520 for (i = 0; i < 32; i++) {
521 *list = g_new0(int64List, 1);
522 (*list)->value = i;
523 (*list)->next = NULL;
524 list = &(*list)->next;
525 }
526 break;
527 }
528 case USER_DEF_NATIVE_LIST_UNION_KIND_U8: {
32bafa8f 529 uint8List **list = &cvalue->u.u8.data;
83c84667
MR
530 for (i = 0; i < 32; i++) {
531 *list = g_new0(uint8List, 1);
532 (*list)->value = i;
533 (*list)->next = NULL;
534 list = &(*list)->next;
535 }
536 break;
537 }
538 case USER_DEF_NATIVE_LIST_UNION_KIND_U16: {
32bafa8f 539 uint16List **list = &cvalue->u.u16.data;
83c84667
MR
540 for (i = 0; i < 32; i++) {
541 *list = g_new0(uint16List, 1);
542 (*list)->value = i;
543 (*list)->next = NULL;
544 list = &(*list)->next;
545 }
546 break;
547 }
548 case USER_DEF_NATIVE_LIST_UNION_KIND_U32: {
32bafa8f 549 uint32List **list = &cvalue->u.u32.data;
83c84667
MR
550 for (i = 0; i < 32; i++) {
551 *list = g_new0(uint32List, 1);
552 (*list)->value = i;
553 (*list)->next = NULL;
554 list = &(*list)->next;
555 }
556 break;
557 }
558 case USER_DEF_NATIVE_LIST_UNION_KIND_U64: {
32bafa8f 559 uint64List **list = &cvalue->u.u64.data;
83c84667
MR
560 for (i = 0; i < 32; i++) {
561 *list = g_new0(uint64List, 1);
562 (*list)->value = i;
563 (*list)->next = NULL;
564 list = &(*list)->next;
565 }
566 break;
567 }
568 case USER_DEF_NATIVE_LIST_UNION_KIND_BOOLEAN: {
32bafa8f 569 boolList **list = &cvalue->u.boolean.data;
83c84667
MR
570 for (i = 0; i < 32; i++) {
571 *list = g_new0(boolList, 1);
572 (*list)->value = (i % 3 == 0);
573 (*list)->next = NULL;
574 list = &(*list)->next;
575 }
576 break;
577 }
578 case USER_DEF_NATIVE_LIST_UNION_KIND_STRING: {
32bafa8f 579 strList **list = &cvalue->u.string.data;
83c84667
MR
580 for (i = 0; i < 32; i++) {
581 *list = g_new0(strList, 1);
582 (*list)->value = g_strdup_printf("%d", i);
583 (*list)->next = NULL;
584 list = &(*list)->next;
585 }
586 break;
587 }
588 case USER_DEF_NATIVE_LIST_UNION_KIND_NUMBER: {
32bafa8f 589 numberList **list = &cvalue->u.number.data;
83c84667
MR
590 for (i = 0; i < 32; i++) {
591 *list = g_new0(numberList, 1);
592 (*list)->value = (double)i / 3;
593 (*list)->next = NULL;
594 list = &(*list)->next;
595 }
596 break;
597 }
598 default:
dfc6f865 599 g_assert_not_reached();
83c84667
MR
600 }
601}
602
603static void check_native_list(QObject *qobj,
604 UserDefNativeListUnionKind kind)
605{
606 QDict *qdict;
607 QList *qlist;
608 int i;
609
83c84667
MR
610 qdict = qobject_to_qdict(qobj);
611 g_assert(qdict);
612 g_assert(qdict_haskey(qdict, "data"));
613 qlist = qlist_copy(qobject_to_qlist(qdict_get(qdict, "data")));
614
615 switch (kind) {
83c84667
MR
616 case USER_DEF_NATIVE_LIST_UNION_KIND_U8:
617 case USER_DEF_NATIVE_LIST_UNION_KIND_U16:
618 case USER_DEF_NATIVE_LIST_UNION_KIND_U32:
619 case USER_DEF_NATIVE_LIST_UNION_KIND_U64:
5923f85f
MAL
620 for (i = 0; i < 32; i++) {
621 QObject *tmp;
622 QNum *qvalue;
623 uint64_t val;
624
625 tmp = qlist_peek(qlist);
626 g_assert(tmp);
627 qvalue = qobject_to_qnum(tmp);
628 g_assert(qnum_get_try_uint(qvalue, &val));
629 g_assert_cmpint(val, ==, i);
630 qobject_decref(qlist_pop(qlist));
631 }
632 break;
633
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:
01b2ffce
MAL
638 /*
639 * All integer elements in JSON arrays get stored into QNums
640 * when we convert to QObjects, so we can check them all in
641 * the same fashion, so simply fall through here.
83c84667
MR
642 */
643 case USER_DEF_NATIVE_LIST_UNION_KIND_INTEGER:
644 for (i = 0; i < 32; i++) {
645 QObject *tmp;
01b2ffce
MAL
646 QNum *qvalue;
647 int64_t val;
648
83c84667
MR
649 tmp = qlist_peek(qlist);
650 g_assert(tmp);
01b2ffce
MAL
651 qvalue = qobject_to_qnum(tmp);
652 g_assert(qnum_get_try_int(qvalue, &val));
653 g_assert_cmpint(val, ==, i);
83c84667
MR
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;
01b2ffce 684 QNum *qvalue;
83c84667
MR
685 GString *double_expected = g_string_new("");
686 GString *double_actual = g_string_new("");
687
688 tmp = qlist_peek(qlist);
689 g_assert(tmp);
01b2ffce 690 qvalue = qobject_to_qnum(tmp);
83c84667 691 g_string_printf(double_expected, "%.6f", (double)i / 3);
01b2ffce 692 g_string_printf(double_actual, "%.6f", qnum_get_double(qvalue));
83c84667
MR
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}