Commit 9c51b441 authored by Eric Blake's avatar Eric Blake Committed by Markus Armbruster
Browse files

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: default avatarEric 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: default avatarMarkus Armbruster <armbru@redhat.com>
parent 8d25dd10
Loading
Loading
Loading
Loading
+8 −0
Original line number Diff line number Diff line
@@ -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'],
+24 −0
Original line number Diff line number Diff line
@@ -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
+128 −3
Original line number Diff line number Diff line
@@ -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);