static void test_visitor_in_errors(TestInputVisitorData *data, const void *unused) { TestStruct *p = NULL; Error *err = NULL; Visitor *v; strList *q = NULL; v = visitor_input_test_init(data, "{ 'integer': false, 'boolean': 'foo', " "'string': -42 }"); visit_type_TestStruct(v, &p, NULL, &err); error_free_or_abort(&err); /* FIXME - a failed parse should not leave a partially-allocated p * for us to clean up; this could cause callers to leak memory. */ g_assert(p->string == NULL); g_free(p->string); g_free(p); v = visitor_input_test_init(data, "[ '1', '2', false, '3' ]"); visit_type_strList(v, &q, NULL, &err); error_free_or_abort(&err); assert(q); qapi_free_strList(q); }
static void test_visitor_in_errors(TestInputVisitorData *data, const void *unused) { TestStruct *p = NULL; Error *err = NULL; Visitor *v; strList *q = NULL; UserDefTwo *r = NULL; WrapAlternate *s = NULL; v = visitor_input_test_init(data, "{ 'integer': false, 'boolean': 'foo', " "'string': -42 }"); visit_type_TestStruct(v, NULL, &p, &err); error_free_or_abort(&err); g_assert(!p); v = visitor_input_test_init(data, "[ '1', '2', false, '3' ]"); visit_type_strList(v, NULL, &q, &err); error_free_or_abort(&err); assert(!q); v = visitor_input_test_init(data, "{ 'str':'hi' }"); visit_type_UserDefTwo(v, NULL, &r, &err); error_free_or_abort(&err); assert(!r); v = visitor_input_test_init(data, "{ }"); visit_type_WrapAlternate(v, NULL, &s, &err); error_free_or_abort(&err); assert(!s); }
static void test_visitor_in_null(TestInputVisitorData *data, const void *unused) { Visitor *v; Error *err = NULL; char *tmp; /* * FIXME: Since QAPI doesn't know the 'null' type yet, we can't * test visit_type_null() by reading into a QAPI struct then * checking that it was populated correctly. The best we can do * for now is ensure that we consumed null from the input, proven * by the fact that we can't re-read the key; and that we detect * when input is not null. */ v = visitor_input_test_init(data, "{ 'a': null, 'b': '' }"); visit_start_struct(v, NULL, NULL, 0, &error_abort); visit_type_null(v, "a", &error_abort); visit_type_str(v, "a", &tmp, &err); g_assert(!tmp); error_free_or_abort(&err); visit_type_null(v, "b", &err); error_free_or_abort(&err); visit_check_struct(v, &error_abort); visit_end_struct(v, NULL); }
static void test_visitor_in_intList(TestInputVisitorData *data, const void *unused) { int64_t value[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 20}; int16List *res = NULL, *tmp; Error *err = NULL; Visitor *v; int i = 0; v = visitor_input_test_init(data, "1,2,0,2-4,20,5-9,1-8"); visit_type_int16List(v, NULL, &res, &error_abort); tmp = res; while (i < sizeof(value) / sizeof(value[0])) { g_assert(tmp); g_assert_cmpint(tmp->value, ==, value[i++]); tmp = tmp->next; } g_assert(!tmp); qapi_free_int16List(res); visitor_input_teardown(data, unused); v = visitor_input_test_init(data, "not an int list"); visit_type_int16List(v, NULL, &res, &err); error_free_or_abort(&err); g_assert(!res); }
/* 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_visitor_in_alternate(TestInputVisitorData *data, const void *unused) { Visitor *v; Error *err = NULL; UserDefAlternate *tmp; WrapAlternate *wrap; v = visitor_input_test_init(data, "42"); visit_type_UserDefAlternate(v, NULL, &tmp, &error_abort); g_assert_cmpint(tmp->type, ==, QTYPE_QINT); g_assert_cmpint(tmp->u.i, ==, 42); qapi_free_UserDefAlternate(tmp); v = visitor_input_test_init(data, "'string'"); visit_type_UserDefAlternate(v, NULL, &tmp, &error_abort); g_assert_cmpint(tmp->type, ==, QTYPE_QSTRING); g_assert_cmpstr(tmp->u.s, ==, "string"); qapi_free_UserDefAlternate(tmp); v = visitor_input_test_init(data, "{'integer':1, 'string':'str', " "'enum1':'value1', 'boolean':true}"); visit_type_UserDefAlternate(v, NULL, &tmp, &error_abort); g_assert_cmpint(tmp->type, ==, QTYPE_QDICT); g_assert_cmpint(tmp->u.udfu.integer, ==, 1); g_assert_cmpstr(tmp->u.udfu.string, ==, "str"); g_assert_cmpint(tmp->u.udfu.enum1, ==, ENUM_ONE_VALUE1); g_assert_cmpint(tmp->u.udfu.u.value1.boolean, ==, true); g_assert_cmpint(tmp->u.udfu.u.value1.has_a_b, ==, false); qapi_free_UserDefAlternate(tmp); v = visitor_input_test_init(data, "false"); visit_type_UserDefAlternate(v, NULL, &tmp, &err); error_free_or_abort(&err); qapi_free_UserDefAlternate(tmp); v = visitor_input_test_init(data, "{ 'alt': 42 }"); visit_type_WrapAlternate(v, NULL, &wrap, &error_abort); g_assert_cmpint(wrap->alt->type, ==, QTYPE_QINT); g_assert_cmpint(wrap->alt->u.i, ==, 42); qapi_free_WrapAlternate(wrap); v = visitor_input_test_init(data, "{ 'alt': 'string' }"); visit_type_WrapAlternate(v, NULL, &wrap, &error_abort); g_assert_cmpint(wrap->alt->type, ==, QTYPE_QSTRING); g_assert_cmpstr(wrap->alt->u.s, ==, "string"); qapi_free_WrapAlternate(wrap); v = visitor_input_test_init(data, "{ 'alt': {'integer':1, 'string':'str', " "'enum1':'value1', 'boolean':true} }"); visit_type_WrapAlternate(v, NULL, &wrap, &error_abort); g_assert_cmpint(wrap->alt->type, ==, QTYPE_QDICT); g_assert_cmpint(wrap->alt->u.udfu.integer, ==, 1); g_assert_cmpstr(wrap->alt->u.udfu.string, ==, "str"); g_assert_cmpint(wrap->alt->u.udfu.enum1, ==, ENUM_ONE_VALUE1); g_assert_cmpint(wrap->alt->u.udfu.u.value1.boolean, ==, true); g_assert_cmpint(wrap->alt->u.udfu.u.value1.has_a_b, ==, false); qapi_free_WrapAlternate(wrap); }
static void dummy_init(Object *obj) { Error *err = NULL; object_property_add_bool(obj, "bv", dummy_get_bv, dummy_set_bv, &err); error_free_or_abort(&err); }
static void test_validate_fail_union_flat(TestInputVisitorData *data, const void *unused) { UserDefFlatUnion *tmp = NULL; Error *err = NULL; Visitor *v; v = validate_test_init(data, "{ 'string': 'c', 'integer': 41, 'boolean': true }"); visit_type_UserDefFlatUnion(v, NULL, &tmp, &err); error_free_or_abort(&err); g_assert(!tmp); }
static void test_validate_fail_list(TestInputVisitorData *data, const void *unused) { UserDefOneList *head = NULL; Error *err = NULL; Visitor *v; v = validate_test_init(data, "[ { 'string': 'string0', 'integer': 42 }, { 'string': 'string1', 'integer': 43 }, { 'string': 'string2', 'integer': 44, 'extra': 'ggg' } ]"); visit_type_UserDefOneList(v, NULL, &head, &err); error_free_or_abort(&err); g_assert(!head); }
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, NULL, &udp, &err); error_free_or_abort(&err); g_assert(!udp); }
static void test_validate_fail_struct(TestInputVisitorData *data, const void *unused) { TestStruct *p = NULL; Error *err = NULL; Visitor *v; v = validate_test_init(data, "{ 'integer': -42, 'boolean': true, 'string': 'foo', 'extra': 42 }"); visit_type_TestStruct(v, NULL, &p, &err); error_free_or_abort(&err); g_assert(!p); }
static void test_visitor_out_enum_errors(TestOutputVisitorData *data, const void *unused) { EnumOne i, bad_values[] = { ENUM_ONE__MAX, -1 }; Error *err; for (i = 0; i < ARRAY_SIZE(bad_values) ; i++) { err = NULL; visit_type_EnumOne(data->ov, "unused", &bad_values[i], &err); error_free_or_abort(&err); visitor_reset(data); } }
static void test_validate_fail_alternate(TestInputVisitorData *data, const void *unused) { UserDefAlternate *tmp; Visitor *v; Error *err = NULL; v = validate_test_init(data, "3.14"); visit_type_UserDefAlternate(v, NULL, &tmp, &err); error_free_or_abort(&err); g_assert(!tmp); }
static void test_validate_fail_union_native_list(TestInputVisitorData *data, const void *unused) { UserDefNativeListUnion *tmp = NULL; Error *err = NULL; Visitor *v; v = validate_test_init(data, "{ 'type': 'integer', 'data' : [ 'string' ] }"); visit_type_UserDefNativeListUnion(v, NULL, &tmp, &err); error_free_or_abort(&err); g_assert(!tmp); }
static void test_validate_fail_union_flat_no_discrim(TestInputVisitorData *data, const void *unused) { UserDefFlatUnion2 *tmp = NULL; Error *err = NULL; Visitor *v; /* test situation where discriminator field ('enum1' here) is missing */ v = validate_test_init(data, "{ 'integer': 42, 'string': 'c', 'string1': 'd', 'string2': 'e' }"); visit_type_UserDefFlatUnion2(v, NULL, &tmp, &err); error_free_or_abort(&err); g_assert(!tmp); }
static void test_visitor_in_int_overflow(TestInputVisitorData *data, const void *unused) { int64_t res = 0; Error *err = NULL; Visitor *v; /* this will overflow a Qint/int64, so should be deserialized into * a QFloat/double field instead, leading to an error if we pass it * to visit_type_int. confirm this. */ v = visitor_input_test_init(data, "%f", DBL_MAX); visit_type_int(v, &res, NULL, &err); error_free_or_abort(&err); }
static void test_visitor_in_int(TestInputVisitorData *data, const void *unused) { int64_t res = 0, value = -42; Error *err = NULL; Visitor *v; v = visitor_input_test_init(data, "-42"); visit_type_int(v, NULL, &res, &err); g_assert(!err); g_assert_cmpint(res, ==, value); visitor_input_teardown(data, unused); v = visitor_input_test_init(data, "not an int"); visit_type_int(v, NULL, &res, &err); error_free_or_abort(&err); }
static void test_visitor_in_alternate(TestInputVisitorData *data, const void *unused) { Visitor *v; Error *err = NULL; UserDefAlternate *tmp; v = visitor_input_test_init(data, "42"); visit_type_UserDefAlternate(v, &tmp, NULL, &error_abort); g_assert_cmpint(tmp->type, ==, USER_DEF_ALTERNATE_KIND_I); g_assert_cmpint(tmp->u.i, ==, 42); qapi_free_UserDefAlternate(tmp); v = visitor_input_test_init(data, "'string'"); visit_type_UserDefAlternate(v, &tmp, NULL, &error_abort); g_assert_cmpint(tmp->type, ==, USER_DEF_ALTERNATE_KIND_S); g_assert_cmpstr(tmp->u.s, ==, "string"); qapi_free_UserDefAlternate(tmp); v = visitor_input_test_init(data, "false"); visit_type_UserDefAlternate(v, &tmp, NULL, &err); error_free_or_abort(&err); qapi_free_UserDefAlternate(tmp); }
static void test_visitor_in_wrong_type(TestInputVisitorData *data, const void *unused) { TestStruct *p = NULL; Visitor *v; strList *q = NULL; int64_t i; Error *err = NULL; /* Make sure arrays and structs cannot be confused */ v = visitor_input_test_init(data, "[]"); visit_type_TestStruct(v, &p, NULL, &err); error_free_or_abort(&err); g_assert(!p); v = visitor_input_test_init(data, "{}"); visit_type_strList(v, &q, NULL, &err); error_free_or_abort(&err); assert(!q); /* Make sure primitives and struct cannot be confused */ v = visitor_input_test_init(data, "1"); visit_type_TestStruct(v, &p, NULL, &err); error_free_or_abort(&err); g_assert(!p); v = visitor_input_test_init(data, "{}"); visit_type_int(v, &i, NULL, &err); error_free_or_abort(&err); /* Make sure primitives and arrays cannot be confused */ v = visitor_input_test_init(data, "1"); visit_type_strList(v, &q, NULL, &err); error_free_or_abort(&err); assert(!q); v = visitor_input_test_init(data, "[]"); visit_type_int(v, &i, NULL, &err); error_free_or_abort(&err); }
static void test_validate_fail_struct_missing(TestInputVisitorData *data, const void *unused) { Error *err = NULL; Visitor *v; QObject *any; GenericAlternate *alt; bool present; int en; int64_t i64; uint32_t u32; int8_t i8; char *str; double dbl; v = validate_test_init(data, "{}"); visit_start_struct(v, NULL, NULL, 0, &error_abort); visit_start_struct(v, "struct", NULL, 0, &err); error_free_or_abort(&err); visit_start_list(v, "list", NULL, 0, &err); error_free_or_abort(&err); visit_start_alternate(v, "alternate", &alt, sizeof(*alt), false, &err); error_free_or_abort(&err); visit_optional(v, "optional", &present); g_assert(!present); visit_type_enum(v, "enum", &en, EnumOne_lookup, &err); error_free_or_abort(&err); visit_type_int(v, "i64", &i64, &err); error_free_or_abort(&err); visit_type_uint32(v, "u32", &u32, &err); error_free_or_abort(&err); visit_type_int8(v, "i8", &i8, &err); error_free_or_abort(&err); visit_type_str(v, "i8", &str, &err); error_free_or_abort(&err); visit_type_number(v, "dbl", &dbl, &err); error_free_or_abort(&err); visit_type_any(v, "any", &any, &err); error_free_or_abort(&err); visit_type_null(v, "null", &err); error_free_or_abort(&err); visit_end_struct(v, NULL); }
static void test_visitor_in_alternate_number(TestInputVisitorData *data, const void *unused) { Visitor *v; Error *err = NULL; AltStrBool *asb; AltStrNum *asn; AltNumStr *ans; AltStrInt *asi; AltIntNum *ain; AltNumInt *ani; /* Parsing an int */ v = visitor_input_test_init(data, "42"); visit_type_AltStrBool(v, &asb, NULL, &err); error_free_or_abort(&err); qapi_free_AltStrBool(asb); /* FIXME: Order of alternate should not affect semantics; asn should * parse the same as ans */ v = visitor_input_test_init(data, "42"); visit_type_AltStrNum(v, &asn, NULL, &err); /* FIXME g_assert_cmpint(asn->type, == ALT_STR_NUM_KIND_N); */ /* FIXME g_assert_cmpfloat(asn->u.n, ==, 42); */ error_free_or_abort(&err); qapi_free_AltStrNum(asn); v = visitor_input_test_init(data, "42"); visit_type_AltNumStr(v, &ans, NULL, &error_abort); g_assert_cmpint(ans->type, ==, ALT_NUM_STR_KIND_N); g_assert_cmpfloat(ans->u.n, ==, 42); qapi_free_AltNumStr(ans); v = visitor_input_test_init(data, "42"); visit_type_AltStrInt(v, &asi, NULL, &error_abort); g_assert_cmpint(asi->type, ==, ALT_STR_INT_KIND_I); g_assert_cmpint(asi->u.i, ==, 42); qapi_free_AltStrInt(asi); v = visitor_input_test_init(data, "42"); visit_type_AltIntNum(v, &ain, NULL, &error_abort); g_assert_cmpint(ain->type, ==, ALT_INT_NUM_KIND_I); g_assert_cmpint(ain->u.i, ==, 42); qapi_free_AltIntNum(ain); v = visitor_input_test_init(data, "42"); visit_type_AltNumInt(v, &ani, NULL, &error_abort); g_assert_cmpint(ani->type, ==, ALT_NUM_INT_KIND_I); g_assert_cmpint(ani->u.i, ==, 42); qapi_free_AltNumInt(ani); /* Parsing a double */ v = visitor_input_test_init(data, "42.5"); visit_type_AltStrBool(v, &asb, NULL, &err); error_free_or_abort(&err); qapi_free_AltStrBool(asb); v = visitor_input_test_init(data, "42.5"); visit_type_AltStrNum(v, &asn, NULL, &error_abort); g_assert_cmpint(asn->type, ==, ALT_STR_NUM_KIND_N); g_assert_cmpfloat(asn->u.n, ==, 42.5); qapi_free_AltStrNum(asn); v = visitor_input_test_init(data, "42.5"); visit_type_AltNumStr(v, &ans, NULL, &error_abort); g_assert_cmpint(ans->type, ==, ALT_NUM_STR_KIND_N); g_assert_cmpfloat(ans->u.n, ==, 42.5); qapi_free_AltNumStr(ans); v = visitor_input_test_init(data, "42.5"); visit_type_AltStrInt(v, &asi, NULL, &err); error_free_or_abort(&err); qapi_free_AltStrInt(asi); v = visitor_input_test_init(data, "42.5"); visit_type_AltIntNum(v, &ain, NULL, &error_abort); g_assert_cmpint(ain->type, ==, ALT_INT_NUM_KIND_N); g_assert_cmpfloat(ain->u.n, ==, 42.5); qapi_free_AltIntNum(ain); v = visitor_input_test_init(data, "42.5"); visit_type_AltNumInt(v, &ani, NULL, &error_abort); g_assert_cmpint(ani->type, ==, ALT_NUM_INT_KIND_N); g_assert_cmpfloat(ani->u.n, ==, 42.5); qapi_free_AltNumInt(ani); }
static void test_visitor_in_alternate_number(TestInputVisitorData *data, const void *unused) { Visitor *v; Error *err = NULL; AltStrBool *asb; AltStrNum *asn; AltNumStr *ans; AltStrInt *asi; AltIntNum *ain; AltNumInt *ani; /* Parsing an int */ v = visitor_input_test_init(data, "42"); visit_type_AltStrBool(v, NULL, &asb, &err); error_free_or_abort(&err); qapi_free_AltStrBool(asb); v = visitor_input_test_init(data, "42"); visit_type_AltStrNum(v, NULL, &asn, &error_abort); g_assert_cmpint(asn->type, ==, QTYPE_QFLOAT); g_assert_cmpfloat(asn->u.n, ==, 42); qapi_free_AltStrNum(asn); v = visitor_input_test_init(data, "42"); visit_type_AltNumStr(v, NULL, &ans, &error_abort); g_assert_cmpint(ans->type, ==, QTYPE_QFLOAT); g_assert_cmpfloat(ans->u.n, ==, 42); qapi_free_AltNumStr(ans); v = visitor_input_test_init(data, "42"); visit_type_AltStrInt(v, NULL, &asi, &error_abort); g_assert_cmpint(asi->type, ==, QTYPE_QINT); g_assert_cmpint(asi->u.i, ==, 42); qapi_free_AltStrInt(asi); v = visitor_input_test_init(data, "42"); visit_type_AltIntNum(v, NULL, &ain, &error_abort); g_assert_cmpint(ain->type, ==, QTYPE_QINT); g_assert_cmpint(ain->u.i, ==, 42); qapi_free_AltIntNum(ain); v = visitor_input_test_init(data, "42"); visit_type_AltNumInt(v, NULL, &ani, &error_abort); g_assert_cmpint(ani->type, ==, QTYPE_QINT); g_assert_cmpint(ani->u.i, ==, 42); qapi_free_AltNumInt(ani); /* Parsing a double */ v = visitor_input_test_init(data, "42.5"); visit_type_AltStrBool(v, NULL, &asb, &err); error_free_or_abort(&err); qapi_free_AltStrBool(asb); v = visitor_input_test_init(data, "42.5"); visit_type_AltStrNum(v, NULL, &asn, &error_abort); g_assert_cmpint(asn->type, ==, QTYPE_QFLOAT); g_assert_cmpfloat(asn->u.n, ==, 42.5); qapi_free_AltStrNum(asn); v = visitor_input_test_init(data, "42.5"); visit_type_AltNumStr(v, NULL, &ans, &error_abort); g_assert_cmpint(ans->type, ==, QTYPE_QFLOAT); g_assert_cmpfloat(ans->u.n, ==, 42.5); qapi_free_AltNumStr(ans); v = visitor_input_test_init(data, "42.5"); visit_type_AltStrInt(v, NULL, &asi, &err); error_free_or_abort(&err); qapi_free_AltStrInt(asi); v = visitor_input_test_init(data, "42.5"); visit_type_AltIntNum(v, NULL, &ain, &error_abort); g_assert_cmpint(ain->type, ==, QTYPE_QFLOAT); g_assert_cmpfloat(ain->u.n, ==, 42.5); qapi_free_AltIntNum(ain); v = visitor_input_test_init(data, "42.5"); visit_type_AltNumInt(v, NULL, &ani, &error_abort); g_assert_cmpint(ani->type, ==, QTYPE_QFLOAT); g_assert_cmpfloat(ani->u.n, ==, 42.5); qapi_free_AltNumInt(ani); }