aboutsummaryrefslogtreecommitdiff
path: root/tests
diff options
context:
space:
mode:
Diffstat (limited to 'tests')
-rw-r--r--tests/Makefile.include11
-rw-r--r--tests/qapi-schema/alternate-base.err1
-rw-r--r--tests/qapi-schema/alternate-invalid-dict.err1
-rw-r--r--tests/qapi-schema/alternate-invalid-dict.exit (renamed from tests/qapi-schema/enum-dict-member.exit)0
-rw-r--r--tests/qapi-schema/alternate-invalid-dict.json4
-rw-r--r--tests/qapi-schema/alternate-invalid-dict.out (renamed from tests/qapi-schema/enum-dict-member.out)0
-rw-r--r--tests/qapi-schema/comments.out14
-rw-r--r--tests/qapi-schema/doc-bad-section.out13
-rw-r--r--tests/qapi-schema/doc-good.json11
-rw-r--r--tests/qapi-schema/doc-good.out22
-rw-r--r--tests/qapi-schema/doc-good.texi7
-rw-r--r--tests/qapi-schema/double-type.err1
-rw-r--r--tests/qapi-schema/empty.out9
-rw-r--r--tests/qapi-schema/enum-bad-member.err1
-rw-r--r--tests/qapi-schema/enum-bad-member.exit1
-rw-r--r--tests/qapi-schema/enum-bad-member.json2
-rw-r--r--tests/qapi-schema/enum-bad-member.out0
-rw-r--r--tests/qapi-schema/enum-dict-member-unknown.err2
-rw-r--r--tests/qapi-schema/enum-dict-member-unknown.exit1
-rw-r--r--tests/qapi-schema/enum-dict-member-unknown.json2
-rw-r--r--tests/qapi-schema/enum-dict-member-unknown.out0
-rw-r--r--tests/qapi-schema/enum-dict-member.err1
-rw-r--r--tests/qapi-schema/enum-dict-member.json2
-rw-r--r--tests/qapi-schema/enum-if-invalid.err1
-rw-r--r--tests/qapi-schema/enum-if-invalid.exit1
-rw-r--r--tests/qapi-schema/enum-if-invalid.json3
-rw-r--r--tests/qapi-schema/enum-if-invalid.out0
-rw-r--r--tests/qapi-schema/event-case.out9
-rw-r--r--tests/qapi-schema/event-member-invalid-dict.err1
-rw-r--r--tests/qapi-schema/event-member-invalid-dict.exit1
-rw-r--r--tests/qapi-schema/event-member-invalid-dict.json2
-rw-r--r--tests/qapi-schema/event-member-invalid-dict.out0
-rw-r--r--tests/qapi-schema/event-nest-struct.json2
-rw-r--r--tests/qapi-schema/flat-union-inline-invalid-dict.err1
-rw-r--r--tests/qapi-schema/flat-union-inline-invalid-dict.exit1
-rw-r--r--tests/qapi-schema/flat-union-inline-invalid-dict.json11
-rw-r--r--tests/qapi-schema/flat-union-inline-invalid-dict.out0
-rw-r--r--tests/qapi-schema/flat-union-inline.json2
-rw-r--r--tests/qapi-schema/flat-union-invalid-if-discriminator.err1
-rw-r--r--tests/qapi-schema/flat-union-invalid-if-discriminator.exit1
-rw-r--r--tests/qapi-schema/flat-union-invalid-if-discriminator.json17
-rw-r--r--tests/qapi-schema/flat-union-invalid-if-discriminator.out0
-rw-r--r--tests/qapi-schema/ident-with-escape.out9
-rw-r--r--tests/qapi-schema/include-relpath.out14
-rw-r--r--tests/qapi-schema/include-repetition.out14
-rw-r--r--tests/qapi-schema/include-simple.out14
-rw-r--r--tests/qapi-schema/indented-expr.out9
-rw-r--r--tests/qapi-schema/nested-struct-data-invalid-dict.err1
-rw-r--r--tests/qapi-schema/nested-struct-data-invalid-dict.exit1
-rw-r--r--tests/qapi-schema/nested-struct-data-invalid-dict.json3
-rw-r--r--tests/qapi-schema/nested-struct-data-invalid-dict.out0
-rw-r--r--tests/qapi-schema/nested-struct-data.json2
-rw-r--r--tests/qapi-schema/qapi-schema-test.json39
-rw-r--r--tests/qapi-schema/qapi-schema-test.out74
-rw-r--r--tests/qapi-schema/struct-member-invalid-dict.err1
-rw-r--r--tests/qapi-schema/struct-member-invalid-dict.exit1
-rw-r--r--tests/qapi-schema/struct-member-invalid-dict.json3
-rw-r--r--tests/qapi-schema/struct-member-invalid-dict.out0
-rw-r--r--tests/qapi-schema/test-qapi.py9
-rw-r--r--tests/qapi-schema/union-branch-invalid-dict.err1
-rw-r--r--tests/qapi-schema/union-branch-invalid-dict.exit1
-rw-r--r--tests/qapi-schema/union-branch-invalid-dict.json4
-rw-r--r--tests/qapi-schema/union-branch-invalid-dict.out0
-rw-r--r--tests/qapi-schema/unknown-expr-key.err3
-rw-r--r--tests/qapi-schema/unknown-expr-key.json2
-rwxr-xr-xtests/qemu-iotests/2291
-rw-r--r--tests/test-cutils.c24
-rw-r--r--tests/test-string-input-visitor.c223
68 files changed, 510 insertions, 103 deletions
diff --git a/tests/Makefile.include b/tests/Makefile.include
index fb0b449..3f5a1d0 100644
--- a/tests/Makefile.include
+++ b/tests/Makefile.include
@@ -318,6 +318,7 @@ qapi-schema += alternate-conflict-string.json
qapi-schema += alternate-conflict-bool-string.json
qapi-schema += alternate-conflict-num-string.json
qapi-schema += alternate-empty.json
+qapi-schema += alternate-invalid-dict.json
qapi-schema += alternate-nested.json
qapi-schema += alternate-unknown.json
qapi-schema += args-alternate.json
@@ -379,10 +380,12 @@ qapi-schema += double-data.json
qapi-schema += double-type.json
qapi-schema += duplicate-key.json
qapi-schema += empty.json
+qapi-schema += enum-bad-member.json
qapi-schema += enum-bad-name.json
qapi-schema += enum-bad-prefix.json
qapi-schema += enum-clash-member.json
-qapi-schema += enum-dict-member.json
+qapi-schema += enum-dict-member-unknown.json
+qapi-schema += enum-if-invalid.json
qapi-schema += enum-int-member.json
qapi-schema += enum-member-case.json
qapi-schema += enum-missing-data.json
@@ -392,6 +395,7 @@ qapi-schema += escape-too-big.json
qapi-schema += escape-too-short.json
qapi-schema += event-boxed-empty.json
qapi-schema += event-case.json
+qapi-schema += event-member-invalid-dict.json
qapi-schema += event-nest-struct.json
qapi-schema += flat-union-array-branch.json
qapi-schema += flat-union-bad-base.json
@@ -401,9 +405,11 @@ qapi-schema += flat-union-base-union.json
qapi-schema += flat-union-clash-member.json
qapi-schema += flat-union-empty.json
qapi-schema += flat-union-inline.json
+qapi-schema += flat-union-inline-invalid-dict.json
qapi-schema += flat-union-int-branch.json
qapi-schema += flat-union-invalid-branch-key.json
qapi-schema += flat-union-invalid-discriminator.json
+qapi-schema += flat-union-invalid-if-discriminator.json
qapi-schema += flat-union-no-base.json
qapi-schema += flat-union-optional-discriminator.json
qapi-schema += flat-union-string-discriminator.json
@@ -428,6 +434,7 @@ qapi-schema += missing-comma-list.json
qapi-schema += missing-comma-object.json
qapi-schema += missing-type.json
qapi-schema += nested-struct-data.json
+qapi-schema += nested-struct-data-invalid-dict.json
qapi-schema += non-objects.json
qapi-schema += oob-test.json
qapi-schema += allow-preconfig-test.json
@@ -458,6 +465,7 @@ qapi-schema += returns-whitelist.json
qapi-schema += struct-base-clash-deep.json
qapi-schema += struct-base-clash.json
qapi-schema += struct-data-invalid.json
+qapi-schema += struct-member-invalid-dict.json
qapi-schema += struct-member-invalid.json
qapi-schema += trailing-comma-list.json
qapi-schema += trailing-comma-object.json
@@ -469,6 +477,7 @@ qapi-schema += unicode-str.json
qapi-schema += union-base-empty.json
qapi-schema += union-base-no-discriminator.json
qapi-schema += union-branch-case.json
+qapi-schema += union-branch-invalid-dict.json
qapi-schema += union-clash-branches.json
qapi-schema += union-empty.json
qapi-schema += union-invalid-base.json
diff --git a/tests/qapi-schema/alternate-base.err b/tests/qapi-schema/alternate-base.err
index 30d8a34..ebe05bc 100644
--- a/tests/qapi-schema/alternate-base.err
+++ b/tests/qapi-schema/alternate-base.err
@@ -1 +1,2 @@
tests/qapi-schema/alternate-base.json:4: Unknown key 'base' in alternate 'Alt'
+Valid keys are 'alternate', 'data', 'if'.
diff --git a/tests/qapi-schema/alternate-invalid-dict.err b/tests/qapi-schema/alternate-invalid-dict.err
new file mode 100644
index 0000000..631d466
--- /dev/null
+++ b/tests/qapi-schema/alternate-invalid-dict.err
@@ -0,0 +1 @@
+tests/qapi-schema/alternate-invalid-dict.json:2: Key 'type' is missing from member 'two' of alternate 'Alt'
diff --git a/tests/qapi-schema/enum-dict-member.exit b/tests/qapi-schema/alternate-invalid-dict.exit
index d00491f..d00491f 100644
--- a/tests/qapi-schema/enum-dict-member.exit
+++ b/tests/qapi-schema/alternate-invalid-dict.exit
diff --git a/tests/qapi-schema/alternate-invalid-dict.json b/tests/qapi-schema/alternate-invalid-dict.json
new file mode 100644
index 0000000..8e0b2ac
--- /dev/null
+++ b/tests/qapi-schema/alternate-invalid-dict.json
@@ -0,0 +1,4 @@
+# exploded member form must have a 'type'
+{ 'alternate': 'Alt',
+ 'data': { 'one': 'str',
+ 'two': { 'if': 'foo' } } }
diff --git a/tests/qapi-schema/enum-dict-member.out b/tests/qapi-schema/alternate-invalid-dict.out
index e69de29..e69de29 100644
--- a/tests/qapi-schema/enum-dict-member.out
+++ b/tests/qapi-schema/alternate-invalid-dict.out
diff --git a/tests/qapi-schema/comments.out b/tests/qapi-schema/comments.out
index 8d2f1ce..d1abc4b 100644
--- a/tests/qapi-schema/comments.out
+++ b/tests/qapi-schema/comments.out
@@ -1,5 +1,15 @@
object q_empty
-enum QType ['none', 'qnull', 'qnum', 'qstring', 'qdict', 'qlist', 'qbool']
+enum QType
prefix QTYPE
+ member none
+ member qnull
+ member qnum
+ member qstring
+ member qdict
+ member qlist
+ member qbool
module comments.json
-enum Status ['good', 'bad', 'ugly']
+enum Status
+ member good
+ member bad
+ member ugly
diff --git a/tests/qapi-schema/doc-bad-section.out b/tests/qapi-schema/doc-bad-section.out
index cd28721..db8014e 100644
--- a/tests/qapi-schema/doc-bad-section.out
+++ b/tests/qapi-schema/doc-bad-section.out
@@ -1,8 +1,17 @@
object q_empty
-enum QType ['none', 'qnull', 'qnum', 'qstring', 'qdict', 'qlist', 'qbool']
+enum QType
prefix QTYPE
+ member none
+ member qnull
+ member qnum
+ member qstring
+ member qdict
+ member qlist
+ member qbool
module doc-bad-section.json
-enum Enum ['one', 'two']
+enum Enum
+ member one
+ member two
doc symbol=Enum
body=
== Produces *invalid* texinfo
diff --git a/tests/qapi-schema/doc-good.json b/tests/qapi-schema/doc-good.json
index 984cd8e..f7fb48a 100644
--- a/tests/qapi-schema/doc-good.json
+++ b/tests/qapi-schema/doc-good.json
@@ -55,7 +55,9 @@
#
# @two is undocumented
##
-{ 'enum': 'Enum', 'data': [ 'one', 'two' ], 'if': 'defined(IFCOND)' }
+{ 'enum': 'Enum', 'data':
+ [ { 'name': 'one', 'if': 'defined(IFONE)' }, 'two' ],
+ 'if': 'defined(IFCOND)' }
##
# @Base:
@@ -70,7 +72,8 @@
#
# Another paragraph (but no @var: line)
##
-{ 'struct': 'Variant1', 'data': { 'var1': 'str' } }
+{ 'struct': 'Variant1',
+ 'data': { 'var1': { 'type': 'str', 'if': 'defined(IFSTR)' } } }
##
# @Variant2:
@@ -83,13 +86,13 @@
{ 'union': 'Object',
'base': 'Base',
'discriminator': 'base1',
- 'data': { 'one': 'Variant1', 'two': 'Variant2' } }
+ 'data': { 'one': 'Variant1', 'two': { 'type': 'Variant2', 'if': 'IFTWO' } } }
##
# @SugaredUnion:
##
{ 'union': 'SugaredUnion',
- 'data': { 'one': 'Variant1', 'two': 'Variant2' } }
+ 'data': { 'one': 'Variant1', 'two': { 'type': 'Variant2', 'if': 'IFTWO' } } }
##
# == Another subsection
diff --git a/tests/qapi-schema/doc-good.out b/tests/qapi-schema/doc-good.out
index 35f3f11..21bf345 100644
--- a/tests/qapi-schema/doc-good.out
+++ b/tests/qapi-schema/doc-good.out
@@ -1,29 +1,45 @@
object q_empty
-enum QType ['none', 'qnull', 'qnum', 'qstring', 'qdict', 'qlist', 'qbool']
+enum QType
prefix QTYPE
+ member none
+ member qnull
+ member qnum
+ member qstring
+ member qdict
+ member qlist
+ member qbool
module doc-good.json
-enum Enum ['one', 'two']
+enum Enum
+ member one
+ if ['defined(IFONE)']
+ member two
if ['defined(IFCOND)']
object Base
member base1: Enum optional=False
object Variant1
member var1: str optional=False
+ if ['defined(IFSTR)']
object Variant2
object Object
base Base
tag base1
case one: Variant1
case two: Variant2
+ if ['IFTWO']
object q_obj_Variant1-wrapper
member data: Variant1 optional=False
object q_obj_Variant2-wrapper
member data: Variant2 optional=False
-enum SugaredUnionKind ['one', 'two']
+enum SugaredUnionKind
+ member one
+ member two
+ if ['IFTWO']
object SugaredUnion
member type: SugaredUnionKind optional=False
tag type
case one: q_obj_Variant1-wrapper
case two: q_obj_Variant2-wrapper
+ if ['IFTWO']
object q_obj_cmd-arg
member arg1: int optional=False
member arg2: str optional=True
diff --git a/tests/qapi-schema/doc-good.texi b/tests/qapi-schema/doc-good.texi
index e42eace..2526abc 100644
--- a/tests/qapi-schema/doc-good.texi
+++ b/tests/qapi-schema/doc-good.texi
@@ -84,12 +84,12 @@ Examples:
@table @asis
@item @code{one}
The @emph{one} @{and only@}
+@*@b{If:} @code{defined(IFONE)}
@item @code{two}
Not documented
@end table
@code{two} is undocumented
-
@b{If:} @code{defined(IFCOND)}
@end deftp
@@ -119,6 +119,7 @@ Another paragraph (but no @code{var}: line)
@table @asis
@item @code{var1: string}
Not documented
+@*@b{If:} @code{defined(IFSTR)}
@end table
@end deftp
@@ -141,7 +142,7 @@ Not documented
@table @asis
@item The members of @code{Base}
@item The members of @code{Variant1} when @code{base1} is @t{"one"}
-@item The members of @code{Variant2} when @code{base1} is @t{"two"}
+@item The members of @code{Variant2} when @code{base1} is @t{"two"} (@b{If:} @code{IFTWO})
@end table
@end deftp
@@ -157,7 +158,7 @@ Not documented
@item @code{type}
One of @t{"one"}, @t{"two"}
@item @code{data: Variant1} when @code{type} is @t{"one"}
-@item @code{data: Variant2} when @code{type} is @t{"two"}
+@item @code{data: Variant2} when @code{type} is @t{"two"} (@b{If:} @code{IFTWO})
@end table
@end deftp
diff --git a/tests/qapi-schema/double-type.err b/tests/qapi-schema/double-type.err
index f9613c6..799193d 100644
--- a/tests/qapi-schema/double-type.err
+++ b/tests/qapi-schema/double-type.err
@@ -1 +1,2 @@
tests/qapi-schema/double-type.json:2: Unknown key 'command' in struct 'bar'
+Valid keys are 'base', 'data', 'if', 'struct'.
diff --git a/tests/qapi-schema/empty.out b/tests/qapi-schema/empty.out
index 0ec234e..5483cb7 100644
--- a/tests/qapi-schema/empty.out
+++ b/tests/qapi-schema/empty.out
@@ -1,3 +1,10 @@
object q_empty
-enum QType ['none', 'qnull', 'qnum', 'qstring', 'qdict', 'qlist', 'qbool']
+enum QType
prefix QTYPE
+ member none
+ member qnull
+ member qnum
+ member qstring
+ member qdict
+ member qlist
+ member qbool
diff --git a/tests/qapi-schema/enum-bad-member.err b/tests/qapi-schema/enum-bad-member.err
new file mode 100644
index 0000000..211db9e
--- /dev/null
+++ b/tests/qapi-schema/enum-bad-member.err
@@ -0,0 +1 @@
+tests/qapi-schema/enum-bad-member.json:2: Member of enum 'MyEnum' requires a string name
diff --git a/tests/qapi-schema/enum-bad-member.exit b/tests/qapi-schema/enum-bad-member.exit
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/tests/qapi-schema/enum-bad-member.exit
@@ -0,0 +1 @@
+1
diff --git a/tests/qapi-schema/enum-bad-member.json b/tests/qapi-schema/enum-bad-member.json
new file mode 100644
index 0000000..98da682
--- /dev/null
+++ b/tests/qapi-schema/enum-bad-member.json
@@ -0,0 +1,2 @@
+# we reject any enum member that is not a string
+{ 'enum': 'MyEnum', 'data': [ [ ] ] }
diff --git a/tests/qapi-schema/enum-bad-member.out b/tests/qapi-schema/enum-bad-member.out
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/tests/qapi-schema/enum-bad-member.out
diff --git a/tests/qapi-schema/enum-dict-member-unknown.err b/tests/qapi-schema/enum-dict-member-unknown.err
new file mode 100644
index 0000000..2aae618
--- /dev/null
+++ b/tests/qapi-schema/enum-dict-member-unknown.err
@@ -0,0 +1,2 @@
+tests/qapi-schema/enum-dict-member-unknown.json:2: Unknown key 'bad-key' in dictionary member of enum 'MyEnum'
+Valid keys are 'if', 'name'.
diff --git a/tests/qapi-schema/enum-dict-member-unknown.exit b/tests/qapi-schema/enum-dict-member-unknown.exit
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/tests/qapi-schema/enum-dict-member-unknown.exit
@@ -0,0 +1 @@
+1
diff --git a/tests/qapi-schema/enum-dict-member-unknown.json b/tests/qapi-schema/enum-dict-member-unknown.json
new file mode 100644
index 0000000..6664c59
--- /dev/null
+++ b/tests/qapi-schema/enum-dict-member-unknown.json
@@ -0,0 +1,2 @@
+# we reject any enum member that is not a string or a dict with 'name'
+{ 'enum': 'MyEnum', 'data': [ { 'name': 'foo', 'bad-key': 'str' } ] }
diff --git a/tests/qapi-schema/enum-dict-member-unknown.out b/tests/qapi-schema/enum-dict-member-unknown.out
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/tests/qapi-schema/enum-dict-member-unknown.out
diff --git a/tests/qapi-schema/enum-dict-member.err b/tests/qapi-schema/enum-dict-member.err
deleted file mode 100644
index 8ca146e..0000000
--- a/tests/qapi-schema/enum-dict-member.err
+++ /dev/null
@@ -1 +0,0 @@
-tests/qapi-schema/enum-dict-member.json:2: Member of enum 'MyEnum' requires a string name
diff --git a/tests/qapi-schema/enum-dict-member.json b/tests/qapi-schema/enum-dict-member.json
deleted file mode 100644
index 79672e0..0000000
--- a/tests/qapi-schema/enum-dict-member.json
+++ /dev/null
@@ -1,2 +0,0 @@
-# we reject any enum member that is not a string
-{ 'enum': 'MyEnum', 'data': [ { 'value': 'str' } ] }
diff --git a/tests/qapi-schema/enum-if-invalid.err b/tests/qapi-schema/enum-if-invalid.err
new file mode 100644
index 0000000..54c3cf8
--- /dev/null
+++ b/tests/qapi-schema/enum-if-invalid.err
@@ -0,0 +1 @@
+tests/qapi-schema/enum-if-invalid.json:2: 'if' condition must be a string or a list of strings
diff --git a/tests/qapi-schema/enum-if-invalid.exit b/tests/qapi-schema/enum-if-invalid.exit
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/tests/qapi-schema/enum-if-invalid.exit
@@ -0,0 +1 @@
+1
diff --git a/tests/qapi-schema/enum-if-invalid.json b/tests/qapi-schema/enum-if-invalid.json
new file mode 100644
index 0000000..60bd0ef
--- /dev/null
+++ b/tests/qapi-schema/enum-if-invalid.json
@@ -0,0 +1,3 @@
+# check invalid 'if' type
+{ 'enum': 'TestIfEnum', 'data':
+ [ 'foo', { 'name' : 'bar', 'if': { 'val': 'foo' } } ] }
diff --git a/tests/qapi-schema/enum-if-invalid.out b/tests/qapi-schema/enum-if-invalid.out
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/tests/qapi-schema/enum-if-invalid.out
diff --git a/tests/qapi-schema/event-case.out b/tests/qapi-schema/event-case.out
index 88c0964..f69d4ff 100644
--- a/tests/qapi-schema/event-case.out
+++ b/tests/qapi-schema/event-case.out
@@ -1,6 +1,13 @@
object q_empty
-enum QType ['none', 'qnull', 'qnum', 'qstring', 'qdict', 'qlist', 'qbool']
+enum QType
prefix QTYPE
+ member none
+ member qnull
+ member qnum
+ member qstring
+ member qdict
+ member qlist
+ member qbool
module event-case.json
event oops None
boxed=False
diff --git a/tests/qapi-schema/event-member-invalid-dict.err b/tests/qapi-schema/event-member-invalid-dict.err
new file mode 100644
index 0000000..1a57fa2
--- /dev/null
+++ b/tests/qapi-schema/event-member-invalid-dict.err
@@ -0,0 +1 @@
+tests/qapi-schema/event-member-invalid-dict.json:1: Key 'type' is missing from member 'a' of 'data' for event 'EVENT_A'
diff --git a/tests/qapi-schema/event-member-invalid-dict.exit b/tests/qapi-schema/event-member-invalid-dict.exit
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/tests/qapi-schema/event-member-invalid-dict.exit
@@ -0,0 +1 @@
+1
diff --git a/tests/qapi-schema/event-member-invalid-dict.json b/tests/qapi-schema/event-member-invalid-dict.json
new file mode 100644
index 0000000..ee6f3ec
--- /dev/null
+++ b/tests/qapi-schema/event-member-invalid-dict.json
@@ -0,0 +1,2 @@
+{ 'event': 'EVENT_A',
+ 'data': { 'a' : { 'string' : 'str', 'integer': 'int' }, 'b' : 'str' } }
diff --git a/tests/qapi-schema/event-member-invalid-dict.out b/tests/qapi-schema/event-member-invalid-dict.out
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/tests/qapi-schema/event-member-invalid-dict.out
diff --git a/tests/qapi-schema/event-nest-struct.json b/tests/qapi-schema/event-nest-struct.json
index ee6f3ec..355ddae 100644
--- a/tests/qapi-schema/event-nest-struct.json
+++ b/tests/qapi-schema/event-nest-struct.json
@@ -1,2 +1,2 @@
{ 'event': 'EVENT_A',
- 'data': { 'a' : { 'string' : 'str', 'integer': 'int' }, 'b' : 'str' } }
+ 'data': { 'a' : { 'type' : { 'integer': 'int' } }, 'b' : 'str' } }
diff --git a/tests/qapi-schema/flat-union-inline-invalid-dict.err b/tests/qapi-schema/flat-union-inline-invalid-dict.err
new file mode 100644
index 0000000..9c4c45b
--- /dev/null
+++ b/tests/qapi-schema/flat-union-inline-invalid-dict.err
@@ -0,0 +1 @@
+tests/qapi-schema/flat-union-inline-invalid-dict.json:7: Key 'type' is missing from member 'value1' of union 'TestUnion'
diff --git a/tests/qapi-schema/flat-union-inline-invalid-dict.exit b/tests/qapi-schema/flat-union-inline-invalid-dict.exit
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/tests/qapi-schema/flat-union-inline-invalid-dict.exit
@@ -0,0 +1 @@
+1
diff --git a/tests/qapi-schema/flat-union-inline-invalid-dict.json b/tests/qapi-schema/flat-union-inline-invalid-dict.json
new file mode 100644
index 0000000..62c7cda
--- /dev/null
+++ b/tests/qapi-schema/flat-union-inline-invalid-dict.json
@@ -0,0 +1,11 @@
+# we require branches to be a struct name
+# TODO: should we allow anonymous inline branch types?
+{ 'enum': 'TestEnum',
+ 'data': [ 'value1', 'value2' ] }
+{ 'struct': 'Base',
+ 'data': { 'enum1': 'TestEnum', 'kind': 'str' } }
+{ 'union': 'TestUnion',
+ 'base': 'Base',
+ 'discriminator': 'enum1',
+ 'data': { 'value1': { 'string': 'str' },
+ 'value2': { 'integer': 'int' } } }
diff --git a/tests/qapi-schema/flat-union-inline-invalid-dict.out b/tests/qapi-schema/flat-union-inline-invalid-dict.out
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/tests/qapi-schema/flat-union-inline-invalid-dict.out
diff --git a/tests/qapi-schema/flat-union-inline.json b/tests/qapi-schema/flat-union-inline.json
index 62c7cda..a9b3ce3 100644
--- a/tests/qapi-schema/flat-union-inline.json
+++ b/tests/qapi-schema/flat-union-inline.json
@@ -7,5 +7,5 @@
{ 'union': 'TestUnion',
'base': 'Base',
'discriminator': 'enum1',
- 'data': { 'value1': { 'string': 'str' },
+ 'data': { 'value1': { 'type': {} },
'value2': { 'integer': 'int' } } }
diff --git a/tests/qapi-schema/flat-union-invalid-if-discriminator.err b/tests/qapi-schema/flat-union-invalid-if-discriminator.err
new file mode 100644
index 0000000..0c94c98
--- /dev/null
+++ b/tests/qapi-schema/flat-union-invalid-if-discriminator.err
@@ -0,0 +1 @@
+tests/qapi-schema/flat-union-invalid-if-discriminator.json:13: The discriminator TestBase.enum1 for union TestUnion must not be conditional
diff --git a/tests/qapi-schema/flat-union-invalid-if-discriminator.exit b/tests/qapi-schema/flat-union-invalid-if-discriminator.exit
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/tests/qapi-schema/flat-union-invalid-if-discriminator.exit
@@ -0,0 +1 @@
+1
diff --git a/tests/qapi-schema/flat-union-invalid-if-discriminator.json b/tests/qapi-schema/flat-union-invalid-if-discriminator.json
new file mode 100644
index 0000000..618ec36
--- /dev/null
+++ b/tests/qapi-schema/flat-union-invalid-if-discriminator.json
@@ -0,0 +1,17 @@
+{ 'enum': 'TestEnum',
+ 'data': [ 'value1', 'value2' ] }
+
+{ 'struct': 'TestBase',
+ 'data': { 'enum1': { 'type': 'TestEnum', 'if': 'FOO' } } }
+
+{ 'struct': 'TestTypeA',
+ 'data': { 'string': 'str' } }
+
+{ 'struct': 'TestTypeB',
+ 'data': { 'integer': 'int' } }
+
+{ 'union': 'TestUnion',
+ 'base': 'TestBase',
+ 'discriminator': 'enum1',
+ 'data': { 'value1': 'TestTypeA',
+ 'value2': 'TestTypeB' } }
diff --git a/tests/qapi-schema/flat-union-invalid-if-discriminator.out b/tests/qapi-schema/flat-union-invalid-if-discriminator.out
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/tests/qapi-schema/flat-union-invalid-if-discriminator.out
diff --git a/tests/qapi-schema/ident-with-escape.out b/tests/qapi-schema/ident-with-escape.out
index 24c976f..7f891f7 100644
--- a/tests/qapi-schema/ident-with-escape.out
+++ b/tests/qapi-schema/ident-with-escape.out
@@ -1,6 +1,13 @@
object q_empty
-enum QType ['none', 'qnull', 'qnum', 'qstring', 'qdict', 'qlist', 'qbool']
+enum QType
prefix QTYPE
+ member none
+ member qnull
+ member qnum
+ member qstring
+ member qdict
+ member qlist
+ member qbool
module ident-with-escape.json
object q_obj_fooA-arg
member bar1: str optional=False
diff --git a/tests/qapi-schema/include-relpath.out b/tests/qapi-schema/include-relpath.out
index ebbabd7..783ccfc 100644
--- a/tests/qapi-schema/include-relpath.out
+++ b/tests/qapi-schema/include-relpath.out
@@ -1,9 +1,19 @@
object q_empty
-enum QType ['none', 'qnull', 'qnum', 'qstring', 'qdict', 'qlist', 'qbool']
+enum QType
prefix QTYPE
+ member none
+ member qnull
+ member qnum
+ member qstring
+ member qdict
+ member qlist
+ member qbool
module include-relpath.json
include include/relpath.json
module include/relpath.json
include include-relpath-sub.json
module include-relpath-sub.json
-enum Status ['good', 'bad', 'ugly']
+enum Status
+ member good
+ member bad
+ member ugly
diff --git a/tests/qapi-schema/include-repetition.out b/tests/qapi-schema/include-repetition.out
index 7235e05..d45977e 100644
--- a/tests/qapi-schema/include-repetition.out
+++ b/tests/qapi-schema/include-repetition.out
@@ -1,10 +1,20 @@
object q_empty
-enum QType ['none', 'qnull', 'qnum', 'qstring', 'qdict', 'qlist', 'qbool']
+enum QType
prefix QTYPE
+ member none
+ member qnull
+ member qnum
+ member qstring
+ member qdict
+ member qlist
+ member qbool
module include-repetition.json
include comments.json
module comments.json
-enum Status ['good', 'bad', 'ugly']
+enum Status
+ member good
+ member bad
+ member ugly
module include-repetition.json
include include-repetition-sub.json
module include-repetition-sub.json
diff --git a/tests/qapi-schema/include-simple.out b/tests/qapi-schema/include-simple.out
index 006f723..1afe208 100644
--- a/tests/qapi-schema/include-simple.out
+++ b/tests/qapi-schema/include-simple.out
@@ -1,7 +1,17 @@
object q_empty
-enum QType ['none', 'qnull', 'qnum', 'qstring', 'qdict', 'qlist', 'qbool']
+enum QType
prefix QTYPE
+ member none
+ member qnull
+ member qnum
+ member qstring
+ member qdict
+ member qlist
+ member qbool
module include-simple.json
include include-simple-sub.json
module include-simple-sub.json
-enum Status ['good', 'bad', 'ugly']
+enum Status
+ member good
+ member bad
+ member ugly
diff --git a/tests/qapi-schema/indented-expr.out b/tests/qapi-schema/indented-expr.out
index bd8a486..c0cf324 100644
--- a/tests/qapi-schema/indented-expr.out
+++ b/tests/qapi-schema/indented-expr.out
@@ -1,6 +1,13 @@
object q_empty
-enum QType ['none', 'qnull', 'qnum', 'qstring', 'qdict', 'qlist', 'qbool']
+enum QType
prefix QTYPE
+ member none
+ member qnull
+ member qnum
+ member qstring
+ member qdict
+ member qlist
+ member qbool
module indented-expr.json
command eins None -> None
gen=True success_response=True boxed=False oob=False preconfig=False
diff --git a/tests/qapi-schema/nested-struct-data-invalid-dict.err b/tests/qapi-schema/nested-struct-data-invalid-dict.err
new file mode 100644
index 0000000..5bd364e
--- /dev/null
+++ b/tests/qapi-schema/nested-struct-data-invalid-dict.err
@@ -0,0 +1 @@
+tests/qapi-schema/nested-struct-data-invalid-dict.json:2: Key 'type' is missing from member 'a' of 'data' for command 'foo'
diff --git a/tests/qapi-schema/nested-struct-data-invalid-dict.exit b/tests/qapi-schema/nested-struct-data-invalid-dict.exit
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/tests/qapi-schema/nested-struct-data-invalid-dict.exit
@@ -0,0 +1 @@
+1
diff --git a/tests/qapi-schema/nested-struct-data-invalid-dict.json b/tests/qapi-schema/nested-struct-data-invalid-dict.json
new file mode 100644
index 0000000..efbe773
--- /dev/null
+++ b/tests/qapi-schema/nested-struct-data-invalid-dict.json
@@ -0,0 +1,3 @@
+# inline subtypes collide with our desired future use of defaults
+{ 'command': 'foo',
+ 'data': { 'a' : { 'string' : 'str', 'integer': 'int' }, 'b' : 'str' } }
diff --git a/tests/qapi-schema/nested-struct-data-invalid-dict.out b/tests/qapi-schema/nested-struct-data-invalid-dict.out
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/tests/qapi-schema/nested-struct-data-invalid-dict.out
diff --git a/tests/qapi-schema/nested-struct-data.json b/tests/qapi-schema/nested-struct-data.json
index efbe773..5b8a40c 100644
--- a/tests/qapi-schema/nested-struct-data.json
+++ b/tests/qapi-schema/nested-struct-data.json
@@ -1,3 +1,3 @@
# inline subtypes collide with our desired future use of defaults
{ 'command': 'foo',
- 'data': { 'a' : { 'string' : 'str', 'integer': 'int' }, 'b' : 'str' } }
+ 'data': { 'a' : { 'type': {} }, 'b' : 'str' } }
diff --git a/tests/qapi-schema/qapi-schema-test.json b/tests/qapi-schema/qapi-schema-test.json
index fb03163..cb0857d 100644
--- a/tests/qapi-schema/qapi-schema-test.json
+++ b/tests/qapi-schema/qapi-schema-test.json
@@ -11,7 +11,7 @@
'guest-sync' ] } }
{ 'struct': 'TestStruct',
- 'data': { 'integer': 'int', 'boolean': 'bool', 'string': 'str' } }
+ 'data': { 'integer': {'type': 'int'}, 'boolean': 'bool', 'string': 'str' } }
# for testing enums
{ 'struct': 'NestedEnumsOne',
@@ -77,7 +77,7 @@
{ 'union': 'UserDefFlatUnion',
'base': 'UserDefUnionBase', # intentional forward reference
'discriminator': 'enum1',
- 'data': { 'value1' : 'UserDefA',
+ 'data': { 'value1' : {'type': 'UserDefA'},
'value2' : 'UserDefB',
'value3' : 'UserDefB'
# 'value4' defaults to empty
@@ -98,7 +98,7 @@
{ 'struct': 'WrapAlternate',
'data': { 'alt': 'UserDefAlternate' } }
{ 'alternate': 'UserDefAlternate',
- 'data': { 'udfu': 'UserDefFlatUnion', 'e': 'EnumOne', 'i': 'int',
+ 'data': { 'udfu': {'type': 'UserDefFlatUnion'}, 'e': 'EnumOne', 'i': 'int',
'n': 'null' } }
{ 'struct': 'UserDefC',
@@ -134,7 +134,7 @@
{ 'command': 'user_def_cmd', 'data': {} }
{ 'command': 'user_def_cmd1', 'data': {'ud1a': 'UserDefOne'} }
{ 'command': 'user_def_cmd2',
- 'data': {'ud1a': 'UserDefOne', '*ud1b': 'UserDefOne'},
+ 'data': {'ud1a': {'type': 'UserDefOne'}, '*ud1b': 'UserDefOne'},
'returns': 'UserDefTwo' }
{ 'command': 'cmd-success-response', 'data': {}, 'success-response': false }
@@ -166,7 +166,7 @@
# testing event
{ 'struct': 'EventStructOne',
- 'data': { 'struct1': 'UserDefOne', 'string': 'str', '*enum2': 'EnumOne' } }
+ 'data': { 'struct1': {'type': 'UserDefOne'}, 'string': 'str', '*enum2': 'EnumOne' } }
{ 'event': 'EVENT_A' }
{ 'event': 'EVENT_B',
@@ -201,23 +201,40 @@
# test 'if' condition handling
-{ 'struct': 'TestIfStruct', 'data': { 'foo': 'int' },
+{ 'struct': 'TestIfStruct', 'data':
+ { 'foo': 'int',
+ 'bar': { 'type': 'int', 'if': 'defined(TEST_IF_STRUCT_BAR)'} },
'if': 'defined(TEST_IF_STRUCT)' }
-{ 'enum': 'TestIfEnum', 'data': [ 'foo', 'bar' ],
+{ 'enum': 'TestIfEnum', 'data':
+ [ 'foo', { 'name' : 'bar', 'if': 'defined(TEST_IF_ENUM_BAR)' } ],
'if': 'defined(TEST_IF_ENUM)' }
-{ 'union': 'TestIfUnion', 'data': { 'foo': 'TestStruct' },
+{ 'union': 'TestIfUnion', 'data':
+ { 'foo': 'TestStruct',
+ 'union_bar': { 'type': 'str', 'if': 'defined(TEST_IF_UNION_BAR)'} },
'if': 'defined(TEST_IF_UNION) && defined(TEST_IF_STRUCT)' }
-{ 'alternate': 'TestIfAlternate', 'data': { 'foo': 'int', 'bar': 'TestStruct' },
+{ 'command': 'TestIfUnionCmd', 'data': { 'union_cmd_arg': 'TestIfUnion' },
+ 'if': 'defined(TEST_IF_UNION)' }
+
+{ 'alternate': 'TestIfAlternate', 'data':
+ { 'foo': 'int',
+ 'bar': { 'type': 'TestStruct', 'if': 'defined(TEST_IF_ALT_BAR)'} },
'if': 'defined(TEST_IF_ALT) && defined(TEST_IF_STRUCT)' }
-{ 'command': 'TestIfCmd', 'data': { 'foo': 'TestIfStruct' },
+{ 'command': 'TestIfAlternateCmd', 'data': { 'alt_cmd_arg': 'TestIfAlternate' },
+ 'if': 'defined(TEST_IF_ALT)' }
+
+{ 'command': 'TestIfCmd', 'data':
+ { 'foo': 'TestIfStruct',
+ 'bar': { 'type': 'TestIfEnum', 'if': 'defined(TEST_IF_CMD_BAR)' } },
'returns': 'UserDefThree',
'if': ['defined(TEST_IF_CMD)', 'defined(TEST_IF_STRUCT)'] }
{ 'command': 'TestCmdReturnDefThree', 'returns': 'UserDefThree' }
-{ 'event': 'TestIfEvent', 'data': { 'foo': 'TestIfStruct' },
+{ 'event': 'TestIfEvent', 'data':
+ { 'foo': 'TestIfStruct',
+ 'bar': { 'type': 'TestIfEnum', 'if': 'defined(TEST_IF_EVT_BAR)' } },
'if': 'defined(TEST_IF_EVT) && defined(TEST_IF_STRUCT)' }
diff --git a/tests/qapi-schema/qapi-schema-test.out b/tests/qapi-schema/qapi-schema-test.out
index 218ac7d..9464101 100644
--- a/tests/qapi-schema/qapi-schema-test.out
+++ b/tests/qapi-schema/qapi-schema-test.out
@@ -1,6 +1,13 @@
object q_empty
-enum QType ['none', 'qnull', 'qnum', 'qstring', 'qdict', 'qlist', 'qbool']
+enum QType
prefix QTYPE
+ member none
+ member qnull
+ member qnum
+ member qstring
+ member qdict
+ member qlist
+ member qbool
module qapi-schema-test.json
object TestStruct
member integer: int optional=False
@@ -11,19 +18,25 @@ object NestedEnumsOne
member enum2: EnumOne optional=True
member enum3: EnumOne optional=False
member enum4: EnumOne optional=True
-enum MyEnum []
+enum MyEnum
object Empty1
object Empty2
base Empty1
command user_def_cmd0 Empty2 -> Empty2
gen=True success_response=True boxed=False oob=False preconfig=False
-enum QEnumTwo ['value1', 'value2']
+enum QEnumTwo
prefix QENUM_TWO
+ member value1
+ member value2
object UserDefOne
base UserDefZero
member string: str optional=False
member enum1: EnumOne optional=True
-enum EnumOne ['value1', 'value2', 'value3', 'value4']
+enum EnumOne
+ member value1
+ member value2
+ member value3
+ member value4
object UserDefZero
member integer: int optional=False
object UserDefTwoDictDict
@@ -127,7 +140,21 @@ object q_obj_sizeList-wrapper
member data: sizeList optional=False
object q_obj_anyList-wrapper
member data: anyList optional=False
-enum UserDefNativeListUnionKind ['integer', 's8', 's16', 's32', 's64', 'u8', 'u16', 'u32', 'u64', 'number', 'boolean', 'string', 'sizes', 'any']
+enum UserDefNativeListUnionKind
+ member integer
+ member s8
+ member s16
+ member s32
+ member s64
+ member u8
+ member u16
+ member u32
+ member u64
+ member number
+ member boolean
+ member string
+ member sizes
+ member any
object UserDefNativeListUnion
member type: UserDefNativeListUnionKind optional=False
tag type
@@ -204,7 +231,8 @@ event EVENT_E UserDefZero
boxed=True
event EVENT_F UserDefAlternate
boxed=True
-enum __org.qemu_x-Enum ['__org.qemu_x-value']
+enum __org.qemu_x-Enum
+ member __org.qemu_x-value
object __org.qemu_x-Base
member __org.qemu_x-member1: __org.qemu_x-Enum optional=False
object __org.qemu_x-Struct
@@ -213,7 +241,8 @@ object __org.qemu_x-Struct
member wchar-t: int optional=True
object q_obj_str-wrapper
member data: str optional=False
-enum __org.qemu_x-Union1Kind ['__org.qemu_x-branch']
+enum __org.qemu_x-Union1Kind
+ member __org.qemu_x-branch
object __org.qemu_x-Union1
member type: __org.qemu_x-Union1Kind optional=False
tag type
@@ -239,25 +268,50 @@ command __org.qemu_x-command q_obj___org.qemu_x-command-arg -> __org.qemu_x-Unio
gen=True success_response=True boxed=False oob=False preconfig=False
object TestIfStruct
member foo: int optional=False
+ member bar: int optional=False
+ if ['defined(TEST_IF_STRUCT_BAR)']
if ['defined(TEST_IF_STRUCT)']
-enum TestIfEnum ['foo', 'bar']
+enum TestIfEnum
+ member foo
+ member bar
+ if ['defined(TEST_IF_ENUM_BAR)']
if ['defined(TEST_IF_ENUM)']
object q_obj_TestStruct-wrapper
member data: TestStruct optional=False
-enum TestIfUnionKind ['foo']
+enum TestIfUnionKind
+ member foo
+ member union_bar
+ if ['defined(TEST_IF_UNION_BAR)']
if ['defined(TEST_IF_UNION) && defined(TEST_IF_STRUCT)']
object TestIfUnion
member type: TestIfUnionKind optional=False
tag type
case foo: q_obj_TestStruct-wrapper
+ case union_bar: q_obj_str-wrapper
+ if ['defined(TEST_IF_UNION_BAR)']
if ['defined(TEST_IF_UNION) && defined(TEST_IF_STRUCT)']
+object q_obj_TestIfUnionCmd-arg
+ member union_cmd_arg: TestIfUnion optional=False
+ if ['defined(TEST_IF_UNION)']
+command TestIfUnionCmd q_obj_TestIfUnionCmd-arg -> None
+ gen=True success_response=True boxed=False oob=False preconfig=False
+ if ['defined(TEST_IF_UNION)']
alternate TestIfAlternate
tag type
case foo: int
case bar: TestStruct
+ if ['defined(TEST_IF_ALT_BAR)']
if ['defined(TEST_IF_ALT) && defined(TEST_IF_STRUCT)']
+object q_obj_TestIfAlternateCmd-arg
+ member alt_cmd_arg: TestIfAlternate optional=False
+ if ['defined(TEST_IF_ALT)']
+command TestIfAlternateCmd q_obj_TestIfAlternateCmd-arg -> None
+ gen=True success_response=True boxed=False oob=False preconfig=False
+ if ['defined(TEST_IF_ALT)']
object q_obj_TestIfCmd-arg
member foo: TestIfStruct optional=False
+ member bar: TestIfEnum optional=False
+ if ['defined(TEST_IF_CMD_BAR)']
if ['defined(TEST_IF_CMD)', 'defined(TEST_IF_STRUCT)']
command TestIfCmd q_obj_TestIfCmd-arg -> UserDefThree
gen=True success_response=True boxed=False oob=False preconfig=False
@@ -266,6 +320,8 @@ command TestCmdReturnDefThree None -> UserDefThree
gen=True success_response=True boxed=False oob=False preconfig=False
object q_obj_TestIfEvent-arg
member foo: TestIfStruct optional=False
+ member bar: TestIfEnum optional=False
+ if ['defined(TEST_IF_EVT_BAR)']
if ['defined(TEST_IF_EVT) && defined(TEST_IF_STRUCT)']
event TestIfEvent q_obj_TestIfEvent-arg
boxed=False
diff --git a/tests/qapi-schema/struct-member-invalid-dict.err b/tests/qapi-schema/struct-member-invalid-dict.err
new file mode 100644
index 0000000..6a765bc
--- /dev/null
+++ b/tests/qapi-schema/struct-member-invalid-dict.err
@@ -0,0 +1 @@
+tests/qapi-schema/struct-member-invalid-dict.json:2: Key 'type' is missing from member '*a' of 'data' for struct 'foo'
diff --git a/tests/qapi-schema/struct-member-invalid-dict.exit b/tests/qapi-schema/struct-member-invalid-dict.exit
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/tests/qapi-schema/struct-member-invalid-dict.exit
@@ -0,0 +1 @@
+1
diff --git a/tests/qapi-schema/struct-member-invalid-dict.json b/tests/qapi-schema/struct-member-invalid-dict.json
new file mode 100644
index 0000000..9fe0d45
--- /dev/null
+++ b/tests/qapi-schema/struct-member-invalid-dict.json
@@ -0,0 +1,3 @@
+# Long form of member must have a value member 'type'
+{ 'struct': 'foo',
+ 'data': { '*a': { 'case': 'foo' } } }
diff --git a/tests/qapi-schema/struct-member-invalid-dict.out b/tests/qapi-schema/struct-member-invalid-dict.out
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/tests/qapi-schema/struct-member-invalid-dict.out
diff --git a/tests/qapi-schema/test-qapi.py b/tests/qapi-schema/test-qapi.py
index cea21c7..d592854 100644
--- a/tests/qapi-schema/test-qapi.py
+++ b/tests/qapi-schema/test-qapi.py
@@ -23,10 +23,13 @@ class QAPISchemaTestVisitor(QAPISchemaVisitor):
def visit_include(self, name, info):
print('include %s' % name)
- def visit_enum_type(self, name, info, ifcond, values, prefix):
- print('enum %s %s' % (name, values))
+ def visit_enum_type(self, name, info, ifcond, members, prefix):
+ print('enum %s' % name)
if prefix:
print(' prefix %s' % prefix)
+ for m in members:
+ print(' member %s' % m.name)
+ self._print_if(m.ifcond, indent=8)
self._print_if(ifcond)
def visit_object_type(self, name, info, ifcond, base, members, variants):
@@ -36,6 +39,7 @@ class QAPISchemaTestVisitor(QAPISchemaVisitor):
for m in members:
print(' member %s: %s optional=%s'
% (m.name, m.type.name, m.optional))
+ self._print_if(m.ifcond, 8)
self._print_variants(variants)
self._print_if(ifcond)
@@ -64,6 +68,7 @@ class QAPISchemaTestVisitor(QAPISchemaVisitor):
print(' tag %s' % variants.tag_member.name)
for v in variants.variants:
print(' case %s: %s' % (v.name, v.type.name))
+ QAPISchemaTestVisitor._print_if(v.ifcond, indent=8)
@staticmethod
def _print_if(ifcond, indent=4):
diff --git a/tests/qapi-schema/union-branch-invalid-dict.err b/tests/qapi-schema/union-branch-invalid-dict.err
new file mode 100644
index 0000000..89f9b36
--- /dev/null
+++ b/tests/qapi-schema/union-branch-invalid-dict.err
@@ -0,0 +1 @@
+tests/qapi-schema/union-branch-invalid-dict.json:2: Key 'type' is missing from member 'integer' of union 'UnionInvalidBranch'
diff --git a/tests/qapi-schema/union-branch-invalid-dict.exit b/tests/qapi-schema/union-branch-invalid-dict.exit
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/tests/qapi-schema/union-branch-invalid-dict.exit
@@ -0,0 +1 @@
+1
diff --git a/tests/qapi-schema/union-branch-invalid-dict.json b/tests/qapi-schema/union-branch-invalid-dict.json
new file mode 100644
index 0000000..9778598
--- /dev/null
+++ b/tests/qapi-schema/union-branch-invalid-dict.json
@@ -0,0 +1,4 @@
+# Long form of member must have a value member 'type'
+{ 'union': 'UnionInvalidBranch',
+ 'data': { 'integer': { 'if': 'foo'},
+ 's8': 'int8' } }
diff --git a/tests/qapi-schema/union-branch-invalid-dict.out b/tests/qapi-schema/union-branch-invalid-dict.out
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/tests/qapi-schema/union-branch-invalid-dict.out
diff --git a/tests/qapi-schema/unknown-expr-key.err b/tests/qapi-schema/unknown-expr-key.err
index 12f5ed5..6ff8bb9 100644
--- a/tests/qapi-schema/unknown-expr-key.err
+++ b/tests/qapi-schema/unknown-expr-key.err
@@ -1 +1,2 @@
-tests/qapi-schema/unknown-expr-key.json:2: Unknown key 'bogus' in struct 'bar'
+tests/qapi-schema/unknown-expr-key.json:2: Unknown keys 'bogus', 'phony' in struct 'bar'
+Valid keys are 'base', 'data', 'if', 'struct'.
diff --git a/tests/qapi-schema/unknown-expr-key.json b/tests/qapi-schema/unknown-expr-key.json
index 3b2be00..13292d7 100644
--- a/tests/qapi-schema/unknown-expr-key.json
+++ b/tests/qapi-schema/unknown-expr-key.json
@@ -1,2 +1,2 @@
# we reject an expression with unknown top-level keys
-{ 'struct': 'bar', 'data': { 'string': 'str'}, 'bogus': { } }
+{ 'struct': 'bar', 'data': { 'string': 'str'}, 'bogus': { }, 'phony': { } }
diff --git a/tests/qemu-iotests/229 b/tests/qemu-iotests/229
index 8660243..893d098 100755
--- a/tests/qemu-iotests/229
+++ b/tests/qemu-iotests/229
@@ -69,7 +69,6 @@ echo
_send_qemu_cmd $QEMU_HANDLE \
"{'execute': 'drive-mirror',
'arguments': {'device': 'testdisk',
- 'mode': 'absolute-paths',
'format': '$IMGFMT',
'target': '$DEST_IMG',
'sync': 'full',
diff --git a/tests/test-cutils.c b/tests/test-cutils.c
index d85c3e0..1aa8351 100644
--- a/tests/test-cutils.c
+++ b/tests/test-cutils.c
@@ -1950,7 +1950,7 @@ static void test_qemu_strtou64_full_max(void)
static void test_qemu_strtosz_simple(void)
{
const char *str;
- char *endptr = NULL;
+ const char *endptr;
int err;
uint64_t res = 0xbaadf00d;
@@ -2017,7 +2017,7 @@ static void test_qemu_strtosz_units(void)
const char *p = "1P";
const char *e = "1E";
int err;
- char *endptr = NULL;
+ const char *endptr;
uint64_t res = 0xbaadf00d;
/* default is M */
@@ -2066,7 +2066,7 @@ static void test_qemu_strtosz_float(void)
{
const char *str = "12.345M";
int err;
- char *endptr = NULL;
+ const char *endptr;
uint64_t res = 0xbaadf00d;
err = qemu_strtosz(str, &endptr, &res);
@@ -2078,7 +2078,7 @@ static void test_qemu_strtosz_float(void)
static void test_qemu_strtosz_invalid(void)
{
const char *str;
- char *endptr = NULL;
+ const char *endptr;
int err;
uint64_t res = 0xbaadf00d;
@@ -2096,12 +2096,22 @@ static void test_qemu_strtosz_invalid(void)
err = qemu_strtosz(str, &endptr, &res);
g_assert_cmpint(err, ==, -EINVAL);
g_assert(endptr == str);
+
+ str = "inf";
+ err = qemu_strtosz(str, &endptr, &res);
+ g_assert_cmpint(err, ==, -EINVAL);
+ g_assert(endptr == str);
+
+ str = "NaN";
+ err = qemu_strtosz(str, &endptr, &res);
+ g_assert_cmpint(err, ==, -EINVAL);
+ g_assert(endptr == str);
}
static void test_qemu_strtosz_trailing(void)
{
const char *str;
- char *endptr = NULL;
+ const char *endptr;
int err;
uint64_t res = 0xbaadf00d;
@@ -2126,7 +2136,7 @@ static void test_qemu_strtosz_trailing(void)
static void test_qemu_strtosz_erange(void)
{
const char *str;
- char *endptr = NULL;
+ const char *endptr;
int err;
uint64_t res = 0xbaadf00d;
@@ -2160,7 +2170,7 @@ static void test_qemu_strtosz_metric(void)
{
const char *str = "12345k";
int err;
- char *endptr = NULL;
+ const char *endptr;
uint64_t res = 0xbaadf00d;
err = qemu_strtosz_metric(str, &endptr, &res);
diff --git a/tests/test-string-input-visitor.c b/tests/test-string-input-visitor.c
index 88e0e1a..34b54df 100644
--- a/tests/test-string-input-visitor.c
+++ b/tests/test-string-input-visitor.c
@@ -92,16 +92,6 @@ static void check_ulist(Visitor *v, uint64_t *expected, size_t n)
uint64List *tail;
int i;
- /* BUG: unsigned numbers above INT64_MAX don't work */
- for (i = 0; i < n; i++) {
- if (expected[i] > INT64_MAX) {
- Error *err = NULL;
- visit_type_uint64List(v, NULL, &res, &err);
- error_free_or_abort(&err);
- return;
- }
- }
-
visit_type_uint64List(v, NULL, &res, &error_abort);
tail = res;
for (i = 0; i < n; i++) {
@@ -117,14 +107,14 @@ static void check_ulist(Visitor *v, uint64_t *expected, size_t n)
static void test_visitor_in_intList(TestInputVisitorData *data,
const void *unused)
{
- /* Note: the visitor *sorts* ranges *unsigned* */
- int64_t expect1[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 20 };
+ int64_t expect1[] = { 1, 2, 0, 2, 3, 4, 20, 5, 6, 7,
+ 8, 9, 1, 2, 3, 4, 5, 6, 7, 8 };
int64_t expect2[] = { 32767, -32768, -32767 };
- int64_t expect3[] = { INT64_MAX, INT64_MIN };
- uint64_t expect4[] = { UINT64_MAX };
+ int64_t expect3[] = { INT64_MIN, INT64_MAX };
+ int64_t expect4[] = { 1 };
+ int64_t expect5[] = { INT64_MAX - 2, INT64_MAX - 1, INT64_MAX };
Error *err = NULL;
int64List *res = NULL;
- int64List *tail;
Visitor *v;
int64_t val;
@@ -140,8 +130,45 @@ static void test_visitor_in_intList(TestInputVisitorData *data,
"-9223372036854775808,9223372036854775807");
check_ilist(v, expect3, ARRAY_SIZE(expect3));
- v = visitor_input_test_init(data, "18446744073709551615");
- check_ulist(v, expect4, ARRAY_SIZE(expect4));
+ v = visitor_input_test_init(data, "1-1");
+ check_ilist(v, expect4, ARRAY_SIZE(expect4));
+
+ v = visitor_input_test_init(data,
+ "9223372036854775805-9223372036854775807");
+ check_ilist(v, expect5, ARRAY_SIZE(expect5));
+
+ /* Value too large */
+
+ v = visitor_input_test_init(data, "9223372036854775808");
+ visit_type_int64List(v, NULL, &res, &err);
+ error_free_or_abort(&err);
+ g_assert(!res);
+
+ /* Value too small */
+
+ v = visitor_input_test_init(data, "-9223372036854775809");
+ visit_type_int64List(v, NULL, &res, &err);
+ error_free_or_abort(&err);
+ g_assert(!res);
+
+ /* Range not ascending */
+
+ v = visitor_input_test_init(data, "3-1");
+ visit_type_int64List(v, NULL, &res, &err);
+ error_free_or_abort(&err);
+ g_assert(!res);
+
+ v = visitor_input_test_init(data, "9223372036854775807-0");
+ visit_type_int64List(v, NULL, &res, &err);
+ error_free_or_abort(&err);
+ g_assert(!res);
+
+ /* Range too big (65536 is the limit against DOS attacks) */
+
+ v = visitor_input_test_init(data, "0-65536");
+ visit_type_int64List(v, NULL, &res, &err);
+ error_free_or_abort(&err);
+ g_assert(!res);
/* Empty list */
@@ -161,39 +188,140 @@ static void test_visitor_in_intList(TestInputVisitorData *data,
v = visitor_input_test_init(data, "0,2-3");
- /* Would be simpler if the visitor genuinely supported virtual walks */
- visit_start_list(v, NULL, (GenericList **)&res, sizeof(*res),
- &error_abort);
- tail = res;
- visit_type_int64(v, NULL, &tail->value, &error_abort);
- g_assert_cmpint(tail->value, ==, 0);
- tail = (int64List *)visit_next_list(v, (GenericList *)tail, sizeof(*res));
- g_assert(tail);
- visit_type_int64(v, NULL, &tail->value, &error_abort);
- g_assert_cmpint(tail->value, ==, 2);
- tail = (int64List *)visit_next_list(v, (GenericList *)tail, sizeof(*res));
- g_assert(tail);
+ visit_start_list(v, NULL, NULL, 0, &error_abort);
+ visit_type_int64(v, NULL, &val, &error_abort);
+ g_assert_cmpint(val, ==, 0);
+ visit_type_int64(v, NULL, &val, &error_abort);
+ g_assert_cmpint(val, ==, 2);
visit_check_list(v, &err);
error_free_or_abort(&err);
- visit_end_list(v, (void **)&res);
-
- qapi_free_int64List(res);
+ visit_end_list(v, NULL);
/* Visit beyond end of list */
+
v = visitor_input_test_init(data, "0");
- visit_start_list(v, NULL, (GenericList **)&res, sizeof(*res),
- &error_abort);
- tail = res;
- visit_type_int64(v, NULL, &tail->value, &err);
- g_assert_cmpint(tail->value, ==, 0);
+ visit_start_list(v, NULL, NULL, 0, &error_abort);
visit_type_int64(v, NULL, &val, &err);
- g_assert_cmpint(val, ==, 1); /* BUG */
+ g_assert_cmpint(val, ==, 0);
+ visit_type_int64(v, NULL, &val, &err);
+ error_free_or_abort(&err);
+
visit_check_list(v, &error_abort);
- visit_end_list(v, (void **)&res);
+ visit_end_list(v, NULL);
+}
- qapi_free_int64List(res);
+static void test_visitor_in_uintList(TestInputVisitorData *data,
+ const void *unused)
+{
+ uint64_t expect1[] = { 1, 2, 0, 2, 3, 4, 20, 5, 6, 7,
+ 8, 9, 1, 2, 3, 4, 5, 6, 7, 8 };
+ uint64_t expect2[] = { 32767, -32768, -32767 };
+ uint64_t expect3[] = { INT64_MIN, INT64_MAX };
+ uint64_t expect4[] = { 1 };
+ uint64_t expect5[] = { UINT64_MAX };
+ uint64_t expect6[] = { UINT64_MAX - 2, UINT64_MAX - 1, UINT64_MAX };
+ Error *err = NULL;
+ uint64List *res = NULL;
+ Visitor *v;
+ uint64_t val;
+
+ /* Valid lists */
+
+ v = visitor_input_test_init(data, "1,2,0,2-4,20,5-9,1-8");
+ check_ulist(v, expect1, ARRAY_SIZE(expect1));
+
+ v = visitor_input_test_init(data, "32767,-32768--32767");
+ check_ulist(v, expect2, ARRAY_SIZE(expect2));
+
+ v = visitor_input_test_init(data,
+ "-9223372036854775808,9223372036854775807");
+ check_ulist(v, expect3, ARRAY_SIZE(expect3));
+
+ v = visitor_input_test_init(data, "1-1");
+ check_ulist(v, expect4, ARRAY_SIZE(expect4));
+
+ v = visitor_input_test_init(data, "18446744073709551615");
+ check_ulist(v, expect5, ARRAY_SIZE(expect5));
+
+ v = visitor_input_test_init(data,
+ "18446744073709551613-18446744073709551615");
+ check_ulist(v, expect6, ARRAY_SIZE(expect6));
+
+ /* Value too large */
+
+ v = visitor_input_test_init(data, "18446744073709551616");
+ visit_type_uint64List(v, NULL, &res, &err);
+ error_free_or_abort(&err);
+ g_assert(!res);
+
+ /* Value too small */
+
+ v = visitor_input_test_init(data, "-18446744073709551616");
+ visit_type_uint64List(v, NULL, &res, &err);
+ error_free_or_abort(&err);
+ g_assert(!res);
+
+ /* Range not ascending */
+
+ v = visitor_input_test_init(data, "3-1");
+ visit_type_uint64List(v, NULL, &res, &err);
+ error_free_or_abort(&err);
+ g_assert(!res);
+
+ v = visitor_input_test_init(data, "18446744073709551615-0");
+ visit_type_uint64List(v, NULL, &res, &err);
+ error_free_or_abort(&err);
+ g_assert(!res);
+
+ /* Range too big (65536 is the limit against DOS attacks) */
+
+ v = visitor_input_test_init(data, "0-65536");
+ visit_type_uint64List(v, NULL, &res, &err);
+ error_free_or_abort(&err);
+ g_assert(!res);
+
+ /* Empty list */
+
+ v = visitor_input_test_init(data, "");
+ visit_type_uint64List(v, NULL, &res, &error_abort);
+ g_assert(!res);
+
+ /* Not a list */
+
+ v = visitor_input_test_init(data, "not an uint list");
+
+ visit_type_uint64List(v, NULL, &res, &err);
+ error_free_or_abort(&err);
+ g_assert(!res);
+
+ /* Unvisited list tail */
+
+ v = visitor_input_test_init(data, "0,2-3");
+
+ visit_start_list(v, NULL, NULL, 0, &error_abort);
+ visit_type_uint64(v, NULL, &val, &error_abort);
+ g_assert_cmpuint(val, ==, 0);
+ visit_type_uint64(v, NULL, &val, &error_abort);
+ g_assert_cmpuint(val, ==, 2);
+
+ visit_check_list(v, &err);
+ error_free_or_abort(&err);
+ visit_end_list(v, NULL);
+
+ /* Visit beyond end of list */
+
+ v = visitor_input_test_init(data, "0");
+
+ visit_start_list(v, NULL, NULL, 0, &error_abort);
+ visit_type_uint64(v, NULL, &val, &err);
+ g_assert_cmpuint(val, ==, 0);
+ visit_type_uint64(v, NULL, &val, &err);
+ error_free_or_abort(&err);
+
+ visit_check_list(v, &error_abort);
+ visit_end_list(v, NULL);
}
static void test_visitor_in_bool(TestInputVisitorData *data,
@@ -252,6 +380,19 @@ static void test_visitor_in_number(TestInputVisitorData *data,
visit_type_number(v, NULL, &res, &err);
g_assert(!err);
g_assert_cmpfloat(res, ==, value);
+
+ /* NaN and infinity has to be rejected */
+
+ v = visitor_input_test_init(data, "NaN");
+
+ visit_type_number(v, NULL, &res, &err);
+ error_free_or_abort(&err);
+
+ v = visitor_input_test_init(data, "inf");
+
+ visit_type_number(v, NULL, &res, &err);
+ error_free_or_abort(&err);
+
}
static void test_visitor_in_string(TestInputVisitorData *data,
@@ -356,6 +497,8 @@ int main(int argc, char **argv)
&in_visitor_data, test_visitor_in_int);
input_visitor_test_add("/string-visitor/input/intList",
&in_visitor_data, test_visitor_in_intList);
+ input_visitor_test_add("/string-visitor/input/uintList",
+ &in_visitor_data, test_visitor_in_uintList);
input_visitor_test_add("/string-visitor/input/bool",
&in_visitor_data, test_visitor_in_bool);
input_visitor_test_add("/string-visitor/input/number",