qapi: Test use of 'number' within alternates

Add some testsuite exposure for use of a 'number' as part of
an alternate.  The current state of the tree has a few bugs
exposed by this: our input parser depends on the ordering of
how the qapi schema declared the alternate, and the parser
does not accept integers for a 'number' in an alternate even
though it does for numbers outside of an alternate.

Mixing 'int' and 'number' in the same alternate is unusual,
since both are supplied by json-numbers, but there does not
seem to be a technical reason to forbid it given that our
json lexer distinguishes between json-numbers that can be
represented as an int vs. those that cannot.

Improve the existing test_visitor_in_alternate() to match the
style of the new test_visitor_in_alternate_number(), and to
ensure full coverage of all possible qtype parsing.

Signed-off-by: Eric Blake <eblake@redhat.com>
Message-Id: <1443565276-4535-9-git-send-email-eblake@redhat.com>
[Eric's follow-up fixes squashed in]
Signed-off-by: Markus Armbruster <armbru@redhat.com>
This commit is contained in:
Eric Blake 2015-09-29 16:21:06 -06:00 committed by Markus Armbruster
parent 8d25dd101f
commit 9c51b44129
3 changed files with 160 additions and 3 deletions

View file

@ -67,6 +67,14 @@
{ 'struct': 'UserDefC',
'data': { 'string1': 'str', 'string2': 'str' } }
# for testing use of 'number' within alternates
{ 'alternate': 'AltStrBool', 'data': { 's': 'str', 'b': 'bool' } }
{ 'alternate': 'AltStrNum', 'data': { 's': 'str', 'n': 'number' } }
{ 'alternate': 'AltNumStr', 'data': { 'n': 'number', 's': 'str' } }
{ 'alternate': 'AltStrInt', 'data': { 's': 'str', 'i': 'int' } }
{ 'alternate': 'AltIntNum', 'data': { 'i': 'int', 'n': 'number' } }
{ 'alternate': 'AltNumInt', 'data': { 'n': 'number', 'i': 'int' } }
# for testing native lists
{ 'union': 'UserDefNativeListUnion',
'data': { 'integer': ['int'],

View file

@ -53,6 +53,30 @@ object :obj-user_def_cmd2-arg
object :obj-user_def_cmd3-arg
member a: int optional=False
member b: int optional=True
alternate AltIntNum
case i: int
case n: number
enum AltIntNumKind ['i', 'n']
alternate AltNumInt
case n: number
case i: int
enum AltNumIntKind ['n', 'i']
alternate AltNumStr
case n: number
case s: str
enum AltNumStrKind ['n', 's']
alternate AltStrBool
case s: str
case b: bool
enum AltStrBoolKind ['s', 'b']
alternate AltStrInt
case s: str
case i: int
enum AltStrIntKind ['s', 'i']
alternate AltStrNum
case s: str
case n: number
enum AltStrNumKind ['s', 'n']
event EVENT_A None
event EVENT_B None
event EVENT_C :obj-EVENT_C-arg

View file

@ -371,12 +371,135 @@ static void test_visitor_in_alternate(TestInputVisitorData *data,
UserDefAlternate *tmp;
v = visitor_input_test_init(data, "42");
visit_type_UserDefAlternate(v, &tmp, NULL, &err);
g_assert(err == NULL);
visit_type_UserDefAlternate(v, &tmp, NULL, &error_abort);
g_assert_cmpint(tmp->kind, ==, USER_DEF_ALTERNATE_KIND_I);
g_assert_cmpint(tmp->i, ==, 42);
qapi_free_UserDefAlternate(tmp);
visitor_input_teardown(data, NULL);
v = visitor_input_test_init(data, "'string'");
visit_type_UserDefAlternate(v, &tmp, NULL, &error_abort);
g_assert_cmpint(tmp->kind, ==, USER_DEF_ALTERNATE_KIND_S);
g_assert_cmpstr(tmp->s, ==, "string");
qapi_free_UserDefAlternate(tmp);
visitor_input_teardown(data, NULL);
v = visitor_input_test_init(data, "false");
visit_type_UserDefAlternate(v, &tmp, NULL, &err);
g_assert(err);
error_free(err);
err = NULL;
qapi_free_UserDefAlternate(tmp);
visitor_input_teardown(data, 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);
g_assert(err);
error_free(err);
err = NULL;
qapi_free_AltStrBool(asb);
visitor_input_teardown(data, NULL);
/* 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->kind, == ALT_STR_NUM_KIND_N); */
/* FIXME g_assert_cmpfloat(asn->n, ==, 42); */
g_assert(err);
error_free(err);
err = NULL;
qapi_free_AltStrNum(asn);
visitor_input_teardown(data, NULL);
v = visitor_input_test_init(data, "42");
visit_type_AltNumStr(v, &ans, NULL, &error_abort);
g_assert_cmpint(ans->kind, ==, ALT_NUM_STR_KIND_N);
g_assert_cmpfloat(ans->n, ==, 42);
qapi_free_AltNumStr(ans);
visitor_input_teardown(data, NULL);
v = visitor_input_test_init(data, "42");
visit_type_AltStrInt(v, &asi, NULL, &error_abort);
g_assert_cmpint(asi->kind, ==, ALT_STR_INT_KIND_I);
g_assert_cmpint(asi->i, ==, 42);
qapi_free_AltStrInt(asi);
visitor_input_teardown(data, NULL);
v = visitor_input_test_init(data, "42");
visit_type_AltIntNum(v, &ain, NULL, &error_abort);
g_assert_cmpint(ain->kind, ==, ALT_INT_NUM_KIND_I);
g_assert_cmpint(ain->i, ==, 42);
qapi_free_AltIntNum(ain);
visitor_input_teardown(data, NULL);
v = visitor_input_test_init(data, "42");
visit_type_AltNumInt(v, &ani, NULL, &error_abort);
g_assert_cmpint(ani->kind, ==, ALT_NUM_INT_KIND_I);
g_assert_cmpint(ani->i, ==, 42);
qapi_free_AltNumInt(ani);
visitor_input_teardown(data, NULL);
/* Parsing a double */
v = visitor_input_test_init(data, "42.5");
visit_type_AltStrBool(v, &asb, NULL, &err);
g_assert(err);
error_free(err);
err = NULL;
qapi_free_AltStrBool(asb);
visitor_input_teardown(data, NULL);
v = visitor_input_test_init(data, "42.5");
visit_type_AltStrNum(v, &asn, NULL, &error_abort);
g_assert_cmpint(asn->kind, ==, ALT_STR_NUM_KIND_N);
g_assert_cmpfloat(asn->n, ==, 42.5);
qapi_free_AltStrNum(asn);
visitor_input_teardown(data, NULL);
v = visitor_input_test_init(data, "42.5");
visit_type_AltNumStr(v, &ans, NULL, &error_abort);
g_assert_cmpint(ans->kind, ==, ALT_NUM_STR_KIND_N);
g_assert_cmpfloat(ans->n, ==, 42.5);
qapi_free_AltNumStr(ans);
visitor_input_teardown(data, NULL);
v = visitor_input_test_init(data, "42.5");
visit_type_AltStrInt(v, &asi, NULL, &err);
g_assert(err);
error_free(err);
err = NULL;
qapi_free_AltStrInt(asi);
visitor_input_teardown(data, NULL);
v = visitor_input_test_init(data, "42.5");
visit_type_AltIntNum(v, &ain, NULL, &error_abort);
g_assert_cmpint(ain->kind, ==, ALT_INT_NUM_KIND_N);
g_assert_cmpfloat(ain->n, ==, 42.5);
qapi_free_AltIntNum(ain);
visitor_input_teardown(data, NULL);
v = visitor_input_test_init(data, "42.5");
visit_type_AltNumInt(v, &ani, NULL, &error_abort);
g_assert_cmpint(ani->kind, ==, ALT_NUM_INT_KIND_N);
g_assert_cmpfloat(ani->n, ==, 42.5);
qapi_free_AltNumInt(ani);
visitor_input_teardown(data, NULL);
}
static void test_native_list_integer_helper(TestInputVisitorData *data,
@ -720,6 +843,8 @@ int main(int argc, char **argv)
&in_visitor_data, test_visitor_in_alternate);
input_visitor_test_add("/visitor/input/errors",
&in_visitor_data, test_visitor_in_errors);
input_visitor_test_add("/visitor/input/alternate-number",
&in_visitor_data, test_visitor_in_alternate_number);
input_visitor_test_add("/visitor/input/native_list/int",
&in_visitor_data,
test_visitor_in_native_list_int);