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. Signed-off-by: Eric Blake <ebl...@redhat.com> --- tests/qapi-schema/qapi-schema-test.json | 8 ++ tests/qapi-schema/qapi-schema-test.out | 24 ++++++ tests/test-qmp-input-visitor.c | 129 +++++++++++++++++++++++++++++++- 3 files changed, 158 insertions(+), 3 deletions(-) diff --git a/tests/qapi-schema/qapi-schema-test.json b/tests/qapi-schema/qapi-schema-test.json index 6665281..cfbe4dd 100644 --- a/tests/qapi-schema/qapi-schema-test.json +++ b/tests/qapi-schema/qapi-schema-test.json @@ -59,6 +59,14 @@ { 'struct': 'UserDefC', 'data': { 'string1': 'str', 'string2': 'str' } } +# for testing use of 'number' within alternates +{ 'alternate': 'AltOne', 'data': { 's': 'str', 'b': 'bool' } } +{ 'alternate': 'AltTwo', 'data': { 's': 'str', 'n': 'number' } } +{ 'alternate': 'AltThree', 'data': { 'n': 'number', 's': 'str' } } +{ 'alternate': 'AltFour', 'data': { 's': 'str', 'i': 'int' } } +{ 'alternate': 'AltFive', 'data': { 'i': 'int', 'n': 'number' } } +{ 'alternate': 'AltSix', 'data': { 'n': 'number', 'i': 'int' } } + # for testing native lists { 'union': 'UserDefNativeListUnion', 'data': { 'integer': ['int'], diff --git a/tests/qapi-schema/qapi-schema-test.out b/tests/qapi-schema/qapi-schema-test.out index 386b057..ba70ea7 100644 --- a/tests/qapi-schema/qapi-schema-test.out +++ b/tests/qapi-schema/qapi-schema-test.out @@ -51,6 +51,30 @@ object :obj-user_def_cmd2-arg object :obj-user_def_cmd3-arg member a: int optional=False member b: int optional=True +alternate AltFive + case i: int + case n: number +enum AltFiveKind ['i', 'n'] +alternate AltFour + case s: str + case i: int +enum AltFourKind ['s', 'i'] +alternate AltOne + case s: str + case b: bool +enum AltOneKind ['s', 'b'] +alternate AltSix + case n: number + case i: int +enum AltSixKind ['n', 'i'] +alternate AltThree + case n: number + case s: str +enum AltThreeKind ['n', 's'] +alternate AltTwo + case s: str + case n: number +enum AltTwoKind ['s', 'n'] event EVENT_A None event EVENT_B None event EVENT_C :obj-EVENT_C-arg diff --git a/tests/test-qmp-input-visitor.c b/tests/test-qmp-input-visitor.c index b6deee3..3ee1a1a 100644 --- a/tests/test-qmp-input-visitor.c +++ b/tests/test-qmp-input-visitor.c @@ -368,15 +368,136 @@ static void test_visitor_in_alternate(TestInputVisitorData *data, { Visitor *v; Error *err = NULL; - UserDefAlternate *tmp; + UserDefAlternate *tmp = NULL; 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->type, ==, USER_DEF_ALTERNATE_KIND_I); g_assert_cmpint(tmp->i, ==, 42); qapi_free_UserDefAlternate(tmp); + tmp = NULL; + + 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->s, ==, "string"); + qapi_free_UserDefAlternate(tmp); + tmp = 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); +} + +static void test_visitor_in_alternate_number(TestInputVisitorData *data, + const void *unused) +{ + Visitor *v; + Error *err = NULL; + AltOne *one = NULL; + AltTwo *two = NULL; + AltThree *three = NULL; + AltFour *four = NULL; + AltFive *five = NULL; + AltSix *six = NULL; + + /* Parsing an int */ + + v = visitor_input_test_init(data, "42"); + visit_type_AltOne(v, &one, NULL, &err); + g_assert(err); + qapi_free_AltOne(one); + one = NULL; + + /* FIXME: Integers should parse as numbers */ + v = visitor_input_test_init(data, "42"); + visit_type_AltTwo(v, &two, NULL, &err); + g_assert(err); + error_free(err); + err = NULL; + qapi_free_AltTwo(two); + one = NULL; + + /* FIXME: Order of alternate should not affect semantics */ + v = visitor_input_test_init(data, "42"); + visit_type_AltThree(v, &three, NULL, &error_abort); + g_assert_cmpint(three->type, ==, ALT_THREE_KIND_N); + g_assert_cmpfloat(three->n, ==, 42); + qapi_free_AltThree(three); + one = NULL; + + v = visitor_input_test_init(data, "42"); + visit_type_AltFour(v, &four, NULL, &error_abort); + g_assert_cmpint(four->type, ==, ALT_FOUR_KIND_I); + g_assert_cmpint(four->i, ==, 42); + qapi_free_AltFour(four); + one = NULL; + + v = visitor_input_test_init(data, "42"); + visit_type_AltFive(v, &five, NULL, &error_abort); + g_assert_cmpint(five->type, ==, ALT_FIVE_KIND_I); + g_assert_cmpint(five->i, ==, 42); + qapi_free_AltFive(five); + one = NULL; + + v = visitor_input_test_init(data, "42"); + visit_type_AltSix(v, &six, NULL, &error_abort); + g_assert_cmpint(six->type, ==, ALT_SIX_KIND_I); + g_assert_cmpint(six->i, ==, 42); + qapi_free_AltSix(six); + one = NULL; + + /* Parsing a double */ + + v = visitor_input_test_init(data, "42.5"); + visit_type_AltOne(v, &one, NULL, &err); + g_assert(err); + error_free(err); + err = NULL; + qapi_free_AltOne(one); + one = NULL; + + v = visitor_input_test_init(data, "42.5"); + visit_type_AltTwo(v, &two, NULL, &error_abort); + g_assert_cmpint(two->type, ==, ALT_TWO_KIND_N); + g_assert_cmpfloat(two->n, ==, 42.5); + qapi_free_AltTwo(two); + two = NULL; + + v = visitor_input_test_init(data, "42.5"); + visit_type_AltThree(v, &three, NULL, &error_abort); + g_assert_cmpint(three->type, ==, ALT_THREE_KIND_N); + g_assert_cmpfloat(three->n, ==, 42.5); + qapi_free_AltThree(three); + three = NULL; + + v = visitor_input_test_init(data, "42.5"); + visit_type_AltFour(v, &four, NULL, &err); + g_assert(err); + error_free(err); + err = NULL; + qapi_free_AltFour(four); + four = NULL; + + v = visitor_input_test_init(data, "42.5"); + visit_type_AltFive(v, &five, NULL, &error_abort); + g_assert_cmpint(five->type, ==, ALT_FIVE_KIND_N); + g_assert_cmpfloat(five->n, ==, 42.5); + qapi_free_AltFive(five); + five = NULL; + + v = visitor_input_test_init(data, "42.5"); + visit_type_AltSix(v, &six, NULL, &error_abort); + g_assert_cmpint(six->type, ==, ALT_SIX_KIND_N); + g_assert_cmpint(six->n, ==, 42.5); + qapi_free_AltSix(six); + six = NULL; } static void test_native_list_integer_helper(TestInputVisitorData *data, @@ -720,6 +841,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); -- 2.4.3