summary refs log tree commit diff stats
path: root/tests
diff options
context:
space:
mode:
Diffstat (limited to 'tests')
-rw-r--r--tests/Makefile26
-rw-r--r--tests/qapi-schema/duplicate-key.err2
-rw-r--r--tests/qapi-schema/flat-union-invalid-branch-key.err2
-rw-r--r--tests/qapi-schema/flat-union-invalid-discriminator.err2
-rw-r--r--tests/qapi-schema/flat-union-no-base.err2
-rw-r--r--tests/qapi-schema/flat-union-string-discriminator.err2
-rw-r--r--tests/qapi-schema/funny-char.err2
-rw-r--r--tests/qapi-schema/include-before-err.err1
-rw-r--r--tests/qapi-schema/include-before-err.exit1
-rw-r--r--tests/qapi-schema/include-before-err.json2
-rw-r--r--tests/qapi-schema/include-before-err.out0
-rw-r--r--tests/qapi-schema/include-cycle-b.json1
-rw-r--r--tests/qapi-schema/include-cycle-c.json1
-rw-r--r--tests/qapi-schema/include-cycle.err3
-rw-r--r--tests/qapi-schema/include-cycle.exit1
-rw-r--r--tests/qapi-schema/include-cycle.json1
-rw-r--r--tests/qapi-schema/include-cycle.out0
-rw-r--r--tests/qapi-schema/include-format-err.err1
-rw-r--r--tests/qapi-schema/include-format-err.exit1
-rw-r--r--tests/qapi-schema/include-format-err.json2
-rw-r--r--tests/qapi-schema/include-format-err.out0
-rw-r--r--tests/qapi-schema/include-nested-err.err2
-rw-r--r--tests/qapi-schema/include-nested-err.exit1
-rw-r--r--tests/qapi-schema/include-nested-err.json1
-rw-r--r--tests/qapi-schema/include-nested-err.out0
-rw-r--r--tests/qapi-schema/include-no-file.err1
-rw-r--r--tests/qapi-schema/include-no-file.exit1
-rw-r--r--tests/qapi-schema/include-no-file.json1
-rw-r--r--tests/qapi-schema/include-no-file.out0
-rw-r--r--tests/qapi-schema/include-non-file.err1
-rw-r--r--tests/qapi-schema/include-non-file.exit1
-rw-r--r--tests/qapi-schema/include-non-file.json1
-rw-r--r--tests/qapi-schema/include-non-file.out0
-rw-r--r--tests/qapi-schema/include-relpath-sub.json2
-rw-r--r--tests/qapi-schema/include-relpath.err0
-rw-r--r--tests/qapi-schema/include-relpath.exit1
-rw-r--r--tests/qapi-schema/include-relpath.json1
-rw-r--r--tests/qapi-schema/include-relpath.out3
-rw-r--r--tests/qapi-schema/include-self-cycle.err1
-rw-r--r--tests/qapi-schema/include-self-cycle.exit1
-rw-r--r--tests/qapi-schema/include-self-cycle.json1
-rw-r--r--tests/qapi-schema/include-self-cycle.out0
-rw-r--r--tests/qapi-schema/include-simple-sub.json2
-rw-r--r--tests/qapi-schema/include-simple.err0
-rw-r--r--tests/qapi-schema/include-simple.exit1
-rw-r--r--tests/qapi-schema/include-simple.json1
-rw-r--r--tests/qapi-schema/include-simple.out3
-rw-r--r--tests/qapi-schema/include/relpath.json1
-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/quoted-structural-chars.err2
-rw-r--r--tests/qapi-schema/test-qapi.py6
-rw-r--r--tests/qapi-schema/trailing-comma-list.err2
-rw-r--r--tests/qapi-schema/trailing-comma-object.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/unclosed-string.err2
-rw-r--r--tests/qapi-schema/union-invalid-base.err2
-rwxr-xr-xtests/qemu-iotests/0319
-rwxr-xr-xtests/qemu-iotests/0367
-rwxr-xr-xtests/qemu-iotests/03919
-rwxr-xr-xtests/qemu-iotests/0514
-rw-r--r--tests/qemu-iotests/051.out10
-rwxr-xr-xtests/qemu-iotests/0543
-rwxr-xr-xtests/qemu-iotests/0597
-rw-r--r--tests/qemu-iotests/059.out8
-rwxr-xr-xtests/qemu-iotests/06021
-rwxr-xr-xtests/qemu-iotests/06125
-rwxr-xr-xtests/qemu-iotests/0652
-rwxr-xr-xtests/qemu-iotests/0833
-rwxr-xr-xtests/qemu-iotests/08573
-rwxr-xr-xtests/qemu-iotests/091105
-rw-r--r--tests/qemu-iotests/091.out28
-rwxr-xr-xtests/qemu-iotests/check18
-rw-r--r--tests/qemu-iotests/common.qemu200
-rw-r--r--tests/qemu-iotests/group1
-rw-r--r--tests/test-qmp-input-strict.c72
-rw-r--r--tests/test-qmp-input-visitor.c89
-rw-r--r--tests/test-qmp-output-visitor.c74
-rw-r--r--tests/test-string-input-visitor.c50
-rw-r--r--tests/test-string-output-visitor.c46
83 files changed, 686 insertions, 297 deletions
diff --git a/tests/Makefile b/tests/Makefile
index 14ecf05b5d..6b8b6f273a 100644
--- a/tests/Makefile
+++ b/tests/Makefile
@@ -190,7 +190,10 @@ check-qapi-schema-y := $(addprefix tests/qapi-schema/, \
         duplicate-key.json union-invalid-base.json flat-union-no-base.json \
         flat-union-invalid-discriminator.json \
         flat-union-invalid-branch-key.json flat-union-reverse-define.json \
-        flat-union-string-discriminator.json)
+        flat-union-string-discriminator.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)
 
 GENERATED_HEADERS += tests/test-qapi-types.h tests/test-qapi-visit.h tests/test-qmp-commands.h
 
@@ -242,13 +245,19 @@ tests/test-vmstate$(EXESUF): tests/test-vmstate.o \
 
 tests/test-qapi-types.c tests/test-qapi-types.h :\
 $(SRC_PATH)/tests/qapi-schema/qapi-schema-test.json $(SRC_PATH)/scripts/qapi-types.py
-	$(call quiet-command,$(PYTHON) $(SRC_PATH)/scripts/qapi-types.py $(gen-out-type) -o tests -p "test-" < $<, "  GEN   $@")
+	$(call quiet-command,$(PYTHON) $(SRC_PATH)/scripts/qapi-types.py \
+		$(gen-out-type) -o tests -p "test-" -i $<, \
+		"  GEN   $@")
 tests/test-qapi-visit.c tests/test-qapi-visit.h :\
 $(SRC_PATH)/tests/qapi-schema/qapi-schema-test.json $(SRC_PATH)/scripts/qapi-visit.py
-	$(call quiet-command,$(PYTHON) $(SRC_PATH)/scripts/qapi-visit.py $(gen-out-type) -o tests -p "test-" < $<, "  GEN   $@")
+	$(call quiet-command,$(PYTHON) $(SRC_PATH)/scripts/qapi-visit.py \
+		$(gen-out-type) -o tests -p "test-" -i $<, \
+		"  GEN   $@")
 tests/test-qmp-commands.h tests/test-qmp-marshal.c :\
 $(SRC_PATH)/tests/qapi-schema/qapi-schema-test.json $(SRC_PATH)/scripts/qapi-commands.py
-	$(call quiet-command,$(PYTHON) $(SRC_PATH)/scripts/qapi-commands.py $(gen-out-type) -o tests -p "test-" < $<, "  GEN   $@")
+	$(call quiet-command,$(PYTHON) $(SRC_PATH)/scripts/qapi-commands.py \
+		$(gen-out-type) -o tests -p "test-" -i $<, \
+		"  GEN   $@")
 
 tests/test-string-output-visitor$(EXESUF): tests/test-string-output-visitor.o $(test-qapi-obj-y) libqemuutil.a libqemustub.a
 tests/test-string-input-visitor$(EXESUF): tests/test-string-input-visitor.o $(test-qapi-obj-y) libqemuutil.a libqemustub.a
@@ -400,9 +409,14 @@ check-tests/test-qapi.py: tests/test-qapi.py
 
 .PHONY: $(patsubst %, check-%, $(check-qapi-schema-y))
 $(patsubst %, check-%, $(check-qapi-schema-y)): check-%.json: $(SRC_PATH)/%.json
-	$(call quiet-command, PYTHONPATH=$(SRC_PATH)/scripts $(PYTHON) $(SRC_PATH)/tests/qapi-schema/test-qapi.py <$^ >$*.test.out 2>$*.test.err; echo $$? >$*.test.exit, "  TEST  $*.out")
+	$(call quiet-command, PYTHONPATH=$(SRC_PATH)/scripts \
+		$(PYTHON) $(SRC_PATH)/tests/qapi-schema/test-qapi.py \
+		$^ >$*.test.out 2>$*.test.err; \
+		echo $$? >$*.test.exit, \
+		"  TEST  $*.out")
 	@diff -q $(SRC_PATH)/$*.out $*.test.out
-	@diff -q $(SRC_PATH)/$*.err $*.test.err
+	@# Sanitize error messages (make them independent of build directory)
+	@perl -p -e 's|\Q$(SRC_PATH)\E/||g' $*.test.err | diff -q $(SRC_PATH)/$*.err -
 	@diff -q $(SRC_PATH)/$*.exit $*.test.exit
 
 # Consolidated targets
diff --git a/tests/qapi-schema/duplicate-key.err b/tests/qapi-schema/duplicate-key.err
index 0801c6a9bb..768b276f80 100644
--- a/tests/qapi-schema/duplicate-key.err
+++ b/tests/qapi-schema/duplicate-key.err
@@ -1 +1 @@
-<stdin>:2:10: Duplicate key "key"
+tests/qapi-schema/duplicate-key.json:2:10: Duplicate key "key"
diff --git a/tests/qapi-schema/flat-union-invalid-branch-key.err b/tests/qapi-schema/flat-union-invalid-branch-key.err
index 1125caf5db..ccf72d2dfe 100644
--- a/tests/qapi-schema/flat-union-invalid-branch-key.err
+++ b/tests/qapi-schema/flat-union-invalid-branch-key.err
@@ -1 +1 @@
-<stdin>:13: Discriminator value 'value_wrong' is not found in enum 'TestEnum'
+tests/qapi-schema/flat-union-invalid-branch-key.json:13: Discriminator value 'value_wrong' is not found in enum 'TestEnum'
diff --git a/tests/qapi-schema/flat-union-invalid-discriminator.err b/tests/qapi-schema/flat-union-invalid-discriminator.err
index cad9dbf225..790b6759b8 100644
--- a/tests/qapi-schema/flat-union-invalid-discriminator.err
+++ b/tests/qapi-schema/flat-union-invalid-discriminator.err
@@ -1 +1 @@
-<stdin>:13: Discriminator 'enum_wrong' is not a member of base type 'TestBase'
+tests/qapi-schema/flat-union-invalid-discriminator.json:13: Discriminator 'enum_wrong' is not a member of base type 'TestBase'
diff --git a/tests/qapi-schema/flat-union-no-base.err b/tests/qapi-schema/flat-union-no-base.err
index e2d7443a3b..a59749eb84 100644
--- a/tests/qapi-schema/flat-union-no-base.err
+++ b/tests/qapi-schema/flat-union-no-base.err
@@ -1 +1 @@
-<stdin>:7: Flat union 'TestUnion' must have a base field
+tests/qapi-schema/flat-union-no-base.json:7: Flat union 'TestUnion' must have a base field
diff --git a/tests/qapi-schema/flat-union-string-discriminator.err b/tests/qapi-schema/flat-union-string-discriminator.err
index 87482704ec..200016bd5c 100644
--- a/tests/qapi-schema/flat-union-string-discriminator.err
+++ b/tests/qapi-schema/flat-union-string-discriminator.err
@@ -1 +1 @@
-<stdin>:13: Discriminator 'kind' must be of enumeration type
+tests/qapi-schema/flat-union-string-discriminator.json:13: Discriminator 'kind' must be of enumeration type
diff --git a/tests/qapi-schema/funny-char.err b/tests/qapi-schema/funny-char.err
index d3dd293faf..bfc890cd9f 100644
--- a/tests/qapi-schema/funny-char.err
+++ b/tests/qapi-schema/funny-char.err
@@ -1 +1 @@
-<stdin>:2:36: Stray ";"
+tests/qapi-schema/funny-char.json:2:36: Stray ";"
diff --git a/tests/qapi-schema/include-before-err.err b/tests/qapi-schema/include-before-err.err
new file mode 100644
index 0000000000..55652751e1
--- /dev/null
+++ b/tests/qapi-schema/include-before-err.err
@@ -0,0 +1 @@
+tests/qapi-schema/include-before-err.json:2:13: Expected ":"
diff --git a/tests/qapi-schema/include-before-err.exit b/tests/qapi-schema/include-before-err.exit
new file mode 100644
index 0000000000..d00491fd7e
--- /dev/null
+++ b/tests/qapi-schema/include-before-err.exit
@@ -0,0 +1 @@
+1
diff --git a/tests/qapi-schema/include-before-err.json b/tests/qapi-schema/include-before-err.json
new file mode 100644
index 0000000000..afb6cb63c4
--- /dev/null
+++ b/tests/qapi-schema/include-before-err.json
@@ -0,0 +1,2 @@
+{ 'include': 'include-simple-sub.json' }
+{ 'command' 'missing-colon' }
diff --git a/tests/qapi-schema/include-before-err.out b/tests/qapi-schema/include-before-err.out
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/tests/qapi-schema/include-before-err.out
diff --git a/tests/qapi-schema/include-cycle-b.json b/tests/qapi-schema/include-cycle-b.json
new file mode 100644
index 0000000000..4fa985dcd5
--- /dev/null
+++ b/tests/qapi-schema/include-cycle-b.json
@@ -0,0 +1 @@
+{ 'include': 'include-cycle-c.json' }
diff --git a/tests/qapi-schema/include-cycle-c.json b/tests/qapi-schema/include-cycle-c.json
new file mode 100644
index 0000000000..d12b5924a3
--- /dev/null
+++ b/tests/qapi-schema/include-cycle-c.json
@@ -0,0 +1 @@
+{ 'include': 'include-cycle.json' }
diff --git a/tests/qapi-schema/include-cycle.err b/tests/qapi-schema/include-cycle.err
new file mode 100644
index 0000000000..602cf62329
--- /dev/null
+++ b/tests/qapi-schema/include-cycle.err
@@ -0,0 +1,3 @@
+In file included from tests/qapi-schema/include-cycle.json:1:
+In file included from include-cycle-b.json:1:
+include-cycle-c.json:1: Inclusion loop for include-cycle.json
diff --git a/tests/qapi-schema/include-cycle.exit b/tests/qapi-schema/include-cycle.exit
new file mode 100644
index 0000000000..d00491fd7e
--- /dev/null
+++ b/tests/qapi-schema/include-cycle.exit
@@ -0,0 +1 @@
+1
diff --git a/tests/qapi-schema/include-cycle.json b/tests/qapi-schema/include-cycle.json
new file mode 100644
index 0000000000..6fcf1ebaac
--- /dev/null
+++ b/tests/qapi-schema/include-cycle.json
@@ -0,0 +1 @@
+{ 'include': 'include-cycle-b.json' }
diff --git a/tests/qapi-schema/include-cycle.out b/tests/qapi-schema/include-cycle.out
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/tests/qapi-schema/include-cycle.out
diff --git a/tests/qapi-schema/include-format-err.err b/tests/qapi-schema/include-format-err.err
new file mode 100644
index 0000000000..721ff4eccc
--- /dev/null
+++ b/tests/qapi-schema/include-format-err.err
@@ -0,0 +1 @@
+tests/qapi-schema/include-format-err.json:1: Invalid 'include' directive
diff --git a/tests/qapi-schema/include-format-err.exit b/tests/qapi-schema/include-format-err.exit
new file mode 100644
index 0000000000..d00491fd7e
--- /dev/null
+++ b/tests/qapi-schema/include-format-err.exit
@@ -0,0 +1 @@
+1
diff --git a/tests/qapi-schema/include-format-err.json b/tests/qapi-schema/include-format-err.json
new file mode 100644
index 0000000000..44980f026f
--- /dev/null
+++ b/tests/qapi-schema/include-format-err.json
@@ -0,0 +1,2 @@
+{ 'include': 'include-simple-sub.json',
+  'foo': 'bar' }
diff --git a/tests/qapi-schema/include-format-err.out b/tests/qapi-schema/include-format-err.out
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/tests/qapi-schema/include-format-err.out
diff --git a/tests/qapi-schema/include-nested-err.err b/tests/qapi-schema/include-nested-err.err
new file mode 100644
index 0000000000..1dacbda3be
--- /dev/null
+++ b/tests/qapi-schema/include-nested-err.err
@@ -0,0 +1,2 @@
+In file included from tests/qapi-schema/include-nested-err.json:1:
+missing-colon.json:1:10: Expected ":"
diff --git a/tests/qapi-schema/include-nested-err.exit b/tests/qapi-schema/include-nested-err.exit
new file mode 100644
index 0000000000..d00491fd7e
--- /dev/null
+++ b/tests/qapi-schema/include-nested-err.exit
@@ -0,0 +1 @@
+1
diff --git a/tests/qapi-schema/include-nested-err.json b/tests/qapi-schema/include-nested-err.json
new file mode 100644
index 0000000000..5631e56ea0
--- /dev/null
+++ b/tests/qapi-schema/include-nested-err.json
@@ -0,0 +1 @@
+{ 'include': 'missing-colon.json' }
diff --git a/tests/qapi-schema/include-nested-err.out b/tests/qapi-schema/include-nested-err.out
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/tests/qapi-schema/include-nested-err.out
diff --git a/tests/qapi-schema/include-no-file.err b/tests/qapi-schema/include-no-file.err
new file mode 100644
index 0000000000..d5b9b22d85
--- /dev/null
+++ b/tests/qapi-schema/include-no-file.err
@@ -0,0 +1 @@
+tests/qapi-schema/include-no-file.json:1: No such file or directory: include-no-file-sub.json
diff --git a/tests/qapi-schema/include-no-file.exit b/tests/qapi-schema/include-no-file.exit
new file mode 100644
index 0000000000..d00491fd7e
--- /dev/null
+++ b/tests/qapi-schema/include-no-file.exit
@@ -0,0 +1 @@
+1
diff --git a/tests/qapi-schema/include-no-file.json b/tests/qapi-schema/include-no-file.json
new file mode 100644
index 0000000000..9249ebd50c
--- /dev/null
+++ b/tests/qapi-schema/include-no-file.json
@@ -0,0 +1 @@
+{ 'include': 'include-no-file-sub.json' }
diff --git a/tests/qapi-schema/include-no-file.out b/tests/qapi-schema/include-no-file.out
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/tests/qapi-schema/include-no-file.out
diff --git a/tests/qapi-schema/include-non-file.err b/tests/qapi-schema/include-non-file.err
new file mode 100644
index 0000000000..9658c78801
--- /dev/null
+++ b/tests/qapi-schema/include-non-file.err
@@ -0,0 +1 @@
+tests/qapi-schema/include-non-file.json:1: Expected a file name (string), got: ['foo', 'bar']
diff --git a/tests/qapi-schema/include-non-file.exit b/tests/qapi-schema/include-non-file.exit
new file mode 100644
index 0000000000..d00491fd7e
--- /dev/null
+++ b/tests/qapi-schema/include-non-file.exit
@@ -0,0 +1 @@
+1
diff --git a/tests/qapi-schema/include-non-file.json b/tests/qapi-schema/include-non-file.json
new file mode 100644
index 0000000000..cd43c3f9db
--- /dev/null
+++ b/tests/qapi-schema/include-non-file.json
@@ -0,0 +1 @@
+{ 'include': [ 'foo', 'bar' ] }
diff --git a/tests/qapi-schema/include-non-file.out b/tests/qapi-schema/include-non-file.out
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/tests/qapi-schema/include-non-file.out
diff --git a/tests/qapi-schema/include-relpath-sub.json b/tests/qapi-schema/include-relpath-sub.json
new file mode 100644
index 0000000000..4bd4af4162
--- /dev/null
+++ b/tests/qapi-schema/include-relpath-sub.json
@@ -0,0 +1,2 @@
+{ 'enum': 'Status',
+  'data': [ 'good', 'bad', 'ugly' ] }
diff --git a/tests/qapi-schema/include-relpath.err b/tests/qapi-schema/include-relpath.err
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/tests/qapi-schema/include-relpath.err
diff --git a/tests/qapi-schema/include-relpath.exit b/tests/qapi-schema/include-relpath.exit
new file mode 100644
index 0000000000..573541ac97
--- /dev/null
+++ b/tests/qapi-schema/include-relpath.exit
@@ -0,0 +1 @@
+0
diff --git a/tests/qapi-schema/include-relpath.json b/tests/qapi-schema/include-relpath.json
new file mode 100644
index 0000000000..05018f3908
--- /dev/null
+++ b/tests/qapi-schema/include-relpath.json
@@ -0,0 +1 @@
+{ 'include': 'include/relpath.json' }
diff --git a/tests/qapi-schema/include-relpath.out b/tests/qapi-schema/include-relpath.out
new file mode 100644
index 0000000000..4ce3dcf12f
--- /dev/null
+++ b/tests/qapi-schema/include-relpath.out
@@ -0,0 +1,3 @@
+[OrderedDict([('enum', 'Status'), ('data', ['good', 'bad', 'ugly'])])]
+[{'enum_name': 'Status', 'enum_values': ['good', 'bad', 'ugly']}]
+[]
diff --git a/tests/qapi-schema/include-self-cycle.err b/tests/qapi-schema/include-self-cycle.err
new file mode 100644
index 0000000000..981742ae5f
--- /dev/null
+++ b/tests/qapi-schema/include-self-cycle.err
@@ -0,0 +1 @@
+tests/qapi-schema/include-self-cycle.json:1: Inclusion loop for include-self-cycle.json
diff --git a/tests/qapi-schema/include-self-cycle.exit b/tests/qapi-schema/include-self-cycle.exit
new file mode 100644
index 0000000000..d00491fd7e
--- /dev/null
+++ b/tests/qapi-schema/include-self-cycle.exit
@@ -0,0 +1 @@
+1
diff --git a/tests/qapi-schema/include-self-cycle.json b/tests/qapi-schema/include-self-cycle.json
new file mode 100644
index 0000000000..55fb1b596f
--- /dev/null
+++ b/tests/qapi-schema/include-self-cycle.json
@@ -0,0 +1 @@
+{ 'include': 'include-self-cycle.json' }
diff --git a/tests/qapi-schema/include-self-cycle.out b/tests/qapi-schema/include-self-cycle.out
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/tests/qapi-schema/include-self-cycle.out
diff --git a/tests/qapi-schema/include-simple-sub.json b/tests/qapi-schema/include-simple-sub.json
new file mode 100644
index 0000000000..4bd4af4162
--- /dev/null
+++ b/tests/qapi-schema/include-simple-sub.json
@@ -0,0 +1,2 @@
+{ 'enum': 'Status',
+  'data': [ 'good', 'bad', 'ugly' ] }
diff --git a/tests/qapi-schema/include-simple.err b/tests/qapi-schema/include-simple.err
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/tests/qapi-schema/include-simple.err
diff --git a/tests/qapi-schema/include-simple.exit b/tests/qapi-schema/include-simple.exit
new file mode 100644
index 0000000000..573541ac97
--- /dev/null
+++ b/tests/qapi-schema/include-simple.exit
@@ -0,0 +1 @@
+0
diff --git a/tests/qapi-schema/include-simple.json b/tests/qapi-schema/include-simple.json
new file mode 100644
index 0000000000..1dd391a592
--- /dev/null
+++ b/tests/qapi-schema/include-simple.json
@@ -0,0 +1 @@
+{ 'include': 'include-simple-sub.json' }
diff --git a/tests/qapi-schema/include-simple.out b/tests/qapi-schema/include-simple.out
new file mode 100644
index 0000000000..4ce3dcf12f
--- /dev/null
+++ b/tests/qapi-schema/include-simple.out
@@ -0,0 +1,3 @@
+[OrderedDict([('enum', 'Status'), ('data', ['good', 'bad', 'ugly'])])]
+[{'enum_name': 'Status', 'enum_values': ['good', 'bad', 'ugly']}]
+[]
diff --git a/tests/qapi-schema/include/relpath.json b/tests/qapi-schema/include/relpath.json
new file mode 100644
index 0000000000..45dee24704
--- /dev/null
+++ b/tests/qapi-schema/include/relpath.json
@@ -0,0 +1 @@
+{ 'include': '../include-relpath-sub.json' }
diff --git a/tests/qapi-schema/missing-colon.err b/tests/qapi-schema/missing-colon.err
index 9f2a35515c..d9d66b377a 100644
--- a/tests/qapi-schema/missing-colon.err
+++ b/tests/qapi-schema/missing-colon.err
@@ -1 +1 @@
-<stdin>: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 4fe0700195..e73d2770d6 100644
--- a/tests/qapi-schema/missing-comma-list.err
+++ b/tests/qapi-schema/missing-comma-list.err
@@ -1 +1 @@
-<stdin>: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 b0121b5f3a..52b3a8a1ec 100644
--- a/tests/qapi-schema/missing-comma-object.err
+++ b/tests/qapi-schema/missing-comma-object.err
@@ -1 +1 @@
-<stdin>: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 a6c2dc26a6..334f0c91ae 100644
--- a/tests/qapi-schema/non-objects.err
+++ b/tests/qapi-schema/non-objects.err
@@ -1 +1 @@
-<stdin>:1:1: Expected "{"
+tests/qapi-schema/non-objects.json:1:1: Expected "{"
diff --git a/tests/qapi-schema/quoted-structural-chars.err b/tests/qapi-schema/quoted-structural-chars.err
index a6c2dc26a6..9b183841dd 100644
--- a/tests/qapi-schema/quoted-structural-chars.err
+++ b/tests/qapi-schema/quoted-structural-chars.err
@@ -1 +1 @@
-<stdin>:1:1: Expected "{"
+tests/qapi-schema/quoted-structural-chars.json:1:1: Expected "{"
diff --git a/tests/qapi-schema/test-qapi.py b/tests/qapi-schema/test-qapi.py
index b3d1e1dbce..634ef2d00a 100644
--- a/tests/qapi-schema/test-qapi.py
+++ b/tests/qapi-schema/test-qapi.py
@@ -12,15 +12,13 @@
 
 from qapi import *
 from pprint import pprint
+import os
 import sys
 
 try:
-    exprs = parse_schema(sys.stdin)
+    exprs = parse_schema(sys.argv[1])
 except SystemExit:
     raise
-except:
-    print >>sys.stderr, "Crashed:", sys.exc_info()[0]
-    exit(1)
 
 pprint(exprs)
 pprint(enum_types)
diff --git a/tests/qapi-schema/trailing-comma-list.err b/tests/qapi-schema/trailing-comma-list.err
index ff839a34e9..24c24b0108 100644
--- a/tests/qapi-schema/trailing-comma-list.err
+++ b/tests/qapi-schema/trailing-comma-list.err
@@ -1 +1 @@
-<stdin>:2:36: Expected "{", "[" or string
+tests/qapi-schema/trailing-comma-list.json:2:36: Expected "{", "[" or string
diff --git a/tests/qapi-schema/trailing-comma-object.err b/tests/qapi-schema/trailing-comma-object.err
index f5409627da..30bce5e194 100644
--- a/tests/qapi-schema/trailing-comma-object.err
+++ b/tests/qapi-schema/trailing-comma-object.err
@@ -1 +1 @@
-<stdin>:2:38: Expected string
+tests/qapi-schema/trailing-comma-object.json:2:38: Expected string
diff --git a/tests/qapi-schema/unclosed-list.err b/tests/qapi-schema/unclosed-list.err
index 0e837a7fad..fb41a86abd 100644
--- a/tests/qapi-schema/unclosed-list.err
+++ b/tests/qapi-schema/unclosed-list.err
@@ -1 +1 @@
-<stdin>: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 e6dc9501dc..db3deedd63 100644
--- a/tests/qapi-schema/unclosed-object.err
+++ b/tests/qapi-schema/unclosed-object.err
@@ -1 +1 @@
-<stdin>:1:21: Expected "," or "}"
+tests/qapi-schema/unclosed-object.json:1:21: Expected "," or "}"
diff --git a/tests/qapi-schema/unclosed-string.err b/tests/qapi-schema/unclosed-string.err
index 948d88339d..12b187074e 100644
--- a/tests/qapi-schema/unclosed-string.err
+++ b/tests/qapi-schema/unclosed-string.err
@@ -1 +1 @@
-<stdin>:1:11: Missing terminating "'"
+tests/qapi-schema/unclosed-string.json:1:11: Missing terminating "'"
diff --git a/tests/qapi-schema/union-invalid-base.err b/tests/qapi-schema/union-invalid-base.err
index dd8e3d1b3b..938f96962b 100644
--- a/tests/qapi-schema/union-invalid-base.err
+++ b/tests/qapi-schema/union-invalid-base.err
@@ -1 +1 @@
-<stdin>:7: Base 'TestBaseWrong' is not a valid type
+tests/qapi-schema/union-invalid-base.json:7: Base 'TestBaseWrong' is not a valid type
diff --git a/tests/qemu-iotests/031 b/tests/qemu-iotests/031
index 1d920ea87a..5aefb88b60 100755
--- a/tests/qemu-iotests/031
+++ b/tests/qemu-iotests/031
@@ -35,6 +35,7 @@ _cleanup()
 trap "_cleanup; exit \$status" 0 1 2 3 15
 
 # get standard environment, filters and checks
+. ./common.env
 . ./common.rc
 . ./common.filter
 . ./common.pattern
@@ -56,22 +57,22 @@ for IMGOPTS in "compat=0.10" "compat=1.1"; do
     echo === Create image with unknown header extension ===
     echo
     _make_test_img 64M
-    ./qcow2.py "$TEST_IMG" add-header-ext 0x12345678 "This is a test header extension"
-    ./qcow2.py "$TEST_IMG" dump-header
+    $PYTHON qcow2.py "$TEST_IMG" add-header-ext 0x12345678 "This is a test header extension"
+    $PYTHON qcow2.py "$TEST_IMG" dump-header
     _check_test_img
 
     echo
     echo === Rewrite header with no backing file ===
     echo
     $QEMU_IMG rebase -u -b "" "$TEST_IMG"
-    ./qcow2.py "$TEST_IMG" dump-header
+    $PYTHON qcow2.py "$TEST_IMG" dump-header
     _check_test_img
 
     echo
     echo === Add a backing file and format ===
     echo
     $QEMU_IMG rebase -u -b "/some/backing/file/path" -F host_device "$TEST_IMG"
-    ./qcow2.py "$TEST_IMG" dump-header
+    $PYTHON qcow2.py "$TEST_IMG" dump-header
 done
 
 # success, all done
diff --git a/tests/qemu-iotests/036 b/tests/qemu-iotests/036
index 03b6aa9de7..29c35d1004 100755
--- a/tests/qemu-iotests/036
+++ b/tests/qemu-iotests/036
@@ -38,6 +38,7 @@ _cleanup()
 trap "_cleanup; exit \$status" 0 1 2 3 15
 
 # get standard environment, filters and checks
+. ./common.env
 . ./common.rc
 . ./common.filter
 . ./common.pattern
@@ -53,15 +54,15 @@ IMGOPTS="compat=1.1"
 echo === Create image with unknown autoclear feature bit ===
 echo
 _make_test_img 64M
-./qcow2.py "$TEST_IMG" set-feature-bit autoclear 63
-./qcow2.py "$TEST_IMG" dump-header
+$PYTHON qcow2.py "$TEST_IMG" set-feature-bit autoclear 63
+$PYTHON qcow2.py "$TEST_IMG" dump-header
 
 echo
 echo === Repair image ===
 echo
 _check_test_img -r all
 
-./qcow2.py "$TEST_IMG" dump-header
+$PYTHON qcow2.py "$TEST_IMG" dump-header
 
 # success, all done
 echo "*** done"
diff --git a/tests/qemu-iotests/039 b/tests/qemu-iotests/039
index b9cbe99560..b7b70300fc 100755
--- a/tests/qemu-iotests/039
+++ b/tests/qemu-iotests/039
@@ -38,6 +38,7 @@ _cleanup()
 trap "_cleanup; exit \$status" 0 1 2 3 15
 
 # get standard environment, filters and checks
+. ./common.env
 . ./common.rc
 . ./common.filter
 
@@ -58,7 +59,7 @@ _make_test_img $size
 $QEMU_IO -c "write -P 0x5a 0 512" "$TEST_IMG" | _filter_qemu_io
 
 # The dirty bit must not be set
-./qcow2.py "$TEST_IMG" dump-header | grep incompatible_features
+$PYTHON qcow2.py "$TEST_IMG" dump-header | grep incompatible_features
 _check_test_img
 
 echo
@@ -73,7 +74,7 @@ $QEMU_IO -c "write -P 0x5a 0 512" -c "abort" "$TEST_IMG" | _filter_qemu_io
 ulimit -c "$old_ulimit"
 
 # The dirty bit must be set
-./qcow2.py "$TEST_IMG" dump-header | grep incompatible_features
+$PYTHON qcow2.py "$TEST_IMG" dump-header | grep incompatible_features
 _check_test_img
 
 echo
@@ -82,7 +83,7 @@ echo "== Read-only access must still work =="
 $QEMU_IO -r -c "read -P 0x5a 0 512" "$TEST_IMG" | _filter_qemu_io
 
 # The dirty bit must be set
-./qcow2.py "$TEST_IMG" dump-header | grep incompatible_features
+$PYTHON qcow2.py "$TEST_IMG" dump-header | grep incompatible_features
 
 echo
 echo "== Repairing the image file must succeed =="
@@ -90,7 +91,7 @@ echo "== Repairing the image file must succeed =="
 _check_test_img -r all
 
 # The dirty bit must not be set
-./qcow2.py "$TEST_IMG" dump-header | grep incompatible_features
+$PYTHON qcow2.py "$TEST_IMG" dump-header | grep incompatible_features
 
 echo
 echo "== Data should still be accessible after repair =="
@@ -109,12 +110,12 @@ $QEMU_IO -c "write -P 0x5a 0 512" -c "abort" "$TEST_IMG" | _filter_qemu_io
 ulimit -c "$old_ulimit"
 
 # The dirty bit must be set
-./qcow2.py "$TEST_IMG" dump-header | grep incompatible_features
+$PYTHON qcow2.py "$TEST_IMG" dump-header | grep incompatible_features
 
 $QEMU_IO -c "write 0 512" "$TEST_IMG" | _filter_qemu_io
 
 # The dirty bit must not be set
-./qcow2.py "$TEST_IMG" dump-header | grep incompatible_features
+$PYTHON qcow2.py "$TEST_IMG" dump-header | grep incompatible_features
 
 echo
 echo "== Creating an image file with lazy_refcounts=off =="
@@ -128,7 +129,7 @@ $QEMU_IO -c "write -P 0x5a 0 512" -c "abort" "$TEST_IMG" | _filter_qemu_io
 ulimit -c "$old_ulimit"
 
 # The dirty bit must not be set since lazy_refcounts=off
-./qcow2.py "$TEST_IMG" dump-header | grep incompatible_features
+$PYTHON qcow2.py "$TEST_IMG" dump-header | grep incompatible_features
 _check_test_img
 
 echo
@@ -144,8 +145,8 @@ $QEMU_IO -c "write 0 512" "$TEST_IMG" | _filter_qemu_io
 $QEMU_IMG commit "$TEST_IMG"
 
 # The dirty bit must not be set
-./qcow2.py "$TEST_IMG" dump-header | grep incompatible_features
-./qcow2.py "$TEST_IMG".base dump-header | grep incompatible_features
+$PYTHON qcow2.py "$TEST_IMG" dump-header | grep incompatible_features
+$PYTHON qcow2.py "$TEST_IMG".base dump-header | grep incompatible_features
 
 _check_test_img
 TEST_IMG="$TEST_IMG".base _check_test_img
diff --git a/tests/qemu-iotests/051 b/tests/qemu-iotests/051
index 073dc7a2d3..c4af131a66 100755
--- a/tests/qemu-iotests/051
+++ b/tests/qemu-iotests/051
@@ -233,6 +233,10 @@ echo 'qemu-io ide0-hd0 "write -P 0x22 0 4k"' | run_qemu -drive file="$TEST_IMG",
 
 $QEMU_IO -c "read -P 0x22 0 4k" "$TEST_IMG" | _filter_qemu_io
 
+echo -e 'qemu-io ide0-hd0 "write -P 0x33 0 4k"\ncommit ide0-hd0' | run_qemu -drive file="$TEST_IMG",snapshot=on | _filter_qemu_io
+
+$QEMU_IO -c "read -P 0x33 0 4k" "$TEST_IMG" | _filter_qemu_io
+
 # success, all done
 echo "*** done"
 rm -f $seq.full
diff --git a/tests/qemu-iotests/051.out b/tests/qemu-iotests/051.out
index 01b0384472..31e329e893 100644
--- a/tests/qemu-iotests/051.out
+++ b/tests/qemu-iotests/051.out
@@ -358,4 +358,14 @@ wrote 4096/4096 bytes at offset 0
 
 read 4096/4096 bytes at offset 0
 4 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+Testing: -drive file=TEST_DIR/t.qcow2,snapshot=on
+QEMU X.Y.Z monitor - type 'help' for more information
+(qemu) qqeqemqemuqemu-qemu-iqemu-ioqemu-io qemu-io iqemu-io idqemu-io ideqemu-io ide0qemu-io ide0-qemu-io ide0-hqemu-io ide0-hdqemu-io ide0-hd0qemu-io ide0-hd0 qemu-io ide0-hd0 "qemu-io ide0-hd0 "wqemu-io ide0-hd0 "wrqemu-io ide0-hd0 "wriqemu-io ide0-hd0 "writqemu-io ide0-hd0 "writeqemu-io ide0-hd0 "write qemu-io ide0-hd0 "write -qemu-io ide0-hd0 "write -Pqemu-io ide0-hd0 "write -P qemu-io ide0-hd0 "write -P 0qemu-io ide0-hd0 "write -P 0xqemu-io ide0-hd0 "write -P 0x3qemu-io ide0-hd0 "write -P 0x33qemu-io ide0-hd0 "write -P 0x33 qemu-io ide0-hd0 "write -P 0x33 0qemu-io ide0-hd0 "write -P 0x33 0 qemu-io ide0-hd0 "write -P 0x33 0 4qemu-io ide0-hd0 "write -P 0x33 0 4kqemu-io ide0-hd0 "write -P 0x33 0 4k"
+wrote 4096/4096 bytes at offset 0
+4 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+(qemu) ccocomcommcommicommitcommit commit icommit idcommit idecommit ide0commit ide0-commit ide0-hcommit ide0-hdcommit ide0-hd0
+(qemu) qququiquit
+
+read 4096/4096 bytes at offset 0
+4 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
 *** done
diff --git a/tests/qemu-iotests/054 b/tests/qemu-iotests/054
index c8b7082b4e..a5ebf99450 100755
--- a/tests/qemu-iotests/054
+++ b/tests/qemu-iotests/054
@@ -35,6 +35,7 @@ _cleanup()
 trap "_cleanup; exit \$status" 0 1 2 3 15
 
 # get standard environment, filters and checks
+. ./common.env
 . ./common.rc
 . ./common.filter
 
@@ -49,7 +50,7 @@ _make_test_img $((1024*1024))T
 echo
 echo "creating too large image (1 EB) using qcow2.py"
 _make_test_img 4G
-./qcow2.py "$TEST_IMG" set-header size $((1024 ** 6))
+$PYTHON qcow2.py "$TEST_IMG" set-header size $((1024 ** 6))
 _check_test_img
 
 # success, all done
diff --git a/tests/qemu-iotests/059 b/tests/qemu-iotests/059
index ca5aa16ff7..26a2fd3e0e 100755
--- a/tests/qemu-iotests/059
+++ b/tests/qemu-iotests/059
@@ -104,6 +104,13 @@ truncate -s 10M $TEST_IMG
 _img_info
 
 echo
+echo "=== Converting to streamOptimized from image with small cluster size==="
+TEST_IMG="$TEST_IMG.qcow2" IMGFMT=qcow2 IMGOPTS="cluster_size=4096" _make_test_img 1G
+$QEMU_IO -c "write -P 0xa 0 512" "$TEST_IMG.qcow2" | _filter_qemu_io
+$QEMU_IO -c "write -P 0xb 10240 512" "$TEST_IMG.qcow2" | _filter_qemu_io
+$QEMU_IMG convert -f qcow2 -O vmdk -o subformat=streamOptimized "$TEST_IMG.qcow2" "$TEST_IMG" 2>&1
+
+echo
 echo "=== Testing version 3 ==="
 _use_sample_img iotest-version3.vmdk.bz2
 _img_info
diff --git a/tests/qemu-iotests/059.out b/tests/qemu-iotests/059.out
index 3371c867bb..eba0dedda0 100644
--- a/tests/qemu-iotests/059.out
+++ b/tests/qemu-iotests/059.out
@@ -2046,10 +2046,18 @@ RW 12582912 VMFS "dummy.IMGFMT" 1
 Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=107374182400
 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===
+Formatting 'TEST_DIR/t.vmdk.IMGFMT', fmt=IMGFMT size=1073741824
+wrote 512/512 bytes at offset 0
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+wrote 512/512 bytes at offset 10240
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+
 === Testing version 3 ===
 image: TEST_DIR/iotest-version3.IMGFMT
 file format: IMGFMT
 virtual size: 1.0G (1073741824 bytes)
+cluster_size: 65536
 
 === Testing 4TB monolithicFlat creation and IO ===
 Formatting 'TEST_DIR/iotest-version3.IMGFMT', fmt=IMGFMT size=4398046511104
diff --git a/tests/qemu-iotests/060 b/tests/qemu-iotests/060
index f0116aab1d..5447b27a1a 100755
--- a/tests/qemu-iotests/060
+++ b/tests/qemu-iotests/060
@@ -35,6 +35,7 @@ _cleanup()
 trap "_cleanup; exit \$status" 0 1 2 3 15
 
 # get standard environment, filters and checks
+. ./common.env
 . ./common.rc
 . ./common.filter
 
@@ -68,13 +69,13 @@ poke_file "$TEST_IMG" "$l1_offset" "\x80\x00\x00\x00\x00\x03\x00\x00"
 _check_test_img
 
 # The corrupt bit should not be set anyway
-./qcow2.py "$TEST_IMG" dump-header | grep incompatible_features
+$PYTHON qcow2.py "$TEST_IMG" dump-header | grep incompatible_features
 
 # Try to write something, thereby forcing the corrupt bit to be set
 $QEMU_IO -c "$OPEN_RW" -c "write -P 0x2a 0 512" | _filter_qemu_io
 
 # The corrupt bit must now be set
-./qcow2.py "$TEST_IMG" dump-header | grep incompatible_features
+$PYTHON qcow2.py "$TEST_IMG" dump-header | grep incompatible_features
 
 # Try to open the image R/W (which should fail)
 $QEMU_IO -c "$OPEN_RW" -c "read 0 512" 2>&1 | _filter_qemu_io \
@@ -99,19 +100,19 @@ poke_file "$TEST_IMG" "$(($rb_offset+8))" "\x00\x01"
 # Redirect new data cluster onto refcount block
 poke_file "$TEST_IMG" "$l2_offset" "\x80\x00\x00\x00\x00\x02\x00\x00"
 _check_test_img
-./qcow2.py "$TEST_IMG" dump-header | grep incompatible_features
+$PYTHON qcow2.py "$TEST_IMG" dump-header | grep incompatible_features
 $QEMU_IO -c "$OPEN_RW" -c "write -P 0x2a 0 512" | _filter_qemu_io
-./qcow2.py "$TEST_IMG" dump-header | grep incompatible_features
+$PYTHON qcow2.py "$TEST_IMG" dump-header | grep incompatible_features
 
 # Try to fix it
 _check_test_img -r all
 
 # The corrupt bit should be cleared
-./qcow2.py "$TEST_IMG" dump-header | grep incompatible_features
+$PYTHON qcow2.py "$TEST_IMG" dump-header | grep incompatible_features
 
 # Look if it's really really fixed
 $QEMU_IO -c "$OPEN_RW" -c "write -P 0x2a 0 512" | _filter_qemu_io
-./qcow2.py "$TEST_IMG" dump-header | grep incompatible_features
+$PYTHON qcow2.py "$TEST_IMG" dump-header | grep incompatible_features
 
 echo
 echo "=== Testing cluster data reference into inactive L2 table ==="
@@ -124,13 +125,13 @@ $QEMU_IO -c "$OPEN_RW" -c "write -P 2 0 512" | _filter_qemu_io
 poke_file "$TEST_IMG" "$l2_offset_after_snapshot" \
                       "\x80\x00\x00\x00\x00\x04\x00\x00"
 _check_test_img
-./qcow2.py "$TEST_IMG" dump-header | grep incompatible_features
+$PYTHON qcow2.py "$TEST_IMG" dump-header | grep incompatible_features
 $QEMU_IO -c "$OPEN_RW" -c "write -P 3 0 512" | _filter_qemu_io
-./qcow2.py "$TEST_IMG" dump-header | grep incompatible_features
+$PYTHON qcow2.py "$TEST_IMG" dump-header | grep incompatible_features
 _check_test_img -r all
-./qcow2.py "$TEST_IMG" dump-header | grep incompatible_features
+$PYTHON qcow2.py "$TEST_IMG" dump-header | grep incompatible_features
 $QEMU_IO -c "$OPEN_RW" -c "write -P 4 0 512" | _filter_qemu_io
-./qcow2.py "$TEST_IMG" dump-header | grep incompatible_features
+$PYTHON qcow2.py "$TEST_IMG" dump-header | grep incompatible_features
 
 # Check data
 $QEMU_IO -c "$OPEN_RO" -c "read -P 4 0 512" | _filter_qemu_io
diff --git a/tests/qemu-iotests/061 b/tests/qemu-iotests/061
index d3a6b388b5..0de789734f 100755
--- a/tests/qemu-iotests/061
+++ b/tests/qemu-iotests/061
@@ -35,6 +35,7 @@ _cleanup()
 trap "_cleanup; exit \$status" 0 1 2 3 15
 
 # get standard environment, filters and checks
+. ./common.env
 . ./common.rc
 . ./common.filter
 
@@ -48,9 +49,9 @@ echo "=== Testing version downgrade with zero expansion ==="
 echo
 IMGOPTS="compat=1.1,lazy_refcounts=on" _make_test_img 64M
 $QEMU_IO -c "write -z 0 128k" "$TEST_IMG" | _filter_qemu_io
-./qcow2.py "$TEST_IMG" dump-header
+$PYTHON qcow2.py "$TEST_IMG" dump-header
 $QEMU_IMG amend -o "compat=0.10" "$TEST_IMG"
-./qcow2.py "$TEST_IMG" dump-header
+$PYTHON qcow2.py "$TEST_IMG" dump-header
 $QEMU_IO -c "read -P 0 0 128k" "$TEST_IMG" | _filter_qemu_io
 _check_test_img
 
@@ -59,9 +60,9 @@ 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" | _filter_qemu_io
-./qcow2.py "$TEST_IMG" dump-header
+$PYTHON qcow2.py "$TEST_IMG" dump-header
 $QEMU_IMG amend -o "compat=0.10" "$TEST_IMG"
-./qcow2.py "$TEST_IMG" dump-header
+$PYTHON qcow2.py "$TEST_IMG" dump-header
 $QEMU_IO -c "read -P 0x2a 0 128k" "$TEST_IMG" | _filter_qemu_io
 _check_test_img
 
@@ -69,11 +70,11 @@ echo
 echo "=== Testing version downgrade with unknown compat/autoclear flags ==="
 echo
 IMGOPTS="compat=1.1" _make_test_img 64M
-./qcow2.py "$TEST_IMG" set-feature-bit compatible 42
-./qcow2.py "$TEST_IMG" set-feature-bit autoclear 42
-./qcow2.py "$TEST_IMG" dump-header
+$PYTHON qcow2.py "$TEST_IMG" set-feature-bit compatible 42
+$PYTHON qcow2.py "$TEST_IMG" set-feature-bit autoclear 42
+$PYTHON qcow2.py "$TEST_IMG" dump-header
 $QEMU_IMG amend -o "compat=0.10" "$TEST_IMG"
-./qcow2.py "$TEST_IMG" dump-header
+$PYTHON qcow2.py "$TEST_IMG" dump-header
 _check_test_img
 
 echo
@@ -81,9 +82,9 @@ echo "=== Testing version upgrade and resize ==="
 echo
 IMGOPTS="compat=0.10" _make_test_img 64M
 $QEMU_IO -c "write -P 0x2a 42M 64k" "$TEST_IMG" | _filter_qemu_io
-./qcow2.py "$TEST_IMG" dump-header
+$PYTHON qcow2.py "$TEST_IMG" dump-header
 $QEMU_IMG amend -o "compat=1.1,lazy_refcounts=on,size=128M" "$TEST_IMG"
-./qcow2.py "$TEST_IMG" dump-header
+$PYTHON qcow2.py "$TEST_IMG" dump-header
 $QEMU_IO -c "read -P 0x2a 42M 64k" "$TEST_IMG" | _filter_qemu_io
 _check_test_img
 
@@ -92,9 +93,9 @@ 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" | _filter_qemu_io
-./qcow2.py "$TEST_IMG" dump-header
+$PYTHON qcow2.py "$TEST_IMG" dump-header
 $QEMU_IMG amend -o "lazy_refcounts=off" "$TEST_IMG"
-./qcow2.py "$TEST_IMG" dump-header
+$PYTHON qcow2.py "$TEST_IMG" dump-header
 $QEMU_IO -c "read -P 0x2a 0 128k" "$TEST_IMG" | _filter_qemu_io
 _check_test_img
 
diff --git a/tests/qemu-iotests/065 b/tests/qemu-iotests/065
index ab5445f62d..e89b61d70b 100755
--- a/tests/qemu-iotests/065
+++ b/tests/qemu-iotests/065
@@ -1,4 +1,4 @@
-#!/usr/bin/env python2
+#!/usr/bin/env python
 #
 # Test for additional information emitted by qemu-img info on qcow2
 # images
diff --git a/tests/qemu-iotests/083 b/tests/qemu-iotests/083
index f764534782..6a52c96bba 100755
--- a/tests/qemu-iotests/083
+++ b/tests/qemu-iotests/083
@@ -29,6 +29,7 @@ tmp=/tmp/$$
 status=1	# failure is the default!
 
 # get standard environment, filters and checks
+. ./common.env
 . ./common.rc
 . ./common.filter
 
@@ -81,7 +82,7 @@ EOF
 		nbd_url="nbd:127.0.0.1:$port:exportname=foo"
 	fi
 
-	./nbd-fault-injector.py $extra_args "127.0.0.1:$port" "$TEST_DIR/nbd-fault-injector.conf" 2>&1 >/dev/null &
+	$PYTHON nbd-fault-injector.py $extra_args "127.0.0.1:$port" "$TEST_DIR/nbd-fault-injector.conf" 2>&1 >/dev/null &
 	wait_for_tcp_port "127.0.0.1:$port"
 	$QEMU_IO -c "read 0 512" "$nbd_url" 2>&1 | _filter_qemu_io | filter_nbd
 
diff --git a/tests/qemu-iotests/085 b/tests/qemu-iotests/085
index 33c8dc410a..56cd6f89b7 100755
--- a/tests/qemu-iotests/085
+++ b/tests/qemu-iotests/085
@@ -30,10 +30,6 @@ echo "QA output created by $seq"
 
 here=`pwd`
 status=1	# failure is the default!
-qemu_pid=
-
-QMP_IN="${TEST_DIR}/qmp-in-$$"
-QMP_OUT="${TEST_DIR}/qmp-out-$$"
 
 snapshot_virt0="snapshot-v0.qcow2"
 snapshot_virt1="snapshot-v1.qcow2"
@@ -42,10 +38,7 @@ MAX_SNAPSHOTS=10
 
 _cleanup()
 {
-    kill -KILL ${qemu_pid}
-    wait ${qemu_pid} 2>/dev/null  # silent kill
-
-    rm -f "${QMP_IN}" "${QMP_OUT}"
+    _cleanup_qemu
     for i in $(seq 1 ${MAX_SNAPSHOTS})
     do
         rm -f "${TEST_DIR}/${i}-${snapshot_virt0}"
@@ -59,43 +52,12 @@ trap "_cleanup; exit \$status" 0 1 2 3 15
 # get standard environment, filters and checks
 . ./common.rc
 . ./common.filter
+. ./common.qemu
 
 _supported_fmt qcow2
 _supported_proto file
 _supported_os Linux
 
-# Wait for expected QMP response from QEMU.  Will time out
-# after 10 seconds, which counts as failure.
-#
-# $1 is the string to expect
-#
-# If $silent is set to anything but an empty string, then
-# response is not echoed out.
-function timed_wait_for()
-{
-    while read -t 10 resp <&5
-    do
-        if [ "${silent}" == "" ]; then
-            echo "${resp}" | _filter_testdir | _filter_qemu
-        fi
-        grep -q "${1}" < <(echo ${resp})
-        if [ $? -eq 0 ]; then
-            return
-        fi
-    done
-    echo "Timeout waiting for ${1}"
-    exit 1  # Timeout means the test failed
-}
-
-# Sends QMP command to QEMU, and waits for the expected response
-#
-# ${1}:  String of the QMP command to send
-# ${2}:  String that the QEMU response should contain
-function send_qmp_cmd()
-{
-    echo "${1}" >&6
-    timed_wait_for "${2}"
-}
 
 # ${1}: unique identifier for the snapshot filename
 function create_single_snapshot()
@@ -104,7 +66,7 @@ function create_single_snapshot()
                       'arguments': { 'device': 'virtio0',
                                      'snapshot-file':'"${TEST_DIR}/${1}-${snapshot_virt0}"',
                                      'format': 'qcow2' } }"
-    send_qmp_cmd "${cmd}" "return"
+    _send_qemu_cmd $h "${cmd}" "return"
 }
 
 # ${1}: unique identifier for the snapshot filename
@@ -120,14 +82,11 @@ function create_group_snapshot()
                        'snapshot-file': '"${TEST_DIR}/${1}-${snapshot_virt1}"' } } ]
              } }"
 
-    send_qmp_cmd "${cmd}" "return"
+    _send_qemu_cmd $h "${cmd}" "return"
 }
 
 size=128M
 
-mkfifo "${QMP_IN}"
-mkfifo "${QMP_OUT}"
-
 _make_test_img $size
 mv "${TEST_IMG}" "${TEST_IMG}.orig"
 _make_test_img $size
@@ -136,23 +95,15 @@ echo
 echo === Running QEMU ===
 echo
 
-"${QEMU}" -nographic -monitor none -serial none -qmp stdio\
-          -drive file="${TEST_IMG}.orig",if=virtio\
-          -drive file="${TEST_IMG}",if=virtio 2>&1 >"${QMP_OUT}" <"${QMP_IN}"&
-qemu_pid=$!
-
-# redirect fifos to file descriptors, to keep from blocking
-exec 5<"${QMP_OUT}"
-exec 6>"${QMP_IN}"
-
-# Don't print response, since it has version information in it
-silent=yes timed_wait_for "capabilities"
+qemu_comm_method="qmp"
+_launch_qemu -drive file="${TEST_IMG}.orig",if=virtio -drive file="${TEST_IMG}",if=virtio
+h=$QEMU_HANDLE
 
 echo
 echo === Sending capabilities ===
 echo
 
-send_qmp_cmd "{ 'execute': 'qmp_capabilities' }" "return"
+_send_qemu_cmd $h "{ 'execute': 'qmp_capabilities' }" "return"
 
 echo
 echo === Create a single snapshot on virtio0 ===
@@ -165,16 +116,16 @@ echo
 echo === Invalid command - missing device and nodename ===
 echo
 
-send_qmp_cmd "{ 'execute': 'blockdev-snapshot-sync',
-                      'arguments': { 'snapshot-file':'"${TEST_DIR}"/1-${snapshot_virt0}',
+_send_qemu_cmd $h "{ 'execute': 'blockdev-snapshot-sync',
+                         'arguments': { 'snapshot-file':'"${TEST_DIR}/1-${snapshot_virt0}"',
                                      'format': 'qcow2' } }" "error"
 
 echo
 echo === Invalid command - missing snapshot-file ===
 echo
 
-send_qmp_cmd "{ 'execute': 'blockdev-snapshot-sync',
-                      'arguments': { 'device': 'virtio0',
+_send_qemu_cmd $h "{ 'execute': 'blockdev-snapshot-sync',
+                         'arguments': { 'device': 'virtio0',
                                      'format': 'qcow2' } }" "error"
 echo
 echo
diff --git a/tests/qemu-iotests/091 b/tests/qemu-iotests/091
new file mode 100755
index 0000000000..384b3ace54
--- /dev/null
+++ b/tests/qemu-iotests/091
@@ -0,0 +1,105 @@
+#!/bin/bash
+#
+# Live migration test
+#
+# Performs a migration from one VM to another via monitor commands
+#
+# Copyright (C) 2014 Red Hat, Inc.
+#
+# 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/>.
+#
+
+# creator
+owner=jcody@redhat.com
+
+seq=`basename $0`
+echo "QA output created by $seq"
+
+here=`pwd`
+status=1    # failure is the default!
+
+MIG_FIFO="${TEST_DIR}/migrate"
+
+_cleanup()
+{
+    rm -f "${MIG_FIFO}"
+    _cleanup_qemu
+    _cleanup_test_img
+}
+trap "_cleanup; exit \$status" 0 1 2 3 15
+
+# get standard environment, filters and checks
+. ./common.rc
+. ./common.filter
+. ./common.qemu
+
+_supported_fmt qcow2
+_supported_proto file
+_supported_os Linux
+
+size=1G
+
+_make_test_img $size
+
+mkfifo "${MIG_FIFO}"
+
+echo
+echo === Starting QEMU VM1 ===
+echo
+
+qemu_comm_method="monitor"
+_launch_qemu -drive file="${TEST_IMG}",cache=none,id=disk
+h1=$QEMU_HANDLE
+
+echo
+echo === Starting QEMU VM2 ===
+echo
+_launch_qemu -drive file="${TEST_IMG}",cache=none,id=disk \
+             -incoming "exec: cat '${MIG_FIFO}'"
+h2=$QEMU_HANDLE
+
+echo
+echo === VM 1: Migrate from VM1 to VM2  ===
+echo
+
+silent=yes
+_send_qemu_cmd $h1 'qemu-io disk "write -P 0x22 0 4M"' "(qemu)"
+echo "vm1: qemu-io disk write complete"
+_send_qemu_cmd $h1 "migrate \"exec: cat > '${MIG_FIFO}'\"" "(qemu)"
+echo "vm1: live migration started"
+qemu_cmd_repeat=20 _send_qemu_cmd $h1 "info migrate" "completed"
+echo "vm1: live migration completed"
+
+echo
+echo === VM 2: Post-migration, write to disk, verify running ===
+echo
+
+_send_qemu_cmd $h2 'qemu-io disk "write 4M 1M"' "(qemu)"
+echo "vm2: qemu-io disk write complete"
+qemu_cmd_repeat=20 _send_qemu_cmd $h2 "info status" "running"
+echo "vm2: qemu process running successfully"
+
+echo "vm2: flush io, and quit"
+_send_qemu_cmd $h2 'qemu-io disk flush' "(qemu)"
+_send_qemu_cmd $h2 'quit' ""
+
+echo "Check image pattern"
+${QEMU_IO} -c "read -P 0x22 0 4M" "${TEST_IMG}" | _filter_testdir | _filter_qemu_io
+
+echo "Running 'qemu-img check -r all \$TEST_IMG'"
+"${QEMU_IMG}" check -r all "${TEST_IMG}" 2>&1 | _filter_testdir | _filter_qemu
+
+echo "*** done"
+rm -f $seq.full
+status=0
diff --git a/tests/qemu-iotests/091.out b/tests/qemu-iotests/091.out
new file mode 100644
index 0000000000..a2e0122966
--- /dev/null
+++ b/tests/qemu-iotests/091.out
@@ -0,0 +1,28 @@
+QA output created by 091
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824 
+
+=== Starting QEMU VM1 ===
+
+
+=== Starting QEMU VM2 ===
+
+
+=== VM 1: Migrate from VM1 to VM2 ===
+
+vm1: qemu-io disk write complete
+vm1: live migration started
+vm1: live migration completed
+
+=== VM 2: Post-migration, write to disk, verify running ===
+
+vm2: qemu-io disk write complete
+vm2: qemu process running successfully
+vm2: flush io, and quit
+Check image pattern
+read 4194304/4194304 bytes at offset 0
+4 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+Running 'qemu-img check -r all $TEST_IMG'
+No errors were found on the image.
+80/16384 = 0.49% allocated, 0.00% fragmented, 0.00% compressed clusters
+Image end offset: 5570560
+*** done
diff --git a/tests/qemu-iotests/check b/tests/qemu-iotests/check
index e2ed5a95f8..ca2ee43d3b 100755
--- a/tests/qemu-iotests/check
+++ b/tests/qemu-iotests/check
@@ -34,6 +34,13 @@ timestamp=${TIMESTAMP:=false}
 # generic initialization
 iam=check
 
+# we need common.env
+if ! . ./common.env
+then
+    echo "$iam: failed to source common.env"
+    exit 1
+fi
+
 # we need common.config
 if ! . ./common.config
 then
@@ -215,9 +222,16 @@ do
 
         start=`_wallclock`
         $timestamp && echo -n "        ["`date "+%T"`"]"
-        [ ! -x $seq ] && chmod u+x $seq # ensure we can run it
+
+        if [ "$(head -n 1 $seq)" == "#!/usr/bin/env python" ]; then
+            run_command="$PYTHON $seq"
+        else
+            [ ! -x $seq ] && chmod u+x $seq # ensure we can run it
+            run_command="./$seq"
+        fi
+
         MALLOC_PERTURB_=${MALLOC_PERTURB_:-$(($RANDOM % 255 + 1))} \
-                ./$seq >$tmp.out 2>&1
+                $run_command >$tmp.out 2>&1
         sts=$?
         $timestamp && _timestamp
         stop=`_wallclock`
diff --git a/tests/qemu-iotests/common.qemu b/tests/qemu-iotests/common.qemu
new file mode 100644
index 0000000000..918af3102c
--- /dev/null
+++ b/tests/qemu-iotests/common.qemu
@@ -0,0 +1,200 @@
+#!/bin/bash
+#
+# This allows for launching of multiple QEMU instances, with independent
+# communication possible to each instance.
+#
+# Each instance can choose, at launch, to use either the QMP or the
+# HMP (monitor) interface.
+#
+# All instances are cleaned up via _cleanup_qemu, including killing the
+# running qemu instance.
+#
+# Copyright (C) 2014 Red Hat, Inc.
+#
+# 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/>.
+#
+
+QEMU_COMM_TIMEOUT=10
+
+QEMU_FIFO_IN="${TEST_DIR}/qmp-in-$$"
+QEMU_FIFO_OUT="${TEST_DIR}/qmp-out-$$"
+
+QEMU_PID=
+_QEMU_HANDLE=0
+QEMU_HANDLE=0
+
+# If bash version is >= 4.1, these will be overwritten and dynamic
+# file descriptor values assigned.
+_out_fd=3
+_in_fd=4
+
+# Wait for expected QMP response from QEMU.  Will time out
+# after 10 seconds, which counts as failure.
+#
+# Override QEMU_COMM_TIMEOUT for a timeout different than the
+# default 10 seconds
+#
+# $1: The handle to use
+# $2+ All remaining arguments comprise the string to search for
+#    in the response.
+#
+# If $silent is set to anything but an empty string, then
+# response is not echoed out.
+function _timed_wait_for()
+{
+    local h=${1}
+    shift
+
+    QEMU_STATUS[$h]=0
+    while read -t ${QEMU_COMM_TIMEOUT} resp <&${QEMU_OUT[$h]}
+    do
+        if [ -z "${silent}" ]; then
+            echo "${resp}" | _filter_testdir | _filter_qemu \
+                           | _filter_qemu_io | _filter_qmp
+        fi
+        grep -q "${*}" < <(echo ${resp})
+        if [ $? -eq 0 ]; then
+            return
+        fi
+    done
+    QEMU_STATUS[$h]=-1
+    if [ -z "${qemu_error_no_exit}" ]; then
+        echo "Timeout waiting for ${*} on handle ${h}"
+        exit 1  # Timeout means the test failed
+    fi
+}
+
+
+# Sends QMP or HMP command to QEMU, and waits for the expected response
+#
+# $1:       QEMU handle to use
+# $2:       String of the QMP command to send
+# ${@: -1}  (Last string passed)
+#             String that the QEMU response should contain. If it is a null
+#             string, do not wait for a response
+#
+# Set qemu_cmd_repeat to the number of times to repeat the cmd
+# until either timeout, or a response.  If it is not set, or <=0,
+# then the command is only sent once.
+#
+# If $qemu_error_no_exit is set, then even if the expected response
+# is not seen, we will not exit.  $QEMU_STATUS[$1] will be set it -1 in
+# that case.
+function _send_qemu_cmd()
+{
+    local h=${1}
+    local count=1
+    local cmd=
+    local use_error=${qemu_error_no_exit}
+    shift
+
+    if [ ${qemu_cmd_repeat} -gt 0 ] 2>/dev/null; then
+        count=${qemu_cmd_repeat}
+        use_error="no"
+    fi
+    # This array element extraction is done to accomodate pathnames with spaces
+    cmd=${@: 1:${#@}-1}
+    shift $(($# - 1))
+
+    while [ ${count} -gt 0 ]
+    do
+        echo "${cmd}" >&${QEMU_IN[${h}]}
+        if [ -n "${1}" ]; then
+            qemu_error_no_exit=${use_error} _timed_wait_for ${h} "${1}"
+            if [ ${QEMU_STATUS[$h]} -eq 0 ]; then
+                return
+            fi
+        fi
+        let count--;
+    done
+    if [ ${QEMU_STATUS[$h]} -ne 0 ] && [ -z "${qemu_error_no_exit}" ]; then
+        echo "Timeout waiting for ${1} on handle ${h}"
+        exit 1 #Timeout means the test failed
+    fi
+}
+
+
+# Launch a QEMU process.
+#
+# Input parameters:
+# $qemu_comm_method: set this variable to 'monitor' (case insensitive)
+#                    to use the QEMU HMP monitor for communication.
+#                    Otherwise, the default of QMP is used.
+# Returns:
+# $QEMU_HANDLE: set to a handle value to communicate with this QEMU instance.
+#
+function _launch_qemu()
+{
+    local comm=
+    local fifo_out=
+    local fifo_in=
+
+    if (shopt -s nocasematch; [[ "${qemu_comm_method}" == "monitor" ]])
+    then
+        comm="-monitor stdio"
+    else
+        local qemu_comm_method="qmp"
+        comm="-monitor none -qmp stdio"
+    fi
+
+    fifo_out=${QEMU_FIFO_OUT}_${_QEMU_HANDLE}
+    fifo_in=${QEMU_FIFO_IN}_${_QEMU_HANDLE}
+    mkfifo "${fifo_out}"
+    mkfifo "${fifo_in}"
+
+    "${QEMU}" -nographic -serial none ${comm} -machine accel=qtest "${@}" 2>&1 \
+                                                                >"${fifo_out}" \
+                                                                <"${fifo_in}" &
+    QEMU_PID[${_QEMU_HANDLE}]=$!
+
+    if [[ "${BASH_VERSINFO[0]}" -ge "5" ||
+        ("${BASH_VERSINFO[0]}" -ge "4"  &&  "${BASH_VERSINFO[1]}" -ge "1") ]]
+    then
+        # bash >= 4.1 required for automatic fd
+        exec {_out_fd}<"${fifo_out}"
+        exec {_in_fd}>"${fifo_in}"
+    else
+        let _out_fd++
+        let _in_fd++
+        eval "exec ${_out_fd}<'${fifo_out}'"
+        eval "exec ${_in_fd}>'${fifo_in}'"
+    fi
+
+    QEMU_OUT[${_QEMU_HANDLE}]=${_out_fd}
+    QEMU_IN[${_QEMU_HANDLE}]=${_in_fd}
+    QEMU_STATUS[${_QEMU_HANDLE}]=0
+
+    if [ "${qemu_comm_method}" == "qmp" ]
+    then
+        # Don't print response, since it has version information in it
+        silent=yes _timed_wait_for ${_QEMU_HANDLE} "capabilities"
+    fi
+    QEMU_HANDLE=${_QEMU_HANDLE}
+    let _QEMU_HANDLE++
+}
+
+
+# Silenty kills the QEMU process
+function _cleanup_qemu()
+{
+    # QEMU_PID[], QEMU_IN[], QEMU_OUT[] all use same indices
+    for i in "${!QEMU_OUT[@]}"
+    do
+        kill -KILL ${QEMU_PID[$i]} 2>/dev/null
+        wait ${QEMU_PID[$i]} 2>/dev/null # silent kill
+        rm -f "${QEMU_FIFO_IN}_${i}" "${QEMU_FIFO_OUT}_${i}"
+        eval "exec ${QEMU_IN[$i]}<&-"   # close file descriptors
+        eval "exec ${QEMU_OUT[$i]}<&-"
+    done
+}
diff --git a/tests/qemu-iotests/group b/tests/qemu-iotests/group
index ae096638b8..cd3e4d2c27 100644
--- a/tests/qemu-iotests/group
+++ b/tests/qemu-iotests/group
@@ -96,3 +96,4 @@
 087 rw auto
 088 rw auto
 090 rw auto quick
+091 rw auto
diff --git a/tests/test-qmp-input-strict.c b/tests/test-qmp-input-strict.c
index f03353b755..449d285e56 100644
--- a/tests/test-qmp-input-strict.c
+++ b/tests/test-qmp-input-strict.c
@@ -86,13 +86,13 @@ static void test_validate_struct(TestInputVisitorData *data,
                                   const void *unused)
 {
     TestStruct *p = NULL;
-    Error *errp = NULL;
+    Error *err = NULL;
     Visitor *v;
 
     v = validate_test_init(data, "{ 'integer': -42, 'boolean': true, 'string': 'foo' }");
 
-    visit_type_TestStruct(v, &p, NULL, &errp);
-    g_assert(!errp);
+    visit_type_TestStruct(v, &p, NULL, &err);
+    g_assert(!err);
     g_free(p->string);
     g_free(p);
 }
@@ -101,13 +101,13 @@ static void test_validate_struct_nested(TestInputVisitorData *data,
                                          const void *unused)
 {
     UserDefNested *udp = NULL;
-    Error *errp = NULL;
+    Error *err = NULL;
     Visitor *v;
 
     v = validate_test_init(data, "{ 'string0': 'string0', 'dict1': { 'string1': 'string1', 'dict2': { 'userdef1': { 'integer': 42, 'string': 'string' }, 'string2': 'string2'}}}");
 
-    visit_type_UserDefNested(v, &udp, NULL, &errp);
-    g_assert(!errp);
+    visit_type_UserDefNested(v, &udp, NULL, &err);
+    g_assert(!err);
     qapi_free_UserDefNested(udp);
 }
 
@@ -115,13 +115,13 @@ static void test_validate_list(TestInputVisitorData *data,
                                 const void *unused)
 {
     UserDefOneList *head = NULL;
-    Error *errp = NULL;
+    Error *err = NULL;
     Visitor *v;
 
     v = validate_test_init(data, "[ { 'string': 'string0', 'integer': 42 }, { 'string': 'string1', 'integer': 43 }, { 'string': 'string2', 'integer': 44 } ]");
 
-    visit_type_UserDefOneList(v, &head, NULL, &errp);
-    g_assert(!errp);
+    visit_type_UserDefOneList(v, &head, NULL, &err);
+    g_assert(!err);
     qapi_free_UserDefOneList(head);
 }
 
@@ -130,12 +130,12 @@ static void test_validate_union(TestInputVisitorData *data,
 {
     UserDefUnion *tmp = NULL;
     Visitor *v;
-    Error *errp = NULL;
+    Error *err = NULL;
 
     v = validate_test_init(data, "{ 'type': 'b', 'integer': 41, 'data' : { 'integer': 42 } }");
 
-    visit_type_UserDefUnion(v, &tmp, NULL, &errp);
-    g_assert(!errp);
+    visit_type_UserDefUnion(v, &tmp, NULL, &err);
+    g_assert(!err);
     qapi_free_UserDefUnion(tmp);
 }
 
@@ -144,7 +144,7 @@ static void test_validate_union_flat(TestInputVisitorData *data,
 {
     UserDefFlatUnion *tmp = NULL;
     Visitor *v;
-    Error *errp = NULL;
+    Error *err = NULL;
 
     v = validate_test_init(data,
                            "{ 'enum1': 'value1', "
@@ -152,8 +152,8 @@ static void test_validate_union_flat(TestInputVisitorData *data,
                            "'boolean': true }");
     /* TODO when generator bug is fixed, add 'integer': 41 */
 
-    visit_type_UserDefFlatUnion(v, &tmp, NULL, &errp);
-    g_assert(!errp);
+    visit_type_UserDefFlatUnion(v, &tmp, NULL, &err);
+    g_assert(!err);
     qapi_free_UserDefFlatUnion(tmp);
 }
 
@@ -162,12 +162,12 @@ static void test_validate_union_anon(TestInputVisitorData *data,
 {
     UserDefAnonUnion *tmp = NULL;
     Visitor *v;
-    Error *errp = NULL;
+    Error *err = NULL;
 
     v = validate_test_init(data, "42");
 
-    visit_type_UserDefAnonUnion(v, &tmp, NULL, &errp);
-    g_assert(!errp);
+    visit_type_UserDefAnonUnion(v, &tmp, NULL, &err);
+    g_assert(!err);
     qapi_free_UserDefAnonUnion(tmp);
 }
 
@@ -175,13 +175,13 @@ static void test_validate_fail_struct(TestInputVisitorData *data,
                                        const void *unused)
 {
     TestStruct *p = NULL;
-    Error *errp = NULL;
+    Error *err = NULL;
     Visitor *v;
 
     v = validate_test_init(data, "{ 'integer': -42, 'boolean': true, 'string': 'foo', 'extra': 42 }");
 
-    visit_type_TestStruct(v, &p, NULL, &errp);
-    g_assert(errp);
+    visit_type_TestStruct(v, &p, NULL, &err);
+    g_assert(err);
     if (p) {
         g_free(p->string);
     }
@@ -192,13 +192,13 @@ static void test_validate_fail_struct_nested(TestInputVisitorData *data,
                                               const void *unused)
 {
     UserDefNested *udp = NULL;
-    Error *errp = NULL;
+    Error *err = NULL;
     Visitor *v;
 
     v = validate_test_init(data, "{ 'string0': 'string0', 'dict1': { 'string1': 'string1', 'dict2': { 'userdef1': { 'integer': 42, 'string': 'string', 'extra': [42, 23, {'foo':'bar'}] }, 'string2': 'string2'}}}");
 
-    visit_type_UserDefNested(v, &udp, NULL, &errp);
-    g_assert(errp);
+    visit_type_UserDefNested(v, &udp, NULL, &err);
+    g_assert(err);
     qapi_free_UserDefNested(udp);
 }
 
@@ -206,13 +206,13 @@ static void test_validate_fail_list(TestInputVisitorData *data,
                                      const void *unused)
 {
     UserDefOneList *head = NULL;
-    Error *errp = NULL;
+    Error *err = NULL;
     Visitor *v;
 
     v = validate_test_init(data, "[ { 'string': 'string0', 'integer': 42 }, { 'string': 'string1', 'integer': 43 }, { 'string': 'string2', 'integer': 44, 'extra': 'ggg' } ]");
 
-    visit_type_UserDefOneList(v, &head, NULL, &errp);
-    g_assert(errp);
+    visit_type_UserDefOneList(v, &head, NULL, &err);
+    g_assert(err);
     qapi_free_UserDefOneList(head);
 }
 
@@ -220,13 +220,13 @@ static void test_validate_fail_union(TestInputVisitorData *data,
                                       const void *unused)
 {
     UserDefUnion *tmp = NULL;
-    Error *errp = NULL;
+    Error *err = NULL;
     Visitor *v;
 
     v = validate_test_init(data, "{ 'type': 'b', 'data' : { 'integer': 42 } }");
 
-    visit_type_UserDefUnion(v, &tmp, NULL, &errp);
-    g_assert(errp);
+    visit_type_UserDefUnion(v, &tmp, NULL, &err);
+    g_assert(err);
     qapi_free_UserDefUnion(tmp);
 }
 
@@ -234,13 +234,13 @@ static void test_validate_fail_union_flat(TestInputVisitorData *data,
                                           const void *unused)
 {
     UserDefFlatUnion *tmp = NULL;
-    Error *errp = NULL;
+    Error *err = NULL;
     Visitor *v;
 
     v = validate_test_init(data, "{ 'string': 'c', 'integer': 41, 'boolean': true }");
 
-    visit_type_UserDefFlatUnion(v, &tmp, NULL, &errp);
-    g_assert(errp);
+    visit_type_UserDefFlatUnion(v, &tmp, NULL, &err);
+    g_assert(err);
     qapi_free_UserDefFlatUnion(tmp);
 }
 
@@ -249,12 +249,12 @@ static void test_validate_fail_union_anon(TestInputVisitorData *data,
 {
     UserDefAnonUnion *tmp = NULL;
     Visitor *v;
-    Error *errp = NULL;
+    Error *err = NULL;
 
     v = validate_test_init(data, "3.14");
 
-    visit_type_UserDefAnonUnion(v, &tmp, NULL, &errp);
-    g_assert(errp);
+    visit_type_UserDefAnonUnion(v, &tmp, NULL, &err);
+    g_assert(err);
     qapi_free_UserDefAnonUnion(tmp);
 }
 
diff --git a/tests/test-qmp-input-visitor.c b/tests/test-qmp-input-visitor.c
index 1729667a6f..a58a3e6fdb 100644
--- a/tests/test-qmp-input-visitor.c
+++ b/tests/test-qmp-input-visitor.c
@@ -90,13 +90,13 @@ static void test_visitor_in_int(TestInputVisitorData *data,
                                 const void *unused)
 {
     int64_t res = 0, value = -42;
-    Error *errp = NULL;
+    Error *err = NULL;
     Visitor *v;
 
     v = visitor_input_test_init(data, "%" PRId64, value);
 
-    visit_type_int(v, &res, NULL, &errp);
-    g_assert(!errp);
+    visit_type_int(v, &res, NULL, &err);
+    g_assert(!err);
     g_assert_cmpint(res, ==, value);
 }
 
@@ -104,7 +104,7 @@ static void test_visitor_in_int_overflow(TestInputVisitorData *data,
                                          const void *unused)
 {
     int64_t res = 0;
-    Error *errp = NULL;
+    Error *err = NULL;
     Visitor *v;
 
     /* this will overflow a Qint/int64, so should be deserialized into
@@ -113,22 +113,22 @@ static void test_visitor_in_int_overflow(TestInputVisitorData *data,
      */
     v = visitor_input_test_init(data, "%f", DBL_MAX);
 
-    visit_type_int(v, &res, NULL, &errp);
-    g_assert(errp);
-    error_free(errp);
+    visit_type_int(v, &res, NULL, &err);
+    g_assert(err);
+    error_free(err);
 }
 
 static void test_visitor_in_bool(TestInputVisitorData *data,
                                  const void *unused)
 {
-    Error *errp = NULL;
+    Error *err = NULL;
     bool res = false;
     Visitor *v;
 
     v = visitor_input_test_init(data, "true");
 
-    visit_type_bool(v, &res, NULL, &errp);
-    g_assert(!errp);
+    visit_type_bool(v, &res, NULL, &err);
+    g_assert(!err);
     g_assert_cmpint(res, ==, true);
 }
 
@@ -136,13 +136,13 @@ static void test_visitor_in_number(TestInputVisitorData *data,
                                    const void *unused)
 {
     double res = 0, value = 3.14;
-    Error *errp = NULL;
+    Error *err = NULL;
     Visitor *v;
 
     v = visitor_input_test_init(data, "%f", value);
 
-    visit_type_number(v, &res, NULL, &errp);
-    g_assert(!errp);
+    visit_type_number(v, &res, NULL, &err);
+    g_assert(!err);
     g_assert_cmpfloat(res, ==, value);
 }
 
@@ -150,13 +150,13 @@ static void test_visitor_in_string(TestInputVisitorData *data,
                                    const void *unused)
 {
     char *res = NULL, *value = (char *) "Q E M U";
-    Error *errp = NULL;
+    Error *err = NULL;
     Visitor *v;
 
     v = visitor_input_test_init(data, "%s", value);
 
-    visit_type_str(v, &res, NULL, &errp);
-    g_assert(!errp);
+    visit_type_str(v, &res, NULL, &err);
+    g_assert(!err);
     g_assert_cmpstr(res, ==, value);
 
     g_free(res);
@@ -165,7 +165,7 @@ static void test_visitor_in_string(TestInputVisitorData *data,
 static void test_visitor_in_enum(TestInputVisitorData *data,
                                  const void *unused)
 {
-    Error *errp = NULL;
+    Error *err = NULL;
     Visitor *v;
     EnumOne i;
 
@@ -174,8 +174,8 @@ static void test_visitor_in_enum(TestInputVisitorData *data,
 
         v = visitor_input_test_init(data, "%s", EnumOne_lookup[i]);
 
-        visit_type_EnumOne(v, &res, NULL, &errp);
-        g_assert(!errp);
+        visit_type_EnumOne(v, &res, NULL, &err);
+        g_assert(!err);
         g_assert_cmpint(i, ==, res);
 
         visitor_input_teardown(data, NULL);
@@ -196,34 +196,33 @@ static void visit_type_TestStruct(Visitor *v, TestStruct **obj,
                                   const char *name, Error **errp)
 {
     Error *err = NULL;
-    if (!error_is_set(errp)) {
-        visit_start_struct(v, (void **)obj, "TestStruct", name, sizeof(TestStruct),
-                           &err);
-        if (!err) {
-            visit_type_int(v, &(*obj)->integer, "integer", &err);
-            visit_type_bool(v, &(*obj)->boolean, "boolean", &err);
-            visit_type_str(v, &(*obj)->string, "string", &err);
-
-            /* Always call end_struct if start_struct succeeded.  */
-            error_propagate(errp, err);
-            err = NULL;
-            visit_end_struct(v, &err);
-        }
+
+    visit_start_struct(v, (void **)obj, "TestStruct", name, sizeof(TestStruct),
+                       &err);
+    if (!err) {
+        visit_type_int(v, &(*obj)->integer, "integer", &err);
+        visit_type_bool(v, &(*obj)->boolean, "boolean", &err);
+        visit_type_str(v, &(*obj)->string, "string", &err);
+
+        /* Always call end_struct if start_struct succeeded.  */
         error_propagate(errp, err);
+        err = NULL;
+        visit_end_struct(v, &err);
     }
+    error_propagate(errp, err);
 }
 
 static void test_visitor_in_struct(TestInputVisitorData *data,
                                    const void *unused)
 {
     TestStruct *p = NULL;
-    Error *errp = NULL;
+    Error *err = NULL;
     Visitor *v;
 
     v = visitor_input_test_init(data, "{ 'integer': -42, 'boolean': true, 'string': 'foo' }");
 
-    visit_type_TestStruct(v, &p, NULL, &errp);
-    g_assert(!errp);
+    visit_type_TestStruct(v, &p, NULL, &err);
+    g_assert(!err);
     g_assert_cmpint(p->integer, ==, -42);
     g_assert(p->boolean == true);
     g_assert_cmpstr(p->string, ==, "foo");
@@ -242,13 +241,13 @@ static void test_visitor_in_struct_nested(TestInputVisitorData *data,
                                           const void *unused)
 {
     UserDefNested *udp = NULL;
-    Error *errp = NULL;
+    Error *err = NULL;
     Visitor *v;
 
     v = visitor_input_test_init(data, "{ 'string0': 'string0', 'dict1': { 'string1': 'string1', 'dict2': { 'userdef1': { 'integer': 42, 'string': 'string' }, 'string2': 'string2'}}}");
 
-    visit_type_UserDefNested(v, &udp, NULL, &errp);
-    g_assert(!errp);
+    visit_type_UserDefNested(v, &udp, NULL, &err);
+    g_assert(!err);
 
     check_and_free_str(udp->string0, "string0");
     check_and_free_str(udp->dict1.string1, "string1");
@@ -265,14 +264,14 @@ static void test_visitor_in_list(TestInputVisitorData *data,
                                  const void *unused)
 {
     UserDefOneList *item, *head = NULL;
-    Error *errp = NULL;
+    Error *err = NULL;
     Visitor *v;
     int i;
 
     v = visitor_input_test_init(data, "[ { 'string': 'string0', 'integer': 42 }, { 'string': 'string1', 'integer': 43 }, { 'string': 'string2', 'integer': 44 } ]");
 
-    visit_type_UserDefOneList(v, &head, NULL, &errp);
-    g_assert(!errp);
+    visit_type_UserDefOneList(v, &head, NULL, &err);
+    g_assert(!err);
     g_assert(head != NULL);
 
     for (i = 0, item = head; item; item = item->next, i++) {
@@ -634,16 +633,16 @@ static void test_visitor_in_errors(TestInputVisitorData *data,
                                    const void *unused)
 {
     TestStruct *p = NULL;
-    Error *errp = NULL;
+    Error *err = NULL;
     Visitor *v;
 
     v = visitor_input_test_init(data, "{ 'integer': false, 'boolean': 'foo', 'string': -42 }");
 
-    visit_type_TestStruct(v, &p, NULL, &errp);
-    g_assert(errp);
+    visit_type_TestStruct(v, &p, NULL, &err);
+    g_assert(err);
     g_assert(p->string == NULL);
 
-    error_free(errp);
+    error_free(err);
     g_free(p->string);
     g_free(p);
 }
diff --git a/tests/test-qmp-output-visitor.c b/tests/test-qmp-output-visitor.c
index da279713f2..2580f3debf 100644
--- a/tests/test-qmp-output-visitor.c
+++ b/tests/test-qmp-output-visitor.c
@@ -45,11 +45,11 @@ static void test_visitor_out_int(TestOutputVisitorData *data,
                                  const void *unused)
 {
     int64_t value = -42;
-    Error *errp = NULL;
+    Error *err = NULL;
     QObject *obj;
 
-    visit_type_int(data->ov, &value, NULL, &errp);
-    g_assert(!errp);
+    visit_type_int(data->ov, &value, NULL, &err);
+    g_assert(!err);
 
     obj = qmp_output_get_qobject(data->qov);
     g_assert(obj != NULL);
@@ -62,12 +62,12 @@ static void test_visitor_out_int(TestOutputVisitorData *data,
 static void test_visitor_out_bool(TestOutputVisitorData *data,
                                   const void *unused)
 {
-    Error *errp = NULL;
+    Error *err = NULL;
     bool value = true;
     QObject *obj;
 
-    visit_type_bool(data->ov, &value, NULL, &errp);
-    g_assert(!errp);
+    visit_type_bool(data->ov, &value, NULL, &err);
+    g_assert(!err);
 
     obj = qmp_output_get_qobject(data->qov);
     g_assert(obj != NULL);
@@ -81,11 +81,11 @@ static void test_visitor_out_number(TestOutputVisitorData *data,
                                     const void *unused)
 {
     double value = 3.14;
-    Error *errp = NULL;
+    Error *err = NULL;
     QObject *obj;
 
-    visit_type_number(data->ov, &value, NULL, &errp);
-    g_assert(!errp);
+    visit_type_number(data->ov, &value, NULL, &err);
+    g_assert(!err);
 
     obj = qmp_output_get_qobject(data->qov);
     g_assert(obj != NULL);
@@ -99,11 +99,11 @@ static void test_visitor_out_string(TestOutputVisitorData *data,
                                     const void *unused)
 {
     char *string = (char *) "Q E M U";
-    Error *errp = NULL;
+    Error *err = NULL;
     QObject *obj;
 
-    visit_type_str(data->ov, &string, NULL, &errp);
-    g_assert(!errp);
+    visit_type_str(data->ov, &string, NULL, &err);
+    g_assert(!err);
 
     obj = qmp_output_get_qobject(data->qov);
     g_assert(obj != NULL);
@@ -117,12 +117,12 @@ static void test_visitor_out_no_string(TestOutputVisitorData *data,
                                        const void *unused)
 {
     char *string = NULL;
-    Error *errp = NULL;
+    Error *err = NULL;
     QObject *obj;
 
     /* A null string should return "" */
-    visit_type_str(data->ov, &string, NULL, &errp);
-    g_assert(!errp);
+    visit_type_str(data->ov, &string, NULL, &err);
+    g_assert(!err);
 
     obj = qmp_output_get_qobject(data->qov);
     g_assert(obj != NULL);
@@ -135,13 +135,13 @@ static void test_visitor_out_no_string(TestOutputVisitorData *data,
 static void test_visitor_out_enum(TestOutputVisitorData *data,
                                   const void *unused)
 {
-    Error *errp = NULL;
+    Error *err = NULL;
     QObject *obj;
     EnumOne i;
 
     for (i = 0; i < ENUM_ONE_MAX; i++) {
-        visit_type_EnumOne(data->ov, &i, "unused", &errp);
-        g_assert(!errp);
+        visit_type_EnumOne(data->ov, &i, "unused", &err);
+        g_assert(!err);
 
         obj = qmp_output_get_qobject(data->qov);
         g_assert(obj != NULL);
@@ -156,13 +156,13 @@ static void test_visitor_out_enum_errors(TestOutputVisitorData *data,
                                          const void *unused)
 {
     EnumOne i, bad_values[] = { ENUM_ONE_MAX, -1 };
-    Error *errp;
+    Error *err;
 
     for (i = 0; i < ARRAY_SIZE(bad_values) ; i++) {
-        errp = NULL;
-        visit_type_EnumOne(data->ov, &bad_values[i], "unused", &errp);
-        g_assert(errp);
-        error_free(errp);
+        err = NULL;
+        visit_type_EnumOne(data->ov, &bad_values[i], "unused", &err);
+        g_assert(err);
+        error_free(err);
     }
 }
 
@@ -193,12 +193,12 @@ static void test_visitor_out_struct(TestOutputVisitorData *data,
                                .boolean = false,
                                .string = (char *) "foo"};
     TestStruct *p = &test_struct;
-    Error *errp = NULL;
+    Error *err = NULL;
     QObject *obj;
     QDict *qdict;
 
-    visit_type_TestStruct(data->ov, &p, NULL, &errp);
-    g_assert(!errp);
+    visit_type_TestStruct(data->ov, &p, NULL, &err);
+    g_assert(!err);
 
     obj = qmp_output_get_qobject(data->qov);
     g_assert(obj != NULL);
@@ -217,7 +217,7 @@ static void test_visitor_out_struct_nested(TestOutputVisitorData *data,
                                            const void *unused)
 {
     int64_t value = 42;
-    Error *errp = NULL;
+    Error *err = NULL;
     UserDefNested *ud2;
     QObject *obj;
     QDict *qdict, *dict1, *dict2, *dict3, *userdef;
@@ -242,8 +242,8 @@ static void test_visitor_out_struct_nested(TestOutputVisitorData *data,
     ud2->dict1.dict3.userdef2->base->integer = value;
     ud2->dict1.dict3.string3 = g_strdup(strings[3]);
 
-    visit_type_UserDefNested(data->ov, &ud2, "unused", &errp);
-    g_assert(!errp);
+    visit_type_UserDefNested(data->ov, &ud2, "unused", &err);
+    g_assert(!err);
 
     obj = qmp_output_get_qobject(data->qov);
     g_assert(obj != NULL);
@@ -283,16 +283,16 @@ static void test_visitor_out_struct_errors(TestOutputVisitorData *data,
     EnumOne bad_values[] = { ENUM_ONE_MAX, -1 };
     UserDefZero b;
     UserDefOne u = { .base = &b }, *pu = &u;
-    Error *errp;
+    Error *err;
     int i;
 
     for (i = 0; i < ARRAY_SIZE(bad_values) ; i++) {
-        errp = NULL;
+        err = NULL;
         u.has_enum1 = true;
         u.enum1 = bad_values[i];
-        visit_type_UserDefOne(data->ov, &pu, "unused", &errp);
-        g_assert(errp);
-        error_free(errp);
+        visit_type_UserDefOne(data->ov, &pu, "unused", &err);
+        g_assert(err);
+        error_free(err);
     }
 }
 
@@ -328,7 +328,7 @@ static void test_visitor_out_list(TestOutputVisitorData *data,
     const int max_items = 10;
     bool value_bool = true;
     int value_int = 10;
-    Error *errp = NULL;
+    Error *err = NULL;
     QListEntry *entry;
     QObject *obj;
     QList *qlist;
@@ -345,8 +345,8 @@ static void test_visitor_out_list(TestOutputVisitorData *data,
         head = p;
     }
 
-    visit_type_TestStructList(data->ov, &head, NULL, &errp);
-    g_assert(!errp);
+    visit_type_TestStructList(data->ov, &head, NULL, &err);
+    g_assert(!err);
 
     obj = qmp_output_get_qobject(data->qov);
     g_assert(obj != NULL);
diff --git a/tests/test-string-input-visitor.c b/tests/test-string-input-visitor.c
index d406263aee..877e737714 100644
--- a/tests/test-string-input-visitor.c
+++ b/tests/test-string-input-visitor.c
@@ -54,62 +54,62 @@ static void test_visitor_in_int(TestInputVisitorData *data,
                                 const void *unused)
 {
     int64_t res = 0, value = -42;
-    Error *errp = NULL;
+    Error *err = NULL;
     Visitor *v;
 
     v = visitor_input_test_init(data, "-42");
 
-    visit_type_int(v, &res, NULL, &errp);
-    g_assert(!errp);
+    visit_type_int(v, &res, NULL, &err);
+    g_assert(!err);
     g_assert_cmpint(res, ==, value);
 }
 
 static void test_visitor_in_bool(TestInputVisitorData *data,
                                  const void *unused)
 {
-    Error *errp = NULL;
+    Error *err = NULL;
     bool res = false;
     Visitor *v;
 
     v = visitor_input_test_init(data, "true");
 
-    visit_type_bool(v, &res, NULL, &errp);
-    g_assert(!errp);
+    visit_type_bool(v, &res, NULL, &err);
+    g_assert(!err);
     g_assert_cmpint(res, ==, true);
     visitor_input_teardown(data, unused);
 
     v = visitor_input_test_init(data, "yes");
 
-    visit_type_bool(v, &res, NULL, &errp);
-    g_assert(!errp);
+    visit_type_bool(v, &res, NULL, &err);
+    g_assert(!err);
     g_assert_cmpint(res, ==, true);
     visitor_input_teardown(data, unused);
 
     v = visitor_input_test_init(data, "on");
 
-    visit_type_bool(v, &res, NULL, &errp);
-    g_assert(!errp);
+    visit_type_bool(v, &res, NULL, &err);
+    g_assert(!err);
     g_assert_cmpint(res, ==, true);
     visitor_input_teardown(data, unused);
 
     v = visitor_input_test_init(data, "false");
 
-    visit_type_bool(v, &res, NULL, &errp);
-    g_assert(!errp);
+    visit_type_bool(v, &res, NULL, &err);
+    g_assert(!err);
     g_assert_cmpint(res, ==, false);
     visitor_input_teardown(data, unused);
 
     v = visitor_input_test_init(data, "no");
 
-    visit_type_bool(v, &res, NULL, &errp);
-    g_assert(!errp);
+    visit_type_bool(v, &res, NULL, &err);
+    g_assert(!err);
     g_assert_cmpint(res, ==, false);
     visitor_input_teardown(data, unused);
 
     v = visitor_input_test_init(data, "off");
 
-    visit_type_bool(v, &res, NULL, &errp);
-    g_assert(!errp);
+    visit_type_bool(v, &res, NULL, &err);
+    g_assert(!err);
     g_assert_cmpint(res, ==, false);
 }
 
@@ -117,13 +117,13 @@ static void test_visitor_in_number(TestInputVisitorData *data,
                                    const void *unused)
 {
     double res = 0, value = 3.14;
-    Error *errp = NULL;
+    Error *err = NULL;
     Visitor *v;
 
     v = visitor_input_test_init(data, "3.14");
 
-    visit_type_number(v, &res, NULL, &errp);
-    g_assert(!errp);
+    visit_type_number(v, &res, NULL, &err);
+    g_assert(!err);
     g_assert_cmpfloat(res, ==, value);
 }
 
@@ -131,13 +131,13 @@ static void test_visitor_in_string(TestInputVisitorData *data,
                                    const void *unused)
 {
     char *res = NULL, *value = (char *) "Q E M U";
-    Error *errp = NULL;
+    Error *err = NULL;
     Visitor *v;
 
     v = visitor_input_test_init(data, value);
 
-    visit_type_str(v, &res, NULL, &errp);
-    g_assert(!errp);
+    visit_type_str(v, &res, NULL, &err);
+    g_assert(!err);
     g_assert_cmpstr(res, ==, value);
 
     g_free(res);
@@ -146,7 +146,7 @@ static void test_visitor_in_string(TestInputVisitorData *data,
 static void test_visitor_in_enum(TestInputVisitorData *data,
                                  const void *unused)
 {
-    Error *errp = NULL;
+    Error *err = NULL;
     Visitor *v;
     EnumOne i;
 
@@ -155,8 +155,8 @@ static void test_visitor_in_enum(TestInputVisitorData *data,
 
         v = visitor_input_test_init(data, EnumOne_lookup[i]);
 
-        visit_type_EnumOne(v, &res, NULL, &errp);
-        g_assert(!errp);
+        visit_type_EnumOne(v, &res, NULL, &err);
+        g_assert(!err);
         g_assert_cmpint(i, ==, res);
 
         visitor_input_teardown(data, NULL);
diff --git a/tests/test-string-output-visitor.c b/tests/test-string-output-visitor.c
index 22363d100f..2af5a21ab5 100644
--- a/tests/test-string-output-visitor.c
+++ b/tests/test-string-output-visitor.c
@@ -45,11 +45,11 @@ static void test_visitor_out_int(TestOutputVisitorData *data,
                                  const void *unused)
 {
     int64_t value = -42;
-    Error *errp = NULL;
+    Error *err = NULL;
     char *str;
 
-    visit_type_int(data->ov, &value, NULL, &errp);
-    g_assert(!errp);
+    visit_type_int(data->ov, &value, NULL, &err);
+    g_assert(!err);
 
     str = string_output_get_string(data->sov);
     g_assert(str != NULL);
@@ -60,12 +60,12 @@ static void test_visitor_out_int(TestOutputVisitorData *data,
 static void test_visitor_out_bool(TestOutputVisitorData *data,
                                   const void *unused)
 {
-    Error *errp = NULL;
+    Error *err = NULL;
     bool value = true;
     char *str;
 
-    visit_type_bool(data->ov, &value, NULL, &errp);
-    g_assert(!errp);
+    visit_type_bool(data->ov, &value, NULL, &err);
+    g_assert(!err);
 
     str = string_output_get_string(data->sov);
     g_assert(str != NULL);
@@ -77,11 +77,11 @@ static void test_visitor_out_number(TestOutputVisitorData *data,
                                     const void *unused)
 {
     double value = 3.14;
-    Error *errp = NULL;
+    Error *err = NULL;
     char *str;
 
-    visit_type_number(data->ov, &value, NULL, &errp);
-    g_assert(!errp);
+    visit_type_number(data->ov, &value, NULL, &err);
+    g_assert(!err);
 
     str = string_output_get_string(data->sov);
     g_assert(str != NULL);
@@ -93,11 +93,11 @@ static void test_visitor_out_string(TestOutputVisitorData *data,
                                     const void *unused)
 {
     char *string = (char *) "Q E M U";
-    Error *errp = NULL;
+    Error *err = NULL;
     char *str;
 
-    visit_type_str(data->ov, &string, NULL, &errp);
-    g_assert(!errp);
+    visit_type_str(data->ov, &string, NULL, &err);
+    g_assert(!err);
 
     str = string_output_get_string(data->sov);
     g_assert(str != NULL);
@@ -109,12 +109,12 @@ static void test_visitor_out_no_string(TestOutputVisitorData *data,
                                        const void *unused)
 {
     char *string = NULL;
-    Error *errp = NULL;
+    Error *err = NULL;
     char *str;
 
     /* A null string should return "" */
-    visit_type_str(data->ov, &string, NULL, &errp);
-    g_assert(!errp);
+    visit_type_str(data->ov, &string, NULL, &err);
+    g_assert(!err);
 
     str = string_output_get_string(data->sov);
     g_assert(str != NULL);
@@ -125,13 +125,13 @@ static void test_visitor_out_no_string(TestOutputVisitorData *data,
 static void test_visitor_out_enum(TestOutputVisitorData *data,
                                   const void *unused)
 {
-    Error *errp = NULL;
+    Error *err = NULL;
     char *str;
     EnumOne i;
 
     for (i = 0; i < ENUM_ONE_MAX; i++) {
-        visit_type_EnumOne(data->ov, &i, "unused", &errp);
-        g_assert(!errp);
+        visit_type_EnumOne(data->ov, &i, "unused", &err);
+        g_assert(!err);
 
         str = string_output_get_string(data->sov);
         g_assert(str != NULL);
@@ -144,13 +144,13 @@ static void test_visitor_out_enum_errors(TestOutputVisitorData *data,
                                          const void *unused)
 {
     EnumOne i, bad_values[] = { ENUM_ONE_MAX, -1 };
-    Error *errp;
+    Error *err;
 
     for (i = 0; i < ARRAY_SIZE(bad_values) ; i++) {
-        errp = NULL;
-        visit_type_EnumOne(data->ov, &bad_values[i], "unused", &errp);
-        g_assert(errp);
-        error_free(errp);
+        err = NULL;
+        visit_type_EnumOne(data->ov, &bad_values[i], "unused", &err);
+        g_assert(err);
+        error_free(err);
     }
 }