1da668aa1SThomas Huth /* 2da668aa1SThomas Huth * QObject Output Visitor unit-tests. 3da668aa1SThomas Huth * 4da668aa1SThomas Huth * Copyright (C) 2011-2016 Red Hat Inc. 5da668aa1SThomas Huth * 6da668aa1SThomas Huth * Authors: 7da668aa1SThomas Huth * Luiz Capitulino <lcapitulino@redhat.com> 8da668aa1SThomas Huth * 9da668aa1SThomas Huth * This work is licensed under the terms of the GNU GPL, version 2 or later. 10da668aa1SThomas Huth * See the COPYING file in the top-level directory. 11da668aa1SThomas Huth */ 12da668aa1SThomas Huth 13da668aa1SThomas Huth #include "qemu/osdep.h" 14da668aa1SThomas Huth 15da668aa1SThomas Huth #include "qemu-common.h" 16da668aa1SThomas Huth #include "qapi/error.h" 17da668aa1SThomas Huth #include "qapi/qobject-output-visitor.h" 18da668aa1SThomas Huth #include "test-qapi-visit.h" 19da668aa1SThomas Huth #include "qapi/qmp/qbool.h" 20da668aa1SThomas Huth #include "qapi/qmp/qdict.h" 21da668aa1SThomas Huth #include "qapi/qmp/qlist.h" 22da668aa1SThomas Huth #include "qapi/qmp/qnull.h" 23da668aa1SThomas Huth #include "qapi/qmp/qnum.h" 24da668aa1SThomas Huth #include "qapi/qmp/qstring.h" 25da668aa1SThomas Huth 26da668aa1SThomas Huth typedef struct TestOutputVisitorData { 27da668aa1SThomas Huth Visitor *ov; 28da668aa1SThomas Huth QObject *obj; 29da668aa1SThomas Huth } TestOutputVisitorData; 30da668aa1SThomas Huth 31da668aa1SThomas Huth static void visitor_output_setup(TestOutputVisitorData *data, 32da668aa1SThomas Huth const void *unused) 33da668aa1SThomas Huth { 34da668aa1SThomas Huth data->ov = qobject_output_visitor_new(&data->obj); 35da668aa1SThomas Huth g_assert(data->ov); 36da668aa1SThomas Huth } 37da668aa1SThomas Huth 38da668aa1SThomas Huth static void visitor_output_teardown(TestOutputVisitorData *data, 39da668aa1SThomas Huth const void *unused) 40da668aa1SThomas Huth { 41da668aa1SThomas Huth visit_free(data->ov); 42da668aa1SThomas Huth data->ov = NULL; 43da668aa1SThomas Huth qobject_unref(data->obj); 44da668aa1SThomas Huth data->obj = NULL; 45da668aa1SThomas Huth } 46da668aa1SThomas Huth 47da668aa1SThomas Huth static QObject *visitor_get(TestOutputVisitorData *data) 48da668aa1SThomas Huth { 49da668aa1SThomas Huth visit_complete(data->ov, &data->obj); 50da668aa1SThomas Huth g_assert(data->obj); 51da668aa1SThomas Huth return data->obj; 52da668aa1SThomas Huth } 53da668aa1SThomas Huth 54da668aa1SThomas Huth static void visitor_reset(TestOutputVisitorData *data) 55da668aa1SThomas Huth { 56da668aa1SThomas Huth visitor_output_teardown(data, NULL); 57da668aa1SThomas Huth visitor_output_setup(data, NULL); 58da668aa1SThomas Huth } 59da668aa1SThomas Huth 60da668aa1SThomas Huth static void test_visitor_out_int(TestOutputVisitorData *data, 61da668aa1SThomas Huth const void *unused) 62da668aa1SThomas Huth { 63da668aa1SThomas Huth int64_t value = -42; 64da668aa1SThomas Huth int64_t val; 65da668aa1SThomas Huth QNum *qnum; 66da668aa1SThomas Huth 67da668aa1SThomas Huth visit_type_int(data->ov, NULL, &value, &error_abort); 68da668aa1SThomas Huth 69da668aa1SThomas Huth qnum = qobject_to(QNum, visitor_get(data)); 70da668aa1SThomas Huth g_assert(qnum); 71da668aa1SThomas Huth g_assert(qnum_get_try_int(qnum, &val)); 72da668aa1SThomas Huth g_assert_cmpint(val, ==, value); 73da668aa1SThomas Huth } 74da668aa1SThomas Huth 75da668aa1SThomas Huth static void test_visitor_out_bool(TestOutputVisitorData *data, 76da668aa1SThomas Huth const void *unused) 77da668aa1SThomas Huth { 78da668aa1SThomas Huth bool value = true; 79da668aa1SThomas Huth QBool *qbool; 80da668aa1SThomas Huth 81da668aa1SThomas Huth visit_type_bool(data->ov, NULL, &value, &error_abort); 82da668aa1SThomas Huth 83da668aa1SThomas Huth qbool = qobject_to(QBool, visitor_get(data)); 84da668aa1SThomas Huth g_assert(qbool); 85da668aa1SThomas Huth g_assert(qbool_get_bool(qbool) == value); 86da668aa1SThomas Huth } 87da668aa1SThomas Huth 88da668aa1SThomas Huth static void test_visitor_out_number(TestOutputVisitorData *data, 89da668aa1SThomas Huth const void *unused) 90da668aa1SThomas Huth { 91da668aa1SThomas Huth double value = 3.14; 92da668aa1SThomas Huth QNum *qnum; 93da668aa1SThomas Huth 94da668aa1SThomas Huth visit_type_number(data->ov, NULL, &value, &error_abort); 95da668aa1SThomas Huth 96da668aa1SThomas Huth qnum = qobject_to(QNum, visitor_get(data)); 97da668aa1SThomas Huth g_assert(qnum); 98da668aa1SThomas Huth g_assert(qnum_get_double(qnum) == value); 99da668aa1SThomas Huth } 100da668aa1SThomas Huth 101da668aa1SThomas Huth static void test_visitor_out_string(TestOutputVisitorData *data, 102da668aa1SThomas Huth const void *unused) 103da668aa1SThomas Huth { 104da668aa1SThomas Huth char *string = (char *) "Q E M U"; 105da668aa1SThomas Huth QString *qstr; 106da668aa1SThomas Huth 107da668aa1SThomas Huth visit_type_str(data->ov, NULL, &string, &error_abort); 108da668aa1SThomas Huth 109da668aa1SThomas Huth qstr = qobject_to(QString, visitor_get(data)); 110da668aa1SThomas Huth g_assert(qstr); 111da668aa1SThomas Huth g_assert_cmpstr(qstring_get_str(qstr), ==, string); 112da668aa1SThomas Huth } 113da668aa1SThomas Huth 114da668aa1SThomas Huth static void test_visitor_out_no_string(TestOutputVisitorData *data, 115da668aa1SThomas Huth const void *unused) 116da668aa1SThomas Huth { 117da668aa1SThomas Huth char *string = NULL; 118da668aa1SThomas Huth QString *qstr; 119da668aa1SThomas Huth 120da668aa1SThomas Huth /* A null string should return "" */ 121da668aa1SThomas Huth visit_type_str(data->ov, NULL, &string, &error_abort); 122da668aa1SThomas Huth 123da668aa1SThomas Huth qstr = qobject_to(QString, visitor_get(data)); 124da668aa1SThomas Huth g_assert(qstr); 125da668aa1SThomas Huth g_assert_cmpstr(qstring_get_str(qstr), ==, ""); 126da668aa1SThomas Huth } 127da668aa1SThomas Huth 128da668aa1SThomas Huth static void test_visitor_out_enum(TestOutputVisitorData *data, 129da668aa1SThomas Huth const void *unused) 130da668aa1SThomas Huth { 131da668aa1SThomas Huth EnumOne i; 132da668aa1SThomas Huth QString *qstr; 133da668aa1SThomas Huth 134da668aa1SThomas Huth for (i = 0; i < ENUM_ONE__MAX; i++) { 135da668aa1SThomas Huth visit_type_EnumOne(data->ov, "unused", &i, &error_abort); 136da668aa1SThomas Huth 137da668aa1SThomas Huth qstr = qobject_to(QString, visitor_get(data)); 138da668aa1SThomas Huth g_assert(qstr); 139da668aa1SThomas Huth g_assert_cmpstr(qstring_get_str(qstr), ==, EnumOne_str(i)); 140da668aa1SThomas Huth visitor_reset(data); 141da668aa1SThomas Huth } 142da668aa1SThomas Huth } 143da668aa1SThomas Huth 144da668aa1SThomas Huth static void test_visitor_out_struct(TestOutputVisitorData *data, 145da668aa1SThomas Huth const void *unused) 146da668aa1SThomas Huth { 147da668aa1SThomas Huth TestStruct test_struct = { .integer = 42, 148da668aa1SThomas Huth .boolean = false, 149da668aa1SThomas Huth .string = (char *) "foo"}; 150da668aa1SThomas Huth TestStruct *p = &test_struct; 151da668aa1SThomas Huth QDict *qdict; 152da668aa1SThomas Huth 153da668aa1SThomas Huth visit_type_TestStruct(data->ov, NULL, &p, &error_abort); 154da668aa1SThomas Huth 155da668aa1SThomas Huth qdict = qobject_to(QDict, visitor_get(data)); 156da668aa1SThomas Huth g_assert(qdict); 157da668aa1SThomas Huth g_assert_cmpint(qdict_size(qdict), ==, 3); 158da668aa1SThomas Huth g_assert_cmpint(qdict_get_int(qdict, "integer"), ==, 42); 159da668aa1SThomas Huth g_assert_cmpint(qdict_get_bool(qdict, "boolean"), ==, false); 160da668aa1SThomas Huth g_assert_cmpstr(qdict_get_str(qdict, "string"), ==, "foo"); 161da668aa1SThomas Huth } 162da668aa1SThomas Huth 163da668aa1SThomas Huth static void test_visitor_out_struct_nested(TestOutputVisitorData *data, 164da668aa1SThomas Huth const void *unused) 165da668aa1SThomas Huth { 166da668aa1SThomas Huth int64_t value = 42; 167da668aa1SThomas Huth UserDefTwo *ud2; 168da668aa1SThomas Huth QDict *qdict, *dict1, *dict2, *dict3, *userdef; 169da668aa1SThomas Huth const char *string = "user def string"; 170da668aa1SThomas Huth const char *strings[] = { "forty two", "forty three", "forty four", 171da668aa1SThomas Huth "forty five" }; 172da668aa1SThomas Huth 173da668aa1SThomas Huth ud2 = g_malloc0(sizeof(*ud2)); 174da668aa1SThomas Huth ud2->string0 = g_strdup(strings[0]); 175da668aa1SThomas Huth 176da668aa1SThomas Huth ud2->dict1 = g_malloc0(sizeof(*ud2->dict1)); 177da668aa1SThomas Huth ud2->dict1->string1 = g_strdup(strings[1]); 178da668aa1SThomas Huth 179da668aa1SThomas Huth ud2->dict1->dict2 = g_malloc0(sizeof(*ud2->dict1->dict2)); 180da668aa1SThomas Huth ud2->dict1->dict2->userdef = g_new0(UserDefOne, 1); 181da668aa1SThomas Huth ud2->dict1->dict2->userdef->string = g_strdup(string); 182da668aa1SThomas Huth ud2->dict1->dict2->userdef->integer = value; 183da668aa1SThomas Huth ud2->dict1->dict2->string = g_strdup(strings[2]); 184da668aa1SThomas Huth 185da668aa1SThomas Huth ud2->dict1->dict3 = g_malloc0(sizeof(*ud2->dict1->dict3)); 186da668aa1SThomas Huth ud2->dict1->has_dict3 = true; 187da668aa1SThomas Huth ud2->dict1->dict3->userdef = g_new0(UserDefOne, 1); 188da668aa1SThomas Huth ud2->dict1->dict3->userdef->string = g_strdup(string); 189da668aa1SThomas Huth ud2->dict1->dict3->userdef->integer = value; 190da668aa1SThomas Huth ud2->dict1->dict3->string = g_strdup(strings[3]); 191da668aa1SThomas Huth 192da668aa1SThomas Huth visit_type_UserDefTwo(data->ov, "unused", &ud2, &error_abort); 193da668aa1SThomas Huth 194da668aa1SThomas Huth qdict = qobject_to(QDict, visitor_get(data)); 195da668aa1SThomas Huth g_assert(qdict); 196da668aa1SThomas Huth g_assert_cmpint(qdict_size(qdict), ==, 2); 197da668aa1SThomas Huth g_assert_cmpstr(qdict_get_str(qdict, "string0"), ==, strings[0]); 198da668aa1SThomas Huth 199da668aa1SThomas Huth dict1 = qdict_get_qdict(qdict, "dict1"); 200da668aa1SThomas Huth g_assert_cmpint(qdict_size(dict1), ==, 3); 201da668aa1SThomas Huth g_assert_cmpstr(qdict_get_str(dict1, "string1"), ==, strings[1]); 202da668aa1SThomas Huth 203da668aa1SThomas Huth dict2 = qdict_get_qdict(dict1, "dict2"); 204da668aa1SThomas Huth g_assert_cmpint(qdict_size(dict2), ==, 2); 205da668aa1SThomas Huth g_assert_cmpstr(qdict_get_str(dict2, "string"), ==, strings[2]); 206da668aa1SThomas Huth userdef = qdict_get_qdict(dict2, "userdef"); 207da668aa1SThomas Huth g_assert_cmpint(qdict_size(userdef), ==, 2); 208da668aa1SThomas Huth g_assert_cmpint(qdict_get_int(userdef, "integer"), ==, value); 209da668aa1SThomas Huth g_assert_cmpstr(qdict_get_str(userdef, "string"), ==, string); 210da668aa1SThomas Huth 211da668aa1SThomas Huth dict3 = qdict_get_qdict(dict1, "dict3"); 212da668aa1SThomas Huth g_assert_cmpint(qdict_size(dict3), ==, 2); 213da668aa1SThomas Huth g_assert_cmpstr(qdict_get_str(dict3, "string"), ==, strings[3]); 214da668aa1SThomas Huth userdef = qdict_get_qdict(dict3, "userdef"); 215da668aa1SThomas Huth g_assert_cmpint(qdict_size(userdef), ==, 2); 216da668aa1SThomas Huth g_assert_cmpint(qdict_get_int(userdef, "integer"), ==, value); 217da668aa1SThomas Huth g_assert_cmpstr(qdict_get_str(userdef, "string"), ==, string); 218da668aa1SThomas Huth 219da668aa1SThomas Huth qapi_free_UserDefTwo(ud2); 220da668aa1SThomas Huth } 221da668aa1SThomas Huth 222da668aa1SThomas Huth static void test_visitor_out_list(TestOutputVisitorData *data, 223da668aa1SThomas Huth const void *unused) 224da668aa1SThomas Huth { 225da668aa1SThomas Huth const char *value_str = "list value"; 226da668aa1SThomas Huth TestStruct *value; 227da668aa1SThomas Huth TestStructList *head = NULL; 228da668aa1SThomas Huth const int max_items = 10; 229da668aa1SThomas Huth bool value_bool = true; 230da668aa1SThomas Huth int value_int = 10; 231da668aa1SThomas Huth QListEntry *entry; 232da668aa1SThomas Huth QList *qlist; 233da668aa1SThomas Huth int i; 234da668aa1SThomas Huth 235da668aa1SThomas Huth /* Build the list in reverse order... */ 236da668aa1SThomas Huth for (i = 0; i < max_items; i++) { 237da668aa1SThomas Huth value = g_malloc0(sizeof(*value)); 238da668aa1SThomas Huth value->integer = value_int + (max_items - i - 1); 239da668aa1SThomas Huth value->boolean = value_bool; 240da668aa1SThomas Huth value->string = g_strdup(value_str); 241da668aa1SThomas Huth 242da668aa1SThomas Huth QAPI_LIST_PREPEND(head, value); 243da668aa1SThomas Huth } 244da668aa1SThomas Huth 245da668aa1SThomas Huth visit_type_TestStructList(data->ov, NULL, &head, &error_abort); 246da668aa1SThomas Huth 247da668aa1SThomas Huth qlist = qobject_to(QList, visitor_get(data)); 248da668aa1SThomas Huth g_assert(qlist); 249da668aa1SThomas Huth g_assert(!qlist_empty(qlist)); 250da668aa1SThomas Huth 251da668aa1SThomas Huth /* ...and ensure that the visitor sees it in order */ 252da668aa1SThomas Huth i = 0; 253da668aa1SThomas Huth QLIST_FOREACH_ENTRY(qlist, entry) { 254da668aa1SThomas Huth QDict *qdict; 255da668aa1SThomas Huth 256da668aa1SThomas Huth qdict = qobject_to(QDict, entry->value); 257da668aa1SThomas Huth g_assert(qdict); 258da668aa1SThomas Huth g_assert_cmpint(qdict_size(qdict), ==, 3); 259da668aa1SThomas Huth g_assert_cmpint(qdict_get_int(qdict, "integer"), ==, value_int + i); 260da668aa1SThomas Huth g_assert_cmpint(qdict_get_bool(qdict, "boolean"), ==, value_bool); 261da668aa1SThomas Huth g_assert_cmpstr(qdict_get_str(qdict, "string"), ==, value_str); 262da668aa1SThomas Huth i++; 263da668aa1SThomas Huth } 264da668aa1SThomas Huth g_assert_cmpint(i, ==, max_items); 265da668aa1SThomas Huth 266da668aa1SThomas Huth qapi_free_TestStructList(head); 267da668aa1SThomas Huth } 268da668aa1SThomas Huth 269da668aa1SThomas Huth static void test_visitor_out_list_qapi_free(TestOutputVisitorData *data, 270da668aa1SThomas Huth const void *unused) 271da668aa1SThomas Huth { 272da668aa1SThomas Huth UserDefTwo *value; 273da668aa1SThomas Huth UserDefTwoList *head = NULL; 274da668aa1SThomas Huth const char string[] = "foo bar"; 275da668aa1SThomas Huth int i, max_count = 1024; 276da668aa1SThomas Huth 277da668aa1SThomas Huth for (i = 0; i < max_count; i++) { 278da668aa1SThomas Huth value = g_malloc0(sizeof(*value)); 279da668aa1SThomas Huth 280da668aa1SThomas Huth value->string0 = g_strdup(string); 281da668aa1SThomas Huth value->dict1 = g_new0(UserDefTwoDict, 1); 282da668aa1SThomas Huth value->dict1->string1 = g_strdup(string); 283da668aa1SThomas Huth value->dict1->dict2 = g_new0(UserDefTwoDictDict, 1); 284da668aa1SThomas Huth value->dict1->dict2->userdef = g_new0(UserDefOne, 1); 285da668aa1SThomas Huth value->dict1->dict2->userdef->string = g_strdup(string); 286da668aa1SThomas Huth value->dict1->dict2->userdef->integer = 42; 287da668aa1SThomas Huth value->dict1->dict2->string = g_strdup(string); 288da668aa1SThomas Huth value->dict1->has_dict3 = false; 289da668aa1SThomas Huth 290da668aa1SThomas Huth QAPI_LIST_PREPEND(head, value); 291da668aa1SThomas Huth } 292da668aa1SThomas Huth 293da668aa1SThomas Huth qapi_free_UserDefTwoList(head); 294da668aa1SThomas Huth } 295da668aa1SThomas Huth 296da668aa1SThomas Huth static void test_visitor_out_any(TestOutputVisitorData *data, 297da668aa1SThomas Huth const void *unused) 298da668aa1SThomas Huth { 299da668aa1SThomas Huth QObject *qobj; 300da668aa1SThomas Huth QNum *qnum; 301da668aa1SThomas Huth QBool *qbool; 302da668aa1SThomas Huth QString *qstring; 303da668aa1SThomas Huth QDict *qdict; 304da668aa1SThomas Huth int64_t val; 305da668aa1SThomas Huth 306da668aa1SThomas Huth qobj = QOBJECT(qnum_from_int(-42)); 307da668aa1SThomas Huth visit_type_any(data->ov, NULL, &qobj, &error_abort); 308da668aa1SThomas Huth qnum = qobject_to(QNum, visitor_get(data)); 309da668aa1SThomas Huth g_assert(qnum); 310da668aa1SThomas Huth g_assert(qnum_get_try_int(qnum, &val)); 311da668aa1SThomas Huth g_assert_cmpint(val, ==, -42); 312da668aa1SThomas Huth qobject_unref(qobj); 313da668aa1SThomas Huth 314da668aa1SThomas Huth visitor_reset(data); 315da668aa1SThomas Huth qdict = qdict_new(); 316da668aa1SThomas Huth qdict_put_int(qdict, "integer", -42); 317da668aa1SThomas Huth qdict_put_bool(qdict, "boolean", true); 318da668aa1SThomas Huth qdict_put_str(qdict, "string", "foo"); 319da668aa1SThomas Huth qobj = QOBJECT(qdict); 320da668aa1SThomas Huth visit_type_any(data->ov, NULL, &qobj, &error_abort); 321da668aa1SThomas Huth qobject_unref(qobj); 322da668aa1SThomas Huth qdict = qobject_to(QDict, visitor_get(data)); 323da668aa1SThomas Huth g_assert(qdict); 324da668aa1SThomas Huth qnum = qobject_to(QNum, qdict_get(qdict, "integer")); 325da668aa1SThomas Huth g_assert(qnum); 326da668aa1SThomas Huth g_assert(qnum_get_try_int(qnum, &val)); 327da668aa1SThomas Huth g_assert_cmpint(val, ==, -42); 328da668aa1SThomas Huth qbool = qobject_to(QBool, qdict_get(qdict, "boolean")); 329da668aa1SThomas Huth g_assert(qbool); 330da668aa1SThomas Huth g_assert(qbool_get_bool(qbool) == true); 331da668aa1SThomas Huth qstring = qobject_to(QString, qdict_get(qdict, "string")); 332da668aa1SThomas Huth g_assert(qstring); 333da668aa1SThomas Huth g_assert_cmpstr(qstring_get_str(qstring), ==, "foo"); 334da668aa1SThomas Huth } 335da668aa1SThomas Huth 336da668aa1SThomas Huth static void test_visitor_out_union_flat(TestOutputVisitorData *data, 337da668aa1SThomas Huth const void *unused) 338da668aa1SThomas Huth { 339da668aa1SThomas Huth QDict *qdict; 340da668aa1SThomas Huth 341da668aa1SThomas Huth UserDefFlatUnion *tmp = g_malloc0(sizeof(UserDefFlatUnion)); 342da668aa1SThomas Huth tmp->enum1 = ENUM_ONE_VALUE1; 343da668aa1SThomas Huth tmp->string = g_strdup("str"); 344da668aa1SThomas Huth tmp->integer = 41; 345da668aa1SThomas Huth tmp->u.value1.boolean = true; 346da668aa1SThomas Huth 347da668aa1SThomas Huth visit_type_UserDefFlatUnion(data->ov, NULL, &tmp, &error_abort); 348da668aa1SThomas Huth qdict = qobject_to(QDict, visitor_get(data)); 349da668aa1SThomas Huth g_assert(qdict); 350da668aa1SThomas Huth g_assert_cmpstr(qdict_get_str(qdict, "enum1"), ==, "value1"); 351da668aa1SThomas Huth g_assert_cmpstr(qdict_get_str(qdict, "string"), ==, "str"); 352da668aa1SThomas Huth g_assert_cmpint(qdict_get_int(qdict, "integer"), ==, 41); 353da668aa1SThomas Huth g_assert_cmpint(qdict_get_bool(qdict, "boolean"), ==, true); 354da668aa1SThomas Huth 355da668aa1SThomas Huth qapi_free_UserDefFlatUnion(tmp); 356da668aa1SThomas Huth } 357da668aa1SThomas Huth 358da668aa1SThomas Huth static void test_visitor_out_alternate(TestOutputVisitorData *data, 359da668aa1SThomas Huth const void *unused) 360da668aa1SThomas Huth { 361da668aa1SThomas Huth UserDefAlternate *tmp; 362da668aa1SThomas Huth QNum *qnum; 363da668aa1SThomas Huth QString *qstr; 364da668aa1SThomas Huth QDict *qdict; 365da668aa1SThomas Huth int64_t val; 366da668aa1SThomas Huth 367da668aa1SThomas Huth tmp = g_new0(UserDefAlternate, 1); 368da668aa1SThomas Huth tmp->type = QTYPE_QNUM; 369da668aa1SThomas Huth tmp->u.i = 42; 370da668aa1SThomas Huth 371da668aa1SThomas Huth visit_type_UserDefAlternate(data->ov, NULL, &tmp, &error_abort); 372da668aa1SThomas Huth qnum = qobject_to(QNum, visitor_get(data)); 373da668aa1SThomas Huth g_assert(qnum); 374da668aa1SThomas Huth g_assert(qnum_get_try_int(qnum, &val)); 375da668aa1SThomas Huth g_assert_cmpint(val, ==, 42); 376da668aa1SThomas Huth 377da668aa1SThomas Huth qapi_free_UserDefAlternate(tmp); 378da668aa1SThomas Huth 379da668aa1SThomas Huth visitor_reset(data); 380da668aa1SThomas Huth tmp = g_new0(UserDefAlternate, 1); 381da668aa1SThomas Huth tmp->type = QTYPE_QSTRING; 382da668aa1SThomas Huth tmp->u.e = ENUM_ONE_VALUE1; 383da668aa1SThomas Huth 384da668aa1SThomas Huth visit_type_UserDefAlternate(data->ov, NULL, &tmp, &error_abort); 385da668aa1SThomas Huth qstr = qobject_to(QString, visitor_get(data)); 386da668aa1SThomas Huth g_assert(qstr); 387da668aa1SThomas Huth g_assert_cmpstr(qstring_get_str(qstr), ==, "value1"); 388da668aa1SThomas Huth 389da668aa1SThomas Huth qapi_free_UserDefAlternate(tmp); 390da668aa1SThomas Huth 391da668aa1SThomas Huth visitor_reset(data); 392da668aa1SThomas Huth tmp = g_new0(UserDefAlternate, 1); 393da668aa1SThomas Huth tmp->type = QTYPE_QNULL; 394da668aa1SThomas Huth tmp->u.n = qnull(); 395da668aa1SThomas Huth 396da668aa1SThomas Huth visit_type_UserDefAlternate(data->ov, NULL, &tmp, &error_abort); 397da668aa1SThomas Huth g_assert_cmpint(qobject_type(visitor_get(data)), ==, QTYPE_QNULL); 398da668aa1SThomas Huth 399da668aa1SThomas Huth qapi_free_UserDefAlternate(tmp); 400da668aa1SThomas Huth 401da668aa1SThomas Huth visitor_reset(data); 402da668aa1SThomas Huth tmp = g_new0(UserDefAlternate, 1); 403da668aa1SThomas Huth tmp->type = QTYPE_QDICT; 404da668aa1SThomas Huth tmp->u.udfu.integer = 1; 405da668aa1SThomas Huth tmp->u.udfu.string = g_strdup("str"); 406da668aa1SThomas Huth tmp->u.udfu.enum1 = ENUM_ONE_VALUE1; 407da668aa1SThomas Huth tmp->u.udfu.u.value1.boolean = true; 408da668aa1SThomas Huth 409da668aa1SThomas Huth visit_type_UserDefAlternate(data->ov, NULL, &tmp, &error_abort); 410da668aa1SThomas Huth qdict = qobject_to(QDict, visitor_get(data)); 411da668aa1SThomas Huth g_assert(qdict); 412da668aa1SThomas Huth g_assert_cmpint(qdict_size(qdict), ==, 4); 413da668aa1SThomas Huth g_assert_cmpint(qdict_get_int(qdict, "integer"), ==, 1); 414da668aa1SThomas Huth g_assert_cmpstr(qdict_get_str(qdict, "string"), ==, "str"); 415da668aa1SThomas Huth g_assert_cmpstr(qdict_get_str(qdict, "enum1"), ==, "value1"); 416da668aa1SThomas Huth g_assert_cmpint(qdict_get_bool(qdict, "boolean"), ==, true); 417da668aa1SThomas Huth 418da668aa1SThomas Huth qapi_free_UserDefAlternate(tmp); 419da668aa1SThomas Huth } 420da668aa1SThomas Huth 421da668aa1SThomas Huth static void test_visitor_out_null(TestOutputVisitorData *data, 422da668aa1SThomas Huth const void *unused) 423da668aa1SThomas Huth { 424da668aa1SThomas Huth QNull *null = NULL; 425da668aa1SThomas Huth QDict *qdict; 426da668aa1SThomas Huth QObject *nil; 427da668aa1SThomas Huth 428da668aa1SThomas Huth visit_start_struct(data->ov, NULL, NULL, 0, &error_abort); 429da668aa1SThomas Huth visit_type_null(data->ov, "a", &null, &error_abort); 430da668aa1SThomas Huth visit_check_struct(data->ov, &error_abort); 431da668aa1SThomas Huth visit_end_struct(data->ov, NULL); 432da668aa1SThomas Huth qdict = qobject_to(QDict, visitor_get(data)); 433da668aa1SThomas Huth g_assert(qdict); 434da668aa1SThomas Huth g_assert_cmpint(qdict_size(qdict), ==, 1); 435da668aa1SThomas Huth nil = qdict_get(qdict, "a"); 436da668aa1SThomas Huth g_assert(nil); 437da668aa1SThomas Huth g_assert(qobject_type(nil) == QTYPE_QNULL); 438da668aa1SThomas Huth } 439da668aa1SThomas Huth 440*00e6832fSMarkus Armbruster static void test_visitor_out_list_struct(TestOutputVisitorData *data, 441*00e6832fSMarkus Armbruster const void *unused) 442da668aa1SThomas Huth { 443*00e6832fSMarkus Armbruster const char *int_member[] = { 444*00e6832fSMarkus Armbruster "integer", "s8", "s16", "s32", "s64", "u8", "u16", "u32", "u64" }; 445*00e6832fSMarkus Armbruster g_autoptr(ArrayStruct) arrs = g_new0(ArrayStruct, 1); 446*00e6832fSMarkus Armbruster int i, j; 447da668aa1SThomas Huth QDict *qdict; 448da668aa1SThomas Huth QList *qlist; 449*00e6832fSMarkus Armbruster QListEntry *e; 450da668aa1SThomas Huth 451*00e6832fSMarkus Armbruster for (i = 31; i >= 0; i--) { 452*00e6832fSMarkus Armbruster QAPI_LIST_PREPEND(arrs->integer, i); 453*00e6832fSMarkus Armbruster } 454*00e6832fSMarkus Armbruster 455*00e6832fSMarkus Armbruster for (i = 31; i >= 0; i--) { 456*00e6832fSMarkus Armbruster QAPI_LIST_PREPEND(arrs->s8, i); 457*00e6832fSMarkus Armbruster } 458*00e6832fSMarkus Armbruster 459*00e6832fSMarkus Armbruster for (i = 31; i >= 0; i--) { 460*00e6832fSMarkus Armbruster QAPI_LIST_PREPEND(arrs->s16, i); 461*00e6832fSMarkus Armbruster } 462*00e6832fSMarkus Armbruster 463*00e6832fSMarkus Armbruster for (i = 31; i >= 0; i--) { 464*00e6832fSMarkus Armbruster QAPI_LIST_PREPEND(arrs->s32, i); 465*00e6832fSMarkus Armbruster } 466*00e6832fSMarkus Armbruster 467*00e6832fSMarkus Armbruster for (i = 31; i >= 0; i--) { 468*00e6832fSMarkus Armbruster QAPI_LIST_PREPEND(arrs->s64, i); 469*00e6832fSMarkus Armbruster } 470*00e6832fSMarkus Armbruster 471*00e6832fSMarkus Armbruster for (i = 31; i >= 0; i--) { 472*00e6832fSMarkus Armbruster QAPI_LIST_PREPEND(arrs->u8, i); 473*00e6832fSMarkus Armbruster } 474*00e6832fSMarkus Armbruster 475*00e6832fSMarkus Armbruster for (i = 31; i >= 0; i--) { 476*00e6832fSMarkus Armbruster QAPI_LIST_PREPEND(arrs->u16, i); 477*00e6832fSMarkus Armbruster } 478*00e6832fSMarkus Armbruster 479*00e6832fSMarkus Armbruster for (i = 31; i >= 0; i--) { 480*00e6832fSMarkus Armbruster QAPI_LIST_PREPEND(arrs->u32, i); 481*00e6832fSMarkus Armbruster } 482*00e6832fSMarkus Armbruster 483*00e6832fSMarkus Armbruster for (i = 31; i >= 0; i--) { 484*00e6832fSMarkus Armbruster QAPI_LIST_PREPEND(arrs->u64, i); 485*00e6832fSMarkus Armbruster } 486*00e6832fSMarkus Armbruster 487*00e6832fSMarkus Armbruster for (i = 31; i >= 0; i--) { 488*00e6832fSMarkus Armbruster QAPI_LIST_PREPEND(arrs->number, (double)i / 3); 489*00e6832fSMarkus Armbruster } 490*00e6832fSMarkus Armbruster 491*00e6832fSMarkus Armbruster for (i = 31; i >= 0; i--) { 492*00e6832fSMarkus Armbruster QAPI_LIST_PREPEND(arrs->boolean, QEMU_IS_ALIGNED(i, 3)); 493*00e6832fSMarkus Armbruster } 494*00e6832fSMarkus Armbruster 495*00e6832fSMarkus Armbruster for (i = 31; i >= 0; i--) { 496*00e6832fSMarkus Armbruster QAPI_LIST_PREPEND(arrs->string, g_strdup_printf("%d", i)); 497*00e6832fSMarkus Armbruster } 498*00e6832fSMarkus Armbruster 499*00e6832fSMarkus Armbruster visit_type_ArrayStruct(data->ov, NULL, &arrs, &error_abort); 500*00e6832fSMarkus Armbruster 501*00e6832fSMarkus Armbruster qdict = qobject_to(QDict, visitor_get(data)); 502da668aa1SThomas Huth g_assert(qdict); 503da668aa1SThomas Huth 504*00e6832fSMarkus Armbruster for (i = 0; i < G_N_ELEMENTS(int_member); i++) { 505*00e6832fSMarkus Armbruster qlist = qdict_get_qlist(qdict, int_member[i]); 506*00e6832fSMarkus Armbruster g_assert(qlist); 507*00e6832fSMarkus Armbruster j = 0; 508*00e6832fSMarkus Armbruster QLIST_FOREACH_ENTRY(qlist, e) { 509*00e6832fSMarkus Armbruster QNum *qvalue = qobject_to(QNum, qlist_entry_obj(e)); 510*00e6832fSMarkus Armbruster g_assert(qvalue); 511*00e6832fSMarkus Armbruster g_assert_cmpint(qnum_get_int(qvalue), ==, j); 512*00e6832fSMarkus Armbruster j++; 513da668aa1SThomas Huth } 514da668aa1SThomas Huth } 515*00e6832fSMarkus Armbruster 516*00e6832fSMarkus Armbruster qlist = qdict_get_qlist(qdict, "number"); 517*00e6832fSMarkus Armbruster g_assert(qlist); 518*00e6832fSMarkus Armbruster i = 0; 519*00e6832fSMarkus Armbruster QLIST_FOREACH_ENTRY(qlist, e) { 520*00e6832fSMarkus Armbruster QNum *qvalue = qobject_to(QNum, qlist_entry_obj(e)); 521*00e6832fSMarkus Armbruster char expected[32], actual[32]; 522*00e6832fSMarkus Armbruster 523*00e6832fSMarkus Armbruster g_assert(qvalue); 524*00e6832fSMarkus Armbruster sprintf(expected, "%.6f", (double)i / 3); 525*00e6832fSMarkus Armbruster sprintf(actual, "%.6f", qnum_get_double(qvalue)); 526*00e6832fSMarkus Armbruster g_assert_cmpstr(actual, ==, expected); 527*00e6832fSMarkus Armbruster i++; 528*00e6832fSMarkus Armbruster } 529*00e6832fSMarkus Armbruster 530*00e6832fSMarkus Armbruster qlist = qdict_get_qlist(qdict, "boolean"); 531*00e6832fSMarkus Armbruster g_assert(qlist); 532*00e6832fSMarkus Armbruster i = 0; 533*00e6832fSMarkus Armbruster QLIST_FOREACH_ENTRY(qlist, e) { 534*00e6832fSMarkus Armbruster QBool *qvalue = qobject_to(QBool, qlist_entry_obj(e)); 535*00e6832fSMarkus Armbruster g_assert(qvalue); 536da668aa1SThomas Huth g_assert_cmpint(qbool_get_bool(qvalue), ==, i % 3 == 0); 537*00e6832fSMarkus Armbruster i++; 538da668aa1SThomas Huth } 539da668aa1SThomas Huth 540*00e6832fSMarkus Armbruster qlist = qdict_get_qlist(qdict, "string"); 541*00e6832fSMarkus Armbruster g_assert(qlist); 542*00e6832fSMarkus Armbruster i = 0; 543*00e6832fSMarkus Armbruster QLIST_FOREACH_ENTRY(qlist, e) { 544*00e6832fSMarkus Armbruster QString *qvalue = qobject_to(QString, qlist_entry_obj(e)); 545*00e6832fSMarkus Armbruster char expected[32]; 546da668aa1SThomas Huth 547*00e6832fSMarkus Armbruster g_assert(qvalue); 548*00e6832fSMarkus Armbruster sprintf(expected, "%d", i); 549*00e6832fSMarkus Armbruster g_assert_cmpstr(qstring_get_str(qvalue), ==, expected); 550*00e6832fSMarkus Armbruster i++; 551da668aa1SThomas Huth } 552da668aa1SThomas Huth } 553da668aa1SThomas Huth 554da668aa1SThomas Huth static void output_visitor_test_add(const char *testpath, 555da668aa1SThomas Huth TestOutputVisitorData *data, 556da668aa1SThomas Huth void (*test_func)(TestOutputVisitorData *data, const void *user_data)) 557da668aa1SThomas Huth { 558da668aa1SThomas Huth g_test_add(testpath, TestOutputVisitorData, data, visitor_output_setup, 559da668aa1SThomas Huth test_func, visitor_output_teardown); 560da668aa1SThomas Huth } 561da668aa1SThomas Huth 562da668aa1SThomas Huth int main(int argc, char **argv) 563da668aa1SThomas Huth { 564da668aa1SThomas Huth TestOutputVisitorData out_visitor_data; 565da668aa1SThomas Huth 566da668aa1SThomas Huth g_test_init(&argc, &argv, NULL); 567da668aa1SThomas Huth 568da668aa1SThomas Huth output_visitor_test_add("/visitor/output/int", 569da668aa1SThomas Huth &out_visitor_data, test_visitor_out_int); 570da668aa1SThomas Huth output_visitor_test_add("/visitor/output/bool", 571da668aa1SThomas Huth &out_visitor_data, test_visitor_out_bool); 572da668aa1SThomas Huth output_visitor_test_add("/visitor/output/number", 573da668aa1SThomas Huth &out_visitor_data, test_visitor_out_number); 574da668aa1SThomas Huth output_visitor_test_add("/visitor/output/string", 575da668aa1SThomas Huth &out_visitor_data, test_visitor_out_string); 576da668aa1SThomas Huth output_visitor_test_add("/visitor/output/no-string", 577da668aa1SThomas Huth &out_visitor_data, test_visitor_out_no_string); 578da668aa1SThomas Huth output_visitor_test_add("/visitor/output/enum", 579da668aa1SThomas Huth &out_visitor_data, test_visitor_out_enum); 580da668aa1SThomas Huth output_visitor_test_add("/visitor/output/struct", 581da668aa1SThomas Huth &out_visitor_data, test_visitor_out_struct); 582da668aa1SThomas Huth output_visitor_test_add("/visitor/output/struct-nested", 583da668aa1SThomas Huth &out_visitor_data, test_visitor_out_struct_nested); 584da668aa1SThomas Huth output_visitor_test_add("/visitor/output/list", 585da668aa1SThomas Huth &out_visitor_data, test_visitor_out_list); 586da668aa1SThomas Huth output_visitor_test_add("/visitor/output/any", 587da668aa1SThomas Huth &out_visitor_data, test_visitor_out_any); 588da668aa1SThomas Huth output_visitor_test_add("/visitor/output/list-qapi-free", 589da668aa1SThomas Huth &out_visitor_data, test_visitor_out_list_qapi_free); 590da668aa1SThomas Huth output_visitor_test_add("/visitor/output/union-flat", 591da668aa1SThomas Huth &out_visitor_data, test_visitor_out_union_flat); 592da668aa1SThomas Huth output_visitor_test_add("/visitor/output/alternate", 593da668aa1SThomas Huth &out_visitor_data, test_visitor_out_alternate); 594da668aa1SThomas Huth output_visitor_test_add("/visitor/output/null", 595da668aa1SThomas Huth &out_visitor_data, test_visitor_out_null); 596*00e6832fSMarkus Armbruster output_visitor_test_add("/visitor/output/list_struct", 597*00e6832fSMarkus Armbruster &out_visitor_data, test_visitor_out_list_struct); 598da668aa1SThomas Huth 599da668aa1SThomas Huth g_test_run(); 600da668aa1SThomas Huth 601da668aa1SThomas Huth return 0; 602da668aa1SThomas Huth } 603