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