[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PULL 33/40] qapi: Drop tests for inline nested structs
From: |
Markus Armbruster |
Subject: |
[Qemu-devel] [PULL 33/40] qapi: Drop tests for inline nested structs |
Date: |
Tue, 5 May 2015 18:47:19 +0200 |
From: Eric Blake <address@hidden>
A future patch will be using a 'name':{dictionary} entry in the
QAPI schema to specify a default value for an optional argument;
but existing use of inline nested structs conflicts with that goal.
More precisely, a definition in the QAPI schema associates a name
with a set of properties:
Example 1: { 'struct': 'Foo', 'data': { MEMBERS... } }
associates the global name 'Foo' with properties (meta-type struct)
and MEMBERS...
Example 2: 'mumble': TYPE
within MEMBERS... above associates 'mumble' with properties (type
TYPE) and (optional false) within type Foo
The syntax of example 1 is extensible; if we need another property,
we add another name/value pair to the dictionary (such as
'base':TYPE). The syntax of example 2 is not extensible, because
the right hand side can only be a type.
We have used name encoding to add a property: "'*mumble': 'int'"
associates 'mumble' with (type int) and (optional true). Nice,
but doesn't scale. So the solution is to change our existing uses
to be syntactic sugar to an extensible form:
NAME: TYPE --> NAME: { 'type': TYPE, 'optional': false }
*ONAME: TYPE --> ONAME: { 'type': TYPE, 'optional': true }
This patch fixes the testsuite to avoid inline nested types, by
breaking the nesting into explicit types; it means that the type
is now boxed instead of unboxed in C code, but makes no difference
on the wire (and if desired, a later patch could change the
generator to not do so much boxing in C). When touching code to
add new allocations, also convert existing allocations to
consistently prefer typesafe g_new0 over g_malloc0 when a type
name is involved.
Signed-off-by: Eric Blake <address@hidden>
Reviewed-by: Markus Armbruster <address@hidden>
Signed-off-by: Markus Armbruster <address@hidden>
---
tests/qapi-schema/qapi-schema-test.json | 12 ++++++--
tests/qapi-schema/qapi-schema-test.out | 8 +++--
tests/test-qmp-commands.c | 17 ++++++-----
tests/test-qmp-input-visitor.c | 14 +++++----
tests/test-qmp-output-visitor.c | 44 +++++++++++++++------------
tests/test-visitor-serialization.c | 54 ++++++++++++++++++---------------
6 files changed, 88 insertions(+), 61 deletions(-)
diff --git a/tests/qapi-schema/qapi-schema-test.json
b/tests/qapi-schema/qapi-schema-test.json
index a6be983..8193dc1 100644
--- a/tests/qapi-schema/qapi-schema-test.json
+++ b/tests/qapi-schema/qapi-schema-test.json
@@ -14,11 +14,17 @@
'base': 'UserDefZero',
'data': { 'string': 'str', '*enum1': 'EnumOne' } }
+{ 'struct': 'UserDefTwoDictDict',
+ 'data': { 'userdef': 'UserDefOne', 'string': 'str' } }
+
+{ 'struct': 'UserDefTwoDict',
+ 'data': { 'string1': 'str',
+ 'dict2': 'UserDefTwoDictDict',
+ '*dict3': 'UserDefTwoDictDict' } }
+
{ 'struct': 'UserDefTwo',
'data': { 'string0': 'str',
- 'dict1': { 'string1': 'str',
- 'dict2': { 'userdef': 'UserDefOne', 'string': 'str' },
- '*dict3': { 'userdef': 'UserDefOne', 'string': 'str' }
} } }
+ 'dict1': 'UserDefTwoDict' } }
# for testing unions
{ 'struct': 'UserDefA',
diff --git a/tests/qapi-schema/qapi-schema-test.out
b/tests/qapi-schema/qapi-schema-test.out
index 48f8f0e..93c4963 100644
--- a/tests/qapi-schema/qapi-schema-test.out
+++ b/tests/qapi-schema/qapi-schema-test.out
@@ -2,7 +2,9 @@
OrderedDict([('struct', 'NestedEnumsOne'), ('data', OrderedDict([('enum1',
'EnumOne'), ('*enum2', 'EnumOne'), ('enum3', 'EnumOne'), ('*enum4',
'EnumOne')]))]),
OrderedDict([('struct', 'UserDefZero'), ('data', OrderedDict([('integer',
'int')]))]),
OrderedDict([('struct', 'UserDefOne'), ('base', 'UserDefZero'), ('data',
OrderedDict([('string', 'str'), ('*enum1', 'EnumOne')]))]),
- OrderedDict([('struct', 'UserDefTwo'), ('data', OrderedDict([('string0',
'str'), ('dict1', OrderedDict([('string1', 'str'), ('dict2',
OrderedDict([('userdef', 'UserDefOne'), ('string', 'str')])), ('*dict3',
OrderedDict([('userdef', 'UserDefOne'), ('string', 'str')]))]))]))]),
+ OrderedDict([('struct', 'UserDefTwoDictDict'), ('data',
OrderedDict([('userdef', 'UserDefOne'), ('string', 'str')]))]),
+ OrderedDict([('struct', 'UserDefTwoDict'), ('data', OrderedDict([('string1',
'str'), ('dict2', 'UserDefTwoDictDict'), ('*dict3', 'UserDefTwoDictDict')]))]),
+ OrderedDict([('struct', 'UserDefTwo'), ('data', OrderedDict([('string0',
'str'), ('dict1', 'UserDefTwoDict')]))]),
OrderedDict([('struct', 'UserDefA'), ('data', OrderedDict([('boolean',
'bool')]))]),
OrderedDict([('struct', 'UserDefB'), ('data', OrderedDict([('integer',
'int')]))]),
OrderedDict([('struct', 'UserDefC'), ('data', OrderedDict([('string1',
'str'), ('string2', 'str')]))]),
@@ -27,7 +29,9 @@
[OrderedDict([('struct', 'NestedEnumsOne'), ('data', OrderedDict([('enum1',
'EnumOne'), ('*enum2', 'EnumOne'), ('enum3', 'EnumOne'), ('*enum4',
'EnumOne')]))]),
OrderedDict([('struct', 'UserDefZero'), ('data', OrderedDict([('integer',
'int')]))]),
OrderedDict([('struct', 'UserDefOne'), ('base', 'UserDefZero'), ('data',
OrderedDict([('string', 'str'), ('*enum1', 'EnumOne')]))]),
- OrderedDict([('struct', 'UserDefTwo'), ('data', OrderedDict([('string0',
'str'), ('dict1', OrderedDict([('string1', 'str'), ('dict2',
OrderedDict([('userdef', 'UserDefOne'), ('string', 'str')])), ('*dict3',
OrderedDict([('userdef', 'UserDefOne'), ('string', 'str')]))]))]))]),
+ OrderedDict([('struct', 'UserDefTwoDictDict'), ('data',
OrderedDict([('userdef', 'UserDefOne'), ('string', 'str')]))]),
+ OrderedDict([('struct', 'UserDefTwoDict'), ('data', OrderedDict([('string1',
'str'), ('dict2', 'UserDefTwoDictDict'), ('*dict3', 'UserDefTwoDictDict')]))]),
+ OrderedDict([('struct', 'UserDefTwo'), ('data', OrderedDict([('string0',
'str'), ('dict1', 'UserDefTwoDict')]))]),
OrderedDict([('struct', 'UserDefA'), ('data', OrderedDict([('boolean',
'bool')]))]),
OrderedDict([('struct', 'UserDefB'), ('data', OrderedDict([('integer',
'int')]))]),
OrderedDict([('struct', 'UserDefC'), ('data', OrderedDict([('string1',
'str'), ('string2', 'str')]))]),
diff --git a/tests/test-qmp-commands.c b/tests/test-qmp-commands.c
index 8b50eac..ad2e403 100644
--- a/tests/test-qmp-commands.c
+++ b/tests/test-qmp-commands.c
@@ -33,12 +33,15 @@ UserDefTwo *qmp_user_def_cmd2(UserDefOne *ud1a,
ret = g_new0(UserDefTwo, 1);
ret->string0 = strdup("blah1");
- ret->dict1.string1 = strdup("blah2");
- ret->dict1.dict2.userdef = ud1c;
- ret->dict1.dict2.string = strdup("blah3");
- ret->dict1.has_dict3 = true;
- ret->dict1.dict3.userdef = ud1d;
- ret->dict1.dict3.string = strdup("blah4");
+ ret->dict1 = g_new0(UserDefTwoDict, 1);
+ ret->dict1->string1 = strdup("blah2");
+ ret->dict1->dict2 = g_new0(UserDefTwoDictDict, 1);
+ ret->dict1->dict2->userdef = ud1c;
+ ret->dict1->dict2->string = strdup("blah3");
+ ret->dict1->dict3 = g_new0(UserDefTwoDictDict, 1);
+ ret->dict1->has_dict3 = true;
+ ret->dict1->dict3->userdef = ud1d;
+ ret->dict1->dict3->string = strdup("blah4");
return ret;
}
@@ -204,7 +207,7 @@ static void test_dealloc_partial(void)
assert(ud2 != NULL);
assert(ud2->string0 != NULL);
assert(strcmp(ud2->string0, text) == 0);
- assert(ud2->dict1.dict2.userdef == NULL);
+ assert(ud2->dict1 == NULL);
/* confirm & release construction error */
assert(err != NULL);
diff --git a/tests/test-qmp-input-visitor.c b/tests/test-qmp-input-visitor.c
index 115fb22..b961953 100644
--- a/tests/test-qmp-input-visitor.c
+++ b/tests/test-qmp-input-visitor.c
@@ -261,13 +261,15 @@ static void
test_visitor_in_struct_nested(TestInputVisitorData *data,
g_assert(!err);
check_and_free_str(udp->string0, "string0");
- check_and_free_str(udp->dict1.string1, "string1");
- g_assert_cmpint(udp->dict1.dict2.userdef->base->integer, ==, 42);
- check_and_free_str(udp->dict1.dict2.userdef->string, "string");
- check_and_free_str(udp->dict1.dict2.string, "string2");
- g_assert(udp->dict1.has_dict3 == false);
+ check_and_free_str(udp->dict1->string1, "string1");
+ g_assert_cmpint(udp->dict1->dict2->userdef->base->integer, ==, 42);
+ check_and_free_str(udp->dict1->dict2->userdef->string, "string");
+ check_and_free_str(udp->dict1->dict2->string, "string2");
+ g_assert(udp->dict1->has_dict3 == false);
- g_free(udp->dict1.dict2.userdef);
+ g_free(udp->dict1->dict2->userdef);
+ g_free(udp->dict1->dict2);
+ g_free(udp->dict1);
g_free(udp);
}
diff --git a/tests/test-qmp-output-visitor.c b/tests/test-qmp-output-visitor.c
index 0584b4d..f8c9367 100644
--- a/tests/test-qmp-output-visitor.c
+++ b/tests/test-qmp-output-visitor.c
@@ -244,19 +244,23 @@ static void
test_visitor_out_struct_nested(TestOutputVisitorData *data,
ud2 = g_malloc0(sizeof(*ud2));
ud2->string0 = g_strdup(strings[0]);
- ud2->dict1.string1 = g_strdup(strings[1]);
- ud2->dict1.dict2.userdef = g_new0(UserDefOne, 1);
- ud2->dict1.dict2.userdef->string = g_strdup(string);
- ud2->dict1.dict2.userdef->base = g_new0(UserDefZero, 1);
- ud2->dict1.dict2.userdef->base->integer = value;
- ud2->dict1.dict2.string = g_strdup(strings[2]);
+ ud2->dict1 = g_malloc0(sizeof(*ud2->dict1));
+ ud2->dict1->string1 = g_strdup(strings[1]);
- ud2->dict1.has_dict3 = true;
- ud2->dict1.dict3.userdef = g_new0(UserDefOne, 1);
- ud2->dict1.dict3.userdef->string = g_strdup(string);
- ud2->dict1.dict3.userdef->base = g_new0(UserDefZero, 1);
- ud2->dict1.dict3.userdef->base->integer = value;
- ud2->dict1.dict3.string = g_strdup(strings[3]);
+ ud2->dict1->dict2 = g_malloc0(sizeof(*ud2->dict1->dict2));
+ ud2->dict1->dict2->userdef = g_new0(UserDefOne, 1);
+ ud2->dict1->dict2->userdef->string = g_strdup(string);
+ ud2->dict1->dict2->userdef->base = g_new0(UserDefZero, 1);
+ ud2->dict1->dict2->userdef->base->integer = value;
+ ud2->dict1->dict2->string = g_strdup(strings[2]);
+
+ ud2->dict1->dict3 = g_malloc0(sizeof(*ud2->dict1->dict3));
+ ud2->dict1->has_dict3 = true;
+ ud2->dict1->dict3->userdef = g_new0(UserDefOne, 1);
+ ud2->dict1->dict3->userdef->string = g_strdup(string);
+ ud2->dict1->dict3->userdef->base = g_new0(UserDefZero, 1);
+ ud2->dict1->dict3->userdef->base->integer = value;
+ ud2->dict1->dict3->string = g_strdup(strings[3]);
visit_type_UserDefTwo(data->ov, &ud2, "unused", &err);
g_assert(!err);
@@ -407,13 +411,15 @@ static void
test_visitor_out_list_qapi_free(TestOutputVisitorData *data,
p->value = g_malloc0(sizeof(*p->value));
p->value->string0 = g_strdup(string);
- p->value->dict1.string1 = g_strdup(string);
- p->value->dict1.dict2.userdef = g_new0(UserDefOne, 1);
- p->value->dict1.dict2.userdef->string = g_strdup(string);
- p->value->dict1.dict2.userdef->base = g_new0(UserDefZero, 1);
- p->value->dict1.dict2.userdef->base->integer = 42;
- p->value->dict1.dict2.string = g_strdup(string);
- p->value->dict1.has_dict3 = false;
+ p->value->dict1 = g_new0(UserDefTwoDict, 1);
+ p->value->dict1->string1 = g_strdup(string);
+ p->value->dict1->dict2 = g_new0(UserDefTwoDictDict, 1);
+ p->value->dict1->dict2->userdef = g_new0(UserDefOne, 1);
+ p->value->dict1->dict2->userdef->string = g_strdup(string);
+ p->value->dict1->dict2->userdef->base = g_new0(UserDefZero, 1);
+ p->value->dict1->dict2->userdef->base->integer = 42;
+ p->value->dict1->dict2->string = g_strdup(string);
+ p->value->dict1->has_dict3 = false;
p->next = head;
head = p;
diff --git a/tests/test-visitor-serialization.c
b/tests/test-visitor-serialization.c
index 1ccaaa9..fa86cae 100644
--- a/tests/test-visitor-serialization.c
+++ b/tests/test-visitor-serialization.c
@@ -1,6 +1,7 @@
/*
* Unit-tests for visitor-based serialization
*
+ * Copyright (C) 2014-2015 Red Hat, Inc.
* Copyright IBM, Corp. 2012
*
* Authors:
@@ -253,18 +254,21 @@ static UserDefTwo *nested_struct_create(void)
{
UserDefTwo *udnp = g_malloc0(sizeof(*udnp));
udnp->string0 = strdup("test_string0");
- udnp->dict1.string1 = strdup("test_string1");
- udnp->dict1.dict2.userdef = g_new0(UserDefOne, 1);
- udnp->dict1.dict2.userdef->base = g_new0(UserDefZero, 1);
- udnp->dict1.dict2.userdef->base->integer = 42;
- udnp->dict1.dict2.userdef->string = strdup("test_string");
- udnp->dict1.dict2.string = strdup("test_string2");
- udnp->dict1.has_dict3 = true;
- udnp->dict1.dict3.userdef = g_new0(UserDefOne, 1);
- udnp->dict1.dict3.userdef->base = g_new0(UserDefZero, 1);
- udnp->dict1.dict3.userdef->base->integer = 43;
- udnp->dict1.dict3.userdef->string = strdup("test_string");
- udnp->dict1.dict3.string = strdup("test_string3");
+ udnp->dict1 = g_malloc0(sizeof(*udnp->dict1));
+ udnp->dict1->string1 = strdup("test_string1");
+ udnp->dict1->dict2 = g_malloc0(sizeof(*udnp->dict1->dict2));
+ udnp->dict1->dict2->userdef = g_new0(UserDefOne, 1);
+ udnp->dict1->dict2->userdef->base = g_new0(UserDefZero, 1);
+ udnp->dict1->dict2->userdef->base->integer = 42;
+ udnp->dict1->dict2->userdef->string = strdup("test_string");
+ udnp->dict1->dict2->string = strdup("test_string2");
+ udnp->dict1->dict3 = g_malloc0(sizeof(*udnp->dict1->dict3));
+ udnp->dict1->has_dict3 = true;
+ udnp->dict1->dict3->userdef = g_new0(UserDefOne, 1);
+ udnp->dict1->dict3->userdef->base = g_new0(UserDefZero, 1);
+ udnp->dict1->dict3->userdef->base->integer = 43;
+ udnp->dict1->dict3->userdef->string = strdup("test_string");
+ udnp->dict1->dict3->string = strdup("test_string3");
return udnp;
}
@@ -273,18 +277,20 @@ static void nested_struct_compare(UserDefTwo *udnp1,
UserDefTwo *udnp2)
g_assert(udnp1);
g_assert(udnp2);
g_assert_cmpstr(udnp1->string0, ==, udnp2->string0);
- g_assert_cmpstr(udnp1->dict1.string1, ==, udnp2->dict1.string1);
- g_assert_cmpint(udnp1->dict1.dict2.userdef->base->integer, ==,
- udnp2->dict1.dict2.userdef->base->integer);
- g_assert_cmpstr(udnp1->dict1.dict2.userdef->string, ==,
- udnp2->dict1.dict2.userdef->string);
- g_assert_cmpstr(udnp1->dict1.dict2.string, ==, udnp2->dict1.dict2.string);
- g_assert(udnp1->dict1.has_dict3 == udnp2->dict1.has_dict3);
- g_assert_cmpint(udnp1->dict1.dict3.userdef->base->integer, ==,
- udnp2->dict1.dict3.userdef->base->integer);
- g_assert_cmpstr(udnp1->dict1.dict3.userdef->string, ==,
- udnp2->dict1.dict3.userdef->string);
- g_assert_cmpstr(udnp1->dict1.dict3.string, ==, udnp2->dict1.dict3.string);
+ g_assert_cmpstr(udnp1->dict1->string1, ==, udnp2->dict1->string1);
+ g_assert_cmpint(udnp1->dict1->dict2->userdef->base->integer, ==,
+ udnp2->dict1->dict2->userdef->base->integer);
+ g_assert_cmpstr(udnp1->dict1->dict2->userdef->string, ==,
+ udnp2->dict1->dict2->userdef->string);
+ g_assert_cmpstr(udnp1->dict1->dict2->string, ==,
+ udnp2->dict1->dict2->string);
+ g_assert(udnp1->dict1->has_dict3 == udnp2->dict1->has_dict3);
+ g_assert_cmpint(udnp1->dict1->dict3->userdef->base->integer, ==,
+ udnp2->dict1->dict3->userdef->base->integer);
+ g_assert_cmpstr(udnp1->dict1->dict3->userdef->string, ==,
+ udnp2->dict1->dict3->userdef->string);
+ g_assert_cmpstr(udnp1->dict1->dict3->string, ==,
+ udnp2->dict1->dict3->string);
}
static void nested_struct_cleanup(UserDefTwo *udnp)
--
1.9.3
- [Qemu-devel] [PULL 16/40] qapi: Use 'alternate' to replace anonymous union, (continued)
- [Qemu-devel] [PULL 16/40] qapi: Use 'alternate' to replace anonymous union, Markus Armbruster, 2015/05/05
- [Qemu-devel] [PULL 22/40] qapi: Unify type bypass and add tests, Markus Armbruster, 2015/05/05
- [Qemu-devel] [PULL 17/40] qapi: Add some expr tests, Markus Armbruster, 2015/05/05
- [Qemu-devel] [PULL 26/40] qapi: Whitelist commands that don't return dictionary, Markus Armbruster, 2015/05/05
- [Qemu-devel] [PULL 25/40] qapi: Require valid names, Markus Armbruster, 2015/05/05
- [Qemu-devel] [PULL 08/40] qapi: Add some union tests, Markus Armbruster, 2015/05/05
- [Qemu-devel] [PULL 20/40] qapi: Better error messages for duplicated expressions, Markus Armbruster, 2015/05/05
- [Qemu-devel] [PULL 24/40] qapi: More rigourous checking of types, Markus Armbruster, 2015/05/05
- [Qemu-devel] [PULL 29/40] qapi: Document 'struct' metatype, Markus Armbruster, 2015/05/05
- [Qemu-devel] [PULL 40/40] qapi: Check for member name conflicts with a base class, Markus Armbruster, 2015/05/05
- [Qemu-devel] [PULL 33/40] qapi: Drop tests for inline nested structs,
Markus Armbruster <=
- [Qemu-devel] [PULL 35/40] qapi: Drop inline nested structs in query-pci, Markus Armbruster, 2015/05/05
- [Qemu-devel] [PULL 23/40] qapi: Add some type check tests, Markus Armbruster, 2015/05/05
- [Qemu-devel] [PULL 39/40] qapi: Support (subset of) \u escapes in strings, Markus Armbruster, 2015/05/05
- [Qemu-devel] [PULL 38/40] qapi: Tweak doc references to QMP when QGA is also meant, Markus Armbruster, 2015/05/05
- [Qemu-devel] [PULL 36/40] qapi: Drop support for inline nested types, Markus Armbruster, 2015/05/05
- [Qemu-devel] [PULL 28/40] qapi: Prefer 'struct' over 'type' in generator, Markus Armbruster, 2015/05/05
- [Qemu-devel] [PULL 34/40] qapi: Drop inline nested struct in query-version, Markus Armbruster, 2015/05/05
- [Qemu-devel] [PULL 32/40] qapi: Merge UserDefTwo and UserDefNested in tests, Markus Armbruster, 2015/05/05
- [Qemu-devel] [PULL 37/40] qapi: Drop dead visitor code related to nested structs, Markus Armbruster, 2015/05/05
- [Qemu-devel] [PULL 30/40] qapi: Use 'struct' instead of 'type' in schema, Markus Armbruster, 2015/05/05