/* test generated deallocation on an object whose construction was prematurely * terminated due to an error */ static void test_dealloc_partial(void) { static const char text[] = "don't leak me"; UserDefTwo *ud2 = NULL; Error *err = NULL; /* create partial object */ { QDict *ud2_dict; QmpInputVisitor *qiv; ud2_dict = qdict_new(); qdict_put_obj(ud2_dict, "string0", QOBJECT(qstring_from_str(text))); qiv = qmp_input_visitor_new(QOBJECT(ud2_dict)); visit_type_UserDefTwo(qmp_input_get_visitor(qiv), &ud2, NULL, &err); qmp_input_visitor_cleanup(qiv); QDECREF(ud2_dict); } /* verify partial success */ assert(ud2 != NULL); assert(ud2->string0 != NULL); assert(strcmp(ud2->string0, text) == 0); assert(ud2->dict1 == NULL); /* confirm & release construction error */ assert(err != NULL); error_free(err); /* tear down partial object */ qapi_free_UserDefTwo(ud2); }
/* test generated deallocation on an object whose construction was prematurely * terminated due to an error */ static void test_dealloc_partial(void) { static const char text[] = "don't leak me"; UserDefTwo *ud2 = NULL; Error *err = NULL; /* create partial object */ { QDict *ud2_dict; Visitor *v; ud2_dict = qdict_new(); qdict_put_str(ud2_dict, "string0", text); v = qobject_input_visitor_new(QOBJECT(ud2_dict)); visit_type_UserDefTwo(v, NULL, &ud2, &err); visit_free(v); qobject_unref(ud2_dict); } /* verify that visit_type_XXX() cleans up properly on error */ error_free_or_abort(&err); assert(!ud2); /* Manually create a partial object, leaving ud2->dict1 at NULL */ ud2 = g_new0(UserDefTwo, 1); ud2->string0 = g_strdup(text); /* tear down partial object */ qapi_free_UserDefTwo(ud2); }
static void test_validate_fail_struct_nested(TestInputVisitorData *data, const void *unused) { UserDefTwo *udp = NULL; Error *err = NULL; Visitor *v; v = validate_test_init(data, "{ 'string0': 'string0', 'dict1': { 'string1': 'string1', 'dict2': { 'userdef1': { 'integer': 42, 'string': 'string', 'extra': [42, 23, {'foo':'bar'}] }, 'string2': 'string2'}}}"); visit_type_UserDefTwo(v, &udp, NULL, &err); g_assert(err); qapi_free_UserDefTwo(udp); }
static void test_validate_struct_nested(TestInputVisitorData *data, const void *unused) { UserDefTwo *udp = NULL; Visitor *v; v = validate_test_init(data, "{ 'string0': 'string0', " "'dict1': { 'string1': 'string1', " "'dict2': { 'userdef': { 'integer': 42, " "'string': 'string' }, 'string': 'string2'}}}"); visit_type_UserDefTwo(v, NULL, &udp, &error_abort); qapi_free_UserDefTwo(udp); }
static void test_visitor_in_struct_nested(TestInputVisitorData *data, const void *unused) { UserDefTwo *udp = NULL; Visitor *v; v = visitor_input_test_init(data, "{ 'string0': 'string0', " "'dict1': { 'string1': 'string1', " "'dict2': { 'userdef': { 'integer': 42, " "'string': 'string' }, 'string': 'string2'}}}"); visit_type_UserDefTwo(v, &udp, NULL, &error_abort); g_assert_cmpstr(udp->string0, ==, "string0"); g_assert_cmpstr(udp->dict1->string1, ==, "string1"); g_assert_cmpint(udp->dict1->dict2->userdef->integer, ==, 42); g_assert_cmpstr(udp->dict1->dict2->userdef->string, ==, "string"); g_assert_cmpstr(udp->dict1->dict2->string, ==, "string2"); g_assert(udp->dict1->has_dict3 == false); qapi_free_UserDefTwo(udp); }
/* test deep nesting with refs to other user-defined types */ static void test_nested_structs(void) { QmpOutputVisitor *mo; QmpInputVisitor *mi; Visitor *v; UserDefOne ud1; UserDefOne *ud1_p = &ud1, *ud1c_p = NULL; UserDefTwo ud2; UserDefTwo *ud2_p = &ud2, *ud2c_p = NULL; Error *err = NULL; QObject *obj; QString *str; ud1.integer = 42; ud1.string = strdup("fourty two"); /* sanity check */ mo = qmp_output_visitor_new(); v = qmp_output_get_visitor(mo); visit_type_UserDefOne(v, &ud1_p, "o_O", &err); if (err) { g_error("%s", error_get_pretty(err)); } obj = qmp_output_get_qobject(mo); g_assert(obj); qobject_decref(obj); ud2.string = strdup("fourty three"); ud2.dict.string = strdup("fourty four"); ud2.dict.dict.userdef = ud1_p; ud2.dict.dict.string = strdup("fourty five"); ud2.dict.has_dict2 = true; ud2.dict.dict2.userdef = ud1_p; ud2.dict.dict2.string = strdup("fourty six"); /* c type -> qobject */ mo = qmp_output_visitor_new(); v = qmp_output_get_visitor(mo); visit_type_UserDefTwo(v, &ud2_p, "unused", &err); if (err) { g_error("%s", error_get_pretty(err)); } obj = qmp_output_get_qobject(mo); g_assert(obj); str = qobject_to_json_pretty(obj); g_print("%s\n", qstring_get_str(str)); QDECREF(str); /* qobject -> c type, should match original struct */ mi = qmp_input_visitor_new(obj); v = qmp_input_get_visitor(mi); visit_type_UserDefTwo(v, &ud2c_p, NULL, &err); if (err) { g_error("%s", error_get_pretty(err)); } g_assert(!g_strcmp0(ud2c_p->string, ud2.string)); g_assert(!g_strcmp0(ud2c_p->dict.string, ud2.dict.string)); ud1c_p = ud2c_p->dict.dict.userdef; g_assert(ud1c_p->integer == ud1_p->integer); g_assert(!g_strcmp0(ud1c_p->string, ud1_p->string)); g_assert(!g_strcmp0(ud2c_p->dict.dict.string, ud2.dict.dict.string)); ud1c_p = ud2c_p->dict.dict2.userdef; g_assert(ud1c_p->integer == ud1_p->integer); g_assert(!g_strcmp0(ud1c_p->string, ud1_p->string)); g_assert(!g_strcmp0(ud2c_p->dict.dict2.string, ud2.dict.dict2.string)); g_free(ud1.string); g_free(ud2.string); g_free(ud2.dict.string); g_free(ud2.dict.dict.string); g_free(ud2.dict.dict2.string); qapi_free_UserDefTwo(ud2c_p); qobject_decref(obj); }
static void nested_struct_cleanup(UserDefTwo *udnp) { qapi_free_UserDefTwo(udnp); }