aboutsummaryrefslogtreecommitdiff
path: root/tests
diff options
context:
space:
mode:
authorPeter Maydell <peter.maydell@linaro.org>2019-09-25 13:31:21 +0100
committerPeter Maydell <peter.maydell@linaro.org>2019-09-25 13:31:21 +0100
commit4142b011cac481356c6d0cf7a9046621a67484af (patch)
treec77bd7e8b6539641343e7ec79c9a31b99c731e11 /tests
parent240ab11fb72049d6373cbbec8d788f8e411a00bc (diff)
parent56176412e7fcfae1c69e4426d94e856b75358231 (diff)
Merge remote-tracking branch 'remotes/armbru/tags/pull-qapi-2019-09-24' into staging
QAPI patches for 2019-09-24 # gpg: Signature made Tue 24 Sep 2019 13:10:36 BST # gpg: using RSA key 354BC8B3D7EB2A6B68674E5F3870B400EB918653 # gpg: issuer "armbru@redhat.com" # gpg: Good signature from "Markus Armbruster <armbru@redhat.com>" [full] # gpg: aka "Markus Armbruster <armbru@pond.sub.org>" [full] # Primary key fingerprint: 354B C8B3 D7EB 2A6B 6867 4E5F 3870 B400 EB91 8653 * remotes/armbru/tags/pull-qapi-2019-09-24: (37 commits) qapi: Assert .visit() and .check_clash() run only after .check() qapi: Fix excessive QAPISchemaEntity.check() recursion qapi: Fix to .check() empty structs just once qapi: Delete useless check_exprs() code for simple union kind qapi: Clean up around check_known_keys() qapi: Simplify check_keys() qapi: Normalize 'if' in check_exprs(), like other sugar qapi: Fix missing 'if' checks in struct, union, alternate 'data' qapi: Reject blank 'if' conditions in addition to empty ones qapi: Fix broken discriminator error messages qapi: Remove null from schema language qapi: Improve reporting of lexical errors qapi: Use quotes more consistently in frontend error messages tests/qapi-schema: Demonstrate suboptimal lexical errors tests/qapi-schema: Demonstrate insufficient 'if' checking tests/qapi-schema: Demonstrate broken discriminator errors tests/qapi-schema: Demonstrate misleading optional tag error tests/qapi-schema: Delete two redundant tests tests/qapi-schema: Cover unknown pragma qapi: Tweak code to match docs/devel/qapi-code-gen.txt ... Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Diffstat (limited to 'tests')
-rw-r--r--tests/Makefile.include16
-rw-r--r--tests/qapi-schema/alternate-branch-if-invalid.err1
-rw-r--r--tests/qapi-schema/alternate-branch-if-invalid.exit (renamed from tests/qapi-schema/args-boxed-empty.exit)0
-rw-r--r--tests/qapi-schema/alternate-branch-if-invalid.json3
-rw-r--r--tests/qapi-schema/alternate-branch-if-invalid.out (renamed from tests/qapi-schema/args-boxed-empty.out)0
-rw-r--r--tests/qapi-schema/alternate-empty.err2
-rw-r--r--tests/qapi-schema/alternate-empty.json4
-rw-r--r--tests/qapi-schema/args-boxed-empty.err1
-rw-r--r--tests/qapi-schema/args-boxed-empty.json3
-rw-r--r--tests/qapi-schema/args-invalid.err2
-rw-r--r--tests/qapi-schema/bad-if-list.err2
-rw-r--r--tests/qapi-schema/bad-if-list.json2
-rw-r--r--tests/qapi-schema/bad-type-int.err2
-rw-r--r--tests/qapi-schema/bad-type-int.json2
-rw-r--r--tests/qapi-schema/doc-missing-colon.err2
-rw-r--r--tests/qapi-schema/doc-missing.err2
-rw-r--r--tests/qapi-schema/doc-no-symbol.err2
-rw-r--r--tests/qapi-schema/double-data.err1
-rw-r--r--tests/qapi-schema/double-data.json2
-rw-r--r--tests/qapi-schema/duplicate-key.err2
-rw-r--r--tests/qapi-schema/duplicate-key.json2
-rw-r--r--tests/qapi-schema/enum-bad-name.err2
-rw-r--r--tests/qapi-schema/enum-bad-name.json3
-rw-r--r--tests/qapi-schema/enum-clash-member.err2
-rw-r--r--tests/qapi-schema/enum-dict-member-unknown.err2
-rw-r--r--tests/qapi-schema/enum-int-member.err2
-rw-r--r--tests/qapi-schema/enum-member-case.err2
-rw-r--r--tests/qapi-schema/escape-outside-string.err2
-rw-r--r--tests/qapi-schema/escape-outside-string.json3
-rw-r--r--tests/qapi-schema/escape-too-big.err1
-rw-r--r--tests/qapi-schema/escape-too-big.json3
-rw-r--r--tests/qapi-schema/escape-too-short.err1
-rw-r--r--tests/qapi-schema/escape-too-short.json3
-rw-r--r--tests/qapi-schema/features-if-invalid.err1
-rw-r--r--tests/qapi-schema/features-if-invalid.exit (renamed from tests/qapi-schema/double-data.exit)0
-rw-r--r--tests/qapi-schema/features-if-invalid.json4
-rw-r--r--tests/qapi-schema/features-if-invalid.out (renamed from tests/qapi-schema/double-data.out)0
-rw-r--r--tests/qapi-schema/flat-union-discriminator-bad-name.err1
-rw-r--r--tests/qapi-schema/flat-union-discriminator-bad-name.exit (renamed from tests/qapi-schema/escape-outside-string.exit)0
-rw-r--r--tests/qapi-schema/flat-union-discriminator-bad-name.json11
-rw-r--r--tests/qapi-schema/flat-union-discriminator-bad-name.out (renamed from tests/qapi-schema/escape-outside-string.out)0
-rw-r--r--tests/qapi-schema/flat-union-empty.err2
-rw-r--r--tests/qapi-schema/flat-union-empty.json2
-rw-r--r--tests/qapi-schema/flat-union-invalid-discriminator.err2
-rw-r--r--tests/qapi-schema/flat-union-invalid-discriminator.json5
-rw-r--r--tests/qapi-schema/flat-union-invalid-if-discriminator.err2
-rw-r--r--tests/qapi-schema/flat-union-invalid-if-discriminator.json5
-rw-r--r--tests/qapi-schema/flat-union-optional-discriminator.err2
-rw-r--r--tests/qapi-schema/flat-union-optional-discriminator.json3
-rw-r--r--tests/qapi-schema/funny-char.err2
-rw-r--r--tests/qapi-schema/funny-word.err1
-rw-r--r--tests/qapi-schema/funny-word.exit (renamed from tests/qapi-schema/escape-too-big.exit)0
-rw-r--r--tests/qapi-schema/funny-word.json1
-rw-r--r--tests/qapi-schema/funny-word.out (renamed from tests/qapi-schema/escape-too-big.out)0
-rw-r--r--tests/qapi-schema/ident-with-escape.err1
-rw-r--r--tests/qapi-schema/ident-with-escape.exit2
-rw-r--r--tests/qapi-schema/ident-with-escape.json2
-rw-r--r--tests/qapi-schema/ident-with-escape.out16
-rw-r--r--tests/qapi-schema/include-before-err.err2
-rw-r--r--tests/qapi-schema/include-format-err.err1
-rw-r--r--tests/qapi-schema/include-format-err.json2
-rw-r--r--tests/qapi-schema/include-nested-err.err2
-rw-r--r--tests/qapi-schema/leading-comma-list.err2
-rw-r--r--tests/qapi-schema/leading-comma-object.err2
-rw-r--r--tests/qapi-schema/missing-colon.err2
-rw-r--r--tests/qapi-schema/missing-comma-list.err2
-rw-r--r--tests/qapi-schema/missing-comma-object.err2
-rw-r--r--tests/qapi-schema/non-objects.err2
-rw-r--r--tests/qapi-schema/pragma-name-case-whitelist-crap.json2
-rw-r--r--tests/qapi-schema/pragma-non-dict.err2
-rw-r--r--tests/qapi-schema/pragma-unknown.err1
-rw-r--r--tests/qapi-schema/pragma-unknown.exit (renamed from tests/qapi-schema/escape-too-short.exit)0
-rw-r--r--tests/qapi-schema/pragma-unknown.json1
-rw-r--r--tests/qapi-schema/pragma-unknown.out (renamed from tests/qapi-schema/escape-too-short.out)0
-rw-r--r--tests/qapi-schema/qapi-schema-test.json13
-rw-r--r--tests/qapi-schema/qapi-schema-test.out21
-rw-r--r--tests/qapi-schema/quoted-structural-chars.err2
-rw-r--r--tests/qapi-schema/string-code-point-127.err1
-rw-r--r--tests/qapi-schema/string-code-point-127.exit (renamed from tests/qapi-schema/include-format-err.exit)0
-rw-r--r--tests/qapi-schema/string-code-point-127.json2
-rw-r--r--tests/qapi-schema/string-code-point-127.out (renamed from tests/qapi-schema/include-format-err.out)0
-rw-r--r--tests/qapi-schema/string-code-point-31.err1
-rw-r--r--tests/qapi-schema/string-code-point-31.exit (renamed from tests/qapi-schema/unicode-str.exit)0
-rw-r--r--tests/qapi-schema/string-code-point-31.json2
-rw-r--r--tests/qapi-schema/string-code-point-31.out (renamed from tests/qapi-schema/unicode-str.out)0
-rw-r--r--tests/qapi-schema/struct-data-invalid.err2
-rw-r--r--tests/qapi-schema/struct-member-if-invalid.err1
-rw-r--r--tests/qapi-schema/struct-member-if-invalid.exit1
-rw-r--r--tests/qapi-schema/struct-member-if-invalid.json3
-rw-r--r--tests/qapi-schema/struct-member-if-invalid.out0
-rw-r--r--tests/qapi-schema/trailing-comma-list.err2
-rw-r--r--tests/qapi-schema/unclosed-list.err2
-rw-r--r--tests/qapi-schema/unclosed-object.err2
-rw-r--r--tests/qapi-schema/unicode-str.err1
-rw-r--r--tests/qapi-schema/unicode-str.json2
-rw-r--r--tests/qapi-schema/union-base-empty.err2
-rw-r--r--tests/qapi-schema/union-branch-if-invalid.err1
-rw-r--r--tests/qapi-schema/union-branch-if-invalid.exit1
-rw-r--r--tests/qapi-schema/union-branch-if-invalid.json6
-rw-r--r--tests/qapi-schema/union-branch-if-invalid.out0
-rw-r--r--tests/qapi-schema/union-empty.err2
-rw-r--r--tests/qapi-schema/union-empty.json2
-rw-r--r--tests/qapi-schema/unknown-escape.json2
-rw-r--r--tests/test-qmp-cmds.c4
104 files changed, 139 insertions, 108 deletions
diff --git a/tests/Makefile.include b/tests/Makefile.include
index 479664f899..0595914526 100644
--- a/tests/Makefile.include
+++ b/tests/Makefile.include
@@ -294,6 +294,7 @@ check-qtest-generic-y += tests/test-hmp$(EXESUF)
qapi-schema += alternate-any.json
qapi-schema += alternate-array.json
qapi-schema += alternate-base.json
+qapi-schema += alternate-branch-if-invalid.json
qapi-schema += alternate-clash.json
qapi-schema += alternate-conflict-dict.json
qapi-schema += alternate-conflict-enum-bool.json
@@ -311,7 +312,6 @@ qapi-schema += args-array-empty.json
qapi-schema += args-array-unknown.json
qapi-schema += args-bad-boxed.json
qapi-schema += args-boxed-anon.json
-qapi-schema += args-boxed-empty.json
qapi-schema += args-boxed-string.json
qapi-schema += args-int.json
qapi-schema += args-invalid.json
@@ -360,7 +360,6 @@ qapi-schema += doc-missing-expr.json
qapi-schema += doc-missing-space.json
qapi-schema += doc-missing.json
qapi-schema += doc-no-symbol.json
-qapi-schema += double-data.json
qapi-schema += double-type.json
qapi-schema += duplicate-key.json
qapi-schema += empty.json
@@ -374,15 +373,13 @@ qapi-schema += enum-int-member.json
qapi-schema += enum-member-case.json
qapi-schema += enum-missing-data.json
qapi-schema += enum-wrong-data.json
-qapi-schema += escape-outside-string.json
-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 += features-bad-type.json
qapi-schema += features-duplicate-name.json
+qapi-schema += features-if-invalid.json
qapi-schema += features-missing-name.json
qapi-schema += features-name-bad-type.json
qapi-schema += features-no-list.json
@@ -393,6 +390,7 @@ qapi-schema += flat-union-bad-discriminator.json
qapi-schema += flat-union-base-any.json
qapi-schema += flat-union-base-union.json
qapi-schema += flat-union-clash-member.json
+qapi-schema += flat-union-discriminator-bad-name.json
qapi-schema += flat-union-empty.json
qapi-schema += flat-union-inline.json
qapi-schema += flat-union-inline-invalid-dict.json
@@ -404,11 +402,11 @@ qapi-schema += flat-union-no-base.json
qapi-schema += flat-union-optional-discriminator.json
qapi-schema += flat-union-string-discriminator.json
qapi-schema += funny-char.json
+qapi-schema += funny-word.json
qapi-schema += ident-with-escape.json
qapi-schema += include-before-err.json
qapi-schema += include-cycle.json
qapi-schema += include-extra-junk.json
-qapi-schema += include-format-err.json
qapi-schema += include-nested-err.json
qapi-schema += include-no-file.json
qapi-schema += include-non-file.json
@@ -431,6 +429,7 @@ qapi-schema += pragma-doc-required-crap.json
qapi-schema += pragma-extra-junk.json
qapi-schema += pragma-name-case-whitelist-crap.json
qapi-schema += pragma-non-dict.json
+qapi-schema += pragma-unknown.json
qapi-schema += pragma-returns-whitelist-crap.json
qapi-schema += qapi-schema-test.json
qapi-schema += quoted-structural-chars.json
@@ -451,9 +450,12 @@ qapi-schema += returns-array-bad.json
qapi-schema += returns-dict.json
qapi-schema += returns-unknown.json
qapi-schema += returns-whitelist.json
+qapi-schema += string-code-point-31.json
+qapi-schema += string-code-point-127.json
qapi-schema += struct-base-clash-deep.json
qapi-schema += struct-base-clash.json
qapi-schema += struct-data-invalid.json
+qapi-schema += struct-member-if-invalid.json
qapi-schema += struct-member-invalid-dict.json
qapi-schema += struct-member-invalid.json
qapi-schema += trailing-comma-list.json
@@ -462,10 +464,10 @@ qapi-schema += type-bypass-bad-gen.json
qapi-schema += unclosed-list.json
qapi-schema += unclosed-object.json
qapi-schema += unclosed-string.json
-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-if-invalid.json
qapi-schema += union-branch-invalid-dict.json
qapi-schema += union-clash-branches.json
qapi-schema += union-empty.json
diff --git a/tests/qapi-schema/alternate-branch-if-invalid.err b/tests/qapi-schema/alternate-branch-if-invalid.err
new file mode 100644
index 0000000000..f1d6c10e00
--- /dev/null
+++ b/tests/qapi-schema/alternate-branch-if-invalid.err
@@ -0,0 +1 @@
+tests/qapi-schema/alternate-branch-if-invalid.json:2: 'if' condition ' ' makes no sense
diff --git a/tests/qapi-schema/args-boxed-empty.exit b/tests/qapi-schema/alternate-branch-if-invalid.exit
index d00491fd7e..d00491fd7e 100644
--- a/tests/qapi-schema/args-boxed-empty.exit
+++ b/tests/qapi-schema/alternate-branch-if-invalid.exit
diff --git a/tests/qapi-schema/alternate-branch-if-invalid.json b/tests/qapi-schema/alternate-branch-if-invalid.json
new file mode 100644
index 0000000000..fea6d9080c
--- /dev/null
+++ b/tests/qapi-schema/alternate-branch-if-invalid.json
@@ -0,0 +1,3 @@
+# Cover alternative with invalid 'if'
+{ 'alternate': 'Alt',
+ 'data': { 'branch': { 'type': 'int', 'if': ' ' } } }
diff --git a/tests/qapi-schema/args-boxed-empty.out b/tests/qapi-schema/alternate-branch-if-invalid.out
index e69de29bb2..e69de29bb2 100644
--- a/tests/qapi-schema/args-boxed-empty.out
+++ b/tests/qapi-schema/alternate-branch-if-invalid.out
diff --git a/tests/qapi-schema/alternate-empty.err b/tests/qapi-schema/alternate-empty.err
index bb06c5bfec..86dbc666eb 100644
--- a/tests/qapi-schema/alternate-empty.err
+++ b/tests/qapi-schema/alternate-empty.err
@@ -1 +1 @@
-tests/qapi-schema/alternate-empty.json:2: Alternate 'Alt' should have at least two branches in 'data'
+tests/qapi-schema/alternate-empty.json:2: Alternate 'Alt' cannot have empty 'data'
diff --git a/tests/qapi-schema/alternate-empty.json b/tests/qapi-schema/alternate-empty.json
index fff15baf16..9f445474e6 100644
--- a/tests/qapi-schema/alternate-empty.json
+++ b/tests/qapi-schema/alternate-empty.json
@@ -1,2 +1,2 @@
-# alternates must list at least two types to be useful
-{ 'alternate': 'Alt', 'data': { 'i': 'int' } }
+# alternates cannot be empty
+{ 'alternate': 'Alt', 'data': { } }
diff --git a/tests/qapi-schema/args-boxed-empty.err b/tests/qapi-schema/args-boxed-empty.err
deleted file mode 100644
index 039603e85c..0000000000
--- a/tests/qapi-schema/args-boxed-empty.err
+++ /dev/null
@@ -1 +0,0 @@
-tests/qapi-schema/args-boxed-empty.json:3: Cannot use 'boxed' with empty type
diff --git a/tests/qapi-schema/args-boxed-empty.json b/tests/qapi-schema/args-boxed-empty.json
deleted file mode 100644
index 52717e065f..0000000000
--- a/tests/qapi-schema/args-boxed-empty.json
+++ /dev/null
@@ -1,3 +0,0 @@
-# 'boxed' requires a non-empty type
-{ 'struct': 'Empty', 'data': {} }
-{ 'command': 'foo', 'boxed': true, 'data': 'Empty' }
diff --git a/tests/qapi-schema/args-invalid.err b/tests/qapi-schema/args-invalid.err
index fe1e94975b..bfb2e4133e 100644
--- a/tests/qapi-schema/args-invalid.err
+++ b/tests/qapi-schema/args-invalid.err
@@ -1 +1 @@
-tests/qapi-schema/args-invalid.json:1: 'data' for command 'foo' should be a dictionary or type name
+tests/qapi-schema/args-invalid.json:1: 'data' for command 'foo' should be an object or type name
diff --git a/tests/qapi-schema/bad-if-list.err b/tests/qapi-schema/bad-if-list.err
index 0af6316f78..53af099083 100644
--- a/tests/qapi-schema/bad-if-list.err
+++ b/tests/qapi-schema/bad-if-list.err
@@ -1 +1 @@
-tests/qapi-schema/bad-if-list.json:2: 'if' condition '' makes no sense
+tests/qapi-schema/bad-if-list.json:2: 'if' condition ' ' makes no sense
diff --git a/tests/qapi-schema/bad-if-list.json b/tests/qapi-schema/bad-if-list.json
index 49ced9b9ca..ea3d95bb6b 100644
--- a/tests/qapi-schema/bad-if-list.json
+++ b/tests/qapi-schema/bad-if-list.json
@@ -1,3 +1,3 @@
# check invalid 'if' content
{ 'struct': 'TestIfStruct', 'data': { 'foo': 'int' },
- 'if': ['foo', ''] }
+ 'if': ['foo', ' '] }
diff --git a/tests/qapi-schema/bad-type-int.err b/tests/qapi-schema/bad-type-int.err
index da89895404..9b2c12c1eb 100644
--- a/tests/qapi-schema/bad-type-int.err
+++ b/tests/qapi-schema/bad-type-int.err
@@ -1 +1 @@
-tests/qapi-schema/bad-type-int.json:3:13: Stray "1"
+tests/qapi-schema/bad-type-int.json:3:13: Stray '123'
diff --git a/tests/qapi-schema/bad-type-int.json b/tests/qapi-schema/bad-type-int.json
index 56fc6f8126..f3ad803cb6 100644
--- a/tests/qapi-schema/bad-type-int.json
+++ b/tests/qapi-schema/bad-type-int.json
@@ -1,3 +1,3 @@
# we reject an expression with a metatype that is not a string
# FIXME: once the parser understands integer inputs, improve the error message
-{ 'struct': 1, 'data': { } }
+{ 'struct': 123, 'data': { } }
diff --git a/tests/qapi-schema/doc-missing-colon.err b/tests/qapi-schema/doc-missing-colon.err
index 817398b8e4..b41d5078b0 100644
--- a/tests/qapi-schema/doc-missing-colon.err
+++ b/tests/qapi-schema/doc-missing-colon.err
@@ -1 +1 @@
-tests/qapi-schema/doc-missing-colon.json:4:1: Line should end with :
+tests/qapi-schema/doc-missing-colon.json:4:1: Line should end with ':'
diff --git a/tests/qapi-schema/doc-missing.err b/tests/qapi-schema/doc-missing.err
index 7f2f326b30..3a377ddc57 100644
--- a/tests/qapi-schema/doc-missing.err
+++ b/tests/qapi-schema/doc-missing.err
@@ -1 +1 @@
-tests/qapi-schema/doc-missing.json:5: Expression missing documentation comment
+tests/qapi-schema/doc-missing.json:5: Definition missing documentation comment
diff --git a/tests/qapi-schema/doc-no-symbol.err b/tests/qapi-schema/doc-no-symbol.err
index 75f032a942..212984ff20 100644
--- a/tests/qapi-schema/doc-no-symbol.err
+++ b/tests/qapi-schema/doc-no-symbol.err
@@ -1 +1 @@
-tests/qapi-schema/doc-no-symbol.json:3: Expression documentation required
+tests/qapi-schema/doc-no-symbol.json:3: Definition documentation required
diff --git a/tests/qapi-schema/double-data.err b/tests/qapi-schema/double-data.err
deleted file mode 100644
index cc765c4ff2..0000000000
--- a/tests/qapi-schema/double-data.err
+++ /dev/null
@@ -1 +0,0 @@
-tests/qapi-schema/double-data.json:2:41: Duplicate key "data"
diff --git a/tests/qapi-schema/double-data.json b/tests/qapi-schema/double-data.json
deleted file mode 100644
index e76b519538..0000000000
--- a/tests/qapi-schema/double-data.json
+++ /dev/null
@@ -1,2 +0,0 @@
-# we reject an expression with duplicate top-level keys
-{ 'struct': 'bar', 'data': { }, 'data': { 'string': 'str'} }
diff --git a/tests/qapi-schema/duplicate-key.err b/tests/qapi-schema/duplicate-key.err
index 6d02f83538..3af2f55174 100644
--- a/tests/qapi-schema/duplicate-key.err
+++ b/tests/qapi-schema/duplicate-key.err
@@ -1 +1 @@
-tests/qapi-schema/duplicate-key.json:3:10: Duplicate key "key"
+tests/qapi-schema/duplicate-key.json:3:10: Duplicate key 'key'
diff --git a/tests/qapi-schema/duplicate-key.json b/tests/qapi-schema/duplicate-key.json
index 14ac0e8a40..06b55840c9 100644
--- a/tests/qapi-schema/duplicate-key.json
+++ b/tests/qapi-schema/duplicate-key.json
@@ -1,3 +1,3 @@
-# QAPI cannot include the same key more than once in any {}
+# Cannot include the same key more than once in any {}
{ 'key': 'value',
'key': 'value' }
diff --git a/tests/qapi-schema/enum-bad-name.err b/tests/qapi-schema/enum-bad-name.err
index 9c3c1002b7..26a09f84ad 100644
--- a/tests/qapi-schema/enum-bad-name.err
+++ b/tests/qapi-schema/enum-bad-name.err
@@ -1 +1 @@
-tests/qapi-schema/enum-bad-name.json:2: Member of enum 'MyEnum' uses invalid name 'not^possible'
+tests/qapi-schema/enum-bad-name.json:3: Member of enum 'MyEnum' uses invalid name 'not\possible'
diff --git a/tests/qapi-schema/enum-bad-name.json b/tests/qapi-schema/enum-bad-name.json
index 8506562b31..1c4620edda 100644
--- a/tests/qapi-schema/enum-bad-name.json
+++ b/tests/qapi-schema/enum-bad-name.json
@@ -1,2 +1,3 @@
# we ensure all enum names can map to C
-{ 'enum': 'MyEnum', 'data': [ 'not^possible' ] }
+# FIXME reports 'not\possible' instead of 'not\\possible'
+{ 'enum': 'MyEnum', 'data': [ 'not\\possible' ] }
diff --git a/tests/qapi-schema/enum-clash-member.err b/tests/qapi-schema/enum-clash-member.err
index 5403c78507..8238d2e807 100644
--- a/tests/qapi-schema/enum-clash-member.err
+++ b/tests/qapi-schema/enum-clash-member.err
@@ -1 +1 @@
-tests/qapi-schema/enum-clash-member.json:2: 'one_two' (member of MyEnum) collides with 'one-two' (member of MyEnum)
+tests/qapi-schema/enum-clash-member.json:2: 'one_two' (value of MyEnum) collides with 'one-two' (value of MyEnum)
diff --git a/tests/qapi-schema/enum-dict-member-unknown.err b/tests/qapi-schema/enum-dict-member-unknown.err
index 2aae618be0..7fd9c032bf 100644
--- a/tests/qapi-schema/enum-dict-member-unknown.err
+++ b/tests/qapi-schema/enum-dict-member-unknown.err
@@ -1,2 +1,2 @@
-tests/qapi-schema/enum-dict-member-unknown.json:2: Unknown key 'bad-key' in dictionary member of enum 'MyEnum'
+tests/qapi-schema/enum-dict-member-unknown.json:2: Unknown key 'bad-key' in member of enum 'MyEnum'
Valid keys are 'if', 'name'.
diff --git a/tests/qapi-schema/enum-int-member.err b/tests/qapi-schema/enum-int-member.err
index 071c5213d8..3f8d7b5b71 100644
--- a/tests/qapi-schema/enum-int-member.err
+++ b/tests/qapi-schema/enum-int-member.err
@@ -1 +1 @@
-tests/qapi-schema/enum-int-member.json:3:31: Stray "1"
+tests/qapi-schema/enum-int-member.json:3:31: Stray '1'
diff --git a/tests/qapi-schema/enum-member-case.err b/tests/qapi-schema/enum-member-case.err
index 3c67a3a067..5d689e92d5 100644
--- a/tests/qapi-schema/enum-member-case.err
+++ b/tests/qapi-schema/enum-member-case.err
@@ -1 +1 @@
-tests/qapi-schema/enum-member-case.json:4: 'Value' (member of NoWayThisWillGetWhitelisted) should not use uppercase
+tests/qapi-schema/enum-member-case.json:4: 'Value' (value of NoWayThisWillGetWhitelisted) should not use uppercase
diff --git a/tests/qapi-schema/escape-outside-string.err b/tests/qapi-schema/escape-outside-string.err
index b9b8837fd2..efee335ba0 100644
--- a/tests/qapi-schema/escape-outside-string.err
+++ b/tests/qapi-schema/escape-outside-string.err
@@ -1 +1 @@
-tests/qapi-schema/escape-outside-string.json:3:27: Stray "\"
+tests/qapi-schema/escape-outside-string.json:3:27: Stray '\'
diff --git a/tests/qapi-schema/escape-outside-string.json b/tests/qapi-schema/escape-outside-string.json
deleted file mode 100644
index 482f79554b..0000000000
--- a/tests/qapi-schema/escape-outside-string.json
+++ /dev/null
@@ -1,3 +0,0 @@
-# escape sequences are permitted only inside strings
-# { 'command': 'foo', 'data': {} }
-{ 'command': 'foo', 'data'\u003a{} }
diff --git a/tests/qapi-schema/escape-too-big.err b/tests/qapi-schema/escape-too-big.err
deleted file mode 100644
index d9aeb5dc38..0000000000
--- a/tests/qapi-schema/escape-too-big.err
+++ /dev/null
@@ -1 +0,0 @@
-tests/qapi-schema/escape-too-big.json:3:14: For now, \u escape only supports non-zero values up to \u007f
diff --git a/tests/qapi-schema/escape-too-big.json b/tests/qapi-schema/escape-too-big.json
deleted file mode 100644
index 62bcecd557..0000000000
--- a/tests/qapi-schema/escape-too-big.json
+++ /dev/null
@@ -1,3 +0,0 @@
-# we don't support full Unicode strings, yet
-# { 'command': 'é' }
-{ 'command': '\u00e9' }
diff --git a/tests/qapi-schema/escape-too-short.err b/tests/qapi-schema/escape-too-short.err
deleted file mode 100644
index 934de598ee..0000000000
--- a/tests/qapi-schema/escape-too-short.err
+++ /dev/null
@@ -1 +0,0 @@
-tests/qapi-schema/escape-too-short.json:3:14: \u escape needs 4 hex digits
diff --git a/tests/qapi-schema/escape-too-short.json b/tests/qapi-schema/escape-too-short.json
deleted file mode 100644
index 6cb1dec8f7..0000000000
--- a/tests/qapi-schema/escape-too-short.json
+++ /dev/null
@@ -1,3 +0,0 @@
-# the \u escape requires 4 hex digits
-# { 'command': 'a' }
-{ 'command': '\u61' }
diff --git a/tests/qapi-schema/features-if-invalid.err b/tests/qapi-schema/features-if-invalid.err
new file mode 100644
index 0000000000..295800b4fc
--- /dev/null
+++ b/tests/qapi-schema/features-if-invalid.err
@@ -0,0 +1 @@
+tests/qapi-schema/features-if-invalid.json:2: 'if' condition must be a string or a list of strings
diff --git a/tests/qapi-schema/double-data.exit b/tests/qapi-schema/features-if-invalid.exit
index d00491fd7e..d00491fd7e 100644
--- a/tests/qapi-schema/double-data.exit
+++ b/tests/qapi-schema/features-if-invalid.exit
diff --git a/tests/qapi-schema/features-if-invalid.json b/tests/qapi-schema/features-if-invalid.json
new file mode 100644
index 0000000000..89c2a6c234
--- /dev/null
+++ b/tests/qapi-schema/features-if-invalid.json
@@ -0,0 +1,4 @@
+# Cover feature with invalid 'if'
+{ 'struct': 'Stru',
+ 'data': {},
+ 'features': [{'name': 'f', 'if': false }] }
diff --git a/tests/qapi-schema/double-data.out b/tests/qapi-schema/features-if-invalid.out
index e69de29bb2..e69de29bb2 100644
--- a/tests/qapi-schema/double-data.out
+++ b/tests/qapi-schema/features-if-invalid.out
diff --git a/tests/qapi-schema/flat-union-discriminator-bad-name.err b/tests/qapi-schema/flat-union-discriminator-bad-name.err
new file mode 100644
index 0000000000..7238d126ca
--- /dev/null
+++ b/tests/qapi-schema/flat-union-discriminator-bad-name.err
@@ -0,0 +1 @@
+tests/qapi-schema/flat-union-discriminator-bad-name.json:7: Discriminator of flat union 'MyUnion' does not allow optional name '*switch'
diff --git a/tests/qapi-schema/escape-outside-string.exit b/tests/qapi-schema/flat-union-discriminator-bad-name.exit
index d00491fd7e..d00491fd7e 100644
--- a/tests/qapi-schema/escape-outside-string.exit
+++ b/tests/qapi-schema/flat-union-discriminator-bad-name.exit
diff --git a/tests/qapi-schema/flat-union-discriminator-bad-name.json b/tests/qapi-schema/flat-union-discriminator-bad-name.json
new file mode 100644
index 0000000000..66376084fc
--- /dev/null
+++ b/tests/qapi-schema/flat-union-discriminator-bad-name.json
@@ -0,0 +1,11 @@
+# discriminator '*switch' isn't a member of base, 'switch' is
+# reports "does not allow optional name", which is good enough
+{ 'enum': 'Enum', 'data': [ 'one', 'two' ] }
+{ 'struct': 'Base',
+ 'data': { '*switch': 'Enum' } }
+{ 'struct': 'Branch', 'data': { 'name': 'str' } }
+{ 'union': 'MyUnion',
+ 'base': 'Base',
+ 'discriminator': '*switch',
+ 'data': { 'one': 'Branch',
+ 'two': 'Branch' } }
diff --git a/tests/qapi-schema/escape-outside-string.out b/tests/qapi-schema/flat-union-discriminator-bad-name.out
index e69de29bb2..e69de29bb2 100644
--- a/tests/qapi-schema/escape-outside-string.out
+++ b/tests/qapi-schema/flat-union-discriminator-bad-name.out
diff --git a/tests/qapi-schema/flat-union-empty.err b/tests/qapi-schema/flat-union-empty.err
index 15754f54eb..fedbc0d1cf 100644
--- a/tests/qapi-schema/flat-union-empty.err
+++ b/tests/qapi-schema/flat-union-empty.err
@@ -1 +1 @@
-tests/qapi-schema/flat-union-empty.json:4: Union 'Union' cannot have empty 'data'
+tests/qapi-schema/flat-union-empty.json:4: Union 'Union' has no branches
diff --git a/tests/qapi-schema/flat-union-empty.json b/tests/qapi-schema/flat-union-empty.json
index 77f1d9abfb..83e1cc7b96 100644
--- a/tests/qapi-schema/flat-union-empty.json
+++ b/tests/qapi-schema/flat-union-empty.json
@@ -1,4 +1,4 @@
-# flat unions cannot be empty
+# flat union discriminator cannot be empty
{ 'enum': 'Empty', 'data': [ ] }
{ 'struct': 'Base', 'data': { 'type': 'Empty' } }
{ 'union': 'Union', 'base': 'Base', 'discriminator': 'type', 'data': { } }
diff --git a/tests/qapi-schema/flat-union-invalid-discriminator.err b/tests/qapi-schema/flat-union-invalid-discriminator.err
index 5f4055614e..495d5a520e 100644
--- a/tests/qapi-schema/flat-union-invalid-discriminator.err
+++ b/tests/qapi-schema/flat-union-invalid-discriminator.err
@@ -1 +1 @@
-tests/qapi-schema/flat-union-invalid-discriminator.json:13: Discriminator 'enum_wrong' is not a member of base struct 'TestBase'
+tests/qapi-schema/flat-union-invalid-discriminator.json:10: Discriminator 'enum_wrong' is not a member of 'base'
diff --git a/tests/qapi-schema/flat-union-invalid-discriminator.json b/tests/qapi-schema/flat-union-invalid-discriminator.json
index 48b94c3a4d..c4fce97362 100644
--- a/tests/qapi-schema/flat-union-invalid-discriminator.json
+++ b/tests/qapi-schema/flat-union-invalid-discriminator.json
@@ -1,9 +1,6 @@
{ 'enum': 'TestEnum',
'data': [ 'value1', 'value2' ] }
-{ 'struct': 'TestBase',
- 'data': { 'enum1': 'TestEnum' } }
-
{ 'struct': 'TestTypeA',
'data': { 'string': 'str' } }
@@ -11,7 +8,7 @@
'data': { 'integer': 'int' } }
{ 'union': 'TestUnion',
- 'base': 'TestBase',
+ 'base': { 'enum1': 'TestEnum' },
'discriminator': 'enum_wrong',
'data': { 'value1': 'TestTypeA',
'value2': 'TestTypeB' } }
diff --git a/tests/qapi-schema/flat-union-invalid-if-discriminator.err b/tests/qapi-schema/flat-union-invalid-if-discriminator.err
index 0c94c9860d..cc5c3fb80b 100644
--- a/tests/qapi-schema/flat-union-invalid-if-discriminator.err
+++ b/tests/qapi-schema/flat-union-invalid-if-discriminator.err
@@ -1 +1 @@
-tests/qapi-schema/flat-union-invalid-if-discriminator.json:13: The discriminator TestBase.enum1 for union TestUnion must not be conditional
+tests/qapi-schema/flat-union-invalid-if-discriminator.json:10: The discriminator 'enum1' for union TestUnion must not be conditional
diff --git a/tests/qapi-schema/flat-union-invalid-if-discriminator.json b/tests/qapi-schema/flat-union-invalid-if-discriminator.json
index 618ec36396..e49992b798 100644
--- a/tests/qapi-schema/flat-union-invalid-if-discriminator.json
+++ b/tests/qapi-schema/flat-union-invalid-if-discriminator.json
@@ -1,9 +1,6 @@
{ 'enum': 'TestEnum',
'data': [ 'value1', 'value2' ] }
-{ 'struct': 'TestBase',
- 'data': { 'enum1': { 'type': 'TestEnum', 'if': 'FOO' } } }
-
{ 'struct': 'TestTypeA',
'data': { 'string': 'str' } }
@@ -11,7 +8,7 @@
'data': { 'integer': 'int' } }
{ 'union': 'TestUnion',
- 'base': 'TestBase',
+ 'base': { 'enum1': { 'type': 'TestEnum', 'if': 'FOO' } },
'discriminator': 'enum1',
'data': { 'value1': 'TestTypeA',
'value2': 'TestTypeB' } }
diff --git a/tests/qapi-schema/flat-union-optional-discriminator.err b/tests/qapi-schema/flat-union-optional-discriminator.err
index aaabedb3bd..45f5407c34 100644
--- a/tests/qapi-schema/flat-union-optional-discriminator.err
+++ b/tests/qapi-schema/flat-union-optional-discriminator.err
@@ -1 +1 @@
-tests/qapi-schema/flat-union-optional-discriminator.json:6: Discriminator of flat union 'MyUnion' does not allow optional name '*switch'
+tests/qapi-schema/flat-union-optional-discriminator.json:7: Discriminator 'switch' is not a member of 'base'
diff --git a/tests/qapi-schema/flat-union-optional-discriminator.json b/tests/qapi-schema/flat-union-optional-discriminator.json
index 08a8f7ef8b..143ab23a0d 100644
--- a/tests/qapi-schema/flat-union-optional-discriminator.json
+++ b/tests/qapi-schema/flat-union-optional-discriminator.json
@@ -1,10 +1,11 @@
# we require the discriminator to be non-optional
+# FIXME reports "discriminator 'switch' is not a member of base struct 'Base'"
{ 'enum': 'Enum', 'data': [ 'one', 'two' ] }
{ 'struct': 'Base',
'data': { '*switch': 'Enum' } }
{ 'struct': 'Branch', 'data': { 'name': 'str' } }
{ 'union': 'MyUnion',
'base': 'Base',
- 'discriminator': '*switch',
+ 'discriminator': 'switch',
'data': { 'one': 'Branch',
'two': 'Branch' } }
diff --git a/tests/qapi-schema/funny-char.err b/tests/qapi-schema/funny-char.err
index bfc890cd9f..139ecf4eb8 100644
--- a/tests/qapi-schema/funny-char.err
+++ b/tests/qapi-schema/funny-char.err
@@ -1 +1 @@
-tests/qapi-schema/funny-char.json:2:36: Stray ";"
+tests/qapi-schema/funny-char.json:2:36: Stray ';'
diff --git a/tests/qapi-schema/funny-word.err b/tests/qapi-schema/funny-word.err
new file mode 100644
index 0000000000..af92fe2551
--- /dev/null
+++ b/tests/qapi-schema/funny-word.err
@@ -0,0 +1 @@
+tests/qapi-schema/funny-word.json:1:3: Stray 'command'
diff --git a/tests/qapi-schema/escape-too-big.exit b/tests/qapi-schema/funny-word.exit
index d00491fd7e..d00491fd7e 100644
--- a/tests/qapi-schema/escape-too-big.exit
+++ b/tests/qapi-schema/funny-word.exit
diff --git a/tests/qapi-schema/funny-word.json b/tests/qapi-schema/funny-word.json
new file mode 100644
index 0000000000..1153b9f12f
--- /dev/null
+++ b/tests/qapi-schema/funny-word.json
@@ -0,0 +1 @@
+{ command: 'foo' }
diff --git a/tests/qapi-schema/escape-too-big.out b/tests/qapi-schema/funny-word.out
index e69de29bb2..e69de29bb2 100644
--- a/tests/qapi-schema/escape-too-big.out
+++ b/tests/qapi-schema/funny-word.out
diff --git a/tests/qapi-schema/ident-with-escape.err b/tests/qapi-schema/ident-with-escape.err
index e69de29bb2..5517dcb4b1 100644
--- a/tests/qapi-schema/ident-with-escape.err
+++ b/tests/qapi-schema/ident-with-escape.err
@@ -0,0 +1 @@
+tests/qapi-schema/ident-with-escape.json:3:3: Unknown escape \u
diff --git a/tests/qapi-schema/ident-with-escape.exit b/tests/qapi-schema/ident-with-escape.exit
index 573541ac97..d00491fd7e 100644
--- a/tests/qapi-schema/ident-with-escape.exit
+++ b/tests/qapi-schema/ident-with-escape.exit
@@ -1 +1 @@
-0
+1
diff --git a/tests/qapi-schema/ident-with-escape.json b/tests/qapi-schema/ident-with-escape.json
index 56617501e7..76b4503d95 100644
--- a/tests/qapi-schema/ident-with-escape.json
+++ b/tests/qapi-schema/ident-with-escape.json
@@ -1,4 +1,4 @@
-# we allow escape sequences in strings, if they map back to ASCII
+# we don't recognize any \ escapes other than \\ (tested elsewhere)
# { 'command': 'fooA', 'data': { 'bar1': 'str' } }
{ 'c\u006fmmand': '\u0066\u006f\u006FA',
'd\u0061ta': { '\u0062\u0061\u00721': '\u0073\u0074\u0072' } }
diff --git a/tests/qapi-schema/ident-with-escape.out b/tests/qapi-schema/ident-with-escape.out
index 39754eba8c..e69de29bb2 100644
--- a/tests/qapi-schema/ident-with-escape.out
+++ b/tests/qapi-schema/ident-with-escape.out
@@ -1,16 +0,0 @@
-module None
-object q_empty
-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
-command fooA q_obj_fooA-arg -> None
- gen=True success_response=True boxed=False oob=False preconfig=False
diff --git a/tests/qapi-schema/include-before-err.err b/tests/qapi-schema/include-before-err.err
index 55652751e1..2b26322170 100644
--- a/tests/qapi-schema/include-before-err.err
+++ b/tests/qapi-schema/include-before-err.err
@@ -1 +1 @@
-tests/qapi-schema/include-before-err.json:2:13: Expected ":"
+tests/qapi-schema/include-before-err.json:2:13: Expected ':'
diff --git a/tests/qapi-schema/include-format-err.err b/tests/qapi-schema/include-format-err.err
deleted file mode 100644
index 721ff4eccc..0000000000
--- a/tests/qapi-schema/include-format-err.err
+++ /dev/null
@@ -1 +0,0 @@
-tests/qapi-schema/include-format-err.json:1: Invalid 'include' directive
diff --git a/tests/qapi-schema/include-format-err.json b/tests/qapi-schema/include-format-err.json
deleted file mode 100644
index 44980f026f..0000000000
--- a/tests/qapi-schema/include-format-err.json
+++ /dev/null
@@ -1,2 +0,0 @@
-{ 'include': 'include-simple-sub.json',
- 'foo': 'bar' }
diff --git a/tests/qapi-schema/include-nested-err.err b/tests/qapi-schema/include-nested-err.err
index 1b7b22706b..aec6207eb0 100644
--- a/tests/qapi-schema/include-nested-err.err
+++ b/tests/qapi-schema/include-nested-err.err
@@ -1,2 +1,2 @@
In file included from tests/qapi-schema/include-nested-err.json:1:
-tests/qapi-schema/missing-colon.json:1:10: Expected ":"
+tests/qapi-schema/missing-colon.json:1:10: Expected ':'
diff --git a/tests/qapi-schema/leading-comma-list.err b/tests/qapi-schema/leading-comma-list.err
index f5c870bb9c..e021e42ad9 100644
--- a/tests/qapi-schema/leading-comma-list.err
+++ b/tests/qapi-schema/leading-comma-list.err
@@ -1 +1 @@
-tests/qapi-schema/leading-comma-list.json:2:13: Expected "{", "[", "]", string, boolean or "null"
+tests/qapi-schema/leading-comma-list.json:2:13: Expected '{', '[', ']', string, boolean or 'null'
diff --git a/tests/qapi-schema/leading-comma-object.err b/tests/qapi-schema/leading-comma-object.err
index f767b95544..3852f123d2 100644
--- a/tests/qapi-schema/leading-comma-object.err
+++ b/tests/qapi-schema/leading-comma-object.err
@@ -1 +1 @@
-tests/qapi-schema/leading-comma-object.json:1:3: Expected string or "}"
+tests/qapi-schema/leading-comma-object.json:1:3: Expected string or '}'
diff --git a/tests/qapi-schema/missing-colon.err b/tests/qapi-schema/missing-colon.err
index d9d66b377a..a255e51918 100644
--- a/tests/qapi-schema/missing-colon.err
+++ b/tests/qapi-schema/missing-colon.err
@@ -1 +1 @@
-tests/qapi-schema/missing-colon.json:1:10: Expected ":"
+tests/qapi-schema/missing-colon.json:1:10: Expected ':'
diff --git a/tests/qapi-schema/missing-comma-list.err b/tests/qapi-schema/missing-comma-list.err
index e73d2770d6..df3f553f39 100644
--- a/tests/qapi-schema/missing-comma-list.err
+++ b/tests/qapi-schema/missing-comma-list.err
@@ -1 +1 @@
-tests/qapi-schema/missing-comma-list.json:2:20: Expected "," or "]"
+tests/qapi-schema/missing-comma-list.json:2:20: Expected ',' or ']'
diff --git a/tests/qapi-schema/missing-comma-object.err b/tests/qapi-schema/missing-comma-object.err
index 52b3a8a1ec..0f691b8ddd 100644
--- a/tests/qapi-schema/missing-comma-object.err
+++ b/tests/qapi-schema/missing-comma-object.err
@@ -1 +1 @@
-tests/qapi-schema/missing-comma-object.json:2:3: Expected "," or "}"
+tests/qapi-schema/missing-comma-object.json:2:3: Expected ',' or '}'
diff --git a/tests/qapi-schema/non-objects.err b/tests/qapi-schema/non-objects.err
index 334f0c91ae..a972abd937 100644
--- a/tests/qapi-schema/non-objects.err
+++ b/tests/qapi-schema/non-objects.err
@@ -1 +1 @@
-tests/qapi-schema/non-objects.json:1:1: Expected "{"
+tests/qapi-schema/non-objects.json:1:1: Expected '{'
diff --git a/tests/qapi-schema/pragma-name-case-whitelist-crap.json b/tests/qapi-schema/pragma-name-case-whitelist-crap.json
index 58382bf4e4..734e1c617b 100644
--- a/tests/qapi-schema/pragma-name-case-whitelist-crap.json
+++ b/tests/qapi-schema/pragma-name-case-whitelist-crap.json
@@ -1,3 +1,3 @@
# 'name-case-whitelist' must be list of strings
-{ 'pragma': { 'name-case-whitelist': null } }
+{ 'pragma': { 'name-case-whitelist': false } }
diff --git a/tests/qapi-schema/pragma-non-dict.err b/tests/qapi-schema/pragma-non-dict.err
index 75bc335aea..b358261050 100644
--- a/tests/qapi-schema/pragma-non-dict.err
+++ b/tests/qapi-schema/pragma-non-dict.err
@@ -1 +1 @@
-tests/qapi-schema/pragma-non-dict.json:3: Value of 'pragma' must be a dictionary
+tests/qapi-schema/pragma-non-dict.json:3: Value of 'pragma' must be an object
diff --git a/tests/qapi-schema/pragma-unknown.err b/tests/qapi-schema/pragma-unknown.err
new file mode 100644
index 0000000000..6ef2058316
--- /dev/null
+++ b/tests/qapi-schema/pragma-unknown.err
@@ -0,0 +1 @@
+tests/qapi-schema/pragma-unknown.json:1: Unknown pragma 'no-such-pragma'
diff --git a/tests/qapi-schema/escape-too-short.exit b/tests/qapi-schema/pragma-unknown.exit
index d00491fd7e..d00491fd7e 100644
--- a/tests/qapi-schema/escape-too-short.exit
+++ b/tests/qapi-schema/pragma-unknown.exit
diff --git a/tests/qapi-schema/pragma-unknown.json b/tests/qapi-schema/pragma-unknown.json
new file mode 100644
index 0000000000..c51bbbb53f
--- /dev/null
+++ b/tests/qapi-schema/pragma-unknown.json
@@ -0,0 +1 @@
+{ 'pragma': { 'no-such-pragma': false } }
diff --git a/tests/qapi-schema/escape-too-short.out b/tests/qapi-schema/pragma-unknown.out
index e69de29bb2..e69de29bb2 100644
--- a/tests/qapi-schema/escape-too-short.out
+++ b/tests/qapi-schema/pragma-unknown.out
diff --git a/tests/qapi-schema/qapi-schema-test.json b/tests/qapi-schema/qapi-schema-test.json
index c6d59acc3e..75c42eb0e3 100644
--- a/tests/qapi-schema/qapi-schema-test.json
+++ b/tests/qapi-schema/qapi-schema-test.json
@@ -25,6 +25,11 @@
{ 'struct': 'Empty1', 'data': { } }
{ 'struct': 'Empty2', 'base': 'Empty1', 'data': { } }
+# Likewise for an empty flat union
+{ 'union': 'Union',
+ 'base': { 'type': 'EnumOne' }, 'discriminator': 'type',
+ 'data': { } }
+
{ 'command': 'user_def_cmd0', 'data': 'Empty2', 'returns': 'Empty2' }
# for testing override of default naming heuristic
@@ -149,6 +154,7 @@
{ 'command': 'guest-sync', 'data': { 'arg': 'any' }, 'returns': 'any' }
{ 'command': 'boxed-struct', 'boxed': true, 'data': 'UserDefZero' }
{ 'command': 'boxed-union', 'data': 'UserDefListUnion', 'boxed': true }
+{ 'command': 'boxed-empty', 'boxed': true, 'data': 'Empty1' }
# Smoke test on out-of-band and allow-preconfig-test
{ 'command': 'test-flags-command', 'allow-oob': true, 'allow-preconfig': true }
@@ -180,23 +186,26 @@
{ 'event': 'EVENT_D',
'data': { 'a' : 'EventStructOne', 'b' : 'str', '*c': 'str', '*enum3': 'EnumOne' } }
{ 'event': 'EVENT_E', 'boxed': true, 'data': 'UserDefZero' }
-{ 'event': 'EVENT_F', 'boxed': true, 'data': 'UserDefAlternate' }
+{ 'event': 'EVENT_F', 'boxed': true, 'data': 'UserDefFlatUnion' }
+{ 'event': 'EVENT_G', 'boxed': true, 'data': 'Empty1' }
# test that we correctly compile downstream extensions, as well as munge
# ticklish names
+# also test union and alternate with just one branch
{ 'enum': '__org.qemu_x-Enum', 'data': [ '__org.qemu_x-value' ] }
{ 'struct': '__org.qemu_x-Base',
'data': { '__org.qemu_x-member1': '__org.qemu_x-Enum' } }
{ 'struct': '__org.qemu_x-Struct', 'base': '__org.qemu_x-Base',
'data': { '__org.qemu_x-member2': 'str', '*wchar-t': 'int' } }
{ 'union': '__org.qemu_x-Union1', 'data': { '__org.qemu_x-branch': 'str' } }
+{ 'alternate': '__org.qemu_x-Alt1', 'data': { '__org.qemu_x-branch': 'str' } }
{ 'struct': '__org.qemu_x-Struct2',
'data': { 'array': ['__org.qemu_x-Union1'] } }
{ 'union': '__org.qemu_x-Union2', 'base': '__org.qemu_x-Base',
'discriminator': '__org.qemu_x-member1',
'data': { '__org.qemu_x-value': '__org.qemu_x-Struct2' } }
{ 'alternate': '__org.qemu_x-Alt',
- 'data': { '__org.qemu_x-branch': 'str', 'b': '__org.qemu_x-Base' } }
+ 'data': { '__org.qemu_x-branch': '__org.qemu_x-Base' } }
{ 'event': '__ORG.QEMU_X-EVENT', 'data': '__org.qemu_x-Struct' }
{ 'command': '__org.qemu_x-command',
'data': { 'a': ['__org.qemu_x-Enum'], 'b': ['__org.qemu_x-Struct'],
diff --git a/tests/qapi-schema/qapi-schema-test.out b/tests/qapi-schema/qapi-schema-test.out
index 85d510bc00..98031da96f 100644
--- a/tests/qapi-schema/qapi-schema-test.out
+++ b/tests/qapi-schema/qapi-schema-test.out
@@ -23,6 +23,15 @@ enum MyEnum
object Empty1
object Empty2
base Empty1
+object q_obj_Union-base
+ member type: EnumOne optional=False
+object Union
+ base q_obj_Union-base
+ tag type
+ case value1: q_empty
+ case value2: q_empty
+ case value3: q_empty
+ case value4: q_empty
command user_def_cmd0 Empty2 -> Empty2
gen=True success_response=True boxed=False oob=False preconfig=False
enum QEnumTwo
@@ -221,6 +230,8 @@ command boxed-struct UserDefZero -> None
gen=True success_response=True boxed=True oob=False preconfig=False
command boxed-union UserDefListUnion -> None
gen=True success_response=True boxed=True oob=False preconfig=False
+command boxed-empty Empty1 -> None
+ gen=True success_response=True boxed=True oob=False preconfig=False
command test-flags-command None -> None
gen=True success_response=True boxed=False oob=True preconfig=True
object UserDefOptions
@@ -252,7 +263,9 @@ event EVENT_D q_obj_EVENT_D-arg
boxed=False
event EVENT_E UserDefZero
boxed=True
-event EVENT_F UserDefAlternate
+event EVENT_F UserDefFlatUnion
+ boxed=True
+event EVENT_G Empty1
boxed=True
enum __org.qemu_x-Enum
member __org.qemu_x-value
@@ -270,6 +283,9 @@ object __org.qemu_x-Union1
member type: __org.qemu_x-Union1Kind optional=False
tag type
case __org.qemu_x-branch: q_obj_str-wrapper
+alternate __org.qemu_x-Alt1
+ tag type
+ case __org.qemu_x-branch: str
array __org.qemu_x-Union1List __org.qemu_x-Union1
object __org.qemu_x-Struct2
member array: __org.qemu_x-Union1List optional=False
@@ -279,8 +295,7 @@ object __org.qemu_x-Union2
case __org.qemu_x-value: __org.qemu_x-Struct2
alternate __org.qemu_x-Alt
tag type
- case __org.qemu_x-branch: str
- case b: __org.qemu_x-Base
+ case __org.qemu_x-branch: __org.qemu_x-Base
event __ORG.QEMU_X-EVENT __org.qemu_x-Struct
boxed=False
array __org.qemu_x-EnumList __org.qemu_x-Enum
diff --git a/tests/qapi-schema/quoted-structural-chars.err b/tests/qapi-schema/quoted-structural-chars.err
index 9b183841dd..6e036c8044 100644
--- a/tests/qapi-schema/quoted-structural-chars.err
+++ b/tests/qapi-schema/quoted-structural-chars.err
@@ -1 +1 @@
-tests/qapi-schema/quoted-structural-chars.json:1:1: Expected "{"
+tests/qapi-schema/quoted-structural-chars.json:1:1: Expected '{'
diff --git a/tests/qapi-schema/string-code-point-127.err b/tests/qapi-schema/string-code-point-127.err
new file mode 100644
index 0000000000..c310910c23
--- /dev/null
+++ b/tests/qapi-schema/string-code-point-127.err
@@ -0,0 +1 @@
+tests/qapi-schema/string-code-point-127.json:2:14: Funny character in string
diff --git a/tests/qapi-schema/include-format-err.exit b/tests/qapi-schema/string-code-point-127.exit
index d00491fd7e..d00491fd7e 100644
--- a/tests/qapi-schema/include-format-err.exit
+++ b/tests/qapi-schema/string-code-point-127.exit
diff --git a/tests/qapi-schema/string-code-point-127.json b/tests/qapi-schema/string-code-point-127.json
new file mode 100644
index 0000000000..480318a69f
--- /dev/null
+++ b/tests/qapi-schema/string-code-point-127.json
@@ -0,0 +1,2 @@
+# We accept printable ASCII: code points 32..126. Test code point 127:
+{ 'command': '' }
diff --git a/tests/qapi-schema/include-format-err.out b/tests/qapi-schema/string-code-point-127.out
index e69de29bb2..e69de29bb2 100644
--- a/tests/qapi-schema/include-format-err.out
+++ b/tests/qapi-schema/string-code-point-127.out
diff --git a/tests/qapi-schema/string-code-point-31.err b/tests/qapi-schema/string-code-point-31.err
new file mode 100644
index 0000000000..45797928d9
--- /dev/null
+++ b/tests/qapi-schema/string-code-point-31.err
@@ -0,0 +1 @@
+tests/qapi-schema/string-code-point-31.json:2:14: Funny character in string
diff --git a/tests/qapi-schema/unicode-str.exit b/tests/qapi-schema/string-code-point-31.exit
index d00491fd7e..d00491fd7e 100644
--- a/tests/qapi-schema/unicode-str.exit
+++ b/tests/qapi-schema/string-code-point-31.exit
diff --git a/tests/qapi-schema/string-code-point-31.json b/tests/qapi-schema/string-code-point-31.json
new file mode 100644
index 0000000000..f186cbd720
--- /dev/null
+++ b/tests/qapi-schema/string-code-point-31.json
@@ -0,0 +1,2 @@
+# We accept printable ASCII: code points 32..126. Test code point 127:
+{ 'command': '' }
diff --git a/tests/qapi-schema/unicode-str.out b/tests/qapi-schema/string-code-point-31.out
index e69de29bb2..e69de29bb2 100644
--- a/tests/qapi-schema/unicode-str.out
+++ b/tests/qapi-schema/string-code-point-31.out
diff --git a/tests/qapi-schema/struct-data-invalid.err b/tests/qapi-schema/struct-data-invalid.err
index 6644f4c2ad..4bf5bcc255 100644
--- a/tests/qapi-schema/struct-data-invalid.err
+++ b/tests/qapi-schema/struct-data-invalid.err
@@ -1 +1 @@
-tests/qapi-schema/struct-data-invalid.json:1: 'data' for struct 'foo' should be a dictionary or type name
+tests/qapi-schema/struct-data-invalid.json:1: 'data' for struct 'foo' should be an object or type name
diff --git a/tests/qapi-schema/struct-member-if-invalid.err b/tests/qapi-schema/struct-member-if-invalid.err
new file mode 100644
index 0000000000..bfd65db97b
--- /dev/null
+++ b/tests/qapi-schema/struct-member-if-invalid.err
@@ -0,0 +1 @@
+tests/qapi-schema/struct-member-if-invalid.json:2: 'if' condition must be a string or a list of strings
diff --git a/tests/qapi-schema/struct-member-if-invalid.exit b/tests/qapi-schema/struct-member-if-invalid.exit
new file mode 100644
index 0000000000..d00491fd7e
--- /dev/null
+++ b/tests/qapi-schema/struct-member-if-invalid.exit
@@ -0,0 +1 @@
+1
diff --git a/tests/qapi-schema/struct-member-if-invalid.json b/tests/qapi-schema/struct-member-if-invalid.json
new file mode 100644
index 0000000000..35078bd660
--- /dev/null
+++ b/tests/qapi-schema/struct-member-if-invalid.json
@@ -0,0 +1,3 @@
+# Cover member with invalid 'if'
+{ 'struct': 'Stru',
+ 'data': { 'member': { 'type': 'int', 'if': true } } }
diff --git a/tests/qapi-schema/struct-member-if-invalid.out b/tests/qapi-schema/struct-member-if-invalid.out
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/tests/qapi-schema/struct-member-if-invalid.out
diff --git a/tests/qapi-schema/trailing-comma-list.err b/tests/qapi-schema/trailing-comma-list.err
index 212e14ae28..601c4537c3 100644
--- a/tests/qapi-schema/trailing-comma-list.err
+++ b/tests/qapi-schema/trailing-comma-list.err
@@ -1 +1 @@
-tests/qapi-schema/trailing-comma-list.json:2:36: Expected "{", "[", string, boolean or "null"
+tests/qapi-schema/trailing-comma-list.json:2:36: Expected '{', '[', string, boolean or 'null'
diff --git a/tests/qapi-schema/unclosed-list.err b/tests/qapi-schema/unclosed-list.err
index fb41a86abd..1cc3a094fe 100644
--- a/tests/qapi-schema/unclosed-list.err
+++ b/tests/qapi-schema/unclosed-list.err
@@ -1 +1 @@
-tests/qapi-schema/unclosed-list.json:1:20: Expected "," or "]"
+tests/qapi-schema/unclosed-list.json:1:20: Expected ',' or ']'
diff --git a/tests/qapi-schema/unclosed-object.err b/tests/qapi-schema/unclosed-object.err
index db3deedd63..fd1a86b704 100644
--- a/tests/qapi-schema/unclosed-object.err
+++ b/tests/qapi-schema/unclosed-object.err
@@ -1 +1 @@
-tests/qapi-schema/unclosed-object.json:1:21: Expected "," or "}"
+tests/qapi-schema/unclosed-object.json:1:21: Expected ',' or '}'
diff --git a/tests/qapi-schema/unicode-str.err b/tests/qapi-schema/unicode-str.err
deleted file mode 100644
index f621cd6448..0000000000
--- a/tests/qapi-schema/unicode-str.err
+++ /dev/null
@@ -1 +0,0 @@
-tests/qapi-schema/unicode-str.json:2: 'command' uses invalid name 'é'
diff --git a/tests/qapi-schema/unicode-str.json b/tests/qapi-schema/unicode-str.json
deleted file mode 100644
index 5253a1b9f3..0000000000
--- a/tests/qapi-schema/unicode-str.json
+++ /dev/null
@@ -1,2 +0,0 @@
-# we don't support full Unicode strings, yet
-{ 'command': 'é' }
diff --git a/tests/qapi-schema/union-base-empty.err b/tests/qapi-schema/union-base-empty.err
index 7695806d81..9453720ede 100644
--- a/tests/qapi-schema/union-base-empty.err
+++ b/tests/qapi-schema/union-base-empty.err
@@ -1 +1 @@
-tests/qapi-schema/union-base-empty.json:5: Discriminator 'type' is not a member of base struct 'Empty'
+tests/qapi-schema/union-base-empty.json:5: Discriminator 'type' is not a member of 'base'
diff --git a/tests/qapi-schema/union-branch-if-invalid.err b/tests/qapi-schema/union-branch-if-invalid.err
new file mode 100644
index 0000000000..607edee382
--- /dev/null
+++ b/tests/qapi-schema/union-branch-if-invalid.err
@@ -0,0 +1 @@
+tests/qapi-schema/union-branch-if-invalid.json:4: 'if' condition '' makes no sense
diff --git a/tests/qapi-schema/union-branch-if-invalid.exit b/tests/qapi-schema/union-branch-if-invalid.exit
new file mode 100644
index 0000000000..d00491fd7e
--- /dev/null
+++ b/tests/qapi-schema/union-branch-if-invalid.exit
@@ -0,0 +1 @@
+1
diff --git a/tests/qapi-schema/union-branch-if-invalid.json b/tests/qapi-schema/union-branch-if-invalid.json
new file mode 100644
index 0000000000..46d4239af6
--- /dev/null
+++ b/tests/qapi-schema/union-branch-if-invalid.json
@@ -0,0 +1,6 @@
+# Cover branch with invalid 'if'
+{ 'enum': 'Branches', 'data': ['branch1'] }
+{ 'struct': 'Stru', 'data': { 'member': 'str' } }
+{ 'union': 'Uni',
+ 'base': { 'tag': 'Branches' }, 'discriminator': 'tag',
+ 'data': { 'branch1': { 'type': 'Stru', 'if': [''] } } }
diff --git a/tests/qapi-schema/union-branch-if-invalid.out b/tests/qapi-schema/union-branch-if-invalid.out
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/tests/qapi-schema/union-branch-if-invalid.out
diff --git a/tests/qapi-schema/union-empty.err b/tests/qapi-schema/union-empty.err
index 12c20221bd..d4241a38a2 100644
--- a/tests/qapi-schema/union-empty.err
+++ b/tests/qapi-schema/union-empty.err
@@ -1 +1 @@
-tests/qapi-schema/union-empty.json:2: Union 'Union' cannot have empty 'data'
+tests/qapi-schema/union-empty.json:2: Union 'Union' has no branches
diff --git a/tests/qapi-schema/union-empty.json b/tests/qapi-schema/union-empty.json
index 1f0b13ca21..df3e5e639a 100644
--- a/tests/qapi-schema/union-empty.json
+++ b/tests/qapi-schema/union-empty.json
@@ -1,2 +1,2 @@
-# unions cannot be empty
+# simple unions cannot be empty
{ 'union': 'Union', 'data': { } }
diff --git a/tests/qapi-schema/unknown-escape.json b/tests/qapi-schema/unknown-escape.json
index 8e6891e52a..8372e8024f 100644
--- a/tests/qapi-schema/unknown-escape.json
+++ b/tests/qapi-schema/unknown-escape.json
@@ -1,3 +1,3 @@
-# we only recognize JSON escape sequences, plus our \' extension (no \x)
+# we only recognize \\
# { 'command': 'foo', 'data': {} }
{ 'command': 'foo', 'dat\x61':{} }
diff --git a/tests/test-qmp-cmds.c b/tests/test-qmp-cmds.c
index ab389f42da..36fdf5b115 100644
--- a/tests/test-qmp-cmds.c
+++ b/tests/test-qmp-cmds.c
@@ -97,6 +97,10 @@ void qmp_boxed_union(UserDefListUnion *arg, Error **errp)
{
}
+void qmp_boxed_empty(Empty1 *arg, Error **errp)
+{
+}
+
__org_qemu_x_Union1 *qmp___org_qemu_x_command(__org_qemu_x_EnumList *a,
__org_qemu_x_StructList *b,
__org_qemu_x_Union2 *c,