2
0

test-qmp-input-visitor.c 30 KB

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