qapi: Use generated TestStruct machinery in tests
Commitd88f5fd
and friends first introduced the various test-qmp-* tests in 2011, with duplicated hand-rolled TestStruct machinery, to make sure the qapi visitor interface was tested. Later, commit4f193e3
in 2013 added a .json file for further testing use by the files, but without consolidating any of the existing hand-rolled visitors. And with four copies, subtle differences have crept in, between the tests themselves (mainly whitespace differences, but also a question of whether to use NULL or "TestStruct" when calling visit_start_struct()) and from what the generator produces (the hand-rolled versions did not cater to partially-allocated objects, because they did not have a deallocation usage). Of course, just because the visitor interface is tested does not mean it is a sane interface; and future patches will be changing some of the visitor contracts. Rather than having to duplicate the cleanup work in each copy of the TestStruct visitor, and keep each hand-rolled copy in sync with what the generator supplies, we might as well just test what the generator should give us in the first place. Signed-off-by: Eric Blake <eblake@redhat.com> Message-Id: <1446791754-23823-2-git-send-email-eblake@redhat.com> Signed-off-by: Markus Armbruster <armbru@redhat.com>
This commit is contained in:
parent
9d5c1dc117
commit
748053c97b
|
@ -3,6 +3,9 @@
|
||||||
# This file is a stress test of supported qapi constructs that must
|
# This file is a stress test of supported qapi constructs that must
|
||||||
# parse and compile correctly.
|
# parse and compile correctly.
|
||||||
|
|
||||||
|
{ 'struct': 'TestStruct',
|
||||||
|
'data': { 'integer': 'int', 'boolean': 'bool', 'string': 'str' } }
|
||||||
|
|
||||||
# for testing enums
|
# for testing enums
|
||||||
{ 'struct': 'NestedEnumsOne',
|
{ 'struct': 'NestedEnumsOne',
|
||||||
'data': { 'enum1': 'EnumOne', # Intentional forward reference
|
'data': { 'enum1': 'EnumOne', # Intentional forward reference
|
||||||
|
@ -46,7 +49,8 @@
|
||||||
|
|
||||||
# dummy struct to force generation of array types not otherwise mentioned
|
# dummy struct to force generation of array types not otherwise mentioned
|
||||||
{ 'struct': 'ForceArrays',
|
{ 'struct': 'ForceArrays',
|
||||||
'data': { 'unused1':['UserDefOne'], 'unused2':['UserDefTwo'] } }
|
'data': { 'unused1':['UserDefOne'], 'unused2':['UserDefTwo'],
|
||||||
|
'unused3':['TestStruct'] } }
|
||||||
|
|
||||||
# for testing unions
|
# for testing unions
|
||||||
# Among other things, test that a name collision between branches does
|
# Among other things, test that a name collision between branches does
|
||||||
|
|
|
@ -92,6 +92,7 @@ object EventStructOne
|
||||||
object ForceArrays
|
object ForceArrays
|
||||||
member unused1: UserDefOneList optional=False
|
member unused1: UserDefOneList optional=False
|
||||||
member unused2: UserDefTwoList optional=False
|
member unused2: UserDefTwoList optional=False
|
||||||
|
member unused3: TestStructList optional=False
|
||||||
enum MyEnum []
|
enum MyEnum []
|
||||||
object NestedEnumsOne
|
object NestedEnumsOne
|
||||||
member enum1: EnumOne optional=False
|
member enum1: EnumOne optional=False
|
||||||
|
@ -100,6 +101,10 @@ object NestedEnumsOne
|
||||||
member enum4: EnumOne optional=True
|
member enum4: EnumOne optional=True
|
||||||
enum QEnumTwo ['value1', 'value2']
|
enum QEnumTwo ['value1', 'value2']
|
||||||
prefix QENUM_TWO
|
prefix QENUM_TWO
|
||||||
|
object TestStruct
|
||||||
|
member integer: int optional=False
|
||||||
|
member boolean: bool optional=False
|
||||||
|
member string: str optional=False
|
||||||
object UserDefA
|
object UserDefA
|
||||||
member boolean: bool optional=False
|
member boolean: bool optional=False
|
||||||
member a_b: int optional=True
|
member a_b: int optional=True
|
||||||
|
|
|
@ -89,41 +89,6 @@ static Visitor *validate_test_init_raw(TestInputVisitorData *data,
|
||||||
return v;
|
return v;
|
||||||
}
|
}
|
||||||
|
|
||||||
typedef struct TestStruct
|
|
||||||
{
|
|
||||||
int64_t integer;
|
|
||||||
bool boolean;
|
|
||||||
char *string;
|
|
||||||
} TestStruct;
|
|
||||||
|
|
||||||
static void visit_type_TestStruct(Visitor *v, TestStruct **obj,
|
|
||||||
const char *name, Error **errp)
|
|
||||||
{
|
|
||||||
Error *err = NULL;
|
|
||||||
|
|
||||||
visit_start_struct(v, (void **)obj, "TestStruct", name, sizeof(TestStruct),
|
|
||||||
&err);
|
|
||||||
if (err) {
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
|
|
||||||
visit_type_int(v, &(*obj)->integer, "integer", &err);
|
|
||||||
if (err) {
|
|
||||||
goto out_end;
|
|
||||||
}
|
|
||||||
visit_type_bool(v, &(*obj)->boolean, "boolean", &err);
|
|
||||||
if (err) {
|
|
||||||
goto out_end;
|
|
||||||
}
|
|
||||||
visit_type_str(v, &(*obj)->string, "string", &err);
|
|
||||||
|
|
||||||
out_end:
|
|
||||||
error_propagate(errp, err);
|
|
||||||
err = NULL;
|
|
||||||
visit_end_struct(v, &err);
|
|
||||||
out:
|
|
||||||
error_propagate(errp, err);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void test_validate_struct(TestInputVisitorData *data,
|
static void test_validate_struct(TestInputVisitorData *data,
|
||||||
const void *unused)
|
const void *unused)
|
||||||
|
|
|
@ -185,40 +185,6 @@ static void test_visitor_in_enum(TestInputVisitorData *data,
|
||||||
data->qiv = NULL;
|
data->qiv = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
typedef struct TestStruct
|
|
||||||
{
|
|
||||||
int64_t integer;
|
|
||||||
bool boolean;
|
|
||||||
char *string;
|
|
||||||
} TestStruct;
|
|
||||||
|
|
||||||
static void visit_type_TestStruct(Visitor *v, TestStruct **obj,
|
|
||||||
const char *name, Error **errp)
|
|
||||||
{
|
|
||||||
Error *err = NULL;
|
|
||||||
|
|
||||||
visit_start_struct(v, (void **)obj, "TestStruct", name, sizeof(TestStruct),
|
|
||||||
&err);
|
|
||||||
if (err) {
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
visit_type_int(v, &(*obj)->integer, "integer", &err);
|
|
||||||
if (err) {
|
|
||||||
goto out_end;
|
|
||||||
}
|
|
||||||
visit_type_bool(v, &(*obj)->boolean, "boolean", &err);
|
|
||||||
if (err) {
|
|
||||||
goto out_end;
|
|
||||||
}
|
|
||||||
visit_type_str(v, &(*obj)->string, "string", &err);
|
|
||||||
|
|
||||||
out_end:
|
|
||||||
error_propagate(errp, err);
|
|
||||||
err = NULL;
|
|
||||||
visit_end_struct(v, &err);
|
|
||||||
out:
|
|
||||||
error_propagate(errp, err);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void test_visitor_in_struct(TestInputVisitorData *data,
|
static void test_visitor_in_struct(TestInputVisitorData *data,
|
||||||
const void *unused)
|
const void *unused)
|
||||||
|
|
|
@ -166,41 +166,6 @@ static void test_visitor_out_enum_errors(TestOutputVisitorData *data,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
typedef struct TestStruct
|
|
||||||
{
|
|
||||||
int64_t integer;
|
|
||||||
bool boolean;
|
|
||||||
char *string;
|
|
||||||
} TestStruct;
|
|
||||||
|
|
||||||
static void visit_type_TestStruct(Visitor *v, TestStruct **obj,
|
|
||||||
const char *name, Error **errp)
|
|
||||||
{
|
|
||||||
Error *err = NULL;
|
|
||||||
|
|
||||||
visit_start_struct(v, (void **)obj, "TestStruct", name, sizeof(TestStruct),
|
|
||||||
&err);
|
|
||||||
if (err) {
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
|
|
||||||
visit_type_int(v, &(*obj)->integer, "integer", &err);
|
|
||||||
if (err) {
|
|
||||||
goto out_end;
|
|
||||||
}
|
|
||||||
visit_type_bool(v, &(*obj)->boolean, "boolean", &err);
|
|
||||||
if (err) {
|
|
||||||
goto out_end;
|
|
||||||
}
|
|
||||||
visit_type_str(v, &(*obj)->string, "string", &err);
|
|
||||||
|
|
||||||
out_end:
|
|
||||||
error_propagate(errp, err);
|
|
||||||
err = NULL;
|
|
||||||
visit_end_struct(v, &err);
|
|
||||||
out:
|
|
||||||
error_propagate(errp, err);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void test_visitor_out_struct(TestOutputVisitorData *data,
|
static void test_visitor_out_struct(TestOutputVisitorData *data,
|
||||||
const void *unused)
|
const void *unused)
|
||||||
|
@ -314,29 +279,6 @@ static void test_visitor_out_struct_errors(TestOutputVisitorData *data,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
typedef struct TestStructList
|
|
||||||
{
|
|
||||||
union {
|
|
||||||
TestStruct *value;
|
|
||||||
uint64_t padding;
|
|
||||||
};
|
|
||||||
struct TestStructList *next;
|
|
||||||
} TestStructList;
|
|
||||||
|
|
||||||
static void visit_type_TestStructList(Visitor *v, TestStructList **obj,
|
|
||||||
const char *name, Error **errp)
|
|
||||||
{
|
|
||||||
GenericList *i, **head = (GenericList **)obj;
|
|
||||||
|
|
||||||
visit_start_list(v, name, errp);
|
|
||||||
|
|
||||||
for (*head = i = visit_next_list(v, head, errp); i; i = visit_next_list(v, &i, errp)) {
|
|
||||||
TestStructList *native_i = (TestStructList *)i;
|
|
||||||
visit_type_TestStruct(v, &native_i->value, NULL, errp);
|
|
||||||
}
|
|
||||||
|
|
||||||
visit_end_list(v, errp);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void test_visitor_out_list(TestOutputVisitorData *data,
|
static void test_visitor_out_list(TestOutputVisitorData *data,
|
||||||
const void *unused)
|
const void *unused)
|
||||||
|
|
|
@ -186,40 +186,6 @@ static void visit_primitive_list(Visitor *v, void **native, Error **errp)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
typedef struct TestStruct
|
|
||||||
{
|
|
||||||
int64_t integer;
|
|
||||||
bool boolean;
|
|
||||||
char *string;
|
|
||||||
} TestStruct;
|
|
||||||
|
|
||||||
static void visit_type_TestStruct(Visitor *v, TestStruct **obj,
|
|
||||||
const char *name, Error **errp)
|
|
||||||
{
|
|
||||||
Error *err = NULL;
|
|
||||||
|
|
||||||
visit_start_struct(v, (void **)obj, NULL, name, sizeof(TestStruct), &err);
|
|
||||||
if (err) {
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
|
|
||||||
visit_type_int(v, &(*obj)->integer, "integer", &err);
|
|
||||||
if (err) {
|
|
||||||
goto out_end;
|
|
||||||
}
|
|
||||||
visit_type_bool(v, &(*obj)->boolean, "boolean", &err);
|
|
||||||
if (err) {
|
|
||||||
goto out_end;
|
|
||||||
}
|
|
||||||
visit_type_str(v, &(*obj)->string, "string", &err);
|
|
||||||
|
|
||||||
out_end:
|
|
||||||
error_propagate(errp, err);
|
|
||||||
err = NULL;
|
|
||||||
visit_end_struct(v, &err);
|
|
||||||
out:
|
|
||||||
error_propagate(errp, err);
|
|
||||||
}
|
|
||||||
|
|
||||||
static TestStruct *struct_create(void)
|
static TestStruct *struct_create(void)
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in New Issue