]> Git Repo - qemu.git/blob - tests/test-qmp-input-visitor.c
Merge remote-tracking branch 'remotes/kraxel/tags/pull-usb-20160321-1' into staging
[qemu.git] / tests / test-qmp-input-visitor.c
1 /*
2  * QMP Input 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 #include <glib.h>
15
16 #include "qemu-common.h"
17 #include "qapi/qmp-input-visitor.h"
18 #include "test-qapi-types.h"
19 #include "test-qapi-visit.h"
20 #include "qapi/qmp/types.h"
21
22 typedef struct TestInputVisitorData {
23     QObject *obj;
24     QmpInputVisitor *qiv;
25 } TestInputVisitorData;
26
27 static void visitor_input_teardown(TestInputVisitorData *data,
28                                    const void *unused)
29 {
30     qobject_decref(data->obj);
31     data->obj = NULL;
32
33     if (data->qiv) {
34         qmp_input_visitor_cleanup(data->qiv);
35         data->qiv = NULL;
36     }
37 }
38
39 /* The various test_init functions are provided instead of a test setup
40    function so that the JSON string used by the tests are kept in the test
41    functions (and not in main()). */
42 static Visitor *visitor_input_test_init_internal(TestInputVisitorData *data,
43                                                  const char *json_string,
44                                                  va_list *ap)
45 {
46     Visitor *v;
47
48     visitor_input_teardown(data, NULL);
49
50     data->obj = qobject_from_jsonv(json_string, ap);
51     g_assert(data->obj);
52
53     data->qiv = qmp_input_visitor_new(data->obj);
54     g_assert(data->qiv);
55
56     v = qmp_input_get_visitor(data->qiv);
57     g_assert(v);
58
59     return v;
60 }
61
62 static GCC_FMT_ATTR(2, 3)
63 Visitor *visitor_input_test_init(TestInputVisitorData *data,
64                                  const char *json_string, ...)
65 {
66     Visitor *v;
67     va_list ap;
68
69     va_start(ap, json_string);
70     v = visitor_input_test_init_internal(data, json_string, &ap);
71     va_end(ap);
72     return v;
73 }
74
75 /* similar to visitor_input_test_init(), but does not expect a string
76  * literal/format json_string argument and so can be used for
77  * programatically generated strings (and we can't pass in programatically
78  * generated strings via %s format parameters since qobject_from_jsonv()
79  * will wrap those in double-quotes and treat the entire object as a
80  * string)
81  */
82 static Visitor *visitor_input_test_init_raw(TestInputVisitorData *data,
83                                             const char *json_string)
84 {
85     return visitor_input_test_init_internal(data, json_string, NULL);
86 }
87
88 static void test_visitor_in_int(TestInputVisitorData *data,
89                                 const void *unused)
90 {
91     int64_t res = 0, value = -42;
92     Visitor *v;
93
94     v = visitor_input_test_init(data, "%" PRId64, value);
95
96     visit_type_int(v, NULL, &res, &error_abort);
97     g_assert_cmpint(res, ==, value);
98 }
99
100 static void test_visitor_in_int_overflow(TestInputVisitorData *data,
101                                          const void *unused)
102 {
103     int64_t res = 0;
104     Error *err = NULL;
105     Visitor *v;
106
107     /* this will overflow a Qint/int64, so should be deserialized into
108      * a QFloat/double field instead, leading to an error if we pass it
109      * to visit_type_int. confirm this.
110      */
111     v = visitor_input_test_init(data, "%f", DBL_MAX);
112
113     visit_type_int(v, NULL, &res, &err);
114     error_free_or_abort(&err);
115 }
116
117 static void test_visitor_in_bool(TestInputVisitorData *data,
118                                  const void *unused)
119 {
120     bool res = false;
121     Visitor *v;
122
123     v = visitor_input_test_init(data, "true");
124
125     visit_type_bool(v, NULL, &res, &error_abort);
126     g_assert_cmpint(res, ==, true);
127 }
128
129 static void test_visitor_in_number(TestInputVisitorData *data,
130                                    const void *unused)
131 {
132     double res = 0, value = 3.14;
133     Visitor *v;
134
135     v = visitor_input_test_init(data, "%f", value);
136
137     visit_type_number(v, NULL, &res, &error_abort);
138     g_assert_cmpfloat(res, ==, value);
139 }
140
141 static void test_visitor_in_string(TestInputVisitorData *data,
142                                    const void *unused)
143 {
144     char *res = NULL, *value = (char *) "Q E M U";
145     Visitor *v;
146
147     v = visitor_input_test_init(data, "%s", value);
148
149     visit_type_str(v, NULL, &res, &error_abort);
150     g_assert_cmpstr(res, ==, value);
151
152     g_free(res);
153 }
154
155 static void test_visitor_in_enum(TestInputVisitorData *data,
156                                  const void *unused)
157 {
158     Visitor *v;
159     EnumOne i;
160
161     for (i = 0; EnumOne_lookup[i]; i++) {
162         EnumOne res = -1;
163
164         v = visitor_input_test_init(data, "%s", EnumOne_lookup[i]);
165
166         visit_type_EnumOne(v, NULL, &res, &error_abort);
167         g_assert_cmpint(i, ==, res);
168     }
169 }
170
171
172 static void test_visitor_in_struct(TestInputVisitorData *data,
173                                    const void *unused)
174 {
175     TestStruct *p = NULL;
176     Visitor *v;
177
178     v = visitor_input_test_init(data, "{ 'integer': -42, 'boolean': true, 'string': 'foo' }");
179
180     visit_type_TestStruct(v, NULL, &p, &error_abort);
181     g_assert_cmpint(p->integer, ==, -42);
182     g_assert(p->boolean == true);
183     g_assert_cmpstr(p->string, ==, "foo");
184
185     g_free(p->string);
186     g_free(p);
187 }
188
189 static void test_visitor_in_struct_nested(TestInputVisitorData *data,
190                                           const void *unused)
191 {
192     UserDefTwo *udp = NULL;
193     Visitor *v;
194
195     v = visitor_input_test_init(data, "{ 'string0': 'string0', "
196                                 "'dict1': { 'string1': 'string1', "
197                                 "'dict2': { 'userdef': { 'integer': 42, "
198                                 "'string': 'string' }, 'string': 'string2'}}}");
199
200     visit_type_UserDefTwo(v, NULL, &udp, &error_abort);
201
202     g_assert_cmpstr(udp->string0, ==, "string0");
203     g_assert_cmpstr(udp->dict1->string1, ==, "string1");
204     g_assert_cmpint(udp->dict1->dict2->userdef->integer, ==, 42);
205     g_assert_cmpstr(udp->dict1->dict2->userdef->string, ==, "string");
206     g_assert_cmpstr(udp->dict1->dict2->string, ==, "string2");
207     g_assert(udp->dict1->has_dict3 == false);
208
209     qapi_free_UserDefTwo(udp);
210 }
211
212 static void test_visitor_in_list(TestInputVisitorData *data,
213                                  const void *unused)
214 {
215     UserDefOneList *item, *head = NULL;
216     Visitor *v;
217     int i;
218
219     v = visitor_input_test_init(data, "[ { 'string': 'string0', 'integer': 42 }, { 'string': 'string1', 'integer': 43 }, { 'string': 'string2', 'integer': 44 } ]");
220
221     visit_type_UserDefOneList(v, NULL, &head, &error_abort);
222     g_assert(head != NULL);
223
224     for (i = 0, item = head; item; item = item->next, i++) {
225         char string[12];
226
227         snprintf(string, sizeof(string), "string%d", i);
228         g_assert_cmpstr(item->value->string, ==, string);
229         g_assert_cmpint(item->value->integer, ==, 42 + i);
230     }
231
232     qapi_free_UserDefOneList(head);
233     head = NULL;
234
235     /* An empty list is valid */
236     v = visitor_input_test_init(data, "[]");
237     visit_type_UserDefOneList(v, NULL, &head, &error_abort);
238     g_assert(!head);
239 }
240
241 static void test_visitor_in_any(TestInputVisitorData *data,
242                                 const void *unused)
243 {
244     QObject *res = NULL;
245     Visitor *v;
246     QInt *qint;
247     QBool *qbool;
248     QString *qstring;
249     QDict *qdict;
250     QObject *qobj;
251
252     v = visitor_input_test_init(data, "-42");
253     visit_type_any(v, NULL, &res, &error_abort);
254     qint = qobject_to_qint(res);
255     g_assert(qint);
256     g_assert_cmpint(qint_get_int(qint), ==, -42);
257     qobject_decref(res);
258
259     v = visitor_input_test_init(data, "{ 'integer': -42, 'boolean': true, 'string': 'foo' }");
260     visit_type_any(v, NULL, &res, &error_abort);
261     qdict = qobject_to_qdict(res);
262     g_assert(qdict && qdict_size(qdict) == 3);
263     qobj = qdict_get(qdict, "integer");
264     g_assert(qobj);
265     qint = qobject_to_qint(qobj);
266     g_assert(qint);
267     g_assert_cmpint(qint_get_int(qint), ==, -42);
268     qobj = qdict_get(qdict, "boolean");
269     g_assert(qobj);
270     qbool = qobject_to_qbool(qobj);
271     g_assert(qbool);
272     g_assert(qbool_get_bool(qbool) == true);
273     qobj = qdict_get(qdict, "string");
274     g_assert(qobj);
275     qstring = qobject_to_qstring(qobj);
276     g_assert(qstring);
277     g_assert_cmpstr(qstring_get_str(qstring), ==, "foo");
278     qobject_decref(res);
279 }
280
281 static void test_visitor_in_union_flat(TestInputVisitorData *data,
282                                        const void *unused)
283 {
284     Visitor *v;
285     UserDefFlatUnion *tmp;
286     UserDefUnionBase *base;
287
288     v = visitor_input_test_init(data,
289                                 "{ 'enum1': 'value1', "
290                                 "'integer': 41, "
291                                 "'string': 'str', "
292                                 "'boolean': true }");
293
294     visit_type_UserDefFlatUnion(v, NULL, &tmp, &error_abort);
295     g_assert_cmpint(tmp->enum1, ==, ENUM_ONE_VALUE1);
296     g_assert_cmpstr(tmp->string, ==, "str");
297     g_assert_cmpint(tmp->integer, ==, 41);
298     g_assert_cmpint(tmp->u.value1.boolean, ==, true);
299
300     base = qapi_UserDefFlatUnion_base(tmp);
301     g_assert(&base->enum1 == &tmp->enum1);
302
303     qapi_free_UserDefFlatUnion(tmp);
304 }
305
306 static void test_visitor_in_alternate(TestInputVisitorData *data,
307                                       const void *unused)
308 {
309     Visitor *v;
310     Error *err = NULL;
311     UserDefAlternate *tmp;
312     WrapAlternate *wrap;
313
314     v = visitor_input_test_init(data, "42");
315     visit_type_UserDefAlternate(v, NULL, &tmp, &error_abort);
316     g_assert_cmpint(tmp->type, ==, QTYPE_QINT);
317     g_assert_cmpint(tmp->u.i, ==, 42);
318     qapi_free_UserDefAlternate(tmp);
319
320     v = visitor_input_test_init(data, "'string'");
321     visit_type_UserDefAlternate(v, NULL, &tmp, &error_abort);
322     g_assert_cmpint(tmp->type, ==, QTYPE_QSTRING);
323     g_assert_cmpstr(tmp->u.s, ==, "string");
324     qapi_free_UserDefAlternate(tmp);
325
326     v = visitor_input_test_init(data, "{'integer':1, 'string':'str', "
327                                 "'enum1':'value1', 'boolean':true}");
328     visit_type_UserDefAlternate(v, NULL, &tmp, &error_abort);
329     g_assert_cmpint(tmp->type, ==, QTYPE_QDICT);
330     g_assert_cmpint(tmp->u.udfu.integer, ==, 1);
331     g_assert_cmpstr(tmp->u.udfu.string, ==, "str");
332     g_assert_cmpint(tmp->u.udfu.enum1, ==, ENUM_ONE_VALUE1);
333     g_assert_cmpint(tmp->u.udfu.u.value1.boolean, ==, true);
334     g_assert_cmpint(tmp->u.udfu.u.value1.has_a_b, ==, false);
335     qapi_free_UserDefAlternate(tmp);
336
337     v = visitor_input_test_init(data, "false");
338     visit_type_UserDefAlternate(v, NULL, &tmp, &err);
339     error_free_or_abort(&err);
340     qapi_free_UserDefAlternate(tmp);
341
342     v = visitor_input_test_init(data, "{ 'alt': 42 }");
343     visit_type_WrapAlternate(v, NULL, &wrap, &error_abort);
344     g_assert_cmpint(wrap->alt->type, ==, QTYPE_QINT);
345     g_assert_cmpint(wrap->alt->u.i, ==, 42);
346     qapi_free_WrapAlternate(wrap);
347
348     v = visitor_input_test_init(data, "{ 'alt': 'string' }");
349     visit_type_WrapAlternate(v, NULL, &wrap, &error_abort);
350     g_assert_cmpint(wrap->alt->type, ==, QTYPE_QSTRING);
351     g_assert_cmpstr(wrap->alt->u.s, ==, "string");
352     qapi_free_WrapAlternate(wrap);
353
354     v = visitor_input_test_init(data, "{ 'alt': {'integer':1, 'string':'str', "
355                                 "'enum1':'value1', 'boolean':true} }");
356     visit_type_WrapAlternate(v, NULL, &wrap, &error_abort);
357     g_assert_cmpint(wrap->alt->type, ==, QTYPE_QDICT);
358     g_assert_cmpint(wrap->alt->u.udfu.integer, ==, 1);
359     g_assert_cmpstr(wrap->alt->u.udfu.string, ==, "str");
360     g_assert_cmpint(wrap->alt->u.udfu.enum1, ==, ENUM_ONE_VALUE1);
361     g_assert_cmpint(wrap->alt->u.udfu.u.value1.boolean, ==, true);
362     g_assert_cmpint(wrap->alt->u.udfu.u.value1.has_a_b, ==, false);
363     qapi_free_WrapAlternate(wrap);
364 }
365
366 static void test_visitor_in_alternate_number(TestInputVisitorData *data,
367                                              const void *unused)
368 {
369     Visitor *v;
370     Error *err = NULL;
371     AltStrBool *asb;
372     AltStrNum *asn;
373     AltNumStr *ans;
374     AltStrInt *asi;
375     AltIntNum *ain;
376     AltNumInt *ani;
377
378     /* Parsing an int */
379
380     v = visitor_input_test_init(data, "42");
381     visit_type_AltStrBool(v, NULL, &asb, &err);
382     error_free_or_abort(&err);
383     qapi_free_AltStrBool(asb);
384
385     v = visitor_input_test_init(data, "42");
386     visit_type_AltStrNum(v, NULL, &asn, &error_abort);
387     g_assert_cmpint(asn->type, ==, QTYPE_QFLOAT);
388     g_assert_cmpfloat(asn->u.n, ==, 42);
389     qapi_free_AltStrNum(asn);
390
391     v = visitor_input_test_init(data, "42");
392     visit_type_AltNumStr(v, NULL, &ans, &error_abort);
393     g_assert_cmpint(ans->type, ==, QTYPE_QFLOAT);
394     g_assert_cmpfloat(ans->u.n, ==, 42);
395     qapi_free_AltNumStr(ans);
396
397     v = visitor_input_test_init(data, "42");
398     visit_type_AltStrInt(v, NULL, &asi, &error_abort);
399     g_assert_cmpint(asi->type, ==, QTYPE_QINT);
400     g_assert_cmpint(asi->u.i, ==, 42);
401     qapi_free_AltStrInt(asi);
402
403     v = visitor_input_test_init(data, "42");
404     visit_type_AltIntNum(v, NULL, &ain, &error_abort);
405     g_assert_cmpint(ain->type, ==, QTYPE_QINT);
406     g_assert_cmpint(ain->u.i, ==, 42);
407     qapi_free_AltIntNum(ain);
408
409     v = visitor_input_test_init(data, "42");
410     visit_type_AltNumInt(v, NULL, &ani, &error_abort);
411     g_assert_cmpint(ani->type, ==, QTYPE_QINT);
412     g_assert_cmpint(ani->u.i, ==, 42);
413     qapi_free_AltNumInt(ani);
414
415     /* Parsing a double */
416
417     v = visitor_input_test_init(data, "42.5");
418     visit_type_AltStrBool(v, NULL, &asb, &err);
419     error_free_or_abort(&err);
420     qapi_free_AltStrBool(asb);
421
422     v = visitor_input_test_init(data, "42.5");
423     visit_type_AltStrNum(v, NULL, &asn, &error_abort);
424     g_assert_cmpint(asn->type, ==, QTYPE_QFLOAT);
425     g_assert_cmpfloat(asn->u.n, ==, 42.5);
426     qapi_free_AltStrNum(asn);
427
428     v = visitor_input_test_init(data, "42.5");
429     visit_type_AltNumStr(v, NULL, &ans, &error_abort);
430     g_assert_cmpint(ans->type, ==, QTYPE_QFLOAT);
431     g_assert_cmpfloat(ans->u.n, ==, 42.5);
432     qapi_free_AltNumStr(ans);
433
434     v = visitor_input_test_init(data, "42.5");
435     visit_type_AltStrInt(v, NULL, &asi, &err);
436     error_free_or_abort(&err);
437     qapi_free_AltStrInt(asi);
438
439     v = visitor_input_test_init(data, "42.5");
440     visit_type_AltIntNum(v, NULL, &ain, &error_abort);
441     g_assert_cmpint(ain->type, ==, QTYPE_QFLOAT);
442     g_assert_cmpfloat(ain->u.n, ==, 42.5);
443     qapi_free_AltIntNum(ain);
444
445     v = visitor_input_test_init(data, "42.5");
446     visit_type_AltNumInt(v, NULL, &ani, &error_abort);
447     g_assert_cmpint(ani->type, ==, QTYPE_QFLOAT);
448     g_assert_cmpfloat(ani->u.n, ==, 42.5);
449     qapi_free_AltNumInt(ani);
450 }
451
452 static void test_native_list_integer_helper(TestInputVisitorData *data,
453                                             const void *unused,
454                                             UserDefNativeListUnionKind kind)
455 {
456     UserDefNativeListUnion *cvalue = NULL;
457     Visitor *v;
458     GString *gstr_list = g_string_new("");
459     GString *gstr_union = g_string_new("");
460     int i;
461
462     for (i = 0; i < 32; i++) {
463         g_string_append_printf(gstr_list, "%d", i);
464         if (i != 31) {
465             g_string_append(gstr_list, ", ");
466         }
467     }
468     g_string_append_printf(gstr_union,  "{ 'type': '%s', 'data': [ %s ] }",
469                            UserDefNativeListUnionKind_lookup[kind],
470                            gstr_list->str);
471     v = visitor_input_test_init_raw(data,  gstr_union->str);
472
473     visit_type_UserDefNativeListUnion(v, NULL, &cvalue, &error_abort);
474     g_assert(cvalue != NULL);
475     g_assert_cmpint(cvalue->type, ==, kind);
476
477     switch (kind) {
478     case USER_DEF_NATIVE_LIST_UNION_KIND_INTEGER: {
479         intList *elem = NULL;
480         for (i = 0, elem = cvalue->u.integer.data;
481              elem; elem = elem->next, i++) {
482             g_assert_cmpint(elem->value, ==, i);
483         }
484         break;
485     }
486     case USER_DEF_NATIVE_LIST_UNION_KIND_S8: {
487         int8List *elem = NULL;
488         for (i = 0, elem = cvalue->u.s8.data; elem; elem = elem->next, i++) {
489             g_assert_cmpint(elem->value, ==, i);
490         }
491         break;
492     }
493     case USER_DEF_NATIVE_LIST_UNION_KIND_S16: {
494         int16List *elem = NULL;
495         for (i = 0, elem = cvalue->u.s16.data; elem; elem = elem->next, i++) {
496             g_assert_cmpint(elem->value, ==, i);
497         }
498         break;
499     }
500     case USER_DEF_NATIVE_LIST_UNION_KIND_S32: {
501         int32List *elem = NULL;
502         for (i = 0, elem = cvalue->u.s32.data; elem; elem = elem->next, i++) {
503             g_assert_cmpint(elem->value, ==, i);
504         }
505         break;
506     }
507     case USER_DEF_NATIVE_LIST_UNION_KIND_S64: {
508         int64List *elem = NULL;
509         for (i = 0, elem = cvalue->u.s64.data; elem; elem = elem->next, i++) {
510             g_assert_cmpint(elem->value, ==, i);
511         }
512         break;
513     }
514     case USER_DEF_NATIVE_LIST_UNION_KIND_U8: {
515         uint8List *elem = NULL;
516         for (i = 0, elem = cvalue->u.u8.data; elem; elem = elem->next, i++) {
517             g_assert_cmpint(elem->value, ==, i);
518         }
519         break;
520     }
521     case USER_DEF_NATIVE_LIST_UNION_KIND_U16: {
522         uint16List *elem = NULL;
523         for (i = 0, elem = cvalue->u.u16.data; elem; elem = elem->next, i++) {
524             g_assert_cmpint(elem->value, ==, i);
525         }
526         break;
527     }
528     case USER_DEF_NATIVE_LIST_UNION_KIND_U32: {
529         uint32List *elem = NULL;
530         for (i = 0, elem = cvalue->u.u32.data; elem; elem = elem->next, i++) {
531             g_assert_cmpint(elem->value, ==, i);
532         }
533         break;
534     }
535     case USER_DEF_NATIVE_LIST_UNION_KIND_U64: {
536         uint64List *elem = NULL;
537         for (i = 0, elem = cvalue->u.u64.data; elem; elem = elem->next, i++) {
538             g_assert_cmpint(elem->value, ==, i);
539         }
540         break;
541     }
542     default:
543         g_assert_not_reached();
544     }
545
546     g_string_free(gstr_union, true);
547     g_string_free(gstr_list, true);
548     qapi_free_UserDefNativeListUnion(cvalue);
549 }
550
551 static void test_visitor_in_native_list_int(TestInputVisitorData *data,
552                                             const void *unused)
553 {
554     test_native_list_integer_helper(data, unused,
555                                     USER_DEF_NATIVE_LIST_UNION_KIND_INTEGER);
556 }
557
558 static void test_visitor_in_native_list_int8(TestInputVisitorData *data,
559                                              const void *unused)
560 {
561     test_native_list_integer_helper(data, unused,
562                                     USER_DEF_NATIVE_LIST_UNION_KIND_S8);
563 }
564
565 static void test_visitor_in_native_list_int16(TestInputVisitorData *data,
566                                               const void *unused)
567 {
568     test_native_list_integer_helper(data, unused,
569                                     USER_DEF_NATIVE_LIST_UNION_KIND_S16);
570 }
571
572 static void test_visitor_in_native_list_int32(TestInputVisitorData *data,
573                                               const void *unused)
574 {
575     test_native_list_integer_helper(data, unused,
576                                     USER_DEF_NATIVE_LIST_UNION_KIND_S32);
577 }
578
579 static void test_visitor_in_native_list_int64(TestInputVisitorData *data,
580                                               const void *unused)
581 {
582     test_native_list_integer_helper(data, unused,
583                                     USER_DEF_NATIVE_LIST_UNION_KIND_S64);
584 }
585
586 static void test_visitor_in_native_list_uint8(TestInputVisitorData *data,
587                                              const void *unused)
588 {
589     test_native_list_integer_helper(data, unused,
590                                     USER_DEF_NATIVE_LIST_UNION_KIND_U8);
591 }
592
593 static void test_visitor_in_native_list_uint16(TestInputVisitorData *data,
594                                                const void *unused)
595 {
596     test_native_list_integer_helper(data, unused,
597                                     USER_DEF_NATIVE_LIST_UNION_KIND_U16);
598 }
599
600 static void test_visitor_in_native_list_uint32(TestInputVisitorData *data,
601                                                const void *unused)
602 {
603     test_native_list_integer_helper(data, unused,
604                                     USER_DEF_NATIVE_LIST_UNION_KIND_U32);
605 }
606
607 static void test_visitor_in_native_list_uint64(TestInputVisitorData *data,
608                                                const void *unused)
609 {
610     test_native_list_integer_helper(data, unused,
611                                     USER_DEF_NATIVE_LIST_UNION_KIND_U64);
612 }
613
614 static void test_visitor_in_native_list_bool(TestInputVisitorData *data,
615                                             const void *unused)
616 {
617     UserDefNativeListUnion *cvalue = NULL;
618     boolList *elem = NULL;
619     Visitor *v;
620     GString *gstr_list = g_string_new("");
621     GString *gstr_union = g_string_new("");
622     int i;
623
624     for (i = 0; i < 32; i++) {
625         g_string_append_printf(gstr_list, "%s",
626                                (i % 3 == 0) ? "true" : "false");
627         if (i != 31) {
628             g_string_append(gstr_list, ", ");
629         }
630     }
631     g_string_append_printf(gstr_union,  "{ 'type': 'boolean', 'data': [ %s ] }",
632                            gstr_list->str);
633     v = visitor_input_test_init_raw(data,  gstr_union->str);
634
635     visit_type_UserDefNativeListUnion(v, NULL, &cvalue, &error_abort);
636     g_assert(cvalue != NULL);
637     g_assert_cmpint(cvalue->type, ==, USER_DEF_NATIVE_LIST_UNION_KIND_BOOLEAN);
638
639     for (i = 0, elem = cvalue->u.boolean.data; elem; elem = elem->next, i++) {
640         g_assert_cmpint(elem->value, ==, (i % 3 == 0) ? 1 : 0);
641     }
642
643     g_string_free(gstr_union, true);
644     g_string_free(gstr_list, true);
645     qapi_free_UserDefNativeListUnion(cvalue);
646 }
647
648 static void test_visitor_in_native_list_string(TestInputVisitorData *data,
649                                                const void *unused)
650 {
651     UserDefNativeListUnion *cvalue = NULL;
652     strList *elem = NULL;
653     Visitor *v;
654     GString *gstr_list = g_string_new("");
655     GString *gstr_union = g_string_new("");
656     int i;
657
658     for (i = 0; i < 32; i++) {
659         g_string_append_printf(gstr_list, "'%d'", i);
660         if (i != 31) {
661             g_string_append(gstr_list, ", ");
662         }
663     }
664     g_string_append_printf(gstr_union,  "{ 'type': 'string', 'data': [ %s ] }",
665                            gstr_list->str);
666     v = visitor_input_test_init_raw(data,  gstr_union->str);
667
668     visit_type_UserDefNativeListUnion(v, NULL, &cvalue, &error_abort);
669     g_assert(cvalue != NULL);
670     g_assert_cmpint(cvalue->type, ==, USER_DEF_NATIVE_LIST_UNION_KIND_STRING);
671
672     for (i = 0, elem = cvalue->u.string.data; elem; elem = elem->next, i++) {
673         gchar str[8];
674         sprintf(str, "%d", i);
675         g_assert_cmpstr(elem->value, ==, str);
676     }
677
678     g_string_free(gstr_union, true);
679     g_string_free(gstr_list, true);
680     qapi_free_UserDefNativeListUnion(cvalue);
681 }
682
683 #define DOUBLE_STR_MAX 16
684
685 static void test_visitor_in_native_list_number(TestInputVisitorData *data,
686                                                const void *unused)
687 {
688     UserDefNativeListUnion *cvalue = NULL;
689     numberList *elem = NULL;
690     Visitor *v;
691     GString *gstr_list = g_string_new("");
692     GString *gstr_union = g_string_new("");
693     int i;
694
695     for (i = 0; i < 32; i++) {
696         g_string_append_printf(gstr_list, "%f", (double)i / 3);
697         if (i != 31) {
698             g_string_append(gstr_list, ", ");
699         }
700     }
701     g_string_append_printf(gstr_union,  "{ 'type': 'number', 'data': [ %s ] }",
702                            gstr_list->str);
703     v = visitor_input_test_init_raw(data,  gstr_union->str);
704
705     visit_type_UserDefNativeListUnion(v, NULL, &cvalue, &error_abort);
706     g_assert(cvalue != NULL);
707     g_assert_cmpint(cvalue->type, ==, USER_DEF_NATIVE_LIST_UNION_KIND_NUMBER);
708
709     for (i = 0, elem = cvalue->u.number.data; elem; elem = elem->next, i++) {
710         GString *double_expected = g_string_new("");
711         GString *double_actual = g_string_new("");
712
713         g_string_printf(double_expected, "%.6f", (double)i / 3);
714         g_string_printf(double_actual, "%.6f", elem->value);
715         g_assert_cmpstr(double_expected->str, ==, double_actual->str);
716
717         g_string_free(double_expected, true);
718         g_string_free(double_actual, true);
719     }
720
721     g_string_free(gstr_union, true);
722     g_string_free(gstr_list, true);
723     qapi_free_UserDefNativeListUnion(cvalue);
724 }
725
726 static void input_visitor_test_add(const char *testpath,
727                                    TestInputVisitorData *data,
728                                    void (*test_func)(TestInputVisitorData *data, const void *user_data))
729 {
730     g_test_add(testpath, TestInputVisitorData, data, NULL, test_func,
731                visitor_input_teardown);
732 }
733
734 static void test_visitor_in_errors(TestInputVisitorData *data,
735                                    const void *unused)
736 {
737     TestStruct *p = NULL;
738     Error *err = NULL;
739     Visitor *v;
740     strList *q = NULL;
741
742     v = visitor_input_test_init(data, "{ 'integer': false, 'boolean': 'foo', "
743                                 "'string': -42 }");
744
745     visit_type_TestStruct(v, NULL, &p, &err);
746     error_free_or_abort(&err);
747     /* FIXME - a failed parse should not leave a partially-allocated p
748      * for us to clean up; this could cause callers to leak memory. */
749     g_assert(p->string == NULL);
750
751     g_free(p->string);
752     g_free(p);
753
754     v = visitor_input_test_init(data, "[ '1', '2', false, '3' ]");
755     visit_type_strList(v, NULL, &q, &err);
756     error_free_or_abort(&err);
757     assert(q);
758     qapi_free_strList(q);
759 }
760
761 static void test_visitor_in_wrong_type(TestInputVisitorData *data,
762                                        const void *unused)
763 {
764     TestStruct *p = NULL;
765     Visitor *v;
766     strList *q = NULL;
767     int64_t i;
768     Error *err = NULL;
769
770     /* Make sure arrays and structs cannot be confused */
771
772     v = visitor_input_test_init(data, "[]");
773     visit_type_TestStruct(v, NULL, &p, &err);
774     error_free_or_abort(&err);
775     g_assert(!p);
776
777     v = visitor_input_test_init(data, "{}");
778     visit_type_strList(v, NULL, &q, &err);
779     error_free_or_abort(&err);
780     assert(!q);
781
782     /* Make sure primitives and struct cannot be confused */
783
784     v = visitor_input_test_init(data, "1");
785     visit_type_TestStruct(v, NULL, &p, &err);
786     error_free_or_abort(&err);
787     g_assert(!p);
788
789     v = visitor_input_test_init(data, "{}");
790     visit_type_int(v, NULL, &i, &err);
791     error_free_or_abort(&err);
792
793     /* Make sure primitives and arrays cannot be confused */
794
795     v = visitor_input_test_init(data, "1");
796     visit_type_strList(v, NULL, &q, &err);
797     error_free_or_abort(&err);
798     assert(!q);
799
800     v = visitor_input_test_init(data, "[]");
801     visit_type_int(v, NULL, &i, &err);
802     error_free_or_abort(&err);
803 }
804
805 int main(int argc, char **argv)
806 {
807     TestInputVisitorData in_visitor_data;
808
809     g_test_init(&argc, &argv, NULL);
810
811     input_visitor_test_add("/visitor/input/int",
812                            &in_visitor_data, test_visitor_in_int);
813     input_visitor_test_add("/visitor/input/int_overflow",
814                            &in_visitor_data, test_visitor_in_int_overflow);
815     input_visitor_test_add("/visitor/input/bool",
816                            &in_visitor_data, test_visitor_in_bool);
817     input_visitor_test_add("/visitor/input/number",
818                            &in_visitor_data, test_visitor_in_number);
819     input_visitor_test_add("/visitor/input/string",
820                            &in_visitor_data, test_visitor_in_string);
821     input_visitor_test_add("/visitor/input/enum",
822                            &in_visitor_data, test_visitor_in_enum);
823     input_visitor_test_add("/visitor/input/struct",
824                            &in_visitor_data, test_visitor_in_struct);
825     input_visitor_test_add("/visitor/input/struct-nested",
826                            &in_visitor_data, test_visitor_in_struct_nested);
827     input_visitor_test_add("/visitor/input/list",
828                            &in_visitor_data, test_visitor_in_list);
829     input_visitor_test_add("/visitor/input/any",
830                            &in_visitor_data, test_visitor_in_any);
831     input_visitor_test_add("/visitor/input/union-flat",
832                            &in_visitor_data, test_visitor_in_union_flat);
833     input_visitor_test_add("/visitor/input/alternate",
834                            &in_visitor_data, test_visitor_in_alternate);
835     input_visitor_test_add("/visitor/input/errors",
836                            &in_visitor_data, test_visitor_in_errors);
837     input_visitor_test_add("/visitor/input/wrong-type",
838                            &in_visitor_data, test_visitor_in_wrong_type);
839     input_visitor_test_add("/visitor/input/alternate-number",
840                            &in_visitor_data, test_visitor_in_alternate_number);
841     input_visitor_test_add("/visitor/input/native_list/int",
842                            &in_visitor_data,
843                            test_visitor_in_native_list_int);
844     input_visitor_test_add("/visitor/input/native_list/int8",
845                            &in_visitor_data,
846                            test_visitor_in_native_list_int8);
847     input_visitor_test_add("/visitor/input/native_list/int16",
848                            &in_visitor_data,
849                            test_visitor_in_native_list_int16);
850     input_visitor_test_add("/visitor/input/native_list/int32",
851                            &in_visitor_data,
852                            test_visitor_in_native_list_int32);
853     input_visitor_test_add("/visitor/input/native_list/int64",
854                            &in_visitor_data,
855                            test_visitor_in_native_list_int64);
856     input_visitor_test_add("/visitor/input/native_list/uint8",
857                            &in_visitor_data,
858                            test_visitor_in_native_list_uint8);
859     input_visitor_test_add("/visitor/input/native_list/uint16",
860                            &in_visitor_data,
861                            test_visitor_in_native_list_uint16);
862     input_visitor_test_add("/visitor/input/native_list/uint32",
863                            &in_visitor_data,
864                            test_visitor_in_native_list_uint32);
865     input_visitor_test_add("/visitor/input/native_list/uint64",
866                            &in_visitor_data,
867                            test_visitor_in_native_list_uint64);
868     input_visitor_test_add("/visitor/input/native_list/bool",
869                            &in_visitor_data, test_visitor_in_native_list_bool);
870     input_visitor_test_add("/visitor/input/native_list/str",
871                            &in_visitor_data,
872                            test_visitor_in_native_list_string);
873     input_visitor_test_add("/visitor/input/native_list/number",
874                            &in_visitor_data,
875                            test_visitor_in_native_list_number);
876
877     g_test_run();
878
879     return 0;
880 }
This page took 0.07023 seconds and 4 git commands to generate.