All of lore.kernel.org
 help / color / mirror / Atom feed
* [Qemu-devel] [PATCH v5 00/10] qemu-iotests improvements
@ 2017-10-17 16:31 Jeff Cody
  2017-10-17 16:31 ` [Qemu-devel] [PATCH v5 01/10] qemu-iotests: refuse to run if TEST_DIR contains spaces Jeff Cody
                   ` (9 more replies)
  0 siblings, 10 replies; 37+ messages in thread
From: Jeff Cody @ 2017-10-17 16:31 UTC (permalink / raw)
  To: qemu-devel; +Cc: qemu-block, jsnow, stefanha, kwolf, eblake


Previous series subject: "qemu-iotests: place output in unique dir"


Changes v4 -> v5:
-------------------

Relatively minor changes:

    * line-too-long complaint by patchew

    * fixed running from out-of-tree

    * fixed 2 other bugs found: one test was forgotten,
      and some QEMU process FIFOs were left behind.

    * output formatting changes

git-backport-diff -r qemu/master.. -u devel-iotests-v4
Key:
[----] : patches are identical
[####] : number of functional differences between upstream/downstream patch
[down] : patch is downstream-only
The flags [FC] indicate (F)unctional and (C)ontextual differences, respectively

001/10:[----] [--] 'qemu-iotests: refuse to run if TEST_DIR contains spaces'
002/10:[0012] [FC] 'qemu-iotests: set TEST_DIR to a unique dir for each test'
003/10:[----] [-C] 'qemu-iotests: automatically clean up bash protocol servers'
004/10:[----] [--] 'qemu-iotests: remove file cleanup from bash tests'
005/10:[0064] [FC] 'qemu-iotests: change qemu pid and fd tracking / cleanup'
006/10:[0007] [FC] 'qemu-iotests: make ./check automatically reap QEMU processes'
007/10:[0003] [FC] 'qemu-iotests: run python tests in own subdirectories'
008/10:[0002] [FC] 'qemu-iotests: modify python tests to run from subdir'
009/10:[----] [--] 'qemu-iotests: add option to save temp files on error'
010/10:[0066] [FC] 'qemu-iotests: add support for running multi-threaded iotests'




Changes v3 -> v4:
-------------------

Significant changes from v3.  Highlights of the major changes from v3:

    * Python tests are properly run in hierarchial sub-directories now
       (Thanks Stefan, John)

    * Protocol servers are cleaned up automatically (Thanks Kevin)

    * Prevent running qemu-iotests if TEST_DIR contains spaces

    * common.qemu process reaping overhauled, and qemu processes
      also automatically killed on test conclusion

    * multi-thread iotest job support.  Here is an example of the
      speedup:


Previous, single-thread run of everything qcow2:


# ./check -qcow2

[...]

Not run: 045 059 064 070 075 076 077 078 081 083 084 088 092 093 094 101
         106 109 113 116 119 123 128 131 135 136 146 148 149 160 171 173 175
Failures: 191
Failed 1 of 149 tests

real    8m22.077s
user    4m48.177s
sys     1m16.553s


Multi-process run:

# ./check -qcow2 -j 5

[...]

Not run: 045 059 064 070 075 076 077 078 081 083 084 088 092 093 094 101
         106 109 113 116 119 123 128 131 135 136 146 148 149 160 171 173 175
Failures: 183 191
Failed 2 of 149 tests

real    3m7.458s
user    5m29.678s
sys     1m55.007s


(See commit message on patch 10 for why there is an additional test
 failure)


git-backport-diff -r qemu/master.. -u devel-iotests-v3
Key:
[----] : patches are identical
[####] : number of functional differences between upstream/downstream patch
[down] : patch is downstream-only
The flags [FC] indicate (F)unctional and (C)ontextual differences, respectively

001/10:[down] 'qemu-iotests: refuse to run if TEST_DIR contains spaces'
002/10:[----] [--] 'qemu-iotests: set TEST_DIR to a unique dir for each test'
003/10:[down] 'qemu-iotests: automatically clean up bash protocol servers'
004/10:[0073] [FC] 'qemu-iotests: remove file cleanup from bash tests'
005/10:[down] 'qemu-iotests: change qemu pid and fd tracking / cleanup'
006/10:[down] 'qemu-iotests: make ./check automatically reap QEMU processes'
007/10:[down] 'qemu-iotests: run python tests in own subdirectories'
008/10:[down] 'qemu-iotests: modify python tests to run from subdir'
009/10:[0017] [FC] 'qemu-iotests: add option to save temp files on error'
010/10:[down] 'qemu-iotests: add support for running multi-threaded iotests'


Jeff Cody (10):
  qemu-iotests: refuse to run if TEST_DIR contains spaces
  qemu-iotests: set TEST_DIR to a unique dir for each test
  qemu-iotests: automatically clean up bash protocol servers
  qemu-iotests: remove file cleanup from bash tests
  qemu-iotests: change qemu pid and fd tracking / cleanup
  qemu-iotests: make ./check automatically reap QEMU processes
  qemu-iotests: run python tests in own subdirectories
  qemu-iotests: modify python tests to run from subdir
  qemu-iotests: add option to save temp files on error
  qemu-iotests: add support for running multi-threaded iotests

 tests/qemu-iotests/001         |   6 -
 tests/qemu-iotests/002         |   6 -
 tests/qemu-iotests/003         |   6 -
 tests/qemu-iotests/004         |   6 -
 tests/qemu-iotests/005         |   6 -
 tests/qemu-iotests/007         |   7 -
 tests/qemu-iotests/008         |   6 -
 tests/qemu-iotests/009         |   6 -
 tests/qemu-iotests/010         |   6 -
 tests/qemu-iotests/011         |   6 -
 tests/qemu-iotests/012         |   6 -
 tests/qemu-iotests/013         |   6 -
 tests/qemu-iotests/014         |   6 -
 tests/qemu-iotests/015         |   7 -
 tests/qemu-iotests/017         |   6 -
 tests/qemu-iotests/018         |   6 -
 tests/qemu-iotests/019         |   8 -
 tests/qemu-iotests/020         |   8 -
 tests/qemu-iotests/021         |   6 -
 tests/qemu-iotests/022         |   6 -
 tests/qemu-iotests/023         |   6 -
 tests/qemu-iotests/024         |   8 -
 tests/qemu-iotests/025         |   6 -
 tests/qemu-iotests/026         |   7 -
 tests/qemu-iotests/027         |   6 -
 tests/qemu-iotests/028         |   8 -
 tests/qemu-iotests/029         |   7 -
 tests/qemu-iotests/030         |  82 ++++-----
 tests/qemu-iotests/031         |   6 -
 tests/qemu-iotests/032         |   6 -
 tests/qemu-iotests/033         |   6 -
 tests/qemu-iotests/034         |   6 -
 tests/qemu-iotests/035         |   6 -
 tests/qemu-iotests/036         |   6 -
 tests/qemu-iotests/037         |   6 -
 tests/qemu-iotests/038         |   6 -
 tests/qemu-iotests/039         |   6 -
 tests/qemu-iotests/040         | 128 ++++++-------
 tests/qemu-iotests/041         | 333 ++++++++++++++++-----------------
 tests/qemu-iotests/042         |   6 -
 tests/qemu-iotests/043         |   7 -
 tests/qemu-iotests/044         |  11 +-
 tests/qemu-iotests/045         |  42 ++---
 tests/qemu-iotests/046         |   6 -
 tests/qemu-iotests/047         |   6 -
 tests/qemu-iotests/048         |   8 -
 tests/qemu-iotests/048.out     |   1 -
 tests/qemu-iotests/049         |   6 -
 tests/qemu-iotests/050         |   8 -
 tests/qemu-iotests/051         |   6 -
 tests/qemu-iotests/052         |   6 -
 tests/qemu-iotests/053         |   7 -
 tests/qemu-iotests/054         |   6 -
 tests/qemu-iotests/055         |  97 +++++-----
 tests/qemu-iotests/056         |  39 ++--
 tests/qemu-iotests/057         |   4 +-
 tests/qemu-iotests/058         |  47 ++---
 tests/qemu-iotests/059         |   7 -
 tests/qemu-iotests/060         |   6 -
 tests/qemu-iotests/061         |   6 -
 tests/qemu-iotests/062         |   6 -
 tests/qemu-iotests/063         |   7 -
 tests/qemu-iotests/064         |   6 -
 tests/qemu-iotests/065         |  13 +-
 tests/qemu-iotests/066         |   6 -
 tests/qemu-iotests/068         |   6 -
 tests/qemu-iotests/069         |   6 -
 tests/qemu-iotests/070         |   6 -
 tests/qemu-iotests/071         |   6 -
 tests/qemu-iotests/072         |   6 -
 tests/qemu-iotests/073         |   6 -
 tests/qemu-iotests/074         |   9 -
 tests/qemu-iotests/074.out     |   1 -
 tests/qemu-iotests/075         |   6 -
 tests/qemu-iotests/076         |   6 -
 tests/qemu-iotests/077         |   6 -
 tests/qemu-iotests/078         |   6 -
 tests/qemu-iotests/079         |   6 -
 tests/qemu-iotests/080         |   7 -
 tests/qemu-iotests/081         |   8 -
 tests/qemu-iotests/082         |   6 -
 tests/qemu-iotests/083         |   8 -
 tests/qemu-iotests/084         |   6 -
 tests/qemu-iotests/085         |  13 --
 tests/qemu-iotests/086         |   6 -
 tests/qemu-iotests/088         |   7 -
 tests/qemu-iotests/089         |   6 -
 tests/qemu-iotests/090         |   6 -
 tests/qemu-iotests/091         |   8 -
 tests/qemu-iotests/092         |   7 -
 tests/qemu-iotests/094         |   9 -
 tests/qemu-iotests/095         |   8 -
 tests/qemu-iotests/096         |   8 +-
 tests/qemu-iotests/097         |   7 -
 tests/qemu-iotests/098         |   7 -
 tests/qemu-iotests/099         |   6 -
 tests/qemu-iotests/101         |   6 -
 tests/qemu-iotests/102         |   7 -
 tests/qemu-iotests/103         |   6 -
 tests/qemu-iotests/104         |   2 -
 tests/qemu-iotests/105         |   6 -
 tests/qemu-iotests/106         |   6 -
 tests/qemu-iotests/107         |   6 -
 tests/qemu-iotests/108         |   6 -
 tests/qemu-iotests/109         |   8 -
 tests/qemu-iotests/110         |   6 -
 tests/qemu-iotests/111         |   6 -
 tests/qemu-iotests/112         |   6 -
 tests/qemu-iotests/113         |   6 -
 tests/qemu-iotests/114         |   6 -
 tests/qemu-iotests/115         |   6 -
 tests/qemu-iotests/116         |   6 -
 tests/qemu-iotests/117         |   7 -
 tests/qemu-iotests/118         | 200 ++++++++++----------
 tests/qemu-iotests/119         |   6 -
 tests/qemu-iotests/120         |   6 -
 tests/qemu-iotests/121         |   6 -
 tests/qemu-iotests/122         |   7 -
 tests/qemu-iotests/123         |   7 -
 tests/qemu-iotests/124         |  24 +--
 tests/qemu-iotests/125         |   6 -
 tests/qemu-iotests/129         |   6 +-
 tests/qemu-iotests/130         |   7 -
 tests/qemu-iotests/131         |   6 -
 tests/qemu-iotests/132         |  19 +-
 tests/qemu-iotests/133         |   6 -
 tests/qemu-iotests/134         |   6 -
 tests/qemu-iotests/135         |   6 -
 tests/qemu-iotests/136         |   7 +-
 tests/qemu-iotests/137         |   6 -
 tests/qemu-iotests/138         |   6 -
 tests/qemu-iotests/139         |  33 ++--
 tests/qemu-iotests/140         |   8 -
 tests/qemu-iotests/141         |   8 -
 tests/qemu-iotests/142         |   7 -
 tests/qemu-iotests/143         |   7 -
 tests/qemu-iotests/144         |   8 -
 tests/qemu-iotests/145         |   7 -
 tests/qemu-iotests/146         |   7 -
 tests/qemu-iotests/147         |  41 ++---
 tests/qemu-iotests/148         |  33 ++--
 tests/qemu-iotests/150         |   6 -
 tests/qemu-iotests/152         |  21 +--
 tests/qemu-iotests/153         |  12 --
 tests/qemu-iotests/154         |   6 -
 tests/qemu-iotests/155         |  54 +++---
 tests/qemu-iotests/156         |   7 -
 tests/qemu-iotests/157         |   6 -
 tests/qemu-iotests/158         |   6 -
 tests/qemu-iotests/159         |   7 -
 tests/qemu-iotests/160         |   7 -
 tests/qemu-iotests/162         |   7 -
 tests/qemu-iotests/163         |  42 ++---
 tests/qemu-iotests/165         |  11 +-
 tests/qemu-iotests/170         |   7 -
 tests/qemu-iotests/171         |   6 -
 tests/qemu-iotests/172         |   8 -
 tests/qemu-iotests/173         |   8 -
 tests/qemu-iotests/174         |   6 -
 tests/qemu-iotests/175         |   6 -
 tests/qemu-iotests/176         |   7 -
 tests/qemu-iotests/177         |   6 -
 tests/qemu-iotests/178         |   7 -
 tests/qemu-iotests/179         |   7 -
 tests/qemu-iotests/181         |   8 -
 tests/qemu-iotests/182         |   6 -
 tests/qemu-iotests/183         |   9 -
 tests/qemu-iotests/184         |   6 -
 tests/qemu-iotests/185         |   9 -
 tests/qemu-iotests/186         |   6 -
 tests/qemu-iotests/187         |   8 -
 tests/qemu-iotests/188         |   6 -
 tests/qemu-iotests/189         |   6 -
 tests/qemu-iotests/190         |   7 -
 tests/qemu-iotests/191         |  10 -
 tests/qemu-iotests/192         |   6 -
 tests/qemu-iotests/195         |   7 -
 tests/qemu-iotests/197         |   7 -
 tests/qemu-iotests/check       | 409 +++++++++++++++++++++++++++++++----------
 tests/qemu-iotests/common.qemu |  82 +++++++--
 tests/qemu-iotests/common.rc   |  98 ++++++----
 tests/qemu-iotests/iotests.py  |  15 +-
 182 files changed, 1044 insertions(+), 1869 deletions(-)

-- 
2.9.5

^ permalink raw reply	[flat|nested] 37+ messages in thread

* [Qemu-devel] [PATCH v5 01/10] qemu-iotests: refuse to run if TEST_DIR contains spaces
  2017-10-17 16:31 [Qemu-devel] [PATCH v5 00/10] qemu-iotests improvements Jeff Cody
@ 2017-10-17 16:31 ` Jeff Cody
  2017-10-18  1:03   ` Eric Blake
  2017-10-17 16:31 ` [Qemu-devel] [PATCH v5 02/10] qemu-iotests: set TEST_DIR to a unique dir for each test Jeff Cody
                   ` (8 subsequent siblings)
  9 siblings, 1 reply; 37+ messages in thread
From: Jeff Cody @ 2017-10-17 16:31 UTC (permalink / raw)
  To: qemu-devel; +Cc: qemu-block, jsnow, stefanha, kwolf, eblake

Currently, not all qemu-iotests work if TEST_DIR has spaces, and they
also might not be safe.  Refuse to run if TEST_DIR in this case, at
least until all tests are fixed sometime in the future.

Signed-off-by: Jeff Cody <jcody@redhat.com>
---
 tests/qemu-iotests/check | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/tests/qemu-iotests/check b/tests/qemu-iotests/check
index e6b6ff7..e2163cc 100755
--- a/tests/qemu-iotests/check
+++ b/tests/qemu-iotests/check
@@ -102,6 +102,14 @@ if [ -z "$TEST_DIR" ]; then
         TEST_DIR=`pwd`/scratch
 fi
 
+case $TEST_DIR in
+    *[[:blank:]]*)
+        echo "The TEST_DIR pathname '$TEST_DIR' contains whitespace. "
+        echo "This is currently unsupported by qemu-iotests"
+        exit 1
+        ;;
+esac
+
 if [ ! -e "$TEST_DIR" ]; then
         mkdir "$TEST_DIR"
 fi
-- 
2.9.5

^ permalink raw reply related	[flat|nested] 37+ messages in thread

* [Qemu-devel] [PATCH v5 02/10] qemu-iotests: set TEST_DIR to a unique dir for each test
  2017-10-17 16:31 [Qemu-devel] [PATCH v5 00/10] qemu-iotests improvements Jeff Cody
  2017-10-17 16:31 ` [Qemu-devel] [PATCH v5 01/10] qemu-iotests: refuse to run if TEST_DIR contains spaces Jeff Cody
@ 2017-10-17 16:31 ` Jeff Cody
  2017-10-17 16:31 ` [Qemu-devel] [PATCH v5 03/10] qemu-iotests: automatically clean up bash protocol servers Jeff Cody
                   ` (7 subsequent siblings)
  9 siblings, 0 replies; 37+ messages in thread
From: Jeff Cody @ 2017-10-17 16:31 UTC (permalink / raw)
  To: qemu-devel; +Cc: qemu-block, jsnow, stefanha, kwolf, eblake

Right now, all qemu-iotests output data into the same scratch directory,
and so each test needs to be responsible for cleaning up its own files.

Have each test use 'scratch/$seq' as its temp directory, so the check
script can do simple cleanup of removing the whole temporary directory.

Reviewed-by: Eric Blake <eblake@redhat.com>
Signed-off-by: Jeff Cody <jcody@redhat.com>
---
 tests/qemu-iotests/check | 21 +++++++++++++++++----
 1 file changed, 17 insertions(+), 4 deletions(-)

diff --git a/tests/qemu-iotests/check b/tests/qemu-iotests/check
index e2163cc..5ae34bf 100755
--- a/tests/qemu-iotests/check
+++ b/tests/qemu-iotests/check
@@ -713,6 +713,7 @@ seq="check"
 
 for seq in $list
 do
+    TEST_DIR_SEQ=$TEST_DIR/$seq
     err=false
     printf %s "$seq"
     if [ -n "$TESTS_REMAINING_LOG" ] ; then
@@ -756,13 +757,23 @@ do
         fi
         export OUTPUT_DIR=$PWD
         if $debug; then
-            (cd "$source_iotests";
+            (
+            export TEST_DIR=$TEST_DIR_SEQ
+            cd "$source_iotests";
+            . ./common.config
+            . ./common.rc
             MALLOC_PERTURB_=${MALLOC_PERTURB_:-$(($RANDOM % 255 + 1))} \
-                    $run_command -d 2>&1 | tee $tmp.out)
+                    $run_command -d 2>&1 | tee $tmp.out
+            )
         else
-            (cd "$source_iotests";
+            (
+            export TEST_DIR=$TEST_DIR_SEQ
+            cd "$source_iotests";
+            . ./common.config
+            . ./common.rc
             MALLOC_PERTURB_=${MALLOC_PERTURB_:-$(($RANDOM % 255 + 1))} \
-                    $run_command >$tmp.out 2>&1)
+                    $run_command >$tmp.out 2>&1
+            )
         fi
         sts=$?
         $timestamp && _timestamp
@@ -826,6 +837,8 @@ do
             fi
         fi
 
+        rm -rf "$TEST_DIR_SEQ"
+
     fi
 
     # come here for each test, except when $showme is true
-- 
2.9.5

^ permalink raw reply related	[flat|nested] 37+ messages in thread

* [Qemu-devel] [PATCH v5 03/10] qemu-iotests: automatically clean up bash protocol servers
  2017-10-17 16:31 [Qemu-devel] [PATCH v5 00/10] qemu-iotests improvements Jeff Cody
  2017-10-17 16:31 ` [Qemu-devel] [PATCH v5 01/10] qemu-iotests: refuse to run if TEST_DIR contains spaces Jeff Cody
  2017-10-17 16:31 ` [Qemu-devel] [PATCH v5 02/10] qemu-iotests: set TEST_DIR to a unique dir for each test Jeff Cody
@ 2017-10-17 16:31 ` Jeff Cody
  2017-10-18  1:15   ` Eric Blake
  2017-10-18 14:46   ` Paolo Bonzini
  2017-10-17 16:31 ` [Qemu-devel] [PATCH v5 04/10] qemu-iotests: remove file cleanup from bash tests Jeff Cody
                   ` (6 subsequent siblings)
  9 siblings, 2 replies; 37+ messages in thread
From: Jeff Cody @ 2017-10-17 16:31 UTC (permalink / raw)
  To: qemu-devel; +Cc: qemu-block, jsnow, stefanha, kwolf, eblake

For bash tests, this allows 'check' to reap all launch protocol
servers / processes, after a test has finished running.

Signed-off-by: Jeff Cody <jcody@redhat.com>
---
 tests/qemu-iotests/check     | 13 +++++++
 tests/qemu-iotests/common.rc | 93 +++++++++++++++++++++++++++++---------------
 2 files changed, 75 insertions(+), 31 deletions(-)

diff --git a/tests/qemu-iotests/check b/tests/qemu-iotests/check
index 5ae34bf..b4ab646 100755
--- a/tests/qemu-iotests/check
+++ b/tests/qemu-iotests/check
@@ -757,6 +757,8 @@ do
         fi
         export OUTPUT_DIR=$PWD
         if $debug; then
+            # Do this in a sub-shell, so we are operating on the right
+            # TEST_DIR / QEMU_TEST_DIR
             (
             export TEST_DIR=$TEST_DIR_SEQ
             cd "$source_iotests";
@@ -766,6 +768,8 @@ do
                     $run_command -d 2>&1 | tee $tmp.out
             )
         else
+            # Do this in a sub-shell, so we are operating on the right
+            # TEST_DIR / QEMU_TEST_DIR
             (
             export TEST_DIR=$TEST_DIR_SEQ
             cd "$source_iotests";
@@ -837,6 +841,15 @@ do
             fi
         fi
 
+        # Do this in a sub-shell, so we are operating on the right
+        # TEST_DIR / QEMU_TEST_DIR
+        (
+        export TEST_DIR=$TEST_DIR_SEQ
+        . "$source_iotests/common.config"
+        . "$source_iotests/common.rc"
+
+        _cleanup_protocols
+        )
         rm -rf "$TEST_DIR_SEQ"
 
     fi
diff --git a/tests/qemu-iotests/common.rc b/tests/qemu-iotests/common.rc
index 0e8a33c..a345ffd 100644
--- a/tests/qemu-iotests/common.rc
+++ b/tests/qemu-iotests/common.rc
@@ -101,7 +101,7 @@ _qemu_nbd_wrapper()
 _qemu_vxhs_wrapper()
 {
     (
-        echo $BASHPID > "${TEST_DIR}/qemu-vxhs.pid"
+        echo $BASHPID > "${QEMU_TEST_DIR}/qemu-vxhs.pid"
         exec "$QEMU_VXHS_PROG" $QEMU_VXHS_OPTIONS "$@"
     )
 }
@@ -248,7 +248,7 @@ _make_test_img()
 
     # Start QNIO server on image directory for vxhs protocol
     if [ $IMGPROTO = "vxhs" ]; then
-        eval "$QEMU_VXHS -d  $TEST_DIR > /dev/null &"
+        eval "$QEMU_VXHS -d  $QEMU_TEST_DIR > /dev/null &"
         sleep 1 # Wait for server to come up.
     fi
 }
@@ -264,29 +264,64 @@ _rm_test_img()
     rm -f "$img"
 }
 
+_cleanup_nbd()
+{
+    if [ -f "${QEMU_TEST_DIR}/qemu-nbd.pid" ]; then
+        local QEMU_NBD_PID
+        read QEMU_NBD_PID < "${QEMU_TEST_DIR}/qemu-nbd.pid"
+        rm -f "${QEMU_TEST_DIR}/qemu-nbd.pid"
+        kill ${QEMU_NBD_PID} >/dev/null 2>&1
+     fi
+}
+
+_cleanup_vxhs()
+{
+    if [ -f "${QEMU_TEST_DIR}/qemu-vxhs.pid" ]; then
+        local QEMU_VXHS_PID
+        read QEMU_VXHS_PID < "${QEMU_TEST_DIR}/qemu-vxhs.pid"
+        rm -f "${QEMU_TEST_DIR}/qemu-vxhs.pid"
+        kill ${QEMU_VXHS_PID} >/dev/null 2>&1
+    fi
+}
+
+_cleanup_rbd()
+{
+    rbd --no-progress rm "$QEMU_TEST_DIR/t.$IMGFMT" > /dev/null
+}
+
+_cleanup_sheepdog()
+{
+    collie vdi delete "$QEMU_TEST_DIR/t.$IMGFMT"
+}
+
+
+_cleanup_protocols()
+{
+    # Some tests (e.g. 058) start some protocols
+    # even though the protocol was not specified when running
+    # check.  If the wrappers create pidfiles, go ahead and clean
+    # up without checking $IMGPROTO.
+    _cleanup_nbd
+    _cleanup_vxhs
+
+    case "$IMGPROTO" in
+
+        rbd)
+            _cleanup_rbd
+            ;;
+
+        sheepdog)
+            _cleanup_sheepdog
+            ;;
+
+    esac
+}
+
 _cleanup_test_img()
 {
+    _cleanup_protocols
+
     case "$IMGPROTO" in
-
-        nbd)
-            if [ -f "${QEMU_TEST_DIR}/qemu-nbd.pid" ]; then
-                local QEMU_NBD_PID
-                read QEMU_NBD_PID < "${QEMU_TEST_DIR}/qemu-nbd.pid"
-                kill ${QEMU_NBD_PID}
-                rm -f "${QEMU_TEST_DIR}/qemu-nbd.pid"
-            fi
-            rm -f "$TEST_IMG_FILE"
-            ;;
-        vxhs)
-            if [ -f "${TEST_DIR}/qemu-vxhs.pid" ]; then
-                local QEMU_VXHS_PID
-                read QEMU_VXHS_PID < "${TEST_DIR}/qemu-vxhs.pid"
-                kill ${QEMU_VXHS_PID} >/dev/null 2>&1
-                rm -f "${TEST_DIR}/qemu-vxhs.pid"
-            fi
-            rm -f "$TEST_IMG_FILE"
-            ;;
-
         file)
             _rm_test_img "$TEST_DIR/t.$IMGFMT"
             _rm_test_img "$TEST_DIR/t.$IMGFMT.orig"
@@ -298,16 +333,12 @@ _cleanup_test_img()
                 TEST_IMG="$ORIG_TEST_IMG"
             fi
             ;;
-
-        rbd)
-            rbd --no-progress rm "$TEST_DIR/t.$IMGFMT" > /dev/null
-            ;;
-
-        sheepdog)
-            collie vdi delete "$TEST_DIR/t.$IMGFMT"
-            ;;
-
     esac
+
+    if [ -n "$TEST_IMG_FILE" ]
+    then
+        rm -f "$TEST_IMG_FILE"
+    fi
 }
 
 _check_test_img()
-- 
2.9.5

^ permalink raw reply related	[flat|nested] 37+ messages in thread

* [Qemu-devel] [PATCH v5 04/10] qemu-iotests: remove file cleanup from bash tests
  2017-10-17 16:31 [Qemu-devel] [PATCH v5 00/10] qemu-iotests improvements Jeff Cody
                   ` (2 preceding siblings ...)
  2017-10-17 16:31 ` [Qemu-devel] [PATCH v5 03/10] qemu-iotests: automatically clean up bash protocol servers Jeff Cody
@ 2017-10-17 16:31 ` Jeff Cody
  2017-10-18 13:46   ` Eric Blake
  2017-10-17 16:31 ` [Qemu-devel] [PATCH v5 05/10] qemu-iotests: change qemu pid and fd tracking / cleanup Jeff Cody
                   ` (5 subsequent siblings)
  9 siblings, 1 reply; 37+ messages in thread
From: Jeff Cody @ 2017-10-17 16:31 UTC (permalink / raw)
  To: qemu-devel; +Cc: qemu-block, jsnow, stefanha, kwolf, eblake

All files for a given test are now self-contained in a subdirectory,
and therefore the "./check" script can do all file-related cleanup
without any help.

This removes file cleanups from the bash tests.  The only cleanup left
is whatever is needed to kill any spawned processes; e.g. _cleanup_qemu.

Signed-off-by: Jeff Cody <jcody@redhat.com>
---
 tests/qemu-iotests/001     |  6 ------
 tests/qemu-iotests/002     |  6 ------
 tests/qemu-iotests/003     |  6 ------
 tests/qemu-iotests/004     |  6 ------
 tests/qemu-iotests/005     |  6 ------
 tests/qemu-iotests/007     |  7 -------
 tests/qemu-iotests/008     |  6 ------
 tests/qemu-iotests/009     |  6 ------
 tests/qemu-iotests/010     |  6 ------
 tests/qemu-iotests/011     |  6 ------
 tests/qemu-iotests/012     |  6 ------
 tests/qemu-iotests/013     |  6 ------
 tests/qemu-iotests/014     |  6 ------
 tests/qemu-iotests/015     |  7 -------
 tests/qemu-iotests/017     |  6 ------
 tests/qemu-iotests/018     |  6 ------
 tests/qemu-iotests/019     |  8 --------
 tests/qemu-iotests/020     |  8 --------
 tests/qemu-iotests/021     |  6 ------
 tests/qemu-iotests/022     |  6 ------
 tests/qemu-iotests/023     |  6 ------
 tests/qemu-iotests/024     |  8 --------
 tests/qemu-iotests/025     |  6 ------
 tests/qemu-iotests/026     |  7 -------
 tests/qemu-iotests/027     |  6 ------
 tests/qemu-iotests/028     |  8 --------
 tests/qemu-iotests/029     |  7 -------
 tests/qemu-iotests/031     |  6 ------
 tests/qemu-iotests/032     |  6 ------
 tests/qemu-iotests/033     |  6 ------
 tests/qemu-iotests/034     |  6 ------
 tests/qemu-iotests/035     |  6 ------
 tests/qemu-iotests/036     |  6 ------
 tests/qemu-iotests/037     |  6 ------
 tests/qemu-iotests/038     |  6 ------
 tests/qemu-iotests/039     |  6 ------
 tests/qemu-iotests/042     |  6 ------
 tests/qemu-iotests/043     |  7 -------
 tests/qemu-iotests/046     |  6 ------
 tests/qemu-iotests/047     |  6 ------
 tests/qemu-iotests/048     |  8 --------
 tests/qemu-iotests/048.out |  1 -
 tests/qemu-iotests/049     |  6 ------
 tests/qemu-iotests/050     |  8 --------
 tests/qemu-iotests/051     |  6 ------
 tests/qemu-iotests/052     |  6 ------
 tests/qemu-iotests/053     |  7 -------
 tests/qemu-iotests/054     |  6 ------
 tests/qemu-iotests/058     | 47 ++++++++++++++--------------------------------
 tests/qemu-iotests/059     |  7 -------
 tests/qemu-iotests/060     |  6 ------
 tests/qemu-iotests/061     |  6 ------
 tests/qemu-iotests/062     |  6 ------
 tests/qemu-iotests/063     |  7 -------
 tests/qemu-iotests/064     |  6 ------
 tests/qemu-iotests/066     |  6 ------
 tests/qemu-iotests/068     |  6 ------
 tests/qemu-iotests/069     |  6 ------
 tests/qemu-iotests/070     |  6 ------
 tests/qemu-iotests/071     |  6 ------
 tests/qemu-iotests/072     |  6 ------
 tests/qemu-iotests/073     |  6 ------
 tests/qemu-iotests/074     |  9 ---------
 tests/qemu-iotests/074.out |  1 -
 tests/qemu-iotests/075     |  6 ------
 tests/qemu-iotests/076     |  6 ------
 tests/qemu-iotests/077     |  6 ------
 tests/qemu-iotests/078     |  6 ------
 tests/qemu-iotests/079     |  6 ------
 tests/qemu-iotests/080     |  7 -------
 tests/qemu-iotests/081     |  8 --------
 tests/qemu-iotests/082     |  6 ------
 tests/qemu-iotests/083     |  8 --------
 tests/qemu-iotests/084     |  6 ------
 tests/qemu-iotests/085     | 13 +------------
 tests/qemu-iotests/086     |  6 ------
 tests/qemu-iotests/088     |  7 -------
 tests/qemu-iotests/089     |  6 ------
 tests/qemu-iotests/090     |  6 ------
 tests/qemu-iotests/091     |  8 +-------
 tests/qemu-iotests/092     |  7 -------
 tests/qemu-iotests/094     |  9 +--------
 tests/qemu-iotests/095     |  8 +-------
 tests/qemu-iotests/097     |  7 -------
 tests/qemu-iotests/098     |  7 -------
 tests/qemu-iotests/099     |  6 ------
 tests/qemu-iotests/101     |  6 ------
 tests/qemu-iotests/102     |  7 +------
 tests/qemu-iotests/103     |  6 ------
 tests/qemu-iotests/104     |  2 --
 tests/qemu-iotests/105     |  6 ------
 tests/qemu-iotests/106     |  6 ------
 tests/qemu-iotests/107     |  6 ------
 tests/qemu-iotests/108     |  6 ------
 tests/qemu-iotests/109     |  8 +-------
 tests/qemu-iotests/110     |  6 ------
 tests/qemu-iotests/111     |  6 ------
 tests/qemu-iotests/112     |  6 ------
 tests/qemu-iotests/113     |  6 ------
 tests/qemu-iotests/114     |  6 ------
 tests/qemu-iotests/115     |  6 ------
 tests/qemu-iotests/116     |  6 ------
 tests/qemu-iotests/117     |  7 +------
 tests/qemu-iotests/119     |  6 ------
 tests/qemu-iotests/120     |  6 ------
 tests/qemu-iotests/121     |  6 ------
 tests/qemu-iotests/122     |  7 -------
 tests/qemu-iotests/123     |  7 -------
 tests/qemu-iotests/125     |  6 ------
 tests/qemu-iotests/130     |  7 +------
 tests/qemu-iotests/131     |  6 ------
 tests/qemu-iotests/133     |  6 ------
 tests/qemu-iotests/134     |  6 ------
 tests/qemu-iotests/135     |  6 ------
 tests/qemu-iotests/137     |  6 ------
 tests/qemu-iotests/138     |  6 ------
 tests/qemu-iotests/140     |  8 +-------
 tests/qemu-iotests/141     |  8 +-------
 tests/qemu-iotests/142     |  7 -------
 tests/qemu-iotests/143     |  7 +------
 tests/qemu-iotests/144     |  8 +-------
 tests/qemu-iotests/145     |  7 -------
 tests/qemu-iotests/146     |  7 +------
 tests/qemu-iotests/150     |  6 ------
 tests/qemu-iotests/153     | 12 ------------
 tests/qemu-iotests/154     |  6 ------
 tests/qemu-iotests/156     |  7 +------
 tests/qemu-iotests/157     |  6 ------
 tests/qemu-iotests/158     |  6 ------
 tests/qemu-iotests/159     |  7 -------
 tests/qemu-iotests/160     |  7 -------
 tests/qemu-iotests/162     |  7 -------
 tests/qemu-iotests/170     |  7 -------
 tests/qemu-iotests/171     |  6 ------
 tests/qemu-iotests/172     |  8 --------
 tests/qemu-iotests/173     |  8 +-------
 tests/qemu-iotests/174     |  6 ------
 tests/qemu-iotests/175     |  6 ------
 tests/qemu-iotests/176     |  7 -------
 tests/qemu-iotests/177     |  6 ------
 tests/qemu-iotests/178     |  7 -------
 tests/qemu-iotests/179     |  7 -------
 tests/qemu-iotests/181     |  8 +-------
 tests/qemu-iotests/182     |  6 ------
 tests/qemu-iotests/183     |  9 +--------
 tests/qemu-iotests/184     |  6 ------
 tests/qemu-iotests/185     |  9 +--------
 tests/qemu-iotests/186     |  6 ------
 tests/qemu-iotests/187     |  8 --------
 tests/qemu-iotests/188     |  6 ------
 tests/qemu-iotests/189     |  6 ------
 tests/qemu-iotests/190     |  7 -------
 tests/qemu-iotests/191     |  4 ----
 tests/qemu-iotests/192     |  6 ------
 tests/qemu-iotests/195     |  7 -------
 tests/qemu-iotests/197     |  7 -------
 156 files changed, 32 insertions(+), 1023 deletions(-)

diff --git a/tests/qemu-iotests/001 b/tests/qemu-iotests/001
index ffd14e2..6f71879 100755
--- a/tests/qemu-iotests/001
+++ b/tests/qemu-iotests/001
@@ -27,12 +27,6 @@ echo "QA output created by $seq"
 here=`pwd`
 status=1	# failure is the default!
 
-_cleanup()
-{
-	_cleanup_test_img
-}
-trap "_cleanup; exit \$status" 0 1 2 3 15
-
 # get standard environment, filters and checks
 . ./common.rc
 . ./common.filter
diff --git a/tests/qemu-iotests/002 b/tests/qemu-iotests/002
index d4f8e91..4c9ff23 100755
--- a/tests/qemu-iotests/002
+++ b/tests/qemu-iotests/002
@@ -27,12 +27,6 @@ echo "QA output created by $seq"
 here=`pwd`
 status=1	# failure is the default!
 
-_cleanup()
-{
-	_cleanup_test_img
-}
-trap "_cleanup; exit \$status" 0 1 2 3 15
-
 # get standard environment, filters and checks
 . ./common.rc
 . ./common.filter
diff --git a/tests/qemu-iotests/003 b/tests/qemu-iotests/003
index 19889b9..2648d03 100755
--- a/tests/qemu-iotests/003
+++ b/tests/qemu-iotests/003
@@ -27,12 +27,6 @@ echo "QA output created by $seq"
 here=`pwd`
 status=1	# failure is the default!
 
-_cleanup()
-{
-	_cleanup_test_img
-}
-trap "_cleanup; exit \$status" 0 1 2 3 15
-
 # get standard environment, filters and checks
 . ./common.rc
 . ./common.filter
diff --git a/tests/qemu-iotests/004 b/tests/qemu-iotests/004
index 6f2aa3d..99743b4 100755
--- a/tests/qemu-iotests/004
+++ b/tests/qemu-iotests/004
@@ -27,12 +27,6 @@ echo "QA output created by $seq"
 here=`pwd`
 status=1	# failure is the default!
 
-_cleanup()
-{
-	_cleanup_test_img
-}
-trap "_cleanup; exit \$status" 0 1 2 3 15
-
 # get standard environment, filters and checks
 . ./common.rc
 . ./common.filter
diff --git a/tests/qemu-iotests/005 b/tests/qemu-iotests/005
index 4447377..23a77e0 100755
--- a/tests/qemu-iotests/005
+++ b/tests/qemu-iotests/005
@@ -30,12 +30,6 @@ echo "QA output created by $seq"
 here=`pwd`
 status=1	# failure is the default!
 
-_cleanup()
-{
-	_cleanup_test_img
-}
-trap "_cleanup; exit \$status" 0 1 2 3 15
-
 # get standard environment, filters and checks
 . ./common.rc
 . ./common.filter
diff --git a/tests/qemu-iotests/007 b/tests/qemu-iotests/007
index fa543ee..c8068e5 100755
--- a/tests/qemu-iotests/007
+++ b/tests/qemu-iotests/007
@@ -27,13 +27,6 @@ echo "QA output created by $seq"
 here=`pwd`
 status=1	# failure is the default!
 
-_cleanup()
-{
-	_cleanup_test_img
-	true
-}
-trap "_cleanup; exit \$status" 0 1 2 3 15
-
 # get standard environment, filters and checks
 . ./common.rc
 . ./common.filter
diff --git a/tests/qemu-iotests/008 b/tests/qemu-iotests/008
index 8e89d74..7f7f8ae 100755
--- a/tests/qemu-iotests/008
+++ b/tests/qemu-iotests/008
@@ -27,12 +27,6 @@ echo "QA output created by $seq"
 here=`pwd`
 status=1	# failure is the default!
 
-_cleanup()
-{
-	_cleanup_test_img
-}
-trap "_cleanup; exit \$status" 0 1 2 3 15
-
 # get standard environment, filters and checks
 . ./common.rc
 . ./common.filter
diff --git a/tests/qemu-iotests/009 b/tests/qemu-iotests/009
index 16e4475..e03412a 100755
--- a/tests/qemu-iotests/009
+++ b/tests/qemu-iotests/009
@@ -27,12 +27,6 @@ echo "QA output created by $seq"
 here=`pwd`
 status=1	# failure is the default!
 
-_cleanup()
-{
-	_cleanup_test_img
-}
-trap "_cleanup; exit \$status" 0 1 2 3 15
-
 # get standard environment, filters and checks
 . ./common.rc
 . ./common.filter
diff --git a/tests/qemu-iotests/010 b/tests/qemu-iotests/010
index 151dac2..8608848 100755
--- a/tests/qemu-iotests/010
+++ b/tests/qemu-iotests/010
@@ -27,12 +27,6 @@ echo "QA output created by $seq"
 here=`pwd`
 status=1	# failure is the default!
 
-_cleanup()
-{
-	_cleanup_test_img
-}
-trap "_cleanup; exit \$status" 0 1 2 3 15
-
 # get standard environment, filters and checks
 . ./common.rc
 . ./common.filter
diff --git a/tests/qemu-iotests/011 b/tests/qemu-iotests/011
index f8d044e..0c0d15f 100755
--- a/tests/qemu-iotests/011
+++ b/tests/qemu-iotests/011
@@ -27,12 +27,6 @@ echo "QA output created by $seq"
 here=`pwd`
 status=1	# failure is the default!
 
-_cleanup()
-{
-	_cleanup_test_img
-}
-trap "_cleanup; exit \$status" 0 1 2 3 15
-
 # get standard environment, filters and checks
 . ./common.rc
 . ./common.filter
diff --git a/tests/qemu-iotests/012 b/tests/qemu-iotests/012
index 01a770d..aa9cfb4 100755
--- a/tests/qemu-iotests/012
+++ b/tests/qemu-iotests/012
@@ -29,12 +29,6 @@ echo "QA output created by $seq"
 here=`pwd`
 status=1	# failure is the default!
 
-_cleanup()
-{
-	_cleanup_test_img
-}
-trap "_cleanup; exit \$status" 0 1 2 3 15
-
 # get standard environment, filters and checks
 . ./common.rc
 . ./common.filter
diff --git a/tests/qemu-iotests/013 b/tests/qemu-iotests/013
index d013f87..0ff9c4d 100755
--- a/tests/qemu-iotests/013
+++ b/tests/qemu-iotests/013
@@ -27,12 +27,6 @@ echo "QA output created by $seq"
 here=`pwd`
 status=1	# failure is the default!
 
-_cleanup()
-{
-	_cleanup_test_img
-}
-trap "_cleanup; exit \$status" 0 1 2 3 15
-
 # get standard environment, filters and checks
 . ./common.rc
 . ./common.filter
diff --git a/tests/qemu-iotests/014 b/tests/qemu-iotests/014
index 2ea79e8..3dee9f7 100755
--- a/tests/qemu-iotests/014
+++ b/tests/qemu-iotests/014
@@ -29,12 +29,6 @@ echo "QA output created by $seq"
 here=`pwd`
 status=1	# failure is the default!
 
-_cleanup()
-{
-	_cleanup_test_img
-}
-trap "_cleanup; exit \$status" 0 1 2 3 15
-
 # get standard environment, filters and checks
 . ./common.rc
 . ./common.filter
diff --git a/tests/qemu-iotests/015 b/tests/qemu-iotests/015
index aaf9c3f..d29a778 100755
--- a/tests/qemu-iotests/015
+++ b/tests/qemu-iotests/015
@@ -27,13 +27,6 @@ echo "QA output created by $seq"
 here=`pwd`
 status=1	# failure is the default!
 
-_cleanup()
-{
-	_cleanup_test_img
-	true
-}
-trap "_cleanup; exit \$status" 0 1 2 3 15
-
 # get standard environment, filters and checks
 . ./common.rc
 . ./common.filter
diff --git a/tests/qemu-iotests/017 b/tests/qemu-iotests/017
index 4f9302d..994ea0e 100755
--- a/tests/qemu-iotests/017
+++ b/tests/qemu-iotests/017
@@ -27,12 +27,6 @@ echo "QA output created by $seq"
 here=`pwd`
 status=1	# failure is the default!
 
-_cleanup()
-{
-	_cleanup_test_img
-}
-trap "_cleanup; exit \$status" 0 1 2 3 15
-
 # get standard environment, filters and checks
 . ./common.rc
 . ./common.filter
diff --git a/tests/qemu-iotests/018 b/tests/qemu-iotests/018
index 1d39d35..11ad2b1 100755
--- a/tests/qemu-iotests/018
+++ b/tests/qemu-iotests/018
@@ -27,12 +27,6 @@ echo "QA output created by $seq"
 here=`pwd`
 status=1	# failure is the default!
 
-_cleanup()
-{
-	_cleanup_test_img
-}
-trap "_cleanup; exit \$status" 0 1 2 3 15
-
 # get standard environment, filters and checks
 . ./common.rc
 . ./common.filter
diff --git a/tests/qemu-iotests/019 b/tests/qemu-iotests/019
index 24a789a..3728193 100755
--- a/tests/qemu-iotests/019
+++ b/tests/qemu-iotests/019
@@ -29,14 +29,6 @@ echo "QA output created by $seq"
 here=`pwd`
 status=1	# failure is the default!
 
-_cleanup()
-{
-	_cleanup_test_img
-    rm -f "$TEST_IMG.base"
-    rm -f "$TEST_IMG.orig"
-}
-trap "_cleanup; exit \$status" 0 1 2 3 15
-
 # get standard environment, filters and checks
 . ./common.rc
 . ./common.filter
diff --git a/tests/qemu-iotests/020 b/tests/qemu-iotests/020
index 7a11110..37cd5d1 100755
--- a/tests/qemu-iotests/020
+++ b/tests/qemu-iotests/020
@@ -27,14 +27,6 @@ echo "QA output created by $seq"
 here=`pwd`
 status=1	# failure is the default!
 
-_cleanup()
-{
-	_cleanup_test_img
-    rm -f "$TEST_IMG.base"
-    rm -f "$TEST_IMG.orig"
-}
-trap "_cleanup; exit \$status" 0 1 2 3 15
-
 # get standard environment, filters and checks
 . ./common.rc
 . ./common.filter
diff --git a/tests/qemu-iotests/021 b/tests/qemu-iotests/021
index 11e8ed7..5ab2acb 100755
--- a/tests/qemu-iotests/021
+++ b/tests/qemu-iotests/021
@@ -27,12 +27,6 @@ echo "QA output created by $seq"
 here=`pwd`
 status=1	# failure is the default!
 
-_cleanup()
-{
-	_cleanup_test_img
-}
-trap "_cleanup; exit \$status" 0 1 2 3 15
-
 # get standard environment, filters and checks
 . ./common.rc
 . ./common.filter
diff --git a/tests/qemu-iotests/022 b/tests/qemu-iotests/022
index 2452a9f..4870b17 100755
--- a/tests/qemu-iotests/022
+++ b/tests/qemu-iotests/022
@@ -29,12 +29,6 @@ echo "QA output created by $seq"
 here=`pwd`
 status=1	# failure is the default!
 
-_cleanup()
-{
-	_cleanup_test_img
-}
-trap "_cleanup; exit \$status" 0 1 2 3 15
-
 # get standard environment, filters and checks
 . ./common.rc
 . ./common.filter
diff --git a/tests/qemu-iotests/023 b/tests/qemu-iotests/023
index 497ae1e..5a2bf4e 100755
--- a/tests/qemu-iotests/023
+++ b/tests/qemu-iotests/023
@@ -27,12 +27,6 @@ echo "QA output created by $seq"
 here=`pwd`
 status=1	# failure is the default!
 
-_cleanup()
-{
-	_cleanup_test_img
-}
-trap "_cleanup; exit \$status" 0 1 2 3 15
-
 # get standard environment, filters and checks
 . ./common.rc
 . ./common.filter
diff --git a/tests/qemu-iotests/024 b/tests/qemu-iotests/024
index e0d77ce..3e638d9 100755
--- a/tests/qemu-iotests/024
+++ b/tests/qemu-iotests/024
@@ -27,14 +27,6 @@ echo "QA output created by $seq"
 here=`pwd`
 status=1	# failure is the default!
 
-_cleanup()
-{
-	_cleanup_test_img
-	rm -f "$TEST_DIR/t.$IMGFMT.base_old"
-	rm -f "$TEST_DIR/t.$IMGFMT.base_new"
-}
-trap "_cleanup; exit \$status" 0 1 2 3 15
-
 # get standard environment, filters and checks
 . ./common.rc
 . ./common.filter
diff --git a/tests/qemu-iotests/025 b/tests/qemu-iotests/025
index f5e672e..93634c1 100755
--- a/tests/qemu-iotests/025
+++ b/tests/qemu-iotests/025
@@ -27,12 +27,6 @@ echo "QA output created by $seq"
 here=`pwd`
 status=1	# failure is the default!
 
-_cleanup()
-{
-	_cleanup_test_img
-}
-trap "_cleanup; exit \$status" 0 1 2 3 15
-
 # get standard environment, filters and checks
 . ./common.rc
 . ./common.filter
diff --git a/tests/qemu-iotests/026 b/tests/qemu-iotests/026
index 7fadfba..dc4ff9f 100755
--- a/tests/qemu-iotests/026
+++ b/tests/qemu-iotests/026
@@ -27,13 +27,6 @@ echo "QA output created by $seq"
 here=`pwd`
 status=1	# failure is the default!
 
-_cleanup()
-{
-	_cleanup_test_img
-    rm "$TEST_DIR/blkdebug.conf"
-}
-trap "_cleanup; exit \$status" 0 1 2 3 15
-
 # get standard environment, filters and checks
 . ./common.rc
 . ./common.filter
diff --git a/tests/qemu-iotests/027 b/tests/qemu-iotests/027
index 08593da..c3f9146 100755
--- a/tests/qemu-iotests/027
+++ b/tests/qemu-iotests/027
@@ -27,12 +27,6 @@ echo "QA output created by $seq"
 here=`pwd`
 status=1	# failure is the default!
 
-_cleanup()
-{
-	_cleanup_test_img
-}
-trap "_cleanup; exit \$status" 0 1 2 3 15
-
 # get standard environment, filters and checks
 . ./common.rc
 . ./common.filter
diff --git a/tests/qemu-iotests/028 b/tests/qemu-iotests/028
index 97a8869..3176789 100755
--- a/tests/qemu-iotests/028
+++ b/tests/qemu-iotests/028
@@ -30,14 +30,6 @@ echo "QA output created by $seq"
 here=`pwd`
 status=1	# failure is the default!
 
-_cleanup()
-{
-    _cleanup_qemu
-    rm -f "${TEST_IMG}.copy"
-    _cleanup_test_img
-}
-trap "_cleanup; exit \$status" 0 1 2 3 15
-
 # get standard environment, filters and checks
 . ./common.rc
 . ./common.filter
diff --git a/tests/qemu-iotests/029 b/tests/qemu-iotests/029
index 30bab24..981a864 100755
--- a/tests/qemu-iotests/029
+++ b/tests/qemu-iotests/029
@@ -27,13 +27,6 @@ echo "QA output created by $seq"
 here=`pwd`
 status=1	# failure is the default!
 
-_cleanup()
-{
-    rm -f $TEST_IMG.snap
-    _cleanup_test_img
-}
-trap "_cleanup; exit \$status" 0 1 2 3 15
-
 # get standard environment, filters and checks
 . ./common.rc
 . ./common.filter
diff --git a/tests/qemu-iotests/031 b/tests/qemu-iotests/031
index 1e08abc..6805c2c 100755
--- a/tests/qemu-iotests/031
+++ b/tests/qemu-iotests/031
@@ -27,12 +27,6 @@ echo "QA output created by $seq"
 here=`pwd`
 status=1	# failure is the default!
 
-_cleanup()
-{
-	_cleanup_test_img
-}
-trap "_cleanup; exit \$status" 0 1 2 3 15
-
 # get standard environment, filters and checks
 . ./common.rc
 . ./common.filter
diff --git a/tests/qemu-iotests/032 b/tests/qemu-iotests/032
index 24bcb52..dafcfb8 100755
--- a/tests/qemu-iotests/032
+++ b/tests/qemu-iotests/032
@@ -29,12 +29,6 @@ echo "QA output created by $seq"
 here=`pwd`
 status=1	# failure is the default!
 
-_cleanup()
-{
-	_cleanup_test_img
-}
-trap "_cleanup; exit \$status" 0 1 2 3 15
-
 # get standard environment, filters and checks
 . ./common.rc
 . ./common.filter
diff --git a/tests/qemu-iotests/033 b/tests/qemu-iotests/033
index 2cdfd13..bf3c59c 100755
--- a/tests/qemu-iotests/033
+++ b/tests/qemu-iotests/033
@@ -27,12 +27,6 @@ echo "QA output created by $seq"
 here=`pwd`
 status=1	# failure is the default!
 
-_cleanup()
-{
-	_cleanup_test_img
-}
-trap "_cleanup; exit \$status" 0 1 2 3 15
-
 # get standard environment, filters and checks
 . ./common.rc
 . ./common.filter
diff --git a/tests/qemu-iotests/034 b/tests/qemu-iotests/034
index 1b28bda..830b0db 100755
--- a/tests/qemu-iotests/034
+++ b/tests/qemu-iotests/034
@@ -27,12 +27,6 @@ echo "QA output created by $seq"
 here=`pwd`
 status=1	# failure is the default!
 
-_cleanup()
-{
-	_cleanup_test_img
-}
-trap "_cleanup; exit \$status" 0 1 2 3 15
-
 # get standard environment, filters and checks
 . ./common.rc
 . ./common.filter
diff --git a/tests/qemu-iotests/035 b/tests/qemu-iotests/035
index efc38e4..a79a4fd 100755
--- a/tests/qemu-iotests/035
+++ b/tests/qemu-iotests/035
@@ -28,12 +28,6 @@ echo "QA output created by $seq"
 here=`pwd`
 status=1	# failure is the default!
 
-_cleanup()
-{
-	_cleanup_test_img
-}
-trap "_cleanup; exit \$status" 0 1 2 3 15
-
 # get standard environment, filters and checks
 . ./common.rc
 . ./common.filter
diff --git a/tests/qemu-iotests/036 b/tests/qemu-iotests/036
index ce638d6..841f347 100755
--- a/tests/qemu-iotests/036
+++ b/tests/qemu-iotests/036
@@ -30,12 +30,6 @@ echo "QA output created by $seq"
 here=`pwd`
 status=1	# failure is the default!
 
-_cleanup()
-{
-	_cleanup_test_img
-}
-trap "_cleanup; exit \$status" 0 1 2 3 15
-
 # get standard environment, filters and checks
 . ./common.rc
 . ./common.filter
diff --git a/tests/qemu-iotests/037 b/tests/qemu-iotests/037
index c476b82..756fc2c 100755
--- a/tests/qemu-iotests/037
+++ b/tests/qemu-iotests/037
@@ -27,12 +27,6 @@ echo "QA output created by $seq"
 here=`pwd`
 status=1	# failure is the default!
 
-_cleanup()
-{
-	_cleanup_test_img
-}
-trap "_cleanup; exit \$status" 0 1 2 3 15
-
 # get standard environment, filters and checks
 . ./common.rc
 . ./common.filter
diff --git a/tests/qemu-iotests/038 b/tests/qemu-iotests/038
index d99a150..cf730ae 100755
--- a/tests/qemu-iotests/038
+++ b/tests/qemu-iotests/038
@@ -27,12 +27,6 @@ echo "QA output created by $seq"
 here=`pwd`
 status=1	# failure is the default!
 
-_cleanup()
-{
-	_cleanup_test_img
-}
-trap "_cleanup; exit \$status" 0 1 2 3 15
-
 # get standard environment, filters and checks
 . ./common.rc
 . ./common.filter
diff --git a/tests/qemu-iotests/039 b/tests/qemu-iotests/039
index 1f48339..dd483c4 100755
--- a/tests/qemu-iotests/039
+++ b/tests/qemu-iotests/039
@@ -30,12 +30,6 @@ echo "QA output created by $seq"
 here=`pwd`
 status=1	# failure is the default!
 
-_cleanup()
-{
-	_cleanup_test_img
-}
-trap "_cleanup; exit \$status" 0 1 2 3 15
-
 # get standard environment, filters and checks
 . ./common.rc
 . ./common.filter
diff --git a/tests/qemu-iotests/042 b/tests/qemu-iotests/042
index a53e7cb..0efeec6 100755
--- a/tests/qemu-iotests/042
+++ b/tests/qemu-iotests/042
@@ -27,12 +27,6 @@ echo "QA output created by $seq"
 here=`pwd`
 status=1	# failure is the default!
 
-_cleanup()
-{
-	_cleanup_test_img
-}
-trap "_cleanup; exit \$status" 0 1 2 3 15
-
 # get standard environment, filters and checks
 . ./common.rc
 . ./common.filter
diff --git a/tests/qemu-iotests/043 b/tests/qemu-iotests/043
index 1c6c22d..48b71fe 100755
--- a/tests/qemu-iotests/043
+++ b/tests/qemu-iotests/043
@@ -27,13 +27,6 @@ echo "QA output created by $seq"
 here=`pwd`
 status=1	# failure is the default!
 
-_cleanup()
-{
-    _cleanup_test_img
-    rm -f "$TEST_IMG".[123].base
-}
-trap "_cleanup; exit \$status" 0 1 2 3 15
-
 # get standard environment, filters and checks
 . ./common.rc
 . ./common.filter
diff --git a/tests/qemu-iotests/046 b/tests/qemu-iotests/046
index f2ebecf..362ed94 100755
--- a/tests/qemu-iotests/046
+++ b/tests/qemu-iotests/046
@@ -27,12 +27,6 @@ echo "QA output created by $seq"
 here=`pwd`
 status=1	# failure is the default!
 
-_cleanup()
-{
-	_cleanup_test_img
-}
-trap "_cleanup; exit \$status" 0 1 2 3 15
-
 # get standard environment, filters and checks
 . ./common.rc
 . ./common.filter
diff --git a/tests/qemu-iotests/047 b/tests/qemu-iotests/047
index 1b8f3d4..1850035 100755
--- a/tests/qemu-iotests/047
+++ b/tests/qemu-iotests/047
@@ -28,12 +28,6 @@ echo "QA output created by $seq"
 here=`pwd`
 status=1	# failure is the default!
 
-_cleanup()
-{
-	_cleanup_test_img
-}
-trap "_cleanup; exit \$status" 0 1 2 3 15
-
 # get standard environment, filters and checks
 . ./common.rc
 . ./common.filter
diff --git a/tests/qemu-iotests/048 b/tests/qemu-iotests/048
index 9ed04a0..c95bd2f 100755
--- a/tests/qemu-iotests/048
+++ b/tests/qemu-iotests/048
@@ -27,14 +27,6 @@ echo "QA output created by $seq"
 
 status=1        # failure is the default!
 
-_cleanup()
-{
-    echo "Cleanup"
-    _cleanup_test_img
-    rm "${TEST_IMG_FILE2}"
-}
-trap "_cleanup; exit \$status" 0 1 2 3 15
-
 _compare()
 {
     $QEMU_IMG compare $QEMU_IMG_EXTRA_ARGS "$@" "$TEST_IMG" "${TEST_IMG2}"
diff --git a/tests/qemu-iotests/048.out b/tests/qemu-iotests/048.out
index 0bcf663..3318eed 100644
--- a/tests/qemu-iotests/048.out
+++ b/tests/qemu-iotests/048.out
@@ -39,4 +39,3 @@ wrote 512/512 bytes at offset 512
 512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
 Content mismatch at offset 512!
 1
-Cleanup
diff --git a/tests/qemu-iotests/049 b/tests/qemu-iotests/049
index df35b6d..00733a6 100755
--- a/tests/qemu-iotests/049
+++ b/tests/qemu-iotests/049
@@ -27,12 +27,6 @@ echo "QA output created by $seq"
 here=`pwd`
 status=1	# failure is the default!
 
-_cleanup()
-{
-	_cleanup_test_img
-}
-trap "_cleanup; exit \$status" 0 1 2 3 15
-
 # get standard environment, filters and checks
 . ./common.rc
 . ./common.filter
diff --git a/tests/qemu-iotests/050 b/tests/qemu-iotests/050
index 03b4a5d..e3b6d8c 100755
--- a/tests/qemu-iotests/050
+++ b/tests/qemu-iotests/050
@@ -27,14 +27,6 @@ echo "QA output created by $seq"
 here=`pwd`
 status=1	# failure is the default!
 
-_cleanup()
-{
-    _cleanup_test_img
-    rm -f "$TEST_IMG.old"
-    rm -f "$TEST_IMG.new"
-}
-trap "_cleanup; exit \$status" 0 1 2 3 15
-
 # get standard environment, filters and checks
 . ./common.rc
 . ./common.filter
diff --git a/tests/qemu-iotests/051 b/tests/qemu-iotests/051
index dba8816..24da3c5 100755
--- a/tests/qemu-iotests/051
+++ b/tests/qemu-iotests/051
@@ -27,12 +27,6 @@ echo "QA output created by $seq"
 here=`pwd`
 status=1	# failure is the default!
 
-_cleanup()
-{
-	_cleanup_test_img
-}
-trap "_cleanup; exit \$status" 0 1 2 3 15
-
 # get standard environment, filters and checks
 . ./common.rc
 . ./common.filter
diff --git a/tests/qemu-iotests/052 b/tests/qemu-iotests/052
index 842eace..fc23fad 100755
--- a/tests/qemu-iotests/052
+++ b/tests/qemu-iotests/052
@@ -27,12 +27,6 @@ echo "QA output created by $seq"
 here=`pwd`
 status=1	# failure is the default!
 
-_cleanup()
-{
-	_cleanup_test_img
-}
-trap "_cleanup; exit \$status" 0 1 2 3 15
-
 # get standard environment, filters and checks
 . ./common.rc
 . ./common.filter
diff --git a/tests/qemu-iotests/053 b/tests/qemu-iotests/053
index 2a04f5f..e8b9037 100755
--- a/tests/qemu-iotests/053
+++ b/tests/qemu-iotests/053
@@ -27,13 +27,6 @@ echo "QA output created by $seq"
 here=`pwd`
 status=1	# failure is the default!
 
-_cleanup()
-{
-	rm -f "$TEST_IMG.orig"
-	_cleanup_test_img
-}
-trap "_cleanup; exit \$status" 0 1 2 3 15
-
 # get standard environment, filters and checks
 . ./common.rc
 . ./common.filter
diff --git a/tests/qemu-iotests/054 b/tests/qemu-iotests/054
index bf47ef9..e2de997 100755
--- a/tests/qemu-iotests/054
+++ b/tests/qemu-iotests/054
@@ -27,12 +27,6 @@ echo "QA output created by $seq"
 here=`pwd`
 status=1	# failure is the default!
 
-_cleanup()
-{
-	_cleanup_test_img
-}
-trap "_cleanup; exit \$status" 0 1 2 3 15
-
 # get standard environment, filters and checks
 . ./common.rc
 . ./common.filter
diff --git a/tests/qemu-iotests/058 b/tests/qemu-iotests/058
index 2253c6a..9ff07aa 100755
--- a/tests/qemu-iotests/058
+++ b/tests/qemu-iotests/058
@@ -29,23 +29,22 @@ echo "QA output created by $seq"
 here=`pwd`
 status=1	# failure is the default!
 
+# get standard environment, filters and checks
+. ./common.rc
+. ./common.filter
+. ./common.pattern
+
+_supported_fmt qcow2
+_supported_proto file
+_supported_os Linux
+_require_command QEMU_NBD
+# Internal snapshots are (currently) impossible with refcount_bits=1
+_unsupported_imgopts 'refcount_bits=1[^0-9]'
+
 nbd_unix_socket=$TEST_DIR/test_qemu_nbd_socket
 nbd_snapshot_img="nbd:unix:$nbd_unix_socket"
 rm -f "${TEST_DIR}/qemu-nbd.pid"
 
-_cleanup_nbd()
-{
-    local NBD_SNAPSHOT_PID
-    if [ -f "${TEST_DIR}/qemu-nbd.pid" ]; then
-        read NBD_SNAPSHOT_PID < "${TEST_DIR}/qemu-nbd.pid"
-        rm -f "${TEST_DIR}/qemu-nbd.pid"
-        if [ -n "$NBD_SNAPSHOT_PID" ]; then
-            kill "$NBD_SNAPSHOT_PID"
-        fi
-    fi
-    rm -f "$nbd_unix_socket"
-}
-
 _wait_for_nbd()
 {
     for ((i = 0; i < 300; i++))
@@ -64,6 +63,7 @@ converted_image=$TEST_IMG.converted
 _export_nbd_snapshot()
 {
     _cleanup_nbd
+    rm -f "$nbd_unix_socket"
     $QEMU_NBD -v -t -k "$nbd_unix_socket" "$TEST_IMG" -l $1 &
     _wait_for_nbd
 }
@@ -71,30 +71,11 @@ _export_nbd_snapshot()
 _export_nbd_snapshot1()
 {
     _cleanup_nbd
+    rm -f "$nbd_unix_socket"
     $QEMU_NBD -v -t -k "$nbd_unix_socket" "$TEST_IMG" -l snapshot.name=$1 &
     _wait_for_nbd
 }
 
-_cleanup()
-{
-    _cleanup_nbd
-    _cleanup_test_img
-    rm -f "$converted_image"
-}
-trap "_cleanup; exit \$status" 0 1 2 3 15
-
-# get standard environment, filters and checks
-. ./common.rc
-. ./common.filter
-. ./common.pattern
-
-_supported_fmt qcow2
-_supported_proto file
-_supported_os Linux
-_require_command QEMU_NBD
-# Internal snapshots are (currently) impossible with refcount_bits=1
-_unsupported_imgopts 'refcount_bits=1[^0-9]'
-
 # Use -f raw instead of -f $IMGFMT for the NBD connection
 QEMU_IO_NBD="$QEMU_IO -f raw --cache=$CACHEMODE"
 
diff --git a/tests/qemu-iotests/059 b/tests/qemu-iotests/059
index a1c34ee..6ccd250 100755
--- a/tests/qemu-iotests/059
+++ b/tests/qemu-iotests/059
@@ -27,13 +27,6 @@ echo "QA output created by $seq"
 here=`pwd`
 status=1	# failure is the default!
 
-_cleanup()
-{
-    _cleanup_test_img
-    rm -f "$TEST_IMG.qcow2"
-}
-trap "_cleanup; exit \$status" 0 1 2 3 15
-
 # get standard environment, filters and checks
 . ./common.rc
 . ./common.filter
diff --git a/tests/qemu-iotests/060 b/tests/qemu-iotests/060
index 8e95c45..6532837 100755
--- a/tests/qemu-iotests/060
+++ b/tests/qemu-iotests/060
@@ -27,12 +27,6 @@ echo "QA output created by $seq"
 here="$PWD"
 status=1	# failure is the default!
 
-_cleanup()
-{
-	_cleanup_test_img
-}
-trap "_cleanup; exit \$status" 0 1 2 3 15
-
 # get standard environment, filters and checks
 . ./common.rc
 . ./common.filter
diff --git a/tests/qemu-iotests/061 b/tests/qemu-iotests/061
index f5678b1..1346dd9 100755
--- a/tests/qemu-iotests/061
+++ b/tests/qemu-iotests/061
@@ -27,12 +27,6 @@ echo "QA output created by $seq"
 here=`pwd`
 status=1	# failure is the default!
 
-_cleanup()
-{
-	_cleanup_test_img
-}
-trap "_cleanup; exit \$status" 0 1 2 3 15
-
 # get standard environment, filters and checks
 . ./common.rc
 . ./common.filter
diff --git a/tests/qemu-iotests/062 b/tests/qemu-iotests/062
index 051fb9f..3a1df0d 100755
--- a/tests/qemu-iotests/062
+++ b/tests/qemu-iotests/062
@@ -28,12 +28,6 @@ echo "QA output created by $seq"
 here=`pwd`
 status=1	# failure is the default!
 
-_cleanup()
-{
-	_cleanup_test_img
-}
-trap "_cleanup; exit \$status" 0 1 2 3 15
-
 # get standard environment, filters and checks
 . ./common.rc
 . ./common.filter
diff --git a/tests/qemu-iotests/063 b/tests/qemu-iotests/063
index e4f6ea9..4a9fc44 100755
--- a/tests/qemu-iotests/063
+++ b/tests/qemu-iotests/063
@@ -28,13 +28,6 @@ echo "QA output created by $seq"
 here=`pwd`
 status=1	# failure is the default!
 
-_cleanup()
-{
-	_cleanup_test_img
-	rm -f "$TEST_IMG.orig" "$TEST_IMG.raw1" "$TEST_IMG.raw2"
-}
-trap "_cleanup; exit \$status" 0 1 2 3 15
-
 # get standard environment, filters and checks
 . ./common.rc
 . ./common.filter
diff --git a/tests/qemu-iotests/064 b/tests/qemu-iotests/064
index 5792fbb..211c541 100755
--- a/tests/qemu-iotests/064
+++ b/tests/qemu-iotests/064
@@ -27,12 +27,6 @@ echo "QA output created by $seq"
 here=`pwd`
 status=1	# failure is the default!
 
-_cleanup()
-{
-    _cleanup_test_img
-}
-trap "_cleanup; exit \$status" 0 1 2 3 15
-
 # get standard environment, filters and checks
 . ./common.rc
 . ./common.filter
diff --git a/tests/qemu-iotests/066 b/tests/qemu-iotests/066
index 8638217..e811f48 100755
--- a/tests/qemu-iotests/066
+++ b/tests/qemu-iotests/066
@@ -27,12 +27,6 @@ echo "QA output created by $seq"
 here="$PWD"
 status=1	# failure is the default!
 
-_cleanup()
-{
-	_cleanup_test_img
-}
-trap "_cleanup; exit \$status" 0 1 2 3 15
-
 # get standard environment, filters and checks
 . ./common.rc
 . ./common.filter
diff --git a/tests/qemu-iotests/068 b/tests/qemu-iotests/068
index e7fca6a..d117ff3 100755
--- a/tests/qemu-iotests/068
+++ b/tests/qemu-iotests/068
@@ -27,12 +27,6 @@ echo "QA output created by $seq"
 here="$PWD"
 status=1	# failure is the default!
 
-_cleanup()
-{
-	_cleanup_test_img
-}
-trap "_cleanup; exit \$status" 0 1 2 3 15
-
 # get standard environment, filters and checks
 . ./common.rc
 . ./common.filter
diff --git a/tests/qemu-iotests/069 b/tests/qemu-iotests/069
index 96e55ef..03d5a3c 100755
--- a/tests/qemu-iotests/069
+++ b/tests/qemu-iotests/069
@@ -27,12 +27,6 @@ echo "QA output created by $seq"
 here="$PWD"
 status=1	# failure is the default!
 
-_cleanup()
-{
-	_cleanup_test_img
-}
-trap "_cleanup; exit \$status" 0 1 2 3 15
-
 # get standard environment, filters and checks
 . ./common.rc
 . ./common.filter
diff --git a/tests/qemu-iotests/070 b/tests/qemu-iotests/070
index 8d08d74..1220cc1 100755
--- a/tests/qemu-iotests/070
+++ b/tests/qemu-iotests/070
@@ -28,12 +28,6 @@ echo "QA output created by $seq"
 here=`pwd`
 status=1	# failure is the default!
 
-_cleanup()
-{
-    _cleanup_test_img
-}
-trap "_cleanup; exit \$status" 0 1 2 3 15
-
 # get standard environment, filters and checks
 . ./common.rc
 . ./common.filter
diff --git a/tests/qemu-iotests/071 b/tests/qemu-iotests/071
index 48b4955..1a8d6e7 100755
--- a/tests/qemu-iotests/071
+++ b/tests/qemu-iotests/071
@@ -27,12 +27,6 @@ echo "QA output created by $seq"
 here="$PWD"
 status=1	# failure is the default!
 
-_cleanup()
-{
-	_cleanup_test_img
-}
-trap "_cleanup; exit \$status" 0 1 2 3 15
-
 # get standard environment, filters and checks
 . ./common.rc
 . ./common.filter
diff --git a/tests/qemu-iotests/072 b/tests/qemu-iotests/072
index aa027c7..8aaf3fd 100755
--- a/tests/qemu-iotests/072
+++ b/tests/qemu-iotests/072
@@ -27,12 +27,6 @@ echo "QA output created by $seq"
 here="$PWD"
 status=1	# failure is the default!
 
-_cleanup()
-{
-	_cleanup_test_img
-}
-trap "_cleanup; exit \$status" 0 1 2 3 15
-
 # get standard environment, filters and checks
 . ./common.rc
 . ./common.filter
diff --git a/tests/qemu-iotests/073 b/tests/qemu-iotests/073
index 40f85b1..c19ad0d 100755
--- a/tests/qemu-iotests/073
+++ b/tests/qemu-iotests/073
@@ -27,12 +27,6 @@ echo "QA output created by $seq"
 here=`pwd`
 status=1	# failure is the default!
 
-_cleanup()
-{
-    _cleanup_test_img
-}
-trap "_cleanup; exit \$status" 0 1 2 3 15
-
 # get standard environment, filters and checks
 . ./common.rc
 . ./common.filter
diff --git a/tests/qemu-iotests/074 b/tests/qemu-iotests/074
index b17866b..d7888ab 100755
--- a/tests/qemu-iotests/074
+++ b/tests/qemu-iotests/074
@@ -27,15 +27,6 @@ echo "QA output created by $seq"
 
 status=1        # failure is the default!
 
-_cleanup()
-{
-    echo "Cleanup"
-    _cleanup_test_img
-    rm "${TEST_IMG2}"
-    rm -f "$TEST_DIR/blkdebug.conf"
-}
-trap "_cleanup; exit \$status" 0 1 2 3 15
-
 _compare()
 {
     $QEMU_IMG compare "$@" "$TEST_IMG" "${TEST_IMG2}"
diff --git a/tests/qemu-iotests/074.out b/tests/qemu-iotests/074.out
index 8fba5ae..fb93965 100644
--- a/tests/qemu-iotests/074.out
+++ b/tests/qemu-iotests/074.out
@@ -15,4 +15,3 @@ qemu-img: Error while reading offset 0 of blkdebug:TEST_DIR/blkdebug.conf:TEST_D
 qemu-img: Error while reading offset 0 of blkdebug:TEST_DIR/blkdebug.conf:TEST_DIR/t.IMGFMT: Input/output error
 Warning: Image size mismatch!
 4
-Cleanup
diff --git a/tests/qemu-iotests/075 b/tests/qemu-iotests/075
index 770d51c..c2509d1 100755
--- a/tests/qemu-iotests/075
+++ b/tests/qemu-iotests/075
@@ -27,12 +27,6 @@ echo "QA output created by $seq"
 here=`pwd`
 status=1	# failure is the default!
 
-_cleanup()
-{
-	_cleanup_test_img
-}
-trap "_cleanup; exit \$status" 0 1 2 3 15
-
 # get standard environment, filters and checks
 . ./common.rc
 . ./common.filter
diff --git a/tests/qemu-iotests/076 b/tests/qemu-iotests/076
index ef9e6a4..69bccad 100755
--- a/tests/qemu-iotests/076
+++ b/tests/qemu-iotests/076
@@ -27,12 +27,6 @@ echo "QA output created by $seq"
 here=`pwd`
 status=1	# failure is the default!
 
-_cleanup()
-{
-	_cleanup_test_img
-}
-trap "_cleanup; exit \$status" 0 1 2 3 15
-
 # get standard environment, filters and checks
 . ./common.rc
 . ./common.filter
diff --git a/tests/qemu-iotests/077 b/tests/qemu-iotests/077
index d2d2a2d..4a458e1 100755
--- a/tests/qemu-iotests/077
+++ b/tests/qemu-iotests/077
@@ -27,12 +27,6 @@ echo "QA output created by $seq"
 here=`pwd`
 status=1	# failure is the default!
 
-_cleanup()
-{
-	_cleanup_test_img
-}
-trap "_cleanup; exit \$status" 0 1 2 3 15
-
 # get standard environment, filters and checks
 . ./common.rc
 . ./common.filter
diff --git a/tests/qemu-iotests/078 b/tests/qemu-iotests/078
index f333e9a..22d078e 100755
--- a/tests/qemu-iotests/078
+++ b/tests/qemu-iotests/078
@@ -27,12 +27,6 @@ echo "QA output created by $seq"
 here=`pwd`
 status=1	# failure is the default!
 
-_cleanup()
-{
-	_cleanup_test_img
-}
-trap "_cleanup; exit \$status" 0 1 2 3 15
-
 # get standard environment, filters and checks
 . ./common.rc
 . ./common.filter
diff --git a/tests/qemu-iotests/079 b/tests/qemu-iotests/079
index b2e3f74..fba6ec6 100755
--- a/tests/qemu-iotests/079
+++ b/tests/qemu-iotests/079
@@ -27,12 +27,6 @@ echo "QA output created by $seq"
 here=`pwd`
 status=1	# failure is the default!
 
-_cleanup()
-{
-	_cleanup_test_img
-}
-trap "_cleanup; exit \$status" 0 1 2 3 15
-
 # get standard environment, filters and checks
 . ./common.rc
 . ./common.filter
diff --git a/tests/qemu-iotests/080 b/tests/qemu-iotests/080
index 55044c7..be548a9 100755
--- a/tests/qemu-iotests/080
+++ b/tests/qemu-iotests/080
@@ -27,13 +27,6 @@ echo "QA output created by $seq"
 here=`pwd`
 status=1	# failure is the default!
 
-_cleanup()
-{
-    rm -f $TEST_IMG.snap
-    _cleanup_test_img
-}
-trap "_cleanup; exit \$status" 0 1 2 3 15
-
 # get standard environment, filters and checks
 . ./common.rc
 . ./common.filter
diff --git a/tests/qemu-iotests/081 b/tests/qemu-iotests/081
index da3fb09..2dadc16 100755
--- a/tests/qemu-iotests/081
+++ b/tests/qemu-iotests/081
@@ -27,14 +27,6 @@ echo "QA output created by $seq"
 here=`pwd`
 status=1	# failure is the default!
 
-_cleanup()
-{
-    rm -rf $TEST_DIR/1.raw
-    rm -rf $TEST_DIR/2.raw
-    rm -rf $TEST_DIR/3.raw
-}
-trap "_cleanup; exit \$status" 0 1 2 3 15
-
 # get standard environment, filters and checks
 . ./common.rc
 . ./common.filter
diff --git a/tests/qemu-iotests/082 b/tests/qemu-iotests/082
index d5c83d4..aa585db 100755
--- a/tests/qemu-iotests/082
+++ b/tests/qemu-iotests/082
@@ -27,12 +27,6 @@ echo "QA output created by $seq"
 here=`pwd`
 status=1	# failure is the default!
 
-_cleanup()
-{
-	_cleanup_test_img
-}
-trap "_cleanup; exit \$status" 0 1 2 3 15
-
 # get standard environment, filters and checks
 . ./common.rc
 . ./common.filter
diff --git a/tests/qemu-iotests/083 b/tests/qemu-iotests/083
index 0306f11..b2d0ce1 100755
--- a/tests/qemu-iotests/083
+++ b/tests/qemu-iotests/083
@@ -27,14 +27,6 @@ echo "QA output created by $seq"
 here=`pwd`
 status=1	# failure is the default!
 
-_cleanup()
-{
-	rm -f nbd.sock
-	rm -f nbd-fault-injector.out
-	rm -f nbd-fault-injector.conf
-}
-trap "_cleanup; exit \$status" 0 1 2 3 15
-
 # get standard environment, filters and checks
 . ./common.rc
 . ./common.filter
diff --git a/tests/qemu-iotests/084 b/tests/qemu-iotests/084
index 04f2aa9..b0d42a0 100755
--- a/tests/qemu-iotests/084
+++ b/tests/qemu-iotests/084
@@ -28,12 +28,6 @@ echo "QA output created by $seq"
 here=`pwd`
 status=1	# failure is the default!
 
-_cleanup()
-{
-	_cleanup_test_img
-}
-trap "_cleanup; exit \$status" 0 1 2 3 15
-
 # get standard environment, filters and checks
 . ./common.rc
 . ./common.filter
diff --git a/tests/qemu-iotests/085 b/tests/qemu-iotests/085
index 5c7668c..7b69f86 100755
--- a/tests/qemu-iotests/085
+++ b/tests/qemu-iotests/085
@@ -37,18 +37,7 @@ snapshot_virt1="snapshot-v1.qcow2"
 
 SNAPSHOTS=10
 
-_cleanup()
-{
-    _cleanup_qemu
-    for i in $(seq 1 ${SNAPSHOTS})
-    do
-        rm -f "${TEST_DIR}/${i}-${snapshot_virt0}"
-        rm -f "${TEST_DIR}/${i}-${snapshot_virt1}"
-    done
-    rm -f "${TEST_IMG}" "${TEST_IMG}.1" "${TEST_IMG}.2" "${TEST_IMG}.base"
-
-}
-trap "_cleanup; exit \$status" 0 1 2 3 15
+trap "_cleanup_qemu; exit \$status" 0 1 2 3 15
 
 # get standard environment, filters and checks
 . ./common.rc
diff --git a/tests/qemu-iotests/086 b/tests/qemu-iotests/086
index cd4494a..4d5f7db 100755
--- a/tests/qemu-iotests/086
+++ b/tests/qemu-iotests/086
@@ -27,12 +27,6 @@ echo "QA output created by $seq"
 here=`pwd`
 status=1	# failure is the default!
 
-_cleanup()
-{
-	_cleanup_test_img
-}
-trap "_cleanup; exit \$status" 0 1 2 3 15
-
 # get standard environment, filters and checks
 . ./common.rc
 . ./common.filter
diff --git a/tests/qemu-iotests/088 b/tests/qemu-iotests/088
index b8076f2..72e7c68 100755
--- a/tests/qemu-iotests/088
+++ b/tests/qemu-iotests/088
@@ -27,13 +27,6 @@ echo "QA output created by $seq"
 here=`pwd`
 status=1	# failure is the default!
 
-_cleanup()
-{
-    rm -f $TEST_IMG.snap
-    _cleanup_test_img
-}
-trap "_cleanup; exit \$status" 0 1 2 3 15
-
 # get standard environment, filters and checks
 . ./common.rc
 . ./common.filter
diff --git a/tests/qemu-iotests/089 b/tests/qemu-iotests/089
index 9bfe230..75151f1 100755
--- a/tests/qemu-iotests/089
+++ b/tests/qemu-iotests/089
@@ -27,12 +27,6 @@ echo "QA output created by $seq"
 here="$PWD"
 status=1	# failure is the default!
 
-_cleanup()
-{
-	_cleanup_test_img
-}
-trap "_cleanup; exit \$status" 0 1 2 3 15
-
 # get standard environment, filters and checks
 . ./common.rc
 . ./common.filter
diff --git a/tests/qemu-iotests/090 b/tests/qemu-iotests/090
index 7380503..c3be13c 100755
--- a/tests/qemu-iotests/090
+++ b/tests/qemu-iotests/090
@@ -27,12 +27,6 @@ echo "QA output created by $seq"
 here="$PWD"
 status=1	# failure is the default!
 
-_cleanup()
-{
-	_cleanup_test_img
-}
-trap "_cleanup; exit \$status" 0 1 2 3 15
-
 # get standard environment, filters and checks
 . ./common.rc
 . ./common.filter
diff --git a/tests/qemu-iotests/091 b/tests/qemu-iotests/091
index 10ac4a8..c4df2fb 100755
--- a/tests/qemu-iotests/091
+++ b/tests/qemu-iotests/091
@@ -31,13 +31,7 @@ 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
+trap "_cleanup_qemu; exit \$status" 0 1 2 3 15
 
 # get standard environment, filters and checks
 . ./common.rc
diff --git a/tests/qemu-iotests/092 b/tests/qemu-iotests/092
index 5bbdd07..3b8cf8f 100755
--- a/tests/qemu-iotests/092
+++ b/tests/qemu-iotests/092
@@ -27,13 +27,6 @@ echo "QA output created by $seq"
 here=`pwd`
 status=1	# failure is the default!
 
-_cleanup()
-{
-    rm -f $TEST_IMG.snap
-    _cleanup_test_img
-}
-trap "_cleanup; exit \$status" 0 1 2 3 15
-
 # get standard environment, filters and checks
 . ./common.rc
 . ./common.filter
diff --git a/tests/qemu-iotests/094 b/tests/qemu-iotests/094
index 9aa01e3..35e882c 100755
--- a/tests/qemu-iotests/094
+++ b/tests/qemu-iotests/094
@@ -27,14 +27,7 @@ echo "QA output created by $seq"
 here="$PWD"
 status=1	# failure is the default!
 
-_cleanup()
-{
-    _cleanup_qemu
-    _cleanup_test_img
-    rm -f "$TEST_DIR/source.$IMGFMT"
-}
-
-trap "_cleanup; exit \$status" 0 1 2 3 15
+trap "_cleanup_qemu; exit \$status" 0 1 2 3 15
 
 # get standard environment, filters and checks
 . ./common.rc
diff --git a/tests/qemu-iotests/095 b/tests/qemu-iotests/095
index 030adb2..75d60c4 100755
--- a/tests/qemu-iotests/095
+++ b/tests/qemu-iotests/095
@@ -30,13 +30,7 @@ echo "QA output created by $seq"
 here=`pwd`
 status=1	# failure is the default!
 
-_cleanup()
-{
-    _cleanup_qemu
-    rm  -f "${TEST_IMG}.base" "${TEST_IMG}.snp1"
-	_cleanup_test_img
-}
-trap "_cleanup; exit \$status" 0 1 2 3 15
+trap "_cleanup_qemu; exit \$status" 0 1 2 3 15
 
 # get standard environment, filters and checks
 . ./common.rc
diff --git a/tests/qemu-iotests/097 b/tests/qemu-iotests/097
index e22670c..81e6729 100755
--- a/tests/qemu-iotests/097
+++ b/tests/qemu-iotests/097
@@ -28,13 +28,6 @@ echo "QA output created by $seq"
 here="$PWD"
 status=1	# failure is the default!
 
-_cleanup()
-{
-    _cleanup_test_img
-    _rm_test_img "$TEST_IMG.itmd"
-}
-trap "_cleanup; exit \$status" 0 1 2 3 15
-
 # get standard environment, filters and checks
 . ./common.rc
 . ./common.filter
diff --git a/tests/qemu-iotests/098 b/tests/qemu-iotests/098
index b002e96..24d8510 100755
--- a/tests/qemu-iotests/098
+++ b/tests/qemu-iotests/098
@@ -27,13 +27,6 @@ echo "QA output created by $seq"
 here="$PWD"
 status=1	# failure is the default!
 
-_cleanup()
-{
-    _cleanup_test_img
-    rm -f "$TEST_DIR/blkdebug.conf"
-}
-trap "_cleanup; exit \$status" 0 1 2 3 15
-
 # get standard environment, filters and checks
 . ./common.rc
 . ./common.filter
diff --git a/tests/qemu-iotests/099 b/tests/qemu-iotests/099
index caaf58e..d811b34 100755
--- a/tests/qemu-iotests/099
+++ b/tests/qemu-iotests/099
@@ -28,12 +28,6 @@ echo "QA output created by $seq"
 here="$PWD"
 status=1	# failure is the default!
 
-_cleanup()
-{
-	_cleanup_test_img
-}
-trap "_cleanup; exit \$status" 0 1 2 3 15
-
 # get standard environment, filters and checks
 . ./common.rc
 . ./common.filter
diff --git a/tests/qemu-iotests/101 b/tests/qemu-iotests/101
index ea53f8b..62faf99 100755
--- a/tests/qemu-iotests/101
+++ b/tests/qemu-iotests/101
@@ -27,12 +27,6 @@ echo "QA output created by $seq"
 here=`pwd`
 status=1	# failure is the default!
 
-_cleanup()
-{
-	_cleanup_test_img
-}
-trap "_cleanup; exit \$status" 0 1 2 3 15
-
 # get standard environment, filters and checks
 . ./common.rc
 . ./common.filter
diff --git a/tests/qemu-iotests/102 b/tests/qemu-iotests/102
index d7ad8d9..201c520 100755
--- a/tests/qemu-iotests/102
+++ b/tests/qemu-iotests/102
@@ -27,12 +27,7 @@ echo "QA output created by $seq"
 here=$PWD
 status=1    # failure is the default!
 
-_cleanup()
-{
-    _cleanup_qemu
-    _cleanup_test_img
-}
-trap "_cleanup; exit \$status" 0 1 2 3 15
+trap "_cleanup_qemu; exit \$status" 0 1 2 3 15
 
 # get standard environment, filters and qemu instance handling
 . ./common.rc
diff --git a/tests/qemu-iotests/103 b/tests/qemu-iotests/103
index ecbd8eb..df86d4f 100755
--- a/tests/qemu-iotests/103
+++ b/tests/qemu-iotests/103
@@ -27,12 +27,6 @@ echo "QA output created by $seq"
 here=$PWD
 status=1	# failure is the default!
 
-_cleanup()
-{
-	_cleanup_test_img
-}
-trap "_cleanup; exit \$status" 0 1 2 3 15
-
 # get standard environment, filters and checks
 . ./common.rc
 . ./common.filter
diff --git a/tests/qemu-iotests/104 b/tests/qemu-iotests/104
index 726d467..f10d311 100755
--- a/tests/qemu-iotests/104
+++ b/tests/qemu-iotests/104
@@ -27,8 +27,6 @@ echo "QA output created by $seq"
 here=`pwd`
 status=1	# failure is the default!
 
-trap "exit \$status" 0 1 2 3 15
-
 # get standard environment, filters and checks
 . ./common.rc
 . ./common.filter
diff --git a/tests/qemu-iotests/105 b/tests/qemu-iotests/105
index 3db4ce3..b469b1b 100755
--- a/tests/qemu-iotests/105
+++ b/tests/qemu-iotests/105
@@ -27,12 +27,6 @@ echo "QA output created by $seq"
 here=`pwd`
 status=1	# failure is the default!
 
-_cleanup()
-{
-	_cleanup_test_img
-}
-trap "_cleanup; exit \$status" 0 1 2 3 15
-
 # get standard environment, filters and checks
 . ./common.rc
 . ./common.filter
diff --git a/tests/qemu-iotests/106 b/tests/qemu-iotests/106
index bfe71f4..e4db5a1 100755
--- a/tests/qemu-iotests/106
+++ b/tests/qemu-iotests/106
@@ -27,12 +27,6 @@ echo "QA output created by $seq"
 here=$PWD
 status=1	# failure is the default!
 
-_cleanup()
-{
-	_cleanup_test_img
-}
-trap "_cleanup; exit \$status" 0 1 2 3 15
-
 # get standard environment and filters
 . ./common.rc
 . ./common.filter
diff --git a/tests/qemu-iotests/107 b/tests/qemu-iotests/107
index d7222dc..d513120 100755
--- a/tests/qemu-iotests/107
+++ b/tests/qemu-iotests/107
@@ -27,12 +27,6 @@ echo "QA output created by $seq"
 here="$PWD"
 status=1	# failure is the default!
 
-_cleanup()
-{
-	_cleanup_test_img
-}
-trap "_cleanup; exit \$status" 0 1 2 3 15
-
 # get standard environment, filters and checks
 . ./common.rc
 . ./common.filter
diff --git a/tests/qemu-iotests/108 b/tests/qemu-iotests/108
index 2355d98..8371db4 100755
--- a/tests/qemu-iotests/108
+++ b/tests/qemu-iotests/108
@@ -28,12 +28,6 @@ echo "QA output created by $seq"
 here="$PWD"
 status=1	# failure is the default!
 
-_cleanup()
-{
-	_cleanup_test_img
-}
-trap "_cleanup; exit \$status" 0 1 2 3 15
-
 # get standard environment, filters and checks
 . ./common.rc
 . ./common.filter
diff --git a/tests/qemu-iotests/109 b/tests/qemu-iotests/109
index d70b574..d4fca99 100755
--- a/tests/qemu-iotests/109
+++ b/tests/qemu-iotests/109
@@ -27,13 +27,7 @@ echo "QA output created by $seq"
 here="$PWD"
 status=1	# failure is the default!
 
-_cleanup()
-{
-    _cleanup_qemu
-    rm -f $TEST_IMG.src
-	_cleanup_test_img
-}
-trap "_cleanup; exit \$status" 0 1 2 3 15
+trap "_cleanup_qemu; exit \$status" 0 1 2 3 15
 
 # get standard environment, filters and checks
 . ./common.rc
diff --git a/tests/qemu-iotests/110 b/tests/qemu-iotests/110
index 9de7369..93dd09f 100755
--- a/tests/qemu-iotests/110
+++ b/tests/qemu-iotests/110
@@ -27,12 +27,6 @@ echo "QA output created by $seq"
 here="$PWD"
 status=1	# failure is the default!
 
-_cleanup()
-{
-	_cleanup_test_img
-}
-trap "_cleanup; exit \$status" 0 1 2 3 15
-
 # get standard environment, filters and checks
 . ./common.rc
 . ./common.filter
diff --git a/tests/qemu-iotests/111 b/tests/qemu-iotests/111
index a1c152d..f590d82 100755
--- a/tests/qemu-iotests/111
+++ b/tests/qemu-iotests/111
@@ -28,12 +28,6 @@ echo "QA output created by $seq"
 here="$PWD"
 status=1	# failure is the default!
 
-_cleanup()
-{
-	_cleanup_test_img
-}
-trap "_cleanup; exit \$status" 0 1 2 3 15
-
 # get standard environment, filters and checks
 . ./common.rc
 . ./common.filter
diff --git a/tests/qemu-iotests/112 b/tests/qemu-iotests/112
index 28eb9aa..ee3679e 100755
--- a/tests/qemu-iotests/112
+++ b/tests/qemu-iotests/112
@@ -27,12 +27,6 @@ echo "QA output created by $seq"
 here="$PWD"
 status=1	# failure is the default!
 
-_cleanup()
-{
-	_cleanup_test_img
-}
-trap "_cleanup; exit \$status" 0 1 2 3 15
-
 # get standard environment, filters and checks
 . ./common.rc
 . ./common.filter
diff --git a/tests/qemu-iotests/113 b/tests/qemu-iotests/113
index 19b68b2..07437ea 100755
--- a/tests/qemu-iotests/113
+++ b/tests/qemu-iotests/113
@@ -28,12 +28,6 @@ echo "QA output created by $seq"
 here="$PWD"
 status=1	# failure is the default!
 
-_cleanup()
-{
-	_cleanup_test_img
-}
-trap "_cleanup; exit \$status" 0 1 2 3 15
-
 # get standard environment, filters and checks
 . ./common.rc
 . ./common.filter
diff --git a/tests/qemu-iotests/114 b/tests/qemu-iotests/114
index 5b7dc54..5bfd473 100755
--- a/tests/qemu-iotests/114
+++ b/tests/qemu-iotests/114
@@ -27,12 +27,6 @@ echo "QA output created by $seq"
 here="$PWD"
 status=1	# failure is the default!
 
-_cleanup()
-{
-	_cleanup_test_img
-}
-trap "_cleanup; exit \$status" 0 1 2 3 15
-
 # get standard environment, filters and checks
 . ./common.rc
 . ./common.filter
diff --git a/tests/qemu-iotests/115 b/tests/qemu-iotests/115
index 665c2ea..0c9aaad 100755
--- a/tests/qemu-iotests/115
+++ b/tests/qemu-iotests/115
@@ -27,12 +27,6 @@ echo "QA output created by $seq"
 here="$PWD"
 status=1	# failure is the default!
 
-_cleanup()
-{
-	_cleanup_test_img
-}
-trap "_cleanup; exit \$status" 0 1 2 3 15
-
 # get standard environment, filters and checks
 . ./common.rc
 . ./common.filter
diff --git a/tests/qemu-iotests/116 b/tests/qemu-iotests/116
index df0172f..e687601 100755
--- a/tests/qemu-iotests/116
+++ b/tests/qemu-iotests/116
@@ -30,12 +30,6 @@ echo "QA output created by $seq"
 here=`pwd`
 status=1	# failure is the default!
 
-_cleanup()
-{
-	_cleanup_test_img
-}
-trap "_cleanup; exit \$status" 0 1 2 3 15
-
 # get standard environment, filters and checks
 . ./common.rc
 . ./common.filter
diff --git a/tests/qemu-iotests/117 b/tests/qemu-iotests/117
index 6c83461..579cecb 100755
--- a/tests/qemu-iotests/117
+++ b/tests/qemu-iotests/117
@@ -27,12 +27,7 @@ echo "QA output created by $seq"
 here="$PWD"
 status=1	# failure is the default!
 
-_cleanup()
-{
-    _cleanup_qemu
-	_cleanup_test_img
-}
-trap "_cleanup; exit \$status" 0 1 2 3 15
+trap "_cleanup_qemu; exit \$status" 0 1 2 3 15
 
 # get standard environment, filters and checks
 . ./common.rc
diff --git a/tests/qemu-iotests/119 b/tests/qemu-iotests/119
index 4f34fb4..8cdb404 100755
--- a/tests/qemu-iotests/119
+++ b/tests/qemu-iotests/119
@@ -28,12 +28,6 @@ echo "QA output created by $seq"
 here="$PWD"
 status=1	# failure is the default!
 
-_cleanup()
-{
-	_cleanup_test_img
-}
-trap "_cleanup; exit \$status" 0 1 2 3 15
-
 # get standard environment, filters and checks
 . ./common.rc
 . ./common.filter
diff --git a/tests/qemu-iotests/120 b/tests/qemu-iotests/120
index f40b97d..bb0e2dd 100755
--- a/tests/qemu-iotests/120
+++ b/tests/qemu-iotests/120
@@ -28,12 +28,6 @@ echo "QA output created by $seq"
 here="$PWD"
 status=1	# failure is the default!
 
-_cleanup()
-{
-	_cleanup_test_img
-}
-trap "_cleanup; exit \$status" 0 1 2 3 15
-
 # get standard environment, filters and checks
 . ./common.rc
 . ./common.filter
diff --git a/tests/qemu-iotests/121 b/tests/qemu-iotests/121
index 1307b4e..d75fce1 100755
--- a/tests/qemu-iotests/121
+++ b/tests/qemu-iotests/121
@@ -27,12 +27,6 @@ echo "QA output created by $seq"
 here="$PWD"
 status=1	# failure is the default!
 
-_cleanup()
-{
-	_cleanup_test_img
-}
-trap "_cleanup; exit \$status" 0 1 2 3 15
-
 # get standard environment, filters and checks
 . ./common.rc
 . ./common.filter
diff --git a/tests/qemu-iotests/122 b/tests/qemu-iotests/122
index 45b359c..3942604 100755
--- a/tests/qemu-iotests/122
+++ b/tests/qemu-iotests/122
@@ -27,13 +27,6 @@ echo "QA output created by $seq"
 here="$PWD"
 status=1	# failure is the default!
 
-_cleanup()
-{
-    rm -f "$TEST_IMG".[123]
-	_cleanup_test_img
-}
-trap "_cleanup; exit \$status" 0 1 2 3 15
-
 # get standard environment, filters and checks
 . ./common.rc
 . ./common.filter
diff --git a/tests/qemu-iotests/123 b/tests/qemu-iotests/123
index b18e3fc..98fd3ce 100755
--- a/tests/qemu-iotests/123
+++ b/tests/qemu-iotests/123
@@ -27,13 +27,6 @@ echo "QA output created by $seq"
 here="$PWD"
 status=1	# failure is the default!
 
-_cleanup()
-{
-    _cleanup_test_img
-    rm -f "$SRC_IMG"
-}
-trap "_cleanup; exit \$status" 0 1 2 3 15
-
 # get standard environment, filters and checks
 . ./common.rc
 . ./common.filter
diff --git a/tests/qemu-iotests/125 b/tests/qemu-iotests/125
index 9424313..bca5fb5 100755
--- a/tests/qemu-iotests/125
+++ b/tests/qemu-iotests/125
@@ -27,12 +27,6 @@ echo "QA output created by $seq"
 here=$PWD
 status=1	# failure is the default!
 
-_cleanup()
-{
-	_cleanup_test_img
-}
-trap "_cleanup; exit \$status" 0 1 2 3 15
-
 get_image_size_on_host()
 {
     $QEMU_IMG info -f "$IMGFMT" "$TEST_IMG" | grep "disk size" \
diff --git a/tests/qemu-iotests/130 b/tests/qemu-iotests/130
index e7e43de..4aad4ea 100755
--- a/tests/qemu-iotests/130
+++ b/tests/qemu-iotests/130
@@ -29,12 +29,7 @@ echo "QA output created by $seq"
 here="$PWD"
 status=1	# failure is the default!
 
-_cleanup()
-{
-    _cleanup_qemu
-    _cleanup_test_img
-}
-trap "_cleanup; exit \$status" 0 1 2 3 15
+trap "_cleanup_qemu; exit \$status" 0 1 2 3 15
 
 # get standard environment, filters and checks
 . ./common.rc
diff --git a/tests/qemu-iotests/131 b/tests/qemu-iotests/131
index 94a9ae7..52588ef 100755
--- a/tests/qemu-iotests/131
+++ b/tests/qemu-iotests/131
@@ -27,12 +27,6 @@ echo "QA output created by $seq"
 here=`pwd`
 status=1	# failure is the default!
 
-_cleanup()
-{
-    _cleanup_test_img
-}
-trap "_cleanup; exit \$status" 0 1 2 3 15
-
 # get standard environment, filters and checks
 . ./common.rc
 . ./common.filter
diff --git a/tests/qemu-iotests/133 b/tests/qemu-iotests/133
index 9d35a6a..2d0aae9 100755
--- a/tests/qemu-iotests/133
+++ b/tests/qemu-iotests/133
@@ -27,12 +27,6 @@ echo "QA output created by $seq"
 here=`pwd`
 status=1	# failure is the default!
 
-_cleanup()
-{
-    _cleanup_test_img
-}
-trap "_cleanup; exit \$status" 0 1 2 3 15
-
 # get standard environment, filters and checks
 . ./common.rc
 . ./common.filter
diff --git a/tests/qemu-iotests/134 b/tests/qemu-iotests/134
index 9914415..147ea2c 100755
--- a/tests/qemu-iotests/134
+++ b/tests/qemu-iotests/134
@@ -27,12 +27,6 @@ echo "QA output created by $seq"
 here=`pwd`
 status=1	# failure is the default!
 
-_cleanup()
-{
-	_cleanup_test_img
-}
-trap "_cleanup; exit \$status" 0 1 2 3 15
-
 # get standard environment, filters and checks
 . ./common.rc
 . ./common.filter
diff --git a/tests/qemu-iotests/135 b/tests/qemu-iotests/135
index ce60831..75c160d 100755
--- a/tests/qemu-iotests/135
+++ b/tests/qemu-iotests/135
@@ -27,12 +27,6 @@ echo "QA output created by $seq"
 here=`pwd`
 status=1	# failure is the default!
 
-_cleanup()
-{
-    _cleanup_test_img
-}
-trap "_cleanup; exit \$status" 0 1 2 3 15
-
 # get standard environment, filters and checks
 . ./common.rc
 . ./common.filter
diff --git a/tests/qemu-iotests/137 b/tests/qemu-iotests/137
index eb91e51..6068a13 100755
--- a/tests/qemu-iotests/137
+++ b/tests/qemu-iotests/137
@@ -27,12 +27,6 @@ echo "QA output created by $seq"
 here="$PWD"
 status=1	# failure is the default!
 
-_cleanup()
-{
-    _cleanup_test_img
-}
-trap "_cleanup; exit \$status" 0 1 2 3 15
-
 # get standard environment, filters and checks
 . ./common.rc
 . ./common.filter
diff --git a/tests/qemu-iotests/138 b/tests/qemu-iotests/138
index 21650d8..9682560 100755
--- a/tests/qemu-iotests/138
+++ b/tests/qemu-iotests/138
@@ -27,12 +27,6 @@ echo "QA output created by $seq"
 here="$PWD"
 status=1	# failure is the default!
 
-_cleanup()
-{
-	_cleanup_test_img
-}
-trap "_cleanup; exit \$status" 0 1 2 3 15
-
 # get standard environment, filters and checks
 . ./common.rc
 . ./common.filter
diff --git a/tests/qemu-iotests/140 b/tests/qemu-iotests/140
index f89d0d6..c5e1a5b 100755
--- a/tests/qemu-iotests/140
+++ b/tests/qemu-iotests/140
@@ -31,13 +31,7 @@ echo "QA output created by $seq"
 here="$PWD"
 status=1	# failure is the default!
 
-_cleanup()
-{
-    _cleanup_qemu
-    _cleanup_test_img
-    rm -f "$TEST_DIR/nbd"
-}
-trap "_cleanup; exit \$status" 0 1 2 3 15
+trap "_cleanup_qemu; exit \$status" 0 1 2 3 15
 
 # get standard environment, filters and checks
 . ./common.rc
diff --git a/tests/qemu-iotests/141 b/tests/qemu-iotests/141
index 2f9d7b9..cff2319 100755
--- a/tests/qemu-iotests/141
+++ b/tests/qemu-iotests/141
@@ -27,13 +27,7 @@ echo "QA output created by $seq"
 here="$PWD"
 status=1	# failure is the default!
 
-_cleanup()
-{
-    _cleanup_qemu
-    _cleanup_test_img
-    rm -f "$TEST_DIR"/{b,m,o}.$IMGFMT
-}
-trap "_cleanup; exit \$status" 0 1 2 3 15
+trap "_cleanup_qemu; exit \$status" 0 1 2 3 15
 
 # get standard environment, filters and checks
 . ./common.rc
diff --git a/tests/qemu-iotests/142 b/tests/qemu-iotests/142
index 1639c83..65775be 100755
--- a/tests/qemu-iotests/142
+++ b/tests/qemu-iotests/142
@@ -27,13 +27,6 @@ echo "QA output created by $seq"
 here=`pwd`
 status=1	# failure is the default!
 
-_cleanup()
-{
-    _cleanup_test_img
-    rm -f $TEST_IMG.snap
-}
-trap "_cleanup; exit \$status" 0 1 2 3 15
-
 # get standard environment, filters and checks
 . ./common.rc
 . ./common.filter
diff --git a/tests/qemu-iotests/143 b/tests/qemu-iotests/143
index 5ff1944..b4736aa 100755
--- a/tests/qemu-iotests/143
+++ b/tests/qemu-iotests/143
@@ -27,12 +27,7 @@ echo "QA output created by $seq"
 here="$PWD"
 status=1	# failure is the default!
 
-_cleanup()
-{
-    _cleanup_qemu
-    rm -f "$TEST_DIR/nbd"
-}
-trap "_cleanup; exit \$status" 0 1 2 3 15
+trap "_cleanup_qemu; exit \$status" 0 1 2 3 15
 
 # get standard environment, filters and checks
 . ./common.rc
diff --git a/tests/qemu-iotests/144 b/tests/qemu-iotests/144
index 00de3c3..b47c561 100755
--- a/tests/qemu-iotests/144
+++ b/tests/qemu-iotests/144
@@ -32,13 +32,7 @@ status=1	# failure is the default!
 TMP_SNAP1=${TEST_DIR}/tmp.qcow2
 TMP_SNAP2=${TEST_DIR}/tmp2.qcow2
 
-_cleanup()
-{
-    _cleanup_qemu
-    rm -f "${TEST_IMG}" "${TMP_SNAP1}" "${TMP_SNAP2}"
-}
-
-trap "_cleanup; exit \$status" 0 1 2 3 15
+trap "_cleanup_qemu; exit \$status" 0 1 2 3 15
 
 # get standard environment, filters and checks
 . ./common.rc
diff --git a/tests/qemu-iotests/145 b/tests/qemu-iotests/145
index c371b3c..930628e 100755
--- a/tests/qemu-iotests/145
+++ b/tests/qemu-iotests/145
@@ -27,13 +27,6 @@ echo "QA output created by $seq"
 here=`pwd`
 status=1	# failure is the default!
 
-_cleanup()
-{
-	_cleanup_test_img
-	true
-}
-trap "_cleanup; exit \$status" 0 1 2 3 15
-
 # get standard environment, filters and checks
 . ./common.rc
 . ./common.filter
diff --git a/tests/qemu-iotests/146 b/tests/qemu-iotests/146
index 043711b..99b1e81 100755
--- a/tests/qemu-iotests/146
+++ b/tests/qemu-iotests/146
@@ -27,12 +27,7 @@ echo "QA output created by $seq"
 here=`pwd`
 status=1    # failure is the default!
 
-_cleanup()
-{
-    _cleanup_qemu
-    _cleanup_test_img
-}
-trap "_cleanup; exit \$status" 0 1 2 3 15
+trap "_cleanup_qemu; exit \$status" 0 1 2 3 15
 
 # get standard environment, filters and checks
 . ./common.rc
diff --git a/tests/qemu-iotests/150 b/tests/qemu-iotests/150
index ee8f637..120920e 100755
--- a/tests/qemu-iotests/150
+++ b/tests/qemu-iotests/150
@@ -27,12 +27,6 @@ echo "QA output created by $seq"
 here="$PWD"
 status=1	# failure is the default!
 
-_cleanup()
-{
-    _cleanup_test_img
-}
-trap "_cleanup; exit \$status" 0 1 2 3 15
-
 # get standard environment, filters and checks
 . ./common.rc
 . ./common.filter
diff --git a/tests/qemu-iotests/153 b/tests/qemu-iotests/153
index fa25eb2..42882eb 100755
--- a/tests/qemu-iotests/153
+++ b/tests/qemu-iotests/153
@@ -28,18 +28,6 @@ here="$PWD"
 tmp=/tmp/$$
 status=1	# failure is the default!
 
-_cleanup()
-{
-    _cleanup_test_img
-    rm -f "${TEST_IMG}.base"
-    rm -f "${TEST_IMG}.convert"
-    rm -f "${TEST_IMG}.a"
-    rm -f "${TEST_IMG}.b"
-    rm -f "${TEST_IMG}.c"
-    rm -f "${TEST_IMG}.lnk"
-}
-trap "_cleanup; exit \$status" 0 1 2 3 15
-
 # get standard environment, filters and checks
 . ./common.rc
 . ./common.filter
diff --git a/tests/qemu-iotests/154 b/tests/qemu-iotests/154
index fde03b0..90e7e65 100755
--- a/tests/qemu-iotests/154
+++ b/tests/qemu-iotests/154
@@ -27,12 +27,6 @@ echo "QA output created by $seq"
 here=`pwd`
 status=1	# failure is the default!
 
-_cleanup()
-{
-	_cleanup_test_img
-}
-trap "_cleanup; exit \$status" 0 1 2 3 15
-
 # get standard environment, filters and checks
 . ./common.rc
 . ./common.filter
diff --git a/tests/qemu-iotests/156 b/tests/qemu-iotests/156
index e75dc4d..9dbc6d7 100755
--- a/tests/qemu-iotests/156
+++ b/tests/qemu-iotests/156
@@ -35,12 +35,7 @@ echo "QA output created by $seq"
 here="$PWD"
 status=1	# failure is the default!
 
-_cleanup()
-{
-    _cleanup_qemu
-    rm -f "$TEST_IMG"{,.target}{,.backing,.overlay}
-}
-trap "_cleanup; exit \$status" 0 1 2 3 15
+trap "_cleanup_qemu; exit \$status" 0 1 2 3 15
 
 # get standard environment, filters and checks
 . ./common.rc
diff --git a/tests/qemu-iotests/157 b/tests/qemu-iotests/157
index 2bf02be..bda53c8 100755
--- a/tests/qemu-iotests/157
+++ b/tests/qemu-iotests/157
@@ -27,12 +27,6 @@ echo "QA output created by $seq"
 here="$PWD"
 status=1	# failure is the default!
 
-_cleanup()
-{
-	_cleanup_test_img
-}
-trap "_cleanup; exit \$status" 0 1 2 3 15
-
 # get standard environment, filters and checks
 . ./common.rc
 . ./common.filter
diff --git a/tests/qemu-iotests/158 b/tests/qemu-iotests/158
index 24ac600..a07708e 100755
--- a/tests/qemu-iotests/158
+++ b/tests/qemu-iotests/158
@@ -27,12 +27,6 @@ echo "QA output created by $seq"
 here=`pwd`
 status=1	# failure is the default!
 
-_cleanup()
-{
-	_cleanup_test_img
-}
-trap "_cleanup; exit \$status" 0 1 2 3 15
-
 # get standard environment, filters and checks
 . ./common.rc
 . ./common.filter
diff --git a/tests/qemu-iotests/159 b/tests/qemu-iotests/159
index 9b0e1ec..7fcccde 100755
--- a/tests/qemu-iotests/159
+++ b/tests/qemu-iotests/159
@@ -26,13 +26,6 @@ echo "QA output created by $seq"
 here="$PWD"
 status=1
 
-_cleanup()
-{
-    _cleanup_test_img
-    rm -f "$TEST_IMG.out"
-}
-trap "_cleanup; exit \$status" 0 1 2 3 15
-
 . ./common.rc
 . ./common.filter
 . ./common.pattern
diff --git a/tests/qemu-iotests/160 b/tests/qemu-iotests/160
index 5c910e5..48dd25d 100755
--- a/tests/qemu-iotests/160
+++ b/tests/qemu-iotests/160
@@ -26,13 +26,6 @@ echo "QA output created by $seq"
 here="$PWD"
 status=1
 
-_cleanup()
-{
-    _cleanup_test_img
-    rm -f "$TEST_IMG.out" "$TEST_IMG.out.dd"
-}
-trap "_cleanup; exit \$status" 0 1 2 3 15
-
 . ./common.rc
 . ./common.filter
 . ./common.pattern
diff --git a/tests/qemu-iotests/162 b/tests/qemu-iotests/162
index 477a806..cad2bd7 100755
--- a/tests/qemu-iotests/162
+++ b/tests/qemu-iotests/162
@@ -28,13 +28,6 @@ echo "QA output created by $seq"
 here="$PWD"
 status=1	# failure is the default!
 
-_cleanup()
-{
-    rm -f "${TEST_DIR}/qemu-nbd.pid"
-    rm -f 42
-}
-trap "_cleanup; exit \$status" 0 1 2 3 15
-
 # get standard environment, filters and checks
 . ./common.rc
 . ./common.filter
diff --git a/tests/qemu-iotests/170 b/tests/qemu-iotests/170
index b79359f..5288a2d 100755
--- a/tests/qemu-iotests/170
+++ b/tests/qemu-iotests/170
@@ -26,13 +26,6 @@ echo "QA output created by $seq"
 here="$PWD"
 status=1
 
-_cleanup()
-{
-    _cleanup_test_img
-    rm -f "$TEST_IMG.out"
-}
-trap "_cleanup; exit \$status" 0 1 2 3 15
-
 . ./common.rc
 . ./common.filter
 . ./common.pattern
diff --git a/tests/qemu-iotests/171 b/tests/qemu-iotests/171
index bcfaaf1..2798d2f 100755
--- a/tests/qemu-iotests/171
+++ b/tests/qemu-iotests/171
@@ -28,12 +28,6 @@ echo "QA output created by $seq"
 here=`pwd`
 status=1	# failure is the default!
 
-_cleanup()
-{
-    _cleanup_test_img
-}
-trap "_cleanup; exit \$status" 0 1 2 3 15
-
 # get standard environment, filters and checks
 . ./common.rc
 . ./common.filter
diff --git a/tests/qemu-iotests/172 b/tests/qemu-iotests/172
index 02c5f79..d9efd4b 100755
--- a/tests/qemu-iotests/172
+++ b/tests/qemu-iotests/172
@@ -27,14 +27,6 @@ echo "QA output created by $seq"
 here=`pwd`
 status=1	# failure is the default!
 
-_cleanup()
-{
-	_cleanup_test_img
-    rm -f "$TEST_IMG.2"
-    rm -f "$TEST_IMG.3"
-}
-trap "_cleanup; exit \$status" 0 1 2 3 15
-
 # get standard environment, filters and checks
 . ./common.rc
 . ./common.filter
diff --git a/tests/qemu-iotests/173 b/tests/qemu-iotests/173
index bdaa092..0c2fde4 100755
--- a/tests/qemu-iotests/173
+++ b/tests/qemu-iotests/173
@@ -27,13 +27,7 @@ echo "QA output created by $seq"
 here=`pwd`
 status=1    # failure is the default!
 
-_cleanup()
-{
-    _cleanup_qemu
-    rm  -f "${QEMU_TEST_DIR}/image.base" "${QEMU_TEST_DIR}/image.snp1"
-    _cleanup_test_img
-}
-trap "_cleanup; exit \$status" 0 1 2 3 15
+trap "_cleanup_qemu; exit \$status" 0 1 2 3 15
 
 # get standard environment, filters and checks
 . ./common.rc
diff --git a/tests/qemu-iotests/174 b/tests/qemu-iotests/174
index 552879d..67cd785 100755
--- a/tests/qemu-iotests/174
+++ b/tests/qemu-iotests/174
@@ -27,12 +27,6 @@ echo "QA output created by $seq"
 here=`pwd`
 status=1	# failure is the default!
 
-_cleanup()
-{
-	_cleanup_test_img
-}
-trap "_cleanup; exit \$status" 0 1 2 3 15
-
 # get standard environment, filters and checks
 . ./common.rc
 . ./common.filter
diff --git a/tests/qemu-iotests/175 b/tests/qemu-iotests/175
index ca56e82..1407597 100755
--- a/tests/qemu-iotests/175
+++ b/tests/qemu-iotests/175
@@ -27,12 +27,6 @@ echo "QA output created by $seq"
 here=`pwd`
 status=1	# failure is the default!
 
-_cleanup()
-{
-	_cleanup_test_img
-}
-trap "_cleanup; exit \$status" 0 1 2 3 15
-
 # get standard environment, filters and checks
 . ./common.rc
 . ./common.filter
diff --git a/tests/qemu-iotests/176 b/tests/qemu-iotests/176
index 950b287..56cd490 100755
--- a/tests/qemu-iotests/176
+++ b/tests/qemu-iotests/176
@@ -31,13 +31,6 @@ echo "QA output created by $seq"
 here="$PWD"
 status=1	# failure is the default!
 
-_cleanup()
-{
-    _cleanup_test_img
-    _rm_test_img "$TEST_IMG.itmd"
-}
-trap "_cleanup; exit \$status" 0 1 2 3 15
-
 # get standard environment, filters and checks
 . ./common.rc
 . ./common.filter
diff --git a/tests/qemu-iotests/177 b/tests/qemu-iotests/177
index f8ed8fb..ed2e8b2 100755
--- a/tests/qemu-iotests/177
+++ b/tests/qemu-iotests/177
@@ -27,12 +27,6 @@ echo "QA output created by $seq"
 here=`pwd`
 status=1	# failure is the default!
 
-_cleanup()
-{
-	_cleanup_test_img
-}
-trap "_cleanup; exit \$status" 0 1 2 3 15
-
 # get standard environment, filters and checks
 . ./common.rc
 . ./common.filter
diff --git a/tests/qemu-iotests/178 b/tests/qemu-iotests/178
index 6af52c6..fd583d1 100755
--- a/tests/qemu-iotests/178
+++ b/tests/qemu-iotests/178
@@ -27,13 +27,6 @@ echo "QA output created by $seq"
 here=`pwd`
 status=1    # failure is the default!
 
-_cleanup()
-{
-    _cleanup_test_img
-    rm -f "$TEST_IMG.converted"
-}
-trap "_cleanup; exit \$status" 0 1 2 3 15
-
 # get standard environment, filters and checks
 . ./common.rc
 . ./common.filter
diff --git a/tests/qemu-iotests/179 b/tests/qemu-iotests/179
index 115944a..f7cf129 100755
--- a/tests/qemu-iotests/179
+++ b/tests/qemu-iotests/179
@@ -27,13 +27,6 @@ echo "QA output created by $seq"
 here="$PWD"
 status=1	# failure is the default!
 
-_cleanup()
-{
-	_cleanup_test_img
-    rm -f "$TEST_DIR/blkdebug.conf"
-}
-trap "_cleanup; exit \$status" 0 1 2 3 15
-
 # get standard environment, filters and checks
 . ./common.rc
 . ./common.filter
diff --git a/tests/qemu-iotests/181 b/tests/qemu-iotests/181
index 0c91e8f..18fb133 100755
--- a/tests/qemu-iotests/181
+++ b/tests/qemu-iotests/181
@@ -29,13 +29,7 @@ status=1	# failure is the default!
 
 MIG_SOCKET="${TEST_DIR}/migrate"
 
-_cleanup()
-{
-    rm -f "${MIG_SOCKET}"
-	_cleanup_test_img
-    _cleanup_qemu
-}
-trap "_cleanup; exit \$status" 0 1 2 3 15
+trap "_cleanup_qemu; exit \$status" 0 1 2 3 15
 
 # get standard environment, filters and checks
 . ./common.rc
diff --git a/tests/qemu-iotests/182 b/tests/qemu-iotests/182
index 2e078ce..a842f9f 100755
--- a/tests/qemu-iotests/182
+++ b/tests/qemu-iotests/182
@@ -28,12 +28,6 @@ here="$PWD"
 tmp=/tmp/$$
 status=1	# failure is the default!
 
-_cleanup()
-{
-    _cleanup_test_img
-}
-trap "_cleanup; exit \$status" 0 1 2 3 15
-
 # get standard environment, filters and checks
 . ./common.rc
 . ./common.filter
diff --git a/tests/qemu-iotests/183 b/tests/qemu-iotests/183
index 20268ff..2e09679 100755
--- a/tests/qemu-iotests/183
+++ b/tests/qemu-iotests/183
@@ -29,14 +29,7 @@ status=1 # failure is the default!
 
 MIG_SOCKET="${TEST_DIR}/migrate"
 
-_cleanup()
-{
-    rm -f "${MIG_SOCKET}"
-    rm -f "${TEST_IMG}.dest"
-    _cleanup_test_img
-    _cleanup_qemu
-}
-trap "_cleanup; exit \$status" 0 1 2 3 15
+trap "_cleanup_qemu; exit \$status" 0 1 2 3 15
 
 # get standard environment, filters and checks
 . ./common.rc
diff --git a/tests/qemu-iotests/184 b/tests/qemu-iotests/184
index 704f38f..2130e64 100755
--- a/tests/qemu-iotests/184
+++ b/tests/qemu-iotests/184
@@ -27,12 +27,6 @@ echo "QA output created by $seq"
 here=`pwd`
 status=1	# failure is the default!
 
-_cleanup()
-{
-    _cleanup_test_img
-}
-trap "_cleanup; exit \$status" 0 1 2 3 15
-
 # get standard environment, filters and checks
 . ./common.rc
 . ./common.filter
diff --git a/tests/qemu-iotests/185 b/tests/qemu-iotests/185
index f5b47e4..7269d5e 100755
--- a/tests/qemu-iotests/185
+++ b/tests/qemu-iotests/185
@@ -29,14 +29,7 @@ status=1 # failure is the default!
 
 MIG_SOCKET="${TEST_DIR}/migrate"
 
-_cleanup()
-{
-    rm -f "${TEST_IMG}.mid"
-    rm -f "${TEST_IMG}.copy"
-    _cleanup_test_img
-    _cleanup_qemu
-}
-trap "_cleanup; exit \$status" 0 1 2 3 15
+trap "_cleanup_qemu; exit \$status" 0 1 2 3 15
 
 # get standard environment, filters and checks
 . ./common.rc
diff --git a/tests/qemu-iotests/186 b/tests/qemu-iotests/186
index 44cc01e..27d6530 100755
--- a/tests/qemu-iotests/186
+++ b/tests/qemu-iotests/186
@@ -27,12 +27,6 @@ echo "QA output created by $seq"
 here=`pwd`
 status=1	# failure is the default!
 
-_cleanup()
-{
-	_cleanup_test_img
-}
-trap "_cleanup; exit \$status" 0 1 2 3 15
-
 # get standard environment, filters and checks
 . ./common.rc
 . ./common.filter
diff --git a/tests/qemu-iotests/187 b/tests/qemu-iotests/187
index 7bb7833..8b29df3 100755
--- a/tests/qemu-iotests/187
+++ b/tests/qemu-iotests/187
@@ -27,14 +27,6 @@ echo "QA output created by $seq"
 here=`pwd`
 status=1	# failure is the default!
 
-_cleanup()
-{
-	_cleanup_test_img
-    rm -f "$TEST_IMG.2"
-    rm -f "$TEST_IMG.3"
-}
-trap "_cleanup; exit \$status" 0 1 2 3 15
-
 # get standard environment, filters and checks
 . ./common.rc
 . ./common.filter
diff --git a/tests/qemu-iotests/188 b/tests/qemu-iotests/188
index 83ed03e..48f855d 100755
--- a/tests/qemu-iotests/188
+++ b/tests/qemu-iotests/188
@@ -27,12 +27,6 @@ echo "QA output created by $seq"
 here=`pwd`
 status=1	# failure is the default!
 
-_cleanup()
-{
-	_cleanup_test_img
-}
-trap "_cleanup; exit \$status" 0 1 2 3 15
-
 # get standard environment, filters and checks
 . ./common.rc
 . ./common.filter
diff --git a/tests/qemu-iotests/189 b/tests/qemu-iotests/189
index e695475..c5d516d 100755
--- a/tests/qemu-iotests/189
+++ b/tests/qemu-iotests/189
@@ -27,12 +27,6 @@ echo "QA output created by $seq"
 here=`pwd`
 status=1	# failure is the default!
 
-_cleanup()
-{
-	_cleanup_test_img
-}
-trap "_cleanup; exit \$status" 0 1 2 3 15
-
 # get standard environment, filters and checks
 . ./common.rc
 . ./common.filter
diff --git a/tests/qemu-iotests/190 b/tests/qemu-iotests/190
index 8f808fe..84d20c6 100755
--- a/tests/qemu-iotests/190
+++ b/tests/qemu-iotests/190
@@ -27,13 +27,6 @@ echo "QA output created by $seq"
 here=`pwd`
 status=1    # failure is the default!
 
-_cleanup()
-{
-    _cleanup_test_img
-    rm -f "$TEST_IMG.converted"
-}
-trap "_cleanup; exit \$status" 0 1 2 3 15
-
 # get standard environment, filters and checks
 . ./common.rc
 . ./common.filter
diff --git a/tests/qemu-iotests/191 b/tests/qemu-iotests/191
index ac2b88f..f97e580 100755
--- a/tests/qemu-iotests/191
+++ b/tests/qemu-iotests/191
@@ -31,10 +31,6 @@ MIG_SOCKET="${TEST_DIR}/migrate"
 
 _cleanup()
 {
-    rm -f "${TEST_IMG}.mid"
-    rm -f "${TEST_IMG}.ovl2"
-    rm -f "${TEST_IMG}.ovl3"
-    _cleanup_test_img
     _cleanup_qemu
 }
 trap "_cleanup; exit \$status" 0 1 2 3 15
diff --git a/tests/qemu-iotests/192 b/tests/qemu-iotests/192
index 595f0d7..be24bfb 100755
--- a/tests/qemu-iotests/192
+++ b/tests/qemu-iotests/192
@@ -28,12 +28,6 @@ echo "QA output created by $seq"
 here=`pwd`
 status=1	# failure is the default!
 
-_cleanup()
-{
-	_cleanup_test_img
-}
-trap "_cleanup; exit \$status" 0 1 2 3 15
-
 # get standard environment, filters and checks
 . ./common.rc
 . ./common.filter
diff --git a/tests/qemu-iotests/195 b/tests/qemu-iotests/195
index e7a403d..b826152 100755
--- a/tests/qemu-iotests/195
+++ b/tests/qemu-iotests/195
@@ -27,13 +27,6 @@ echo "QA output created by $seq"
 here=`pwd`
 status=1 # failure is the default!
 
-_cleanup()
-{
-    _cleanup_test_img
-    rm -f "$TEST_IMG.mid"
-}
-trap "_cleanup; exit \$status" 0 1 2 3 15
-
 # get standard environment, filters and checks
 . ./common.rc
 . ./common.filter
diff --git a/tests/qemu-iotests/197 b/tests/qemu-iotests/197
index 887eb4f..df09870 100755
--- a/tests/qemu-iotests/197
+++ b/tests/qemu-iotests/197
@@ -41,13 +41,6 @@ case "$TEST_DIR" in
         _notrun "Suspicious TEST_DIR='$TEST_DIR', cowardly refusing to run" ;;
 esac
 
-_cleanup()
-{
-    _cleanup_test_img
-    rm -f "$BLKDBG_CONF"
-}
-trap "_cleanup; exit \$status" 0 1 2 3 15
-
 # Test is supported for any backing file; but we force qcow2 for our wrapper.
 _supported_fmt generic
 _supported_proto generic
-- 
2.9.5

^ permalink raw reply related	[flat|nested] 37+ messages in thread

* [Qemu-devel] [PATCH v5 05/10] qemu-iotests: change qemu pid and fd tracking / cleanup
  2017-10-17 16:31 [Qemu-devel] [PATCH v5 00/10] qemu-iotests improvements Jeff Cody
                   ` (3 preceding siblings ...)
  2017-10-17 16:31 ` [Qemu-devel] [PATCH v5 04/10] qemu-iotests: remove file cleanup from bash tests Jeff Cody
@ 2017-10-17 16:31 ` Jeff Cody
  2017-10-18 13:59   ` Jeff Cody
  2017-10-18 14:22   ` Eric Blake
  2017-10-17 16:31 ` [Qemu-devel] [PATCH v5 06/10] qemu-iotests: make ./check automatically reap QEMU processes Jeff Cody
                   ` (4 subsequent siblings)
  9 siblings, 2 replies; 37+ messages in thread
From: Jeff Cody @ 2017-10-17 16:31 UTC (permalink / raw)
  To: qemu-devel; +Cc: qemu-block, jsnow, stefanha, kwolf, eblake

So that later patches can cleanup running qemu processes called from
different subshells, track resources to cleanup in pid and fd list
files.

In subsquent patches, ./check will kill all QEMU processes launched with
the common.qemu framework, and the tests will not need to cleanup
manually (unless they want to do so as part of the test, e.g. wait for
a process to end such as migration).

Signed-off-by: Jeff Cody <jcody@redhat.com>
---
 tests/qemu-iotests/common.qemu | 82 ++++++++++++++++++++++++++++++++----------
 tests/qemu-iotests/common.rc   |  3 +-
 2 files changed, 64 insertions(+), 21 deletions(-)

diff --git a/tests/qemu-iotests/common.qemu b/tests/qemu-iotests/common.qemu
index 7b3052d..35a08a6 100644
--- a/tests/qemu-iotests/common.qemu
+++ b/tests/qemu-iotests/common.qemu
@@ -33,6 +33,10 @@ QEMU_FIFO_OUT="${QEMU_TEST_DIR}/qmp-out-$$"
 QEMU_HANDLE=0
 export _QEMU_HANDLE=0
 
+QEMU_PID_LIST="${QEMU_TEST_DIR}"/qemu-pid.lst
+QEMU_OUT_FD_LIST="${QEMU_TEST_DIR}"/qemu-out-fd.lst
+QEMU_IN_FD_LIST="${QEMU_TEST_DIR}"/qemu-in-fd.lst
+QEMU_FIFO_LIST="${QEMU_TEST_DIR}"/qemu-fifo.lst
 # If bash version is >= 4.1, these will be overwritten and dynamic
 # file descriptor values assigned.
 _out_fd=3
@@ -193,6 +197,10 @@ function _launch_qemu()
     QEMU_OUT[${_QEMU_HANDLE}]=${_out_fd}
     QEMU_IN[${_QEMU_HANDLE}]=${_in_fd}
     QEMU_STATUS[${_QEMU_HANDLE}]=0
+    echo ${_out_fd} >> "$QEMU_OUT_FD_LIST"
+    echo ${_in_fd} >> "$QEMU_IN_FD_LIST"
+    echo ${fifo_in} >> "$QEMU_FIFO_LIST"
+    echo ${fifo_out} >> "$QEMU_FIFO_LIST"
 
     if [ "${qemu_comm_method}" == "qmp" ]
     then
@@ -209,35 +217,71 @@ function _launch_qemu()
 
 # Silenty kills the QEMU process
 #
+# This is able to kill and clean up after QEMU processes without the
+# need for any subshell-specific variables, so long as the qemu-pidlist
+# and qemu-out-fd.list and qemu-in-fd.list files are properly maintained.
+#
 # If $wait is set to anything other than the empty string, the process will not
 # be killed but only waited for, and any output will be forwarded to stdout. If
 # $wait is empty, the process will be killed and all output will be suppressed.
 function _cleanup_qemu()
 {
-    # QEMU_PID[], QEMU_IN[], QEMU_OUT[] all use same indices
-    for i in "${!QEMU_OUT[@]}"
+    local fifo_path=
+    local testdir_path=
+
+    if [ ! -e "${QEMU_PID_LIST}" ]; then
+        return
+    fi
+
+    # get line count, and therefore number of processes to kill
+    numproc=$(wc -l "${QEMU_PID_LIST}" | sed 's/\s.*//')
+
+    for i in $(seq 1 $numproc)
     do
         local QEMU_PID
-        if [ -f "${QEMU_TEST_DIR}/qemu-${i}.pid" ]; then
-            read QEMU_PID < "${QEMU_TEST_DIR}/qemu-${i}.pid"
-            rm -f "${QEMU_TEST_DIR}/qemu-${i}.pid"
-            if [ -z "${wait}" ] && [ -n "${QEMU_PID}" ]; then
-                kill -KILL ${QEMU_PID} 2>/dev/null
-            fi
-            if [ -n "${QEMU_PID}" ]; then
-                wait ${QEMU_PID} 2>/dev/null # silent kill
-            fi
+        local OUT_FD
+        local IN_FD
+        j=$(expr $i - 1)
+
+        QEMU_PID=$(tail -n+${i} "${QEMU_PID_LIST}" | head -n1)
+        OUT_FD=$(tail -n+${i} "${QEMU_OUT_FD_LIST}" | head -n1)
+        IN_FD=$(tail -n+${i} "${QEMU_IN_FD_LIST}" | head -n1)
+
+        if [ -z "${wait}" ] && [ -n "${QEMU_PID}" ]; then
+            kill -KILL ${QEMU_PID} 2>/dev/null
+        fi
+        if [ -n "${QEMU_PID}" ]; then
+            wait ${QEMU_PID} 2>/dev/null # silent kill
         fi
 
-        if [ -n "${wait}" ]; then
-            cat <&${QEMU_OUT[$i]} | _filter_testdir | _filter_qemu \
-                                  | _filter_qemu_io | _filter_qmp | _filter_hmp
+        if [ -n "${wait}" ] && [ -n "${OUT_FD}" ]; then
+            cat <&${OUT_FD} | _filter_testdir | _filter_qemu \
+                            | _filter_qemu_io | _filter_qmp | _filter_hmp
+        fi
+
+        if [ -n "${IN_FD}" ]; then
+            eval "exec ${IN_FD}<&-"   # close file descriptors
+        fi
+        if [ -n "${OUT_FD}" ]; then
+            eval "exec ${OUT_FD}<&-"
         fi
-        rm -f "${QEMU_FIFO_IN}_${i}" "${QEMU_FIFO_OUT}_${i}"
-        eval "exec ${QEMU_IN[$i]}<&-"   # close file descriptors
-        eval "exec ${QEMU_OUT[$i]}<&-"
 
-        unset QEMU_IN[$i]
-        unset QEMU_OUT[$i]
+        unset QEMU_IN[$j]
+        unset QEMU_OUT[$j]
     done
+
+    # The FIFOs do not correspond to process entry in the pidlist, so
+    # just clean them up afterwards
+    while read fifo_name
+    do
+        # make sure entries are inside the $TEST_DIR
+        fifo_path=$(dirname -z $(realpath "$fifo_name"))
+        testdir_path=$(realpath "$QEMU_TEST_DIR")
+        if [ "$fifo_path" == "$testdir_path" ]
+        then
+            rm -f "$fifo_name"
+        fi
+    done < "${QEMU_FIFO_LIST}"
+
+    rm -f "${QEMU_PID_LIST}" "${QEMU_OUT_FD_LIST}" "${QEMU_IN_FD_LIST}" "$QEMU_FIFO_LIST}"
 }
diff --git a/tests/qemu-iotests/common.rc b/tests/qemu-iotests/common.rc
index a345ffd..b26b02f 100644
--- a/tests/qemu-iotests/common.rc
+++ b/tests/qemu-iotests/common.rc
@@ -40,7 +40,6 @@ poke_file()
     printf "$3" | dd "of=$1" bs=1 "seek=$2" conv=notrunc &>/dev/null
 }
 
-
 if ! . ./common.config
     then
     echo "$0: failed to source common.config"
@@ -51,7 +50,7 @@ _qemu_wrapper()
 {
     (
         if [ -n "${QEMU_NEED_PID}" ]; then
-            echo $BASHPID > "${QEMU_TEST_DIR}/qemu-${_QEMU_HANDLE}.pid"
+            echo $BASHPID >> "${QEMU_TEST_DIR}/qemu-pid.lst"
         fi
         exec "$QEMU_PROG" $QEMU_OPTIONS "$@"
     )
-- 
2.9.5

^ permalink raw reply related	[flat|nested] 37+ messages in thread

* [Qemu-devel] [PATCH v5 06/10] qemu-iotests: make ./check automatically reap QEMU processes
  2017-10-17 16:31 [Qemu-devel] [PATCH v5 00/10] qemu-iotests improvements Jeff Cody
                   ` (4 preceding siblings ...)
  2017-10-17 16:31 ` [Qemu-devel] [PATCH v5 05/10] qemu-iotests: change qemu pid and fd tracking / cleanup Jeff Cody
@ 2017-10-17 16:31 ` Jeff Cody
  2017-10-18 14:24   ` Eric Blake
  2017-10-17 16:31 ` [Qemu-devel] [PATCH v5 07/10] qemu-iotests: run python tests in own subdirectories Jeff Cody
                   ` (3 subsequent siblings)
  9 siblings, 1 reply; 37+ messages in thread
From: Jeff Cody @ 2017-10-17 16:31 UTC (permalink / raw)
  To: qemu-devel; +Cc: qemu-block, jsnow, stefanha, kwolf, eblake

Check will now take care of cleaning up all QEMU processes started
from bash tests using the common.qemu framework.

This also paves the way to added another check option to keep QEMU
processes around, in the case of a failed test.

Signed-off-by: Jeff Cody <jcody@redhat.com>
---
 tests/qemu-iotests/085   | 2 --
 tests/qemu-iotests/091   | 2 --
 tests/qemu-iotests/094   | 2 --
 tests/qemu-iotests/095   | 2 --
 tests/qemu-iotests/102   | 2 --
 tests/qemu-iotests/109   | 2 --
 tests/qemu-iotests/117   | 2 --
 tests/qemu-iotests/130   | 2 --
 tests/qemu-iotests/140   | 2 --
 tests/qemu-iotests/141   | 2 --
 tests/qemu-iotests/143   | 2 --
 tests/qemu-iotests/144   | 2 --
 tests/qemu-iotests/146   | 2 --
 tests/qemu-iotests/156   | 2 --
 tests/qemu-iotests/173   | 2 --
 tests/qemu-iotests/181   | 2 --
 tests/qemu-iotests/183   | 2 --
 tests/qemu-iotests/185   | 2 --
 tests/qemu-iotests/191   | 6 ------
 tests/qemu-iotests/check | 7 +++++--
 20 files changed, 5 insertions(+), 44 deletions(-)

diff --git a/tests/qemu-iotests/085 b/tests/qemu-iotests/085
index 7b69f86..283f9a9 100755
--- a/tests/qemu-iotests/085
+++ b/tests/qemu-iotests/085
@@ -37,8 +37,6 @@ snapshot_virt1="snapshot-v1.qcow2"
 
 SNAPSHOTS=10
 
-trap "_cleanup_qemu; exit \$status" 0 1 2 3 15
-
 # get standard environment, filters and checks
 . ./common.rc
 . ./common.filter
diff --git a/tests/qemu-iotests/091 b/tests/qemu-iotests/091
index c4df2fb..cc4c50c 100755
--- a/tests/qemu-iotests/091
+++ b/tests/qemu-iotests/091
@@ -31,8 +31,6 @@ status=1    # failure is the default!
 
 MIG_FIFO="${TEST_DIR}/migrate"
 
-trap "_cleanup_qemu; exit \$status" 0 1 2 3 15
-
 # get standard environment, filters and checks
 . ./common.rc
 . ./common.filter
diff --git a/tests/qemu-iotests/094 b/tests/qemu-iotests/094
index 35e882c..1587550 100755
--- a/tests/qemu-iotests/094
+++ b/tests/qemu-iotests/094
@@ -27,8 +27,6 @@ echo "QA output created by $seq"
 here="$PWD"
 status=1	# failure is the default!
 
-trap "_cleanup_qemu; exit \$status" 0 1 2 3 15
-
 # get standard environment, filters and checks
 . ./common.rc
 . ./common.filter
diff --git a/tests/qemu-iotests/095 b/tests/qemu-iotests/095
index 75d60c4..2891014 100755
--- a/tests/qemu-iotests/095
+++ b/tests/qemu-iotests/095
@@ -30,8 +30,6 @@ echo "QA output created by $seq"
 here=`pwd`
 status=1	# failure is the default!
 
-trap "_cleanup_qemu; exit \$status" 0 1 2 3 15
-
 # get standard environment, filters and checks
 . ./common.rc
 . ./common.filter
diff --git a/tests/qemu-iotests/102 b/tests/qemu-iotests/102
index 201c520..2980638 100755
--- a/tests/qemu-iotests/102
+++ b/tests/qemu-iotests/102
@@ -27,8 +27,6 @@ echo "QA output created by $seq"
 here=$PWD
 status=1    # failure is the default!
 
-trap "_cleanup_qemu; exit \$status" 0 1 2 3 15
-
 # get standard environment, filters and qemu instance handling
 . ./common.rc
 . ./common.filter
diff --git a/tests/qemu-iotests/109 b/tests/qemu-iotests/109
index d4fca99..2f6e456 100755
--- a/tests/qemu-iotests/109
+++ b/tests/qemu-iotests/109
@@ -27,8 +27,6 @@ echo "QA output created by $seq"
 here="$PWD"
 status=1	# failure is the default!
 
-trap "_cleanup_qemu; exit \$status" 0 1 2 3 15
-
 # get standard environment, filters and checks
 . ./common.rc
 . ./common.filter
diff --git a/tests/qemu-iotests/117 b/tests/qemu-iotests/117
index 579cecb..a427ee7 100755
--- a/tests/qemu-iotests/117
+++ b/tests/qemu-iotests/117
@@ -27,8 +27,6 @@ echo "QA output created by $seq"
 here="$PWD"
 status=1	# failure is the default!
 
-trap "_cleanup_qemu; exit \$status" 0 1 2 3 15
-
 # get standard environment, filters and checks
 . ./common.rc
 . ./common.filter
diff --git a/tests/qemu-iotests/130 b/tests/qemu-iotests/130
index 4aad4ea..3610738 100755
--- a/tests/qemu-iotests/130
+++ b/tests/qemu-iotests/130
@@ -29,8 +29,6 @@ echo "QA output created by $seq"
 here="$PWD"
 status=1	# failure is the default!
 
-trap "_cleanup_qemu; exit \$status" 0 1 2 3 15
-
 # get standard environment, filters and checks
 . ./common.rc
 . ./common.filter
diff --git a/tests/qemu-iotests/140 b/tests/qemu-iotests/140
index c5e1a5b..ec79402 100755
--- a/tests/qemu-iotests/140
+++ b/tests/qemu-iotests/140
@@ -31,8 +31,6 @@ echo "QA output created by $seq"
 here="$PWD"
 status=1	# failure is the default!
 
-trap "_cleanup_qemu; exit \$status" 0 1 2 3 15
-
 # get standard environment, filters and checks
 . ./common.rc
 . ./common.filter
diff --git a/tests/qemu-iotests/141 b/tests/qemu-iotests/141
index cff2319..39b75a4 100755
--- a/tests/qemu-iotests/141
+++ b/tests/qemu-iotests/141
@@ -27,8 +27,6 @@ echo "QA output created by $seq"
 here="$PWD"
 status=1	# failure is the default!
 
-trap "_cleanup_qemu; exit \$status" 0 1 2 3 15
-
 # get standard environment, filters and checks
 . ./common.rc
 . ./common.filter
diff --git a/tests/qemu-iotests/143 b/tests/qemu-iotests/143
index b4736aa..e107ae3 100755
--- a/tests/qemu-iotests/143
+++ b/tests/qemu-iotests/143
@@ -27,8 +27,6 @@ echo "QA output created by $seq"
 here="$PWD"
 status=1	# failure is the default!
 
-trap "_cleanup_qemu; exit \$status" 0 1 2 3 15
-
 # get standard environment, filters and checks
 . ./common.rc
 . ./common.filter
diff --git a/tests/qemu-iotests/144 b/tests/qemu-iotests/144
index b47c561..8b55d33 100755
--- a/tests/qemu-iotests/144
+++ b/tests/qemu-iotests/144
@@ -32,8 +32,6 @@ status=1	# failure is the default!
 TMP_SNAP1=${TEST_DIR}/tmp.qcow2
 TMP_SNAP2=${TEST_DIR}/tmp2.qcow2
 
-trap "_cleanup_qemu; exit \$status" 0 1 2 3 15
-
 # get standard environment, filters and checks
 . ./common.rc
 . ./common.filter
diff --git a/tests/qemu-iotests/146 b/tests/qemu-iotests/146
index 99b1e81..7dffe22 100755
--- a/tests/qemu-iotests/146
+++ b/tests/qemu-iotests/146
@@ -27,8 +27,6 @@ echo "QA output created by $seq"
 here=`pwd`
 status=1    # failure is the default!
 
-trap "_cleanup_qemu; exit \$status" 0 1 2 3 15
-
 # get standard environment, filters and checks
 . ./common.rc
 . ./common.filter
diff --git a/tests/qemu-iotests/156 b/tests/qemu-iotests/156
index 9dbc6d7..26ebd73 100755
--- a/tests/qemu-iotests/156
+++ b/tests/qemu-iotests/156
@@ -35,8 +35,6 @@ echo "QA output created by $seq"
 here="$PWD"
 status=1	# failure is the default!
 
-trap "_cleanup_qemu; exit \$status" 0 1 2 3 15
-
 # get standard environment, filters and checks
 . ./common.rc
 . ./common.filter
diff --git a/tests/qemu-iotests/173 b/tests/qemu-iotests/173
index 0c2fde4..933cd96 100755
--- a/tests/qemu-iotests/173
+++ b/tests/qemu-iotests/173
@@ -27,8 +27,6 @@ echo "QA output created by $seq"
 here=`pwd`
 status=1    # failure is the default!
 
-trap "_cleanup_qemu; exit \$status" 0 1 2 3 15
-
 # get standard environment, filters and checks
 . ./common.rc
 . ./common.filter
diff --git a/tests/qemu-iotests/181 b/tests/qemu-iotests/181
index 18fb133..e6f7908 100755
--- a/tests/qemu-iotests/181
+++ b/tests/qemu-iotests/181
@@ -29,8 +29,6 @@ status=1	# failure is the default!
 
 MIG_SOCKET="${TEST_DIR}/migrate"
 
-trap "_cleanup_qemu; exit \$status" 0 1 2 3 15
-
 # get standard environment, filters and checks
 . ./common.rc
 . ./common.filter
diff --git a/tests/qemu-iotests/183 b/tests/qemu-iotests/183
index 2e09679..cb82d3c 100755
--- a/tests/qemu-iotests/183
+++ b/tests/qemu-iotests/183
@@ -29,8 +29,6 @@ status=1 # failure is the default!
 
 MIG_SOCKET="${TEST_DIR}/migrate"
 
-trap "_cleanup_qemu; exit \$status" 0 1 2 3 15
-
 # get standard environment, filters and checks
 . ./common.rc
 . ./common.filter
diff --git a/tests/qemu-iotests/185 b/tests/qemu-iotests/185
index 7269d5e..ef4b1cd 100755
--- a/tests/qemu-iotests/185
+++ b/tests/qemu-iotests/185
@@ -29,8 +29,6 @@ status=1 # failure is the default!
 
 MIG_SOCKET="${TEST_DIR}/migrate"
 
-trap "_cleanup_qemu; exit \$status" 0 1 2 3 15
-
 # get standard environment, filters and checks
 . ./common.rc
 . ./common.filter
diff --git a/tests/qemu-iotests/191 b/tests/qemu-iotests/191
index f97e580..7fc1365 100755
--- a/tests/qemu-iotests/191
+++ b/tests/qemu-iotests/191
@@ -29,12 +29,6 @@ status=1 # failure is the default!
 
 MIG_SOCKET="${TEST_DIR}/migrate"
 
-_cleanup()
-{
-    _cleanup_qemu
-}
-trap "_cleanup; exit \$status" 0 1 2 3 15
-
 # get standard environment, filters and checks
 . ./common.rc
 . ./common.filter
diff --git a/tests/qemu-iotests/check b/tests/qemu-iotests/check
index b4ab646..057ea39 100755
--- a/tests/qemu-iotests/check
+++ b/tests/qemu-iotests/check
@@ -845,10 +845,13 @@ do
         # TEST_DIR / QEMU_TEST_DIR
         (
         export TEST_DIR=$TEST_DIR_SEQ
-        . "$source_iotests/common.config"
-        . "$source_iotests/common.rc"
+        cd "$source_iotests";
+        . ./common.config
+        . ./common.rc
+        . ./common.qemu
 
         _cleanup_protocols
+        _cleanup_qemu
         )
         rm -rf "$TEST_DIR_SEQ"
 
-- 
2.9.5

^ permalink raw reply related	[flat|nested] 37+ messages in thread

* [Qemu-devel] [PATCH v5 07/10] qemu-iotests: run python tests in own subdirectories
  2017-10-17 16:31 [Qemu-devel] [PATCH v5 00/10] qemu-iotests improvements Jeff Cody
                   ` (5 preceding siblings ...)
  2017-10-17 16:31 ` [Qemu-devel] [PATCH v5 06/10] qemu-iotests: make ./check automatically reap QEMU processes Jeff Cody
@ 2017-10-17 16:31 ` Jeff Cody
  2017-10-17 16:31 ` [Qemu-devel] [PATCH v5 08/10] qemu-iotests: modify python tests to run from subdir Jeff Cody
                   ` (2 subsequent siblings)
  9 siblings, 0 replies; 37+ messages in thread
From: Jeff Cody @ 2017-10-17 16:31 UTC (permalink / raw)
  To: qemu-devel; +Cc: qemu-block, jsnow, stefanha, kwolf, eblake

This adds the framework to iotests.py to run python iotests in a
subdirectory structure, structured like so:

scratch/
├── TestNumber
│   ├── TestClassName
│   │   ├── test_method_name

Prior to this patch, tests were run in a test subdirectory from
previous patches in the series, like this:

scratch/
├── TestNumber

However, given the nature of python's unittest framework, additional
subdirectories are needed, if we want to insure that we can save
intermediate files in case of test failures (as we will do in a
subsequent patch) without running the risk of tainting other test
methods from the test file.

In python tests using iiotests.QMPTestCase, any reference to
'iotests.test_dir' should be replaced by 'self.workdir'.  This
may also require changing the scope of path name variables.

Suggested-by: Stefan Hajnoczi <stefanha@redhat.com>
Signed-off-by: Jeff Cody <jcody@redhat.com>
---
 tests/qemu-iotests/iotests.py | 11 +++++++++++
 1 file changed, 11 insertions(+)

diff --git a/tests/qemu-iotests/iotests.py b/tests/qemu-iotests/iotests.py
index 6f05790..7ff400a 100644
--- a/tests/qemu-iotests/iotests.py
+++ b/tests/qemu-iotests/iotests.py
@@ -262,6 +262,17 @@ index_re = re.compile(r'([^\[]+)\[([^\]]+)\]')
 class QMPTestCase(unittest.TestCase):
     '''Abstract base class for QMP test cases'''
 
+    def __init__(self, *args):
+        super(QMPTestCase, self).__init__(*args)
+        self.workdir = os.path.join(test_dir, self.__class__.__name__,
+                                    self._testMethodName)
+        try:
+            os.makedirs(self.workdir)
+        except OSError, error:
+            if error.errno != errno.EEXIST:
+                raise
+        os.chdir(self.workdir)
+
     def dictpath(self, d, path):
         '''Traverse a path in a nested dict'''
         for component in path.split('/'):
-- 
2.9.5

^ permalink raw reply related	[flat|nested] 37+ messages in thread

* [Qemu-devel] [PATCH v5 08/10] qemu-iotests: modify python tests to run from subdir
  2017-10-17 16:31 [Qemu-devel] [PATCH v5 00/10] qemu-iotests improvements Jeff Cody
                   ` (6 preceding siblings ...)
  2017-10-17 16:31 ` [Qemu-devel] [PATCH v5 07/10] qemu-iotests: run python tests in own subdirectories Jeff Cody
@ 2017-10-17 16:31 ` Jeff Cody
  2017-10-17 16:31 ` [Qemu-devel] [PATCH v5 09/10] qemu-iotests: add option to save temp files on error Jeff Cody
  2017-10-17 16:31 ` [Qemu-devel] [PATCH v5 10/10] qemu-iotests: add support for running multi-threaded iotests Jeff Cody
  9 siblings, 0 replies; 37+ messages in thread
From: Jeff Cody @ 2017-10-17 16:31 UTC (permalink / raw)
  To: qemu-devel; +Cc: qemu-block, jsnow, stefanha, kwolf, eblake

Also removes any intermediate file deletion; this is no longer needed,
as 'check' will take care of that once the test is completed (unless
the user requests to save files on failure, and the test fails)

Signed-off-by: Jeff Cody <jcody@redhat.com>
---
 tests/qemu-iotests/030 |  82 ++++++------
 tests/qemu-iotests/040 | 128 +++++++++----------
 tests/qemu-iotests/041 | 333 +++++++++++++++++++++++++------------------------
 tests/qemu-iotests/044 |  11 +-
 tests/qemu-iotests/045 |  42 +++----
 tests/qemu-iotests/055 |  97 +++++++-------
 tests/qemu-iotests/056 |  39 +++---
 tests/qemu-iotests/057 |   4 +-
 tests/qemu-iotests/065 |  13 +-
 tests/qemu-iotests/096 |   8 +-
 tests/qemu-iotests/118 | 200 ++++++++++++++---------------
 tests/qemu-iotests/124 |  24 ++--
 tests/qemu-iotests/129 |   6 +-
 tests/qemu-iotests/132 |  19 ++-
 tests/qemu-iotests/136 |   7 +-
 tests/qemu-iotests/139 |  33 +++--
 tests/qemu-iotests/147 |  41 +++---
 tests/qemu-iotests/148 |  33 +++--
 tests/qemu-iotests/152 |  21 ++--
 tests/qemu-iotests/155 |  54 ++++----
 tests/qemu-iotests/163 |  42 +++----
 tests/qemu-iotests/165 |  11 +-
 22 files changed, 581 insertions(+), 667 deletions(-)

diff --git a/tests/qemu-iotests/030 b/tests/qemu-iotests/030
index 1883894..6e52509 100755
--- a/tests/qemu-iotests/030
+++ b/tests/qemu-iotests/030
@@ -23,27 +23,24 @@ import os
 import iotests
 from iotests import qemu_img, qemu_io
 
-backing_img = os.path.join(iotests.test_dir, 'backing.img')
-mid_img = os.path.join(iotests.test_dir, 'mid.img')
-test_img = os.path.join(iotests.test_dir, 'test.img')
 
 class TestSingleDrive(iotests.QMPTestCase):
     image_len = 1 * 1024 * 1024 # MB
 
     def setUp(self):
-        iotests.create_image(backing_img, TestSingleDrive.image_len)
-        qemu_img('create', '-f', iotests.imgfmt, '-o', 'backing_file=%s' % backing_img, mid_img)
-        qemu_img('create', '-f', iotests.imgfmt, '-o', 'backing_file=%s' % mid_img, test_img)
-        qemu_io('-f', 'raw', '-c', 'write -P 0x1 0 512', backing_img)
-        qemu_io('-f', iotests.imgfmt, '-c', 'write -P 0x1 524288 512', mid_img)
-        self.vm = iotests.VM().add_drive("blkdebug::" + test_img, "backing.node-name=mid")
+        self.backing_img = os.path.join(self.workdir, 'backing.img')
+        self.mid_img = os.path.join(self.workdir, 'mid.img')
+        self.test_img = os.path.join(self.workdir, 'test.img')
+        iotests.create_image(self.backing_img, TestSingleDrive.image_len)
+        qemu_img('create', '-f', iotests.imgfmt, '-o', 'backing_file=%s' % self.backing_img, self.mid_img)
+        qemu_img('create', '-f', iotests.imgfmt, '-o', 'backing_file=%s' % self.mid_img, self.test_img)
+        qemu_io('-f', 'raw', '-c', 'write -P 0x1 0 512', self.backing_img)
+        qemu_io('-f', iotests.imgfmt, '-c', 'write -P 0x1 524288 512', self.mid_img)
+        self.vm = iotests.VM().add_drive("blkdebug::" + self.test_img, "backing.node-name=mid")
         self.vm.launch()
 
     def tearDown(self):
         self.vm.shutdown()
-        os.remove(test_img)
-        os.remove(mid_img)
-        os.remove(backing_img)
 
     def test_stream(self):
         self.assert_no_active_block_jobs()
@@ -56,15 +53,15 @@ class TestSingleDrive(iotests.QMPTestCase):
         self.assert_no_active_block_jobs()
         self.vm.shutdown()
 
-        self.assertEqual(qemu_io('-f', 'raw', '-c', 'map', backing_img),
-                         qemu_io('-f', iotests.imgfmt, '-c', 'map', test_img),
+        self.assertEqual(qemu_io('-f', 'raw', '-c', 'map', self.backing_img),
+                         qemu_io('-f', iotests.imgfmt, '-c', 'map', self.test_img),
                          'image file map does not match backing file after streaming')
 
     def test_stream_intermediate(self):
         self.assert_no_active_block_jobs()
 
-        self.assertNotEqual(qemu_io('-f', 'raw', '-rU', '-c', 'map', backing_img),
-                            qemu_io('-f', iotests.imgfmt, '-rU', '-c', 'map', mid_img),
+        self.assertNotEqual(qemu_io('-f', 'raw', '-rU', '-c', 'map', self.backing_img),
+                            qemu_io('-f', iotests.imgfmt, '-rU', '-c', 'map', self.mid_img),
                             'image file map matches backing file before streaming')
 
         result = self.vm.qmp('block-stream', device='mid', job_id='stream-mid')
@@ -75,8 +72,8 @@ class TestSingleDrive(iotests.QMPTestCase):
         self.assert_no_active_block_jobs()
         self.vm.shutdown()
 
-        self.assertEqual(qemu_io('-f', 'raw', '-c', 'map', backing_img),
-                         qemu_io('-f', iotests.imgfmt, '-c', 'map', mid_img),
+        self.assertEqual(qemu_io('-f', 'raw', '-c', 'map', self.backing_img),
+                         qemu_io('-f', iotests.imgfmt, '-c', 'map', self.mid_img),
                          'image file map does not match backing file after streaming')
 
     def test_stream_pause(self):
@@ -107,18 +104,18 @@ class TestSingleDrive(iotests.QMPTestCase):
         self.assert_no_active_block_jobs()
         self.vm.shutdown()
 
-        self.assertEqual(qemu_io('-f', 'raw', '-c', 'map', backing_img),
-                         qemu_io('-f', iotests.imgfmt, '-c', 'map', test_img),
+        self.assertEqual(qemu_io('-f', 'raw', '-c', 'map', self.backing_img),
+                         qemu_io('-f', iotests.imgfmt, '-c', 'map', self.test_img),
                          'image file map does not match backing file after streaming')
 
     def test_stream_no_op(self):
         self.assert_no_active_block_jobs()
 
         # The image map is empty before the operation
-        empty_map = qemu_io('-f', iotests.imgfmt, '-rU', '-c', 'map', test_img)
+        empty_map = qemu_io('-f', iotests.imgfmt, '-rU', '-c', 'map', self.test_img)
 
         # This is a no-op: no data should ever be copied from the base image
-        result = self.vm.qmp('block-stream', device='drive0', base=mid_img)
+        result = self.vm.qmp('block-stream', device='drive0', base=self.mid_img)
         self.assert_qmp(result, 'return', {})
 
         self.wait_until_completed()
@@ -126,13 +123,13 @@ class TestSingleDrive(iotests.QMPTestCase):
         self.assert_no_active_block_jobs()
         self.vm.shutdown()
 
-        self.assertEqual(qemu_io('-f', iotests.imgfmt, '-c', 'map', test_img),
+        self.assertEqual(qemu_io('-f', iotests.imgfmt, '-c', 'map', self.test_img),
                          empty_map, 'image file map changed after a no-op')
 
     def test_stream_partial(self):
         self.assert_no_active_block_jobs()
 
-        result = self.vm.qmp('block-stream', device='drive0', base=backing_img)
+        result = self.vm.qmp('block-stream', device='drive0', base=self.backing_img)
         self.assert_qmp(result, 'return', {})
 
         self.wait_until_completed()
@@ -140,8 +137,8 @@ class TestSingleDrive(iotests.QMPTestCase):
         self.assert_no_active_block_jobs()
         self.vm.shutdown()
 
-        self.assertEqual(qemu_io('-f', iotests.imgfmt, '-c', 'map', mid_img),
-                         qemu_io('-f', iotests.imgfmt, '-c', 'map', test_img),
+        self.assertEqual(qemu_io('-f', iotests.imgfmt, '-c', 'map', self.mid_img),
+                         qemu_io('-f', iotests.imgfmt, '-c', 'map', self.test_img),
                          'image file map does not match backing file after streaming')
 
     def test_device_not_found(self):
@@ -157,7 +154,6 @@ class TestParallelOps(iotests.QMPTestCase):
     num_ops = 4 # Number of parallel block-stream operations
     num_imgs = num_ops * 2 + 1
     image_len = num_ops * 1024 * 1024
-    imgs = []
 
     def setUp(self):
         opts = []
@@ -167,7 +163,7 @@ class TestParallelOps(iotests.QMPTestCase):
         for i in range(self.num_imgs):
             img_depth = self.num_imgs - i - 1
             opts.append("backing." * img_depth + "node-name=node%d" % i)
-            self.imgs.append(os.path.join(iotests.test_dir, 'img-%d.img' % i))
+            self.imgs.append(os.path.join(self.workdir, 'img-%d.img' % i))
 
         # Create all images
         iotests.create_image(self.imgs[0], self.image_len)
@@ -192,8 +188,6 @@ class TestParallelOps(iotests.QMPTestCase):
 
     def tearDown(self):
         self.vm.shutdown()
-        for img in self.imgs:
-            os.remove(img)
 
     # Test that it's possible to run several block-stream operations
     # in parallel in the same snapshot chain
@@ -395,8 +389,8 @@ class TestQuorum(iotests.QMPTestCase):
 
         # Initialize file names and command-line options
         for i in range(self.num_children):
-            child_img = os.path.join(iotests.test_dir, 'img-%d.img' % i)
-            backing_img = os.path.join(iotests.test_dir, 'backing-%d.img' % i)
+            child_img = os.path.join(self.workdir, 'img-%d.img' % i)
+            backing_img = os.path.join(self.workdir, 'backing-%d.img' % i)
             self.children.append(child_img)
             self.backing.append(backing_img)
             qemu_img('create', '-f', iotests.imgfmt, backing_img, '1M')
@@ -414,10 +408,6 @@ class TestQuorum(iotests.QMPTestCase):
 
     def tearDown(self):
         self.vm.shutdown()
-        for img in self.children:
-            os.remove(img)
-        for img in self.backing:
-            os.remove(img)
 
     def test_stream_quorum(self):
         if not iotests.supports_quorum():
@@ -446,6 +436,8 @@ class TestSmallerBackingFile(iotests.QMPTestCase):
     image_len = 2 * backing_len
 
     def setUp(self):
+        backing_img = os.path.join(self.workdir, 'backing.img')
+        test_img = os.path.join(self.workdir, 'test.img')
         iotests.create_image(backing_img, self.backing_len)
         qemu_img('create', '-f', iotests.imgfmt, '-o', 'backing_file=%s' % backing_img, test_img, str(self.image_len))
         self.vm = iotests.VM().add_drive(test_img)
@@ -495,6 +487,8 @@ new_state = "1"
 
 class TestEIO(TestErrors):
     def setUp(self):
+        backing_img = os.path.join(self.workdir, 'backing.img')
+        test_img = os.path.join(self.workdir, 'test.img')
         self.blkdebug_file = backing_img + ".blkdebug"
         iotests.create_image(backing_img, TestErrors.image_len)
         self.create_blkdebug_file(self.blkdebug_file, "read_aio", 5)
@@ -507,9 +501,6 @@ class TestEIO(TestErrors):
 
     def tearDown(self):
         self.vm.shutdown()
-        os.remove(test_img)
-        os.remove(backing_img)
-        os.remove(self.blkdebug_file)
 
     def test_report(self):
         self.assert_no_active_block_jobs()
@@ -637,6 +628,8 @@ class TestEIO(TestErrors):
 
 class TestENOSPC(TestErrors):
     def setUp(self):
+        backing_img = os.path.join(self.workdir, 'backing.img')
+        test_img = os.path.join(self.workdir, 'test.img')
         self.blkdebug_file = backing_img + ".blkdebug"
         iotests.create_image(backing_img, TestErrors.image_len)
         self.create_blkdebug_file(self.blkdebug_file, "read_aio", 28)
@@ -649,9 +642,6 @@ class TestENOSPC(TestErrors):
 
     def tearDown(self):
         self.vm.shutdown()
-        os.remove(test_img)
-        os.remove(backing_img)
-        os.remove(self.blkdebug_file)
 
     def test_enospc(self):
         self.assert_no_active_block_jobs()
@@ -695,6 +685,8 @@ class TestStreamStop(iotests.QMPTestCase):
     image_len = 8 * 1024 * 1024 * 1024 # GB
 
     def setUp(self):
+        backing_img = os.path.join(self.workdir, 'backing.img')
+        test_img = os.path.join(self.workdir, 'test.img')
         qemu_img('create', backing_img, str(TestStreamStop.image_len))
         qemu_io('-f', 'raw', '-c', 'write -P 0x1 0 32M', backing_img)
         qemu_img('create', '-f', iotests.imgfmt, '-o', 'backing_file=%s' % backing_img, test_img)
@@ -704,8 +696,6 @@ class TestStreamStop(iotests.QMPTestCase):
 
     def tearDown(self):
         self.vm.shutdown()
-        os.remove(test_img)
-        os.remove(backing_img)
 
     def test_stream_stop(self):
         self.assert_no_active_block_jobs()
@@ -724,6 +714,8 @@ class TestSetSpeed(iotests.QMPTestCase):
     image_len = 80 * 1024 * 1024 # MB
 
     def setUp(self):
+        backing_img = os.path.join(self.workdir, 'backing.img')
+        test_img = os.path.join(self.workdir, 'test.img')
         qemu_img('create', backing_img, str(TestSetSpeed.image_len))
         qemu_io('-f', 'raw', '-c', 'write -P 0x1 0 32M', backing_img)
         qemu_img('create', '-f', iotests.imgfmt, '-o', 'backing_file=%s' % backing_img, test_img)
@@ -733,8 +725,6 @@ class TestSetSpeed(iotests.QMPTestCase):
 
     def tearDown(self):
         self.vm.shutdown()
-        os.remove(test_img)
-        os.remove(backing_img)
 
     # This is a short performance test which is not run by default.
     # Invoke "IMGFMT=qed ./030 TestSetSpeed.perf_test_throughput"
diff --git a/tests/qemu-iotests/040 b/tests/qemu-iotests/040
index c284d08..c4ba9bb 100755
--- a/tests/qemu-iotests/040
+++ b/tests/qemu-iotests/040
@@ -28,9 +28,6 @@ from iotests import qemu_img, qemu_io
 import struct
 import errno
 
-backing_img = os.path.join(iotests.test_dir, 'backing.img')
-mid_img = os.path.join(iotests.test_dir, 'mid.img')
-test_img = os.path.join(iotests.test_dir, 'test.img')
 
 class ImageCommitTestCase(iotests.QMPTestCase):
     '''Abstract base class for image commit test cases'''
@@ -76,12 +73,15 @@ class TestSingleDrive(ImageCommitTestCase):
     test_len = 1 * 1024 * 256
 
     def setUp(self):
-        iotests.create_image(backing_img, self.image_len)
-        qemu_img('create', '-f', iotests.imgfmt, '-o', 'backing_file=%s' % backing_img, mid_img)
-        qemu_img('create', '-f', iotests.imgfmt, '-o', 'backing_file=%s' % mid_img, test_img)
-        qemu_io('-f', 'raw', '-c', 'write -P 0xab 0 524288', backing_img)
-        qemu_io('-f', iotests.imgfmt, '-c', 'write -P 0xef 524288 524288', mid_img)
-        self.vm = iotests.VM().add_drive(test_img, "node-name=top,backing.node-name=mid,backing.backing.node-name=base", interface="none")
+        self.backing_img = os.path.join(self.workdir, 'backing.img')
+        self.mid_img = os.path.join(self.workdir, 'mid.img')
+        self.test_img = os.path.join(self.workdir, 'test.img')
+        iotests.create_image(self.backing_img, self.image_len)
+        qemu_img('create', '-f', iotests.imgfmt, '-o', 'backing_file=%s' % self.backing_img, self.mid_img)
+        qemu_img('create', '-f', iotests.imgfmt, '-o', 'backing_file=%s' % self.mid_img, self.test_img)
+        qemu_io('-f', 'raw', '-c', 'write -P 0xab 0 524288', self.backing_img)
+        qemu_io('-f', iotests.imgfmt, '-c', 'write -P 0xef 524288 524288', self.mid_img)
+        self.vm = iotests.VM().add_drive(self.test_img, "node-name=top,backing.node-name=mid,backing.backing.node-name=base", interface="none")
         if iotests.qemu_default_machine == 's390-ccw-virtio':
             self.vm.add_device("virtio-scsi-ccw")
         else:
@@ -92,52 +92,49 @@ class TestSingleDrive(ImageCommitTestCase):
 
     def tearDown(self):
         self.vm.shutdown()
-        os.remove(test_img)
-        os.remove(mid_img)
-        os.remove(backing_img)
 
     def test_commit(self):
-        self.run_commit_test(mid_img, backing_img)
-        self.assertEqual(-1, qemu_io('-f', 'raw', '-c', 'read -P 0xab 0 524288', backing_img).find("verification failed"))
-        self.assertEqual(-1, qemu_io('-f', 'raw', '-c', 'read -P 0xef 524288 524288', backing_img).find("verification failed"))
+        self.run_commit_test(self.mid_img, self.backing_img)
+        self.assertEqual(-1, qemu_io('-f', 'raw', '-c', 'read -P 0xab 0 524288', self.backing_img).find("verification failed"))
+        self.assertEqual(-1, qemu_io('-f', 'raw', '-c', 'read -P 0xef 524288 524288', self.backing_img).find("verification failed"))
 
     def test_device_not_found(self):
-        result = self.vm.qmp('block-commit', device='nonexistent', top='%s' % mid_img)
+        result = self.vm.qmp('block-commit', device='nonexistent', top='%s' % self.mid_img)
         self.assert_qmp(result, 'error/class', 'DeviceNotFound')
 
     def test_top_same_base(self):
         self.assert_no_active_block_jobs()
-        result = self.vm.qmp('block-commit', device='drive0', top='%s' % backing_img, base='%s' % backing_img)
+        result = self.vm.qmp('block-commit', device='drive0', top='%s' % self.backing_img, base='%s' % self.backing_img)
         self.assert_qmp(result, 'error/class', 'GenericError')
-        self.assert_qmp(result, 'error/desc', 'Base \'%s\' not found' % backing_img)
+        self.assert_qmp(result, 'error/desc', 'Base \'%s\' not found' % self.backing_img)
 
     def test_top_invalid(self):
         self.assert_no_active_block_jobs()
-        result = self.vm.qmp('block-commit', device='drive0', top='badfile', base='%s' % backing_img)
+        result = self.vm.qmp('block-commit', device='drive0', top='badfile', base='%s' % self.backing_img)
         self.assert_qmp(result, 'error/class', 'GenericError')
         self.assert_qmp(result, 'error/desc', 'Top image file badfile not found')
 
     def test_base_invalid(self):
         self.assert_no_active_block_jobs()
-        result = self.vm.qmp('block-commit', device='drive0', top='%s' % mid_img, base='badfile')
+        result = self.vm.qmp('block-commit', device='drive0', top='%s' % self.mid_img, base='badfile')
         self.assert_qmp(result, 'error/class', 'GenericError')
         self.assert_qmp(result, 'error/desc', 'Base \'badfile\' not found')
 
     def test_top_is_active(self):
-        self.run_commit_test(test_img, backing_img, need_ready=True)
-        self.assertEqual(-1, qemu_io('-f', 'raw', '-c', 'read -P 0xab 0 524288', backing_img).find("verification failed"))
-        self.assertEqual(-1, qemu_io('-f', 'raw', '-c', 'read -P 0xef 524288 524288', backing_img).find("verification failed"))
+        self.run_commit_test(self.test_img, self.backing_img, need_ready=True)
+        self.assertEqual(-1, qemu_io('-f', 'raw', '-c', 'read -P 0xab 0 524288', self.backing_img).find("verification failed"))
+        self.assertEqual(-1, qemu_io('-f', 'raw', '-c', 'read -P 0xef 524288 524288', self.backing_img).find("verification failed"))
 
     def test_top_is_default_active(self):
         self.run_default_commit_test()
-        self.assertEqual(-1, qemu_io('-f', 'raw', '-c', 'read -P 0xab 0 524288', backing_img).find("verification failed"))
-        self.assertEqual(-1, qemu_io('-f', 'raw', '-c', 'read -P 0xef 524288 524288', backing_img).find("verification failed"))
+        self.assertEqual(-1, qemu_io('-f', 'raw', '-c', 'read -P 0xab 0 524288', self.backing_img).find("verification failed"))
+        self.assertEqual(-1, qemu_io('-f', 'raw', '-c', 'read -P 0xef 524288 524288', self.backing_img).find("verification failed"))
 
     def test_top_and_base_reversed(self):
         self.assert_no_active_block_jobs()
-        result = self.vm.qmp('block-commit', device='drive0', top='%s' % backing_img, base='%s' % mid_img)
+        result = self.vm.qmp('block-commit', device='drive0', top='%s' % self.backing_img, base='%s' % self.mid_img)
         self.assert_qmp(result, 'error/class', 'GenericError')
-        self.assert_qmp(result, 'error/desc', 'Base \'%s\' not found' % mid_img)
+        self.assert_qmp(result, 'error/desc', 'Base \'%s\' not found' % self.mid_img)
 
     # When the job is running on a BB that is automatically deleted on hot
     # unplug, the job is cancelled when the device disappears
@@ -146,8 +143,8 @@ class TestSingleDrive(ImageCommitTestCase):
             return
 
         self.assert_no_active_block_jobs()
-        result = self.vm.qmp('block-commit', device='drive0', top=mid_img,
-                             base=backing_img, speed=(self.image_len / 4))
+        result = self.vm.qmp('block-commit', device='drive0', top=self.mid_img,
+                             base=self.backing_img, speed=(self.image_len / 4))
         self.assert_qmp(result, 'return', {})
         result = self.vm.qmp('device_del', id='scsi0')
         self.assert_qmp(result, 'return', {})
@@ -174,18 +171,18 @@ class TestSingleDrive(ImageCommitTestCase):
             return
 
         self.assert_no_active_block_jobs()
-        result = self.vm.qmp('block-commit', device='drive0', top=mid_img,
-                             base=backing_img, speed=(self.image_len / 4))
+        result = self.vm.qmp('block-commit', device='drive0', top=self.mid_img,
+                             base=self.backing_img, speed=(self.image_len / 4))
         self.assert_qmp(result, 'return', {})
 
         result = self.vm.qmp('query-block')
-        self.assert_qmp(result, 'return[0]/inserted/file', test_img)
+        self.assert_qmp(result, 'return[0]/inserted/file', self.test_img)
         self.assert_qmp(result, 'return[0]/inserted/drv', iotests.imgfmt)
-        self.assert_qmp(result, 'return[0]/inserted/backing_file', mid_img)
+        self.assert_qmp(result, 'return[0]/inserted/backing_file', self.mid_img)
         self.assert_qmp(result, 'return[0]/inserted/backing_file_depth', 2)
-        self.assert_qmp(result, 'return[0]/inserted/image/filename', test_img)
-        self.assert_qmp(result, 'return[0]/inserted/image/backing-image/filename', mid_img)
-        self.assert_qmp(result, 'return[0]/inserted/image/backing-image/backing-image/filename', backing_img)
+        self.assert_qmp(result, 'return[0]/inserted/image/filename', self.test_img)
+        self.assert_qmp(result, 'return[0]/inserted/image/backing-image/filename', self.mid_img)
+        self.assert_qmp(result, 'return[0]/inserted/image/backing-image/backing-image/filename', self.backing_img)
 
         result = self.vm.qmp('query-blockstats')
         self.assert_qmp(result, 'return[0]/node-name', 'top')
@@ -202,19 +199,24 @@ class TestRelativePaths(ImageCommitTestCase):
     dir1 = "dir1"
     dir2 = "dir2/"
     dir3 = "dir2/dir3/"
+    backing_img = ""
+    mid_img = ""
+    test_img = ""
+    backing_img_abs = ""
+    mid_img_abs = ""
 
-    test_img = os.path.join(iotests.test_dir, dir3, 'test.img')
     mid_img = "../mid.img"
     backing_img = "../dir1/backing.img"
 
-    backing_img_abs = os.path.join(iotests.test_dir, dir1, 'backing.img')
-    mid_img_abs = os.path.join(iotests.test_dir, dir2, 'mid.img')
 
     def setUp(self):
+        self.test_img = os.path.join(self.workdir, self.dir3, 'test.img')
+        self.backing_img_abs = os.path.join(self.workdir, self.dir1, 'backing.img')
+        self.mid_img_abs = os.path.join(self.workdir, self.dir2, 'mid.img')
         try:
-            os.mkdir(os.path.join(iotests.test_dir, self.dir1))
-            os.mkdir(os.path.join(iotests.test_dir, self.dir2))
-            os.mkdir(os.path.join(iotests.test_dir, self.dir3))
+            os.mkdir(os.path.join(self.workdir, self.dir1))
+            os.mkdir(os.path.join(self.workdir, self.dir2))
+            os.mkdir(os.path.join(self.workdir, self.dir3))
         except OSError as exception:
             if exception.errno != errno.EEXIST:
                 raise
@@ -230,16 +232,6 @@ class TestRelativePaths(ImageCommitTestCase):
 
     def tearDown(self):
         self.vm.shutdown()
-        os.remove(self.test_img)
-        os.remove(self.mid_img_abs)
-        os.remove(self.backing_img_abs)
-        try:
-            os.rmdir(os.path.join(iotests.test_dir, self.dir1))
-            os.rmdir(os.path.join(iotests.test_dir, self.dir3))
-            os.rmdir(os.path.join(iotests.test_dir, self.dir2))
-        except OSError as exception:
-            if exception.errno != errno.EEXIST and exception.errno != errno.ENOTEMPTY:
-                raise
 
     def test_commit(self):
         self.run_commit_test(self.mid_img, self.backing_img)
@@ -284,25 +276,25 @@ class TestSetSpeed(ImageCommitTestCase):
     image_len = 80 * 1024 * 1024 # MB
 
     def setUp(self):
-        qemu_img('create', backing_img, str(TestSetSpeed.image_len))
-        qemu_img('create', '-f', iotests.imgfmt, '-o', 'backing_file=%s' % backing_img, mid_img)
-        qemu_img('create', '-f', iotests.imgfmt, '-o', 'backing_file=%s' % mid_img, test_img)
-        qemu_io('-f', iotests.imgfmt, '-c', 'write -P 0x1 0 512', test_img)
-        qemu_io('-f', iotests.imgfmt, '-c', 'write -P 0xef 524288 524288', mid_img)
-        self.vm = iotests.VM().add_drive(test_img)
+        self.backing_img = os.path.join(self.workdir, 'backing.img')
+        self.mid_img = os.path.join(self.workdir, 'mid.img')
+        self.test_img = os.path.join(self.workdir, 'test.img')
+        qemu_img('create', self.backing_img, str(TestSetSpeed.image_len))
+        qemu_img('create', '-f', iotests.imgfmt, '-o', 'backing_file=%s' % self.backing_img, self.mid_img)
+        qemu_img('create', '-f', iotests.imgfmt, '-o', 'backing_file=%s' % self.mid_img, self.test_img)
+        qemu_io('-f', iotests.imgfmt, '-c', 'write -P 0x1 0 512', self.test_img)
+        qemu_io('-f', iotests.imgfmt, '-c', 'write -P 0xef 524288 524288', self.mid_img)
+        self.vm = iotests.VM().add_drive(self.test_img)
         self.vm.launch()
 
     def tearDown(self):
         self.vm.shutdown()
-        os.remove(test_img)
-        os.remove(mid_img)
-        os.remove(backing_img)
 
     def test_set_speed(self):
         self.assert_no_active_block_jobs()
 
         self.vm.pause_drive('drive0')
-        result = self.vm.qmp('block-commit', device='drive0', top=mid_img, speed=1024 * 1024)
+        result = self.vm.qmp('block-commit', device='drive0', top=self.mid_img, speed=1024 * 1024)
         self.assert_qmp(result, 'return', {})
 
         # Ensure the speed we set was accepted
@@ -317,12 +309,12 @@ class TestActiveZeroLengthImage(TestSingleDrive):
 
 class TestReopenOverlay(ImageCommitTestCase):
     image_len = 1024 * 1024
-    img0 = os.path.join(iotests.test_dir, '0.img')
-    img1 = os.path.join(iotests.test_dir, '1.img')
-    img2 = os.path.join(iotests.test_dir, '2.img')
-    img3 = os.path.join(iotests.test_dir, '3.img')
 
     def setUp(self):
+        self.img0 = os.path.join(self.workdir, '0.img')
+        self.img1 = os.path.join(self.workdir, '1.img')
+        self.img2 = os.path.join(self.workdir, '2.img')
+        self.img3 = os.path.join(self.workdir, '3.img')
         iotests.create_image(self.img0, self.image_len)
         qemu_img('create', '-f', iotests.imgfmt, '-o', 'backing_file=%s' % self.img0, self.img1)
         qemu_img('create', '-f', iotests.imgfmt, '-o', 'backing_file=%s' % self.img1, self.img2)
@@ -333,10 +325,6 @@ class TestReopenOverlay(ImageCommitTestCase):
 
     def tearDown(self):
         self.vm.shutdown()
-        os.remove(self.img0)
-        os.remove(self.img1)
-        os.remove(self.img2)
-        os.remove(self.img3)
 
     # This tests what happens when the overlay image of the 'top' node
     # needs to be reopened in read-write mode in order to update the
diff --git a/tests/qemu-iotests/041 b/tests/qemu-iotests/041
index a860a31..3b73f11 100755
--- a/tests/qemu-iotests/041
+++ b/tests/qemu-iotests/041
@@ -23,38 +23,26 @@ import os
 import iotests
 from iotests import qemu_img, qemu_io
 
-backing_img = os.path.join(iotests.test_dir, 'backing.img')
-target_backing_img = os.path.join(iotests.test_dir, 'target-backing.img')
-test_img = os.path.join(iotests.test_dir, 'test.img')
-target_img = os.path.join(iotests.test_dir, 'target.img')
-
-quorum_img1 = os.path.join(iotests.test_dir, 'quorum1.img')
-quorum_img2 = os.path.join(iotests.test_dir, 'quorum2.img')
-quorum_img3 = os.path.join(iotests.test_dir, 'quorum3.img')
-quorum_repair_img = os.path.join(iotests.test_dir, 'quorum_repair.img')
-quorum_snapshot_file = os.path.join(iotests.test_dir, 'quorum_snapshot.img')
 
 class TestSingleDrive(iotests.QMPTestCase):
     image_len = 1 * 1024 * 1024 # MB
     qmp_cmd = 'drive-mirror'
-    qmp_target = target_img
 
     def setUp(self):
-        iotests.create_image(backing_img, self.image_len)
-        qemu_img('create', '-f', iotests.imgfmt, '-o', 'backing_file=%s' % backing_img, test_img)
-        self.vm = iotests.VM().add_drive(test_img, "node-name=top,backing.node-name=base")
+        self.backing_img = os.path.join(self.workdir, 'backing.img')
+        self.test_img = os.path.join(self.workdir, 'test.img')
+        self.target_img = os.path.join(self.workdir, 'target.img')
+        self.qmp_target = self.target_img
+        iotests.create_image(self.backing_img, self.image_len)
+        qemu_img('create', '-f', iotests.imgfmt, '-o', 'backing_file=%s' % self.backing_img, self.test_img)
+        self.vm = iotests.VM().add_drive(self.test_img, "node-name=top,backing.node-name=base")
         if iotests.qemu_default_machine == 'pc':
             self.vm.add_drive(None, 'media=cdrom', 'ide')
         self.vm.launch()
 
     def tearDown(self):
         self.vm.shutdown()
-        os.remove(test_img)
-        os.remove(backing_img)
-        try:
-            os.remove(target_img)
-        except OSError:
-            pass
+        pass
 
     def test_complete(self):
         self.assert_no_active_block_jobs()
@@ -65,9 +53,9 @@ class TestSingleDrive(iotests.QMPTestCase):
 
         self.complete_and_wait()
         result = self.vm.qmp('query-block')
-        self.assert_qmp(result, 'return[0]/inserted/file', target_img)
+        self.assert_qmp(result, 'return[0]/inserted/file', self.target_img)
         self.vm.shutdown()
-        self.assertTrue(iotests.compare_images(test_img, target_img),
+        self.assertTrue(iotests.compare_images(self.test_img, self.target_img),
                         'target image does not match source after mirroring')
 
     def test_cancel(self):
@@ -79,7 +67,7 @@ class TestSingleDrive(iotests.QMPTestCase):
 
         self.cancel_and_wait(force=True)
         result = self.vm.qmp('query-block')
-        self.assert_qmp(result, 'return[0]/inserted/file', test_img)
+        self.assert_qmp(result, 'return[0]/inserted/file', self.test_img)
         self.vm.shutdown()
 
     def test_cancel_after_ready(self):
@@ -91,9 +79,9 @@ class TestSingleDrive(iotests.QMPTestCase):
 
         self.wait_ready_and_cancel()
         result = self.vm.qmp('query-block')
-        self.assert_qmp(result, 'return[0]/inserted/file', test_img)
+        self.assert_qmp(result, 'return[0]/inserted/file', self.test_img)
         self.vm.shutdown()
-        self.assertTrue(iotests.compare_images(test_img, target_img),
+        self.assertTrue(iotests.compare_images(self.test_img, self.target_img),
                         'target image does not match source after mirroring')
 
     def test_pause(self):
@@ -117,7 +105,7 @@ class TestSingleDrive(iotests.QMPTestCase):
 
         self.complete_and_wait()
         self.vm.shutdown()
-        self.assertTrue(iotests.compare_images(test_img, target_img),
+        self.assertTrue(iotests.compare_images(self.test_img, self.target_img),
                         'target image does not match source after mirroring')
 
     def test_small_buffer(self):
@@ -130,41 +118,41 @@ class TestSingleDrive(iotests.QMPTestCase):
 
         self.complete_and_wait()
         result = self.vm.qmp('query-block')
-        self.assert_qmp(result, 'return[0]/inserted/file', target_img)
+        self.assert_qmp(result, 'return[0]/inserted/file', self.target_img)
         self.vm.shutdown()
-        self.assertTrue(iotests.compare_images(test_img, target_img),
+        self.assertTrue(iotests.compare_images(self.test_img, self.target_img),
                         'target image does not match source after mirroring')
 
     def test_small_buffer2(self):
         self.assert_no_active_block_jobs()
 
         qemu_img('create', '-f', iotests.imgfmt, '-o', 'cluster_size=%d,size=%d'
-                        % (self.image_len, self.image_len), target_img)
+                        % (self.image_len, self.image_len), self.target_img)
         result = self.vm.qmp(self.qmp_cmd, device='drive0', sync='full',
                              buf_size=65536, mode='existing', target=self.qmp_target)
         self.assert_qmp(result, 'return', {})
 
         self.complete_and_wait()
         result = self.vm.qmp('query-block')
-        self.assert_qmp(result, 'return[0]/inserted/file', target_img)
+        self.assert_qmp(result, 'return[0]/inserted/file', self.target_img)
         self.vm.shutdown()
-        self.assertTrue(iotests.compare_images(test_img, target_img),
+        self.assertTrue(iotests.compare_images(self.test_img, self.target_img),
                         'target image does not match source after mirroring')
 
     def test_large_cluster(self):
         self.assert_no_active_block_jobs()
 
         qemu_img('create', '-f', iotests.imgfmt, '-o', 'cluster_size=%d,backing_file=%s'
-                        % (self.image_len, backing_img), target_img)
+                        % (self.image_len, self.backing_img), self.target_img)
         result = self.vm.qmp(self.qmp_cmd, device='drive0', sync='full',
                              mode='existing', target=self.qmp_target)
         self.assert_qmp(result, 'return', {})
 
         self.complete_and_wait()
         result = self.vm.qmp('query-block')
-        self.assert_qmp(result, 'return[0]/inserted/file', target_img)
+        self.assert_qmp(result, 'return[0]/inserted/file', self.target_img)
         self.vm.shutdown()
-        self.assertTrue(iotests.compare_images(test_img, target_img),
+        self.assertTrue(iotests.compare_images(self.test_img, self.target_img),
                         'target image does not match source after mirroring')
 
     # Tests that the insertion of the mirror_top filter node doesn't make a
@@ -177,12 +165,12 @@ class TestSingleDrive(iotests.QMPTestCase):
         self.assert_qmp(result, 'return', {})
 
         result = self.vm.qmp('query-block')
-        self.assert_qmp(result, 'return[0]/inserted/file', test_img)
+        self.assert_qmp(result, 'return[0]/inserted/file', self.test_img)
         self.assert_qmp(result, 'return[0]/inserted/drv', iotests.imgfmt)
-        self.assert_qmp(result, 'return[0]/inserted/backing_file', backing_img)
+        self.assert_qmp(result, 'return[0]/inserted/backing_file', self.backing_img)
         self.assert_qmp(result, 'return[0]/inserted/backing_file_depth', 1)
-        self.assert_qmp(result, 'return[0]/inserted/image/filename', test_img)
-        self.assert_qmp(result, 'return[0]/inserted/image/backing-image/filename', backing_img)
+        self.assert_qmp(result, 'return[0]/inserted/image/filename', self.test_img)
+        self.assert_qmp(result, 'return[0]/inserted/image/backing-image/filename', self.backing_img)
 
         result = self.vm.qmp('query-blockstats')
         self.assert_qmp(result, 'return[0]/node-name', 'top')
@@ -190,12 +178,12 @@ class TestSingleDrive(iotests.QMPTestCase):
 
         self.cancel_and_wait(force=True)
         result = self.vm.qmp('query-block')
-        self.assert_qmp(result, 'return[0]/inserted/file', test_img)
+        self.assert_qmp(result, 'return[0]/inserted/file', self.test_img)
         self.assert_qmp(result, 'return[0]/inserted/drv', iotests.imgfmt)
-        self.assert_qmp(result, 'return[0]/inserted/backing_file', backing_img)
+        self.assert_qmp(result, 'return[0]/inserted/backing_file', self.backing_img)
         self.assert_qmp(result, 'return[0]/inserted/backing_file_depth', 1)
-        self.assert_qmp(result, 'return[0]/inserted/image/filename', test_img)
-        self.assert_qmp(result, 'return[0]/inserted/image/backing-image/filename', backing_img)
+        self.assert_qmp(result, 'return[0]/inserted/image/filename', self.test_img)
+        self.assert_qmp(result, 'return[0]/inserted/image/backing-image/filename', self.backing_img)
 
         result = self.vm.qmp('query-blockstats')
         self.assert_qmp(result, 'return[0]/node-name', 'top')
@@ -223,14 +211,14 @@ class TestSingleDrive(iotests.QMPTestCase):
 
 class TestSingleBlockdev(TestSingleDrive):
     qmp_cmd = 'blockdev-mirror'
-    qmp_target = 'node1'
 
     def setUp(self):
         TestSingleDrive.setUp(self)
-        qemu_img('create', '-f', iotests.imgfmt, '-o', 'backing_file=%s' % backing_img, target_img)
+        self.qmp_target = 'node1'
+        qemu_img('create', '-f', iotests.imgfmt, '-o', 'backing_file=%s' % self.backing_img, self.target_img)
         args = {'driver': iotests.imgfmt,
                 'node-name': self.qmp_target,
-                'file': { 'filename': target_img, 'driver': 'file' } }
+                'file': { 'filename': self.target_img, 'driver': 'file' } }
         result = self.vm.qmp("blockdev-add", **args)
         self.assert_qmp(result, 'return', {})
 
@@ -256,51 +244,52 @@ class TestSingleBlockdevUnalignedLength(TestSingleBlockdev):
 
 class TestMirrorNoBacking(iotests.QMPTestCase):
     image_len = 2 * 1024 * 1024 # MB
+    target_backing_img = ""
+    backing_img = ""
+    test_img = ""
+    target_img = ""
 
     def setUp(self):
-        iotests.create_image(backing_img, TestMirrorNoBacking.image_len)
-        qemu_img('create', '-f', iotests.imgfmt, '-o', 'backing_file=%s' % backing_img, test_img)
-        self.vm = iotests.VM().add_drive(test_img)
+        self.target_backing_img = os.path.join(self.workdir, 'target-backing.img')
+        self.backing_img = os.path.join(self.workdir, 'backing.img')
+        self.test_img = os.path.join(self.workdir, 'test.img')
+        self.target_img = os.path.join(self.workdir, 'target.img')
+        iotests.create_image(self.backing_img, TestMirrorNoBacking.image_len)
+        qemu_img('create', '-f', iotests.imgfmt, '-o', 'backing_file=%s' % self.backing_img, self.test_img)
+        self.vm = iotests.VM().add_drive(self.test_img)
         self.vm.launch()
 
     def tearDown(self):
         self.vm.shutdown()
-        os.remove(test_img)
-        os.remove(backing_img)
-        try:
-            os.remove(target_backing_img)
-        except:
-            pass
-        os.remove(target_img)
 
     def test_complete(self):
         self.assert_no_active_block_jobs()
 
-        qemu_img('create', '-f', iotests.imgfmt, '-o', 'backing_file=%s' % backing_img, target_img)
+        qemu_img('create', '-f', iotests.imgfmt, '-o', 'backing_file=%s' % self.backing_img, self.target_img)
         result = self.vm.qmp('drive-mirror', device='drive0', sync='full',
-                             mode='existing', target=target_img)
+                             mode='existing', target=self.target_img)
         self.assert_qmp(result, 'return', {})
 
         self.complete_and_wait()
         result = self.vm.qmp('query-block')
-        self.assert_qmp(result, 'return[0]/inserted/file', target_img)
+        self.assert_qmp(result, 'return[0]/inserted/file', self.target_img)
         self.vm.shutdown()
-        self.assertTrue(iotests.compare_images(test_img, target_img),
+        self.assertTrue(iotests.compare_images(self.test_img, self.target_img),
                         'target image does not match source after mirroring')
 
     def test_cancel(self):
         self.assert_no_active_block_jobs()
 
-        qemu_img('create', '-f', iotests.imgfmt, '-o', 'backing_file=%s' % backing_img, target_img)
+        qemu_img('create', '-f', iotests.imgfmt, '-o', 'backing_file=%s' % self.backing_img, self.target_img)
         result = self.vm.qmp('drive-mirror', device='drive0', sync='full',
-                             mode='existing', target=target_img)
+                             mode='existing', target=self.target_img)
         self.assert_qmp(result, 'return', {})
 
         self.wait_ready_and_cancel()
         result = self.vm.qmp('query-block')
-        self.assert_qmp(result, 'return[0]/inserted/file', test_img)
+        self.assert_qmp(result, 'return[0]/inserted/file', self.test_img)
         self.vm.shutdown()
-        self.assertTrue(iotests.compare_images(test_img, target_img),
+        self.assertTrue(iotests.compare_images(self.test_img, self.target_img),
                         'target image does not match source after mirroring')
 
     def test_large_cluster(self):
@@ -308,67 +297,67 @@ class TestMirrorNoBacking(iotests.QMPTestCase):
 
         # qemu-img create fails if the image is not there
         qemu_img('create', '-f', iotests.imgfmt, '-o', 'size=%d'
-                        %(TestMirrorNoBacking.image_len), target_backing_img)
+                        %(TestMirrorNoBacking.image_len), self.target_backing_img)
         qemu_img('create', '-f', iotests.imgfmt, '-o', 'cluster_size=%d,backing_file=%s'
-                        % (TestMirrorNoBacking.image_len, target_backing_img), target_img)
+                        % (TestMirrorNoBacking.image_len, self.target_backing_img), self.target_img)
 
         result = self.vm.qmp('drive-mirror', device='drive0', sync='full',
-                             mode='existing', target=target_img)
+                             mode='existing', target=self.target_img)
         self.assert_qmp(result, 'return', {})
 
         self.complete_and_wait()
         result = self.vm.qmp('query-block')
-        self.assert_qmp(result, 'return[0]/inserted/file', target_img)
+        self.assert_qmp(result, 'return[0]/inserted/file', self.target_img)
         self.vm.shutdown()
-        self.assertTrue(iotests.compare_images(test_img, target_img),
+        self.assertTrue(iotests.compare_images(self.test_img, self.target_img),
                         'target image does not match source after mirroring')
 
 class TestMirrorResized(iotests.QMPTestCase):
     backing_len = 1 * 1024 * 1024 # MB
     image_len = 2 * 1024 * 1024 # MB
+    backing_img = ''
+    test_img = ''
+    target_img = ''
 
     def setUp(self):
-        iotests.create_image(backing_img, TestMirrorResized.backing_len)
-        qemu_img('create', '-f', iotests.imgfmt, '-o', 'backing_file=%s' % backing_img, test_img)
-        qemu_img('resize', test_img, '2M')
-        self.vm = iotests.VM().add_drive(test_img)
+        self.backing_img = os.path.join(self.workdir, 'backing.img')
+        self.test_img = os.path.join(self.workdir, 'test.img')
+        self.target_img = os.path.join(self.workdir, 'target.img')
+        iotests.create_image(self.backing_img, TestMirrorResized.backing_len)
+        qemu_img('create', '-f', iotests.imgfmt, '-o', 'backing_file=%s' % self.backing_img, self.test_img)
+        qemu_img('resize', self.test_img, '2M')
+        self.vm = iotests.VM().add_drive(self.test_img)
         self.vm.launch()
 
     def tearDown(self):
         self.vm.shutdown()
-        os.remove(test_img)
-        os.remove(backing_img)
-        try:
-            os.remove(target_img)
-        except OSError:
-            pass
 
     def test_complete_top(self):
         self.assert_no_active_block_jobs()
 
         result = self.vm.qmp('drive-mirror', device='drive0', sync='top',
-                             target=target_img)
+                             target=self.target_img)
         self.assert_qmp(result, 'return', {})
 
         self.complete_and_wait()
         result = self.vm.qmp('query-block')
-        self.assert_qmp(result, 'return[0]/inserted/file', target_img)
+        self.assert_qmp(result, 'return[0]/inserted/file', self.target_img)
         self.vm.shutdown()
-        self.assertTrue(iotests.compare_images(test_img, target_img),
+        self.assertTrue(iotests.compare_images(self.test_img, self.target_img),
                         'target image does not match source after mirroring')
 
     def test_complete_full(self):
         self.assert_no_active_block_jobs()
 
         result = self.vm.qmp('drive-mirror', device='drive0', sync='full',
-                             target=target_img)
+                             target=self.target_img)
         self.assert_qmp(result, 'return', {})
 
         self.complete_and_wait()
         result = self.vm.qmp('query-block')
-        self.assert_qmp(result, 'return[0]/inserted/file', target_img)
+        self.assert_qmp(result, 'return[0]/inserted/file', self.target_img)
         self.vm.shutdown()
-        self.assertTrue(iotests.compare_images(test_img, target_img),
+        self.assertTrue(iotests.compare_images(self.test_img, self.target_img),
                         'target image does not match source after mirroring')
 
 class TestReadErrors(iotests.QMPTestCase):
@@ -377,6 +366,9 @@ class TestReadErrors(iotests.QMPTestCase):
     # this should be a multiple of twice the default granularity
     # so that we hit this offset first in state 1
     MIRROR_GRANULARITY = 1024 * 1024
+    backing_img = ''
+    test_img = ''
+    target_img = ''
 
     def create_blkdebug_file(self, name, event, errno):
         file = open(name, 'w')
@@ -402,31 +394,30 @@ new_state = "1"
         file.close()
 
     def setUp(self):
-        self.blkdebug_file = backing_img + ".blkdebug"
-        iotests.create_image(backing_img, TestReadErrors.image_len)
+        self.backing_img = os.path.join(self.workdir, 'backing.img')
+        self.test_img = os.path.join(self.workdir, 'test.img')
+        self.target_img = os.path.join(self.workdir, 'target.img')
+        self.blkdebug_file = self.backing_img + ".blkdebug"
+        iotests.create_image(self.backing_img, TestReadErrors.image_len)
         self.create_blkdebug_file(self.blkdebug_file, "read_aio", 5)
         qemu_img('create', '-f', iotests.imgfmt,
                  '-o', 'backing_file=blkdebug:%s:%s,backing_fmt=raw'
-                       % (self.blkdebug_file, backing_img),
-                 test_img)
+                       % (self.blkdebug_file, self.backing_img),
+                 self.test_img)
         # Write something for tests that use sync='top'
         qemu_io('-c', 'write %d 512' % (self.MIRROR_GRANULARITY + 65536),
-                        test_img)
-        self.vm = iotests.VM().add_drive(test_img)
+                        self.test_img)
+        self.vm = iotests.VM().add_drive(self.test_img)
         self.vm.launch()
 
     def tearDown(self):
         self.vm.shutdown()
-        os.remove(test_img)
-        os.remove(target_img)
-        os.remove(backing_img)
-        os.remove(self.blkdebug_file)
 
     def test_report_read(self):
         self.assert_no_active_block_jobs()
 
         result = self.vm.qmp('drive-mirror', device='drive0', sync='full',
-                             target=target_img)
+                             target=self.target_img)
         self.assert_qmp(result, 'return', {})
 
         completed = False
@@ -453,7 +444,7 @@ new_state = "1"
         self.assert_no_active_block_jobs()
 
         result = self.vm.qmp('drive-mirror', device='drive0', sync='full',
-                             target=target_img, on_source_error='ignore')
+                             target=self.target_img, on_source_error='ignore')
         self.assert_qmp(result, 'return', {})
 
         event = self.vm.get_qmp_event(wait=True)
@@ -471,10 +462,10 @@ new_state = "1"
         # Test COW into the target image.  The first half of the
         # cluster at MIRROR_GRANULARITY has to be copied from
         # backing_img, even though sync='top'.
-        qemu_img('create', '-f', iotests.imgfmt, '-ocluster_size=131072,backing_file=%s' %(backing_img), target_img)
+        qemu_img('create', '-f', iotests.imgfmt, '-ocluster_size=131072,backing_file=%s' %(self.backing_img), self.target_img)
         result = self.vm.qmp('drive-mirror', device='drive0', sync='top',
                              on_source_error='ignore',
-                             mode='existing', target=target_img)
+                             mode='existing', target=self.target_img)
         self.assert_qmp(result, 'return', {})
 
         event = self.vm.get_qmp_event(wait=True)
@@ -487,15 +478,15 @@ new_state = "1"
         self.vm.shutdown()
 
         # Detach blkdebug to compare images successfully
-        qemu_img('rebase', '-f', iotests.imgfmt, '-u', '-b', backing_img, test_img)
-        self.assertTrue(iotests.compare_images(test_img, target_img),
+        qemu_img('rebase', '-f', iotests.imgfmt, '-u', '-b', self.backing_img, self.test_img)
+        self.assertTrue(iotests.compare_images(self.test_img, self.target_img),
                         'target image does not match source after mirroring')
 
     def test_stop_read(self):
         self.assert_no_active_block_jobs()
 
         result = self.vm.qmp('drive-mirror', device='drive0', sync='full',
-                             target=target_img, on_source_error='stop')
+                             target=self.target_img, on_source_error='stop')
         self.assert_qmp(result, 'return', {})
 
         error = False
@@ -557,27 +548,26 @@ new_state = "1"
         file.close()
 
     def setUp(self):
-        self.blkdebug_file = target_img + ".blkdebug"
-        iotests.create_image(backing_img, TestWriteErrors.image_len)
+        self.backing_img = os.path.join(self.workdir, 'backing.img')
+        self.test_img = os.path.join(self.workdir, 'test.img')
+        self.target_img = os.path.join(self.workdir, 'target.img')
+        self.blkdebug_file = self.target_img + ".blkdebug"
+        iotests.create_image(self.backing_img, TestWriteErrors.image_len)
         self.create_blkdebug_file(self.blkdebug_file, "write_aio", 5)
-        qemu_img('create', '-f', iotests.imgfmt, '-obacking_file=%s' %(backing_img), test_img)
-        self.vm = iotests.VM().add_drive(test_img)
-        self.target_img = 'blkdebug:%s:%s' % (self.blkdebug_file, target_img)
-        qemu_img('create', '-f', iotests.imgfmt, '-osize=%d' %(TestWriteErrors.image_len), target_img)
+        qemu_img('create', '-f', iotests.imgfmt, '-obacking_file=%s' %(self.backing_img), self.test_img)
+        self.vm = iotests.VM().add_drive(self.test_img)
+        self.blkdebug_target_img = 'blkdebug:%s:%s' % (self.blkdebug_file, self.target_img)
+        qemu_img('create', '-f', iotests.imgfmt, '-osize=%d' %(TestWriteErrors.image_len), self.target_img)
         self.vm.launch()
 
     def tearDown(self):
         self.vm.shutdown()
-        os.remove(test_img)
-        os.remove(target_img)
-        os.remove(backing_img)
-        os.remove(self.blkdebug_file)
 
     def test_report_write(self):
         self.assert_no_active_block_jobs()
 
         result = self.vm.qmp('drive-mirror', device='drive0', sync='full',
-                             mode='existing', target=self.target_img)
+                             mode='existing', target=self.blkdebug_target_img)
         self.assert_qmp(result, 'return', {})
 
         completed = False
@@ -604,7 +594,7 @@ new_state = "1"
         self.assert_no_active_block_jobs()
 
         result = self.vm.qmp('drive-mirror', device='drive0', sync='full',
-                             mode='existing', target=self.target_img,
+                             mode='existing', target=self.blkdebug_target_img,
                              on_target_error='ignore')
         self.assert_qmp(result, 'return', {})
 
@@ -621,7 +611,7 @@ new_state = "1"
         self.assert_no_active_block_jobs()
 
         result = self.vm.qmp('drive-mirror', device='drive0', sync='full',
-                             mode='existing', target=self.target_img,
+                             mode='existing', target=self.blkdebug_target_img,
                              on_target_error='stop')
         self.assert_qmp(result, 'return', {})
 
@@ -655,24 +645,27 @@ new_state = "1"
 
 class TestSetSpeed(iotests.QMPTestCase):
     image_len = 80 * 1024 * 1024 # MB
+    backing_img = ''
+    test_img = ''
+    target_img = ''
 
     def setUp(self):
-        qemu_img('create', backing_img, str(TestSetSpeed.image_len))
-        qemu_img('create', '-f', iotests.imgfmt, '-o', 'backing_file=%s' % backing_img, test_img)
-        self.vm = iotests.VM().add_drive(test_img)
+        self.backing_img = os.path.join(self.workdir, 'backing.img')
+        self.test_img = os.path.join(self.workdir, 'test.img')
+        self.target_img = os.path.join(self.workdir, 'target.img')
+        qemu_img('create', self.backing_img, str(TestSetSpeed.image_len))
+        qemu_img('create', '-f', iotests.imgfmt, '-o', 'backing_file=%s' % self.backing_img, self.test_img)
+        self.vm = iotests.VM().add_drive(self.test_img)
         self.vm.launch()
 
     def tearDown(self):
         self.vm.shutdown()
-        os.remove(test_img)
-        os.remove(backing_img)
-        os.remove(target_img)
 
     def test_set_speed(self):
         self.assert_no_active_block_jobs()
 
         result = self.vm.qmp('drive-mirror', device='drive0', sync='full',
-                             target=target_img)
+                             target=self.target_img)
         self.assert_qmp(result, 'return', {})
 
         # Default speed is 0
@@ -692,7 +685,7 @@ class TestSetSpeed(iotests.QMPTestCase):
 
         # Check setting speed in drive-mirror works
         result = self.vm.qmp('drive-mirror', device='drive0', sync='full',
-                             target=target_img, speed=4*1024*1024)
+                             target=self.target_img, speed=4*1024*1024)
         self.assert_qmp(result, 'return', {})
 
         result = self.vm.qmp('query-block-jobs')
@@ -705,13 +698,13 @@ class TestSetSpeed(iotests.QMPTestCase):
         self.assert_no_active_block_jobs()
 
         result = self.vm.qmp('drive-mirror', device='drive0', sync='full',
-                             target=target_img, speed=-1)
+                             target=self.target_img, speed=-1)
         self.assert_qmp(result, 'error/class', 'GenericError')
 
         self.assert_no_active_block_jobs()
 
         result = self.vm.qmp('drive-mirror', device='drive0', sync='full',
-                             target=target_img)
+                             target=self.target_img)
         self.assert_qmp(result, 'return', {})
 
         result = self.vm.qmp('block-job-set-speed', device='drive0', speed=-1)
@@ -721,22 +714,24 @@ class TestSetSpeed(iotests.QMPTestCase):
 
 class TestUnbackedSource(iotests.QMPTestCase):
     image_len = 2 * 1024 * 1024 # MB
+    test_img = ''
+    target_img = ''
 
     def setUp(self):
-        qemu_img('create', '-f', iotests.imgfmt, test_img,
+        self.test_img = os.path.join(self.workdir, 'test.img')
+        self.target_img = os.path.join(self.workdir, 'target.img')
+        qemu_img('create', '-f', iotests.imgfmt, self.test_img,
                  str(TestUnbackedSource.image_len))
-        self.vm = iotests.VM().add_drive(test_img)
+        self.vm = iotests.VM().add_drive(self.test_img)
         self.vm.launch()
 
     def tearDown(self):
         self.vm.shutdown()
-        os.remove(test_img)
-        os.remove(target_img)
 
     def test_absolute_paths_full(self):
         self.assert_no_active_block_jobs()
         result = self.vm.qmp('drive-mirror', device='drive0',
-                             sync='full', target=target_img,
+                             sync='full', target=self.target_img,
                              mode='absolute-paths')
         self.assert_qmp(result, 'return', {})
         self.complete_and_wait()
@@ -745,7 +740,7 @@ class TestUnbackedSource(iotests.QMPTestCase):
     def test_absolute_paths_top(self):
         self.assert_no_active_block_jobs()
         result = self.vm.qmp('drive-mirror', device='drive0',
-                             sync='top', target=target_img,
+                             sync='top', target=self.target_img,
                              mode='absolute-paths')
         self.assert_qmp(result, 'return', {})
         self.complete_and_wait()
@@ -754,7 +749,7 @@ class TestUnbackedSource(iotests.QMPTestCase):
     def test_absolute_paths_none(self):
         self.assert_no_active_block_jobs()
         result = self.vm.qmp('drive-mirror', device='drive0',
-                             sync='none', target=target_img,
+                             sync='none', target=self.target_img,
                              mode='absolute-paths')
         self.assert_qmp(result, 'return', {})
         self.complete_and_wait()
@@ -762,26 +757,28 @@ class TestUnbackedSource(iotests.QMPTestCase):
 
 class TestGranularity(iotests.QMPTestCase):
     image_len = 10 * 1024 * 1024 # MB
+    test_img = ''
+    target_img = ''
 
     def setUp(self):
-        qemu_img('create', '-f', iotests.imgfmt, test_img,
+        self.test_img = os.path.join(self.workdir, 'test.img')
+        self.target_img = os.path.join(self.workdir, 'target.img')
+        qemu_img('create', '-f', iotests.imgfmt, self.test_img,
                  str(TestGranularity.image_len))
         qemu_io('-c', 'write 0 %d' % (self.image_len),
-                test_img)
-        self.vm = iotests.VM().add_drive(test_img)
+                self.test_img)
+        self.vm = iotests.VM().add_drive(self.test_img)
         self.vm.launch()
 
     def tearDown(self):
         self.vm.shutdown()
-        self.assertTrue(iotests.compare_images(test_img, target_img),
+        self.assertTrue(iotests.compare_images(self.test_img, self.target_img),
                         'target image does not match source after mirroring')
-        os.remove(test_img)
-        os.remove(target_img)
 
     def test_granularity(self):
         self.assert_no_active_block_jobs()
         result = self.vm.qmp('drive-mirror', device='drive0',
-                             sync='full', target=target_img,
+                             sync='full', target=self.target_img,
                              mode='absolute-paths', granularity=8192)
         self.assert_qmp(result, 'return', {})
         event = self.vm.get_qmp_event(wait=60.0)
@@ -794,9 +791,21 @@ class TestRepairQuorum(iotests.QMPTestCase):
     """ This class test quorum file repair using drive-mirror.
         It's mostly a fork of TestSingleDrive """
     image_len = 1 * 1024 * 1024 # MB
-    IMAGES = [ quorum_img1, quorum_img2, quorum_img3 ]
+    quorum_img1 = ''
+    quorum_img2 = ''
+    quorum_img3 = ''
+    quroum_repair_img = ''
+    quorum_snapshot_file = ''
+
+    IMAGES = [ ]
 
     def setUp(self):
+        self.quorum_img1 = os.path.join(self.workdir, 'quorum1.img')
+        self.quorum_img2 = os.path.join(self.workdir, 'quorum2.img')
+        self.quorum_img3 = os.path.join(self.workdir, 'quorum3.img')
+        self.quorum_repair_img = os.path.join(self.workdir, 'quorum_repair.img')
+        self.quorum_snapshot_file = os.path.join(self.workdir, 'quorum_snapshot.img')
+        self.IMAGES = [ self.quorum_img1, self.quorum_img2, self.quorum_img3 ]
         self.vm = iotests.VM()
 
         if iotests.qemu_default_machine == 'pc':
@@ -823,12 +832,6 @@ class TestRepairQuorum(iotests.QMPTestCase):
 
     def tearDown(self):
         self.vm.shutdown()
-        for i in self.IMAGES + [ quorum_repair_img, quorum_snapshot_file ]:
-            # Do a try/except because the test may have deleted some images
-            try:
-                os.remove(i)
-            except OSError:
-                pass
 
     def test_complete(self):
         if not iotests.supports_quorum():
@@ -838,15 +841,15 @@ class TestRepairQuorum(iotests.QMPTestCase):
 
         result = self.vm.qmp('drive-mirror', job_id='job0', device='quorum0',
                              sync='full', node_name="repair0", replaces="img1",
-                             target=quorum_repair_img, format=iotests.imgfmt)
+                             target=self.quorum_repair_img, format=iotests.imgfmt)
         self.assert_qmp(result, 'return', {})
 
         self.complete_and_wait(drive="job0")
-        self.assert_has_block_node("repair0", quorum_repair_img)
+        self.assert_has_block_node("repair0", self.quorum_repair_img)
         # TODO: a better test requiring some QEMU infrastructure will be added
         #       to check that this file is really driven by quorum
         self.vm.shutdown()
-        self.assertTrue(iotests.compare_images(quorum_img2, quorum_repair_img),
+        self.assertTrue(iotests.compare_images(self.quorum_img2, self.quorum_repair_img),
                         'target image does not match source after mirroring')
 
     def test_cancel(self):
@@ -857,13 +860,13 @@ class TestRepairQuorum(iotests.QMPTestCase):
 
         result = self.vm.qmp('drive-mirror', job_id='job0', device='quorum0',
                              sync='full', node_name="repair0", replaces="img1",
-                             target=quorum_repair_img, format=iotests.imgfmt)
+                             target=self.quorum_repair_img, format=iotests.imgfmt)
         self.assert_qmp(result, 'return', {})
 
         self.cancel_and_wait(drive="job0", force=True)
         # here we check that the last registered quorum file has not been
         # swapped out and unref
-        self.assert_has_block_node(None, quorum_img3)
+        self.assert_has_block_node(None, self.quorum_img3)
         self.vm.shutdown()
 
     def test_cancel_after_ready(self):
@@ -874,15 +877,15 @@ class TestRepairQuorum(iotests.QMPTestCase):
 
         result = self.vm.qmp('drive-mirror', job_id='job0', device='quorum0',
                              sync='full', node_name="repair0", replaces="img1",
-                             target=quorum_repair_img, format=iotests.imgfmt)
+                             target=self.quorum_repair_img, format=iotests.imgfmt)
         self.assert_qmp(result, 'return', {})
 
         self.wait_ready_and_cancel(drive="job0")
         # here we check that the last registered quorum file has not been
         # swapped out and unref
-        self.assert_has_block_node(None, quorum_img3)
+        self.assert_has_block_node(None, self.quorum_img3)
         self.vm.shutdown()
-        self.assertTrue(iotests.compare_images(quorum_img2, quorum_repair_img),
+        self.assertTrue(iotests.compare_images(self.quorum_img2, self.quorum_repair_img),
                         'target image does not match source after mirroring')
 
     def test_pause(self):
@@ -893,7 +896,7 @@ class TestRepairQuorum(iotests.QMPTestCase):
 
         result = self.vm.qmp('drive-mirror', job_id='job0', device='quorum0',
                              sync='full', node_name="repair0", replaces="img1",
-                             target=quorum_repair_img, format=iotests.imgfmt)
+                             target=self.quorum_repair_img, format=iotests.imgfmt)
         self.assert_qmp(result, 'return', {})
 
         self.pause_job('job0')
@@ -910,7 +913,7 @@ class TestRepairQuorum(iotests.QMPTestCase):
 
         self.complete_and_wait(drive="job0")
         self.vm.shutdown()
-        self.assertTrue(iotests.compare_images(quorum_img2, quorum_repair_img),
+        self.assertTrue(iotests.compare_images(self.quorum_img2, self.quorum_repair_img),
                         'target image does not match source after mirroring')
 
     def test_medium_not_found(self):
@@ -924,7 +927,7 @@ class TestRepairQuorum(iotests.QMPTestCase):
                              sync='full',
                              node_name='repair0',
                              replaces='img1',
-                             target=quorum_repair_img, format=iotests.imgfmt)
+                             target=self.quorum_repair_img, format=iotests.imgfmt)
         self.assert_qmp(result, 'error/class', 'GenericError')
 
     def test_image_not_found(self):
@@ -933,7 +936,7 @@ class TestRepairQuorum(iotests.QMPTestCase):
 
         result = self.vm.qmp('drive-mirror', job_id='job0', device='quorum0',
                              sync='full', node_name='repair0', replaces='img1',
-                             mode='existing', target=quorum_repair_img,
+                             mode='existing', target=self.quorum_repair_img,
                              format=iotests.imgfmt)
         self.assert_qmp(result, 'error/class', 'GenericError')
 
@@ -945,7 +948,7 @@ class TestRepairQuorum(iotests.QMPTestCase):
                              device='nonexistent', sync='full',
                              node_name='repair0',
                              replaces='img1',
-                             target=quorum_repair_img, format=iotests.imgfmt)
+                             target=self.quorum_repair_img, format=iotests.imgfmt)
         self.assert_qmp(result, 'error/class', 'GenericError')
 
     def test_wrong_sync_mode(self):
@@ -955,7 +958,7 @@ class TestRepairQuorum(iotests.QMPTestCase):
         result = self.vm.qmp('drive-mirror', device='quorum0', job_id='job0',
                              node_name='repair0',
                              replaces='img1',
-                             target=quorum_repair_img, format=iotests.imgfmt)
+                             target=self.quorum_repair_img, format=iotests.imgfmt)
         self.assert_qmp(result, 'error/class', 'GenericError')
 
     def test_no_node_name(self):
@@ -964,7 +967,7 @@ class TestRepairQuorum(iotests.QMPTestCase):
 
         result = self.vm.qmp('drive-mirror', job_id='job0', device='quorum0',
                              sync='full', replaces='img1',
-                             target=quorum_repair_img, format=iotests.imgfmt)
+                             target=self.quorum_repair_img, format=iotests.imgfmt)
         self.assert_qmp(result, 'error/class', 'GenericError')
 
     def test_nonexistent_replaces(self):
@@ -973,7 +976,7 @@ class TestRepairQuorum(iotests.QMPTestCase):
 
         result = self.vm.qmp('drive-mirror', job_id='job0', device='quorum0',
                              sync='full', node_name='repair0', replaces='img77',
-                             target=quorum_repair_img, format=iotests.imgfmt)
+                             target=self.quorum_repair_img, format=iotests.imgfmt)
         self.assert_qmp(result, 'error/class', 'GenericError')
 
     def test_after_a_quorum_snapshot(self):
@@ -981,21 +984,21 @@ class TestRepairQuorum(iotests.QMPTestCase):
             return
 
         result = self.vm.qmp('blockdev-snapshot-sync', node_name='img1',
-                             snapshot_file=quorum_snapshot_file,
+                             snapshot_file=self.quorum_snapshot_file,
                              snapshot_node_name="snap1");
 
         result = self.vm.qmp('drive-mirror', job_id='job0', device='quorum0',
                              sync='full', node_name='repair0', replaces="img1",
-                             target=quorum_repair_img, format=iotests.imgfmt)
+                             target=self.quorum_repair_img, format=iotests.imgfmt)
         self.assert_qmp(result, 'error/class', 'GenericError')
 
         result = self.vm.qmp('drive-mirror', job_id='job0', device='quorum0',
                              sync='full', node_name='repair0', replaces="snap1",
-                             target=quorum_repair_img, format=iotests.imgfmt)
+                             target=self.quorum_repair_img, format=iotests.imgfmt)
         self.assert_qmp(result, 'return', {})
 
         self.complete_and_wait('job0')
-        self.assert_has_block_node("repair0", quorum_repair_img)
+        self.assert_has_block_node("repair0", self.quorum_repair_img)
         # TODO: a better test requiring some QEMU infrastructure will be added
         #       to check that this file is really driven by quorum
         self.vm.shutdown()
diff --git a/tests/qemu-iotests/044 b/tests/qemu-iotests/044
index 11ea0f4..c051250 100755
--- a/tests/qemu-iotests/044
+++ b/tests/qemu-iotests/044
@@ -27,7 +27,6 @@ from iotests import qemu_img, qemu_img_verbose, qemu_io
 import struct
 import subprocess
 
-test_img = os.path.join(iotests.test_dir, 'test.img')
 
 class TestRefcountTableGrowth(iotests.QMPTestCase):
     '''Abstract base class for image mirroring test cases'''
@@ -99,18 +98,18 @@ class TestRefcountTableGrowth(iotests.QMPTestCase):
 
 
     def setUp(self):
-        qemu_img('create', '-f', iotests.imgfmt, '-o', 'cluster_size=512', test_img, '16G')
-        self.preallocate(test_img)
+        self.test_img = os.path.join(self.workdir, 'test.img')
+        qemu_img('create', '-f', iotests.imgfmt, '-o', 'cluster_size=512', self.test_img, '16G')
+        self.preallocate(self.test_img)
         pass
 
 
     def tearDown(self):
-        os.remove(test_img)
         pass
 
     def test_grow_refcount_table(self):
-        qemu_io('-c', 'write 3800M 1M', test_img)
-        qemu_img_verbose('check' , test_img)
+        qemu_io('-c', 'write 3800M 1M', self.test_img)
+        qemu_img_verbose('check' , self.test_img)
         pass
 
 if __name__ == '__main__':
diff --git a/tests/qemu-iotests/045 b/tests/qemu-iotests/045
index 6be8fc4..3f025b9 100755
--- a/tests/qemu-iotests/045
+++ b/tests/qemu-iotests/045
@@ -22,26 +22,25 @@ import os
 import iotests
 from iotests import qemu_img
 
-image0 = os.path.join(iotests.test_dir, 'image0')
-image1 = os.path.join(iotests.test_dir, 'image1')
-image2 = os.path.join(iotests.test_dir, 'image2')
-image3 = os.path.join(iotests.test_dir, 'image3')
-image4 = os.path.join(iotests.test_dir, 'image4')
-
 class TestFdSets(iotests.QMPTestCase):
 
     def setUp(self):
+        self.image0 = os.path.join(self.workdir, 'image0')
+        self.image1 = os.path.join(self.workdir, 'image1')
+        self.image2 = os.path.join(self.workdir, 'image2')
+        self.image3 = os.path.join(self.workdir, 'image3')
+        self.image4 = os.path.join(self.workdir, 'image4')
         self.vm = iotests.VM()
-        qemu_img('create', '-f', iotests.imgfmt, image0, '128K')
-        qemu_img('create', '-f', iotests.imgfmt, image1, '128K')
-        qemu_img('create', '-f', iotests.imgfmt, image2, '128K')
-        qemu_img('create', '-f', iotests.imgfmt, image3, '128K')
-        qemu_img('create', '-f', iotests.imgfmt, image4, '128K')
-        self.file0 = open(image0, 'r')
-        self.file1 = open(image1, 'w+')
-        self.file2 = open(image2, 'r')
-        self.file3 = open(image3, 'r')
-        self.file4 = open(image4, 'r')
+        qemu_img('create', '-f', iotests.imgfmt, self.image0, '128K')
+        qemu_img('create', '-f', iotests.imgfmt, self.image1, '128K')
+        qemu_img('create', '-f', iotests.imgfmt, self.image2, '128K')
+        qemu_img('create', '-f', iotests.imgfmt, self.image3, '128K')
+        qemu_img('create', '-f', iotests.imgfmt, self.image4, '128K')
+        self.file0 = open(self.image0, 'r')
+        self.file1 = open(self.image1, 'w+')
+        self.file2 = open(self.image2, 'r')
+        self.file3 = open(self.image3, 'r')
+        self.file4 = open(self.image4, 'r')
         self.vm.add_fd(self.file0.fileno(), 1, 'image0:r')
         self.vm.add_fd(self.file1.fileno(), 1, 'image1:w+')
         self.vm.add_fd(self.file2.fileno(), 0, 'image2:r')
@@ -57,11 +56,6 @@ class TestFdSets(iotests.QMPTestCase):
         self.file2.close()
         self.file3.close()
         self.file4.close()
-        os.remove(image0)
-        os.remove(image1)
-        os.remove(image2)
-        os.remove(image3)
-        os.remove(image4)
 
     def test_query_fdset(self):
         result = self.vm.qmp('query-fdsets')
@@ -128,8 +122,9 @@ class TestFdSets(iotests.QMPTestCase):
 # Add fd at runtime, there are two ways: monitor related or fdset related
 class TestSCMFd(iotests.QMPTestCase):
     def setUp(self):
+        self.image0 = os.path.join(self.workdir, 'image0')
         self.vm = iotests.VM()
-        qemu_img('create', '-f', iotests.imgfmt, image0, '128K')
+        qemu_img('create', '-f', iotests.imgfmt, self.image0, '128K')
         # Add an unused monitor, to verify it works fine when two monitor
         # instances present
         self.vm.add_monitor_telnet("0",4445)
@@ -137,10 +132,9 @@ class TestSCMFd(iotests.QMPTestCase):
 
     def tearDown(self):
         self.vm.shutdown()
-        os.remove(image0)
 
     def _send_fd_by_SCM(self):
-        ret = self.vm.send_fd_scm(image0)
+        ret = self.vm.send_fd_scm(self.image0)
         self.assertEqual(ret, 0, 'Failed to send fd with UNIX SCM')
 
     def test_add_fd(self):
diff --git a/tests/qemu-iotests/055 b/tests/qemu-iotests/055
index e1206ca..4527ecf 100755
--- a/tests/qemu-iotests/055
+++ b/tests/qemu-iotests/055
@@ -26,8 +26,6 @@ import iotests
 from iotests import qemu_img, qemu_io
 
 test_img = os.path.join(iotests.test_dir, 'test.img')
-target_img = os.path.join(iotests.test_dir, 'target.img')
-blockdev_target_img = os.path.join(iotests.test_dir, 'blockdev-target.img')
 
 image_len = 64 * 1024 * 1024 # MB
 
@@ -40,27 +38,23 @@ def setUpModule():
     qemu_io('-f', iotests.imgfmt, '-c', 'write -P0xdc 32M 124k', test_img)
     qemu_io('-f', iotests.imgfmt, '-c', 'write -P0x33 67043328 64k', test_img)
 
-def tearDownModule():
-    os.remove(test_img)
 
 
 class TestSingleDrive(iotests.QMPTestCase):
     def setUp(self):
-        qemu_img('create', '-f', iotests.imgfmt, blockdev_target_img, str(image_len))
+        self.target_img = os.path.join(self.workdir, 'target.img')
+        self.blockdev_target_img = os.path.join(self.workdir, 'blockdev-target.img')
+        qemu_img('create', '-f', iotests.imgfmt, self.blockdev_target_img, str(image_len))
 
         self.vm = iotests.VM().add_drive(test_img)
-        self.vm.add_drive(blockdev_target_img, interface="none")
+        self.vm.add_drive(self.blockdev_target_img, interface="none")
         if iotests.qemu_default_machine == 'pc':
             self.vm.add_drive(None, 'media=cdrom', 'ide')
         self.vm.launch()
 
     def tearDown(self):
         self.vm.shutdown()
-        os.remove(blockdev_target_img)
-        try:
-            os.remove(target_img)
-        except OSError:
-            pass
+        pass
 
     def do_test_cancel(self, cmd, target):
         self.assert_no_active_block_jobs()
@@ -72,7 +66,7 @@ class TestSingleDrive(iotests.QMPTestCase):
         self.assert_qmp(event, 'data/type', 'backup')
 
     def test_cancel_drive_backup(self):
-        self.do_test_cancel('drive-backup', target_img)
+        self.do_test_cancel('drive-backup', self.target_img)
 
     def test_cancel_blockdev_backup(self):
         self.do_test_cancel('blockdev-backup', 'drive1')
@@ -108,17 +102,17 @@ class TestSingleDrive(iotests.QMPTestCase):
                         'target image does not match source after backup')
 
     def test_pause_drive_backup(self):
-        self.do_test_pause('drive-backup', target_img, target_img)
+        self.do_test_pause('drive-backup', self.target_img, self.target_img)
 
     def test_pause_blockdev_backup(self):
-        self.do_test_pause('blockdev-backup', 'drive1', blockdev_target_img)
+        self.do_test_pause('blockdev-backup', 'drive1', self.blockdev_target_img)
 
     def test_medium_not_found(self):
         if iotests.qemu_default_machine != 'pc':
             return
 
         result = self.vm.qmp('drive-backup', device='drive2', # CD-ROM
-                             target=target_img, sync='full')
+                             target=self.target_img, sync='full')
         self.assert_qmp(result, 'error/class', 'GenericError')
 
     def test_medium_not_found_blockdev_backup(self):
@@ -131,12 +125,12 @@ class TestSingleDrive(iotests.QMPTestCase):
 
     def test_image_not_found(self):
         result = self.vm.qmp('drive-backup', device='drive0',
-                             target=target_img, sync='full', mode='existing')
+                             target=self.target_img, sync='full', mode='existing')
         self.assert_qmp(result, 'error/class', 'GenericError')
 
     def test_invalid_format(self):
         result = self.vm.qmp('drive-backup', device='drive0',
-                             target=target_img, sync='full',
+                             target=self.target_img, sync='full',
                              format='spaghetti-noodles')
         self.assert_qmp(result, 'error/class', 'GenericError')
 
@@ -146,7 +140,7 @@ class TestSingleDrive(iotests.QMPTestCase):
 
     def test_device_not_found(self):
         self.do_test_device_not_found('drive-backup', device='nonexistent',
-                                      target=target_img, sync='full')
+                                      target=self.target_img, sync='full')
 
         self.do_test_device_not_found('blockdev-backup', device='nonexistent',
                                       target='drive0', sync='full')
@@ -164,19 +158,17 @@ class TestSingleDrive(iotests.QMPTestCase):
 
 class TestSetSpeed(iotests.QMPTestCase):
     def setUp(self):
-        qemu_img('create', '-f', iotests.imgfmt, blockdev_target_img, str(image_len))
+        self.target_img = os.path.join(self.workdir, 'target.img')
+        self.blockdev_target_img = os.path.join(self.workdir, 'blockdev-target.img')
+        qemu_img('create', '-f', iotests.imgfmt, self.blockdev_target_img, str(image_len))
 
         self.vm = iotests.VM().add_drive(test_img)
-        self.vm.add_drive(blockdev_target_img, interface="none")
+        self.vm.add_drive(self.blockdev_target_img, interface="none")
         self.vm.launch()
 
     def tearDown(self):
         self.vm.shutdown()
-        os.remove(blockdev_target_img)
-        try:
-            os.remove(target_img)
-        except OSError:
-            pass
+        pass
 
     def do_test_set_speed(self, cmd, target):
         self.assert_no_active_block_jobs()
@@ -215,7 +207,7 @@ class TestSetSpeed(iotests.QMPTestCase):
         self.assert_qmp(event, 'data/type', 'backup')
 
     def test_set_speed_drive_backup(self):
-        self.do_test_set_speed('drive-backup', target_img)
+        self.do_test_set_speed('drive-backup', self.target_img)
 
     def test_set_speed_blockdev_backup(self):
         self.do_test_set_speed('blockdev-backup', 'drive1')
@@ -241,28 +233,27 @@ class TestSetSpeed(iotests.QMPTestCase):
         self.assert_qmp(event, 'data/type', 'backup')
 
     def test_set_speed_invalid_drive_backup(self):
-        self.do_test_set_speed_invalid('drive-backup', target_img)
+        self.do_test_set_speed_invalid('drive-backup', self.target_img)
 
     def test_set_speed_invalid_blockdev_backup(self):
         self.do_test_set_speed_invalid('blockdev-backup',  'drive1')
 
 class TestSingleTransaction(iotests.QMPTestCase):
+
     def setUp(self):
-        qemu_img('create', '-f', iotests.imgfmt, blockdev_target_img, str(image_len))
+        self.target_img = os.path.join(self.workdir, 'target.img')
+        self.blockdev_target_img = os.path.join(self.workdir, 'blockdev-target.img')
+        qemu_img('create', '-f', iotests.imgfmt, self.blockdev_target_img, str(image_len))
 
         self.vm = iotests.VM().add_drive(test_img)
-        self.vm.add_drive(blockdev_target_img, interface="none")
+        self.vm.add_drive(self.blockdev_target_img, interface="none")
         if iotests.qemu_default_machine == 'pc':
             self.vm.add_drive(None, 'media=cdrom', 'ide')
         self.vm.launch()
 
     def tearDown(self):
         self.vm.shutdown()
-        os.remove(blockdev_target_img)
-        try:
-            os.remove(target_img)
-        except OSError:
-            pass
+        pass
 
     def do_test_cancel(self, cmd, target):
         self.assert_no_active_block_jobs()
@@ -281,7 +272,7 @@ class TestSingleTransaction(iotests.QMPTestCase):
         self.assert_qmp(event, 'data/type', 'backup')
 
     def test_cancel_drive_backup(self):
-        self.do_test_cancel('drive-backup', target_img)
+        self.do_test_cancel('drive-backup', self.target_img)
 
     def test_cancel_blockdev_backup(self):
         self.do_test_cancel('blockdev-backup', 'drive1')
@@ -322,10 +313,10 @@ class TestSingleTransaction(iotests.QMPTestCase):
                         'target image does not match source after backup')
 
     def test_pause_drive_backup(self):
-        self.do_test_pause('drive-backup', target_img, target_img)
+        self.do_test_pause('drive-backup', self.target_img, self.target_img)
 
     def test_pause_blockdev_backup(self):
-        self.do_test_pause('blockdev-backup', 'drive1', blockdev_target_img)
+        self.do_test_pause('blockdev-backup', 'drive1', self.blockdev_target_img)
 
     def do_test_medium_not_found(self, cmd, target):
         if iotests.qemu_default_machine != 'pc':
@@ -341,7 +332,7 @@ class TestSingleTransaction(iotests.QMPTestCase):
         self.assert_qmp(result, 'error/class', 'GenericError')
 
     def test_medium_not_found_drive_backup(self):
-        self.do_test_medium_not_found('drive-backup', target_img)
+        self.do_test_medium_not_found('drive-backup', self.target_img)
 
     def test_medium_not_found_blockdev_backup(self):
         self.do_test_medium_not_found('blockdev-backup', 'drive1')
@@ -351,7 +342,7 @@ class TestSingleTransaction(iotests.QMPTestCase):
                 'type': 'drive-backup',
                 'data': { 'device': 'drive0',
                           'mode': 'existing',
-                          'target': target_img,
+                          'target': self.target_img,
                           'sync': 'full' },
             }
         ])
@@ -362,7 +353,7 @@ class TestSingleTransaction(iotests.QMPTestCase):
                 'type': 'drive-backup',
                 'data': { 'device': 'nonexistent',
                           'mode': 'existing',
-                          'target': target_img,
+                          'target': self.target_img,
                           'sync': 'full' },
             }
         ])
@@ -410,7 +401,7 @@ class TestSingleTransaction(iotests.QMPTestCase):
                 'type': 'drive-backup',
                 'data': { 'device': 'nonexistent',
                           'mode': 'existing',
-                          'target': target_img,
+                          'target': self.target_img,
                           'sync': 'full' },
             }, {
                 'type': 'Abort',
@@ -452,21 +443,21 @@ class TestDriveCompression(iotests.QMPTestCase):
     fmt_supports_compression = [{'type': 'qcow2', 'args': ()},
                                 {'type': 'vmdk', 'args': ('-o', 'subformat=streamOptimized')}]
 
+    def setUp(self):
+        self.target_img = os.path.join(self.workdir, 'target.img')
+        self.blockdev_target_img = os.path.join(self.workdir, 'blockdev-target.img')
+
     def tearDown(self):
         self.vm.shutdown()
-        os.remove(blockdev_target_img)
-        try:
-            os.remove(target_img)
-        except OSError:
-            pass
+        pass
 
     def do_prepare_drives(self, fmt, args, attach_target):
         self.vm = iotests.VM().add_drive(test_img)
 
-        qemu_img('create', '-f', fmt, blockdev_target_img,
+        qemu_img('create', '-f', fmt, self.blockdev_target_img,
                  str(TestDriveCompression.image_len), *args)
         if attach_target:
-            self.vm.add_drive(blockdev_target_img, format=fmt, interface="none")
+            self.vm.add_drive(self.blockdev_target_img, format=fmt, interface="none")
 
         self.vm.launch()
 
@@ -481,14 +472,14 @@ class TestDriveCompression(iotests.QMPTestCase):
         self.wait_until_completed()
 
         self.vm.shutdown()
-        self.assertTrue(iotests.compare_images(test_img, blockdev_target_img,
+        self.assertTrue(iotests.compare_images(test_img, self.blockdev_target_img,
                                                iotests.imgfmt, format['type']),
                         'target image does not match source after backup')
 
     def test_complete_compress_drive_backup(self):
         for format in TestDriveCompression.fmt_supports_compression:
             self.do_test_compress_complete('drive-backup', format, False,
-                                           target=blockdev_target_img, mode='existing')
+                                           target=self.blockdev_target_img, mode='existing')
 
     def test_complete_compress_blockdev_backup(self):
         for format in TestDriveCompression.fmt_supports_compression:
@@ -511,7 +502,7 @@ class TestDriveCompression(iotests.QMPTestCase):
     def test_compress_cancel_drive_backup(self):
         for format in TestDriveCompression.fmt_supports_compression:
             self.do_test_compress_cancel('drive-backup', format, False,
-                                         target=blockdev_target_img, mode='existing')
+                                         target=self.blockdev_target_img, mode='existing')
 
     def test_compress_cancel_blockdev_backup(self):
        for format in TestDriveCompression.fmt_supports_compression:
@@ -546,14 +537,14 @@ class TestDriveCompression(iotests.QMPTestCase):
         self.wait_until_completed()
 
         self.vm.shutdown()
-        self.assertTrue(iotests.compare_images(test_img, blockdev_target_img,
+        self.assertTrue(iotests.compare_images(test_img, self.blockdev_target_img,
                                                iotests.imgfmt, format['type']),
                         'target image does not match source after backup')
 
     def test_compress_pause_drive_backup(self):
         for format in TestDriveCompression.fmt_supports_compression:
             self.do_test_compress_pause('drive-backup', format, False,
-                                        target=blockdev_target_img, mode='existing')
+                                        target=self.blockdev_target_img, mode='existing')
 
     def test_compress_pause_blockdev_backup(self):
         for format in TestDriveCompression.fmt_supports_compression:
diff --git a/tests/qemu-iotests/056 b/tests/qemu-iotests/056
index 04f2c3c..47da53f 100755
--- a/tests/qemu-iotests/056
+++ b/tests/qemu-iotests/056
@@ -25,50 +25,45 @@ import os
 import iotests
 from iotests import qemu_img, qemu_io, create_image
 
-backing_img = os.path.join(iotests.test_dir, 'backing.img')
-test_img = os.path.join(iotests.test_dir, 'test.img')
-target_img = os.path.join(iotests.test_dir, 'target.img')
 
 class TestSyncModesNoneAndTop(iotests.QMPTestCase):
     image_len = 64 * 1024 * 1024 # MB
 
     def setUp(self):
-        create_image(backing_img, TestSyncModesNoneAndTop.image_len)
-        qemu_img('create', '-f', iotests.imgfmt, '-o', 'backing_file=%s' % backing_img, test_img)
-        qemu_io('-c', 'write -P0x41 0 512', test_img)
-        qemu_io('-c', 'write -P0xd5 1M 32k', test_img)
-        qemu_io('-c', 'write -P0xdc 32M 124k', test_img)
-        qemu_io('-c', 'write -P0xdc 67043328 64k', test_img)
-        self.vm = iotests.VM().add_drive(test_img)
+        self.backing_img = os.path.join(self.workdir, 'backing.img')
+        self.test_img = os.path.join(self.workdir, 'test.img')
+        self.target_img = os.path.join(self.workdir, 'target.img')
+        create_image(self.backing_img, TestSyncModesNoneAndTop.image_len)
+        qemu_img('create', '-f', iotests.imgfmt, '-o', 'backing_file=%s' % self.backing_img, self.test_img)
+        qemu_io('-c', 'write -P0x41 0 512', self.test_img)
+        qemu_io('-c', 'write -P0xd5 1M 32k', self.test_img)
+        qemu_io('-c', 'write -P0xdc 32M 124k', self.test_img)
+        qemu_io('-c', 'write -P0xdc 67043328 64k', self.test_img)
+        self.vm = iotests.VM().add_drive(self.test_img)
         self.vm.launch()
 
     def tearDown(self):
         self.vm.shutdown()
-        os.remove(test_img)
-        os.remove(backing_img)
-        try:
-            os.remove(target_img)
-        except OSError:
-            pass
+        pass
 
     def test_complete_top(self):
         self.assert_no_active_block_jobs()
         result = self.vm.qmp('drive-backup', device='drive0', sync='top',
-                             format=iotests.imgfmt, target=target_img)
+                             format=iotests.imgfmt, target=self.target_img)
         self.assert_qmp(result, 'return', {})
 
         self.wait_until_completed(check_offset=False)
 
         self.assert_no_active_block_jobs()
         self.vm.shutdown()
-        self.assertTrue(iotests.compare_images(test_img, target_img),
+        self.assertTrue(iotests.compare_images(self.test_img, self.target_img),
                         'target image does not match source after backup')
 
     def test_cancel_sync_none(self):
         self.assert_no_active_block_jobs()
 
         result = self.vm.qmp('drive-backup', device='drive0',
-                             sync='none', target=target_img)
+                             sync='none', target=self.target_img)
         self.assert_qmp(result, 'return', {})
         time.sleep(1)
         self.vm.hmp_qemu_io('drive0', 'write -P0x5e 0 512')
@@ -80,21 +75,21 @@ class TestSyncModesNoneAndTop(iotests.QMPTestCase):
 
         self.vm.shutdown()
         time.sleep(1)
-        self.assertEqual(-1, qemu_io('-c', 'read -P0x41 0 512', target_img).find("verification failed"))
+        self.assertEqual(-1, qemu_io('-c', 'read -P0x41 0 512', self.target_img).find("verification failed"))
 
 class TestBeforeWriteNotifier(iotests.QMPTestCase):
     def setUp(self):
+        self.target_img = os.path.join(self.workdir, 'target.img')
         self.vm = iotests.VM().add_drive_raw("file=blkdebug::null-co://,id=drive0,align=65536,driver=blkdebug")
         self.vm.launch()
 
     def tearDown(self):
         self.vm.shutdown()
-        os.remove(target_img)
 
     def test_before_write_notifier(self):
         self.vm.pause_drive("drive0")
         result = self.vm.qmp('drive-backup', device='drive0',
-                             sync='full', target=target_img,
+                             sync='full', target=self.target_img,
                              format="file", speed=1)
         self.assert_qmp(result, 'return', {})
         result = self.vm.qmp('block-job-pause', device="drive0")
diff --git a/tests/qemu-iotests/057 b/tests/qemu-iotests/057
index 9f0a5a3..00b07d3 100755
--- a/tests/qemu-iotests/057
+++ b/tests/qemu-iotests/057
@@ -38,7 +38,7 @@ class ImageSnapshotTestCase(iotests.QMPTestCase):
         self.vm = iotests.VM()
         for i in range(0, image_num):
             filename = '%s%d' % (test_img_base_name, i)
-            img = os.path.join(iotests.test_dir, filename)
+            img = os.path.join(self.workdir, filename)
             device = '%s%d' % (test_drv_base_name, i)
             qemu_img('create', '-f', iotests.imgfmt, img, str(self.image_len))
             self.vm.add_drive(img)
@@ -49,8 +49,6 @@ class ImageSnapshotTestCase(iotests.QMPTestCase):
 
     def tearDown(self):
         self.vm.shutdown()
-        for dev_expect in self.expect:
-            os.remove(dev_expect['image'])
 
     def createSnapshotInTransaction(self, snapshot_num, abort = False):
         actions = []
diff --git a/tests/qemu-iotests/065 b/tests/qemu-iotests/065
index 72aa970..6c67f7d 100755
--- a/tests/qemu-iotests/065
+++ b/tests/qemu-iotests/065
@@ -26,19 +26,18 @@ import iotests
 from iotests import qemu_img, qemu_img_pipe
 import unittest
 
-test_img = os.path.join(iotests.test_dir, 'test.img')
 
 class TestImageInfoSpecific(iotests.QMPTestCase):
     '''Abstract base class for ImageInfoSpecific tests'''
+    test_img = ''
 
     def setUp(self):
+        self.test_img = os.path.join(self.workdir, 'test.img')
         if self.img_options is None:
             self.skipTest('Skipping abstract test class')
         qemu_img('create', '-f', iotests.imgfmt, '-o', self.img_options,
-                 test_img, '128K')
+                 self.test_img, '128K')
 
-    def tearDown(self):
-        os.remove(test_img)
 
 class TestQemuImgInfo(TestImageInfoSpecific):
     '''Abstract base class for qemu-img info tests'''
@@ -48,13 +47,13 @@ class TestQemuImgInfo(TestImageInfoSpecific):
     human_compare = None
 
     def test_json(self):
-        data = json.loads(qemu_img_pipe('info', '--output=json', test_img))
+        data = json.loads(qemu_img_pipe('info', '--output=json', self.test_img))
         data = data['format-specific']
         self.assertEqual(data['type'], iotests.imgfmt)
         self.assertEqual(data['data'], self.json_compare)
 
     def test_human(self):
-        data = qemu_img_pipe('info', '--output=human', test_img).split('\n')
+        data = qemu_img_pipe('info', '--output=human', self.test_img).split('\n')
         data = data[(data.index('Format specific information:') + 1)
                     :data.index('')]
         for field in data:
@@ -71,7 +70,7 @@ class TestQMP(TestImageInfoSpecific):
 
     def setUp(self):
         self.TestImageInfoSpecific.setUp(self)
-        self.vm = iotests.VM().add_drive(test_img, self.qemu_options)
+        self.vm = iotests.VM().add_drive(self.test_img, self.qemu_options)
         self.vm.launch()
 
     def tearDown(self):
diff --git a/tests/qemu-iotests/096 b/tests/qemu-iotests/096
index aeeb375..b9388ec 100644
--- a/tests/qemu-iotests/096
+++ b/tests/qemu-iotests/096
@@ -23,13 +23,15 @@ 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')
+    base_img = ''
+    target_img = ''
     group = 'mygroup'
     iops = 6000
     iops_size = 1024
 
     def setUp(self):
+        self.base_img = os.path.join(self.workdir, 'base.img')
+        self.target_img = os.path.join(self.workdir, 'target.img')
         opts = []
         opts.append('node-name=base')
         opts.append('throttling.group=%s' % self.group)
@@ -41,8 +43,6 @@ class TestLiveSnapshot(iotests.QMPTestCase):
 
     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-block')
diff --git a/tests/qemu-iotests/118 b/tests/qemu-iotests/118
index 8a9e838..b011780 100755
--- a/tests/qemu-iotests/118
+++ b/tests/qemu-iotests/118
@@ -25,12 +25,17 @@ import time
 import iotests
 from iotests import qemu_img
 
-old_img = os.path.join(iotests.test_dir, 'test0.img')
-new_img = os.path.join(iotests.test_dir, 'test1.img')
 
 class ChangeBaseClass(iotests.QMPTestCase):
     has_opened = False
     has_closed = False
+    old_img = ''
+    new_img = ''
+
+    def setUp(self):
+        self.old_img = os.path.join(self.workdir, 'test0.img')
+        self.new_img = os.path.join(self.workdir, 'test1.img')
+
 
     def process_events(self):
         for event in self.vm.get_qmp_events(wait=False):
@@ -62,11 +67,15 @@ class ChangeBaseClass(iotests.QMPTestCase):
             self.fail('Timeout while waiting for the tray to close')
 
 class GeneralChangeTestsBaseClass(ChangeBaseClass):
+    ChangeBaseClass = ChangeBaseClass
 
     device_name = None
 
+    def setUp(self):
+        self.ChangeBaseClass.setUp(self);
+
     def test_change(self):
-        result = self.vm.qmp('change', device='drive0', target=new_img,
+        result = self.vm.qmp('change', device='drive0', target=self.new_img,
                                        arg=iotests.imgfmt)
         self.assert_qmp(result, 'return', {})
 
@@ -76,16 +85,16 @@ class GeneralChangeTestsBaseClass(ChangeBaseClass):
         result = self.vm.qmp('query-block')
         if self.has_real_tray:
             self.assert_qmp(result, 'return[0]/tray_open', False)
-        self.assert_qmp(result, 'return[0]/inserted/image/filename', new_img)
+        self.assert_qmp(result, 'return[0]/inserted/image/filename', self.new_img)
 
     def test_blockdev_change_medium(self):
         if self.device_name is not None:
             result = self.vm.qmp('blockdev-change-medium',
-                                 id=self.device_name, filename=new_img,
+                                 id=self.device_name, filename=self.new_img,
                                  format=iotests.imgfmt)
         else:
             result = self.vm.qmp('blockdev-change-medium',
-                                 device='drive0', filename=new_img,
+                                 device='drive0', filename=self.new_img,
                                  format=iotests.imgfmt)
 
         self.assert_qmp(result, 'return', {})
@@ -96,7 +105,7 @@ class GeneralChangeTestsBaseClass(ChangeBaseClass):
         result = self.vm.qmp('query-block')
         if self.has_real_tray:
             self.assert_qmp(result, 'return[0]/tray_open', False)
-        self.assert_qmp(result, 'return[0]/inserted/image/filename', new_img)
+        self.assert_qmp(result, 'return[0]/inserted/image/filename', self.new_img)
 
     def test_eject(self):
         if self.device_name is not None:
@@ -128,10 +137,10 @@ class GeneralChangeTestsBaseClass(ChangeBaseClass):
 
         if self.device_name is not None:
             result = self.vm.qmp('blockdev-change-medium', id=self.device_name,
-                                 filename=new_img, format=iotests.imgfmt)
+                                 filename=self.new_img, format=iotests.imgfmt)
         else:
             result = self.vm.qmp('blockdev-change-medium', device='drive0',
-                                 filename=new_img, format=iotests.imgfmt)
+                                 filename=self.new_img, format=iotests.imgfmt)
         self.assert_qmp(result, 'return', {})
 
         self.wait_for_close()
@@ -139,7 +148,7 @@ class GeneralChangeTestsBaseClass(ChangeBaseClass):
         result = self.vm.qmp('query-block')
         if self.has_real_tray:
             self.assert_qmp(result, 'return[0]/tray_open', False)
-        self.assert_qmp(result, 'return[0]/inserted/image/filename', new_img)
+        self.assert_qmp(result, 'return[0]/inserted/image/filename', self.new_img)
 
     def test_tray_open_close(self):
         if self.device_name is not None:
@@ -158,7 +167,7 @@ class GeneralChangeTestsBaseClass(ChangeBaseClass):
         if self.was_empty == True:
             self.assert_qmp_absent(result, 'return[0]/inserted')
         else:
-            self.assert_qmp(result, 'return[0]/inserted/image/filename', old_img)
+            self.assert_qmp(result, 'return[0]/inserted/image/filename', self.old_img)
 
         if self.device_name is not None:
             result = self.vm.qmp('blockdev-close-tray', id=self.device_name)
@@ -175,7 +184,7 @@ class GeneralChangeTestsBaseClass(ChangeBaseClass):
         if self.was_empty == True:
             self.assert_qmp_absent(result, 'return[0]/inserted')
         else:
-            self.assert_qmp(result, 'return[0]/inserted/image/filename', old_img)
+            self.assert_qmp(result, 'return[0]/inserted/image/filename', self.old_img)
 
     def test_tray_eject_close(self):
         result = self.vm.qmp('eject', device='drive0', force=True)
@@ -213,10 +222,10 @@ class GeneralChangeTestsBaseClass(ChangeBaseClass):
         if self.was_empty == True:
             self.assert_qmp_absent(result, 'return[0]/inserted')
         else:
-            self.assert_qmp(result, 'return[0]/inserted/image/filename', old_img)
+            self.assert_qmp(result, 'return[0]/inserted/image/filename', self.old_img)
 
         result = self.vm.qmp('blockdev-change-medium', device='drive0',
-                                                       filename=new_img,
+                                                       filename=self.new_img,
                                                        format=iotests.imgfmt)
         self.assert_qmp(result, 'return', {})
 
@@ -225,13 +234,13 @@ class GeneralChangeTestsBaseClass(ChangeBaseClass):
         result = self.vm.qmp('query-block')
         if self.has_real_tray:
             self.assert_qmp(result, 'return[0]/tray_open', False)
-        self.assert_qmp(result, 'return[0]/inserted/image/filename', new_img)
+        self.assert_qmp(result, 'return[0]/inserted/image/filename', self.new_img)
 
     def test_cycle(self):
         result = self.vm.qmp('blockdev-add',
                              node_name='new',
                              driver=iotests.imgfmt,
-                             file={'filename': new_img,
+                             file={'filename': self.new_img,
                                     'driver': 'file'})
         self.assert_qmp(result, 'return', {})
 
@@ -251,7 +260,7 @@ class GeneralChangeTestsBaseClass(ChangeBaseClass):
         if self.was_empty == True:
             self.assert_qmp_absent(result, 'return[0]/inserted')
         else:
-            self.assert_qmp(result, 'return[0]/inserted/image/filename', old_img)
+            self.assert_qmp(result, 'return[0]/inserted/image/filename', self.old_img)
 
         if self.device_name is not None:
             result = self.vm.qmp('x-blockdev-remove-medium',
@@ -276,7 +285,7 @@ class GeneralChangeTestsBaseClass(ChangeBaseClass):
         result = self.vm.qmp('query-block')
         if self.has_real_tray:
             self.assert_qmp(result, 'return[0]/tray_open', True)
-        self.assert_qmp(result, 'return[0]/inserted/image/filename', new_img)
+        self.assert_qmp(result, 'return[0]/inserted/image/filename', self.new_img)
 
         if self.device_name is not None:
             result = self.vm.qmp('blockdev-close-tray', id=self.device_name)
@@ -289,7 +298,7 @@ class GeneralChangeTestsBaseClass(ChangeBaseClass):
         result = self.vm.qmp('query-block')
         if self.has_real_tray:
             self.assert_qmp(result, 'return[0]/tray_open', False)
-        self.assert_qmp(result, 'return[0]/inserted/image/filename', new_img)
+        self.assert_qmp(result, 'return[0]/inserted/image/filename', self.new_img)
 
     def test_close_on_closed(self):
         result = self.vm.qmp('blockdev-close-tray', device='drive0')
@@ -311,7 +320,7 @@ class GeneralChangeTestsBaseClass(ChangeBaseClass):
         result = self.vm.qmp('blockdev-add',
                              node_name='new',
                              driver=iotests.imgfmt,
-                             file={'filename': new_img,
+                             file={'filename': self.new_img,
                                    'driver': 'file'})
         self.assert_qmp(result, 'return', {})
 
@@ -321,29 +330,29 @@ class GeneralChangeTestsBaseClass(ChangeBaseClass):
 
 class TestInitiallyFilled(GeneralChangeTestsBaseClass):
     was_empty = False
+    GeneralChangeTestsBaseClass = GeneralChangeTestsBaseClass
 
     def setUp(self, media, interface):
-        qemu_img('create', '-f', iotests.imgfmt, old_img, '1440k')
-        qemu_img('create', '-f', iotests.imgfmt, new_img, '1440k')
+        self.GeneralChangeTestsBaseClass.setUp(self)
+        qemu_img('create', '-f', iotests.imgfmt, self.old_img, '1440k')
+        qemu_img('create', '-f', iotests.imgfmt, self.new_img, '1440k')
         self.vm = iotests.VM()
         if interface == 'ide':
             self.device_name = 'qdev0'
-            self.vm.add_drive(old_img, 'media=%s' % media, 'none')
+            self.vm.add_drive(self.old_img, 'media=%s' % media, 'none')
             self.vm.add_device('ide-cd,drive=drive0,id=%s' % self.device_name)
         else:
-            self.vm.add_drive(old_img, 'media=%s' % media, interface)
+            self.vm.add_drive(self.old_img, 'media=%s' % media, interface)
         self.vm.launch()
 
     def tearDown(self):
         self.vm.shutdown()
-        os.remove(old_img)
-        os.remove(new_img)
 
     def test_insert_on_filled(self):
         result = self.vm.qmp('blockdev-add',
                              node_name='new',
                              driver=iotests.imgfmt,
-                             file={'filename': new_img,
+                             file={'filename': self.new_img,
                                    'driver': 'file'})
         self.assert_qmp(result, 'return', {})
 
@@ -358,15 +367,16 @@ class TestInitiallyFilled(GeneralChangeTestsBaseClass):
 
 class TestInitiallyEmpty(GeneralChangeTestsBaseClass):
     was_empty = True
+    GeneralChangeTestsBaseClass = GeneralChangeTestsBaseClass
 
     def setUp(self, media, interface):
-        qemu_img('create', '-f', iotests.imgfmt, new_img, '1440k')
+        self.GeneralChangeTestsBaseClass.setUp(self)
+        qemu_img('create', '-f', iotests.imgfmt, self.new_img, '1440k')
         self.vm = iotests.VM().add_drive(None, 'media=%s' % media, interface)
         self.vm.launch()
 
     def tearDown(self):
         self.vm.shutdown()
-        os.remove(new_img)
 
     def test_remove_on_empty(self):
         result = self.vm.qmp('blockdev-open-tray', device='drive0')
@@ -411,67 +421,64 @@ class TestFloppyInitiallyEmpty(TestInitiallyEmpty):
 
 class TestChangeReadOnly(ChangeBaseClass):
     def setUp(self):
-        qemu_img('create', '-f', iotests.imgfmt, old_img, '1440k')
-        qemu_img('create', '-f', iotests.imgfmt, new_img, '1440k')
+        ChangeBaseClass.setUp(self)
+        qemu_img('create', '-f', iotests.imgfmt, self.old_img, '1440k')
+        qemu_img('create', '-f', iotests.imgfmt, self.new_img, '1440k')
         self.vm = iotests.VM()
 
     def tearDown(self):
         self.vm.shutdown()
-        os.chmod(old_img, 0666)
-        os.chmod(new_img, 0666)
-        os.remove(old_img)
-        os.remove(new_img)
 
     def test_ro_ro_retain(self):
-        os.chmod(old_img, 0444)
-        os.chmod(new_img, 0444)
-        self.vm.add_drive(old_img, 'media=disk,read-only=on', 'floppy')
+        os.chmod(self.old_img, 0444)
+        os.chmod(self.new_img, 0444)
+        self.vm.add_drive(self.old_img, 'media=disk,read-only=on', 'floppy')
         self.vm.launch()
 
         result = self.vm.qmp('query-block')
         self.assert_qmp(result, 'return[0]/inserted/ro', True)
-        self.assert_qmp(result, 'return[0]/inserted/image/filename', old_img)
+        self.assert_qmp(result, 'return[0]/inserted/image/filename', self.old_img)
 
         result = self.vm.qmp('blockdev-change-medium', device='drive0',
-                                                       filename=new_img,
+                                                       filename=self.new_img,
                                                        format=iotests.imgfmt,
                                                        read_only_mode='retain')
         self.assert_qmp(result, 'return', {})
 
         result = self.vm.qmp('query-block')
         self.assert_qmp(result, 'return[0]/inserted/ro', True)
-        self.assert_qmp(result, 'return[0]/inserted/image/filename', new_img)
+        self.assert_qmp(result, 'return[0]/inserted/image/filename', self.new_img)
 
     def test_ro_rw_retain(self):
-        os.chmod(old_img, 0444)
-        self.vm.add_drive(old_img, 'media=disk,read-only=on', 'floppy')
+        os.chmod(self.old_img, 0444)
+        self.vm.add_drive(self.old_img, 'media=disk,read-only=on', 'floppy')
         self.vm.launch()
 
         result = self.vm.qmp('query-block')
         self.assert_qmp(result, 'return[0]/inserted/ro', True)
-        self.assert_qmp(result, 'return[0]/inserted/image/filename', old_img)
+        self.assert_qmp(result, 'return[0]/inserted/image/filename', self.old_img)
 
         result = self.vm.qmp('blockdev-change-medium', device='drive0',
-                                                       filename=new_img,
+                                                       filename=self.new_img,
                                                        format=iotests.imgfmt,
                                                        read_only_mode='retain')
         self.assert_qmp(result, 'return', {})
 
         result = self.vm.qmp('query-block')
         self.assert_qmp(result, 'return[0]/inserted/ro', True)
-        self.assert_qmp(result, 'return[0]/inserted/image/filename', new_img)
+        self.assert_qmp(result, 'return[0]/inserted/image/filename', self.new_img)
 
     def test_rw_ro_retain(self):
-        os.chmod(new_img, 0444)
-        self.vm.add_drive(old_img, 'media=disk', 'floppy')
+        os.chmod(self.new_img, 0444)
+        self.vm.add_drive(self.old_img, 'media=disk', 'floppy')
         self.vm.launch()
 
         result = self.vm.qmp('query-block')
         self.assert_qmp(result, 'return[0]/inserted/ro', False)
-        self.assert_qmp(result, 'return[0]/inserted/image/filename', old_img)
+        self.assert_qmp(result, 'return[0]/inserted/image/filename', self.old_img)
 
         result = self.vm.qmp('blockdev-change-medium', device='drive0',
-                                                       filename=new_img,
+                                                       filename=self.new_img,
                                                        format=iotests.imgfmt,
                                                        read_only_mode='retain')
         self.assert_qmp(result, 'error/class', 'GenericError')
@@ -480,145 +487,145 @@ class TestChangeReadOnly(ChangeBaseClass):
 
         result = self.vm.qmp('query-block')
         self.assert_qmp(result, 'return[0]/inserted/ro', False)
-        self.assert_qmp(result, 'return[0]/inserted/image/filename', old_img)
+        self.assert_qmp(result, 'return[0]/inserted/image/filename', self.old_img)
 
     def test_ro_rw(self):
-        os.chmod(old_img, 0444)
-        self.vm.add_drive(old_img, 'media=disk,read-only=on', 'floppy')
+        os.chmod(self.old_img, 0444)
+        self.vm.add_drive(self.old_img, 'media=disk,read-only=on', 'floppy')
         self.vm.launch()
 
         result = self.vm.qmp('query-block')
         self.assert_qmp(result, 'return[0]/inserted/ro', True)
-        self.assert_qmp(result, 'return[0]/inserted/image/filename', old_img)
+        self.assert_qmp(result, 'return[0]/inserted/image/filename', self.old_img)
 
         result = self.vm.qmp('blockdev-change-medium',
                              device='drive0',
-                             filename=new_img,
+                             filename=self.new_img,
                              format=iotests.imgfmt,
                              read_only_mode='read-write')
         self.assert_qmp(result, 'return', {})
 
         result = self.vm.qmp('query-block')
         self.assert_qmp(result, 'return[0]/inserted/ro', False)
-        self.assert_qmp(result, 'return[0]/inserted/image/filename', new_img)
+        self.assert_qmp(result, 'return[0]/inserted/image/filename', self.new_img)
 
     def test_rw_ro(self):
-        os.chmod(new_img, 0444)
-        self.vm.add_drive(old_img, 'media=disk', 'floppy')
+        os.chmod(self.new_img, 0444)
+        self.vm.add_drive(self.old_img, 'media=disk', 'floppy')
         self.vm.launch()
 
         result = self.vm.qmp('query-block')
         self.assert_qmp(result, 'return[0]/inserted/ro', False)
-        self.assert_qmp(result, 'return[0]/inserted/image/filename', old_img)
+        self.assert_qmp(result, 'return[0]/inserted/image/filename', self.old_img)
 
         result = self.vm.qmp('blockdev-change-medium',
                              device='drive0',
-                             filename=new_img,
+                             filename=self.new_img,
                              format=iotests.imgfmt,
                              read_only_mode='read-only')
         self.assert_qmp(result, 'return', {})
 
         result = self.vm.qmp('query-block')
         self.assert_qmp(result, 'return[0]/inserted/ro', True)
-        self.assert_qmp(result, 'return[0]/inserted/image/filename', new_img)
+        self.assert_qmp(result, 'return[0]/inserted/image/filename', self.new_img)
 
     def test_make_rw_ro(self):
-        self.vm.add_drive(old_img, 'media=disk', 'floppy')
+        self.vm.add_drive(self.old_img, 'media=disk', 'floppy')
         self.vm.launch()
 
         result = self.vm.qmp('query-block')
         self.assert_qmp(result, 'return[0]/inserted/ro', False)
-        self.assert_qmp(result, 'return[0]/inserted/image/filename', old_img)
+        self.assert_qmp(result, 'return[0]/inserted/image/filename', self.old_img)
 
         result = self.vm.qmp('blockdev-change-medium',
                              device='drive0',
-                             filename=new_img,
+                             filename=self.new_img,
                              format=iotests.imgfmt,
                              read_only_mode='read-only')
         self.assert_qmp(result, 'return', {})
 
         result = self.vm.qmp('query-block')
         self.assert_qmp(result, 'return[0]/inserted/ro', True)
-        self.assert_qmp(result, 'return[0]/inserted/image/filename', new_img)
+        self.assert_qmp(result, 'return[0]/inserted/image/filename', self.new_img)
 
     def test_make_ro_rw(self):
-        os.chmod(new_img, 0444)
-        self.vm.add_drive(old_img, 'media=disk', 'floppy')
+        os.chmod(self.new_img, 0444)
+        self.vm.add_drive(self.old_img, 'media=disk', 'floppy')
         self.vm.launch()
 
         result = self.vm.qmp('query-block')
         self.assert_qmp(result, 'return[0]/inserted/ro', False)
-        self.assert_qmp(result, 'return[0]/inserted/image/filename', old_img)
+        self.assert_qmp(result, 'return[0]/inserted/image/filename', self.old_img)
 
         result = self.vm.qmp('blockdev-change-medium',
                              device='drive0',
-                             filename=new_img,
+                             filename=self.new_img,
                              format=iotests.imgfmt,
                              read_only_mode='read-write')
         self.assert_qmp(result, 'error/class', 'GenericError')
 
         result = self.vm.qmp('query-block')
         self.assert_qmp(result, 'return[0]/inserted/ro', False)
-        self.assert_qmp(result, 'return[0]/inserted/image/filename', old_img)
+        self.assert_qmp(result, 'return[0]/inserted/image/filename', self.old_img)
 
     def test_make_rw_ro_by_retain(self):
-        os.chmod(old_img, 0444)
-        self.vm.add_drive(old_img, 'media=disk,read-only=on', 'floppy')
+        os.chmod(self.old_img, 0444)
+        self.vm.add_drive(self.old_img, 'media=disk,read-only=on', 'floppy')
         self.vm.launch()
 
         result = self.vm.qmp('query-block')
         self.assert_qmp(result, 'return[0]/inserted/ro', True)
-        self.assert_qmp(result, 'return[0]/inserted/image/filename', old_img)
+        self.assert_qmp(result, 'return[0]/inserted/image/filename', self.old_img)
 
         result = self.vm.qmp('blockdev-change-medium', device='drive0',
-                                                       filename=new_img,
+                                                       filename=self.new_img,
                                                        format=iotests.imgfmt,
                                                        read_only_mode='retain')
         self.assert_qmp(result, 'return', {})
 
         result = self.vm.qmp('query-block')
         self.assert_qmp(result, 'return[0]/inserted/ro', True)
-        self.assert_qmp(result, 'return[0]/inserted/image/filename', new_img)
+        self.assert_qmp(result, 'return[0]/inserted/image/filename', self.new_img)
 
     def test_make_ro_rw_by_retain(self):
-        os.chmod(new_img, 0444)
-        self.vm.add_drive(old_img, 'media=disk', 'floppy')
+        os.chmod(self.new_img, 0444)
+        self.vm.add_drive(self.old_img, 'media=disk', 'floppy')
         self.vm.launch()
 
         result = self.vm.qmp('query-block')
         self.assert_qmp(result, 'return[0]/inserted/ro', False)
-        self.assert_qmp(result, 'return[0]/inserted/image/filename', old_img)
+        self.assert_qmp(result, 'return[0]/inserted/image/filename', self.old_img)
 
         result = self.vm.qmp('blockdev-change-medium', device='drive0',
-                                                       filename=new_img,
+                                                       filename=self.new_img,
                                                        format=iotests.imgfmt,
                                                        read_only_mode='retain')
         self.assert_qmp(result, 'error/class', 'GenericError')
 
         result = self.vm.qmp('query-block')
         self.assert_qmp(result, 'return[0]/inserted/ro', False)
-        self.assert_qmp(result, 'return[0]/inserted/image/filename', old_img)
+        self.assert_qmp(result, 'return[0]/inserted/image/filename', self.old_img)
 
     def test_rw_ro_cycle(self):
-        os.chmod(new_img, 0444)
-        self.vm.add_drive(old_img, 'media=disk', 'floppy')
+        os.chmod(self.new_img, 0444)
+        self.vm.add_drive(self.old_img, 'media=disk', 'floppy')
         self.vm.launch()
 
         result = self.vm.qmp('query-block')
         self.assert_qmp(result, 'return[0]/inserted/ro', False)
-        self.assert_qmp(result, 'return[0]/inserted/image/filename', old_img)
+        self.assert_qmp(result, 'return[0]/inserted/image/filename', self.old_img)
 
         result = self.vm.qmp('blockdev-add',
                              node_name='new',
                              driver=iotests.imgfmt,
                              read_only=True,
-                             file={'filename': new_img,
+                             file={'filename': self.new_img,
                                     'driver': 'file'})
         self.assert_qmp(result, 'return', {})
 
         result = self.vm.qmp('query-block')
         self.assert_qmp(result, 'return[0]/inserted/ro', False)
-        self.assert_qmp(result, 'return[0]/inserted/image/filename', old_img)
+        self.assert_qmp(result, 'return[0]/inserted/image/filename', self.old_img)
 
         result = self.vm.qmp('x-blockdev-remove-medium', device='drive0')
         self.assert_qmp(result, 'return', {})
@@ -632,11 +639,11 @@ class TestChangeReadOnly(ChangeBaseClass):
 
         result = self.vm.qmp('query-block')
         self.assert_qmp(result, 'return[0]/inserted/ro', True)
-        self.assert_qmp(result, 'return[0]/inserted/image/filename', new_img)
+        self.assert_qmp(result, 'return[0]/inserted/image/filename', self.new_img)
 
         result = self.vm.qmp('query-block')
         self.assert_qmp(result, 'return[0]/inserted/ro', True)
-        self.assert_qmp(result, 'return[0]/inserted/image/filename', new_img)
+        self.assert_qmp(result, 'return[0]/inserted/image/filename', self.new_img)
 
 GeneralChangeTestsBaseClass = None
 TestInitiallyFilled = None
@@ -644,8 +651,10 @@ TestInitiallyEmpty = None
 
 
 class TestBlockJobsAfterCycle(ChangeBaseClass):
+    ChangeBaseClass = ChangeBaseClass
     def setUp(self):
-        qemu_img('create', '-f', iotests.imgfmt, old_img, '1M')
+        self.ChangeBaseClass.setUp(self)
+        qemu_img('create', '-f', iotests.imgfmt, self.old_img, '1M')
 
         self.vm = iotests.VM()
         self.vm.add_drive_raw("id=drive0,driver=null-co,if=none")
@@ -665,7 +674,7 @@ class TestBlockJobsAfterCycle(ChangeBaseClass):
         result = self.vm.qmp('blockdev-add',
                              node_name='node0',
                              driver=iotests.imgfmt,
-                             file={'filename': old_img,
+                             file={'filename': self.old_img,
                                    'driver': 'file'})
         self.assert_qmp(result, 'return', {})
 
@@ -674,15 +683,10 @@ class TestBlockJobsAfterCycle(ChangeBaseClass):
         self.assert_qmp(result, 'return', {})
 
         result = self.vm.qmp('query-block')
-        self.assert_qmp(result, 'return[0]/inserted/image/filename', old_img)
+        self.assert_qmp(result, 'return[0]/inserted/image/filename', self.old_img)
 
     def tearDown(self):
         self.vm.shutdown()
-        os.remove(old_img)
-        try:
-            os.remove(new_img)
-        except OSError:
-            pass
 
     def test_snapshot_and_commit(self):
         # We need backing file support
@@ -690,15 +694,15 @@ class TestBlockJobsAfterCycle(ChangeBaseClass):
             return
 
         result = self.vm.qmp('blockdev-snapshot-sync', device='drive0',
-                                                       snapshot_file=new_img,
+                                                       snapshot_file=self.new_img,
                                                        format=iotests.imgfmt)
         self.assert_qmp(result, 'return', {})
 
         result = self.vm.qmp('query-block')
-        self.assert_qmp(result, 'return[0]/inserted/image/filename', new_img)
+        self.assert_qmp(result, 'return[0]/inserted/image/filename', self.new_img)
         self.assert_qmp(result,
                         'return[0]/inserted/image/backing-image/filename',
-                        old_img)
+                        self.old_img)
 
         result = self.vm.qmp('block-commit', device='drive0')
         self.assert_qmp(result, 'return', {})
diff --git a/tests/qemu-iotests/124 b/tests/qemu-iotests/124
index 8e76e62..91ca06d 100644
--- a/tests/qemu-iotests/124
+++ b/tests/qemu-iotests/124
@@ -54,11 +54,12 @@ def transaction_drive_backup(device, target, **kwargs):
 
 
 class Bitmap:
-    def __init__(self, name, drive):
+    def __init__(self, name, drive, workdir=iotests.test_dir):
         self.name = name
         self.drive = drive
         self.num = 0
         self.backups = list()
+        self.workdir = workdir
 
     def base_target(self):
         return (self.drive['backup'], None)
@@ -67,7 +68,7 @@ class Bitmap:
         if num is None:
             num = self.num
         self.num = num + 1
-        base = os.path.join(iotests.test_dir,
+        base = os.path.join(self.workdir,
                             "%s.%s." % (self.drive['id'], self.name))
         suff = "%i.%s" % (num, self.drive['fmt'])
         target = base + "inc" + suff
@@ -85,12 +86,6 @@ class Bitmap:
             try_remove(image)
         self.num -= 1
 
-    def cleanup(self):
-        for backup in self.backups:
-            for image in backup:
-                try_remove(image)
-
-
 class TestIncrementalBackupBase(iotests.QMPTestCase):
     def __init__(self, *args):
         super(TestIncrementalBackupBase, self).__init__(*args)
@@ -98,7 +93,7 @@ class TestIncrementalBackupBase(iotests.QMPTestCase):
         self.files = list()
         self.drives = list()
         self.vm = iotests.VM()
-        self.err_img = os.path.join(iotests.test_dir, 'err.%s' % iotests.imgfmt)
+        self.err_img = os.path.join(self.workdir, 'err.%s' % iotests.imgfmt)
 
 
     def setUp(self):
@@ -118,9 +113,9 @@ class TestIncrementalBackupBase(iotests.QMPTestCase):
 
     def add_node(self, node_id, fmt=iotests.imgfmt, path=None, backup=None):
         if path is None:
-            path = os.path.join(iotests.test_dir, '%s.%s' % (node_id, fmt))
+            path = os.path.join(self.workdir, '%s.%s' % (node_id, fmt))
         if backup is None:
-            backup = os.path.join(iotests.test_dir,
+            backup = os.path.join(self.workdir,
                                   '%s.full.backup.%s' % (node_id, fmt))
 
         self.drives.append({
@@ -196,7 +191,7 @@ class TestIncrementalBackupBase(iotests.QMPTestCase):
 
 
     def add_bitmap(self, name, drive, **kwargs):
-        bitmap = Bitmap(name, drive)
+        bitmap = Bitmap(name, drive, self.workdir)
         self.bitmaps.append(bitmap)
         result = self.vm.qmp('block-dirty-bitmap-add', node=drive['id'],
                              name=bitmap.name, **kwargs)
@@ -273,11 +268,6 @@ class TestIncrementalBackupBase(iotests.QMPTestCase):
 
     def tearDown(self):
         self.vm.shutdown()
-        for bitmap in self.bitmaps:
-            bitmap.cleanup()
-        for filename in self.files:
-            try_remove(filename)
-
 
 
 class TestIncrementalBackup(TestIncrementalBackupBase):
diff --git a/tests/qemu-iotests/129 b/tests/qemu-iotests/129
index 9e87e1c..8293649 100644
--- a/tests/qemu-iotests/129
+++ b/tests/qemu-iotests/129
@@ -23,11 +23,11 @@ import iotests
 import time
 
 class TestStopWithBlockJob(iotests.QMPTestCase):
-    test_img = os.path.join(iotests.test_dir, 'test.img')
-    target_img = os.path.join(iotests.test_dir, 'target.img')
-    base_img = os.path.join(iotests.test_dir, 'base.img')
 
     def setUp(self):
+        self.test_img = os.path.join(self.workdir, 'test.img')
+        self.target_img = os.path.join(self.workdir, 'target.img')
+        self.base_img = os.path.join(self.workdir, 'base.img')
         iotests.qemu_img('create', '-f', iotests.imgfmt, self.base_img, "1G")
         iotests.qemu_img('create', '-f', iotests.imgfmt, self.test_img, "-b", self.base_img)
         iotests.qemu_io('-f', iotests.imgfmt, '-c', 'write -P0x5d 1M 128M', self.test_img)
diff --git a/tests/qemu-iotests/132 b/tests/qemu-iotests/132
index f53ef6e..3ca6f06 100644
--- a/tests/qemu-iotests/132
+++ b/tests/qemu-iotests/132
@@ -23,36 +23,31 @@ import os
 import iotests
 from iotests import qemu_img, qemu_io
 
-test_img = os.path.join(iotests.test_dir, 'test.img')
-target_img = os.path.join(iotests.test_dir, 'target.img')
 
 class TestSingleDrive(iotests.QMPTestCase):
     image_len = 2 * 1024 * 1024 # MB
 
     def setUp(self):
+        self.test_img = os.path.join(self.workdir, 'test.img')
+        self.target_img = os.path.join(self.workdir, 'target.img')
         # Write data to the image so we can compare later
-        qemu_img('create', '-f', iotests.imgfmt, test_img, str(TestSingleDrive.image_len))
-        qemu_io('-f', iotests.imgfmt, '-c', 'write -P0x5d 0 2M', test_img)
+        qemu_img('create', '-f', iotests.imgfmt, self.test_img, str(TestSingleDrive.image_len))
+        qemu_io('-f', iotests.imgfmt, '-c', 'write -P0x5d 0 2M', self.test_img)
 
-        self.vm = iotests.VM().add_drive(test_img, 'discard=unmap')
+        self.vm = iotests.VM().add_drive(self.test_img, 'discard=unmap')
         self.vm.launch()
 
     def tearDown(self):
         self.vm.shutdown()
-        os.remove(test_img)
-        try:
-            os.remove(target_img)
-        except OSError:
-            pass
 
     def test_mirror_discard(self):
         result = self.vm.qmp('drive-mirror', device='drive0', sync='full',
-                             target=target_img)
+                             target=self.target_img)
         self.assert_qmp(result, 'return', {})
         self.vm.hmp_qemu_io('drive0', 'discard 0 64k')
         self.complete_and_wait('drive0')
         self.vm.shutdown()
-        self.assertTrue(iotests.compare_images(test_img, target_img),
+        self.assertTrue(iotests.compare_images(self.test_img, self.target_img),
                         'target image does not match source after mirroring')
 
 if __name__ == '__main__':
diff --git a/tests/qemu-iotests/136 b/tests/qemu-iotests/136
index 4b99489..8109d63 100644
--- a/tests/qemu-iotests/136
+++ b/tests/qemu-iotests/136
@@ -27,7 +27,6 @@ nsec_per_sec = 1000000000
 op_latency = nsec_per_sec / 1000 # See qtest_latency_ns in accounting.c
 bad_sector = 8192
 bad_offset = bad_sector * 512
-blkdebug_file = os.path.join(iotests.test_dir, 'blkdebug.conf')
 
 class BlockDeviceStatsTestCase(iotests.QMPTestCase):
     test_img = "null-aio://"
@@ -53,7 +52,7 @@ class BlockDeviceStatsTestCase(iotests.QMPTestCase):
         raise Exception("Device not found for blockstats: %s" % device)
 
     def create_blkdebug_file(self):
-        file = open(blkdebug_file, 'w')
+        file = open(self.blkdebug_file, 'w')
         file.write('''
 [inject-error]
 event = "read_aio"
@@ -68,6 +67,7 @@ sector = "%d"
         file.close()
 
     def setUp(self):
+        self.blkdebug_file = os.path.join(self.workdir, 'blkdebug.conf')
         drive_args = []
         drive_args.append("stats-intervals.0=%d" % interval_length)
         drive_args.append("stats-account-invalid=%s" %
@@ -76,7 +76,7 @@ sector = "%d"
                           (self.account_failed and "on" or "off"))
         self.create_blkdebug_file()
         self.vm = iotests.VM().add_drive('blkdebug:%s:%s' %
-                                         (blkdebug_file, self.test_img),
+                                         (self.blkdebug_file, self.test_img),
                                          ','.join(drive_args))
         self.vm.launch()
         # Set an initial value for the clock
@@ -84,7 +84,6 @@ sector = "%d"
 
     def tearDown(self):
         self.vm.shutdown()
-        os.remove(blkdebug_file)
 
     def accounted_ops(self, read = False, write = False, flush = False):
         ops = 0
diff --git a/tests/qemu-iotests/139 b/tests/qemu-iotests/139
index f8f0280..7699dd2 100644
--- a/tests/qemu-iotests/139
+++ b/tests/qemu-iotests/139
@@ -23,8 +23,6 @@ import os
 import iotests
 import time
 
-base_img = os.path.join(iotests.test_dir, 'base.img')
-new_img = os.path.join(iotests.test_dir, 'new.img')
 if iotests.qemu_default_machine == 's390-ccw-virtio':
     default_virtio_blk = 'virtio-blk-ccw'
 else:
@@ -33,7 +31,9 @@ else:
 class TestBlockdevDel(iotests.QMPTestCase):
 
     def setUp(self):
-        iotests.qemu_img('create', '-f', iotests.imgfmt, base_img, '1M')
+        self.base_img = os.path.join(self.workdir, 'base.img')
+        self.new_img = os.path.join(self.workdir, 'new.img')
+        iotests.qemu_img('create', '-f', iotests.imgfmt, self.base_img, '1M')
         self.vm = iotests.VM()
         if iotests.qemu_default_machine == 's390-ccw-virtio':
             self.vm.add_device("virtio-scsi-ccw,id=virtio-scsi")
@@ -44,9 +44,6 @@ class TestBlockdevDel(iotests.QMPTestCase):
 
     def tearDown(self):
         self.vm.shutdown()
-        os.remove(base_img)
-        if os.path.isfile(new_img):
-            os.remove(new_img)
 
     # Check whether a BlockDriverState exists
     def checkBlockDriverState(self, node, must_exist = True):
@@ -64,7 +61,7 @@ class TestBlockdevDel(iotests.QMPTestCase):
                 'node-name': node,
                 'file': {'driver': 'file',
                          'node-name': file_node,
-                         'filename': base_img}}
+                         'filename': self.base_img}}
         result = self.vm.qmp('blockdev-add', conv_keys = False, **opts)
         self.assert_qmp(result, 'return', {})
         self.checkBlockDriverState(node)
@@ -74,12 +71,12 @@ class TestBlockdevDel(iotests.QMPTestCase):
     def addBlockDriverStateOverlay(self, node):
         self.checkBlockDriverState(node, False)
         iotests.qemu_img('create', '-u', '-f', iotests.imgfmt,
-                         '-b', base_img, new_img, '1M')
+                         '-b', self.base_img, self.new_img, '1M')
         opts = {'driver': iotests.imgfmt,
                 'node-name': node,
                 'backing': None,
                 'file': {'driver': 'file',
-                         'filename': new_img}}
+                         'filename': self.new_img}}
         result = self.vm.qmp('blockdev-add', conv_keys = False, **opts)
         self.assert_qmp(result, 'return', {})
         self.checkBlockDriverState(node)
@@ -143,7 +140,7 @@ class TestBlockdevDel(iotests.QMPTestCase):
         self.checkBlockDriverState(node)
         self.checkBlockDriverState(overlay, False)
         opts = {'node-name': node,
-                'snapshot-file': new_img,
+                'snapshot-file': self.new_img,
                 'snapshot-node-name': overlay,
                 'format': iotests.imgfmt}
         result = self.vm.qmp('blockdev-snapshot-sync', conv_keys=False, **opts)
@@ -166,7 +163,7 @@ class TestBlockdevDel(iotests.QMPTestCase):
         self.checkBlockDriverState(new_node, False)
         opts = {'device': node,
                 'job-id': node,
-                'target': new_img,
+                'target': self.new_img,
                 'node-name': new_node,
                 'sync': 'top',
                 'format': iotests.imgfmt}
@@ -189,7 +186,7 @@ class TestBlockdevDel(iotests.QMPTestCase):
         image = {'driver': iotests.imgfmt,
                  'node-name': node,
                  'file': {'driver': 'file',
-                          'filename': base_img}}
+                          'filename': self.base_img}}
         opts = {'driver': 'blkdebug',
                 'node-name': debug,
                 'image': image}
@@ -205,15 +202,15 @@ class TestBlockdevDel(iotests.QMPTestCase):
         self.checkBlockDriverState(test, False)
         self.checkBlockDriverState(raw, False)
         self.checkBlockDriverState(blkverify, False)
-        iotests.qemu_img('create', '-f', iotests.imgfmt, new_img, '1M')
+        iotests.qemu_img('create', '-f', iotests.imgfmt, self.new_img, '1M')
         node_0 = {'driver': iotests.imgfmt,
                   'node-name': test,
                   'file': {'driver': 'file',
-                           'filename': base_img}}
+                           'filename': self.base_img}}
         node_1 = {'driver': iotests.imgfmt,
                   'node-name': raw,
                   'file': {'driver': 'file',
-                           'filename': new_img}}
+                           'filename': self.new_img}}
         opts = {'driver': 'blkverify',
                 'node-name': blkverify,
                 'test': node_0,
@@ -229,15 +226,15 @@ class TestBlockdevDel(iotests.QMPTestCase):
         self.checkBlockDriverState(child0, False)
         self.checkBlockDriverState(child1, False)
         self.checkBlockDriverState(quorum, False)
-        iotests.qemu_img('create', '-f', iotests.imgfmt, new_img, '1M')
+        iotests.qemu_img('create', '-f', iotests.imgfmt, self.new_img, '1M')
         child_0 = {'driver': iotests.imgfmt,
                    'node-name': child0,
                    'file': {'driver': 'file',
-                            'filename': base_img}}
+                            'filename': self.base_img}}
         child_1 = {'driver': iotests.imgfmt,
                    'node-name': child1,
                    'file': {'driver': 'file',
-                            'filename': new_img}}
+                            'filename': self.new_img}}
         opts = {'driver': 'quorum',
                 'node-name': quorum,
                 'vote-threshold': 1,
diff --git a/tests/qemu-iotests/147 b/tests/qemu-iotests/147
index db34838..09194cc 100755
--- a/tests/qemu-iotests/147
+++ b/tests/qemu-iotests/147
@@ -27,8 +27,6 @@ from iotests import cachemode, imgfmt, qemu_img, qemu_nbd
 
 NBD_PORT = 10811
 
-test_img = os.path.join(iotests.test_dir, 'test.img')
-unix_socket = os.path.join(iotests.test_dir, 'nbd.socket')
 
 
 def flatten_sock_addr(crumpled_address):
@@ -38,6 +36,11 @@ def flatten_sock_addr(crumpled_address):
 
 
 class NBDBlockdevAddBase(iotests.QMPTestCase):
+
+    def setUp(self):
+        self.test_img = os.path.join(self.workdir, 'test.img')
+        self.unix_socket = os.path.join(self.workdir, 'nbd.socket')
+
     def blockdev_add_options(self, address, export=None):
         options = { 'node-name': 'nbd-blockdev',
                     'driver': 'raw',
@@ -70,20 +73,16 @@ class NBDBlockdevAddBase(iotests.QMPTestCase):
 
 class QemuNBD(NBDBlockdevAddBase):
     def setUp(self):
-        qemu_img('create', '-f', iotests.imgfmt, test_img, '64k')
+        NBDBlockdevAddBase.setUp(self)
+        qemu_img('create', '-f', iotests.imgfmt, self.test_img, '64k')
         self.vm = iotests.VM()
         self.vm.launch()
 
     def tearDown(self):
         self.vm.shutdown()
-        os.remove(test_img)
-        try:
-            os.remove(unix_socket)
-        except OSError:
-            pass
 
     def _server_up(self, *args):
-        self.assertEqual(qemu_nbd('-f', imgfmt, test_img, *args), 0)
+        self.assertEqual(qemu_nbd('-f', imgfmt, self.test_img, *args), 0)
 
     def test_inet(self):
         self._server_up('-p', str(NBD_PORT))
@@ -96,21 +95,22 @@ class QemuNBD(NBDBlockdevAddBase):
                          flatten_sock_addr(address))
 
     def test_unix(self):
-        self._server_up('-k', unix_socket)
+        self._server_up('-k', self.unix_socket)
         address = { 'type': 'unix',
-                    'data': { 'path': unix_socket } }
-        self.client_test('nbd+unix://?socket=' + unix_socket,
+                    'data': { 'path': self.unix_socket } }
+        self.client_test('nbd+unix://?socket=' + self.unix_socket,
                          flatten_sock_addr(address))
 
 
 class BuiltinNBD(NBDBlockdevAddBase):
     def setUp(self):
-        qemu_img('create', '-f', iotests.imgfmt, test_img, '64k')
+        NBDBlockdevAddBase.setUp(self)
+        qemu_img('create', '-f', iotests.imgfmt, self.test_img, '64k')
         self.vm = iotests.VM()
         self.vm.launch()
         self.server = iotests.VM('.server')
         self.server.add_drive_raw('if=none,id=nbd-export,' +
-                                  'file=%s,' % test_img +
+                                  'file=%s,' % self.test_img +
                                   'format=%s,' % imgfmt +
                                   'cache=%s' % cachemode)
         self.server.launch()
@@ -118,11 +118,6 @@ class BuiltinNBD(NBDBlockdevAddBase):
     def tearDown(self):
         self.vm.shutdown()
         self.server.shutdown()
-        os.remove(test_img)
-        try:
-            os.remove(unix_socket)
-        except OSError:
-            pass
 
     def _server_up(self, address):
         result = self.server.qmp('nbd-server-start', addr=address)
@@ -173,18 +168,18 @@ class BuiltinNBD(NBDBlockdevAddBase):
 
     def test_unix(self):
         address = { 'type': 'unix',
-                    'data': { 'path': unix_socket } }
+                    'data': { 'path': self.unix_socket } }
         self._server_up(address)
-        self.client_test('nbd+unix:///nbd-export?socket=' + unix_socket,
+        self.client_test('nbd+unix:///nbd-export?socket=' + self.unix_socket,
                          flatten_sock_addr(address), 'nbd-export')
         self._server_down()
 
     def test_fd(self):
         self._server_up({ 'type': 'unix',
-                          'data': { 'path': unix_socket } })
+                          'data': { 'path': self.unix_socket } })
 
         sockfd = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
-        sockfd.connect(unix_socket)
+        sockfd.connect(self.unix_socket)
 
         result = self.vm.send_fd_scm(str(sockfd.fileno()))
         self.assertEqual(result, 0, 'Failed to send socket FD')
diff --git a/tests/qemu-iotests/148 b/tests/qemu-iotests/148
index e01b061..9e66616 100644
--- a/tests/qemu-iotests/148
+++ b/tests/qemu-iotests/148
@@ -22,14 +22,6 @@
 import os
 import iotests
 
-imgs = (os.path.join(iotests.test_dir, 'quorum0.img'),
-        os.path.join(iotests.test_dir, 'quorum1.img'),
-        os.path.join(iotests.test_dir, 'quorum2.img'))
-
-img_conf = (os.path.join(iotests.test_dir, 'quorum0.conf'),
-            os.path.join(iotests.test_dir, 'quorum1.conf'),
-            os.path.join(iotests.test_dir, 'quorum2.conf'))
-
 event_rate = 1000000000
 sector_size = 512
 offset = 10
@@ -48,15 +40,23 @@ sector = "%d"
         file.close()
 
     def setUp(self):
+        self.imgs = (os.path.join(self.workdir, 'quorum0.img'),
+                     os.path.join(self.workdir, 'quorum1.img'),
+                     os.path.join(self.workdir, 'quorum2.img'))
+
+        self.img_conf = (os.path.join(self.workdir, 'quorum0.conf'),
+                         os.path.join(self.workdir, 'quorum1.conf'),
+                         os.path.join(self.workdir, 'quorum2.conf'))
+
         driveopts = ['driver=quorum', 'vote-threshold=2']
         driveopts.append('read-pattern=%s' % self.read_pattern)
-        for i in range(len(imgs)):
-            iotests.qemu_img('create', '-f', iotests.imgfmt, imgs[i], '1M')
-            self.create_blkdebug_file(img_conf[i], i + offset)
+        for i in range(len(self.imgs)):
+            iotests.qemu_img('create', '-f', iotests.imgfmt, self.imgs[i], '1M')
+            self.create_blkdebug_file(self.img_conf[i], i + offset)
             driveopts.append('children.%d.driver=%s' % (i, iotests.imgfmt))
             driveopts.append('children.%d.file.driver=blkdebug' % i)
-            driveopts.append('children.%d.file.config=%s' % (i, img_conf[i]))
-            driveopts.append('children.%d.file.image.filename=%s' % (i, imgs[i]))
+            driveopts.append('children.%d.file.config=%s' % (i, self.img_conf[i]))
+            driveopts.append('children.%d.file.image.filename=%s' % (i, self.imgs[i]))
             driveopts.append('children.%d.node-name=img%d' % (i, i))
         self.vm = iotests.VM()
         self.vm.add_drive(None, opts = ','.join(driveopts))
@@ -64,9 +64,6 @@ sector = "%d"
 
     def tearDown(self):
         self.vm.shutdown()
-        for i in range(len(imgs)):
-            os.remove(imgs[i])
-            os.remove(img_conf[i])
 
     def do_check_event(self, node, sector = 0):
         if node == None:
@@ -107,7 +104,7 @@ sector = "%d"
 
         # I/O errors in different children: all events are emitted
         delay = 10
-        for i in range(len(imgs)):
+        for i in range(len(self.imgs)):
             self.vm.hmp_qemu_io("drive0", "aio_read %d %d" %
                                 ((offset + i) * sector_size, sector_size))
             self.vm.qtest("clock_step %d" % delay)
@@ -119,7 +116,7 @@ sector = "%d"
 
         # I/O errors in different children: all events are emitted
         delay = 2 * event_rate
-        for i in range(len(imgs)):
+        for i in range(len(self.imgs)):
             self.vm.hmp_qemu_io("drive0", "aio_read %d %d" %
                                 ((offset + i) * sector_size, sector_size))
             self.vm.qtest("clock_step %d" % delay)
diff --git a/tests/qemu-iotests/152 b/tests/qemu-iotests/152
index fec546d..07f713d 100644
--- a/tests/qemu-iotests/152
+++ b/tests/qemu-iotests/152
@@ -22,39 +22,34 @@ import os
 import iotests
 from iotests import qemu_img
 
-test_img = os.path.join(iotests.test_dir, 'test.img')
-target_img = os.path.join(iotests.test_dir, 'target.img')
 
 class TestUnaligned(iotests.QMPTestCase):
     def setUp(self):
-        qemu_img('create', '-f', iotests.imgfmt, test_img, '512')
-        self.vm = iotests.VM().add_drive(test_img)
+        self.test_img = os.path.join(self.workdir, 'test.img')
+        self.target_img = os.path.join(self.workdir, 'target.img')
+        qemu_img('create', '-f', iotests.imgfmt, self.test_img, '512')
+        self.vm = iotests.VM().add_drive(self.test_img)
         self.vm.launch()
 
     def tearDown(self):
         self.vm.shutdown()
-        os.remove(test_img)
-        try:
-            os.remove(target_img)
-        except OSError:
-            pass
 
     def test_unaligned(self):
         result = self.vm.qmp('drive-mirror', device='drive0', sync='full',
-                             granularity=65536, target=target_img)
+                             granularity=65536, target=self.target_img)
         self.complete_and_wait()
         self.vm.shutdown()
-        self.assertEqual(iotests.image_size(test_img), iotests.image_size(target_img),
+        self.assertEqual(iotests.image_size(self.test_img), iotests.image_size(self.target_img),
                          "Target size doesn't match source when granularity when unaligend")
 
     def test_unaligned_with_update(self):
         result = self.vm.qmp('drive-mirror', device='drive0', sync='full',
-                             granularity=65536, target=target_img)
+                             granularity=65536, target=self.target_img)
         self.wait_ready()
         self.vm.hmp_qemu_io('drive0', 'write 0 512')
         self.complete_and_wait(wait_ready=False)
         self.vm.shutdown()
-        self.assertEqual(iotests.image_size(test_img), iotests.image_size(target_img),
+        self.assertEqual(iotests.image_size(self.test_img), iotests.image_size(self.target_img),
                          "Target size doesn't match source when granularity when unaligend")
 
 
diff --git a/tests/qemu-iotests/155 b/tests/qemu-iotests/155
index 0b86ea4..66a84e6 100755
--- a/tests/qemu-iotests/155
+++ b/tests/qemu-iotests/155
@@ -25,11 +25,6 @@ import os
 import iotests
 from iotests import qemu_img
 
-back0_img = os.path.join(iotests.test_dir, 'back0.' + iotests.imgfmt)
-back1_img = os.path.join(iotests.test_dir, 'back1.' + iotests.imgfmt)
-back2_img = os.path.join(iotests.test_dir, 'back2.' + iotests.imgfmt)
-source_img = os.path.join(iotests.test_dir, 'source.' + iotests.imgfmt)
-target_img = os.path.join(iotests.test_dir, 'target.' + iotests.imgfmt)
 
 
 # Class variables for controlling its behavior:
@@ -51,10 +46,15 @@ class BaseClass(iotests.QMPTestCase):
     target_real_backing = None
 
     def setUp(self):
-        qemu_img('create', '-f', iotests.imgfmt, back0_img, '1M')
-        qemu_img('create', '-f', iotests.imgfmt, '-b', back0_img, back1_img)
-        qemu_img('create', '-f', iotests.imgfmt, '-b', back1_img, back2_img)
-        qemu_img('create', '-f', iotests.imgfmt, '-b', back2_img, source_img)
+        self.back0_img = os.path.join(self.workdir, 'back0.' + iotests.imgfmt)
+        self.back1_img = os.path.join(self.workdir, 'back1.' + iotests.imgfmt)
+        self.back2_img = os.path.join(self.workdir, 'back2.' + iotests.imgfmt)
+        self.source_img = os.path.join(self.workdir, 'source.' + iotests.imgfmt)
+        self.target_img = os.path.join(self.workdir, 'target.' + iotests.imgfmt)
+        qemu_img('create', '-f', iotests.imgfmt, self.back0_img, '1M')
+        qemu_img('create', '-f', iotests.imgfmt, '-b', self.back0_img, self.back1_img)
+        qemu_img('create', '-f', iotests.imgfmt, '-b', self.back1_img, self.back2_img)
+        qemu_img('create', '-f', iotests.imgfmt, '-b', self.back2_img, self.source_img)
 
         self.vm = iotests.VM()
         self.vm.add_drive(None, '', 'none')
@@ -66,7 +66,7 @@ class BaseClass(iotests.QMPTestCase):
                              node_name='source',
                              driver=iotests.imgfmt,
                              file={'driver': 'file',
-                                   'filename': source_img})
+                                   'filename': self.source_img})
         self.assert_qmp(result, 'return', {})
 
         result = self.vm.qmp('x-blockdev-insert-medium',
@@ -78,15 +78,15 @@ class BaseClass(iotests.QMPTestCase):
         if self.existing:
             if self.target_backing:
                 qemu_img('create', '-f', iotests.imgfmt,
-                         '-b', self.target_backing, target_img, '1M')
+                         '-b', self.target_backing, self.target_img, '1M')
             else:
-                qemu_img('create', '-f', iotests.imgfmt, target_img, '1M')
+                qemu_img('create', '-f', iotests.imgfmt, self.target_img, '1M')
 
             if self.cmd == 'blockdev-mirror':
                 options = { 'node-name': 'target',
                             'driver': iotests.imgfmt,
                             'file': { 'driver': 'file',
-                                      'filename': target_img } }
+                                      'filename': self.target_img } }
                 if self.target_blockdev_backing:
                     options['backing'] = self.target_blockdev_backing
 
@@ -95,14 +95,6 @@ class BaseClass(iotests.QMPTestCase):
 
     def tearDown(self):
         self.vm.shutdown()
-        os.remove(source_img)
-        os.remove(back2_img)
-        os.remove(back1_img)
-        os.remove(back0_img)
-        try:
-            os.remove(target_img)
-        except OSError:
-            pass
 
     def findBlockNode(self, node_name, id=None):
         if id:
@@ -124,13 +116,13 @@ class BaseClass(iotests.QMPTestCase):
         node = self.findBlockNode('source')
 
         self.assert_qmp(node, 'image' + '/backing-image' * 0 + '/filename',
-                        source_img)
+                        self.source_img)
         self.assert_qmp(node, 'image' + '/backing-image' * 1 + '/filename',
-                        back2_img)
+                        self.back2_img)
         self.assert_qmp(node, 'image' + '/backing-image' * 2 + '/filename',
-                        back1_img)
+                        self.back1_img)
         self.assert_qmp(node, 'image' + '/backing-image' * 3 + '/filename',
-                        back0_img)
+                        self.back0_img)
         self.assert_qmp_absent(node, 'image' + '/backing-image' * 4)
 
     def assertCorrectBackingImage(self, node, default_image):
@@ -163,7 +155,7 @@ class MirrorBaseClass(BaseClass):
             else:
                 mode = 'absolute-paths'
             result = self.vm.qmp(self.cmd, device='drive0', sync=sync,
-                                 target=target_img, format=iotests.imgfmt,
+                                 target=self.target_img, format=iotests.imgfmt,
                                  mode=mode, node_name='target')
 
         self.assert_qmp(result, 'return', {})
@@ -186,14 +178,14 @@ class MirrorBaseClass(BaseClass):
         self.runMirror('top')
 
         node = self.findBlockNode('target', 'drive0')
-        self.assertCorrectBackingImage(node, back2_img)
+        self.assertCorrectBackingImage(node, self.back2_img)
         self.assertIntactSourceBackingChain()
 
     def testNone(self):
         self.runMirror('none')
 
         node = self.findBlockNode('target', 'drive0')
-        self.assertCorrectBackingImage(node, source_img)
+        self.assertCorrectBackingImage(node, self.source_img)
         self.assertIntactSourceBackingChain()
 
 
@@ -233,7 +225,7 @@ class TestCommit(BaseClass):
     existing = False
 
     def testCommit(self):
-        result = self.vm.qmp('block-commit', device='drive0', base=back1_img)
+        result = self.vm.qmp('block-commit', device='drive0', base=self.back1_img)
         self.assert_qmp(result, 'return', {})
 
         self.vm.event_wait('BLOCK_JOB_READY')
@@ -245,9 +237,9 @@ class TestCommit(BaseClass):
 
         node = self.findBlockNode(None, 'drive0')
         self.assert_qmp(node, 'image' + '/backing-image' * 0 + '/filename',
-                        back1_img)
+                        self.back1_img)
         self.assert_qmp(node, 'image' + '/backing-image' * 1 + '/filename',
-                        back0_img)
+                        self.back0_img)
         self.assert_qmp_absent(node, 'image' + '/backing-image' * 2 +
                                '/filename')
 
diff --git a/tests/qemu-iotests/163 b/tests/qemu-iotests/163
index 4038423..7940618 100644
--- a/tests/qemu-iotests/163
+++ b/tests/qemu-iotests/163
@@ -21,8 +21,6 @@
 import os, random, iotests, struct, qcow2
 from iotests import qemu_img, qemu_io, image_size
 
-test_img = os.path.join(iotests.test_dir, 'test.img')
-check_img = os.path.join(iotests.test_dir, 'check.img')
 
 def size_to_int(str):
     suff = ['B', 'K', 'M', 'G', 'T']
@@ -81,41 +79,39 @@ class ShrinkBaseClass(iotests.QMPTestCase):
     }
 
     def setUp(self):
+        self.test_img = os.path.join(self.workdir, 'test.img')
+        self.check_img = os.path.join(self.workdir, 'check.img')
         if iotests.imgfmt == 'raw':
-            qemu_img('create', '-f', iotests.imgfmt, test_img, self.image_len)
-            qemu_img('create', '-f', iotests.imgfmt, check_img,
+            qemu_img('create', '-f', iotests.imgfmt, self.test_img, self.image_len)
+            qemu_img('create', '-f', iotests.imgfmt, self.check_img,
                      self.shrink_size)
         else:
             qemu_img('create', '-f', iotests.imgfmt,
                      '-o', 'cluster_size=' + self.cluster_size +
                      ',refcount_bits=' + self.refcount_bits,
-                     test_img, self.image_len)
+                     self.test_img, self.image_len)
             qemu_img('create', '-f', iotests.imgfmt,
                      '-o', 'cluster_size=%s'% self.cluster_size,
-                     check_img, self.shrink_size)
-        qemu_io('-c', 'write -P 0xff 0 ' + self.shrink_size, check_img)
-
-    def tearDown(self):
-        os.remove(test_img)
-        os.remove(check_img)
+                     self.check_img, self.shrink_size)
+        qemu_io('-c', 'write -P 0xff 0 ' + self.shrink_size, self.check_img)
 
     def image_verify(self):
-        self.assertEqual(image_size(test_img), image_size(check_img),
+        self.assertEqual(image_size(self.test_img), image_size(self.check_img),
                          "Verifying image size")
-        self.image_check[iotests.imgfmt](self, test_img)
+        self.image_check[iotests.imgfmt](self, self.test_img)
 
         if iotests.imgfmt == 'raw':
             return
-        self.assertEqual(qemu_img('check', test_img), 0,
+        self.assertEqual(qemu_img('check', self.test_img), 0,
                          "Verifying image corruption")
 
     def test_empty_image(self):
-        qemu_img('resize',  '-f', iotests.imgfmt, '--shrink', test_img,
+        qemu_img('resize',  '-f', iotests.imgfmt, '--shrink', self.test_img,
                  self.shrink_size)
 
         self.assertEqual(
-            qemu_io('-c', 'read -P 0x00 %s'%self.shrink_size, test_img),
-            qemu_io('-c', 'read -P 0x00 %s'%self.shrink_size, check_img),
+            qemu_io('-c', 'read -P 0x00 %s'%self.shrink_size, self.test_img),
+            qemu_io('-c', 'read -P 0x00 %s'%self.shrink_size, self.check_img),
             "Verifying image content")
 
         self.image_verify()
@@ -124,12 +120,12 @@ class ShrinkBaseClass(iotests.QMPTestCase):
         for offs in range(0, size_to_int(self.image_len),
                           size_to_int(self.chunk_size)):
             qemu_io('-c', 'write -P 0xff %d %s' % (offs, self.chunk_size),
-                    test_img)
+                    self.test_img)
 
-        qemu_img('resize',  '-f', iotests.imgfmt, '--shrink', test_img,
+        qemu_img('resize',  '-f', iotests.imgfmt, '--shrink', self.test_img,
                  self.shrink_size)
 
-        self.assertEqual(qemu_img("compare", test_img, check_img), 0,
+        self.assertEqual(qemu_img("compare", self.test_img, self.check_img), 0,
                          "Verifying image content")
 
         self.image_verify()
@@ -140,12 +136,12 @@ class ShrinkBaseClass(iotests.QMPTestCase):
         random.shuffle(offs_list)
         for offs in offs_list:
             qemu_io('-c', 'write -P 0xff %d %s' % (offs, self.chunk_size),
-                    test_img)
+                    self.test_img)
 
-        qemu_img('resize',  '-f', iotests.imgfmt, '--shrink', test_img,
+        qemu_img('resize',  '-f', iotests.imgfmt, '--shrink', self.test_img,
                  self.shrink_size)
 
-        self.assertEqual(qemu_img("compare", test_img, check_img), 0,
+        self.assertEqual(qemu_img("compare", self.test_img, self.check_img), 0,
                          "Verifying image content")
 
         self.image_verify()
diff --git a/tests/qemu-iotests/165 b/tests/qemu-iotests/165
index a3932db..6672fa9 100755
--- a/tests/qemu-iotests/165
+++ b/tests/qemu-iotests/165
@@ -23,7 +23,6 @@ import re
 import iotests
 from iotests import qemu_img
 
-disk = os.path.join(iotests.test_dir, 'disk')
 disk_size = 0x40000000 # 1G
 
 # regions for qemu_io: (start, count) in bytes
@@ -36,16 +35,14 @@ regions2 = ((0x10000000, 0x20000),
 class TestPersistentDirtyBitmap(iotests.QMPTestCase):
 
     def setUp(self):
-        qemu_img('create', '-f', iotests.imgfmt, disk, str(disk_size))
-
-    def tearDown(self):
-        os.remove(disk)
+        self.disk = os.path.join(self.workdir, 'disk')
+        qemu_img('create', '-f', iotests.imgfmt, self.disk, str(disk_size))
 
     def mkVm(self):
-        return iotests.VM().add_drive(disk)
+        return iotests.VM().add_drive(self.disk)
 
     def mkVmRo(self):
-        return iotests.VM().add_drive(disk, opts='readonly=on')
+        return iotests.VM().add_drive(self.disk, opts='readonly=on')
 
     def getSha256(self):
         result = self.vm.qmp('x-debug-block-dirty-bitmap-sha256',
-- 
2.9.5

^ permalink raw reply related	[flat|nested] 37+ messages in thread

* [Qemu-devel] [PATCH v5 09/10] qemu-iotests: add option to save temp files on error
  2017-10-17 16:31 [Qemu-devel] [PATCH v5 00/10] qemu-iotests improvements Jeff Cody
                   ` (7 preceding siblings ...)
  2017-10-17 16:31 ` [Qemu-devel] [PATCH v5 08/10] qemu-iotests: modify python tests to run from subdir Jeff Cody
@ 2017-10-17 16:31 ` Jeff Cody
  2017-10-18 14:33   ` Eric Blake
  2017-10-17 16:31 ` [Qemu-devel] [PATCH v5 10/10] qemu-iotests: add support for running multi-threaded iotests Jeff Cody
  9 siblings, 1 reply; 37+ messages in thread
From: Jeff Cody @ 2017-10-17 16:31 UTC (permalink / raw)
  To: qemu-devel; +Cc: qemu-block, jsnow, stefanha, kwolf, eblake

Now that ./check takes care of cleaning up after each tests, it
can also selectively not clean up.  Add option to leave all output from
tests intact if that test encountered an error.

Signed-off-by: Jeff Cody <jcody@redhat.com>
---
 tests/qemu-iotests/check | 13 ++++++++++++-
 1 file changed, 12 insertions(+), 1 deletion(-)

diff --git a/tests/qemu-iotests/check b/tests/qemu-iotests/check
index 057ea39..a66f7b0 100755
--- a/tests/qemu-iotests/check
+++ b/tests/qemu-iotests/check
@@ -125,6 +125,7 @@ sortme=false
 expunge=true
 have_test_arg=false
 cachemode=false
+save_on_err=false
 
 tmp="${TEST_DIR}"/$$
 rm -f $tmp.list $tmp.tmp $tmp.sed
@@ -263,6 +264,8 @@ other options
     -o options          -o options to pass to qemu-img create/convert
     -T                  output timestamps
     -c mode             cache mode
+    -s                  save test scratch directory on test failure
+
 
 testlist options
     -g group[,group...]        include tests from these groups
@@ -435,6 +438,10 @@ testlist options
             xgroup=true
             xpand=false
             ;;
+        -s)
+            save_on_err=true
+            xpand=false
+            ;;
         '[0-9][0-9][0-9] [0-9][0-9][0-9][0-9]')
             echo "No tests?"
             status=1
@@ -853,7 +860,11 @@ do
         _cleanup_protocols
         _cleanup_qemu
         )
-        rm -rf "$TEST_DIR_SEQ"
+
+        if [ "$save_on_err" != "true" ] || [ "$err" != "true" ]
+        then
+            rm -rf "$TEST_DIR_SEQ"
+        fi
 
     fi
 
-- 
2.9.5

^ permalink raw reply related	[flat|nested] 37+ messages in thread

* [Qemu-devel] [PATCH v5 10/10] qemu-iotests: add support for running multi-threaded iotests
  2017-10-17 16:31 [Qemu-devel] [PATCH v5 00/10] qemu-iotests improvements Jeff Cody
                   ` (8 preceding siblings ...)
  2017-10-17 16:31 ` [Qemu-devel] [PATCH v5 09/10] qemu-iotests: add option to save temp files on error Jeff Cody
@ 2017-10-17 16:31 ` Jeff Cody
  2017-10-18  3:45   ` Jeff Cody
  9 siblings, 1 reply; 37+ messages in thread
From: Jeff Cody @ 2017-10-17 16:31 UTC (permalink / raw)
  To: qemu-devel; +Cc: qemu-block, jsnow, stefanha, kwolf, eblake

This adds support for running qemu-iotests in an arbitrary number
of sub-processes, so that tests can be run in parallel.

This necessarily changes the output format, although it should still
be familiar.  If you run in a single thread, the output format will
largely be the same as before this patch.

To run in more than one process, use the '-j num' option, e.g.:
  ./check -qcow2 -j 5

Some caveats:

    * Some output format options, such as timestamps, are currently
      not compatible with multiple jobs.  If you select multiple
      jobs, timestamps will be disabled.

    * Some tests may be more prone to failure with multiple jobs.
      This isn't a flaw of multiple jobs per se, but rather of
      fragile tests.  Some tests (181, 183) are very sensitive in
      timing, and high cpu loads can cause them to fail.  It may be
      worth adding support for 'single-thread only' tests in subsequent
      patches, that complete designated single-thread jobs at the end.

    * Running protocol tests multi-threaded may fail, as multiple
      tests may try to bind the same address.

If '-j' is not specified, the default is a single iotest being run
at a time.

Signed-off-by: Jeff Cody <jcody@redhat.com>
---
 tests/qemu-iotests/check      | 427 +++++++++++++++++++++++++++++-------------
 tests/qemu-iotests/common.rc  |   2 +-
 tests/qemu-iotests/iotests.py |   4 +-
 3 files changed, 297 insertions(+), 136 deletions(-)

diff --git a/tests/qemu-iotests/check b/tests/qemu-iotests/check
index a66f7b0..363617e 100755
--- a/tests/qemu-iotests/check
+++ b/tests/qemu-iotests/check
@@ -26,6 +26,8 @@ n_bad=0
 bad=""
 notrun=""
 interrupt=true
+TEST_DIR_SEQ="$TEST_DIR"
+MAX_JOBS=1
 
 # by default don't output timestamps
 timestamp=${TIMESTAMP:=false}
@@ -125,6 +127,7 @@ sortme=false
 expunge=true
 have_test_arg=false
 cachemode=false
+multijob=false
 save_on_err=false
 
 tmp="${TEST_DIR}"/$$
@@ -220,6 +223,11 @@ s/ .*//p
         CACHEMODE_IS_DEFAULT=false
         cachemode=false
         continue
+    elif $multijob
+    then
+        MAX_JOBS="$r"
+        multijob=false
+        continue
     fi
 
     xpand=true
@@ -262,9 +270,10 @@ other options
     -misalign           misalign memory allocations
     -n                  show me, do not run tests
     -o options          -o options to pass to qemu-img create/convert
-    -T                  output timestamps
+    -T                  output timestamps, disabled if using '-j'
     -c mode             cache mode
     -s                  save test scratch directory on test failure
+    -j num              run tests in 'num' processes
 
 
 testlist options
@@ -442,6 +451,10 @@ testlist options
             save_on_err=true
             xpand=false
             ;;
+        -j)
+            multijob=true
+            xpand=false
+            ;;
         '[0-9][0-9][0-9] [0-9][0-9][0-9][0-9]')
             echo "No tests?"
             status=1
@@ -506,6 +519,20 @@ BEGIN        { for (t='$start'; t<='$end'; t++) printf "%03d\n",t }' \
 
 done
 
+# No need for multi-process support, and this keeps output simpler
+if $showme
+then
+    MAX_JOBS=1
+fi
+
+# TODO: Change test output format so that this can be useful
+#       with multi-process jobs
+if $timestamp && [ $MAX_JOBS -gt 1 ]
+then
+    echo "Not showing timestamps with multi-job test"
+    timestamp=false
+fi
+
 # Set qemu-io cache mode with $CACHEMODE we have
 QEMU_IO_OPTIONS="$QEMU_IO_OPTIONS --cache $CACHEMODE"
 
@@ -670,8 +697,11 @@ END        { if (NR > 0) {
 
         if [ ! -z "$notrun" ]
         then
-            echo "Not run:$notrun"
-            echo "Not run:$notrun" >>check.log
+            # if run with $MAX_JOBS > 1, this will likely be
+            # out of order
+            notrun=$(echo $notrun|tr " " "\n"|sort|tr "\n" " ")
+            echo "Not run: $notrun"
+            echo "Not run: $notrun" >>check.log
         fi
         if [ ! -z "$n_bad" -a $n_bad != 0 ]
         then
@@ -694,7 +724,7 @@ END        { if (NR > 0) {
     rm -f $tmp.*
 }
 
-trap "_wrapup; exit \$status" 0 1 2 3 15
+trap "_wait_to_finish; _wrapup; exit \$status" 0 1 2 3 15
 
 [ -f $TIMESTAMP_FILE ] || touch $TIMESTAMP_FILE
 
@@ -718,11 +748,235 @@ seq="check"
 
 [ -n "$TESTS_REMAINING_LOG" ] && echo $list > $TESTS_REMAINING_LOG
 
+# Execute actual test.  This will be run in a background process.
+_do_test()
+{
+    local seq=$1
+    local err=false
+    local tmp="${TEST_DIR}/$seq/$seq"
+    local TEST_DIR_SEQ=$TEST_DIR/$seq
+
+    _wallclock > "${TEST_DIR}/$seq.start.clock"
+    $timestamp && printf %s "        [$(date "+%T")]"
+
+    if [ "$(head -n 1 "$source_iotests/$seq")" == "#!/usr/bin/env python" ]; then
+        run_command="$PYTHON $seq"
+    else
+        run_command="./$seq"
+    fi
+    export OUTPUT_DIR=$PWD
+    if $debug; then
+        # Do this in a sub-shell, so we are operating on the right
+        # TEST_DIR / QEMU_TEST_DIR
+        (
+        export TEST_DIR=$TEST_DIR_SEQ
+        cd "$source_iotests";
+        . ./common.config
+        . ./common.rc
+            MALLOC_PERTURB_=${MALLOC_PERTURB_:-$(($RANDOM % 255 + 1))} \
+            $run_command -d 2>&1 | tee $tmp.out
+        )
+    else
+        # Do this in a sub-shell, so we are operating on the right
+        # TEST_DIR / QEMU_TEST_DIR
+        (
+        export TEST_DIR=$TEST_DIR_SEQ
+        cd "$source_iotests";
+        . ./common.config
+        . ./common.rc
+            MALLOC_PERTURB_=${MALLOC_PERTURB_:-$(($RANDOM % 255 + 1))} \
+            $run_command >$tmp.out 2>&1
+        )
+    fi
+    sts=$?
+    $timestamp && _timestamp
+    _wallclock > "${TEST_DIR}/$seq.stop.clock"
+
+    if [ -f core ]
+    then
+        printf " [dumped core]"
+        mv core $seq.core
+        err=true
+    fi
+
+    if [ ! -f $seq.notrun ]
+    then
+        if [ $sts -ne 0 ]
+        then
+            printf %s " [failed, exit status $sts]" > "$TEST_DIR/$seq.err"
+            err=true
+        fi
+    fi
+
+
+    # Do this in a sub-shell, so we are operating on the right
+    # TEST_DIR / QEMU_TEST_DIR
+    (
+    export TEST_DIR=$TEST_DIR_SEQ
+    cd "$source_iotests";
+    . ./common.config
+    . ./common.rc
+    . ./common.qemu
+
+    _cleanup_protocols
+    _cleanup_qemu
+    )
+
+    if [ "$err" == "true" ]
+    then
+        touch "$TEST_DIR/$seq.err"
+    fi
+}
+
+# Runs after we detect a test has completed
+function _check_results()
+{
+    local seq=$1
+    local err=false
+    local localtmp="${TEST_DIR}/$seq/$seq"
+    local TEST_DIR_SEQ=$TEST_DIR/$seq
+    local success=true
+
+    if [ -f $seq.notrun ]
+    then
+        if [ $MAX_JOBS -gt 1 ]
+        then
+            printf "$seq   "
+        fi
+        $timestamp || printf " [not run] "
+        $timestamp && printf " [not run]" && printf %s "        $seq -- "
+        cat $seq.notrun
+        notrun="$notrun $seq"
+        success=false
+    else
+        reference="$source_iotests/$seq.out"
+        reference_machine="$source_iotests/$seq.$QEMU_DEFAULT_MACHINE.out"
+        if [ -f "$reference_machine" ]; then
+            reference="$reference_machine"
+        fi
+
+        reference_format="$source_iotests/$seq.out.$IMGFMT"
+        if [ -f "$reference_format" ]; then
+            reference="$reference_format"
+        fi
+
+        if [ "$CACHEMODE" = "none" ]; then
+            [ -f "$source_iotests/$seq.out.nocache" ] && reference="$source_iotests/$seq.out.nocache"
+        fi
+
+        if [ ! -f "$reference" ]
+        then
+            echo " - no qualified output"
+        else
+            if diff -w "$reference" $localtmp.out >/dev/null 2>&1
+            then
+                if $err
+                then
+                    :
+                else
+                    stop=$(cat "$TEST_DIR/$seq.stop.clock")
+                    start=$(cat "$TEST_DIR/$seq.start.clock")
+                    echo "$seq `expr $stop - $start`" >>$tmp.time
+                fi
+            else
+                printf " - output mismatch (see $seq.out.bad)"
+                mv $localtmp.out $seq.out.bad
+                $diff -w "$reference" $(realpath $seq.out.bad)
+                err=true
+            fi
+        fi
+    fi
+
+    if [ "$err" == "true" ] || [ -f "$TEST_DIR/$seq.err" ]
+    then
+        if [ $MAX_JOBS -gt 1 ]
+        then
+            printf "\n$seq    [  fail ] "
+        fi
+        if [ -f "$TEST_DIR/$seq.err" ]
+        then
+            cat "$TEST_DIR/$seq.err"
+        fi
+        success=false
+        err=true
+        bad="$bad $seq"
+        n_bad=`expr $n_bad + 1`
+        quick=false
+    fi
+
+
+    if [ "$save_on_err" != "true" ] || [ "$err" != "true" ]
+    then
+        rm -rf "$TEST_DIR_SEQ"
+    fi
+
+    [ -f $seq.notrun ] || try=`expr $try + 1`
+
+    rm -f "$TEST_DIR/$seq.stop.clock" "$TEST_DIR/$seq.start.clock"
+
+    if [ $MAX_JOBS -eq 1 ] || [ "$success" == "false" ]
+    then
+        printf "\n"
+    fi
+}
+
+# Even if interrupted, we want to wait until
+# all tests have completed, so we can properly clean
+# up after them via _check_results
+function _wait_to_finish()
+{
+    while [ $jobs_running -gt 0 ]
+    do
+        i=0
+        while [ $jobs_running -gt 0 ]
+        do
+            job=${job_slots[$i]}
+            if [ $job -gt 0 ]
+            then
+                if [ -z "$(ps -o pid -h -p $job)" ]
+                then
+                    _check_results ${job_seq[$i]}
+                    job_slots[$i]=0
+                    job_seq[$i]=-1
+                    let jobs_running--
+                fi
+            fi
+            let i++
+            let i=`expr $i % $MAX_JOBS`
+            sleep 0.1
+        done
+    done
+}
+
+job_slots=
+
+jobs_running=0
+
+for i in `seq 0 $MAX_JOBS`
+do
+    job_slots[$i]=0
+done
+
+
+# Now iterate of the list of tests
 for seq in $list
 do
-    TEST_DIR_SEQ=$TEST_DIR/$seq
-    err=false
+
+    rm -f $seq.out.bad
+    lasttime=`sed -n -e "/^$seq /s/.* //p" <$TIMESTAMP_FILE`
     printf %s "$seq"
+    if [ "X$lasttime" != X ]; then
+        printf %s " ${lasttime}s ..."
+    else
+        printf "        "        # prettier output with timestamps.
+    fi
+    rm -f core $seq.notrun
+    if [ $MAX_JOBS -gt 1 ]
+    then
+        printf "\n"
+    fi
+
+    err=false
     if [ -n "$TESTS_REMAINING_LOG" ] ; then
         sed -e "s/$seq//" -e 's/  / /' -e 's/^ *//' $TESTS_REMAINING_LOG > $TESTS_REMAINING_LOG.tmp
         mv $TESTS_REMAINING_LOG.tmp $TESTS_REMAINING_LOG
@@ -743,144 +997,51 @@ do
         echo " - no such test?"
         echo "/^$seq\$/d" >>$tmp.expunged
     else
-        # really going to try and run this one
-        #
-        rm -f $seq.out.bad
-        lasttime=`sed -n -e "/^$seq /s/.* //p" <$TIMESTAMP_FILE`
-        if [ "X$lasttime" != X ]; then
-                printf %s " ${lasttime}s ..."
-        else
-                printf "        "        # prettier output with timestamps.
-        fi
-        rm -f core $seq.notrun
 
-        start=`_wallclock`
-        $timestamp && printf %s "        [$(date "+%T")]"
-
-        if [ "$(head -n 1 "$source_iotests/$seq")" == "#!/usr/bin/env python" ]; then
-            run_command="$PYTHON $seq"
-        else
-            run_command="./$seq"
-        fi
-        export OUTPUT_DIR=$PWD
-        if $debug; then
-            # Do this in a sub-shell, so we are operating on the right
-            # TEST_DIR / QEMU_TEST_DIR
-            (
-            export TEST_DIR=$TEST_DIR_SEQ
-            cd "$source_iotests";
-            . ./common.config
-            . ./common.rc
-            MALLOC_PERTURB_=${MALLOC_PERTURB_:-$(($RANDOM % 255 + 1))} \
-                    $run_command -d 2>&1 | tee $tmp.out
-            )
-        else
-            # Do this in a sub-shell, so we are operating on the right
-            # TEST_DIR / QEMU_TEST_DIR
-            (
-            export TEST_DIR=$TEST_DIR_SEQ
-            cd "$source_iotests";
-            . ./common.config
-            . ./common.rc
-            MALLOC_PERTURB_=${MALLOC_PERTURB_:-$(($RANDOM % 255 + 1))} \
-                    $run_command >$tmp.out 2>&1
-            )
-        fi
-        sts=$?
-        $timestamp && _timestamp
-        stop=`_wallclock`
-
-        if [ -f core ]
-        then
-            printf " [dumped core]"
-            mv core $seq.core
-            err=true
-        fi
-
-        if [ -f $seq.notrun ]
+        if [ $MAX_JOBS -eq 1 ]
         then
-            $timestamp || printf " [not run] "
-            $timestamp && echo " [not run]" && printf %s "        $seq -- "
-            cat $seq.notrun
-            notrun="$notrun $seq"
+            # This way we can mimic the same output format before multi-process test
+            # support was added, if we are running one test at a time
+            _do_test $seq
+            _check_results $seq
         else
-            if [ $sts -ne 0 ]
-            then
-                printf %s " [failed, exit status $sts]"
-                err=true
-            fi
-
-            reference="$source_iotests/$seq.out"
-            reference_machine="$source_iotests/$seq.$QEMU_DEFAULT_MACHINE.out"
-            if [ -f "$reference_machine" ]; then
-                reference="$reference_machine"
-            fi
-
-            reference_format="$source_iotests/$seq.out.$IMGFMT"
-            if [ -f "$reference_format" ]; then
-                reference="$reference_format"
-            fi
-
-            if [ "$CACHEMODE" = "none" ]; then
-                [ -f "$source_iotests/$seq.out.nocache" ] && reference="$source_iotests/$seq.out.nocache"
-            fi
-
-            if [ ! -f "$reference" ]
-            then
-                echo " - no qualified output"
-                err=true
-            else
-                if diff -w "$reference" $tmp.out >/dev/null 2>&1
+            # loop until a job slot becomes free
+            i=0
+            while true
+            do
+                job=${job_slots[$i]}
+                if [ $job -le 0 ]
+                then
+                    let jobs_running++
+                    job_seq[$i]=$seq
+                    # Execute the test in the background
+                    _do_test $seq &
+                    job_slots[$i]=$!
+                    break
+                elif [ -z "$(ps -o pid -h -p $job)" ]
                 then
-                    echo ""
-                    if $err
-                    then
-                        :
-                    else
-                        echo "$seq `expr $stop - $start`" >>$tmp.time
-                    fi
-                else
-                    echo " - output mismatch (see $seq.out.bad)"
-                    mv $tmp.out $seq.out.bad
-                    $diff -w "$reference" $(realpath $seq.out.bad)
-                    err=true
+                    # job has completed
+                    _check_results ${job_seq[$i]}
+                    job_slots[$i]=0
+                    job_seq[$i]=-1
+                    let jobs_running--
+                    continue
                 fi
-            fi
-        fi
-
-        # Do this in a sub-shell, so we are operating on the right
-        # TEST_DIR / QEMU_TEST_DIR
-        (
-        export TEST_DIR=$TEST_DIR_SEQ
-        cd "$source_iotests";
-        . ./common.config
-        . ./common.rc
-        . ./common.qemu
 
-        _cleanup_protocols
-        _cleanup_qemu
-        )
+                let i++
+                let i=`expr $i % $MAX_JOBS`
 
-        if [ "$save_on_err" != "true" ] || [ "$err" != "true" ]
-        then
-            rm -rf "$TEST_DIR_SEQ"
+                if [ $i -eq 0 ]
+                then
+                    sleep 0.25
+                fi
+            done
         fi
-
     fi
-
-    # come here for each test, except when $showme is true
-    #
-    if $err
-    then
-        bad="$bad $seq"
-        n_bad=`expr $n_bad + 1`
-        quick=false
-    fi
-    [ -f $seq.notrun ] || try=`expr $try + 1`
-
-    seq="after_$seq"
 done
 
+_wait_to_finish
+
 interrupt=false
 status=`expr $n_bad`
 exit
diff --git a/tests/qemu-iotests/common.rc b/tests/qemu-iotests/common.rc
index b26b02f..273a815 100644
--- a/tests/qemu-iotests/common.rc
+++ b/tests/qemu-iotests/common.rc
@@ -392,7 +392,7 @@ _img_info()
 #
 _notrun()
 {
-    echo "$*" >"$OUTPUT_DIR/$seq.notrun"
+    printf "$*" >"$OUTPUT_DIR/$seq.notrun"
     echo "$seq not run: $*"
     status=0
     exit
diff --git a/tests/qemu-iotests/iotests.py b/tests/qemu-iotests/iotests.py
index 7ff400a..11dfcf5 100644
--- a/tests/qemu-iotests/iotests.py
+++ b/tests/qemu-iotests/iotests.py
@@ -427,8 +427,8 @@ def notrun(reason):
     # Each test in qemu-iotests has a number ("seq")
     seq = os.path.basename(sys.argv[0])
 
-    open('%s/%s.notrun' % (output_dir, seq), 'wb').write(reason + '\n')
-    print '%s not run: %s' % (seq, reason)
+    open('%s/%s.notrun' % (output_dir, seq), 'wb').write(reason)
+    print '%s not run: %s\n' % (seq, reason)
     sys.exit(0)
 
 def verify_image_format(supported_fmts=[], unsupported_fmts=[]):
-- 
2.9.5

^ permalink raw reply related	[flat|nested] 37+ messages in thread

* Re: [Qemu-devel] [PATCH v5 01/10] qemu-iotests: refuse to run if TEST_DIR contains spaces
  2017-10-17 16:31 ` [Qemu-devel] [PATCH v5 01/10] qemu-iotests: refuse to run if TEST_DIR contains spaces Jeff Cody
@ 2017-10-18  1:03   ` Eric Blake
  2017-10-18  3:05     ` Jeff Cody
  0 siblings, 1 reply; 37+ messages in thread
From: Eric Blake @ 2017-10-18  1:03 UTC (permalink / raw)
  To: Jeff Cody, qemu-devel; +Cc: qemu-block, jsnow, stefanha, kwolf

[-- Attachment #1: Type: text/plain, Size: 1379 bytes --]

On 10/17/2017 11:31 AM, Jeff Cody wrote:
> Currently, not all qemu-iotests work if TEST_DIR has spaces, and they
> also might not be safe.  Refuse to run if TEST_DIR in this case, at
> least until all tests are fixed sometime in the future.
> 
> Signed-off-by: Jeff Cody <jcody@redhat.com>
> ---
>  tests/qemu-iotests/check | 8 ++++++++
>  1 file changed, 8 insertions(+)
> 
> diff --git a/tests/qemu-iotests/check b/tests/qemu-iotests/check
> index e6b6ff7..e2163cc 100755
> --- a/tests/qemu-iotests/check
> +++ b/tests/qemu-iotests/check
> @@ -102,6 +102,14 @@ if [ -z "$TEST_DIR" ]; then
>          TEST_DIR=`pwd`/scratch
>  fi
>  
> +case $TEST_DIR in
> +    *[[:blank:]]*)
> +        echo "The TEST_DIR pathname '$TEST_DIR' contains whitespace. "

Echoes a trailing space. Do we care?

> +        echo "This is currently unsupported by qemu-iotests"

Is it just whitespace, or should we also be wary of other shell
metacharacters (such as quotes or glob characters)?  In test 197, I did
an alternative check for anything that is not alphanumeric, -, or _ (and
allowing / between names).

> +        exit 1
> +        ;;
> +esac
> +
>  if [ ! -e "$TEST_DIR" ]; then
>          mkdir "$TEST_DIR"
>  fi
> 

-- 
Eric Blake, Principal Software Engineer
Red Hat, Inc.           +1-919-301-3266
Virtualization:  qemu.org | libvirt.org


[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 619 bytes --]

^ permalink raw reply	[flat|nested] 37+ messages in thread

* Re: [Qemu-devel] [PATCH v5 03/10] qemu-iotests: automatically clean up bash protocol servers
  2017-10-17 16:31 ` [Qemu-devel] [PATCH v5 03/10] qemu-iotests: automatically clean up bash protocol servers Jeff Cody
@ 2017-10-18  1:15   ` Eric Blake
  2017-10-18 14:46   ` Paolo Bonzini
  1 sibling, 0 replies; 37+ messages in thread
From: Eric Blake @ 2017-10-18  1:15 UTC (permalink / raw)
  To: Jeff Cody, qemu-devel; +Cc: qemu-block, jsnow, stefanha, kwolf

[-- Attachment #1: Type: text/plain, Size: 606 bytes --]

On 10/17/2017 11:31 AM, Jeff Cody wrote:
> For bash tests, this allows 'check' to reap all launch protocol
> servers / processes, after a test has finished running.

Nice stuff!

> 
> Signed-off-by: Jeff Cody <jcody@redhat.com>
> ---
>  tests/qemu-iotests/check     | 13 +++++++
>  tests/qemu-iotests/common.rc | 93 +++++++++++++++++++++++++++++---------------
>  2 files changed, 75 insertions(+), 31 deletions(-)

Reviewed-by: Eric Blake <eblake@redhat.com>

-- 
Eric Blake, Principal Software Engineer
Red Hat, Inc.           +1-919-301-3266
Virtualization:  qemu.org | libvirt.org


[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 619 bytes --]

^ permalink raw reply	[flat|nested] 37+ messages in thread

* Re: [Qemu-devel] [PATCH v5 01/10] qemu-iotests: refuse to run if TEST_DIR contains spaces
  2017-10-18  1:03   ` Eric Blake
@ 2017-10-18  3:05     ` Jeff Cody
  0 siblings, 0 replies; 37+ messages in thread
From: Jeff Cody @ 2017-10-18  3:05 UTC (permalink / raw)
  To: Eric Blake; +Cc: qemu-devel, qemu-block, jsnow, stefanha, kwolf

On Tue, Oct 17, 2017 at 08:03:56PM -0500, Eric Blake wrote:
> On 10/17/2017 11:31 AM, Jeff Cody wrote:
> > Currently, not all qemu-iotests work if TEST_DIR has spaces, and they
> > also might not be safe.  Refuse to run if TEST_DIR in this case, at
> > least until all tests are fixed sometime in the future.
> > 
> > Signed-off-by: Jeff Cody <jcody@redhat.com>
> > ---
> >  tests/qemu-iotests/check | 8 ++++++++
> >  1 file changed, 8 insertions(+)
> > 
> > diff --git a/tests/qemu-iotests/check b/tests/qemu-iotests/check
> > index e6b6ff7..e2163cc 100755
> > --- a/tests/qemu-iotests/check
> > +++ b/tests/qemu-iotests/check
> > @@ -102,6 +102,14 @@ if [ -z "$TEST_DIR" ]; then
> >          TEST_DIR=`pwd`/scratch
> >  fi
> >  
> > +case $TEST_DIR in
> > +    *[[:blank:]]*)
> > +        echo "The TEST_DIR pathname '$TEST_DIR' contains whitespace. "
> 
> Echoes a trailing space. Do we care?
> 

Heh, spurious whitespcae, a bit ironic, I suppose...

Might as well take care of it with a v6, along with expanding the tests as
you hint at below.

> > +        echo "This is currently unsupported by qemu-iotests"
> 
> Is it just whitespace, or should we also be wary of other shell
> metacharacters (such as quotes or glob characters)?  In test 197, I did
> an alternative check for anything that is not alphanumeric, -, or _ (and
> allowing / between names).

I know that '-' works, because for years my work directory has been called
"qemu-kvm".  I'm not sure about globbing characters like *, or quotes, but
probably not a bad idea to exclude them as well (although, someone that
uses '*' in their directory names is probably no stranger to data
catastrophe!).

> 
> > +        exit 1
> > +        ;;
> > +esac
> > +
> >  if [ ! -e "$TEST_DIR" ]; then
> >          mkdir "$TEST_DIR"
> >  fi
> > 
> 
> -- 
> Eric Blake, Principal Software Engineer
> Red Hat, Inc.           +1-919-301-3266
> Virtualization:  qemu.org | libvirt.org
> 

^ permalink raw reply	[flat|nested] 37+ messages in thread

* Re: [Qemu-devel] [PATCH v5 10/10] qemu-iotests: add support for running multi-threaded iotests
  2017-10-17 16:31 ` [Qemu-devel] [PATCH v5 10/10] qemu-iotests: add support for running multi-threaded iotests Jeff Cody
@ 2017-10-18  3:45   ` Jeff Cody
  0 siblings, 0 replies; 37+ messages in thread
From: Jeff Cody @ 2017-10-18  3:45 UTC (permalink / raw)
  To: qemu-devel; +Cc: qemu-block, jsnow, stefanha, kwolf, eblake

On Tue, Oct 17, 2017 at 12:31:55PM -0400, Jeff Cody wrote:
> This adds support for running qemu-iotests in an arbitrary number
> of sub-processes, so that tests can be run in parallel.
> 
> This necessarily changes the output format, although it should still
> be familiar.  If you run in a single thread, the output format will
> largely be the same as before this patch.
> 
> To run in more than one process, use the '-j num' option, e.g.:
>   ./check -qcow2 -j 5
> 
> Some caveats:
> 
>     * Some output format options, such as timestamps, are currently
>       not compatible with multiple jobs.  If you select multiple
>       jobs, timestamps will be disabled.
> 
>     * Some tests may be more prone to failure with multiple jobs.
>       This isn't a flaw of multiple jobs per se, but rather of
>       fragile tests.  Some tests (181, 183) are very sensitive in
>       timing, and high cpu loads can cause them to fail.  It may be
>       worth adding support for 'single-thread only' tests in subsequent
>       patches, that complete designated single-thread jobs at the end.
> 
>     * Running protocol tests multi-threaded may fail, as multiple
>       tests may try to bind the same address.
> 
> If '-j' is not specified, the default is a single iotest being run
> at a time.
> 
> Signed-off-by: Jeff Cody <jcody@redhat.com>
> ---
>  tests/qemu-iotests/check      | 427 +++++++++++++++++++++++++++++-------------
>  tests/qemu-iotests/common.rc  |   2 +-
>  tests/qemu-iotests/iotests.py |   4 +-
>  3 files changed, 297 insertions(+), 136 deletions(-)
> 
> diff --git a/tests/qemu-iotests/check b/tests/qemu-iotests/check
> index a66f7b0..363617e 100755
> --- a/tests/qemu-iotests/check
> +++ b/tests/qemu-iotests/check

[...]

> +
> +# Even if interrupted, we want to wait until
> +# all tests have completed, so we can properly clean
> +# up after them via _check_results
> +function _wait_to_finish()
> +{
> +    while [ $jobs_running -gt 0 ]
> +    do
> +        i=0
> +        while [ $jobs_running -gt 0 ]
> +        do
> +            job=${job_slots[$i]}
> +            if [ $job -gt 0 ]
> +            then
> +                if [ -z "$(ps -o pid -h -p $job)" ]
> +                then
> +                    _check_results ${job_seq[$i]}
> +                    job_slots[$i]=0
> +                    job_seq[$i]=-1
> +                    let jobs_running--
> +                fi
> +            fi
> +            let i++
> +            let i=`expr $i % $MAX_JOBS`
> +            sleep 0.1
> +        done
> +    done

Oops.  That double while loop, while harmless, is spurious.  When I do a v6,
I'll remove the outer one when addressing any other review comments.

 

^ permalink raw reply	[flat|nested] 37+ messages in thread

* Re: [Qemu-devel] [PATCH v5 04/10] qemu-iotests: remove file cleanup from bash tests
  2017-10-17 16:31 ` [Qemu-devel] [PATCH v5 04/10] qemu-iotests: remove file cleanup from bash tests Jeff Cody
@ 2017-10-18 13:46   ` Eric Blake
  2017-10-18 13:56     ` Jeff Cody
  0 siblings, 1 reply; 37+ messages in thread
From: Eric Blake @ 2017-10-18 13:46 UTC (permalink / raw)
  To: Jeff Cody, qemu-devel; +Cc: qemu-block, jsnow, stefanha, kwolf

[-- Attachment #1: Type: text/plain, Size: 5603 bytes --]

On 10/17/2017 11:31 AM, Jeff Cody wrote:
> All files for a given test are now self-contained in a subdirectory,
> and therefore the "./check" script can do all file-related cleanup
> without any help.
> 
> This removes file cleanups from the bash tests.  The only cleanup left
> is whatever is needed to kill any spawned processes; e.g. _cleanup_qemu.
> 
> Signed-off-by: Jeff Cody <jcody@redhat.com>
> ---

>  tests/qemu-iotests/197     |  7 -------

Looks like you have rebased to the current state of the tree.  There may
be a couple more attempting to sneak in before things get merged, but I
trust you'll stay on top of that.

>  156 files changed, 32 insertions(+), 1023 deletions(-)

Fun diffstat, but took me a while to scan through for any mistakes.

> +++ b/tests/qemu-iotests/007
> @@ -27,13 +27,6 @@ echo "QA output created by $seq"
>  here=`pwd`
>  status=1	# failure is the default!
>  
> -_cleanup()
> -{
> -	_cleanup_test_img
> -	true
> -}
> -trap "_cleanup; exit \$status" 0 1 2 3 15

Interesting use of 'true' (why? Since the only call to _cleanup changes
exit status to $status anyways, it does not matter what state $? was
left in after _cleanup)!  Not a problem to see it disappear.

> +++ b/tests/qemu-iotests/028
> @@ -30,14 +30,6 @@ echo "QA output created by $seq"
>  here=`pwd`
>  status=1	# failure is the default!
>  
> -_cleanup()
> -{
> -    _cleanup_qemu
> -    rm -f "${TEST_IMG}.copy"
> -    _cleanup_test_img
> -}
> -trap "_cleanup; exit \$status" 0 1 2 3 15

Is this removal of _cleanup_qemu correct, or does it belong in a
different patch in the series? [1]

> +++ b/tests/qemu-iotests/058
> @@ -29,23 +29,22 @@ echo "QA output created by $seq"
>  here=`pwd`
>  status=1	# failure is the default!
>  
> +# get standard environment, filters and checks
> +. ./common.rc
> +. ./common.filter
> +. ./common.pattern
> +
> +_supported_fmt qcow2
> +_supported_proto file
> +_supported_os Linux
> +_require_command QEMU_NBD
> +# Internal snapshots are (currently) impossible with refcount_bits=1
> +_unsupported_imgopts 'refcount_bits=1[^0-9]'
> +

Code motion...

>  nbd_unix_socket=$TEST_DIR/test_qemu_nbd_socket
>  nbd_snapshot_img="nbd:unix:$nbd_unix_socket"
>  rm -f "${TEST_DIR}/qemu-nbd.pid"
>  
> -_cleanup_nbd()
> -{
> -    local NBD_SNAPSHOT_PID
> -    if [ -f "${TEST_DIR}/qemu-nbd.pid" ]; then
> -        read NBD_SNAPSHOT_PID < "${TEST_DIR}/qemu-nbd.pid"
> -        rm -f "${TEST_DIR}/qemu-nbd.pid"
> -        if [ -n "$NBD_SNAPSHOT_PID" ]; then
> -            kill "$NBD_SNAPSHOT_PID"
> -        fi
> -    fi
> -    rm -f "$nbd_unix_socket"
> -}

...and dropping redundant code that used to be overridden by the common
includes but now would take priority...

> -
>  _wait_for_nbd()
>  {
>      for ((i = 0; i < 300; i++))
> @@ -64,6 +63,7 @@ converted_image=$TEST_IMG.converted
>  _export_nbd_snapshot()
>  {
>      _cleanup_nbd
> +    rm -f "$nbd_unix_socket"
>      $QEMU_NBD -v -t -k "$nbd_unix_socket" "$TEST_IMG" -l $1 &
>      _wait_for_nbd
>  }
> @@ -71,30 +71,11 @@ _export_nbd_snapshot()
>  _export_nbd_snapshot1()
>  {
>      _cleanup_nbd
> +    rm -f "$nbd_unix_socket"

...tweaks to account for the change in common ordering,

>      $QEMU_NBD -v -t -k "$nbd_unix_socket" "$TEST_IMG" -l snapshot.name=$1 &
>      _wait_for_nbd
>  }
>  
> -_cleanup()
> -{
> -    _cleanup_nbd
> -    _cleanup_test_img
> -    rm -f "$converted_image"
> -}
> -trap "_cleanup; exit \$status" 0 1 2 3 15
> -
> -# get standard environment, filters and checks
> -. ./common.rc
> -. ./common.filter
> -. ./common.pattern
> -
> -_supported_fmt qcow2
> -_supported_proto file
> -_supported_os Linux
> -_require_command QEMU_NBD
> -# Internal snapshots are (currently) impossible with refcount_bits=1
> -_unsupported_imgopts 'refcount_bits=1[^0-9]'
> -

...and back to code motion.  This file is different enough from the
usual patterns of cleanups in the rest of the series; should some of
this rearrangement be split into a separate patch?  But only if you have
to respin; if we have nothing else preventing v5 from going in, I don't
think we need the review churn.

> +++ b/tests/qemu-iotests/085
> @@ -37,18 +37,7 @@ snapshot_virt1="snapshot-v1.qcow2"
>  
>  SNAPSHOTS=10
>  
> -_cleanup()
> -{
> -    _cleanup_qemu
> -    for i in $(seq 1 ${SNAPSHOTS})
> -    do
> -        rm -f "${TEST_DIR}/${i}-${snapshot_virt0}"
> -        rm -f "${TEST_DIR}/${i}-${snapshot_virt1}"
> -    done
> -    rm -f "${TEST_IMG}" "${TEST_IMG}.1" "${TEST_IMG}.2" "${TEST_IMG}.base"
> -
> -}
> -trap "_cleanup; exit \$status" 0 1 2 3 15
> +trap "_cleanup_qemu; exit \$status" 0 1 2 3 15

[1] Evidence that the change to 28 may be broken.

> +++ b/tests/qemu-iotests/191
> @@ -31,10 +31,6 @@ MIG_SOCKET="${TEST_DIR}/migrate"
>  
>  _cleanup()
>  {
> -    rm -f "${TEST_IMG}.mid"
> -    rm -f "${TEST_IMG}.ovl2"
> -    rm -f "${TEST_IMG}.ovl3"
> -    _cleanup_test_img
>      _cleanup_qemu
>  }
>  trap "_cleanup; exit \$status" 0 1 2 3 15

Elsewhere, you removed the _cleanup function entirely, and changed the
trap to directly call _cleanup_qemu.  Worth doing here?

It looks like only 28 was broken, and that fix is an obvious pattern, as
well as any other minor tweaks you want to make based on my comments.
With that correction,
Reviewed-by: Eric Blake <eblake@redhat.com>

-- 
Eric Blake, Principal Software Engineer
Red Hat, Inc.           +1-919-301-3266
Virtualization:  qemu.org | libvirt.org


[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 619 bytes --]

^ permalink raw reply	[flat|nested] 37+ messages in thread

* Re: [Qemu-devel] [PATCH v5 04/10] qemu-iotests: remove file cleanup from bash tests
  2017-10-18 13:46   ` Eric Blake
@ 2017-10-18 13:56     ` Jeff Cody
  0 siblings, 0 replies; 37+ messages in thread
From: Jeff Cody @ 2017-10-18 13:56 UTC (permalink / raw)
  To: Eric Blake; +Cc: qemu-devel, qemu-block, jsnow, stefanha, kwolf

On Wed, Oct 18, 2017 at 08:46:46AM -0500, Eric Blake wrote:
> On 10/17/2017 11:31 AM, Jeff Cody wrote:
> > All files for a given test are now self-contained in a subdirectory,
> > and therefore the "./check" script can do all file-related cleanup
> > without any help.
> > 
> > This removes file cleanups from the bash tests.  The only cleanup left
> > is whatever is needed to kill any spawned processes; e.g. _cleanup_qemu.
> > 
> > Signed-off-by: Jeff Cody <jcody@redhat.com>
> > ---
> 
> >  tests/qemu-iotests/197     |  7 -------
> 
> Looks like you have rebased to the current state of the tree.  There may
> be a couple more attempting to sneak in before things get merged, but I
> trust you'll stay on top of that.
> 
> >  156 files changed, 32 insertions(+), 1023 deletions(-)
> 
> Fun diffstat, but took me a while to scan through for any mistakes.
> 
> > +++ b/tests/qemu-iotests/007
> > @@ -27,13 +27,6 @@ echo "QA output created by $seq"
> >  here=`pwd`
> >  status=1	# failure is the default!
> >  
> > -_cleanup()
> > -{
> > -	_cleanup_test_img
> > -	true
> > -}
> > -trap "_cleanup; exit \$status" 0 1 2 3 15
> 
> Interesting use of 'true' (why? Since the only call to _cleanup changes
> exit status to $status anyways, it does not matter what state $? was
> left in after _cleanup)!  Not a problem to see it disappear.
> 
> > +++ b/tests/qemu-iotests/028
> > @@ -30,14 +30,6 @@ echo "QA output created by $seq"
> >  here=`pwd`
> >  status=1	# failure is the default!
> >  
> > -_cleanup()
> > -{
> > -    _cleanup_qemu
> > -    rm -f "${TEST_IMG}.copy"
> > -    _cleanup_test_img
> > -}
> > -trap "_cleanup; exit \$status" 0 1 2 3 15
> 
> Is this removal of _cleanup_qemu correct, or does it belong in a
> different patch in the series? [1]
> 

Nice catch.  I think I had missed that instance before, and then squashed
the change into the wrong patch.  It should be in patch 6.


> > +++ b/tests/qemu-iotests/058
> > @@ -29,23 +29,22 @@ echo "QA output created by $seq"
> >  here=`pwd`
> >  status=1	# failure is the default!
> >  
> > +# get standard environment, filters and checks
> > +. ./common.rc
> > +. ./common.filter
> > +. ./common.pattern
> > +
> > +_supported_fmt qcow2
> > +_supported_proto file
> > +_supported_os Linux
> > +_require_command QEMU_NBD
> > +# Internal snapshots are (currently) impossible with refcount_bits=1
> > +_unsupported_imgopts 'refcount_bits=1[^0-9]'
> > +
> 
> Code motion...
> 
> >  nbd_unix_socket=$TEST_DIR/test_qemu_nbd_socket
> >  nbd_snapshot_img="nbd:unix:$nbd_unix_socket"
> >  rm -f "${TEST_DIR}/qemu-nbd.pid"
> >  
> > -_cleanup_nbd()
> > -{
> > -    local NBD_SNAPSHOT_PID
> > -    if [ -f "${TEST_DIR}/qemu-nbd.pid" ]; then
> > -        read NBD_SNAPSHOT_PID < "${TEST_DIR}/qemu-nbd.pid"
> > -        rm -f "${TEST_DIR}/qemu-nbd.pid"
> > -        if [ -n "$NBD_SNAPSHOT_PID" ]; then
> > -            kill "$NBD_SNAPSHOT_PID"
> > -        fi
> > -    fi
> > -    rm -f "$nbd_unix_socket"
> > -}
> 
> ...and dropping redundant code that used to be overridden by the common
> includes but now would take priority...
> 
> > -
> >  _wait_for_nbd()
> >  {
> >      for ((i = 0; i < 300; i++))
> > @@ -64,6 +63,7 @@ converted_image=$TEST_IMG.converted
> >  _export_nbd_snapshot()
> >  {
> >      _cleanup_nbd
> > +    rm -f "$nbd_unix_socket"
> >      $QEMU_NBD -v -t -k "$nbd_unix_socket" "$TEST_IMG" -l $1 &
> >      _wait_for_nbd
> >  }
> > @@ -71,30 +71,11 @@ _export_nbd_snapshot()
> >  _export_nbd_snapshot1()
> >  {
> >      _cleanup_nbd
> > +    rm -f "$nbd_unix_socket"
> 
> ...tweaks to account for the change in common ordering,
> 
> >      $QEMU_NBD -v -t -k "$nbd_unix_socket" "$TEST_IMG" -l snapshot.name=$1 &
> >      _wait_for_nbd
> >  }
> >  
> > -_cleanup()
> > -{
> > -    _cleanup_nbd
> > -    _cleanup_test_img
> > -    rm -f "$converted_image"
> > -}
> > -trap "_cleanup; exit \$status" 0 1 2 3 15
> > -
> > -# get standard environment, filters and checks
> > -. ./common.rc
> > -. ./common.filter
> > -. ./common.pattern
> > -
> > -_supported_fmt qcow2
> > -_supported_proto file
> > -_supported_os Linux
> > -_require_command QEMU_NBD
> > -# Internal snapshots are (currently) impossible with refcount_bits=1
> > -_unsupported_imgopts 'refcount_bits=1[^0-9]'
> > -
> 
> ...and back to code motion.  This file is different enough from the
> usual patterns of cleanups in the rest of the series; should some of
> this rearrangement be split into a separate patch?  But only if you have
> to respin; if we have nothing else preventing v5 from going in, I don't
> think we need the review churn.
> 

I'll do that.  We'll need a v6, there have been a couple other things you've
pointed out, and I've found a couple small bugs as well.

> > +++ b/tests/qemu-iotests/085
> > @@ -37,18 +37,7 @@ snapshot_virt1="snapshot-v1.qcow2"
> >  
> >  SNAPSHOTS=10
> >  
> > -_cleanup()
> > -{
> > -    _cleanup_qemu
> > -    for i in $(seq 1 ${SNAPSHOTS})
> > -    do
> > -        rm -f "${TEST_DIR}/${i}-${snapshot_virt0}"
> > -        rm -f "${TEST_DIR}/${i}-${snapshot_virt1}"
> > -    done
> > -    rm -f "${TEST_IMG}" "${TEST_IMG}.1" "${TEST_IMG}.2" "${TEST_IMG}.base"
> > -
> > -}
> > -trap "_cleanup; exit \$status" 0 1 2 3 15
> > +trap "_cleanup_qemu; exit \$status" 0 1 2 3 15
> 
> [1] Evidence that the change to 28 may be broken.
> 
> > +++ b/tests/qemu-iotests/191
> > @@ -31,10 +31,6 @@ MIG_SOCKET="${TEST_DIR}/migrate"
> >  
> >  _cleanup()
> >  {
> > -    rm -f "${TEST_IMG}.mid"
> > -    rm -f "${TEST_IMG}.ovl2"
> > -    rm -f "${TEST_IMG}.ovl3"
> > -    _cleanup_test_img
> >      _cleanup_qemu
> >  }
> >  trap "_cleanup; exit \$status" 0 1 2 3 15
> 
> Elsewhere, you removed the _cleanup function entirely, and changed the
> trap to directly call _cleanup_qemu.  Worth doing here?
>

Yes, I think so.

> It looks like only 28 was broken, and that fix is an obvious pattern, as
> well as any other minor tweaks you want to make based on my comments.
> With that correction,
> Reviewed-by: Eric Blake <eblake@redhat.com>
> 

Thanks!

^ permalink raw reply	[flat|nested] 37+ messages in thread

* Re: [Qemu-devel] [PATCH v5 05/10] qemu-iotests: change qemu pid and fd tracking / cleanup
  2017-10-17 16:31 ` [Qemu-devel] [PATCH v5 05/10] qemu-iotests: change qemu pid and fd tracking / cleanup Jeff Cody
@ 2017-10-18 13:59   ` Jeff Cody
  2017-10-18 14:11     ` Eric Blake
  2017-10-18 14:22   ` Eric Blake
  1 sibling, 1 reply; 37+ messages in thread
From: Jeff Cody @ 2017-10-18 13:59 UTC (permalink / raw)
  To: qemu-devel; +Cc: qemu-block, jsnow, stefanha, kwolf, eblake

On Tue, Oct 17, 2017 at 12:31:50PM -0400, Jeff Cody wrote:
> So that later patches can cleanup running qemu processes called from
> different subshells, track resources to cleanup in pid and fd list
> files.
> 
> In subsquent patches, ./check will kill all QEMU processes launched with
> the common.qemu framework, and the tests will not need to cleanup
> manually (unless they want to do so as part of the test, e.g. wait for
> a process to end such as migration).
> 
> Signed-off-by: Jeff Cody <jcody@redhat.com>
> ---
>  tests/qemu-iotests/common.qemu | 82 ++++++++++++++++++++++++++++++++----------
>  tests/qemu-iotests/common.rc   |  3 +-
>  2 files changed, 64 insertions(+), 21 deletions(-)
> 
> diff --git a/tests/qemu-iotests/common.qemu b/tests/qemu-iotests/common.qemu
> index 7b3052d..35a08a6 100644
> --- a/tests/qemu-iotests/common.qemu
> +++ b/tests/qemu-iotests/common.qemu
> @@ -33,6 +33,10 @@ QEMU_FIFO_OUT="${QEMU_TEST_DIR}/qmp-out-$$"
>  QEMU_HANDLE=0
>  export _QEMU_HANDLE=0
>  
> +QEMU_PID_LIST="${QEMU_TEST_DIR}"/qemu-pid.lst
> +QEMU_OUT_FD_LIST="${QEMU_TEST_DIR}"/qemu-out-fd.lst
> +QEMU_IN_FD_LIST="${QEMU_TEST_DIR}"/qemu-in-fd.lst
> +QEMU_FIFO_LIST="${QEMU_TEST_DIR}"/qemu-fifo.lst
>  # If bash version is >= 4.1, these will be overwritten and dynamic
>  # file descriptor values assigned.
>  _out_fd=3
> @@ -193,6 +197,10 @@ function _launch_qemu()
>      QEMU_OUT[${_QEMU_HANDLE}]=${_out_fd}
>      QEMU_IN[${_QEMU_HANDLE}]=${_in_fd}
>      QEMU_STATUS[${_QEMU_HANDLE}]=0
> +    echo ${_out_fd} >> "$QEMU_OUT_FD_LIST"
> +    echo ${_in_fd} >> "$QEMU_IN_FD_LIST"
> +    echo ${fifo_in} >> "$QEMU_FIFO_LIST"
> +    echo ${fifo_out} >> "$QEMU_FIFO_LIST"
>  
>      if [ "${qemu_comm_method}" == "qmp" ]
>      then
> @@ -209,35 +217,71 @@ function _launch_qemu()
>  
>  # Silenty kills the QEMU process
>  #
> +# This is able to kill and clean up after QEMU processes without the
> +# need for any subshell-specific variables, so long as the qemu-pidlist
> +# and qemu-out-fd.list and qemu-in-fd.list files are properly maintained.
> +#
>  # If $wait is set to anything other than the empty string, the process will not
>  # be killed but only waited for, and any output will be forwarded to stdout. If
>  # $wait is empty, the process will be killed and all output will be suppressed.
>  function _cleanup_qemu()
>  {
> -    # QEMU_PID[], QEMU_IN[], QEMU_OUT[] all use same indices
> -    for i in "${!QEMU_OUT[@]}"
> +    local fifo_path=
> +    local testdir_path=
> +
> +    if [ ! -e "${QEMU_PID_LIST}" ]; then
> +        return
> +    fi
> +
> +    # get line count, and therefore number of processes to kill
> +    numproc=$(wc -l "${QEMU_PID_LIST}" | sed 's/\s.*//')
> +
> +    for i in $(seq 1 $numproc)
>      do
>          local QEMU_PID
> -        if [ -f "${QEMU_TEST_DIR}/qemu-${i}.pid" ]; then
> -            read QEMU_PID < "${QEMU_TEST_DIR}/qemu-${i}.pid"
> -            rm -f "${QEMU_TEST_DIR}/qemu-${i}.pid"
> -            if [ -z "${wait}" ] && [ -n "${QEMU_PID}" ]; then
> -                kill -KILL ${QEMU_PID} 2>/dev/null
> -            fi
> -            if [ -n "${QEMU_PID}" ]; then
> -                wait ${QEMU_PID} 2>/dev/null # silent kill
> -            fi
> +        local OUT_FD
> +        local IN_FD
> +        j=$(expr $i - 1)
> +
> +        QEMU_PID=$(tail -n+${i} "${QEMU_PID_LIST}" | head -n1)
> +        OUT_FD=$(tail -n+${i} "${QEMU_OUT_FD_LIST}" | head -n1)
> +        IN_FD=$(tail -n+${i} "${QEMU_IN_FD_LIST}" | head -n1)
> +
> +        if [ -z "${wait}" ] && [ -n "${QEMU_PID}" ]; then
> +            kill -KILL ${QEMU_PID} 2>/dev/null
> +        fi
> +        if [ -n "${QEMU_PID}" ]; then
> +            wait ${QEMU_PID} 2>/dev/null # silent kill
>          fi
>  
> -        if [ -n "${wait}" ]; then
> -            cat <&${QEMU_OUT[$i]} | _filter_testdir | _filter_qemu \
> -                                  | _filter_qemu_io | _filter_qmp | _filter_hmp
> +        if [ -n "${wait}" ] && [ -n "${OUT_FD}" ]; then
> +            cat <&${OUT_FD} | _filter_testdir | _filter_qemu \
> +                            | _filter_qemu_io | _filter_qmp | _filter_hmp
> +        fi
> +
> +        if [ -n "${IN_FD}" ]; then
> +            eval "exec ${IN_FD}<&-"   # close file descriptors
> +        fi
> +        if [ -n "${OUT_FD}" ]; then
> +            eval "exec ${OUT_FD}<&-"
>          fi
> -        rm -f "${QEMU_FIFO_IN}_${i}" "${QEMU_FIFO_OUT}_${i}"
> -        eval "exec ${QEMU_IN[$i]}<&-"   # close file descriptors
> -        eval "exec ${QEMU_OUT[$i]}<&-"
>  
> -        unset QEMU_IN[$i]
> -        unset QEMU_OUT[$i]
> +        unset QEMU_IN[$j]
> +        unset QEMU_OUT[$j]
>      done
> +
> +    # The FIFOs do not correspond to process entry in the pidlist, so
> +    # just clean them up afterwards
> +    while read fifo_name
> +    do
> +        # make sure entries are inside the $TEST_DIR
> +        fifo_path=$(dirname -z $(realpath "$fifo_name"))

Pointing out another issue I noticed after testing on a different machine:
in Bash > 4.4, this generates a warning, which breaks diff stats.  The fix
is to drop the '-z':
        fifo_path=$(dirname $(realpath "$fifo_name"))

> +        testdir_path=$(realpath "$QEMU_TEST_DIR")
> +        if [ "$fifo_path" == "$testdir_path" ]
> +        then
> +            rm -f "$fifo_name"
> +        fi
> +    done < "${QEMU_FIFO_LIST}"
> +
> +    rm -f "${QEMU_PID_LIST}" "${QEMU_OUT_FD_LIST}" "${QEMU_IN_FD_LIST}" "$QEMU_FIFO_LIST}"
>  }
> diff --git a/tests/qemu-iotests/common.rc b/tests/qemu-iotests/common.rc
> index a345ffd..b26b02f 100644
> --- a/tests/qemu-iotests/common.rc
> +++ b/tests/qemu-iotests/common.rc
> @@ -40,7 +40,6 @@ poke_file()
>      printf "$3" | dd "of=$1" bs=1 "seek=$2" conv=notrunc &>/dev/null
>  }
>  
> -
>  if ! . ./common.config
>      then
>      echo "$0: failed to source common.config"
> @@ -51,7 +50,7 @@ _qemu_wrapper()
>  {
>      (
>          if [ -n "${QEMU_NEED_PID}" ]; then
> -            echo $BASHPID > "${QEMU_TEST_DIR}/qemu-${_QEMU_HANDLE}.pid"
> +            echo $BASHPID >> "${QEMU_TEST_DIR}/qemu-pid.lst"
>          fi
>          exec "$QEMU_PROG" $QEMU_OPTIONS "$@"
>      )
> -- 
> 2.9.5
> 

^ permalink raw reply	[flat|nested] 37+ messages in thread

* Re: [Qemu-devel] [PATCH v5 05/10] qemu-iotests: change qemu pid and fd tracking / cleanup
  2017-10-18 13:59   ` Jeff Cody
@ 2017-10-18 14:11     ` Eric Blake
  0 siblings, 0 replies; 37+ messages in thread
From: Eric Blake @ 2017-10-18 14:11 UTC (permalink / raw)
  To: Jeff Cody, qemu-devel; +Cc: qemu-block, jsnow, stefanha, kwolf

[-- Attachment #1: Type: text/plain, Size: 1713 bytes --]

On 10/18/2017 08:59 AM, Jeff Cody wrote:
> On Tue, Oct 17, 2017 at 12:31:50PM -0400, Jeff Cody wrote:
>> So that later patches can cleanup running qemu processes called from
>> different subshells, track resources to cleanup in pid and fd list
>> files.
>>
>> In subsquent patches, ./check will kill all QEMU processes launched with

s/subsquent/subsequent/

>> the common.qemu framework, and the tests will not need to cleanup
>> manually (unless they want to do so as part of the test, e.g. wait for
>> a process to end such as migration).
>>
>> Signed-off-by: Jeff Cody <jcody@redhat.com>
>> ---

>> +    # The FIFOs do not correspond to process entry in the pidlist, so
>> +    # just clean them up afterwards
>> +    while read fifo_name
>> +    do
>> +        # make sure entries are inside the $TEST_DIR
>> +        fifo_path=$(dirname -z $(realpath "$fifo_name"))
> 
> Pointing out another issue I noticed after testing on a different machine:
> in Bash > 4.4, this generates a warning, which breaks diff stats.  The fix
> is to drop the '-z':
>         fifo_path=$(dirname $(realpath "$fifo_name"))

That, and 'dirname -z' is GNU-specific.  It is handy for getting the
name of a directory that ends in newline (yes, you are evil if you do
'mkdir $"abc\n"', because $(dirname "$dir") will strip that trailing
newline and likely trip up a poorly-written script to operate on 'abc'
instead).  But as we already check for no whitespace in $TESTDIR, we
don't have to rely on -z to work around evil directories with a name
ending in newline.

-- 
Eric Blake, Principal Software Engineer
Red Hat, Inc.           +1-919-301-3266
Virtualization:  qemu.org | libvirt.org


[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 619 bytes --]

^ permalink raw reply	[flat|nested] 37+ messages in thread

* Re: [Qemu-devel] [PATCH v5 05/10] qemu-iotests: change qemu pid and fd tracking / cleanup
  2017-10-17 16:31 ` [Qemu-devel] [PATCH v5 05/10] qemu-iotests: change qemu pid and fd tracking / cleanup Jeff Cody
  2017-10-18 13:59   ` Jeff Cody
@ 2017-10-18 14:22   ` Eric Blake
  1 sibling, 0 replies; 37+ messages in thread
From: Eric Blake @ 2017-10-18 14:22 UTC (permalink / raw)
  To: Jeff Cody, qemu-devel; +Cc: qemu-block, jsnow, stefanha, kwolf

[-- Attachment #1: Type: text/plain, Size: 1649 bytes --]

On 10/17/2017 11:31 AM, Jeff Cody wrote:
> So that later patches can cleanup running qemu processes called from
> different subshells, track resources to cleanup in pid and fd list
> files.
> 
> In subsquent patches, ./check will kill all QEMU processes launched with
> the common.qemu framework, and the tests will not need to cleanup
> manually (unless they want to do so as part of the test, e.g. wait for
> a process to end such as migration).
> 
> Signed-off-by: Jeff Cody <jcody@redhat.com>
> ---
>  tests/qemu-iotests/common.qemu | 82 ++++++++++++++++++++++++++++++++----------
>  tests/qemu-iotests/common.rc   |  3 +-
>  2 files changed, 64 insertions(+), 21 deletions(-)

Modulo the typo in the commit message in response to your other tweaks,


> +    # get line count, and therefore number of processes to kill
> +    numproc=$(wc -l "${QEMU_PID_LIST}" | sed 's/\s.*//')

Instead of having to use sed, just do:

numproc=$(wc -l < "${QEMU_PID_LIST}")

wc is required to behave differently when parsing stdin than when
parsing a named file, so you might as well take advantage of it.

> +
> +    for i in $(seq 1 $numproc)

Are we sure seq is always available?  Shave a subshell, and avoid the
dependency, by using bash's:

for i in {1..$numproc}

> +++ b/tests/qemu-iotests/common.rc
> @@ -40,7 +40,6 @@ poke_file()
>      printf "$3" | dd "of=$1" bs=1 "seek=$2" conv=notrunc &>/dev/null
>  }
>  
> -
>  if ! . ./common.config

Spurious whitespace change?



-- 
Eric Blake, Principal Software Engineer
Red Hat, Inc.           +1-919-301-3266
Virtualization:  qemu.org | libvirt.org


[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 619 bytes --]

^ permalink raw reply	[flat|nested] 37+ messages in thread

* Re: [Qemu-devel] [PATCH v5 06/10] qemu-iotests: make ./check automatically reap QEMU processes
  2017-10-17 16:31 ` [Qemu-devel] [PATCH v5 06/10] qemu-iotests: make ./check automatically reap QEMU processes Jeff Cody
@ 2017-10-18 14:24   ` Eric Blake
  0 siblings, 0 replies; 37+ messages in thread
From: Eric Blake @ 2017-10-18 14:24 UTC (permalink / raw)
  To: Jeff Cody, qemu-devel; +Cc: qemu-block, jsnow, stefanha, kwolf

[-- Attachment #1: Type: text/plain, Size: 1042 bytes --]

On 10/17/2017 11:31 AM, Jeff Cody wrote:
> Check will now take care of cleaning up all QEMU processes started
> from bash tests using the common.qemu framework.
> 
> This also paves the way to added another check option to keep QEMU
> processes around, in the case of a failed test.
> 
> Signed-off-by: Jeff Cody <jcody@redhat.com>
> ---
>  tests/qemu-iotests/085   | 2 --

and 28, after fixing things earlier in the series

> +++ b/tests/qemu-iotests/check
> @@ -845,10 +845,13 @@ do
>          # TEST_DIR / QEMU_TEST_DIR
>          (
>          export TEST_DIR=$TEST_DIR_SEQ
> -        . "$source_iotests/common.config"
> -        . "$source_iotests/common.rc"
> +        cd "$source_iotests";
> +        . ./common.config
> +        . ./common.rc
> +        . ./common.qemu
>  
>          _cleanup_protocols
> +        _cleanup_qemu

Reviewed-by: Eric Blake <eblake@redhat.com>

-- 
Eric Blake, Principal Software Engineer
Red Hat, Inc.           +1-919-301-3266
Virtualization:  qemu.org | libvirt.org


[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 619 bytes --]

^ permalink raw reply	[flat|nested] 37+ messages in thread

* Re: [Qemu-devel] [PATCH v5 09/10] qemu-iotests: add option to save temp files on error
  2017-10-17 16:31 ` [Qemu-devel] [PATCH v5 09/10] qemu-iotests: add option to save temp files on error Jeff Cody
@ 2017-10-18 14:33   ` Eric Blake
  0 siblings, 0 replies; 37+ messages in thread
From: Eric Blake @ 2017-10-18 14:33 UTC (permalink / raw)
  To: Jeff Cody, qemu-devel; +Cc: qemu-block, jsnow, stefanha, kwolf

[-- Attachment #1: Type: text/plain, Size: 1642 bytes --]

On 10/17/2017 11:31 AM, Jeff Cody wrote:
> Now that ./check takes care of cleaning up after each tests, it
> can also selectively not clean up.  Add option to leave all output from
> tests intact if that test encountered an error.
> 
> Signed-off-by: Jeff Cody <jcody@redhat.com>
> ---
>  tests/qemu-iotests/check | 13 ++++++++++++-
>  1 file changed, 12 insertions(+), 1 deletion(-)
> 
> diff --git a/tests/qemu-iotests/check b/tests/qemu-iotests/check
> index 057ea39..a66f7b0 100755
> --- a/tests/qemu-iotests/check
> +++ b/tests/qemu-iotests/check
> @@ -125,6 +125,7 @@ sortme=false
>  expunge=true
>  have_test_arg=false
>  cachemode=false
> +save_on_err=false
>  
>  tmp="${TEST_DIR}"/$$
>  rm -f $tmp.list $tmp.tmp $tmp.sed
> @@ -263,6 +264,8 @@ other options
>      -o options          -o options to pass to qemu-img create/convert
>      -T                  output timestamps
>      -c mode             cache mode
> +    -s                  save test scratch directory on test failure

Is there an easy way to force all tests to fail (and thus preserve the
scratch directory for inspection, even though the test normally would
succeed)?  It might serve as a useful double-check that you got
everything in this series, maybe even worth documenting in the commit
messages.

> +
> +        if [ "$save_on_err" != "true" ] || [ "$err" != "true" ]
> +        then
> +            rm -rf "$TEST_DIR_SEQ"
> +        fi

I suppose the easiest way is to hack this 'if'.

-- 
Eric Blake, Principal Software Engineer
Red Hat, Inc.           +1-919-301-3266
Virtualization:  qemu.org | libvirt.org


[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 619 bytes --]

^ permalink raw reply	[flat|nested] 37+ messages in thread

* Re: [Qemu-devel] [PATCH v5 03/10] qemu-iotests: automatically clean up bash protocol servers
  2017-10-17 16:31 ` [Qemu-devel] [PATCH v5 03/10] qemu-iotests: automatically clean up bash protocol servers Jeff Cody
  2017-10-18  1:15   ` Eric Blake
@ 2017-10-18 14:46   ` Paolo Bonzini
  2017-10-18 15:03     ` Jeff Cody
                       ` (2 more replies)
  1 sibling, 3 replies; 37+ messages in thread
From: Paolo Bonzini @ 2017-10-18 14:46 UTC (permalink / raw)
  To: Jeff Cody, qemu-devel; +Cc: kwolf, jsnow, stefanha, qemu-block

On 17/10/2017 18:31, Jeff Cody wrote:
>              )
>          else
> +            # Do this in a sub-shell, so we are operating on the right
> +            # TEST_DIR / QEMU_TEST_DIR
>              (
>              export TEST_DIR=$TEST_DIR_SEQ
>              cd "$source_iotests";

Where is the missing ")"?

> @@ -837,6 +841,15 @@ do
>              fi
>          fi
>  
> +        # Do this in a sub-shell, so we are operating on the right
> +        # TEST_DIR / QEMU_TEST_DIR
> +        (
> +        export TEST_DIR=$TEST_DIR_SEQ
> +        . "$source_iotests/common.config"
> +        . "$source_iotests/common.rc"
> +
> +        _cleanup_protocols

"check" wasn't including common.rc before this patch, and most of the
content of that file doesn't apply to "check".  So if we want to move
cleanup code to "check" we should remove it from common.rc too.

In general, I think we should strive to have a better separation between
tests and harness.  This for example could let us write a different
harness for the same tests and integrate the tests better into Avocado.
Hence I see one advantage and one disadvantage in your series:

* by adding more functionality to "check", it shows that the current
separation may fail with a more sophisticated harness (such as the one
you are creating here)

* it adds a lot more knowledge of QEMU (especially protocols) in
"check", but there is still some unbalance: tests create the images and
the protocol servers, but the harness cleans it up.  The visible result
of this unbalance is for example how multi-process protocol tests can
fail when multiple tests try to bind the same address.

I think it's the right direction, but it feels like it's not there
yet...  Sorry---I know this is not very constructive, but I hope it
helps anyway.

Maybe we should actually rewrite "check" in Python.  That would force us
to think more about the design.

Paolo

^ permalink raw reply	[flat|nested] 37+ messages in thread

* Re: [Qemu-devel] [PATCH v5 03/10] qemu-iotests: automatically clean up bash protocol servers
  2017-10-18 14:46   ` Paolo Bonzini
@ 2017-10-18 15:03     ` Jeff Cody
  2017-10-18 15:16       ` Paolo Bonzini
  2017-10-18 15:06     ` Eric Blake
  2017-10-18 15:43     ` Daniel P. Berrange
  2 siblings, 1 reply; 37+ messages in thread
From: Jeff Cody @ 2017-10-18 15:03 UTC (permalink / raw)
  To: Paolo Bonzini; +Cc: qemu-devel, kwolf, jsnow, stefanha, qemu-block

On Wed, Oct 18, 2017 at 04:46:20PM +0200, Paolo Bonzini wrote:
> On 17/10/2017 18:31, Jeff Cody wrote:
> >              )
> >          else
> > +            # Do this in a sub-shell, so we are operating on the right
> > +            # TEST_DIR / QEMU_TEST_DIR
> >              (
> >              export TEST_DIR=$TEST_DIR_SEQ
> >              cd "$source_iotests";
> 
> Where is the missing ")"?

It's part of the diff context, not a change itself... it's still there, just
not shown in the patch.

> 
> > @@ -837,6 +841,15 @@ do
> >              fi
> >          fi
> >  
> > +        # Do this in a sub-shell, so we are operating on the right
> > +        # TEST_DIR / QEMU_TEST_DIR
> > +        (
> > +        export TEST_DIR=$TEST_DIR_SEQ
> > +        . "$source_iotests/common.config"
> > +        . "$source_iotests/common.rc"
> > +
> > +        _cleanup_protocols
> 
> "check" wasn't including common.rc before this patch, and most of the
> content of that file doesn't apply to "check".  So if we want to move
> cleanup code to "check" we should remove it from common.rc too.
> 
> In general, I think we should strive to have a better separation between
> tests and harness.  This for example could let us write a different
> harness for the same tests and integrate the tests better into Avocado.
> Hence I see one advantage and one disadvantage in your series:
> 
> * by adding more functionality to "check", it shows that the current
> separation may fail with a more sophisticated harness (such as the one
> you are creating here)
> 
> * it adds a lot more knowledge of QEMU (especially protocols) in
> "check", but there is still some unbalance: tests create the images and
> the protocol servers, but the harness cleans it up.  The visible result
> of this unbalance is for example how multi-process protocol tests can
> fail when multiple tests try to bind the same address.
> 
> I think it's the right direction, but it feels like it's not there
> yet...  Sorry---I know this is not very constructive, but I hope it
> helps anyway.
> 
> Maybe we should actually rewrite "check" in Python.  That would force us
> to think more about the design.
> 

I think writing a more sophisticated harness in another language, such as
Python, has merit.  But to clarify, do you mean that as a 'nack' to this
series, or as something to be done later, after this series?  If this series
improves the existing harness, I don't see why to exclude it because a new
re-write could be superior (which I don't dispute).

^ permalink raw reply	[flat|nested] 37+ messages in thread

* Re: [Qemu-devel] [PATCH v5 03/10] qemu-iotests: automatically clean up bash protocol servers
  2017-10-18 14:46   ` Paolo Bonzini
  2017-10-18 15:03     ` Jeff Cody
@ 2017-10-18 15:06     ` Eric Blake
  2017-10-18 15:43     ` Daniel P. Berrange
  2 siblings, 0 replies; 37+ messages in thread
From: Eric Blake @ 2017-10-18 15:06 UTC (permalink / raw)
  To: Paolo Bonzini, Jeff Cody, qemu-devel; +Cc: kwolf, jsnow, qemu-block, stefanha

[-- Attachment #1: Type: text/plain, Size: 591 bytes --]

On 10/18/2017 09:46 AM, Paolo Bonzini wrote:
> On 17/10/2017 18:31, Jeff Cody wrote:
>>              )
>>          else
>> +            # Do this in a sub-shell, so we are operating on the right
>> +            # TEST_DIR / QEMU_TEST_DIR
>>              (
>>              export TEST_DIR=$TEST_DIR_SEQ
>>              cd "$source_iotests";
> 
> Where is the missing ")"?

This hunk is just adding comments, not '(', so it is already well-paired.

-- 
Eric Blake, Principal Software Engineer
Red Hat, Inc.           +1-919-301-3266
Virtualization:  qemu.org | libvirt.org


[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 619 bytes --]

^ permalink raw reply	[flat|nested] 37+ messages in thread

* Re: [Qemu-devel] [PATCH v5 03/10] qemu-iotests: automatically clean up bash protocol servers
  2017-10-18 15:03     ` Jeff Cody
@ 2017-10-18 15:16       ` Paolo Bonzini
  2017-10-18 15:34         ` Jeff Cody
  0 siblings, 1 reply; 37+ messages in thread
From: Paolo Bonzini @ 2017-10-18 15:16 UTC (permalink / raw)
  To: Jeff Cody; +Cc: qemu-devel, kwolf, jsnow, stefanha, qemu-block

On 18/10/2017 17:03, Jeff Cody wrote:
> On Wed, Oct 18, 2017 at 04:46:20PM +0200, Paolo Bonzini wrote:
>> On 17/10/2017 18:31, Jeff Cody wrote:
>>>              )
>>>          else
>>> +            # Do this in a sub-shell, so we are operating on the right
>>> +            # TEST_DIR / QEMU_TEST_DIR
>>>              (
>>>              export TEST_DIR=$TEST_DIR_SEQ
>>>              cd "$source_iotests";
>> Where is the missing ")"?
> It's part of the diff context, not a change itself... it's still there, just
> not shown in the patch.
> 
>>> @@ -837,6 +841,15 @@ do
>>>              fi
>>>          fi
>>>  
>>> +        # Do this in a sub-shell, so we are operating on the right
>>> +        # TEST_DIR / QEMU_TEST_DIR
>>> +        (
>>> +        export TEST_DIR=$TEST_DIR_SEQ
>>> +        . "$source_iotests/common.config"
>>> +        . "$source_iotests/common.rc"
>>> +
>>> +        _cleanup_protocols
>> "check" wasn't including common.rc before this patch, and most of the
>> content of that file doesn't apply to "check".  So if we want to move
>> cleanup code to "check" we should remove it from common.rc too.
>>
>> In general, I think we should strive to have a better separation between
>> tests and harness.  This for example could let us write a different
>> harness for the same tests and integrate the tests better into Avocado.
>> Hence I see one advantage and one disadvantage in your series:
>>
>> * by adding more functionality to "check", it shows that the current
>> separation may fail with a more sophisticated harness (such as the one
>> you are creating here)
>>
>> * it adds a lot more knowledge of QEMU (especially protocols) in
>> "check", but there is still some unbalance: tests create the images and
>> the protocol servers, but the harness cleans it up.  The visible result
>> of this unbalance is for example how multi-process protocol tests can
>> fail when multiple tests try to bind the same address.
>>
>> I think it's the right direction, but it feels like it's not there
>> yet...  Sorry---I know this is not very constructive, but I hope it
>> helps anyway.
>>
>> Maybe we should actually rewrite "check" in Python.  That would force us
>> to think more about the design.
>
> I think writing a more sophisticated harness in another language, such as
> Python, has merit.  But to clarify, do you mean that as a 'nack' to this
> series, or as something to be done later, after this series?  If this series
> improves the existing harness, I don't see why to exclude it because a new

Well, I have no idea (hence the "not very constructive" part).  I'm only
"nacking" the sourcing of common.rc in the check script.

The series improves the harness, but it also sets a very different
separation between the tests and the harness (especially WRT the tests
cleaning up after themselves).  The level of separation would at least
be clearer if check didn't include common.rc.

Paolo

^ permalink raw reply	[flat|nested] 37+ messages in thread

* Re: [Qemu-devel] [PATCH v5 03/10] qemu-iotests: automatically clean up bash protocol servers
  2017-10-18 15:16       ` Paolo Bonzini
@ 2017-10-18 15:34         ` Jeff Cody
  2017-10-18 15:39           ` Paolo Bonzini
  0 siblings, 1 reply; 37+ messages in thread
From: Jeff Cody @ 2017-10-18 15:34 UTC (permalink / raw)
  To: Paolo Bonzini; +Cc: qemu-devel, kwolf, jsnow, stefanha, qemu-block

On Wed, Oct 18, 2017 at 05:16:44PM +0200, Paolo Bonzini wrote:
> On 18/10/2017 17:03, Jeff Cody wrote:
> > On Wed, Oct 18, 2017 at 04:46:20PM +0200, Paolo Bonzini wrote:
> >> On 17/10/2017 18:31, Jeff Cody wrote:
> >>>              )
> >>>          else
> >>> +            # Do this in a sub-shell, so we are operating on the right
> >>> +            # TEST_DIR / QEMU_TEST_DIR
> >>>              (
> >>>              export TEST_DIR=$TEST_DIR_SEQ
> >>>              cd "$source_iotests";
> >> Where is the missing ")"?
> > It's part of the diff context, not a change itself... it's still there, just
> > not shown in the patch.
> > 
> >>> @@ -837,6 +841,15 @@ do
> >>>              fi
> >>>          fi
> >>>  
> >>> +        # Do this in a sub-shell, so we are operating on the right
> >>> +        # TEST_DIR / QEMU_TEST_DIR
> >>> +        (
> >>> +        export TEST_DIR=$TEST_DIR_SEQ
> >>> +        . "$source_iotests/common.config"
> >>> +        . "$source_iotests/common.rc"
> >>> +
> >>> +        _cleanup_protocols
> >> "check" wasn't including common.rc before this patch, and most of the
> >> content of that file doesn't apply to "check".  So if we want to move
> >> cleanup code to "check" we should remove it from common.rc too.
> >>
> >> In general, I think we should strive to have a better separation between
> >> tests and harness.  This for example could let us write a different
> >> harness for the same tests and integrate the tests better into Avocado.
> >> Hence I see one advantage and one disadvantage in your series:
> >>
> >> * by adding more functionality to "check", it shows that the current
> >> separation may fail with a more sophisticated harness (such as the one
> >> you are creating here)
> >>
> >> * it adds a lot more knowledge of QEMU (especially protocols) in
> >> "check", but there is still some unbalance: tests create the images and
> >> the protocol servers, but the harness cleans it up.  The visible result
> >> of this unbalance is for example how multi-process protocol tests can
> >> fail when multiple tests try to bind the same address.
> >>
> >> I think it's the right direction, but it feels like it's not there
> >> yet...  Sorry---I know this is not very constructive, but I hope it
> >> helps anyway.
> >>
> >> Maybe we should actually rewrite "check" in Python.  That would force us
> >> to think more about the design.
> >
> > I think writing a more sophisticated harness in another language, such as
> > Python, has merit.  But to clarify, do you mean that as a 'nack' to this
> > series, or as something to be done later, after this series?  If this series
> > improves the existing harness, I don't see why to exclude it because a new
> 
> Well, I have no idea (hence the "not very constructive" part).  I'm only
> "nacking" the sourcing of common.rc in the check script.
> 
> The series improves the harness, but it also sets a very different
> separation between the tests and the harness (especially WRT the tests
> cleaning up after themselves).  The level of separation would at least
> be clearer if check didn't include common.rc.
>

I can get rid of the common.rc includes prior to running the tests, but this
series really requires including common.rc in the spot you mentioned, for
automatically cleaning up protocol and QEMU processes.

That auto-cleanup is arguably a big improvement, as it has been relatively
common to run across tests that leave processes running in the background.

I agree that it sets up different expectations, but that is at least partly
intentional.  I don't really want to have to rely on individually written
tests to clean up properly. That is ~200 chances (and growing) for a
mistake; instead, this series moves that responsibility into a single place
to maintain.

^ permalink raw reply	[flat|nested] 37+ messages in thread

* Re: [Qemu-devel] [PATCH v5 03/10] qemu-iotests: automatically clean up bash protocol servers
  2017-10-18 15:34         ` Jeff Cody
@ 2017-10-18 15:39           ` Paolo Bonzini
  2017-10-18 15:50             ` Jeff Cody
  0 siblings, 1 reply; 37+ messages in thread
From: Paolo Bonzini @ 2017-10-18 15:39 UTC (permalink / raw)
  To: Jeff Cody; +Cc: qemu-devel, kwolf, jsnow, stefanha, qemu-block

On 18/10/2017 17:34, Jeff Cody wrote:
>> Well, I have no idea (hence the "not very constructive" part).  I'm only
>> "nacking" the sourcing of common.rc in the check script.
>>
>> The series improves the harness, but it also sets a very different
>> separation between the tests and the harness (especially WRT the tests
>> cleaning up after themselves).  The level of separation would at least
>> be clearer if check didn't include common.rc.
>>
> I can get rid of the common.rc includes prior to running the tests, but this
> series really requires including common.rc in the spot you mentioned, for
> automatically cleaning up protocol and QEMU processes.

Understood, but does it have to be common.rc?  Can it be a different
file?  That at least would still make it clear what check is doing (for
example it is not launching qemu, which is part of common.rc).

> That auto-cleanup is arguably a big improvement, as it has been relatively
> common to run across tests that leave processes running in the background.
> 
> I agree that it sets up different expectations, but that is at least partly
> intentional.  I don't really want to have to rely on individually written
> tests to clean up properly. That is ~200 chances (and growing) for a
> mistake; instead, this series moves that responsibility into a single place
> to maintain.

Understood, that's also why I'm all but nacking the entire series!

Paolo

^ permalink raw reply	[flat|nested] 37+ messages in thread

* Re: [Qemu-devel] [PATCH v5 03/10] qemu-iotests: automatically clean up bash protocol servers
  2017-10-18 14:46   ` Paolo Bonzini
  2017-10-18 15:03     ` Jeff Cody
  2017-10-18 15:06     ` Eric Blake
@ 2017-10-18 15:43     ` Daniel P. Berrange
  2 siblings, 0 replies; 37+ messages in thread
From: Daniel P. Berrange @ 2017-10-18 15:43 UTC (permalink / raw)
  To: Paolo Bonzini; +Cc: Jeff Cody, qemu-devel, kwolf, jsnow, qemu-block, stefanha

On Wed, Oct 18, 2017 at 04:46:20PM +0200, Paolo Bonzini wrote:
> Maybe we should actually rewrite "check" in Python.  That would force us
> to think more about the design.

I think that would be great.

Any shell script that's more than 5 lines long is a shell script that
should not exist. It is a terrible language for doing anything remotely
complex, and the iotest harness easily falls into category.

Regards,
Daniel
-- 
|: https://berrange.com      -o-    https://www.flickr.com/photos/dberrange :|
|: https://libvirt.org         -o-            https://fstop138.berrange.com :|
|: https://entangle-photo.org    -o-    https://www.instagram.com/dberrange :|

^ permalink raw reply	[flat|nested] 37+ messages in thread

* Re: [Qemu-devel] [PATCH v5 03/10] qemu-iotests: automatically clean up bash protocol servers
  2017-10-18 15:39           ` Paolo Bonzini
@ 2017-10-18 15:50             ` Jeff Cody
  2017-10-18 15:51               ` Paolo Bonzini
  0 siblings, 1 reply; 37+ messages in thread
From: Jeff Cody @ 2017-10-18 15:50 UTC (permalink / raw)
  To: Paolo Bonzini; +Cc: qemu-devel, kwolf, jsnow, stefanha, qemu-block

On Wed, Oct 18, 2017 at 05:39:40PM +0200, Paolo Bonzini wrote:
> On 18/10/2017 17:34, Jeff Cody wrote:
> >> Well, I have no idea (hence the "not very constructive" part).  I'm only
> >> "nacking" the sourcing of common.rc in the check script.
> >>
> >> The series improves the harness, but it also sets a very different
> >> separation between the tests and the harness (especially WRT the tests
> >> cleaning up after themselves).  The level of separation would at least
> >> be clearer if check didn't include common.rc.
> >>
> > I can get rid of the common.rc includes prior to running the tests, but this
> > series really requires including common.rc in the spot you mentioned, for
> > automatically cleaning up protocol and QEMU processes.
> 
> Understood, but does it have to be common.rc?  Can it be a different
> file?  That at least would still make it clear what check is doing (for
> example it is not launching qemu, which is part of common.rc).
> 

Here is what we need from common.rc for this series:

_rm_test_img
_cleanup_nbd
_cleanup_vxhs
_cleanup_rbd
_cleanup_sheepdog
_cleanup_protocols
_cleanup_test_img


They all have a common theme (cleanup), so I could move them all to a
common.cleanup (naming suggestion?) file (which would need to be included by
common.rc, as well).

Would this be a strong enough delineation to overcome your concerns?


> > That auto-cleanup is arguably a big improvement, as it has been relatively
> > common to run across tests that leave processes running in the background.
> > 
> > I agree that it sets up different expectations, but that is at least partly
> > intentional.  I don't really want to have to rely on individually written
> > tests to clean up properly. That is ~200 chances (and growing) for a
> > mistake; instead, this series moves that responsibility into a single place
> > to maintain.
> 
> Understood, that's also why I'm all but nacking the entire series!
> 
> Paolo

^ permalink raw reply	[flat|nested] 37+ messages in thread

* Re: [Qemu-devel] [PATCH v5 03/10] qemu-iotests: automatically clean up bash protocol servers
  2017-10-18 15:50             ` Jeff Cody
@ 2017-10-18 15:51               ` Paolo Bonzini
  2017-10-18 16:19                 ` Jeff Cody
  0 siblings, 1 reply; 37+ messages in thread
From: Paolo Bonzini @ 2017-10-18 15:51 UTC (permalink / raw)
  To: Jeff Cody; +Cc: qemu-devel, kwolf, jsnow, stefanha, qemu-block

On 18/10/2017 17:50, Jeff Cody wrote:
> Here is what we need from common.rc for this series:
> 
> _rm_test_img
> _cleanup_nbd
> _cleanup_vxhs
> _cleanup_rbd
> _cleanup_sheepdog
> _cleanup_protocols
> _cleanup_test_img
> 
> 
> They all have a common theme (cleanup), so I could move them all to a
> common.cleanup (naming suggestion?) file (which would need to be included by
> common.rc, as well).
> 
> Would this be a strong enough delineation to overcome your concerns?

A great start.  Which of these are actually needed by the tests (and
hence by common.rc) and why?

Paolo

^ permalink raw reply	[flat|nested] 37+ messages in thread

* Re: [Qemu-devel] [PATCH v5 03/10] qemu-iotests: automatically clean up bash protocol servers
  2017-10-18 15:51               ` Paolo Bonzini
@ 2017-10-18 16:19                 ` Jeff Cody
  2017-10-18 16:39                   ` Paolo Bonzini
  0 siblings, 1 reply; 37+ messages in thread
From: Jeff Cody @ 2017-10-18 16:19 UTC (permalink / raw)
  To: Paolo Bonzini; +Cc: qemu-devel, kwolf, jsnow, stefanha, qemu-block

On Wed, Oct 18, 2017 at 05:51:53PM +0200, Paolo Bonzini wrote:
> On 18/10/2017 17:50, Jeff Cody wrote:
> > Here is what we need from common.rc for this series:
> > 
> > _rm_test_img
> > _cleanup_nbd
> > _cleanup_vxhs
> > _cleanup_rbd
> > _cleanup_sheepdog
> > _cleanup_protocols
> > _cleanup_test_img
> > 
> > 
> > They all have a common theme (cleanup), so I could move them all to a
> > common.cleanup (naming suggestion?) file (which would need to be included by
> > common.rc, as well).
> > 
> > Would this be a strong enough delineation to overcome your concerns?
> 
> A great start.  Which of these are actually needed by the tests (and
> hence by common.rc) and why?
> 

 Some tests are written such that they do intermediate cleanups between
 multiple internal sub-tests for varying reasons, and so use those cleanup
 functions as part of their testing.  The function _cleanup_test_img
 effectively calls all the other functions I listed, so they are really all
 required for the tests, if they choose to call _cleanup_test_img.

And for 'check' to tear everything down to a clean state, it also needs to
use the cleanup functions for everything that is not just a file/directory.

-Jeff

^ permalink raw reply	[flat|nested] 37+ messages in thread

* Re: [Qemu-devel] [PATCH v5 03/10] qemu-iotests: automatically clean up bash protocol servers
  2017-10-18 16:19                 ` Jeff Cody
@ 2017-10-18 16:39                   ` Paolo Bonzini
  2017-10-18 17:27                     ` Jeff Cody
  0 siblings, 1 reply; 37+ messages in thread
From: Paolo Bonzini @ 2017-10-18 16:39 UTC (permalink / raw)
  To: Jeff Cody; +Cc: qemu-devel, kwolf, jsnow, stefanha, qemu-block

On 18/10/2017 18:19, Jeff Cody wrote:
>>> Here is what we need from common.rc for this series:
>>>
>>> _rm_test_img
>>> _cleanup_nbd
>>> _cleanup_vxhs
>>> _cleanup_rbd
>>> _cleanup_sheepdog
>>> _cleanup_protocols
>>> _cleanup_test_img
>>>
>>> They all have a common theme (cleanup), so I could move them all to a
>>> common.cleanup (naming suggestion?) file (which would need to be included by
>>> common.rc, as well).
>>>
>>> Would this be a strong enough delineation to overcome your concerns?
>>
>> A great start.  Which of these are actually needed by the tests (and
>> hence by common.rc) and why?
>
>  Some tests are written such that they do intermediate cleanups between
>  multiple internal sub-tests for varying reasons, and so use those cleanup
>  functions as part of their testing.  The function _cleanup_test_img
>  effectively calls all the other functions I listed, so they are really all
>  required for the tests, if they choose to call _cleanup_test_img.
> 
> And for 'check' to tear everything down to a clean state, it also needs to
> use the cleanup functions for everything that is not just a file/directory.

Do these tests really need the "cleanup protocols" part, because the few
that have more than one _cleanup_test_img (059, 066, 070, 084, 146, 171)
are either file-only or non-raw, so they should be able to just rebuild
the format on top of the same image.

Maybe that's where the separation lies---protocol vs. format, where
cleaning up the "file" protocol need not do anything because it's done
when removing the test directory.  If that's the case, it'd be nice
because it might also make it much easier to tackle the issue with
parallel tests.

Paolo

^ permalink raw reply	[flat|nested] 37+ messages in thread

* Re: [Qemu-devel] [PATCH v5 03/10] qemu-iotests: automatically clean up bash protocol servers
  2017-10-18 16:39                   ` Paolo Bonzini
@ 2017-10-18 17:27                     ` Jeff Cody
  2017-10-19 10:23                       ` Paolo Bonzini
  0 siblings, 1 reply; 37+ messages in thread
From: Jeff Cody @ 2017-10-18 17:27 UTC (permalink / raw)
  To: Paolo Bonzini; +Cc: qemu-devel, kwolf, jsnow, stefanha, qemu-block

On Wed, Oct 18, 2017 at 06:39:26PM +0200, Paolo Bonzini wrote:
> On 18/10/2017 18:19, Jeff Cody wrote:
> >>> Here is what we need from common.rc for this series:
> >>>
> >>> _rm_test_img
> >>> _cleanup_nbd
> >>> _cleanup_vxhs
> >>> _cleanup_rbd
> >>> _cleanup_sheepdog
> >>> _cleanup_protocols
> >>> _cleanup_test_img
> >>>
> >>> They all have a common theme (cleanup), so I could move them all to a
> >>> common.cleanup (naming suggestion?) file (which would need to be included by
> >>> common.rc, as well).
> >>>
> >>> Would this be a strong enough delineation to overcome your concerns?
> >>
> >> A great start.  Which of these are actually needed by the tests (and
> >> hence by common.rc) and why?
> >
> >  Some tests are written such that they do intermediate cleanups between
> >  multiple internal sub-tests for varying reasons, and so use those cleanup
> >  functions as part of their testing.  The function _cleanup_test_img
> >  effectively calls all the other functions I listed, so they are really all
> >  required for the tests, if they choose to call _cleanup_test_img.
> > 
> > And for 'check' to tear everything down to a clean state, it also needs to
> > use the cleanup functions for everything that is not just a file/directory.
> 
> Do these tests really need the "cleanup protocols" part, because the few
> that have more than one _cleanup_test_img (059, 066, 070, 084, 146, 171)
> are either file-only or non-raw, so they should be able to just rebuild
> the format on top of the same image.
> 

Maybe not, but that could just be the nature of what bugs we are testing for
at this time.  These specific tests may not need to, but it is not
inconceivable to have a test that involves bringing up and tearing down
a protocol based server some arbitrary number times, to test that specific
behavior.

> Maybe that's where the separation lies---protocol vs. format, where
> cleaning up the "file" protocol need not do anything because it's done
> when removing the test directory.  If that's the case, it'd be nice
> because it might also make it much easier to tackle the issue with
> parallel tests.
>

On final exit, yes, a test needs not remember to remove all of its mouse
droppings.  But as far as not needing to remove images in intermediate
stages of a given test, I think that assumes too much. For instance,
qemu-img _should_ be able to rebuild a format on top of the same image.  But
maybe a test wants to see if that specific functionality actually works as
intended, and compares removing and creating an image to rebuilding on top
of an image, etc.

^ permalink raw reply	[flat|nested] 37+ messages in thread

* Re: [Qemu-devel] [PATCH v5 03/10] qemu-iotests: automatically clean up bash protocol servers
  2017-10-18 17:27                     ` Jeff Cody
@ 2017-10-19 10:23                       ` Paolo Bonzini
  2017-10-19 14:52                         ` Jeff Cody
  0 siblings, 1 reply; 37+ messages in thread
From: Paolo Bonzini @ 2017-10-19 10:23 UTC (permalink / raw)
  To: Jeff Cody; +Cc: qemu-devel, kwolf, jsnow, stefanha, qemu-block

On 18/10/2017 19:27, Jeff Cody wrote:
> On Wed, Oct 18, 2017 at 06:39:26PM +0200, Paolo Bonzini wrote:
>> On 18/10/2017 18:19, Jeff Cody wrote:
>>>>> Here is what we need from common.rc for this series:
>>>>>
>>>>> _rm_test_img
>>>>> _cleanup_nbd
>>>>> _cleanup_vxhs
>>>>> _cleanup_rbd
>>>>> _cleanup_sheepdog
>>>>> _cleanup_protocols
>>>>> _cleanup_test_img
>>>>>
>>>>> They all have a common theme (cleanup), so I could move them all to a
>>>>> common.cleanup (naming suggestion?) file (which would need to be included by
>>>>> common.rc, as well).
>>>>>
>>>>> Would this be a strong enough delineation to overcome your concerns?
>>>>
>>>> A great start.  Which of these are actually needed by the tests (and
>>>> hence by common.rc) and why?
>>>
>>>  Some tests are written such that they do intermediate cleanups between
>>>  multiple internal sub-tests for varying reasons, and so use those cleanup
>>>  functions as part of their testing.  The function _cleanup_test_img
>>>  effectively calls all the other functions I listed, so they are really all
>>>  required for the tests, if they choose to call _cleanup_test_img.
>>>
>>> And for 'check' to tear everything down to a clean state, it also needs to
>>> use the cleanup functions for everything that is not just a file/directory.
>>
>> Do these tests really need the "cleanup protocols" part, because the few
>> that have more than one _cleanup_test_img (059, 066, 070, 084, 146, 171)
>> are either file-only or non-raw, so they should be able to just rebuild
>> the format on top of the same image.
>>
> 
> Maybe not, but that could just be the nature of what bugs we are testing for
> at this time.  These specific tests may not need to, but it is not
> inconceivable to have a test that involves bringing up and tearing down
> a protocol based server some arbitrary number times, to test that specific
> behavior.

Right, but such a test should probably be protocol-specific; it can just
use "file" and invoke QEMU_NBD on its own for example, similar to what
tests 058 and 162 already do.

For example, it's very different if you delete and recreate a raw image
_and_ rerun qemu-nbd, or only do the latter.

>> Maybe that's where the separation lies---protocol vs. format, where
>> cleaning up the "file" protocol need not do anything because it's done
>> when removing the test directory.  If that's the case, it'd be nice
>> because it might also make it much easier to tackle the issue with
>> parallel tests.
> 
> On final exit, yes, a test needs not remember to remove all of its mouse
> droppings.  But as far as not needing to remove images in intermediate
> stages of a given test, I think that assumes too much. For instance,
> qemu-img _should_ be able to rebuild a format on top of the same image.  But
> maybe a test wants to see if that specific functionality actually works as
> intended, and compares removing and creating an image to rebuilding on top
> of an image, etc.

Right, but let's draw a line, does such a test need to support multiple
protocols?  For example:

- 083 and 143 for example are very much NBD-specific; 083 uses
"_supported_proto nbd", while 143 probably should be using either "file"
or "nbd".

- only 058 and 162 are running qemu-nbd manually, and they actually
start a _new_ NBD protocol server


In addition not many tests do not use _make_test_img, as seen with "git
grep -LE '_make_test_img|bin/env python' [0-9][0-9][0-9]".  They are:

- 064, 070 and 135 which use the sample image and thus _should_ be using
file

- 049, 082, 111 which is creating images with "qemu-img create"; 049 and
111 might actually use nfs too.  150 is using "qemu-img convert", which
is also creation more or less

- 083 is NBD-specific because it uses the fault injector

- 113 probably should be more generic than just NBD

- 128 is pretty unique in that it creates a Linux device mapper device (!)

- 143 probably should be using either "file" or "nbd".

- 162 is also a bit unique in that it tests null-co:// and disregards
IMGFMT/IMGPROTO


So it does seem that handling the protocol in "check" is a good
approximation.

And by the way, the only existing uses of "_supported_proto" are

    _supported_proto file
    _supported_proto file nfs
    _supported_proto file sheepdog rbd nfs
    _supported_proto generic
    _supported_proto nbd
    _supported_proto nfs

so another thing to do might be to change _supported_proto to a
feature-based test:

- file/sheepdog/rbd/nfs are those that support resizing (aka "truncate")

- file/nfs are generally those that support "qemu-img create" (plus
others that should be "generic" actually, including 090, 103, 107); 150
is "file" because it needs "map" in addition to "create".

- nfs is used in test 173 to test protocol-based images with relative
filename backing strings; it probably can run on file too, anyway that's
a third important discriminating feature

- nbd is used in a bunch of random tests that can be made more generic
(094, 113, 119, 123).  Only 083 is NBD-specific because it uses the NBD
fault injector, and it actually doesn't use the protocol that is created
by the caller.


Since you are doing a lot of whole-directory moves, "_supported" tags
could become a separate configuration file, e.g.

----
# all generic, no need to include it
#[001]

[025]
fmt=raw qcow2 qed
# specify feature
proto=+resize

[143]
fmt=generic
proto=nbd
start_protocol=no

[150]
fmt=raw qcow2
proto=+create +map
----

The few tests using start_protocol=no would have to ensure parallel-safe
operation themselves.  This would also enable a more consistent handling
across shell and Python tests.

So, this is why I was wondering whether patches 3/4 kinda paint
ourselves in the corner.

So, looking at the patches:

- 1, 2, 7, 8, 9 are definitely good ideas, and should be done _before_
an eventual/hypothetical Python rewrite of "check".

- for 5, 6 I think we should be using shell job control instead in
"check" ('set -m')

  #! /bin/sh
  set -m
  # Start a job which leaves two processes behind.  By starting it
  # in the background, we can get the leader process's pid in $!
  # That pid is also the process group id of the whole job.
  sh -c 'echo subshell pid is $$; sleep 10 | sleep 15 &' &
  pgrp=$!
  wait
  echo '$! is '$pgrp', killing all processes in that group:'
  pgrep -g $pgrp -a
  kill -TERM -$pgrp
  sleep 1
  echo Leftover processes have been killed:
  ps axo pid,ppid,pgrp,stat,tty,comm|grep sleep

(Python can do the same by setting preexec_fn=os.setpgrp when calling
Subprocess.popen; then you can kill the entire group with os.killpg)

- 10 depends on everything before. SAD! ;)

It's a pity to lose the cleanup in patch 4, but I think it's better in
the long term if we have a clear idea of the tests' tasks vs. the harness's.

Thanks,

Paolo

^ permalink raw reply	[flat|nested] 37+ messages in thread

* Re: [Qemu-devel] [PATCH v5 03/10] qemu-iotests: automatically clean up bash protocol servers
  2017-10-19 10:23                       ` Paolo Bonzini
@ 2017-10-19 14:52                         ` Jeff Cody
  2017-10-19 21:03                           ` Paolo Bonzini
  0 siblings, 1 reply; 37+ messages in thread
From: Jeff Cody @ 2017-10-19 14:52 UTC (permalink / raw)
  To: Paolo Bonzini; +Cc: qemu-devel, kwolf, jsnow, stefanha, qemu-block

On Thu, Oct 19, 2017 at 12:23:39PM +0200, Paolo Bonzini wrote:
> On 18/10/2017 19:27, Jeff Cody wrote:
> > On Wed, Oct 18, 2017 at 06:39:26PM +0200, Paolo Bonzini wrote:
> >> On 18/10/2017 18:19, Jeff Cody wrote:
> >>>>> Here is what we need from common.rc for this series:
> >>>>>
> >>>>> _rm_test_img
> >>>>> _cleanup_nbd
> >>>>> _cleanup_vxhs
> >>>>> _cleanup_rbd
> >>>>> _cleanup_sheepdog
> >>>>> _cleanup_protocols
> >>>>> _cleanup_test_img
> >>>>>
> >>>>> They all have a common theme (cleanup), so I could move them all to a
> >>>>> common.cleanup (naming suggestion?) file (which would need to be included by
> >>>>> common.rc, as well).
> >>>>>
> >>>>> Would this be a strong enough delineation to overcome your concerns?
> >>>>
> >>>> A great start.  Which of these are actually needed by the tests (and
> >>>> hence by common.rc) and why?
> >>>
> >>>  Some tests are written such that they do intermediate cleanups between
> >>>  multiple internal sub-tests for varying reasons, and so use those cleanup
> >>>  functions as part of their testing.  The function _cleanup_test_img
> >>>  effectively calls all the other functions I listed, so they are really all
> >>>  required for the tests, if they choose to call _cleanup_test_img.
> >>>
> >>> And for 'check' to tear everything down to a clean state, it also needs to
> >>> use the cleanup functions for everything that is not just a file/directory.
> >>
> >> Do these tests really need the "cleanup protocols" part, because the few
> >> that have more than one _cleanup_test_img (059, 066, 070, 084, 146, 171)
> >> are either file-only or non-raw, so they should be able to just rebuild
> >> the format on top of the same image.
> >>
> > 
> > Maybe not, but that could just be the nature of what bugs we are testing for
> > at this time.  These specific tests may not need to, but it is not
> > inconceivable to have a test that involves bringing up and tearing down
> > a protocol based server some arbitrary number times, to test that specific
> > behavior.
> 
> Right, but such a test should probably be protocol-specific; it can just
> use "file" and invoke QEMU_NBD on its own for example, similar to what
> tests 058 and 162 already do.
> 
> For example, it's very different if you delete and recreate a raw image
> _and_ rerun qemu-nbd, or only do the latter.
> 
> >> Maybe that's where the separation lies---protocol vs. format, where
> >> cleaning up the "file" protocol need not do anything because it's done
> >> when removing the test directory.  If that's the case, it'd be nice
> >> because it might also make it much easier to tackle the issue with
> >> parallel tests.
> > 
> > On final exit, yes, a test needs not remember to remove all of its mouse
> > droppings.  But as far as not needing to remove images in intermediate
> > stages of a given test, I think that assumes too much. For instance,
> > qemu-img _should_ be able to rebuild a format on top of the same image.  But
> > maybe a test wants to see if that specific functionality actually works as
> > intended, and compares removing and creating an image to rebuilding on top
> > of an image, etc.
> 
> Right, but let's draw a line, does such a test need to support multiple
> protocols?  For example:
> 

This is a good question.  But, I'm not sure that this is a question this
series is trying to answer; one goal of this series is to keep the existing
APIs currently in use by tests unchanged.

> - 083 and 143 for example are very much NBD-specific; 083 uses
> "_supported_proto nbd", while 143 probably should be using either "file"
> or "nbd".
> 
> - only 058 and 162 are running qemu-nbd manually, and they actually
> start a _new_ NBD protocol server
> 
> 
> In addition not many tests do not use _make_test_img, as seen with "git
> grep -LE '_make_test_img|bin/env python' [0-9][0-9][0-9]".  They are:
> 
> - 064, 070 and 135 which use the sample image and thus _should_ be using
> file
> 
> - 049, 082, 111 which is creating images with "qemu-img create"; 049 and
> 111 might actually use nfs too.  150 is using "qemu-img convert", which
> is also creation more or less
> 
> - 083 is NBD-specific because it uses the fault injector
> 
> - 113 probably should be more generic than just NBD
> 
> - 128 is pretty unique in that it creates a Linux device mapper device (!)
> 
> - 143 probably should be using either "file" or "nbd".
> 
> - 162 is also a bit unique in that it tests null-co:// and disregards
> IMGFMT/IMGPROTO
> 
> 
> So it does seem that handling the protocol in "check" is a good
> approximation.
> 
> And by the way, the only existing uses of "_supported_proto" are
> 
>     _supported_proto file
>     _supported_proto file nfs
>     _supported_proto file sheepdog rbd nfs
>     _supported_proto generic
>     _supported_proto nbd
>     _supported_proto nfs
> 
> so another thing to do might be to change _supported_proto to a
> feature-based test:
> 
> - file/sheepdog/rbd/nfs are those that support resizing (aka "truncate")
> 
> - file/nfs are generally those that support "qemu-img create" (plus
> others that should be "generic" actually, including 090, 103, 107); 150
> is "file" because it needs "map" in addition to "create".
> 
> - nfs is used in test 173 to test protocol-based images with relative
> filename backing strings; it probably can run on file too, anyway that's
> a third important discriminating feature
> 
> - nbd is used in a bunch of random tests that can be made more generic
> (094, 113, 119, 123).  Only 083 is NBD-specific because it uses the NBD
> fault injector, and it actually doesn't use the protocol that is created
> by the caller.
> 
> 
> Since you are doing a lot of whole-directory moves, "_supported" tags
> could become a separate configuration file, e.g.
> 
> ----
> # all generic, no need to include it
> #[001]
> 
> [025]
> fmt=raw qcow2 qed
> # specify feature
> proto=+resize
> 
> [143]
> fmt=generic
> proto=nbd
> start_protocol=no
> 
> [150]
> fmt=raw qcow2
> proto=+create +map
> ----
> 
> The few tests using start_protocol=no would have to ensure parallel-safe
> operation themselves.  This would also enable a more consistent handling
> across shell and Python tests.
> 
> So, this is why I was wondering whether patches 3/4 kinda paint
> ourselves in the corner.
> 

I think this conflates a bit how we'd like to restructure tests in a future
harness rewrite, and what this series does.  I'm advocating that this series
keep the same test APIs intact, and remove the need for tests to perform
exit cleanup.

(Patch 10 is just some icing, since patches 1-9 make it fairly easy to
add)

If we look at what patches 3 & 4 do:

Patch 3:

    - Code movement within common.rc, but doesn't change the API.  Tests
      still just call _cleanup_test_img() as needed.

    - It does break apart _cleanup_test_img(), thereby technically creating
      some new APIs available to future tests:
         * _cleanup_nbd()
         * _cleanup_vxhs()
         * _cleanup_rbd()
         * _cleanup_sheepdog()
         * _cleanup_protocols()

      Maybe these new APIs are a sticking point?  If so, perhaps we can mark
      them (via comments) as internal-only?

    - ./check does an extra protocol cleanup check after a test is run, via
      the new _cleanup_protocols().

    As far as existing tests go, no changes yet.

Patch 4:

    - Removes test exit cleanup from tests

    Now this does change test behavior, as it relies on the harness for file
    and protocol cleanup at test exit.

    This will indeed paint us in a corner if we want a new check.py to not
    perform the test exit cleanup, and leave test cleanup (either partially
    or fully) as the responsibility for the tests. [1]

> So, looking at the patches:
> 
> - 1, 2, 7, 8, 9 are definitely good ideas, and should be done _before_
> an eventual/hypothetical Python rewrite of "check".

Alas, 9 requires 4 (which in turn requires 3).  Without 4, there is nothing
to keep, as the tests try to remove it all.

> 
> - for 5, 6 I think we should be using shell job control instead in
> "check" ('set -m')
> 
>   #! /bin/sh
>   set -m
>   # Start a job which leaves two processes behind.  By starting it
>   # in the background, we can get the leader process's pid in $!
>   # That pid is also the process group id of the whole job.
>   sh -c 'echo subshell pid is $$; sleep 10 | sleep 15 &' &
>   pgrp=$!
>   wait
>   echo '$! is '$pgrp', killing all processes in that group:'
>   pgrep -g $pgrp -a
>   kill -TERM -$pgrp
>   sleep 1
>   echo Leftover processes have been killed:
>   ps axo pid,ppid,pgrp,stat,tty,comm|grep sleep
> 

Existing tests right now use _cleanup_qemu in their tests (outside of final
cleanup): 095 109 117 130, etc.  So we can do process control differently,
but _cleanup_qemu still needs to exist and also clean up other files (such
as fifos, close fds, etc..), and provide the same functionality (optional
wait-for-completion, etc.), if we are keeping the usage by tests the same.

> (Python can do the same by setting preexec_fn=os.setpgrp when calling
> Subprocess.popen; then you can kill the entire group with os.killpg)
> 

Yeah - a new check rewrite in a language like python would make process
control significantly easier.

> - 10 depends on everything before. SAD! ;)
> 
> It's a pity to lose the cleanup in patch 4, but I think it's better in
> the long term if we have a clear idea of the tests' tasks vs. the harness's.
>

This is the crux of it all, I suppose.

[1] So on that point: do you think individual tests should be responsible
for cleaning up files and processes at test exit?  If that answer is a 'yes'
to either files or processes, then 3, 4, 6 (and maybe 9) are incompatible
with a future redesign with that assumption.  FWIW, my thought is that the
answer should be "the harness shall perform both file and process cleanup on
test exit".

Jeff

^ permalink raw reply	[flat|nested] 37+ messages in thread

* Re: [Qemu-devel] [PATCH v5 03/10] qemu-iotests: automatically clean up bash protocol servers
  2017-10-19 14:52                         ` Jeff Cody
@ 2017-10-19 21:03                           ` Paolo Bonzini
  0 siblings, 0 replies; 37+ messages in thread
From: Paolo Bonzini @ 2017-10-19 21:03 UTC (permalink / raw)
  To: Jeff Cody; +Cc: qemu-devel, kwolf, jsnow, stefanha, qemu-block

On 19/10/2017 16:52, Jeff Cody wrote:
> On Thu, Oct 19, 2017 at 12:23:39PM +0200, Paolo Bonzini wrote:
>> On 18/10/2017 19:27, Jeff Cody wrote:
>>> On final exit, yes, a test needs not remember to remove all of its mouse
>>> droppings.  But as far as not needing to remove images in intermediate
>>> stages of a given test, I think that assumes too much. For instance,
>>> qemu-img _should_ be able to rebuild a format on top of the same image.  But
>>> maybe a test wants to see if that specific functionality actually works as
>>> intended, and compares removing and creating an image to rebuilding on top
>>> of an image, etc.
>>
>> Right, but let's draw a line, does such a test need to support multiple
>> protocols?  For example:
>>
> This is a good question.  But, I'm not sure that this is a question this
> series is trying to answer; one goal of this series is to keep the existing
> APIs currently in use by tests unchanged.

Right, but in order to do so it's also making the line between test and
harness unclear, which is something I'd like to avoid (when I looked at
it a couple months ago, the line was surprisingly clear apart from some
confusion around searching for programs, and separating check vs.
common.rc turned out to be very easy).

>> [snip] So, this is why I was wondering whether patches 3/4 kinda paint
>> ourselves in the corner.
> 
> I think this conflates a bit how we'd like to restructure tests in a future
> harness rewrite, and what this series does.

This is true.  But this sure is not exactly keeping the test APIs
intact.  The APIs are intact, but the usage isn't---for example, for
patch 9 to work you need to _not_ use _cleanup_test_img in the tests.

> If we look at what patches 3 & 4 do:
> 
> Patch 3:
> 
>     - Code movement within common.rc, but doesn't change the API.  Tests
>       still just call _cleanup_test_img() as needed.
> 
>     - It does break apart _cleanup_test_img(), thereby technically creating
>       some new APIs available to future tests:
>          * _cleanup_nbd()
>          * _cleanup_vxhs()
>          * _cleanup_rbd()
>          * _cleanup_sheepdog()
>          * _cleanup_protocols()
> 
>       Maybe these new APIs are a sticking point?  If so, perhaps we can mark
>       them (via comments) as internal-only?
> 
>     - ./check does an extra protocol cleanup check after a test is run, via
>       the new _cleanup_protocols().
> 
>     As far as existing tests go, no changes yet.

Here I'd like to remove _cleanup_test_img as a test API even.  Most
invocations out of the "trap" are unnecessary.  Some (for VMDK) can be
changed to _rm_test_img or changed to create a file with a new name (to
make patch 9 more effective).

With that change, we can apply patch 4 with no issue.

> Patch 4:
> 
>     - Removes test exit cleanup from tests
> 
>     Now this does change test behavior, as it relies on the harness for file
>     and protocol cleanup at test exit.
> 
>     This will indeed paint us in a corner if we want a new check.py to not
>     perform the test exit cleanup, and leave test cleanup (either partially
>     or fully) as the responsibility for the tests. [1]

I think patch 9 is enough proof that check should perform the test exit
cleanup.

But again, the thing I'm worried about is mixing code between check and
tests.

>> So, looking at the patches:
>>
>> - 1, 2, 7, 8, 9 are definitely good ideas, and should be done _before_
>> an eventual/hypothetical Python rewrite of "check".
> 
> Alas, 9 requires 4 (which in turn requires 3).  Without 4, there is nothing
> to keep, as the tests try to remove it all.
> 
>> - for 5, 6 I think we should be using shell job control instead in
>> "check" ('set -m')
>>
>>   #! /bin/sh
>>   set -m
>>   # Start a job which leaves two processes behind.  By starting it
>>   # in the background, we can get the leader process's pid in $!
>>   # That pid is also the process group id of the whole job.
>>   sh -c 'echo subshell pid is $$; sleep 10 | sleep 15 &' &
>>   pgrp=$!
>>   wait
>>   echo '$! is '$pgrp', killing all processes in that group:'
>>   pgrep -g $pgrp -a
>>   kill -TERM -$pgrp
>>   sleep 1
>>   echo Leftover processes have been killed:
>>   ps axo pid,ppid,pgrp,stat,tty,comm|grep sleep
>>
> 
> Existing tests right now use _cleanup_qemu in their tests (outside of final
> cleanup): 095 109 117 130, etc.  So we can do process control differently,
> but _cleanup_qemu still needs to exist and also clean up other files (such
> as fifos, close fds, etc..), and provide the same functionality (optional
> wait-for-completion, etc.), if we are keeping the usage by tests the same.

Yes, _cleanup_qemu can stay in the tests.

> [1] So on that point: do you think individual tests should be responsible
> for cleaning up files and processes at test exit?  If that answer is a 'yes'
> to either files or processes, then 3, 4, 6 (and maybe 9) are incompatible
> with a future redesign with that assumption.  FWIW, my thought is that the
> answer should be "the harness shall perform both file and process cleanup on
> test exit".

I definitely agree on that, but I that the harness can be a little less
refined: kill the whole process group and rm -rf the whole test
directory.  Protocols may need a little bit of refinement, but
everything else should use OS services and ignore the QEMUness of
qemu-iotests (and especially the fact that tests are shell scripts).

Paolo

^ permalink raw reply	[flat|nested] 37+ messages in thread

end of thread, other threads:[~2017-10-19 21:03 UTC | newest]

Thread overview: 37+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-10-17 16:31 [Qemu-devel] [PATCH v5 00/10] qemu-iotests improvements Jeff Cody
2017-10-17 16:31 ` [Qemu-devel] [PATCH v5 01/10] qemu-iotests: refuse to run if TEST_DIR contains spaces Jeff Cody
2017-10-18  1:03   ` Eric Blake
2017-10-18  3:05     ` Jeff Cody
2017-10-17 16:31 ` [Qemu-devel] [PATCH v5 02/10] qemu-iotests: set TEST_DIR to a unique dir for each test Jeff Cody
2017-10-17 16:31 ` [Qemu-devel] [PATCH v5 03/10] qemu-iotests: automatically clean up bash protocol servers Jeff Cody
2017-10-18  1:15   ` Eric Blake
2017-10-18 14:46   ` Paolo Bonzini
2017-10-18 15:03     ` Jeff Cody
2017-10-18 15:16       ` Paolo Bonzini
2017-10-18 15:34         ` Jeff Cody
2017-10-18 15:39           ` Paolo Bonzini
2017-10-18 15:50             ` Jeff Cody
2017-10-18 15:51               ` Paolo Bonzini
2017-10-18 16:19                 ` Jeff Cody
2017-10-18 16:39                   ` Paolo Bonzini
2017-10-18 17:27                     ` Jeff Cody
2017-10-19 10:23                       ` Paolo Bonzini
2017-10-19 14:52                         ` Jeff Cody
2017-10-19 21:03                           ` Paolo Bonzini
2017-10-18 15:06     ` Eric Blake
2017-10-18 15:43     ` Daniel P. Berrange
2017-10-17 16:31 ` [Qemu-devel] [PATCH v5 04/10] qemu-iotests: remove file cleanup from bash tests Jeff Cody
2017-10-18 13:46   ` Eric Blake
2017-10-18 13:56     ` Jeff Cody
2017-10-17 16:31 ` [Qemu-devel] [PATCH v5 05/10] qemu-iotests: change qemu pid and fd tracking / cleanup Jeff Cody
2017-10-18 13:59   ` Jeff Cody
2017-10-18 14:11     ` Eric Blake
2017-10-18 14:22   ` Eric Blake
2017-10-17 16:31 ` [Qemu-devel] [PATCH v5 06/10] qemu-iotests: make ./check automatically reap QEMU processes Jeff Cody
2017-10-18 14:24   ` Eric Blake
2017-10-17 16:31 ` [Qemu-devel] [PATCH v5 07/10] qemu-iotests: run python tests in own subdirectories Jeff Cody
2017-10-17 16:31 ` [Qemu-devel] [PATCH v5 08/10] qemu-iotests: modify python tests to run from subdir Jeff Cody
2017-10-17 16:31 ` [Qemu-devel] [PATCH v5 09/10] qemu-iotests: add option to save temp files on error Jeff Cody
2017-10-18 14:33   ` Eric Blake
2017-10-17 16:31 ` [Qemu-devel] [PATCH v5 10/10] qemu-iotests: add support for running multi-threaded iotests Jeff Cody
2017-10-18  3:45   ` Jeff Cody

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.