소스 검색

qapi: Add tests of complex objects within alternate

Upcoming patches will adjust how we visit an object branch of an
alternate; but we were completely lacking testsuite coverage.
Rectify this, so that the future patches will be able to highlight
the changes and still prove that we avoided regressions.

In particular, the use of a flat union UserDefFlatUnion rather
than a simple struct UserDefA as the branch will give us coverage
of an object with variants.  And visiting an alternate as both
the top level and as a nested member gives confidence in correct
memory allocation handling, especially if the test is run under
valgrind.

Signed-off-by: Eric Blake <eblake@redhat.com>
Message-Id: <1455778109-6278-5-git-send-email-eblake@redhat.com>
Signed-off-by: Markus Armbruster <armbru@redhat.com>
Eric Blake 9 년 전
부모
커밋
68d078395d
4개의 변경된 파일67개의 추가작업 그리고 4개의 파일을 삭제
  1. 3 1
      tests/qapi-schema/qapi-schema-test.json
  2. 3 1
      tests/qapi-schema/qapi-schema-test.out
  3. 36 1
      tests/test-qmp-input-visitor.c
  4. 25 1
      tests/test-qmp-output-visitor.c

+ 3 - 1
tests/qapi-schema/qapi-schema-test.json

@@ -85,8 +85,10 @@
   'data': { 'value1' : 'UserDefC', # intentional forward reference
   'data': { 'value1' : 'UserDefC', # intentional forward reference
             'value2' : 'UserDefB' } }
             'value2' : 'UserDefB' } }
 
 
+{ 'struct': 'WrapAlternate',
+  'data': { 'alt': 'UserDefAlternate' } }
 { 'alternate': 'UserDefAlternate',
 { 'alternate': 'UserDefAlternate',
-  'data': { 'uda': 'UserDefA', 's': 'str', 'i': 'int' } }
+  'data': { 'udfu': 'UserDefFlatUnion', 's': 'str', 'i': 'int' } }
 
 
 { 'struct': 'UserDefC',
 { 'struct': 'UserDefC',
   'data': { 'string1': 'str', 'string2': 'str' } }
   'data': { 'string1': 'str', 'string2': 'str' } }

+ 3 - 1
tests/qapi-schema/qapi-schema-test.out

@@ -105,7 +105,7 @@ object UserDefA
     member boolean: bool optional=False
     member boolean: bool optional=False
     member a_b: int optional=True
     member a_b: int optional=True
 alternate UserDefAlternate
 alternate UserDefAlternate
-    case uda: UserDefA
+    case udfu: UserDefFlatUnion
     case s: str
     case s: str
     case i: int
     case i: int
 object UserDefB
 object UserDefB
@@ -172,6 +172,8 @@ object UserDefUnionBase2
     member enum1: QEnumTwo optional=False
     member enum1: QEnumTwo optional=False
 object UserDefZero
 object UserDefZero
     member integer: int optional=False
     member integer: int optional=False
+object WrapAlternate
+    member alt: UserDefAlternate optional=False
 event __ORG.QEMU_X-EVENT __org.qemu_x-Struct
 event __ORG.QEMU_X-EVENT __org.qemu_x-Struct
 alternate __org.qemu_x-Alt
 alternate __org.qemu_x-Alt
     case __org.qemu_x-branch: str
     case __org.qemu_x-branch: str

+ 36 - 1
tests/test-qmp-input-visitor.c

@@ -1,7 +1,7 @@
 /*
 /*
  * QMP Input Visitor unit-tests.
  * QMP Input Visitor unit-tests.
  *
  *
- * Copyright (C) 2011, 2015 Red Hat Inc.
+ * Copyright (C) 2011-2016 Red Hat Inc.
  *
  *
  * Authors:
  * Authors:
  *  Luiz Capitulino <lcapitulino@redhat.com>
  *  Luiz Capitulino <lcapitulino@redhat.com>
@@ -309,6 +309,7 @@ static void test_visitor_in_alternate(TestInputVisitorData *data,
     Visitor *v;
     Visitor *v;
     Error *err = NULL;
     Error *err = NULL;
     UserDefAlternate *tmp;
     UserDefAlternate *tmp;
+    WrapAlternate *wrap;
 
 
     v = visitor_input_test_init(data, "42");
     v = visitor_input_test_init(data, "42");
     visit_type_UserDefAlternate(v, NULL, &tmp, &error_abort);
     visit_type_UserDefAlternate(v, NULL, &tmp, &error_abort);
@@ -322,10 +323,44 @@ static void test_visitor_in_alternate(TestInputVisitorData *data,
     g_assert_cmpstr(tmp->u.s, ==, "string");
     g_assert_cmpstr(tmp->u.s, ==, "string");
     qapi_free_UserDefAlternate(tmp);
     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");
     v = visitor_input_test_init(data, "false");
     visit_type_UserDefAlternate(v, NULL, &tmp, &err);
     visit_type_UserDefAlternate(v, NULL, &tmp, &err);
     error_free_or_abort(&err);
     error_free_or_abort(&err);
     qapi_free_UserDefAlternate(tmp);
     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 test_visitor_in_alternate_number(TestInputVisitorData *data,
 static void test_visitor_in_alternate_number(TestInputVisitorData *data,

+ 25 - 1
tests/test-qmp-output-visitor.c

@@ -1,7 +1,7 @@
 /*
 /*
  * QMP Output Visitor unit-tests.
  * QMP Output Visitor unit-tests.
  *
  *
- * Copyright (C) 2011, 2015 Red Hat Inc.
+ * Copyright (C) 2011-2016 Red Hat Inc.
  *
  *
  * Authors:
  * Authors:
  *  Luiz Capitulino <lcapitulino@redhat.com>
  *  Luiz Capitulino <lcapitulino@redhat.com>
@@ -427,6 +427,7 @@ static void test_visitor_out_alternate(TestOutputVisitorData *data,
 {
 {
     QObject *arg;
     QObject *arg;
     UserDefAlternate *tmp;
     UserDefAlternate *tmp;
+    QDict *qdict;
 
 
     tmp = g_new0(UserDefAlternate, 1);
     tmp = g_new0(UserDefAlternate, 1);
     tmp->type = QTYPE_QINT;
     tmp->type = QTYPE_QINT;
@@ -453,6 +454,29 @@ static void test_visitor_out_alternate(TestOutputVisitorData *data,
 
 
     qapi_free_UserDefAlternate(tmp);
     qapi_free_UserDefAlternate(tmp);
     qobject_decref(arg);
     qobject_decref(arg);
+
+    tmp = g_new0(UserDefAlternate, 1);
+    tmp->type = QTYPE_QDICT;
+    tmp->u.udfu = g_new0(UserDefFlatUnion, 1);
+    tmp->u.udfu->integer = 1;
+    tmp->u.udfu->string = g_strdup("str");
+    tmp->u.udfu->enum1 = ENUM_ONE_VALUE1;
+    tmp->u.udfu->u.value1 = g_new0(UserDefA, 1);
+    tmp->u.udfu->u.value1->boolean = true;
+
+    visit_type_UserDefAlternate(data->ov, NULL, &tmp, &error_abort);
+    arg = qmp_output_get_qobject(data->qov);
+
+    g_assert_cmpint(qobject_type(arg), ==, QTYPE_QDICT);
+    qdict = qobject_to_qdict(arg);
+    g_assert_cmpint(qdict_size(qdict), ==, 4);
+    g_assert_cmpint(qdict_get_int(qdict, "integer"), ==, 1);
+    g_assert_cmpstr(qdict_get_str(qdict, "string"), ==, "str");
+    g_assert_cmpstr(qdict_get_str(qdict, "enum1"), ==, "value1");
+    g_assert_cmpint(qdict_get_bool(qdict, "boolean"), ==, true);
+
+    qapi_free_UserDefAlternate(tmp);
+    qobject_decref(arg);
 }
 }
 
 
 static void test_visitor_out_empty(TestOutputVisitorData *data,
 static void test_visitor_out_empty(TestOutputVisitorData *data,