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