]> git.proxmox.com Git - mirror_qemu.git/blame - tests/test-qobject-output-visitor.c
check-qjson: Test errors from qobject_from_json()
[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;
0abfc4b8 61 QInt *qint;
f294f82a 62
51e72bc1 63 visit_type_int(data->ov, NULL, &value, &error_abort);
f294f82a 64
0abfc4b8
MA
65 qint = qobject_to_qint(visitor_get(data));
66 g_assert(qint);
67 g_assert_cmpint(qint_get_int(qint), ==, value);
f294f82a
LC
68}
69
70static void test_visitor_out_bool(TestOutputVisitorData *data,
71 const void *unused)
72{
f294f82a 73 bool value = true;
dfad9ec4 74 QBool *qbool;
f294f82a 75
51e72bc1 76 visit_type_bool(data->ov, NULL, &value, &error_abort);
f294f82a 77
dfad9ec4
MA
78 qbool = qobject_to_qbool(visitor_get(data));
79 g_assert(qbool);
80 g_assert(qbool_get_bool(qbool) == value);
f294f82a
LC
81}
82
83static void test_visitor_out_number(TestOutputVisitorData *data,
84 const void *unused)
85{
86 double value = 3.14;
8978b34a 87 QFloat *qfloat;
f294f82a 88
51e72bc1 89 visit_type_number(data->ov, NULL, &value, &error_abort);
f294f82a 90
8978b34a
MA
91 qfloat = qobject_to_qfloat(visitor_get(data));
92 g_assert(qfloat);
93 g_assert(qfloat_get_double(qfloat) == value);
f294f82a
LC
94}
95
96static void test_visitor_out_string(TestOutputVisitorData *data,
97 const void *unused)
98{
99 char *string = (char *) "Q E M U";
363e13f8 100 QString *qstr;
f294f82a 101
51e72bc1 102 visit_type_str(data->ov, NULL, &string, &error_abort);
f294f82a 103
363e13f8
MA
104 qstr = qobject_to_qstring(visitor_get(data));
105 g_assert(qstr);
106 g_assert_cmpstr(qstring_get_str(qstr), ==, string);
f294f82a
LC
107}
108
109static void test_visitor_out_no_string(TestOutputVisitorData *data,
110 const void *unused)
111{
112 char *string = NULL;
363e13f8 113 QString *qstr;
f294f82a
LC
114
115 /* A null string should return "" */
51e72bc1 116 visit_type_str(data->ov, NULL, &string, &error_abort);
f294f82a 117
363e13f8
MA
118 qstr = qobject_to_qstring(visitor_get(data));
119 g_assert(qstr);
120 g_assert_cmpstr(qstring_get_str(qstr), ==, "");
f294f82a
LC
121}
122
123static void test_visitor_out_enum(TestOutputVisitorData *data,
124 const void *unused)
125{
f294f82a 126 EnumOne i;
363e13f8 127 QString *qstr;
f294f82a 128
7fb1cf16 129 for (i = 0; i < ENUM_ONE__MAX; i++) {
51e72bc1 130 visit_type_EnumOne(data->ov, "unused", &i, &error_abort);
f294f82a 131
363e13f8
MA
132 qstr = qobject_to_qstring(visitor_get(data));
133 g_assert(qstr);
134 g_assert_cmpstr(qstring_get_str(qstr), ==, EnumOne_lookup[i]);
f2ff429b 135 visitor_reset(data);
f294f82a
LC
136 }
137}
138
139static void test_visitor_out_enum_errors(TestOutputVisitorData *data,
140 const void *unused)
141{
7fb1cf16 142 EnumOne i, bad_values[] = { ENUM_ONE__MAX, -1 };
e940f543 143 Error *err;
f294f82a
LC
144
145 for (i = 0; i < ARRAY_SIZE(bad_values) ; i++) {
e940f543 146 err = NULL;
51e72bc1 147 visit_type_EnumOne(data->ov, "unused", &bad_values[i], &err);
e940f543
MA
148 g_assert(err);
149 error_free(err);
f2ff429b 150 visitor_reset(data);
f294f82a
LC
151 }
152}
153
f294f82a
LC
154
155static void test_visitor_out_struct(TestOutputVisitorData *data,
156 const void *unused)
157{
158 TestStruct test_struct = { .integer = 42,
159 .boolean = false,
160 .string = (char *) "foo"};
161 TestStruct *p = &test_struct;
f294f82a
LC
162 QDict *qdict;
163
51e72bc1 164 visit_type_TestStruct(data->ov, NULL, &p, &error_abort);
f294f82a 165
ca6b6e1e
MA
166 qdict = qobject_to_qdict(visitor_get(data));
167 g_assert(qdict);
f294f82a
LC
168 g_assert_cmpint(qdict_size(qdict), ==, 3);
169 g_assert_cmpint(qdict_get_int(qdict, "integer"), ==, 42);
34acbc95 170 g_assert_cmpint(qdict_get_bool(qdict, "boolean"), ==, false);
f294f82a 171 g_assert_cmpstr(qdict_get_str(qdict, "string"), ==, "foo");
f294f82a
LC
172}
173
174static void test_visitor_out_struct_nested(TestOutputVisitorData *data,
175 const void *unused)
176{
177 int64_t value = 42;
b6fcf32d 178 UserDefTwo *ud2;
f294f82a
LC
179 QDict *qdict, *dict1, *dict2, *dict3, *userdef;
180 const char *string = "user def string";
beae9d79
SW
181 const char *strings[] = { "forty two", "forty three", "forty four",
182 "forty five" };
f294f82a
LC
183
184 ud2 = g_malloc0(sizeof(*ud2));
185 ud2->string0 = g_strdup(strings[0]);
186
6446a592
EB
187 ud2->dict1 = g_malloc0(sizeof(*ud2->dict1));
188 ud2->dict1->string1 = g_strdup(strings[1]);
189
190 ud2->dict1->dict2 = g_malloc0(sizeof(*ud2->dict1->dict2));
191 ud2->dict1->dict2->userdef = g_new0(UserDefOne, 1);
192 ud2->dict1->dict2->userdef->string = g_strdup(string);
ddf21908 193 ud2->dict1->dict2->userdef->integer = value;
6446a592
EB
194 ud2->dict1->dict2->string = g_strdup(strings[2]);
195
196 ud2->dict1->dict3 = g_malloc0(sizeof(*ud2->dict1->dict3));
197 ud2->dict1->has_dict3 = true;
198 ud2->dict1->dict3->userdef = g_new0(UserDefOne, 1);
199 ud2->dict1->dict3->userdef->string = g_strdup(string);
ddf21908 200 ud2->dict1->dict3->userdef->integer = value;
6446a592 201 ud2->dict1->dict3->string = g_strdup(strings[3]);
f294f82a 202
51e72bc1 203 visit_type_UserDefTwo(data->ov, "unused", &ud2, &error_abort);
f294f82a 204
ca6b6e1e
MA
205 qdict = qobject_to_qdict(visitor_get(data));
206 g_assert(qdict);
f294f82a
LC
207 g_assert_cmpint(qdict_size(qdict), ==, 2);
208 g_assert_cmpstr(qdict_get_str(qdict, "string0"), ==, strings[0]);
209
210 dict1 = qdict_get_qdict(qdict, "dict1");
211 g_assert_cmpint(qdict_size(dict1), ==, 3);
212 g_assert_cmpstr(qdict_get_str(dict1, "string1"), ==, strings[1]);
213
214 dict2 = qdict_get_qdict(dict1, "dict2");
215 g_assert_cmpint(qdict_size(dict2), ==, 2);
b6fcf32d
EB
216 g_assert_cmpstr(qdict_get_str(dict2, "string"), ==, strings[2]);
217 userdef = qdict_get_qdict(dict2, "userdef");
f294f82a
LC
218 g_assert_cmpint(qdict_size(userdef), ==, 2);
219 g_assert_cmpint(qdict_get_int(userdef, "integer"), ==, value);
220 g_assert_cmpstr(qdict_get_str(userdef, "string"), ==, string);
221
222 dict3 = qdict_get_qdict(dict1, "dict3");
223 g_assert_cmpint(qdict_size(dict3), ==, 2);
b6fcf32d
EB
224 g_assert_cmpstr(qdict_get_str(dict3, "string"), ==, strings[3]);
225 userdef = qdict_get_qdict(dict3, "userdef");
f294f82a
LC
226 g_assert_cmpint(qdict_size(userdef), ==, 2);
227 g_assert_cmpint(qdict_get_int(userdef, "integer"), ==, value);
228 g_assert_cmpstr(qdict_get_str(userdef, "string"), ==, string);
229
b6fcf32d 230 qapi_free_UserDefTwo(ud2);
f294f82a
LC
231}
232
9e9eace8
PB
233static void test_visitor_out_struct_errors(TestOutputVisitorData *data,
234 const void *unused)
235{
7fb1cf16 236 EnumOne bad_values[] = { ENUM_ONE__MAX, -1 };
ddf21908
EB
237 UserDefOne u = {0};
238 UserDefOne *pu = &u;
e940f543 239 Error *err;
9e9eace8
PB
240 int i;
241
242 for (i = 0; i < ARRAY_SIZE(bad_values) ; i++) {
e940f543 243 err = NULL;
9e9eace8
PB
244 u.has_enum1 = true;
245 u.enum1 = bad_values[i];
51e72bc1 246 visit_type_UserDefOne(data->ov, "unused", &pu, &err);
e940f543
MA
247 g_assert(err);
248 error_free(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;
28770e05
MA
334 QInt *qint;
335 QBool *qbool;
336 QString *qstring;
337 QDict *qdict;
28770e05
MA
338
339 qobj = QOBJECT(qint_from_int(-42));
51e72bc1 340 visit_type_any(data->ov, NULL, &qobj, &error_abort);
0abfc4b8
MA
341 qint = qobject_to_qint(visitor_get(data));
342 g_assert(qint);
343 g_assert_cmpint(qint_get_int(qint), ==, -42);
28770e05
MA
344 qobject_decref(qobj);
345
f2ff429b 346 visitor_reset(data);
28770e05
MA
347 qdict = qdict_new();
348 qdict_put(qdict, "integer", qint_from_int(-42));
349 qdict_put(qdict, "boolean", qbool_from_bool(true));
350 qdict_put(qdict, "string", qstring_from_str("foo"));
351 qobj = QOBJECT(qdict);
51e72bc1 352 visit_type_any(data->ov, NULL, &qobj, &error_abort);
b18f1141 353 qobject_decref(qobj);
ca6b6e1e 354 qdict = qobject_to_qdict(visitor_get(data));
28770e05 355 g_assert(qdict);
0abfc4b8 356 qint = qobject_to_qint(qdict_get(qdict, "integer"));
28770e05
MA
357 g_assert(qint);
358 g_assert_cmpint(qint_get_int(qint), ==, -42);
dfad9ec4 359 qbool = qobject_to_qbool(qdict_get(qdict, "boolean"));
28770e05
MA
360 g_assert(qbool);
361 g_assert(qbool_get_bool(qbool) == true);
363e13f8 362 qstring = qobject_to_qstring(qdict_get(qdict, "string"));
28770e05
MA
363 g_assert(qstring);
364 g_assert_cmpstr(qstring_get_str(qstring), ==, "foo");
28770e05
MA
365}
366
2fc00432
MA
367static void test_visitor_out_union_flat(TestOutputVisitorData *data,
368 const void *unused)
369{
2fc00432
MA
370 QDict *qdict;
371
2fc00432 372 UserDefFlatUnion *tmp = g_malloc0(sizeof(UserDefFlatUnion));
0f61af3e 373 tmp->enum1 = ENUM_ONE_VALUE1;
5223070c 374 tmp->string = g_strdup("str");
c363acef 375 tmp->integer = 41;
544a3731 376 tmp->u.value1.boolean = true;
2fc00432 377
51e72bc1 378 visit_type_UserDefFlatUnion(data->ov, NULL, &tmp, &error_abort);
ca6b6e1e
MA
379 qdict = qobject_to_qdict(visitor_get(data));
380 g_assert(qdict);
5223070c
WX
381 g_assert_cmpstr(qdict_get_str(qdict, "enum1"), ==, "value1");
382 g_assert_cmpstr(qdict_get_str(qdict, "string"), ==, "str");
c363acef 383 g_assert_cmpint(qdict_get_int(qdict, "integer"), ==, 41);
2fc00432
MA
384 g_assert_cmpint(qdict_get_bool(qdict, "boolean"), ==, true);
385
386 qapi_free_UserDefFlatUnion(tmp);
2fc00432
MA
387}
388
ab045267
EB
389static void test_visitor_out_alternate(TestOutputVisitorData *data,
390 const void *unused)
2c38b600 391{
12fafd7c 392 UserDefAlternate *tmp;
0abfc4b8 393 QInt *qint;
363e13f8 394 QString *qstr;
68d07839 395 QDict *qdict;
2c38b600 396
12fafd7c 397 tmp = g_new0(UserDefAlternate, 1);
0426d53c 398 tmp->type = QTYPE_QINT;
c363acef 399 tmp->u.i = 42;
2c38b600 400
51e72bc1 401 visit_type_UserDefAlternate(data->ov, NULL, &tmp, &error_abort);
0abfc4b8
MA
402 qint = qobject_to_qint(visitor_get(data));
403 g_assert(qint);
404 g_assert_cmpint(qint_get_int(qint), ==, 42);
2c38b600 405
ab045267 406 qapi_free_UserDefAlternate(tmp);
12fafd7c 407
f2ff429b 408 visitor_reset(data);
12fafd7c 409 tmp = g_new0(UserDefAlternate, 1);
0426d53c 410 tmp->type = QTYPE_QSTRING;
12fafd7c
EB
411 tmp->u.s = g_strdup("hello");
412
51e72bc1 413 visit_type_UserDefAlternate(data->ov, NULL, &tmp, &error_abort);
363e13f8
MA
414 qstr = qobject_to_qstring(visitor_get(data));
415 g_assert(qstr);
416 g_assert_cmpstr(qstring_get_str(qstr), ==, "hello");
12fafd7c
EB
417
418 qapi_free_UserDefAlternate(tmp);
68d07839 419
f2ff429b 420 visitor_reset(data);
68d07839
EB
421 tmp = g_new0(UserDefAlternate, 1);
422 tmp->type = QTYPE_QDICT;
becceedc
EB
423 tmp->u.udfu.integer = 1;
424 tmp->u.udfu.string = g_strdup("str");
425 tmp->u.udfu.enum1 = ENUM_ONE_VALUE1;
544a3731 426 tmp->u.udfu.u.value1.boolean = true;
68d07839
EB
427
428 visit_type_UserDefAlternate(data->ov, NULL, &tmp, &error_abort);
ca6b6e1e
MA
429 qdict = qobject_to_qdict(visitor_get(data));
430 g_assert(qdict);
68d07839
EB
431 g_assert_cmpint(qdict_size(qdict), ==, 4);
432 g_assert_cmpint(qdict_get_int(qdict, "integer"), ==, 1);
433 g_assert_cmpstr(qdict_get_str(qdict, "string"), ==, "str");
434 g_assert_cmpstr(qdict_get_str(qdict, "enum1"), ==, "value1");
435 g_assert_cmpint(qdict_get_bool(qdict, "boolean"), ==, true);
436
437 qapi_free_UserDefAlternate(tmp);
2c38b600
MA
438}
439
3df016f1
EB
440static void test_visitor_out_null(TestOutputVisitorData *data,
441 const void *unused)
a199b2b6 442{
3df016f1
EB
443 QDict *qdict;
444 QObject *nil;
a199b2b6 445
3df016f1
EB
446 visit_start_struct(data->ov, NULL, NULL, 0, &error_abort);
447 visit_type_null(data->ov, "a", &error_abort);
15c2f669 448 visit_check_struct(data->ov, &error_abort);
1158bb2a 449 visit_end_struct(data->ov, NULL);
ca6b6e1e
MA
450 qdict = qobject_to_qdict(visitor_get(data));
451 g_assert(qdict);
3df016f1
EB
452 g_assert_cmpint(qdict_size(qdict), ==, 1);
453 nil = qdict_get(qdict, "a");
454 g_assert(nil);
455 g_assert(qobject_type(nil) == QTYPE_QNULL);
a199b2b6
MA
456}
457
83c84667
MR
458static void init_native_list(UserDefNativeListUnion *cvalue)
459{
460 int i;
c363acef 461 switch (cvalue->type) {
83c84667 462 case USER_DEF_NATIVE_LIST_UNION_KIND_INTEGER: {
32bafa8f 463 intList **list = &cvalue->u.integer.data;
83c84667
MR
464 for (i = 0; i < 32; i++) {
465 *list = g_new0(intList, 1);
466 (*list)->value = i;
467 (*list)->next = NULL;
468 list = &(*list)->next;
469 }
470 break;
471 }
472 case USER_DEF_NATIVE_LIST_UNION_KIND_S8: {
32bafa8f 473 int8List **list = &cvalue->u.s8.data;
83c84667
MR
474 for (i = 0; i < 32; i++) {
475 *list = g_new0(int8List, 1);
476 (*list)->value = i;
477 (*list)->next = NULL;
478 list = &(*list)->next;
479 }
480 break;
481 }
482 case USER_DEF_NATIVE_LIST_UNION_KIND_S16: {
32bafa8f 483 int16List **list = &cvalue->u.s16.data;
83c84667
MR
484 for (i = 0; i < 32; i++) {
485 *list = g_new0(int16List, 1);
486 (*list)->value = i;
487 (*list)->next = NULL;
488 list = &(*list)->next;
489 }
490 break;
491 }
492 case USER_DEF_NATIVE_LIST_UNION_KIND_S32: {
32bafa8f 493 int32List **list = &cvalue->u.s32.data;
83c84667
MR
494 for (i = 0; i < 32; i++) {
495 *list = g_new0(int32List, 1);
496 (*list)->value = i;
497 (*list)->next = NULL;
498 list = &(*list)->next;
499 }
500 break;
501 }
502 case USER_DEF_NATIVE_LIST_UNION_KIND_S64: {
32bafa8f 503 int64List **list = &cvalue->u.s64.data;
83c84667
MR
504 for (i = 0; i < 32; i++) {
505 *list = g_new0(int64List, 1);
506 (*list)->value = i;
507 (*list)->next = NULL;
508 list = &(*list)->next;
509 }
510 break;
511 }
512 case USER_DEF_NATIVE_LIST_UNION_KIND_U8: {
32bafa8f 513 uint8List **list = &cvalue->u.u8.data;
83c84667
MR
514 for (i = 0; i < 32; i++) {
515 *list = g_new0(uint8List, 1);
516 (*list)->value = i;
517 (*list)->next = NULL;
518 list = &(*list)->next;
519 }
520 break;
521 }
522 case USER_DEF_NATIVE_LIST_UNION_KIND_U16: {
32bafa8f 523 uint16List **list = &cvalue->u.u16.data;
83c84667
MR
524 for (i = 0; i < 32; i++) {
525 *list = g_new0(uint16List, 1);
526 (*list)->value = i;
527 (*list)->next = NULL;
528 list = &(*list)->next;
529 }
530 break;
531 }
532 case USER_DEF_NATIVE_LIST_UNION_KIND_U32: {
32bafa8f 533 uint32List **list = &cvalue->u.u32.data;
83c84667
MR
534 for (i = 0; i < 32; i++) {
535 *list = g_new0(uint32List, 1);
536 (*list)->value = i;
537 (*list)->next = NULL;
538 list = &(*list)->next;
539 }
540 break;
541 }
542 case USER_DEF_NATIVE_LIST_UNION_KIND_U64: {
32bafa8f 543 uint64List **list = &cvalue->u.u64.data;
83c84667
MR
544 for (i = 0; i < 32; i++) {
545 *list = g_new0(uint64List, 1);
546 (*list)->value = i;
547 (*list)->next = NULL;
548 list = &(*list)->next;
549 }
550 break;
551 }
552 case USER_DEF_NATIVE_LIST_UNION_KIND_BOOLEAN: {
32bafa8f 553 boolList **list = &cvalue->u.boolean.data;
83c84667
MR
554 for (i = 0; i < 32; i++) {
555 *list = g_new0(boolList, 1);
556 (*list)->value = (i % 3 == 0);
557 (*list)->next = NULL;
558 list = &(*list)->next;
559 }
560 break;
561 }
562 case USER_DEF_NATIVE_LIST_UNION_KIND_STRING: {
32bafa8f 563 strList **list = &cvalue->u.string.data;
83c84667
MR
564 for (i = 0; i < 32; i++) {
565 *list = g_new0(strList, 1);
566 (*list)->value = g_strdup_printf("%d", i);
567 (*list)->next = NULL;
568 list = &(*list)->next;
569 }
570 break;
571 }
572 case USER_DEF_NATIVE_LIST_UNION_KIND_NUMBER: {
32bafa8f 573 numberList **list = &cvalue->u.number.data;
83c84667
MR
574 for (i = 0; i < 32; i++) {
575 *list = g_new0(numberList, 1);
576 (*list)->value = (double)i / 3;
577 (*list)->next = NULL;
578 list = &(*list)->next;
579 }
580 break;
581 }
582 default:
dfc6f865 583 g_assert_not_reached();
83c84667
MR
584 }
585}
586
587static void check_native_list(QObject *qobj,
588 UserDefNativeListUnionKind kind)
589{
590 QDict *qdict;
591 QList *qlist;
592 int i;
593
83c84667
MR
594 qdict = qobject_to_qdict(qobj);
595 g_assert(qdict);
596 g_assert(qdict_haskey(qdict, "data"));
597 qlist = qlist_copy(qobject_to_qlist(qdict_get(qdict, "data")));
598
599 switch (kind) {
600 case USER_DEF_NATIVE_LIST_UNION_KIND_S8:
601 case USER_DEF_NATIVE_LIST_UNION_KIND_S16:
602 case USER_DEF_NATIVE_LIST_UNION_KIND_S32:
603 case USER_DEF_NATIVE_LIST_UNION_KIND_S64:
604 case USER_DEF_NATIVE_LIST_UNION_KIND_U8:
605 case USER_DEF_NATIVE_LIST_UNION_KIND_U16:
606 case USER_DEF_NATIVE_LIST_UNION_KIND_U32:
607 case USER_DEF_NATIVE_LIST_UNION_KIND_U64:
608 /* all integer elements in JSON arrays get stored into QInts when
609 * we convert to QObjects, so we can check them all in the same
610 * fashion, so simply fall through here
611 */
612 case USER_DEF_NATIVE_LIST_UNION_KIND_INTEGER:
613 for (i = 0; i < 32; i++) {
614 QObject *tmp;
615 QInt *qvalue;
616 tmp = qlist_peek(qlist);
617 g_assert(tmp);
618 qvalue = qobject_to_qint(tmp);
619 g_assert_cmpint(qint_get_int(qvalue), ==, i);
620 qobject_decref(qlist_pop(qlist));
621 }
622 break;
623 case USER_DEF_NATIVE_LIST_UNION_KIND_BOOLEAN:
624 for (i = 0; i < 32; i++) {
625 QObject *tmp;
626 QBool *qvalue;
627 tmp = qlist_peek(qlist);
628 g_assert(tmp);
629 qvalue = qobject_to_qbool(tmp);
fc48ffc3 630 g_assert_cmpint(qbool_get_bool(qvalue), ==, i % 3 == 0);
83c84667
MR
631 qobject_decref(qlist_pop(qlist));
632 }
633 break;
634 case USER_DEF_NATIVE_LIST_UNION_KIND_STRING:
635 for (i = 0; i < 32; i++) {
636 QObject *tmp;
637 QString *qvalue;
638 gchar str[8];
639 tmp = qlist_peek(qlist);
640 g_assert(tmp);
641 qvalue = qobject_to_qstring(tmp);
642 sprintf(str, "%d", i);
643 g_assert_cmpstr(qstring_get_str(qvalue), ==, str);
644 qobject_decref(qlist_pop(qlist));
645 }
646 break;
647 case USER_DEF_NATIVE_LIST_UNION_KIND_NUMBER:
648 for (i = 0; i < 32; i++) {
649 QObject *tmp;
650 QFloat *qvalue;
651 GString *double_expected = g_string_new("");
652 GString *double_actual = g_string_new("");
653
654 tmp = qlist_peek(qlist);
655 g_assert(tmp);
656 qvalue = qobject_to_qfloat(tmp);
657 g_string_printf(double_expected, "%.6f", (double)i / 3);
658 g_string_printf(double_actual, "%.6f", qfloat_get_double(qvalue));
659 g_assert_cmpstr(double_actual->str, ==, double_expected->str);
660
661 qobject_decref(qlist_pop(qlist));
662 g_string_free(double_expected, true);
663 g_string_free(double_actual, true);
664 }
665 break;
666 default:
dfc6f865 667 g_assert_not_reached();
83c84667
MR
668 }
669 QDECREF(qlist);
670}
671
672static void test_native_list(TestOutputVisitorData *data,
673 const void *unused,
674 UserDefNativeListUnionKind kind)
675{
676 UserDefNativeListUnion *cvalue = g_new0(UserDefNativeListUnion, 1);
83c84667
MR
677 QObject *obj;
678
c363acef 679 cvalue->type = kind;
83c84667
MR
680 init_native_list(cvalue);
681
51e72bc1 682 visit_type_UserDefNativeListUnion(data->ov, NULL, &cvalue, &error_abort);
83c84667 683
23d1705f 684 obj = visitor_get(data);
c363acef 685 check_native_list(obj, cvalue->type);
83c84667 686 qapi_free_UserDefNativeListUnion(cvalue);
83c84667
MR
687}
688
689static void test_visitor_out_native_list_int(TestOutputVisitorData *data,
690 const void *unused)
691{
692 test_native_list(data, unused, USER_DEF_NATIVE_LIST_UNION_KIND_INTEGER);
693}
694
695static void test_visitor_out_native_list_int8(TestOutputVisitorData *data,
696 const void *unused)
697{
698 test_native_list(data, unused, USER_DEF_NATIVE_LIST_UNION_KIND_S8);
699}
700
701static void test_visitor_out_native_list_int16(TestOutputVisitorData *data,
702 const void *unused)
703{
704 test_native_list(data, unused, USER_DEF_NATIVE_LIST_UNION_KIND_S16);
705}
706
707static void test_visitor_out_native_list_int32(TestOutputVisitorData *data,
708 const void *unused)
709{
710 test_native_list(data, unused, USER_DEF_NATIVE_LIST_UNION_KIND_S32);
711}
712
713static void test_visitor_out_native_list_int64(TestOutputVisitorData *data,
714 const void *unused)
715{
716 test_native_list(data, unused, USER_DEF_NATIVE_LIST_UNION_KIND_S64);
717}
718
719static void test_visitor_out_native_list_uint8(TestOutputVisitorData *data,
720 const void *unused)
721{
722 test_native_list(data, unused, USER_DEF_NATIVE_LIST_UNION_KIND_U8);
723}
724
725static void test_visitor_out_native_list_uint16(TestOutputVisitorData *data,
726 const void *unused)
727{
728 test_native_list(data, unused, USER_DEF_NATIVE_LIST_UNION_KIND_U16);
729}
730
731static void test_visitor_out_native_list_uint32(TestOutputVisitorData *data,
732 const void *unused)
733{
734 test_native_list(data, unused, USER_DEF_NATIVE_LIST_UNION_KIND_U32);
735}
736
737static void test_visitor_out_native_list_uint64(TestOutputVisitorData *data,
738 const void *unused)
739{
740 test_native_list(data, unused, USER_DEF_NATIVE_LIST_UNION_KIND_U64);
741}
742
743static void test_visitor_out_native_list_bool(TestOutputVisitorData *data,
744 const void *unused)
745{
746 test_native_list(data, unused, USER_DEF_NATIVE_LIST_UNION_KIND_BOOLEAN);
747}
748
749static void test_visitor_out_native_list_str(TestOutputVisitorData *data,
750 const void *unused)
751{
752 test_native_list(data, unused, USER_DEF_NATIVE_LIST_UNION_KIND_STRING);
753}
754
755static void test_visitor_out_native_list_number(TestOutputVisitorData *data,
756 const void *unused)
757{
758 test_native_list(data, unused, USER_DEF_NATIVE_LIST_UNION_KIND_NUMBER);
759}
760
f294f82a
LC
761static void output_visitor_test_add(const char *testpath,
762 TestOutputVisitorData *data,
763 void (*test_func)(TestOutputVisitorData *data, const void *user_data))
764{
765 g_test_add(testpath, TestOutputVisitorData, data, visitor_output_setup,
766 test_func, visitor_output_teardown);
767}
768
769int main(int argc, char **argv)
770{
771 TestOutputVisitorData out_visitor_data;
772
773 g_test_init(&argc, &argv, NULL);
774
775 output_visitor_test_add("/visitor/output/int",
776 &out_visitor_data, test_visitor_out_int);
777 output_visitor_test_add("/visitor/output/bool",
778 &out_visitor_data, test_visitor_out_bool);
779 output_visitor_test_add("/visitor/output/number",
780 &out_visitor_data, test_visitor_out_number);
781 output_visitor_test_add("/visitor/output/string",
782 &out_visitor_data, test_visitor_out_string);
783 output_visitor_test_add("/visitor/output/no-string",
784 &out_visitor_data, test_visitor_out_no_string);
785 output_visitor_test_add("/visitor/output/enum",
786 &out_visitor_data, test_visitor_out_enum);
787 output_visitor_test_add("/visitor/output/enum-errors",
788 &out_visitor_data, test_visitor_out_enum_errors);
789 output_visitor_test_add("/visitor/output/struct",
790 &out_visitor_data, test_visitor_out_struct);
791 output_visitor_test_add("/visitor/output/struct-nested",
792 &out_visitor_data, test_visitor_out_struct_nested);
9e9eace8
PB
793 output_visitor_test_add("/visitor/output/struct-errors",
794 &out_visitor_data, test_visitor_out_struct_errors);
f294f82a
LC
795 output_visitor_test_add("/visitor/output/list",
796 &out_visitor_data, test_visitor_out_list);
28770e05
MA
797 output_visitor_test_add("/visitor/output/any",
798 &out_visitor_data, test_visitor_out_any);
f294f82a
LC
799 output_visitor_test_add("/visitor/output/list-qapi-free",
800 &out_visitor_data, test_visitor_out_list_qapi_free);
2fc00432
MA
801 output_visitor_test_add("/visitor/output/union-flat",
802 &out_visitor_data, test_visitor_out_union_flat);
ab045267
EB
803 output_visitor_test_add("/visitor/output/alternate",
804 &out_visitor_data, test_visitor_out_alternate);
3df016f1
EB
805 output_visitor_test_add("/visitor/output/null",
806 &out_visitor_data, test_visitor_out_null);
83c84667 807 output_visitor_test_add("/visitor/output/native_list/int",
805017b7
EB
808 &out_visitor_data,
809 test_visitor_out_native_list_int);
83c84667 810 output_visitor_test_add("/visitor/output/native_list/int8",
805017b7
EB
811 &out_visitor_data,
812 test_visitor_out_native_list_int8);
83c84667 813 output_visitor_test_add("/visitor/output/native_list/int16",
805017b7
EB
814 &out_visitor_data,
815 test_visitor_out_native_list_int16);
83c84667 816 output_visitor_test_add("/visitor/output/native_list/int32",
805017b7
EB
817 &out_visitor_data,
818 test_visitor_out_native_list_int32);
83c84667 819 output_visitor_test_add("/visitor/output/native_list/int64",
805017b7
EB
820 &out_visitor_data,
821 test_visitor_out_native_list_int64);
83c84667 822 output_visitor_test_add("/visitor/output/native_list/uint8",
805017b7
EB
823 &out_visitor_data,
824 test_visitor_out_native_list_uint8);
83c84667 825 output_visitor_test_add("/visitor/output/native_list/uint16",
805017b7
EB
826 &out_visitor_data,
827 test_visitor_out_native_list_uint16);
83c84667 828 output_visitor_test_add("/visitor/output/native_list/uint32",
805017b7
EB
829 &out_visitor_data,
830 test_visitor_out_native_list_uint32);
83c84667 831 output_visitor_test_add("/visitor/output/native_list/uint64",
805017b7
EB
832 &out_visitor_data,
833 test_visitor_out_native_list_uint64);
83c84667 834 output_visitor_test_add("/visitor/output/native_list/bool",
805017b7
EB
835 &out_visitor_data,
836 test_visitor_out_native_list_bool);
83c84667 837 output_visitor_test_add("/visitor/output/native_list/string",
805017b7
EB
838 &out_visitor_data,
839 test_visitor_out_native_list_str);
83c84667 840 output_visitor_test_add("/visitor/output/native_list/number",
805017b7
EB
841 &out_visitor_data,
842 test_visitor_out_native_list_number);
f294f82a
LC
843
844 g_test_run();
845
846 return 0;
847}