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