qapi: More rigourous checking of types

Now that we know every expression is valid with regards to
its keys, we can add further tests that those keys refer to
valid types.  With this patch, all uses of a type (the 'data':
of command, type, union, alternate, and event; the 'returns':
of command; the 'base': of type and union) must resolve to an
appropriate subset of metatypes  declared by the current qapi
parse; this includes recursing into each member of a data
dictionary.  Dealing with '**' and nested anonymous structs
will be done in later patches.

Update the testsuite to match improved output.

Signed-off-by: Eric Blake <eblake@redhat.com>
Reviewed-by: Markus Armbruster <armbru@redhat.com>
Signed-off-by: Markus Armbruster <armbru@redhat.com>
This commit is contained in:
Eric Blake 2015-05-04 09:05:21 -06:00 committed by Markus Armbruster
parent 0d8b9fb5f2
commit dd883c6f05
52 changed files with 126 additions and 77 deletions

View file

@ -1 +1 @@
tests/qapi-schema/alternate-array.json:5: Alternate 'Alt' member 'two' must not be array type
tests/qapi-schema/alternate-array.json:5: Member 'two' of alternate 'Alt' cannot be an array

View file

@ -1 +1 @@
tests/qapi-schema/alternate-nested.json:4: Alternate 'Alt2' member 'nested' has invalid type 'Alt1'
tests/qapi-schema/alternate-nested.json:4: Member 'nested' of alternate 'Alt2' cannot use alternate type 'Alt1'

View file

@ -1 +1 @@
tests/qapi-schema/alternate-unknown.json:2: Alternate 'Alt' member 'unknown' has invalid type 'MissingType'
tests/qapi-schema/alternate-unknown.json:2: Member 'unknown' of alternate 'Alt' uses unknown type 'MissingType'

View file

@ -0,0 +1 @@
tests/qapi-schema/bad-base.json:3: 'base' for type 'MyType' cannot use union type 'Union'

View file

@ -1 +1 @@
0
1

View file

@ -1,3 +1,3 @@
# FIXME: we should reject a base that is not a struct
# we reject a base that is not a struct
{ 'union': 'Union', 'data': { 'a': 'int', 'b': 'str' } }
{ 'type': 'MyType', 'base': 'Union', 'data': { 'c': 'int' } }

View file

@ -1,4 +0,0 @@
[OrderedDict([('union', 'Union'), ('data', OrderedDict([('a', 'int'), ('b', 'str')]))]),
OrderedDict([('type', 'MyType'), ('base', 'Union'), ('data', OrderedDict([('c', 'int')]))])]
[{'enum_name': 'UnionKind', 'enum_values': None}]
[OrderedDict([('type', 'MyType'), ('base', 'Union'), ('data', OrderedDict([('c', 'int')]))])]

View file

@ -0,0 +1 @@
tests/qapi-schema/bad-data.json:2: 'data' for command 'oops' cannot be an array

View file

@ -1 +1 @@
0
1

View file

@ -1,2 +1,2 @@
# FIXME: we should ensure 'data' is a dictionary for all but enums
# we ensure 'data' is a dictionary for all but enums
{ 'command': 'oops', 'data': [ ] }

View file

@ -1,3 +0,0 @@
[OrderedDict([('command', 'oops'), ('data', [])])]
[]
[]

View file

@ -0,0 +1 @@
tests/qapi-schema/data-array-empty.json:2: Member 'empty' of 'data' for command 'oops': array type must contain single type name

View file

@ -1 +1 @@
0
1

View file

@ -1,2 +1,2 @@
# FIXME: we should reject an array for data if it does not contain a known type
# we reject an array for data if it does not contain a known type
{ 'command': 'oops', 'data': { 'empty': [ ] } }

View file

@ -1,3 +0,0 @@
[OrderedDict([('command', 'oops'), ('data', OrderedDict([('empty', [])]))])]
[]
[]

View file

@ -0,0 +1 @@
tests/qapi-schema/data-array-unknown.json:2: Member 'array' of 'data' for command 'oops' uses unknown type 'array of NoSuchType'

View file

@ -1 +1 @@
0
1

View file

@ -1,2 +1,2 @@
# FIXME: we should reject an array for data if it does not contain a known type
# we reject an array for data if it does not contain a known type
{ 'command': 'oops', 'data': { 'array': [ 'NoSuchType' ] } }

View file

@ -1,3 +0,0 @@
[OrderedDict([('command', 'oops'), ('data', OrderedDict([('array', ['NoSuchType'])]))])]
[]
[]

View file

@ -0,0 +1 @@
tests/qapi-schema/data-int.json:2: 'data' for command 'oops' cannot use built-in type 'int'

View file

@ -1 +1 @@
0
1

View file

@ -1,2 +1,2 @@
# FIXME: we should reject commands where data is not an array or complex type
# we reject commands where data is not an array or complex type
{ 'command': 'oops', 'data': 'int' }

View file

@ -1,3 +0,0 @@
[OrderedDict([('command', 'oops'), ('data', 'int')])]
[]
[]

View file

@ -0,0 +1 @@
tests/qapi-schema/data-member-array-bad.json:2: Member 'member' of 'data' for command 'oops': array type must contain single type name

View file

@ -1 +1 @@
0
1

View file

@ -1,2 +1,2 @@
# FIXME: we should reject data if it does not contain a valid array type
# we reject data if it does not contain a valid array type
{ 'command': 'oops', 'data': { 'member': [ { 'nested': 'str' } ] } }

View file

@ -1,3 +0,0 @@
[OrderedDict([('command', 'oops'), ('data', OrderedDict([('member', [OrderedDict([('nested', 'str')])])]))])]
[]
[]

View file

@ -0,0 +1 @@
tests/qapi-schema/data-member-unknown.json:2: Member 'member' of 'data' for command 'oops' uses unknown type 'NoSuchType'

View file

@ -1 +1 @@
0
1

View file

@ -1,2 +1,2 @@
# FIXME: we should reject data if it does not contain a known type
# we reject data if it does not contain a known type
{ 'command': 'oops', 'data': { 'member': 'NoSuchType' } }

View file

@ -1,3 +0,0 @@
[OrderedDict([('command', 'oops'), ('data', OrderedDict([('member', 'NoSuchType')]))])]
[]
[]

View file

@ -0,0 +1 @@
tests/qapi-schema/data-unknown.json:2: 'data' for command 'oops' uses unknown type 'NoSuchType'

View file

@ -1 +1 @@
0
1

View file

@ -1,2 +1,2 @@
# FIXME: we should reject data if it does not contain a known type
# we reject data if it does not contain a known type
{ 'command': 'oops', 'data': 'NoSuchType' }

View file

@ -1,3 +0,0 @@
[OrderedDict([('command', 'oops'), ('data', 'NoSuchType')])]
[]
[]

View file

@ -0,0 +1 @@
tests/qapi-schema/flat-union-int-branch.json:8: Member 'value1' of union 'TestUnion' cannot use built-in type 'int'

View file

@ -1 +1 @@
0
1

View file

@ -1,4 +1,4 @@
# FIXME: we should require flat union branches to be a complex type
# we require flat union branches to be a complex type
{ 'enum': 'TestEnum',
'data': [ 'value1', 'value2' ] }
{ 'type': 'Base',

View file

@ -1,7 +0,0 @@
[OrderedDict([('enum', 'TestEnum'), ('data', ['value1', 'value2'])]),
OrderedDict([('type', 'Base'), ('data', OrderedDict([('enum1', 'TestEnum')]))]),
OrderedDict([('type', 'TestTypeB'), ('data', OrderedDict([('integer', 'int')]))]),
OrderedDict([('union', 'TestUnion'), ('base', 'Base'), ('discriminator', 'enum1'), ('data', OrderedDict([('value1', 'int'), ('value2', 'TestTypeB')]))])]
[{'enum_name': 'TestEnum', 'enum_values': ['value1', 'value2']}]
[OrderedDict([('type', 'Base'), ('data', OrderedDict([('enum1', 'TestEnum')]))]),
OrderedDict([('type', 'TestTypeB'), ('data', OrderedDict([('integer', 'int')]))])]

View file

@ -0,0 +1 @@
tests/qapi-schema/returns-array-bad.json:2: 'returns' for command 'oops': array type must contain single type name

View file

@ -1 +1 @@
0
1

View file

@ -1,2 +1,2 @@
# FIXME: we should reject an array return that is not a single type
# we reject an array return that is not a single type
{ 'command': 'oops', 'returns': [ 'str', 'str' ] }

View file

@ -1,3 +0,0 @@
[OrderedDict([('command', 'oops'), ('returns', ['str', 'str'])])]
[]
[]

View file

@ -0,0 +1 @@
tests/qapi-schema/returns-unknown.json:2: 'returns' for command 'oops' uses unknown type 'NoSuchType'

View file

@ -1 +1 @@
0
1

View file

@ -1,2 +1,2 @@
# FIXME: we should reject returns if it does not contain a known type
# we reject returns if it does not contain a known type
{ 'command': 'oops', 'returns': 'NoSuchType' }

View file

@ -1,3 +0,0 @@
[OrderedDict([('command', 'oops'), ('returns', 'NoSuchType')])]
[]
[]

View file

@ -0,0 +1 @@
tests/qapi-schema/union-unknown.json:2: Member 'unknown' of union 'Union' uses unknown type 'MissingType'

View file

@ -1 +1 @@
0
1

View file

@ -1,3 +1,3 @@
# FIXME: we should reject a union with unknown type in branch
# we reject a union with unknown type in branch
{ 'union': 'Union',
'data': { 'unknown': 'MissingType' } }

View file

@ -1,3 +0,0 @@
[OrderedDict([('union', 'Union'), ('data', OrderedDict([('unknown', 'MissingType')]))])]
[{'enum_name': 'UnionKind', 'enum_values': None}]
[]