diff options
Diffstat (limited to 'tests')
95 files changed, 590 insertions, 179 deletions
diff --git a/tests/Makefile b/tests/Makefile index dbd32a6..cb221de 100644 --- a/tests/Makefile +++ b/tests/Makefile @@ -224,52 +224,125 @@ check-qtest-xtensaeb-y = $(check-qtest-xtensa-y) check-qtest-generic-y += tests/qom-test$(EXESUF) -check-qapi-schema-y := $(addprefix tests/qapi-schema/, \ - comments.json empty.json enum-empty.json enum-missing-data.json \ - enum-wrong-data.json enum-int-member.json enum-dict-member.json \ - enum-clash-member.json enum-max-member.json enum-union-clash.json \ - enum-bad-name.json enum-bad-prefix.json \ - funny-char.json indented-expr.json \ - missing-type.json bad-ident.json ident-with-escape.json \ - escape-outside-string.json unknown-escape.json \ - escape-too-short.json escape-too-big.json unicode-str.json \ - double-type.json bad-base.json bad-type-bool.json bad-type-int.json \ - bad-type-dict.json double-data.json unknown-expr-key.json \ - redefined-type.json redefined-command.json redefined-builtin.json \ - redefined-event.json command-int.json bad-data.json event-max.json \ - type-bypass-bad-gen.json \ - args-invalid.json \ - args-array-empty.json args-array-unknown.json args-int.json \ - args-unknown.json args-member-unknown.json args-member-array.json \ - args-member-array-bad.json args-alternate.json args-union.json \ - args-any.json \ - returns-array-bad.json returns-int.json returns-dict.json \ - returns-unknown.json returns-alternate.json returns-whitelist.json \ - missing-colon.json missing-comma-list.json missing-comma-object.json \ - struct-data-invalid.json struct-member-invalid.json \ - nested-struct-data.json non-objects.json \ - qapi-schema-test.json quoted-structural-chars.json \ - leading-comma-list.json leading-comma-object.json \ - trailing-comma-list.json trailing-comma-object.json \ - unclosed-list.json unclosed-object.json unclosed-string.json \ - duplicate-key.json union-invalid-base.json union-bad-branch.json \ - union-optional-branch.json union-unknown.json union-max.json \ - flat-union-optional-discriminator.json flat-union-no-base.json \ - flat-union-invalid-discriminator.json flat-union-inline.json \ - flat-union-invalid-branch-key.json flat-union-reverse-define.json \ - flat-union-string-discriminator.json union-base-no-discriminator.json \ - flat-union-bad-discriminator.json flat-union-bad-base.json \ - flat-union-base-any.json \ - flat-union-array-branch.json flat-union-int-branch.json \ - flat-union-base-union.json flat-union-branch-clash.json \ - alternate-nested.json alternate-unknown.json alternate-clash.json \ - alternate-good.json alternate-base.json alternate-array.json \ - alternate-conflict-string.json alternate-conflict-dict.json \ - include-simple.json include-relpath.json include-format-err.json \ - include-non-file.json include-no-file.json include-before-err.json \ - include-nested-err.json include-self-cycle.json include-cycle.json \ - include-repetition.json event-nest-struct.json event-case.json \ - struct-base-clash.json struct-base-clash-deep.json ) +qapi-schema += alternate-array.json +qapi-schema += alternate-base.json +qapi-schema += alternate-clash.json +qapi-schema += alternate-conflict-dict.json +qapi-schema += alternate-conflict-string.json +qapi-schema += alternate-empty.json +qapi-schema += alternate-nested.json +qapi-schema += alternate-unknown.json +qapi-schema += args-alternate.json +qapi-schema += args-any.json +qapi-schema += args-array-empty.json +qapi-schema += args-array-unknown.json +qapi-schema += args-int.json +qapi-schema += args-invalid.json +qapi-schema += args-member-array-bad.json +qapi-schema += args-member-unknown.json +qapi-schema += args-name-clash.json +qapi-schema += args-union.json +qapi-schema += args-unknown.json +qapi-schema += bad-base.json +qapi-schema += bad-data.json +qapi-schema += bad-ident.json +qapi-schema += bad-type-bool.json +qapi-schema += bad-type-dict.json +qapi-schema += bad-type-int.json +qapi-schema += command-int.json +qapi-schema += comments.json +qapi-schema += double-data.json +qapi-schema += double-type.json +qapi-schema += duplicate-key.json +qapi-schema += empty.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-int-member.json +qapi-schema += enum-max-member.json +qapi-schema += enum-missing-data.json +qapi-schema += enum-union-clash.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-case.json +qapi-schema += event-max.json +qapi-schema += event-nest-struct.json +qapi-schema += flat-union-array-branch.json +qapi-schema += flat-union-bad-base.json +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-branch.json +qapi-schema += flat-union-clash-member.json +qapi-schema += flat-union-clash-type.json +qapi-schema += flat-union-empty.json +qapi-schema += flat-union-inline.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-no-base.json +qapi-schema += flat-union-optional-discriminator.json +qapi-schema += flat-union-string-discriminator.json +qapi-schema += funny-char.json +qapi-schema += ident-with-escape.json +qapi-schema += include-before-err.json +qapi-schema += include-cycle.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 +qapi-schema += include-relpath.json +qapi-schema += include-repetition.json +qapi-schema += include-self-cycle.json +qapi-schema += include-simple.json +qapi-schema += indented-expr.json +qapi-schema += leading-comma-list.json +qapi-schema += leading-comma-object.json +qapi-schema += missing-colon.json +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 += non-objects.json +qapi-schema += qapi-schema-test.json +qapi-schema += quoted-structural-chars.json +qapi-schema += redefined-builtin.json +qapi-schema += redefined-command.json +qapi-schema += redefined-event.json +qapi-schema += redefined-type.json +qapi-schema += returns-alternate.json +qapi-schema += returns-array-bad.json +qapi-schema += returns-dict.json +qapi-schema += returns-unknown.json +qapi-schema += returns-whitelist.json +qapi-schema += struct-base-clash-base.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.json +qapi-schema += trailing-comma-list.json +qapi-schema += trailing-comma-object.json +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-bad-branch.json +qapi-schema += union-base-no-discriminator.json +qapi-schema += union-clash-branches.json +qapi-schema += union-clash-data.json +qapi-schema += union-clash-type.json +qapi-schema += union-empty.json +qapi-schema += union-invalid-base.json +qapi-schema += union-max.json +qapi-schema += union-optional-branch.json +qapi-schema += union-unknown.json +qapi-schema += unknown-escape.json +qapi-schema += unknown-expr-key.json +check-qapi-schema-y := $(addprefix tests/qapi-schema/, $(qapi-schema)) GENERATED_HEADERS += tests/test-qapi-types.h tests/test-qapi-visit.h \ tests/test-qmp-commands.h tests/test-qapi-event.h \ diff --git a/tests/ds1338-test.c b/tests/ds1338-test.c index a7fb415..7d513d8 100644 --- a/tests/ds1338-test.c +++ b/tests/ds1338-test.c @@ -61,7 +61,7 @@ int main(int argc, char **argv) g_test_init(&argc, &argv, NULL); - s = qtest_start("-display none -machine imx25_pdk"); + s = qtest_start("-display none -machine imx25-pdk"); i2c = imx_i2c_create(IMX25_I2C_0_BASE); addr = DS1338_ADDR; diff --git a/tests/qapi-schema/alternate-clash.err b/tests/qapi-schema/alternate-clash.err index 51bea3e..a475ab6 100644 --- a/tests/qapi-schema/alternate-clash.err +++ b/tests/qapi-schema/alternate-clash.err @@ -1 +1 @@ -tests/qapi-schema/alternate-clash.json:2: Alternate 'Alt1' member 'ONE' clashes with 'one' +tests/qapi-schema/alternate-clash.json:7: Alternate 'Alt1' member 'a_b' clashes with 'a-b' diff --git a/tests/qapi-schema/alternate-clash.json b/tests/qapi-schema/alternate-clash.json index 3947935..6d73bc5 100644 --- a/tests/qapi-schema/alternate-clash.json +++ b/tests/qapi-schema/alternate-clash.json @@ -1,3 +1,8 @@ -# we detect C enum collisions in an alternate +# Alternate branch name collision +# Reject an alternate that would result in a collision in generated C +# names (this would try to generate two enum values 'ALT1_KIND_A_B'). +# TODO: In the future, if alternates are simplified to not generate +# the implicit Alt1Kind enum, we would still have a collision with the +# resulting C union trying to have two members named 'a_b'. { 'alternate': 'Alt1', - 'data': { 'one': 'str', 'ONE': 'int' } } + 'data': { 'a-b': 'str', 'a_b': 'int' } } diff --git a/tests/qapi-schema/alternate-good.err b/tests/qapi-schema/alternate-empty.err index e69de29..e69de29 100644 --- a/tests/qapi-schema/alternate-good.err +++ b/tests/qapi-schema/alternate-empty.err diff --git a/tests/qapi-schema/alternate-good.exit b/tests/qapi-schema/alternate-empty.exit index 573541a..573541a 100644 --- a/tests/qapi-schema/alternate-good.exit +++ b/tests/qapi-schema/alternate-empty.exit diff --git a/tests/qapi-schema/alternate-empty.json b/tests/qapi-schema/alternate-empty.json new file mode 100644 index 0000000..db3820f --- /dev/null +++ b/tests/qapi-schema/alternate-empty.json @@ -0,0 +1,2 @@ +# FIXME - alternates should list at least two types to be useful +{ 'alternate': 'Alt', 'data': { 'i': 'int' } } diff --git a/tests/qapi-schema/alternate-empty.out b/tests/qapi-schema/alternate-empty.out new file mode 100644 index 0000000..0f153b6 --- /dev/null +++ b/tests/qapi-schema/alternate-empty.out @@ -0,0 +1,4 @@ +object :empty +alternate Alt + case i: int +enum AltKind ['i'] diff --git a/tests/qapi-schema/alternate-good.json b/tests/qapi-schema/alternate-good.json deleted file mode 100644 index 3371770..0000000 --- a/tests/qapi-schema/alternate-good.json +++ /dev/null @@ -1,9 +0,0 @@ -# Working example of alternate -{ 'struct': 'Data', - 'data': { '*number': 'int', '*name': 'str' } } -{ 'enum': 'Enum', - 'data': [ 'hello', 'world' ] } -{ 'alternate': 'Alt', - 'data': { 'value': 'int', - 'string': 'Enum', - 'struct': 'Data' } } diff --git a/tests/qapi-schema/alternate-good.out b/tests/qapi-schema/alternate-good.out deleted file mode 100644 index 65af727..0000000 --- a/tests/qapi-schema/alternate-good.out +++ /dev/null @@ -1,10 +0,0 @@ -object :empty -alternate Alt - case value: int - case string: Enum - case struct: Data -enum AltKind ['value', 'string', 'struct'] -object Data - member number: int optional=True - member name: str optional=True -enum Enum ['hello', 'world'] diff --git a/tests/qapi-schema/alternate-nested.json b/tests/qapi-schema/alternate-nested.json index c4233b9..8e22186 100644 --- a/tests/qapi-schema/alternate-nested.json +++ b/tests/qapi-schema/alternate-nested.json @@ -2,4 +2,4 @@ { 'alternate': 'Alt1', 'data': { 'name': 'str', 'value': 'int' } } { 'alternate': 'Alt2', - 'data': { 'nested': 'Alt1' } } + 'data': { 'nested': 'Alt1', 'b': 'bool' } } diff --git a/tests/qapi-schema/alternate-unknown.json b/tests/qapi-schema/alternate-unknown.json index ad5c103..08c80dc 100644 --- a/tests/qapi-schema/alternate-unknown.json +++ b/tests/qapi-schema/alternate-unknown.json @@ -1,3 +1,3 @@ # we reject an alternate with unknown type in branch { 'alternate': 'Alt', - 'data': { 'unknown': 'MissingType' } } + 'data': { 'unknown': 'MissingType', 'i': 'int' } } diff --git a/tests/qapi-schema/args-member-array.json b/tests/qapi-schema/args-member-array.json deleted file mode 100644 index e6f7f5d..0000000 --- a/tests/qapi-schema/args-member-array.json +++ /dev/null @@ -1,4 +0,0 @@ -# valid array members -{ 'enum': 'abc', 'data': [ 'a', 'b', 'c' ] } -{ 'struct': 'def', 'data': { 'array': [ 'abc' ] } } -{ 'command': 'okay', 'data': { 'member1': [ 'int' ], 'member2': [ 'def' ] } } diff --git a/tests/qapi-schema/args-member-array.out b/tests/qapi-schema/args-member-array.out deleted file mode 100644 index b3b92df..0000000 --- a/tests/qapi-schema/args-member-array.out +++ /dev/null @@ -1,9 +0,0 @@ -object :empty -object :obj-okay-arg - member member1: intList optional=False - member member2: defList optional=False -enum abc ['a', 'b', 'c'] -object def - member array: abcList optional=False -command okay :obj-okay-arg -> None - gen=True success_response=True diff --git a/tests/qapi-schema/args-member-array.err b/tests/qapi-schema/args-name-clash.err index e69de29..e69de29 100644 --- a/tests/qapi-schema/args-member-array.err +++ b/tests/qapi-schema/args-name-clash.err diff --git a/tests/qapi-schema/args-member-array.exit b/tests/qapi-schema/args-name-clash.exit index 573541a..573541a 100644 --- a/tests/qapi-schema/args-member-array.exit +++ b/tests/qapi-schema/args-name-clash.exit diff --git a/tests/qapi-schema/args-name-clash.json b/tests/qapi-schema/args-name-clash.json new file mode 100644 index 0000000..9e8f889 --- /dev/null +++ b/tests/qapi-schema/args-name-clash.json @@ -0,0 +1,5 @@ +# C member name collision +# FIXME - This parses, but fails to compile, because the C struct is given +# two 'a_b' members. Either reject this at parse time, or munge the C names +# to avoid the collision. +{ 'command': 'oops', 'data': { 'a-b': 'str', 'a_b': 'str' } } diff --git a/tests/qapi-schema/args-name-clash.out b/tests/qapi-schema/args-name-clash.out new file mode 100644 index 0000000..9b2f6e4 --- /dev/null +++ b/tests/qapi-schema/args-name-clash.out @@ -0,0 +1,6 @@ +object :empty +object :obj-oops-arg + member a-b: str optional=False + member a_b: str optional=False +command oops :obj-oops-arg -> None + gen=True success_response=True diff --git a/tests/qapi-schema/duplicate-key.err b/tests/qapi-schema/duplicate-key.err index 768b276..6d02f83 100644 --- a/tests/qapi-schema/duplicate-key.err +++ b/tests/qapi-schema/duplicate-key.err @@ -1 +1 @@ -tests/qapi-schema/duplicate-key.json:2: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 1b55d88..14ac0e8 100644 --- a/tests/qapi-schema/duplicate-key.json +++ b/tests/qapi-schema/duplicate-key.json @@ -1,2 +1,3 @@ +# QAPI cannot include the same key more than once in any {} { 'key': 'value', 'key': 'value' } diff --git a/tests/qapi-schema/enum-empty.json b/tests/qapi-schema/enum-empty.json deleted file mode 100644 index 40d4e85..0000000 --- a/tests/qapi-schema/enum-empty.json +++ /dev/null @@ -1,2 +0,0 @@ -# An empty enum, although unusual, is currently acceptable -{ 'enum': 'MyEnum', 'data': [ ] } diff --git a/tests/qapi-schema/enum-empty.out b/tests/qapi-schema/enum-empty.out deleted file mode 100644 index a449d45..0000000 --- a/tests/qapi-schema/enum-empty.out +++ /dev/null @@ -1,2 +0,0 @@ -object :empty -enum MyEnum [] diff --git a/tests/qapi-schema/flat-union-bad-base.err b/tests/qapi-schema/flat-union-bad-base.err index f9c31b2..79b8a71 100644 --- a/tests/qapi-schema/flat-union-bad-base.err +++ b/tests/qapi-schema/flat-union-bad-base.err @@ -1 +1 @@ -tests/qapi-schema/flat-union-bad-base.json:9: Flat union 'TestUnion' must have a string base field +tests/qapi-schema/flat-union-bad-base.json:9: 'base' for union 'TestUnion' should be a type name diff --git a/tests/qapi-schema/flat-union-base-any.err b/tests/qapi-schema/flat-union-base-any.err index ad4d629..646f1c9 100644 --- a/tests/qapi-schema/flat-union-base-any.err +++ b/tests/qapi-schema/flat-union-base-any.err @@ -1 +1 @@ -tests/qapi-schema/flat-union-base-any.json:8: Base 'any' is not a valid struct +tests/qapi-schema/flat-union-base-any.json:8: 'base' for union 'TestUnion' cannot use built-in type 'any' diff --git a/tests/qapi-schema/flat-union-base-union.err b/tests/qapi-schema/flat-union-base-union.err index ede9859..f138395 100644 --- a/tests/qapi-schema/flat-union-base-union.err +++ b/tests/qapi-schema/flat-union-base-union.err @@ -1 +1 @@ -tests/qapi-schema/flat-union-base-union.json:11: Base 'UnionBase' is not a valid struct +tests/qapi-schema/flat-union-base-union.json:14: 'base' for union 'TestUnion' cannot use union type 'UnionBase' diff --git a/tests/qapi-schema/flat-union-base-union.json b/tests/qapi-schema/flat-union-base-union.json index 6a8ea68..98b4eba 100644 --- a/tests/qapi-schema/flat-union-base-union.json +++ b/tests/qapi-schema/flat-union-base-union.json @@ -1,4 +1,7 @@ -# we require the base to be a struct +# For now, we require the base to be a struct without variants +# TODO: It would be possible to allow a union as a base, as long as all +# permutations of QMP names exposed by base do not clash with any QMP +# member names added by local variants. { 'enum': 'TestEnum', 'data': [ 'value1', 'value2' ] } { 'struct': 'TestTypeA', diff --git a/tests/qapi-schema/flat-union-branch-clash.err b/tests/qapi-schema/flat-union-branch-clash.err deleted file mode 100644 index f112766..0000000 --- a/tests/qapi-schema/flat-union-branch-clash.err +++ /dev/null @@ -1 +0,0 @@ -tests/qapi-schema/flat-union-branch-clash.json:10: Member name 'name' of branch 'value1' clashes with base 'Base' diff --git a/tests/qapi-schema/enum-empty.err b/tests/qapi-schema/flat-union-clash-branch.err index e69de29..e69de29 100644 --- a/tests/qapi-schema/enum-empty.err +++ b/tests/qapi-schema/flat-union-clash-branch.err diff --git a/tests/qapi-schema/enum-empty.exit b/tests/qapi-schema/flat-union-clash-branch.exit index 573541a..573541a 100644 --- a/tests/qapi-schema/enum-empty.exit +++ b/tests/qapi-schema/flat-union-clash-branch.exit diff --git a/tests/qapi-schema/flat-union-clash-branch.json b/tests/qapi-schema/flat-union-clash-branch.json new file mode 100644 index 0000000..e593336 --- /dev/null +++ b/tests/qapi-schema/flat-union-clash-branch.json @@ -0,0 +1,18 @@ +# Flat union branch name collision +# FIXME: this parses, but then fails to compile due to a duplicate 'c_d' +# (one from the base member, the other from the branch name). We should +# either reject the collision at parse time, or munge the generated branch +# name to allow this to compile. +{ 'enum': 'TestEnum', + 'data': [ 'base', 'c-d' ] } +{ 'struct': 'Base', + 'data': { 'enum1': 'TestEnum', '*c_d': 'str' } } +{ 'struct': 'Branch1', + 'data': { 'string': 'str' } } +{ 'struct': 'Branch2', + 'data': { 'value': 'int' } } +{ 'union': 'TestUnion', + 'base': 'Base', + 'discriminator': 'enum1', + 'data': { 'base': 'Branch1', + 'c-d': 'Branch2' } } diff --git a/tests/qapi-schema/flat-union-clash-branch.out b/tests/qapi-schema/flat-union-clash-branch.out new file mode 100644 index 0000000..8e0da73 --- /dev/null +++ b/tests/qapi-schema/flat-union-clash-branch.out @@ -0,0 +1,14 @@ +object :empty +object Base + member enum1: TestEnum optional=False + member c_d: str optional=True +object Branch1 + member string: str optional=False +object Branch2 + member value: int optional=False +enum TestEnum ['base', 'c-d'] +object TestUnion + base Base + tag enum1 + case base: Branch1 + case c-d: Branch2 diff --git a/tests/qapi-schema/flat-union-clash-member.err b/tests/qapi-schema/flat-union-clash-member.err new file mode 100644 index 0000000..2f0397a --- /dev/null +++ b/tests/qapi-schema/flat-union-clash-member.err @@ -0,0 +1 @@ +tests/qapi-schema/flat-union-clash-member.json:11: Member name 'name' of branch 'value1' clashes with base 'Base' diff --git a/tests/qapi-schema/flat-union-branch-clash.exit b/tests/qapi-schema/flat-union-clash-member.exit index d00491f..d00491f 100644 --- a/tests/qapi-schema/flat-union-branch-clash.exit +++ b/tests/qapi-schema/flat-union-clash-member.exit diff --git a/tests/qapi-schema/flat-union-branch-clash.json b/tests/qapi-schema/flat-union-clash-member.json index 8fb054f..9efc771 100644 --- a/tests/qapi-schema/flat-union-branch-clash.json +++ b/tests/qapi-schema/flat-union-clash-member.json @@ -1,4 +1,5 @@ -# we check for no duplicate keys between branches and base +# We check for no duplicate keys between branch members and base +# base's member 'name' clashes with Branch1's { 'enum': 'TestEnum', 'data': [ 'value1', 'value2' ] } { 'struct': 'Base', diff --git a/tests/qapi-schema/flat-union-branch-clash.out b/tests/qapi-schema/flat-union-clash-member.out index e69de29..e69de29 100644 --- a/tests/qapi-schema/flat-union-branch-clash.out +++ b/tests/qapi-schema/flat-union-clash-member.out diff --git a/tests/qapi-schema/flat-union-clash-type.err b/tests/qapi-schema/flat-union-clash-type.err new file mode 100644 index 0000000..b44dd40 --- /dev/null +++ b/tests/qapi-schema/flat-union-clash-type.err @@ -0,0 +1 @@ +tests/qapi-schema/flat-union-clash-type.json:11: Discriminator name 'type' collides with enum value in 'TestEnum' diff --git a/tests/qapi-schema/flat-union-clash-type.exit b/tests/qapi-schema/flat-union-clash-type.exit new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/tests/qapi-schema/flat-union-clash-type.exit @@ -0,0 +1 @@ +1 diff --git a/tests/qapi-schema/flat-union-clash-type.json b/tests/qapi-schema/flat-union-clash-type.json new file mode 100644 index 0000000..8f710f0 --- /dev/null +++ b/tests/qapi-schema/flat-union-clash-type.json @@ -0,0 +1,14 @@ +# Flat union branch 'type' +# Reject this, because we would have a clash in generated C, between the +# outer tag 'type' and the branch name 'type' within the union. +# TODO: We could munge the generated C branch name to let it compile. +{ 'enum': 'TestEnum', + 'data': [ 'type' ] } +{ 'struct': 'Base', + 'data': { 'type': 'TestEnum' } } +{ 'struct': 'Branch1', + 'data': { 'string': 'str' } } +{ 'union': 'TestUnion', + 'base': 'Base', + 'discriminator': 'type', + 'data': { 'type': 'Branch1' } } diff --git a/tests/qapi-schema/flat-union-reverse-define.err b/tests/qapi-schema/flat-union-clash-type.out index e69de29..e69de29 100644 --- a/tests/qapi-schema/flat-union-reverse-define.err +++ b/tests/qapi-schema/flat-union-clash-type.out diff --git a/tests/qapi-schema/returns-int.err b/tests/qapi-schema/flat-union-empty.err index e69de29..e69de29 100644 --- a/tests/qapi-schema/returns-int.err +++ b/tests/qapi-schema/flat-union-empty.err diff --git a/tests/qapi-schema/flat-union-reverse-define.exit b/tests/qapi-schema/flat-union-empty.exit index 573541a..573541a 100644 --- a/tests/qapi-schema/flat-union-reverse-define.exit +++ b/tests/qapi-schema/flat-union-empty.exit diff --git a/tests/qapi-schema/flat-union-empty.json b/tests/qapi-schema/flat-union-empty.json new file mode 100644 index 0000000..67dd297 --- /dev/null +++ b/tests/qapi-schema/flat-union-empty.json @@ -0,0 +1,4 @@ +# FIXME - flat unions should not 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-empty.out b/tests/qapi-schema/flat-union-empty.out new file mode 100644 index 0000000..0e0665a --- /dev/null +++ b/tests/qapi-schema/flat-union-empty.out @@ -0,0 +1,7 @@ +object :empty +object Base + member type: Empty optional=False +enum Empty [] +object Union + base Base + tag type diff --git a/tests/qapi-schema/flat-union-inline.err b/tests/qapi-schema/flat-union-inline.err index ec58627..2333358 100644 --- a/tests/qapi-schema/flat-union-inline.err +++ b/tests/qapi-schema/flat-union-inline.err @@ -1 +1 @@ -tests/qapi-schema/flat-union-inline.json:7: Flat union 'TestUnion' must have a string base field +tests/qapi-schema/flat-union-inline.json:7: Member 'value1' of union 'TestUnion' should be a type name diff --git a/tests/qapi-schema/flat-union-inline.json b/tests/qapi-schema/flat-union-inline.json index 6bfdd65..62c7cda 100644 --- a/tests/qapi-schema/flat-union-inline.json +++ b/tests/qapi-schema/flat-union-inline.json @@ -1,11 +1,11 @@ # we require branches to be a struct name -# TODO: should we allow anonymous inline types? +# TODO: should we allow anonymous inline branch types? { 'enum': 'TestEnum', 'data': [ 'value1', 'value2' ] } { 'struct': 'Base', 'data': { 'enum1': 'TestEnum', 'kind': 'str' } } { 'union': 'TestUnion', - 'base': { 'enum1': 'TestEnum', 'kind': 'str' }, + 'base': 'Base', 'discriminator': 'enum1', 'data': { 'value1': { 'string': 'str' }, 'value2': { 'integer': 'int' } } } diff --git a/tests/qapi-schema/flat-union-no-base.err b/tests/qapi-schema/flat-union-no-base.err index bb3f708..841c93b 100644 --- a/tests/qapi-schema/flat-union-no-base.err +++ b/tests/qapi-schema/flat-union-no-base.err @@ -1 +1 @@ -tests/qapi-schema/flat-union-no-base.json:9: Flat union 'TestUnion' must have a string base field +tests/qapi-schema/flat-union-no-base.json:9: Flat union 'TestUnion' must have a base diff --git a/tests/qapi-schema/flat-union-reverse-define.json b/tests/qapi-schema/flat-union-reverse-define.json deleted file mode 100644 index 648bbfe..0000000 --- a/tests/qapi-schema/flat-union-reverse-define.json +++ /dev/null @@ -1,17 +0,0 @@ -{ 'union': 'TestUnion', - 'base': 'TestBase', - 'discriminator': 'enum1', - 'data': { 'value1': 'TestTypeA', - 'value2': 'TestTypeB' } } - -{ 'struct': 'TestBase', - 'data': { 'enum1': 'TestEnum' } } - -{ 'enum': 'TestEnum', - 'data': [ 'value1', 'value2' ] } - -{ 'struct': 'TestTypeA', - 'data': { 'string': 'str' } } - -{ 'struct': 'TestTypeB', - 'data': { 'integer': 'int' } } diff --git a/tests/qapi-schema/flat-union-reverse-define.out b/tests/qapi-schema/flat-union-reverse-define.out deleted file mode 100644 index a5a9134..0000000 --- a/tests/qapi-schema/flat-union-reverse-define.out +++ /dev/null @@ -1,13 +0,0 @@ -object :empty -object TestBase - member enum1: TestEnum optional=False -enum TestEnum ['value1', 'value2'] -object TestTypeA - member string: str optional=False -object TestTypeB - member integer: int optional=False -object TestUnion - base TestBase - tag enum1 - case value1: TestTypeA - case value2: TestTypeB diff --git a/tests/qapi-schema/include-non-file.err b/tests/qapi-schema/include-non-file.err index 9658c78..faae1ea 100644 --- a/tests/qapi-schema/include-non-file.err +++ b/tests/qapi-schema/include-non-file.err @@ -1 +1 @@ -tests/qapi-schema/include-non-file.json:1: Expected a file name (string), got: ['foo', 'bar'] +tests/qapi-schema/include-non-file.json:1: Value of 'include' must be a string diff --git a/tests/qapi-schema/include-non-file.json b/tests/qapi-schema/include-non-file.json index cd43c3f..4711aa4 100644 --- a/tests/qapi-schema/include-non-file.json +++ b/tests/qapi-schema/include-non-file.json @@ -1 +1 @@ -{ 'include': [ 'foo', 'bar' ] } +{ 'include': {} } diff --git a/tests/qapi-schema/qapi-schema-test.json b/tests/qapi-schema/qapi-schema-test.json index 6897a6e..4e2d7c2 100644 --- a/tests/qapi-schema/qapi-schema-test.json +++ b/tests/qapi-schema/qapi-schema-test.json @@ -1,10 +1,15 @@ # *-*- Mode: Python -*-* +# This file is a stress test of supported qapi constructs that must +# parse and compile correctly. + # for testing enums -{ 'enum': 'EnumOne', - 'data': [ 'value1', 'value2', 'value3' ] } { 'struct': 'NestedEnumsOne', - 'data': { 'enum1': 'EnumOne', '*enum2': 'EnumOne', 'enum3': 'EnumOne', '*enum4': 'EnumOne' } } + 'data': { 'enum1': 'EnumOne', # Intentional forward reference + '*enum2': 'EnumOne', 'enum3': 'EnumOne', '*enum4': 'EnumOne' } } + +# An empty enum, although unusual, is currently acceptable +{ 'enum': 'MyEnum', 'data': [ ] } # for testing override of default naming heuristic { 'enum': 'QEnumTwo', @@ -14,7 +19,11 @@ # for testing nested structs { 'struct': 'UserDefOne', 'base': 'UserDefZero', # intentional forward reference - 'data': { 'string': 'str', '*enum1': 'EnumOne' } } + 'data': { 'string': 'str', + '*enum1': 'EnumOne' } } # intentional forward reference + +{ 'enum': 'EnumOne', + 'data': [ 'value1', 'value2', 'value3' ] } { 'struct': 'UserDefZero', 'data': { 'integer': 'int' } } @@ -31,12 +40,19 @@ 'data': { 'string0': 'str', 'dict1': 'UserDefTwoDict' } } +# dummy struct to force generation of array types not otherwise mentioned +{ 'struct': 'ForceArrays', + 'data': { 'unused1':['UserDefOne'], 'unused2':['UserDefTwo'] } } + # for testing unions +# Among other things, test that a name collision between branches does +# not cause any problems (since only one branch can be in use at a time), +# by intentionally using two branches that both have a C member 'a_b' { 'struct': 'UserDefA', - 'data': { 'boolean': 'bool' } } + 'data': { 'boolean': 'bool', '*a_b': 'int' } } { 'struct': 'UserDefB', - 'data': { 'intb': 'int' } } + 'data': { 'intb': 'int', '*a-b': 'bool' } } { 'union': 'UserDefFlatUnion', 'base': 'UserDefUnionBase', # intentional forward reference @@ -64,6 +80,14 @@ { 'struct': 'UserDefC', 'data': { 'string1': 'str', 'string2': 'str' } } +# for testing use of 'number' within alternates +{ 'alternate': 'AltStrBool', 'data': { 's': 'str', 'b': 'bool' } } +{ 'alternate': 'AltStrNum', 'data': { 's': 'str', 'n': 'number' } } +{ 'alternate': 'AltNumStr', 'data': { 'n': 'number', 's': 'str' } } +{ 'alternate': 'AltStrInt', 'data': { 's': 'str', 'i': 'int' } } +{ 'alternate': 'AltIntNum', 'data': { 'i': 'int', 'n': 'number' } } +{ 'alternate': 'AltNumInt', 'data': { 'n': 'number', 'i': 'int' } } + # for testing native lists { 'union': 'UserDefNativeListUnion', 'data': { 'integer': ['int'], @@ -87,9 +111,10 @@ { 'command': 'user_def_cmd2', 'data': {'ud1a': 'UserDefOne', '*ud1b': 'UserDefOne'}, 'returns': 'UserDefTwo' } -{ 'command': 'user_def_cmd3', 'data': {'a': 'int', '*b': 'int' }, + +# Returning a non-dictionary requires a name from the whitelist +{ 'command': 'guest-get-time', 'data': {'a': 'int', '*b': 'int' }, 'returns': 'int' } -# note: command name 'guest-sync' chosen to avoid "cannot use built-in" error { 'command': 'guest-sync', 'data': { 'arg': 'any' }, 'returns': 'any' } # For testing integer range flattening in opts-visitor. The following schema diff --git a/tests/qapi-schema/qapi-schema-test.out b/tests/qapi-schema/qapi-schema-test.out index 1f6e858..a6c80e0 100644 --- a/tests/qapi-schema/qapi-schema-test.out +++ b/tests/qapi-schema/qapi-schema-test.out @@ -17,6 +17,9 @@ object :obj-anyList-wrapper member data: anyList optional=False object :obj-boolList-wrapper member data: boolList optional=False +object :obj-guest-get-time-arg + member a: int optional=False + member b: int optional=True object :obj-guest-sync-arg member arg: any optional=False object :obj-int16List-wrapper @@ -50,9 +53,30 @@ object :obj-user_def_cmd1-arg object :obj-user_def_cmd2-arg member ud1a: UserDefOne optional=False member ud1b: UserDefOne optional=True -object :obj-user_def_cmd3-arg - member a: int optional=False - member b: int optional=True +alternate AltIntNum + case i: int + case n: number +enum AltIntNumKind ['i', 'n'] +alternate AltNumInt + case n: number + case i: int +enum AltNumIntKind ['n', 'i'] +alternate AltNumStr + case n: number + case s: str +enum AltNumStrKind ['n', 's'] +alternate AltStrBool + case s: str + case b: bool +enum AltStrBoolKind ['s', 'b'] +alternate AltStrInt + case s: str + case i: int +enum AltStrIntKind ['s', 'i'] +alternate AltStrNum + case s: str + case n: number +enum AltStrNumKind ['s', 'n'] event EVENT_A None event EVENT_B None event EVENT_C :obj-EVENT_C-arg @@ -62,6 +86,10 @@ object EventStructOne member struct1: UserDefOne optional=False member string: str optional=False member enum2: EnumOne optional=True +object ForceArrays + member unused1: UserDefOneList optional=False + member unused2: UserDefTwoList optional=False +enum MyEnum [] object NestedEnumsOne member enum1: EnumOne optional=False member enum2: EnumOne optional=True @@ -71,6 +99,7 @@ enum QEnumTwo ['value1', 'value2'] prefix QENUM_TWO object UserDefA member boolean: bool optional=False + member a_b: int optional=True alternate UserDefAlternate case uda: UserDefA case s: str @@ -78,6 +107,7 @@ alternate UserDefAlternate enum UserDefAlternateKind ['uda', 's', 'i'] object UserDefB member intb: int optional=False + member a-b: bool optional=True object UserDefC member string1: str optional=False member string2: str optional=False @@ -157,6 +187,8 @@ object __org.qemu_x-Union2 case __org.qemu_x-value: __org.qemu_x-Struct2 command __org.qemu_x-command :obj-__org.qemu_x-command-arg -> __org.qemu_x-Union1 gen=True success_response=True +command guest-get-time :obj-guest-get-time-arg -> int + gen=True success_response=True command guest-sync :obj-guest-sync-arg -> any gen=True success_response=True command user_def_cmd None -> None @@ -165,5 +197,3 @@ command user_def_cmd1 :obj-user_def_cmd1-arg -> None gen=True success_response=True command user_def_cmd2 :obj-user_def_cmd2-arg -> UserDefTwo gen=True success_response=True -command user_def_cmd3 :obj-user_def_cmd3-arg -> int - gen=True success_response=True diff --git a/tests/qapi-schema/returns-int.json b/tests/qapi-schema/returns-int.json deleted file mode 100644 index 870ec63..0000000 --- a/tests/qapi-schema/returns-int.json +++ /dev/null @@ -1,3 +0,0 @@ -# It is okay (although not extensible) to return a non-dictionary -# But to make it work, the name must be in a whitelist -{ 'command': 'guest-get-time', 'returns': 'int' } diff --git a/tests/qapi-schema/returns-int.out b/tests/qapi-schema/returns-int.out deleted file mode 100644 index a2da259..0000000 --- a/tests/qapi-schema/returns-int.out +++ /dev/null @@ -1,3 +0,0 @@ -object :empty -command guest-get-time None -> int - gen=True success_response=True diff --git a/tests/qapi-schema/struct-base-clash-base.err b/tests/qapi-schema/struct-base-clash-base.err new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/tests/qapi-schema/struct-base-clash-base.err diff --git a/tests/qapi-schema/returns-int.exit b/tests/qapi-schema/struct-base-clash-base.exit index 573541a..573541a 100644 --- a/tests/qapi-schema/returns-int.exit +++ b/tests/qapi-schema/struct-base-clash-base.exit diff --git a/tests/qapi-schema/struct-base-clash-base.json b/tests/qapi-schema/struct-base-clash-base.json new file mode 100644 index 0000000..0c84025 --- /dev/null +++ b/tests/qapi-schema/struct-base-clash-base.json @@ -0,0 +1,9 @@ +# Struct member 'base' +# FIXME: this parses, but then fails to compile due to a duplicate 'base' +# (one explicit in QMP, the other used to box the base class members). +# We should either reject the collision at parse time, or change the +# generated struct to allow this to compile. +{ 'struct': 'Base', 'data': {} } +{ 'struct': 'Sub', + 'base': 'Base', + 'data': { 'base': 'str' } } diff --git a/tests/qapi-schema/struct-base-clash-base.out b/tests/qapi-schema/struct-base-clash-base.out new file mode 100644 index 0000000..e69a416 --- /dev/null +++ b/tests/qapi-schema/struct-base-clash-base.out @@ -0,0 +1,5 @@ +object :empty +object Base +object Sub + base Base + member base: str optional=False diff --git a/tests/qapi-schema/struct-base-clash-deep.err b/tests/qapi-schema/struct-base-clash-deep.err index e3e9f8d..f7a25a3 100644 --- a/tests/qapi-schema/struct-base-clash-deep.err +++ b/tests/qapi-schema/struct-base-clash-deep.err @@ -1 +1 @@ -tests/qapi-schema/struct-base-clash-deep.json:7: Member name 'name' clashes with base 'Base' +tests/qapi-schema/struct-base-clash-deep.json:10: Member name 'name' clashes with base 'Base' diff --git a/tests/qapi-schema/struct-base-clash-deep.json b/tests/qapi-schema/struct-base-clash-deep.json index 552fe94..fa873ab 100644 --- a/tests/qapi-schema/struct-base-clash-deep.json +++ b/tests/qapi-schema/struct-base-clash-deep.json @@ -1,4 +1,7 @@ -# we check for no duplicate keys with indirect base +# Reject attempts to duplicate QMP members +# Here, 'name' would have to appear twice on the wire, locally and +# indirectly for the grandparent base; the collision doesn't care that +# one instance is optional. { 'struct': 'Base', 'data': { 'name': 'str' } } { 'struct': 'Mid', diff --git a/tests/qapi-schema/struct-base-clash.err b/tests/qapi-schema/struct-base-clash.err index 3ac37fb..3a9f66b 100644 --- a/tests/qapi-schema/struct-base-clash.err +++ b/tests/qapi-schema/struct-base-clash.err @@ -1 +1 @@ -tests/qapi-schema/struct-base-clash.json:4: Member name 'name' clashes with base 'Base' +tests/qapi-schema/struct-base-clash.json:5: Member name 'name' clashes with base 'Base' diff --git a/tests/qapi-schema/struct-base-clash.json b/tests/qapi-schema/struct-base-clash.json index f2afc9b..11aec80 100644 --- a/tests/qapi-schema/struct-base-clash.json +++ b/tests/qapi-schema/struct-base-clash.json @@ -1,4 +1,5 @@ -# we check for no duplicate keys with base +# Reject attempts to duplicate QMP members +# Here, 'name' would have to appear twice on the wire, locally and for base. { 'struct': 'Base', 'data': { 'name': 'str' } } { 'struct': 'Sub', diff --git a/tests/qapi-schema/union-clash-branches.err b/tests/qapi-schema/union-clash-branches.err new file mode 100644 index 0000000..005c48d --- /dev/null +++ b/tests/qapi-schema/union-clash-branches.err @@ -0,0 +1 @@ +tests/qapi-schema/union-clash-branches.json:4: Union 'TestUnion' member 'a_b' clashes with 'a-b' diff --git a/tests/qapi-schema/union-clash-branches.exit b/tests/qapi-schema/union-clash-branches.exit new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/tests/qapi-schema/union-clash-branches.exit @@ -0,0 +1 @@ +1 diff --git a/tests/qapi-schema/union-clash-branches.json b/tests/qapi-schema/union-clash-branches.json new file mode 100644 index 0000000..31d135f --- /dev/null +++ b/tests/qapi-schema/union-clash-branches.json @@ -0,0 +1,5 @@ +# Union branch name collision +# Reject a union that would result in a collision in generated C names (this +# would try to generate two enum values 'TEST_UNION_KIND_A_B'). +{ 'union': 'TestUnion', + 'data': { 'a-b': 'int', 'a_b': 'str' } } diff --git a/tests/qapi-schema/union-clash-branches.out b/tests/qapi-schema/union-clash-branches.out new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/tests/qapi-schema/union-clash-branches.out diff --git a/tests/qapi-schema/union-clash-data.err b/tests/qapi-schema/union-clash-data.err new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/tests/qapi-schema/union-clash-data.err diff --git a/tests/qapi-schema/union-clash-data.exit b/tests/qapi-schema/union-clash-data.exit new file mode 100644 index 0000000..573541a --- /dev/null +++ b/tests/qapi-schema/union-clash-data.exit @@ -0,0 +1 @@ +0 diff --git a/tests/qapi-schema/union-clash-data.json b/tests/qapi-schema/union-clash-data.json new file mode 100644 index 0000000..7308e69 --- /dev/null +++ b/tests/qapi-schema/union-clash-data.json @@ -0,0 +1,7 @@ +# Union branch 'data' +# FIXME: this parses, but then fails to compile due to a duplicate 'data' +# (one from the branch name, another as a filler to avoid an empty union). +# we should either detect the collision at parse time, or change the +# generated struct to allow this to compile. +{ 'union': 'TestUnion', + 'data': { 'data': 'int' } } diff --git a/tests/qapi-schema/union-clash-data.out b/tests/qapi-schema/union-clash-data.out new file mode 100644 index 0000000..6277239 --- /dev/null +++ b/tests/qapi-schema/union-clash-data.out @@ -0,0 +1,6 @@ +object :empty +object :obj-int-wrapper + member data: int optional=False +object TestUnion + case data: :obj-int-wrapper +enum TestUnionKind ['data'] diff --git a/tests/qapi-schema/union-clash-type.err b/tests/qapi-schema/union-clash-type.err new file mode 100644 index 0000000..a5dead1 --- /dev/null +++ b/tests/qapi-schema/union-clash-type.err @@ -0,0 +1 @@ +tests/qapi-schema/union-clash-type.json:8: Union 'TestUnion' member 'kind' clashes with '(automatic)' diff --git a/tests/qapi-schema/union-clash-type.exit b/tests/qapi-schema/union-clash-type.exit new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/tests/qapi-schema/union-clash-type.exit @@ -0,0 +1 @@ +1 diff --git a/tests/qapi-schema/union-clash-type.json b/tests/qapi-schema/union-clash-type.json new file mode 100644 index 0000000..cfc256b --- /dev/null +++ b/tests/qapi-schema/union-clash-type.json @@ -0,0 +1,9 @@ +# Union branch 'type' +# Reject this, because we would have a clash in generated C, between the +# simple union's implicit tag member 'kind' and the branch name 'kind' +# within the union. +# TODO: Even when the generated C is switched to use 'type' rather than +# 'kind', to match the QMP spelling, the collision should still be detected. +# Or, we could munge the branch name to allow compilation. +{ 'union': 'TestUnion', + 'data': { 'kind': 'int', 'type': 'str' } } diff --git a/tests/qapi-schema/union-clash-type.out b/tests/qapi-schema/union-clash-type.out new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/tests/qapi-schema/union-clash-type.out diff --git a/tests/qapi-schema/union-empty.err b/tests/qapi-schema/union-empty.err new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/tests/qapi-schema/union-empty.err diff --git a/tests/qapi-schema/union-empty.exit b/tests/qapi-schema/union-empty.exit new file mode 100644 index 0000000..573541a --- /dev/null +++ b/tests/qapi-schema/union-empty.exit @@ -0,0 +1 @@ +0 diff --git a/tests/qapi-schema/union-empty.json b/tests/qapi-schema/union-empty.json new file mode 100644 index 0000000..1785007 --- /dev/null +++ b/tests/qapi-schema/union-empty.json @@ -0,0 +1,2 @@ +# FIXME - unions should not be empty +{ 'union': 'Union', 'data': { } } diff --git a/tests/qapi-schema/union-empty.out b/tests/qapi-schema/union-empty.out new file mode 100644 index 0000000..8b5a7bf --- /dev/null +++ b/tests/qapi-schema/union-empty.out @@ -0,0 +1,3 @@ +object :empty +object Union +enum UnionKind [] diff --git a/tests/qapi-schema/union-invalid-base.err b/tests/qapi-schema/union-invalid-base.err index 9f63796..03d7b97 100644 --- a/tests/qapi-schema/union-invalid-base.err +++ b/tests/qapi-schema/union-invalid-base.err @@ -1 +1 @@ -tests/qapi-schema/union-invalid-base.json:8: Base 'int' is not a valid struct +tests/qapi-schema/union-invalid-base.json:8: 'base' for union 'TestUnion' cannot use built-in type 'int' diff --git a/tests/qemu-iotests/041 b/tests/qemu-iotests/041 index 59c1a76..05b5962 100755 --- a/tests/qemu-iotests/041 +++ b/tests/qemu-iotests/041 @@ -780,7 +780,7 @@ class TestRepairQuorum(iotests.QMPTestCase): # here we check that the last registered quorum file has not been # swapped out and unref result = self.vm.qmp('query-named-block-nodes') - self.assert_qmp(result, 'return[0]/file', quorum_img3) + self.assert_qmp(result, 'return[1]/file', quorum_img3) self.vm.shutdown() def test_cancel_after_ready(self): @@ -799,7 +799,7 @@ class TestRepairQuorum(iotests.QMPTestCase): result = self.vm.qmp('query-named-block-nodes') # here we check that the last registered quorum file has not been # swapped out and unref - self.assert_qmp(result, 'return[0]/file', quorum_img3) + self.assert_qmp(result, 'return[1]/file', quorum_img3) self.vm.shutdown() self.assertTrue(iotests.compare_images(quorum_img2, quorum_repair_img), 'target image does not match source after mirroring') diff --git a/tests/qemu-iotests/051 b/tests/qemu-iotests/051 index 4a8055b..17dbf04 100755 --- a/tests/qemu-iotests/051 +++ b/tests/qemu-iotests/051 @@ -108,7 +108,8 @@ echo echo === Overriding backing file === echo -echo "info block" | run_qemu -drive file="$TEST_IMG",driver=qcow2,backing.file.filename="$TEST_IMG.orig" -nodefaults +echo "info block" | run_qemu -drive file="$TEST_IMG",driver=qcow2,backing.file.filename="$TEST_IMG.orig" -nodefaults\ + | _filter_generated_node_ids # Drivers that don't support backing files run_qemu -drive file="$TEST_IMG",driver=raw,backing.file.filename="$TEST_IMG.orig" diff --git a/tests/qemu-iotests/051.out b/tests/qemu-iotests/051.out index 0429be2..7765aa0 100644 --- a/tests/qemu-iotests/051.out +++ b/tests/qemu-iotests/051.out @@ -59,7 +59,7 @@ QEMU X.Y.Z monitor - type 'help' for more information Testing: -drive file=TEST_DIR/t.qcow2,driver=qcow2,backing.file.filename=TEST_DIR/t.qcow2.orig -nodefaults QEMU X.Y.Z monitor - type 'help' for more information (qemu) i[K[Din[K[D[Dinf[K[D[D[Dinfo[K[D[D[D[Dinfo [K[D[D[D[D[Dinfo b[K[D[D[D[D[D[Dinfo bl[K[D[D[D[D[D[D[Dinfo blo[K[D[D[D[D[D[D[D[Dinfo bloc[K[D[D[D[D[D[D[D[D[Dinfo block[K -ide0-hd0: TEST_DIR/t.qcow2 (qcow2) +ide0-hd0 (NODE_NAME): TEST_DIR/t.qcow2 (qcow2) Cache mode: writeback Backing file: TEST_DIR/t.qcow2.orig (chain depth: 1) (qemu) q[K[Dqu[K[D[Dqui[K[D[D[Dquit[K diff --git a/tests/qemu-iotests/059.out b/tests/qemu-iotests/059.out index 67e3cf5..00057fe 100644 --- a/tests/qemu-iotests/059.out +++ b/tests/qemu-iotests/059.out @@ -16,17 +16,17 @@ qemu-io: can't open device TEST_DIR/t.vmdk: L1 size too big no file open, try 'help open' === Testing monolithicFlat creation and opening === -Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=2147483648 +Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=2147483648 subformat=monolithicFlat image: TEST_DIR/t.IMGFMT file format: IMGFMT virtual size: 2.0G (2147483648 bytes) === Testing monolithicFlat with zeroed_grain === qemu-img: TEST_DIR/t.IMGFMT: Flat image can't enable zeroed grain -Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=2147483648 +Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=2147483648 subformat=monolithicFlat === Testing big twoGbMaxExtentFlat === -Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824000 +Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824000 subformat=twoGbMaxExtentFlat image: TEST_DIR/t.vmdk file format: vmdk virtual size: 1.0T (1073741824000 bytes) @@ -2043,7 +2043,7 @@ RW 12582912 VMFS "dummy.IMGFMT" 1 === Testing truncated sparse === -Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=107374182400 +Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=107374182400 subformat=monolithicSparse qemu-img: Could not open 'TEST_DIR/t.IMGFMT': File truncated, expecting at least 13172736 bytes === Converting to streamOptimized from image with small cluster size=== @@ -2054,7 +2054,7 @@ wrote 512/512 bytes at offset 10240 512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) === Testing monolithicFlat with internally generated JSON file name === -Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864 +Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864 subformat=monolithicFlat qemu-io: can't open: Cannot use relative extent paths with VMDK descriptor file 'json:{"image": {"driver": "file", "filename": "TEST_DIR/t.IMGFMT"}, "driver": "blkdebug", "inject-error.0.event": "read_aio"}' === Testing version 3 === @@ -2264,7 +2264,7 @@ read 512/512 bytes at offset 64931328 512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) === Testing 4TB monolithicFlat creation and IO === -Formatting 'TEST_DIR/iotest-version3.IMGFMT', fmt=IMGFMT size=4398046511104 +Formatting 'TEST_DIR/iotest-version3.IMGFMT', fmt=IMGFMT size=4398046511104 subformat=monolithicFlat image: TEST_DIR/iotest-version3.IMGFMT file format: IMGFMT virtual size: 4.0T (4398046511104 bytes) diff --git a/tests/qemu-iotests/061 b/tests/qemu-iotests/061 index 1df887a..e191e65 100755 --- a/tests/qemu-iotests/061 +++ b/tests/qemu-iotests/061 @@ -58,8 +58,8 @@ echo echo "=== Testing dirty version downgrade ===" echo IMGOPTS="compat=1.1,lazy_refcounts=on" _make_test_img 64M -$QEMU_IO -c "write -P 0x2a 0 128k" -c flush -c abort "$TEST_IMG" 2>&1 \ - | _filter_qemu_io +$QEMU_IO -c "write -P 0x2a 0 128k" -c flush \ + -c "sigraise $(kill -l KILL)" "$TEST_IMG" 2>&1 | _filter_qemu_io $PYTHON qcow2.py "$TEST_IMG" dump-header $QEMU_IMG amend -o "compat=0.10" "$TEST_IMG" $PYTHON qcow2.py "$TEST_IMG" dump-header @@ -92,8 +92,8 @@ echo echo "=== Testing dirty lazy_refcounts=off ===" echo IMGOPTS="compat=1.1,lazy_refcounts=on" _make_test_img 64M -$QEMU_IO -c "write -P 0x2a 0 128k" -c flush -c abort "$TEST_IMG" 2>&1 \ - | _filter_qemu_io +$QEMU_IO -c "write -P 0x2a 0 128k" -c flush \ + -c "sigraise $(kill -l KILL)" "$TEST_IMG" 2>&1 | _filter_qemu_io $PYTHON qcow2.py "$TEST_IMG" dump-header $QEMU_IMG amend -o "lazy_refcounts=off" "$TEST_IMG" $PYTHON qcow2.py "$TEST_IMG" dump-header diff --git a/tests/qemu-iotests/061.out b/tests/qemu-iotests/061.out index a683f46..b16bea9 100644 --- a/tests/qemu-iotests/061.out +++ b/tests/qemu-iotests/061.out @@ -57,7 +57,7 @@ No errors were found on the image. Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864 wrote 131072/131072 bytes at offset 0 128 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) -./common.config: Aborted (core dumped) ( exec "$QEMU_IO_PROG" $QEMU_IO_OPTIONS "$@" ) +./common.config: Killed ( exec "$QEMU_IO_PROG" $QEMU_IO_OPTIONS "$@" ) magic 0x514649fb version 3 backing_file_offset 0x0 @@ -215,7 +215,7 @@ No errors were found on the image. Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864 wrote 131072/131072 bytes at offset 0 128 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) -./common.config: Aborted (core dumped) ( exec "$QEMU_IO_PROG" $QEMU_IO_OPTIONS "$@" ) +./common.config: Killed ( exec "$QEMU_IO_PROG" $QEMU_IO_OPTIONS "$@" ) magic 0x514649fb version 3 backing_file_offset 0x0 diff --git a/tests/qemu-iotests/067 b/tests/qemu-iotests/067 index 3e9a053..3788534 100755 --- a/tests/qemu-iotests/067 +++ b/tests/qemu-iotests/067 @@ -48,7 +48,8 @@ function do_run_qemu() function run_qemu() { do_run_qemu "$@" 2>&1 | _filter_testdir | _filter_qmp | _filter_qemu \ - | sed -e 's/\("actual-size":\s*\)[0-9]\+/\1SIZE/g' + | sed -e 's/\("actual-size":\s*\)[0-9]\+/\1SIZE/g' \ + | _filter_generated_node_ids } size=128M diff --git a/tests/qemu-iotests/067.out b/tests/qemu-iotests/067.out index 5fbc881..27ad56f 100644 --- a/tests/qemu-iotests/067.out +++ b/tests/qemu-iotests/067.out @@ -40,6 +40,7 @@ Testing: -drive file=TEST_DIR/t.qcow2,format=qcow2,if=none,id=disk -device virti }, "iops_wr": 0, "ro": false, + "node-name": "NODE_NAME", "backing_file_depth": 0, "drv": "qcow2", "iops": 0, @@ -151,6 +152,7 @@ Testing: -drive file=TEST_DIR/t.qcow2,format=qcow2,if=none,id=disk }, "iops_wr": 0, "ro": false, + "node-name": "NODE_NAME", "backing_file_depth": 0, "drv": "qcow2", "iops": 0, @@ -270,6 +272,7 @@ Testing: }, "iops_wr": 0, "ro": false, + "node-name": "NODE_NAME", "backing_file_depth": 0, "drv": "qcow2", "iops": 0, @@ -390,6 +393,7 @@ Testing: }, "iops_wr": 0, "ro": false, + "node-name": "NODE_NAME", "backing_file_depth": 0, "drv": "qcow2", "iops": 0, @@ -480,6 +484,7 @@ Testing: }, "iops_wr": 0, "ro": false, + "node-name": "NODE_NAME", "backing_file_depth": 0, "drv": "qcow2", "iops": 0, diff --git a/tests/qemu-iotests/081 b/tests/qemu-iotests/081 index d9b042c..51873ff 100755 --- a/tests/qemu-iotests/081 +++ b/tests/qemu-iotests/081 @@ -53,7 +53,8 @@ function do_run_qemu() function run_qemu() { - do_run_qemu "$@" 2>&1 | _filter_testdir | _filter_qemu | _filter_qmp | _filter_qemu_io + do_run_qemu "$@" 2>&1 | _filter_testdir | _filter_qemu | _filter_qmp\ + | _filter_qemu_io | _filter_generated_node_ids } test_quorum=$($QEMU_IMG --help|grep quorum) diff --git a/tests/qemu-iotests/081.out b/tests/qemu-iotests/081.out index 692c4a4..044793d 100644 --- a/tests/qemu-iotests/081.out +++ b/tests/qemu-iotests/081.out @@ -30,7 +30,7 @@ Testing: -drive file=TEST_DIR/2.IMGFMT,format=IMGFMT,if=none,id=drive2 QMP_VERSION {"return": {}} {"return": {}} -{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "QUORUM_REPORT_BAD", "data": {"node-name": "", "sectors-count": 20480, "sector-num": 0}} +{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "QUORUM_REPORT_BAD", "data": {"node-name": "NODE_NAME", "sectors-count": 20480, "sector-num": 0}} read 10485760/10485760 bytes at offset 0 10 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) {"return": ""} diff --git a/tests/qemu-iotests/096 b/tests/qemu-iotests/096 new file mode 100644 index 0000000..e34204b --- /dev/null +++ b/tests/qemu-iotests/096 @@ -0,0 +1,69 @@ +#!/usr/bin/env python +# +# Test that snapshots move the throttling configuration to the active +# layer +# +# Copyright (C) 2015 Igalia, S.L. +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see <http://www.gnu.org/licenses/>. +# + +import iotests +import os + +class TestLiveSnapshot(iotests.QMPTestCase): + base_img = os.path.join(iotests.test_dir, 'base.img') + target_img = os.path.join(iotests.test_dir, 'target.img') + group = 'mygroup' + iops = 6000 + iops_size = 1024 + + def setUp(self): + opts = [] + opts.append('node-name=base') + opts.append('throttling.group=%s' % self.group) + opts.append('throttling.iops-total=%d' % self.iops) + opts.append('throttling.iops-size=%d' % self.iops_size) + iotests.qemu_img('create', '-f', iotests.imgfmt, self.base_img, '100M') + self.vm = iotests.VM().add_drive(self.base_img, ','.join(opts)) + self.vm.launch() + + def tearDown(self): + self.vm.shutdown() + os.remove(self.base_img) + os.remove(self.target_img) + + def checkConfig(self, active_layer): + result = self.vm.qmp('query-named-block-nodes') + for r in result['return']: + if r['node-name'] == active_layer: + self.assertEqual(r['group'], self.group) + self.assertEqual(r['iops'], self.iops) + self.assertEqual(r['iops_size'], self.iops_size) + else: + self.assertFalse(r.has_key('group')) + self.assertEqual(r['iops'], 0) + self.assertFalse(r.has_key('iops_size')) + + def testSnapshot(self): + self.checkConfig('base') + self.vm.qmp('blockdev-snapshot-sync', + node_name = 'base', + snapshot_node_name = 'target', + snapshot_file = self.target_img, + format = iotests.imgfmt) + self.checkConfig('target') + +if __name__ == '__main__': + iotests.main(supported_fmts=['qcow2']) diff --git a/tests/qemu-iotests/096.out b/tests/qemu-iotests/096.out new file mode 100644 index 0000000..ae1213e --- /dev/null +++ b/tests/qemu-iotests/096.out @@ -0,0 +1,5 @@ +. +---------------------------------------------------------------------- +Ran 1 tests + +OK diff --git a/tests/qemu-iotests/common.filter b/tests/qemu-iotests/common.filter index d6d05de..cfdb633 100644 --- a/tests/qemu-iotests/common.filter +++ b/tests/qemu-iotests/common.filter @@ -128,6 +128,11 @@ _filter_date() -e 's/[A-Z][a-z][a-z] [A-z][a-z][a-z] *[0-9][0-9]* [0-9][0-9]:[0-9][0-9]:[0-9][0-9] [0-9][0-9][0-9][0-9]$/DATE/' } +_filter_generated_node_ids() +{ + sed -re 's/\#block[0-9]{3,}/NODE_NAME/' +} + # replace occurrences of the actual TEST_DIR value with TEST_DIR _filter_testdir() { diff --git a/tests/qemu-iotests/group b/tests/qemu-iotests/group index 439b1d2..30c784e 100644 --- a/tests/qemu-iotests/group +++ b/tests/qemu-iotests/group @@ -102,6 +102,7 @@ 093 auto 094 rw auto quick 095 rw auto quick +096 rw auto quick 097 rw auto backing 098 rw auto backing quick 099 rw auto quick diff --git a/tests/test-qmp-commands.c b/tests/test-qmp-commands.c index 8d5249e..bc59835 100644 --- a/tests/test-qmp-commands.c +++ b/tests/test-qmp-commands.c @@ -46,7 +46,7 @@ UserDefTwo *qmp_user_def_cmd2(UserDefOne *ud1a, return ret; } -int64_t qmp_user_def_cmd3(int64_t a, bool has_b, int64_t b, Error **errp) +int64_t qmp_guest_get_time(int64_t a, bool has_b, int64_t b, Error **errp) { return a + (has_b ? b : 0); } @@ -160,7 +160,7 @@ static void test_dispatch_cmd_io(void) qdict_put(args3, "a", qint_from_int(66)); qdict_put(req, "arguments", args3); - qdict_put(req, "execute", qstring_from_str("user_def_cmd3")); + qdict_put(req, "execute", qstring_from_str("guest-get-time")); ret3 = qobject_to_qint(test_qmp_dispatch(req)); assert(qint_get_int(ret3) == 66); diff --git a/tests/test-qmp-input-visitor.c b/tests/test-qmp-input-visitor.c index 61715b3..8941963 100644 --- a/tests/test-qmp-input-visitor.c +++ b/tests/test-qmp-input-visitor.c @@ -371,12 +371,135 @@ static void test_visitor_in_alternate(TestInputVisitorData *data, UserDefAlternate *tmp; v = visitor_input_test_init(data, "42"); - - visit_type_UserDefAlternate(v, &tmp, NULL, &err); - g_assert(err == NULL); + visit_type_UserDefAlternate(v, &tmp, NULL, &error_abort); g_assert_cmpint(tmp->kind, ==, USER_DEF_ALTERNATE_KIND_I); g_assert_cmpint(tmp->i, ==, 42); qapi_free_UserDefAlternate(tmp); + visitor_input_teardown(data, NULL); + + v = visitor_input_test_init(data, "'string'"); + visit_type_UserDefAlternate(v, &tmp, NULL, &error_abort); + g_assert_cmpint(tmp->kind, ==, USER_DEF_ALTERNATE_KIND_S); + g_assert_cmpstr(tmp->s, ==, "string"); + qapi_free_UserDefAlternate(tmp); + visitor_input_teardown(data, NULL); + + v = visitor_input_test_init(data, "false"); + visit_type_UserDefAlternate(v, &tmp, NULL, &err); + g_assert(err); + error_free(err); + err = NULL; + qapi_free_UserDefAlternate(tmp); + visitor_input_teardown(data, NULL); +} + +static void test_visitor_in_alternate_number(TestInputVisitorData *data, + const void *unused) +{ + Visitor *v; + Error *err = NULL; + AltStrBool *asb; + AltStrNum *asn; + AltNumStr *ans; + AltStrInt *asi; + AltIntNum *ain; + AltNumInt *ani; + + /* Parsing an int */ + + v = visitor_input_test_init(data, "42"); + visit_type_AltStrBool(v, &asb, NULL, &err); + g_assert(err); + error_free(err); + err = NULL; + qapi_free_AltStrBool(asb); + visitor_input_teardown(data, NULL); + + /* FIXME: Order of alternate should not affect semantics; asn should + * parse the same as ans */ + v = visitor_input_test_init(data, "42"); + visit_type_AltStrNum(v, &asn, NULL, &err); + /* FIXME g_assert_cmpint(asn->kind, == ALT_STR_NUM_KIND_N); */ + /* FIXME g_assert_cmpfloat(asn->n, ==, 42); */ + g_assert(err); + error_free(err); + err = NULL; + qapi_free_AltStrNum(asn); + visitor_input_teardown(data, NULL); + + v = visitor_input_test_init(data, "42"); + visit_type_AltNumStr(v, &ans, NULL, &error_abort); + g_assert_cmpint(ans->kind, ==, ALT_NUM_STR_KIND_N); + g_assert_cmpfloat(ans->n, ==, 42); + qapi_free_AltNumStr(ans); + visitor_input_teardown(data, NULL); + + v = visitor_input_test_init(data, "42"); + visit_type_AltStrInt(v, &asi, NULL, &error_abort); + g_assert_cmpint(asi->kind, ==, ALT_STR_INT_KIND_I); + g_assert_cmpint(asi->i, ==, 42); + qapi_free_AltStrInt(asi); + visitor_input_teardown(data, NULL); + + v = visitor_input_test_init(data, "42"); + visit_type_AltIntNum(v, &ain, NULL, &error_abort); + g_assert_cmpint(ain->kind, ==, ALT_INT_NUM_KIND_I); + g_assert_cmpint(ain->i, ==, 42); + qapi_free_AltIntNum(ain); + visitor_input_teardown(data, NULL); + + v = visitor_input_test_init(data, "42"); + visit_type_AltNumInt(v, &ani, NULL, &error_abort); + g_assert_cmpint(ani->kind, ==, ALT_NUM_INT_KIND_I); + g_assert_cmpint(ani->i, ==, 42); + qapi_free_AltNumInt(ani); + visitor_input_teardown(data, NULL); + + /* Parsing a double */ + + v = visitor_input_test_init(data, "42.5"); + visit_type_AltStrBool(v, &asb, NULL, &err); + g_assert(err); + error_free(err); + err = NULL; + qapi_free_AltStrBool(asb); + visitor_input_teardown(data, NULL); + + v = visitor_input_test_init(data, "42.5"); + visit_type_AltStrNum(v, &asn, NULL, &error_abort); + g_assert_cmpint(asn->kind, ==, ALT_STR_NUM_KIND_N); + g_assert_cmpfloat(asn->n, ==, 42.5); + qapi_free_AltStrNum(asn); + visitor_input_teardown(data, NULL); + + v = visitor_input_test_init(data, "42.5"); + visit_type_AltNumStr(v, &ans, NULL, &error_abort); + g_assert_cmpint(ans->kind, ==, ALT_NUM_STR_KIND_N); + g_assert_cmpfloat(ans->n, ==, 42.5); + qapi_free_AltNumStr(ans); + visitor_input_teardown(data, NULL); + + v = visitor_input_test_init(data, "42.5"); + visit_type_AltStrInt(v, &asi, NULL, &err); + g_assert(err); + error_free(err); + err = NULL; + qapi_free_AltStrInt(asi); + visitor_input_teardown(data, NULL); + + v = visitor_input_test_init(data, "42.5"); + visit_type_AltIntNum(v, &ain, NULL, &error_abort); + g_assert_cmpint(ain->kind, ==, ALT_INT_NUM_KIND_N); + g_assert_cmpfloat(ain->n, ==, 42.5); + qapi_free_AltIntNum(ain); + visitor_input_teardown(data, NULL); + + v = visitor_input_test_init(data, "42.5"); + visit_type_AltNumInt(v, &ani, NULL, &error_abort); + g_assert_cmpint(ani->kind, ==, ALT_NUM_INT_KIND_N); + g_assert_cmpfloat(ani->n, ==, 42.5); + qapi_free_AltNumInt(ani); + visitor_input_teardown(data, NULL); } static void test_native_list_integer_helper(TestInputVisitorData *data, @@ -720,6 +843,8 @@ int main(int argc, char **argv) &in_visitor_data, test_visitor_in_alternate); input_visitor_test_add("/visitor/input/errors", &in_visitor_data, test_visitor_in_errors); + input_visitor_test_add("/visitor/input/alternate-number", + &in_visitor_data, test_visitor_in_alternate_number); input_visitor_test_add("/visitor/input/native_list/int", &in_visitor_data, test_visitor_in_native_list_int); |