Richard W.M. Jones
2014-Sep-16  14:05 UTC
[Libguestfs] [PATCH 0/3] tests: Introduce test harness for running tests.
These are my thoughts on adding a test harness to run tests instead of using automake. The aim of this exercise is to allow us to run the full test suite on an installed copy of libguestfs. Another aim is to allow us to work around all the limitations and problems of automake. The first patch makes an observation that since the ./run script sets up $PATH to contain all the directories containing binaries, we can change all the test scripts to use (eg) 'guestfish' instead of '../fish/guestfish'. This allows the test scripts to be reused to test the installed binary, simply by not invoking the ./run script. Note this change is completely compatible with the current test system. The second patch is just preparation. The third patch adds (or rather, generates) a shell script in the top level directory called 'test-harness'. This script is what will run the tests (replacing automake). The test-harness script can be used both to run the tests on the built tree, using: ./run test-harness [subdirectory] or on an installed tree. The plan would be to install all the test scripts and data files required into @libdir@/guestfs/tests, and then you could run the test suite by doing: cd /usr/lib/guestfs/tests ./test-harness ./test-harness --fast ./test-harness --slow --valgrind The test-harness script is wired into the existing Makefile.am's by having the generator also generate 'tests.mk' fragments which are included in the existing Makefile.am's. They contain rules for 'check', 'check-valgrind' etc which were previously written by hand. The aim here is to have commands like: make check make -C inspector check-valgrind just work as they do currently. Some unfinished business in the current patch set: - Some tests need data files (tests/data and tests/guests) but these are probably too large to ship around with the test suite, and have to be generated because we don't want the test suite to require the appliance. Exactly how this will work is not fully decided. - Only the inspector/ subdirectory has been converted. All the other tests and directories would have to be converted. Although this is quite a lot of compatibility, it's still going to be a long and painful process. Rich.
Richard W.M. Jones
2014-Sep-16  14:05 UTC
[Libguestfs] [PATCH 1/3] tests: Don't use relative paths to binaries in tests.
All tests run under the ./run binary.  For a long time the ./run
binary has set the $PATH environment variable to contain all of the
directories with binaries in them.
Therefore there is no reason to use ../fish/guestfish instead of just
plain guestfish (and the same applies to other built binaries).
---
 align/test-virt-alignment-scan-guests.sh           |  2 +-
 align/test-virt-alignment-scan.sh                  |  2 +-
 builder/test-virt-builder-list.sh                  |  6 ++--
 builder/test-virt-builder-planner.sh               |  6 ++--
 builder/test-virt-builder.sh                       |  6 ++--
 builder/test-virt-index-validate.sh                |  6 ++--
 builder/website/test-guest.sh                      |  6 ++--
 builder/website/validate.sh                        |  6 ++--
 cat/test-virt-cat.sh                               |  4 +--
 cat/test-virt-filesystems.sh                       |  4 +--
 cat/test-virt-log.sh                               |  2 +-
 cat/test-virt-ls.sh                                |  8 ++---
 customize/test-virt-customize.sh                   |  2 +-
 df/test-virt-df-guests.sh                          |  2 +-
 df/test-virt-df.sh                                 |  2 +-
 diff/test-virt-diff.sh                             |  8 ++---
 edit/test-virt-edit.sh                             | 14 ++++----
 fish/test-a.sh                                     | 14 ++++----
 fish/test-add-domain.sh                            | 14 ++++----
 fish/test-add-uri.sh                               | 30 ++++++++--------
 fish/test-alloc.sh                                 |  4 +--
 fish/test-copy.sh                                  |  4 +--
 fish/test-d.sh                                     | 10 +++---
 fish/test-edit.sh                                  |  2 +-
 fish/test-escapes.sh                               |  2 +-
 fish/test-events.sh                                |  2 +-
 fish/test-file-attrs.sh                            |  2 +-
 fish/test-find0.sh                                 |  2 +-
 fish/test-glob.sh                                  |  2 +-
 fish/test-inspect.sh                               |  2 +-
 fish/test-invalid-params.sh                        |  6 ++--
 fish/test-mount-local.sh                           |  2 +-
 fish/test-prep.sh                                  |  2 +-
 fish/test-read-file.sh                             |  2 +-
 fish/test-remote-events.sh                         | 10 +++---
 fish/test-remote.sh                                | 16 ++++-----
 fish/test-reopen.sh                                |  2 +-
 fish/test-run.sh                                   |  2 +-
 fish/test-stringlist.sh                            | 10 +++---
 fish/test-tilde.sh                                 | 12 +++----
 fish/test-upload-to-dir.sh                         |  2 +-
 format/test-virt-format.sh                         |  6 ++--
 fuse/test-fuse-umount-race.sh                      |  6 ++--
 fuse/test-fuse.sh                                  | 13 +++----
 inspector/test-virt-inspector.sh                   |  4 +--
 make-fs/test-virt-make-fs.sh                       |  4 +--
 p2v/test-virt-p2v.sh                               |  4 +--
 rescue/test-virt-rescue-suggest.sh                 |  2 +-
 resize/test-virt-resize.sh                         | 14 ++++----
 sparsify/test-virt-sparsify-in-place.sh            |  6 ++--
 sparsify/test-virt-sparsify.sh                     |  6 ++--
 sysprep/test-virt-sysprep-passwords.sh             |  6 ++--
 sysprep/test-virt-sysprep-script.sh                |  8 ++---
 sysprep/test-virt-sysprep.sh                       |  6 ++--
 tests/9p/test-9p.sh                                |  4 +--
 tests/btrfs/test-btrfs-devices.sh                  |  6 ++--
 tests/create/test-disk-create.sh                   |  4 +--
 tests/disks/test-qemu-drive-libvirt.sh             |  3 +-
 tests/disks/test-qemu-drive.sh                     | 20 +++++------
 tests/guests/guest-aux/make-debian-img.sh          |  2 +-
 tests/guests/guest-aux/make-ubuntu-img.sh          |  2 +-
 tests/guests/guest-aux/make-windows-img.sh         |  4 +--
 tests/luks/test-luks-list.sh                       |  4 +--
 tests/luks/test-luks.sh                            |  4 +--
 tests/lvm/test-lvm-filtering.sh                    |  2 +-
 tests/md/test-inspect-fstab-md.sh                  |  8 ++---
 tests/md/test-inspect-fstab.sh                     | 17 +++++----
 tests/md/test-list-filesystems.sh                  |  2 +-
 tests/md/test-list-md-devices.sh                   |  4 +--
 tests/md/test-mdadm.sh                             | 40 +++++++++++-----------
 tests/mountable/test-mountable-inspect.sh          | 11 +++---
 tests/network/test-network.sh                      |  4 +--
 tests/ntfsclone/test-ntfsclone.sh                  |  8 ++---
 tests/protocol/test-both-ends-cancel.sh            |  2 +-
 .../test-cancellation-download-librarycancels.sh   |  2 +-
 .../test-cancellation-upload-daemoncancels.sh      |  2 +-
 tests/protocol/test-qemudie-killsub.sh             |  4 +--
 tests/protocol/test-qemudie-midcommand.sh          |  4 +--
 tests/protocol/test-qemudie-synch.sh               |  4 +--
 tests/qemu/qemu-force-tcg.sh                       |  4 +--
 tests/qemu/qemu-liveness.sh                        |  4 +--
 tests/qemu/qemu-snapshot-isolation.sh              | 12 +++----
 tests/regressions/rhbz1001875.sh                   |  2 +-
 tests/regressions/rhbz1044014.sh                   |  4 +--
 tests/regressions/rhbz1054761.sh                   |  4 +--
 tests/regressions/rhbz1091803.sh                   |  2 +-
 tests/regressions/rhbz503169c13.sh                 |  2 +-
 tests/regressions/rhbz557655.sh                    |  4 +--
 tests/regressions/rhbz563450.sh                    |  2 +-
 tests/regressions/rhbz563450b.sh                   |  2 +-
 tests/regressions/rhbz576879.sh                    |  2 +-
 tests/regressions/rhbz578407.sh                    | 14 ++++----
 tests/regressions/rhbz580246.sh                    |  2 +-
 tests/regressions/rhbz602997.sh                    |  6 ++--
 tests/regressions/rhbz690819.sh                    |  6 ++--
 tests/regressions/rhbz727178.sh                    |  9 +++--
 tests/regressions/rhbz789960.sh                    |  2 +-
 tests/regressions/rhbz811649.sh                    |  4 +--
 tests/regressions/rhbz895904.sh                    |  2 +-
 tests/regressions/rhbz909624.sh                    |  2 +-
 tests/regressions/rhbz957772.sh                    |  2 +-
 tests/regressions/rhbz975797.sh                    | 10 +++---
 tests/relative-paths/test-relative-paths.sh        |  4 +--
 tests/rsync/test-rsync.sh                          |  8 ++---
 v2v/test-v2v-i-disk.sh                             |  4 +--
 v2v/test-v2v-i-ova.sh                              |  4 +--
 v2v/test-v2v-machine-readable.sh                   |  2 +-
 v2v/test-v2v-networks-and-bridges.sh               |  4 +--
 v2v/test-v2v-no-copy.sh                            |  6 ++--
 v2v/test-v2v-o-glance.sh                           |  4 +--
 v2v/test-v2v-o-libvirt.sh                          |  4 +--
 v2v/test-v2v-o-null.sh                             |  4 +--
 v2v/test-v2v-o-rhev.sh                             |  4 +--
 v2v/test-v2v-o-vdsm-options.sh                     |  4 +--
 v2v/test-v2v-of-option.sh                          |  6 ++--
 v2v/test-v2v-on-option.sh                          |  4 +--
 v2v/test-v2v-print-source.sh                       |  2 +-
 v2v/test-v2v-real-conversions.sh                   |  2 +-
 v2v/test-v2v-windows-conversion.sh                 |  6 ++--
 119 files changed, 323 insertions(+), 346 deletions(-)
diff --git a/align/test-virt-alignment-scan-guests.sh
b/align/test-virt-alignment-scan-guests.sh
index 3647c29..99e2585 100755
--- a/align/test-virt-alignment-scan-guests.sh
+++ b/align/test-virt-alignment-scan-guests.sh
@@ -26,7 +26,7 @@ fi
 guestsdir="$(cd ../tests/guests && pwd)"
 libvirt_uri="test://$guestsdir/guests-all-good.xml"
 
-$VG ./virt-alignment-scan -c "$libvirt_uri"
+$VG virt-alignment-scan -c "$libvirt_uri"
 r=$?
 
 # 0, 2 and 3 are reasonable non-error exit codes.  Others are errors.
diff --git a/align/test-virt-alignment-scan.sh
b/align/test-virt-alignment-scan.sh
index 2b1ec37..293a9ef 100755
--- a/align/test-virt-alignment-scan.sh
+++ b/align/test-virt-alignment-scan.sh
@@ -18,7 +18,7 @@
 
 export LANG=C
 
-$VG ./virt-alignment-scan -a ../tests/guests/fedora.img
+$VG virt-alignment-scan -a ../tests/guests/fedora.img
 r=$?
 
 # 0, 2 and 3 are reasonable non-error exit codes.  Others are errors.
diff --git a/builder/test-virt-builder-list.sh
b/builder/test-virt-builder-list.sh
index 76d7913..49daae7 100755
--- a/builder/test-virt-builder-list.sh
+++ b/builder/test-virt-builder-list.sh
@@ -26,7 +26,7 @@ abs_builddir=$(pwd)
 export XDG_CONFIG_HOME export
XDG_CONFIG_DIRS="$abs_builddir/test-config"
 
-short_list=$($VG ./virt-builder --no-check-signature --no-cache --list)
+short_list=$($VG virt-builder --no-check-signature --no-cache --list)
 
 if [ "$short_list" != "phony-debian             x86_64     Phony
Debian
 phony-fedora             x86_64     Phony Fedora
@@ -40,7 +40,7 @@ phony-windows            x86_64     Phony Windows" ];
then
     exit 1
 fi
 
-long_list=$(./virt-builder --no-check-signature --no-cache --list --long)
+long_list=$(virt-builder --no-check-signature --no-cache --list --long)
 
 if [ "$long_list" != "Source URI:
file://$abs_builddir/test-index
 
@@ -111,7 +111,7 @@ Phony Windows look-alike used for testing." ]; then
     exit 1
 fi
 
-json_list=$(./virt-builder --no-check-signature --no-cache --list --list-format
json)
+json_list=$(virt-builder --no-check-signature --no-cache --list --list-format
json)
 
 if [ "$json_list" != "{
   \"version\": 1,
diff --git a/builder/test-virt-builder-planner.sh
b/builder/test-virt-builder-planner.sh
index 6b839bb..f974c27 100755
--- a/builder/test-virt-builder-planner.sh
+++ b/builder/test-virt-builder-planner.sh
@@ -29,7 +29,7 @@ if [ ! -f fedora.xz -o ! -f fedora.qcow2 -o ! -f
fedora.qcow2.xz ]; then
     exit 77
 fi
 
-if [ "$(../fish/guestfish get-backend)" = "uml" ]; then
+if [ "$(guestfish get-backend)" = "uml" ]; then
     echo "$0: test skipped because backend is UML"
     exit 77
 fi
@@ -43,8 +43,8 @@ for input in phony-fedora phony-fedora-qcow2
phony-fedora-qcow2-uncompressed pho
             if [ "$size" != "none" ]; then args="$args
--size $size"; fi
             if [ "$format" != "none" ]; then
args="$args --format $format"; fi
 
-            echo $VG ./virt-builder $input $args
-            $VG ./virt-builder $input $args
+            echo $VG virt-builder $input $args
+            $VG virt-builder $input $args
         done
     done
 done
diff --git a/builder/test-virt-builder.sh b/builder/test-virt-builder.sh
index f927a96..f357d12 100755
--- a/builder/test-virt-builder.sh
+++ b/builder/test-virt-builder.sh
@@ -37,7 +37,7 @@ fi
 output=phony-fedora.img
 
 format=qcow2
-if [ "$(../fish/guestfish get-backend)" = "uml" ]; then
+if [ "$(guestfish get-backend)" = "uml" ]; then
     format=raw
 
     # XXX We specifically want virt-builder to work with the UML
@@ -55,7 +55,7 @@ rm -f $output
 # Note we cannot test --install, --run since the phony Fedora doesn't
 # have a real OS inside just some configuration files.  Just about
 # every other option is fair game.
-$VG ./virt-builder phony-fedora \
+$VG virt-builder phony-fedora \
     -v --no-cache --no-check-signature $no_network \
     -o $output --size 2G --format $format \
     --arch x86_64 \
@@ -74,7 +74,7 @@ $VG ./virt-builder phony-fedora \
     --firstboot-install "minicom,inkscape"
 
 # Check that some modifications were made.
-$VG ../fish/guestfish --ro -i -a $output > test.out <<EOF
+$VG guestfish --ro -i -a $output > test.out <<EOF
 # Uploaded files
 is-file /etc/foo/bar/baz/Makefile
 cat /etc/foo/bar/baz/foo
diff --git a/builder/test-virt-index-validate.sh
b/builder/test-virt-index-validate.sh
index 37e7339..c66929d 100755
--- a/builder/test-virt-index-validate.sh
+++ b/builder/test-virt-index-validate.sh
@@ -19,6 +19,6 @@
 export LANG=C
 set -e
 
-! $VG ./virt-index-validate test-virt-index-validate-bad-1
-$VG ./virt-index-validate test-virt-index-validate-good-1
-$VG ./virt-index-validate test-virt-index-validate-good-2
+! $VG virt-index-validate test-virt-index-validate-bad-1
+$VG virt-index-validate test-virt-index-validate-good-1
+$VG virt-index-validate test-virt-index-validate-good-2
diff --git a/builder/website/test-guest.sh b/builder/website/test-guest.sh
index 9372425..7854aeb 100755
--- a/builder/website/test-guest.sh
+++ b/builder/website/test-guest.sh
@@ -27,14 +27,14 @@
 export LANG=C
 set -e
 
-if [ ! -x builder/virt-builder ]; then
+if ! virt-builder --help >/dev/null 2>&1 || [ ! -f
builder/virt-builder.pod ]; then
     echo "$0: running the test from the wrong directory, or libguestfs has
not been built"
     exit 1
 fi
 
 if [ $# -lt 1 ]; then
     echo "$0: missing os-version"
-    echo "try: ./run builder/virt-builder -l"
+    echo "try: ./run virt-builder -l"
     exit 1
 fi
 
@@ -42,7 +42,7 @@ osversion="$1"
 shift
 output="$osversion.img"
 
-builder/virt-builder "$osversion" \
+virt-builder "$osversion" \
     --no-cache -v \
     --size 10G \
     --root-password password:123456 \
diff --git a/builder/website/validate.sh b/builder/website/validate.sh
index f2e24cf..2a7ba32 100755
--- a/builder/website/validate.sh
+++ b/builder/website/validate.sh
@@ -24,8 +24,8 @@ fn=test-filename-for-index-validate
 rm -f $fn
 touch $fn
 
-$VG ../virt-index-validate $srcdir/index
-$VG ../virt-index-validate $srcdir/index.asc
-$VG ../virt-index-validate $fn
+$VG virt-index-validate $srcdir/index
+$VG virt-index-validate $srcdir/index.asc
+$VG virt-index-validate $fn
 
 rm $fn
diff --git a/cat/test-virt-cat.sh b/cat/test-virt-cat.sh
index 8c8e5d7..fbf09ea 100755
--- a/cat/test-virt-cat.sh
+++ b/cat/test-virt-cat.sh
@@ -20,11 +20,11 @@ export LANG=C
 set -e
 
 # Read out the test files from the image using virt-cat.
-if [ "$($VG ./virt-cat ../tests/guests/fedora.img /etc/test1)" !=
"abcdefg" ]; then
+if [ "$($VG virt-cat ../tests/guests/fedora.img /etc/test1)" !=
"abcdefg" ]; then
     echo "$0: error: mismatch in file test1"
     exit 1
 fi
-if [ "$($VG ./virt-cat ../tests/guests/fedora.img /etc/test2)" !=
"" ]; then
+if [ "$($VG virt-cat ../tests/guests/fedora.img /etc/test2)" !=
"" ]; then
     echo "$0: error: mismatch in file test2"
     exit 1
 fi
diff --git a/cat/test-virt-filesystems.sh b/cat/test-virt-filesystems.sh
index 8ed29e4..2999950 100755
--- a/cat/test-virt-filesystems.sh
+++ b/cat/test-virt-filesystems.sh
@@ -19,7 +19,7 @@
 export LANG=C
 set -e
 
-output="$($VG ./virt-filesystems -a ../tests/guests/fedora.img |
sort)"
+output="$($VG virt-filesystems -a ../tests/guests/fedora.img | sort)"
 expected="/dev/VG/LV1
 /dev/VG/LV2
 /dev/VG/LV3
@@ -32,7 +32,7 @@ if [ "$output" != "$expected" ]; then
     exit 1
 fi
 
-output="$($VG ./virt-filesystems -a ../tests/guests/fedora.img --all
--long --uuid -h --no-title | awk '{print $1}' | sort -u)"
+output="$($VG virt-filesystems -a ../tests/guests/fedora.img --all --long
--uuid -h --no-title | awk '{print $1}' | sort -u)"
 expected="/dev/VG
 /dev/VG/LV1
 /dev/VG/LV2
diff --git a/cat/test-virt-log.sh b/cat/test-virt-log.sh
index 5f04c10..af6bb95 100755
--- a/cat/test-virt-log.sh
+++ b/cat/test-virt-log.sh
@@ -21,5 +21,5 @@ set -e
 
 # Read out the log files from the image using virt-log.
 for f in ../tests/guests/{fedora,debian,ubuntu}.img; do
-    if [ -s "$f" ]; then $VG ./virt-log -a "$f"; fi
+    if [ -s "$f" ]; then $VG virt-log -a "$f"; fi
 done
diff --git a/cat/test-virt-ls.sh b/cat/test-virt-ls.sh
index 55fc114..5bb4b8a 100755
--- a/cat/test-virt-ls.sh
+++ b/cat/test-virt-ls.sh
@@ -20,7 +20,7 @@ export LANG=C
 set -e
 
 # Read out the test directory using virt-ls.
-if [ "$($VG ./virt-ls ../tests/guests/fedora.img /bin)" != "ls
+if [ "$($VG virt-ls ../tests/guests/fedora.img /bin)" != "ls
 test1
 test2
 test3
@@ -33,7 +33,7 @@ test7" ]; then
 fi
 
 # Try the -lR option.
-output="$($VG ./virt-ls -lR ../tests/guests/fedora.img /boot | awk
'{print $1 $2 $4}')"
+output="$($VG virt-ls -lR ../tests/guests/fedora.img /boot | awk
'{print $1 $2 $4}')"
 expected="d0755/boot
 d0755/boot/grub
 -0644/boot/grub/grub.conf
@@ -49,5 +49,5 @@ if [ "$output" != "$expected" ]; then
 fi
 
 # Try the -l and -R options.   XXX Should check the output.
-$VG ./virt-ls -l ../tests/guests/fedora.img /
-$VG ./virt-ls -R ../tests/guests/fedora.img /
+$VG virt-ls -l ../tests/guests/fedora.img /
+$VG virt-ls -R ../tests/guests/fedora.img /
diff --git a/customize/test-virt-customize.sh b/customize/test-virt-customize.sh
index 623e6a2..979e6f0 100755
--- a/customize/test-virt-customize.sh
+++ b/customize/test-virt-customize.sh
@@ -26,7 +26,7 @@ for f in ../tests/guests/{debian,fedora,ubuntu}.img; do
     # Ignore zero-sized windows.img if ntfs-3g is not installed.
     if [ -s "$f" ]; then
         # Add --no-network so UML works.
-	$VG ./virt-customize -n -a $f \
+	$VG virt-customize -n -a $f \
             --no-network \
             --write /etc/motd:HELLO \
             --chmod 0600:/etc/motd \
diff --git a/df/test-virt-df-guests.sh b/df/test-virt-df-guests.sh
index 126b880..b485cd7 100755
--- a/df/test-virt-df-guests.sh
+++ b/df/test-virt-df-guests.sh
@@ -29,4 +29,4 @@ fi
 guestsdir="$(cd ../tests/guests && pwd)"
 libvirt_uri="test://$guestsdir/guests.xml"
 
-$VG ./virt-df -c "$libvirt_uri"
+$VG virt-df -c "$libvirt_uri"
diff --git a/df/test-virt-df.sh b/df/test-virt-df.sh
index 6be90f8..6a69cea 100755
--- a/df/test-virt-df.sh
+++ b/df/test-virt-df.sh
@@ -20,7 +20,7 @@ export LANG=C
 set -e
 
 # Run virt-df.
-output=$($VG ./virt-df ../tests/guests/fedora.img)
+output=$($VG virt-df ../tests/guests/fedora.img)
 
 # Check title is the first line.
 if [[ ! $output =~ ^Filesystem.* ]]; then
diff --git a/diff/test-virt-diff.sh b/diff/test-virt-diff.sh
index 3a3a1aa..fa13411 100755
--- a/diff/test-virt-diff.sh
+++ b/diff/test-virt-diff.sh
@@ -24,7 +24,7 @@ if [ ! -f ../tests/guests/fedora.img ]; then
     exit 77
 fi
 
-if [ "$(../fish/guestfish get-backend)" = "uml" ]; then
+if [ "$(guestfish get-backend)" = "uml" ]; then
     echo "$0: test skipped because backend is UML"
     exit 77
 fi
@@ -32,16 +32,16 @@ fi
 rm -f fedora.qcow2
 
 # Modify a copy of the image.
-../fish/guestfish -- \
+guestfish -- \
   disk-create fedora.qcow2 qcow2 -1 \
     backingfile:../tests/guests/fedora.img backingformat:raw
 
-../fish/guestfish -a fedora.qcow2 -i <<EOF
+guestfish -a fedora.qcow2 -i <<EOF
 touch /diff
 write-append /etc/motd "Testing virt-diff\n"
 EOF
 
-output="$($VG ./virt-diff -a ../tests/guests/fedora.img -A
fedora.qcow2)"
+output="$($VG virt-diff -a ../tests/guests/fedora.img -A
fedora.qcow2)"
 
 expected="\
 + - 0644          0 /diff
diff --git a/edit/test-virt-edit.sh b/edit/test-virt-edit.sh
index 99c2e7c..33c0603 100755
--- a/edit/test-virt-edit.sh
+++ b/edit/test-virt-edit.sh
@@ -19,7 +19,7 @@
 export LANG=C
 set -e
 
-if [ "$(../fish/guestfish get-backend)" = "uml" ]; then
+if [ "$(guestfish get-backend)" = "uml" ]; then
     echo "$0: skipping test because uml backend does not support
qcow2"
     exit 77
 fi
@@ -28,15 +28,15 @@ rm -f test.qcow2
 
 # Make a copy of the Fedora image so we can write to it then
 # discard it.
-../fish/guestfish -- \
+guestfish -- \
   disk-create test.qcow2 qcow2 -1 \
     backingfile:../tests/guests/fedora.img backingformat:raw
 
 # Edit interactively.  We have to simulate this by setting $EDITOR.
 # The command will be: echo newline >> /tmp/file
 export EDITOR='echo newline >>'
-./virt-edit -a test.qcow2 /etc/test3
-if [ "$(../cat/virt-cat -a test.qcow2 /etc/test3)" != "a
+virt-edit -a test.qcow2 /etc/test3
+if [ "$(virt-cat -a test.qcow2 /etc/test3)" != "a
 b
 c
 d
@@ -50,8 +50,8 @@ unset EDITOR
 
 # Edit non-interactively, only if we have 'perl' binary.
 if perl --version >/dev/null 2>&1; then
-    ./virt-edit -a test.qcow2 /etc/test3 -e 's/^[a-f]/$lineno/'
-    if [ "$(../cat/virt-cat -a test.qcow2 /etc/test3)" != "1
+    virt-edit -a test.qcow2 /etc/test3 -e 's/^[a-f]/$lineno/'
+    if [ "$(virt-cat -a test.qcow2 /etc/test3)" != "1
 2
 3
 4
@@ -65,7 +65,7 @@ fi
 
 # Verify the mode of /etc/test3 is still 0600 and the UID:GID is 10:11.
 # See tests/guests/guest-aux/make-fedora-img.pl and RHBZ#788641.
-if [ "$(../fish/guestfish -i -a test.qcow2 --ro lstat /etc/test3 | grep -E
'^(mode|uid|gid):' | sort)" != "gid: 11
+if [ "$(guestfish -i -a test.qcow2 --ro lstat /etc/test3 | grep -E
'^(mode|uid|gid):' | sort)" != "gid: 11
 mode: 33152
 uid: 10" ]; then
     echo "$0: error: editing /etc/test3 did not preserve permissions or
ownership"
diff --git a/fish/test-a.sh b/fish/test-a.sh
index 44188ed..0fcc7d1 100755
--- a/fish/test-a.sh
+++ b/fish/test-a.sh
@@ -23,28 +23,28 @@ set -e
 rm -f test-a.out
 rm -f test-a.img
 
-$VG ./guestfish sparse test-a.img 100M
+$VG guestfish sparse test-a.img 100M
 
-$VG ./guestfish -x -a test-a.img </dev/null >test-a.out 2>&1
+$VG guestfish -x -a test-a.img </dev/null >test-a.out 2>&1
 
 ! grep -sq 'add_drive.*format' test-a.out
 
 rm test-a.img
-$VG ./guestfish disk-create test-a.img qcow2 100M
+$VG guestfish disk-create test-a.img qcow2 100M
 
-$VG ./guestfish -x --format=qcow2 -a test-a.img </dev/null >test-a.out
2>&1
+$VG guestfish -x --format=qcow2 -a test-a.img </dev/null >test-a.out
2>&1
 
 grep -sq 'add_drive.*format:qcow2' test-a.out
 
-$VG ./guestfish -x --ro --format=qcow2 -a test-a.img </dev/null
>test-a.out 2>&1
+$VG guestfish -x --ro --format=qcow2 -a test-a.img </dev/null >test-a.out
2>&1
 
 grep -sq 'add_drive.*readonly:true.*format:qcow2' test-a.out
 
-$VG ./guestfish -x --format -a test-a.img </dev/null >test-a.out
2>&1
+$VG guestfish -x --format -a test-a.img </dev/null >test-a.out
2>&1
 
 ! grep -sq 'add_drive.*format' test-a.out
 
-$VG ./guestfish -x -a test-a.img --format=raw -a /dev/null </dev/null
>test-a.out 2>&1
+$VG guestfish -x -a test-a.img --format=raw -a /dev/null </dev/null
>test-a.out 2>&1
 
 ! grep -sq 'add_drive.*test-a.img.*format' test-a.out
 
diff --git a/fish/test-add-domain.sh b/fish/test-add-domain.sh
index a6b0e10..608d2de 100755
--- a/fish/test-add-domain.sh
+++ b/fish/test-add-domain.sh
@@ -25,10 +25,10 @@ rm -f test-add-domain.xml test-add-domain.out
 
 cwd="$(pwd)"
 
-$VG ./guestfish sparse test-add-domain-1.img 1M
-$VG ./guestfish sparse test-add-domain-2.img 1M
-$VG ./guestfish disk-create test-add-domain-3.img qcow2 1M
-$VG ./guestfish sparse test-add-domain-4.img 1M
+$VG guestfish sparse test-add-domain-1.img 1M
+$VG guestfish sparse test-add-domain-2.img 1M
+$VG guestfish disk-create test-add-domain-3.img qcow2 1M
+$VG guestfish sparse test-add-domain-4.img 1M
 
 # Libvirt test XML, see libvirt.git/examples/xml/test/testnode.xml
 cat > test-add-domain.xml <<EOF
@@ -66,7 +66,7 @@ cat > test-add-domain.xml <<EOF
 </node>
 EOF
 
-$VG ./guestfish >test-add-domain.out <<EOF
+$VG guestfish >test-add-domain.out <<EOF
   domain guest libvirturi:test://$cwd/test-add-domain.xml readonly:true
   debug-drives
 EOF
@@ -76,7 +76,7 @@ grep -sq "test-add-domain-2.img readonly format=raw"
test-add-domain.out
 grep -sq "test-add-domain-3.img readonly format=qcow2"
test-add-domain.out
 
 # Test readonlydisk = "ignore".
-$VG ./guestfish >test-add-domain.out <<EOF
+$VG guestfish >test-add-domain.out <<EOF
   -domain guest libvirturi:test://$cwd/test-add-domain.xml readonly:true
readonlydisk:ignore
   debug-drives
 EOF
@@ -88,7 +88,7 @@ grep -sq "test-add-domain-3.img" test-add-domain.out
 # Test atomicity.
 rm test-add-domain-3.img
 
-$VG ./guestfish >test-add-domain.out <<EOF
+$VG guestfish >test-add-domain.out <<EOF
   -domain guest libvirturi:test://$cwd/test-add-domain.xml readonly:true
   debug-drives
 EOF
diff --git a/fish/test-add-uri.sh b/fish/test-add-uri.sh
index 1a5b067..2f83754 100755
--- a/fish/test-add-uri.sh
+++ b/fish/test-add-uri.sh
@@ -24,7 +24,7 @@ set -x
 rm -f test-add-uri.out
 rm -f test-add-uri.img
 
-$VG ./guestfish sparse test-add-uri.img 10M
+$VG guestfish sparse test-add-uri.img 10M
 
 function fail ()
 {
@@ -34,51 +34,51 @@ function fail ()
 }
 
 # file:// URI should be handled exactly like a regular file.
-$VG ./guestfish -x -a file://$(pwd)/test-add-uri.img </dev/null
>test-add-uri.out 2>&1
+$VG guestfish -x -a file://$(pwd)/test-add-uri.img </dev/null
>test-add-uri.out 2>&1
 grep -sq 'add_drive ".*/test-add-uri.img"' test-add-uri.out
|| fail
 
 # curl
-$VG ./guestfish -x -a ftp://user@example.com/disk.img </dev/null
>test-add-uri.out 2>&1
+$VG guestfish -x -a ftp://user@example.com/disk.img </dev/null
>test-add-uri.out 2>&1
 grep -sq 'add_drive "/disk.img" "protocol:ftp"
"server:tcp:example.com" "username:user"'
test-add-uri.out || fail
 
 # gluster
-$VG ./guestfish -x -a gluster://example.com/disk </dev/null
>test-add-uri.out 2>&1
+$VG guestfish -x -a gluster://example.com/disk </dev/null
>test-add-uri.out 2>&1
 grep -sq 'add_drive "disk" "protocol:gluster"
"server:tcp:example.com"' test-add-uri.out || fail
 
 # NBD
-$VG ./guestfish -x -a nbd://example.com </dev/null >test-add-uri.out
2>&1
+$VG guestfish -x -a nbd://example.com </dev/null >test-add-uri.out
2>&1
 grep -sq 'add_drive "" "protocol:nbd"
"server:tcp:example.com"' test-add-uri.out || fail
 
-$VG ./guestfish -x -a nbd://example.com:3000 </dev/null >test-add-uri.out
2>&1
+$VG guestfish -x -a nbd://example.com:3000 </dev/null >test-add-uri.out
2>&1
 grep -sq 'add_drive "" "protocol:nbd"
"server:tcp:example.com:3000"' test-add-uri.out || fail
 
-$VG ./guestfish -x -a 'nbd://?socket=/sk' </dev/null
>test-add-uri.out 2>&1
+$VG guestfish -x -a 'nbd://?socket=/sk' </dev/null
>test-add-uri.out 2>&1
 grep -sq 'add_drive "" "protocol:nbd"
"server:unix:/sk"' test-add-uri.out || fail
 
-$VG ./guestfish -x -a 'nbd:///export?socket=/sk' </dev/null
>test-add-uri.out 2>&1
+$VG guestfish -x -a 'nbd:///export?socket=/sk' </dev/null
>test-add-uri.out 2>&1
 grep -sq 'add_drive "/export" "protocol:nbd"
"server:unix:/sk"' test-add-uri.out || fail
 
 # rbd
-$VG ./guestfish -x -a rbd://example.com:6789/pool/disk </dev/null
>test-add-uri.out 2>&1
+$VG guestfish -x -a rbd://example.com:6789/pool/disk </dev/null
>test-add-uri.out 2>&1
 grep -sq 'add_drive "pool/disk" "protocol:rbd"
"server:tcp:example.com:6789"' test-add-uri.out || fail
-$VG ./guestfish -x -a rbd:///pool/disk </dev/null >test-add-uri.out
2>&1
+$VG guestfish -x -a rbd:///pool/disk </dev/null >test-add-uri.out
2>&1
 grep -sq 'add_drive "pool/disk" "protocol:rbd"'
test-add-uri.out || fail
 
 # sheepdog
-$VG ./guestfish -x -a sheepdog:///volume/image </dev/null
>test-add-uri.out 2>&1
+$VG guestfish -x -a sheepdog:///volume/image </dev/null >test-add-uri.out
2>&1
 grep -sq 'add_drive "volume/image"
"protocol:sheepdog"' test-add-uri.out || fail
 
-$VG ./guestfish -x -a sheepdog://example.com:3000/volume/image </dev/null
>test-add-uri.out 2>&1
+$VG guestfish -x -a sheepdog://example.com:3000/volume/image </dev/null
>test-add-uri.out 2>&1
 grep -sq 'add_drive "volume/image" "protocol:sheepdog"
"server:tcp:example.com:3000"' test-add-uri.out || fail
 
 # ssh
-$VG ./guestfish -x -a ssh://example.com/disk.img </dev/null
>test-add-uri.out 2>&1
+$VG guestfish -x -a ssh://example.com/disk.img </dev/null
>test-add-uri.out 2>&1
 grep -sq 'add_drive "/disk.img" "protocol:ssh"
"server:tcp:example.com"' test-add-uri.out || fail
 
-$VG ./guestfish -x -a ssh://user@example.com/disk.img </dev/null
>test-add-uri.out 2>&1
+$VG guestfish -x -a ssh://user@example.com/disk.img </dev/null
>test-add-uri.out 2>&1
 grep -sq 'add_drive "/disk.img" "protocol:ssh"
"server:tcp:example.com" "username:user"'
test-add-uri.out || fail
 
-$VG ./guestfish -x -a ssh://user@example.com:2000/disk.img </dev/null
>test-add-uri.out 2>&1
+$VG guestfish -x -a ssh://user@example.com:2000/disk.img </dev/null
>test-add-uri.out 2>&1
 grep -sq 'add_drive "/disk.img" "protocol:ssh"
"server:tcp:example.com:2000" "username:user"'
test-add-uri.out || fail
 
 rm test-add-uri.out
diff --git a/fish/test-alloc.sh b/fish/test-alloc.sh
index 3f46f8b..98f8f4e 100755
--- a/fish/test-alloc.sh
+++ b/fish/test-alloc.sh
@@ -22,7 +22,7 @@ set -e
 
 rm -f test-alloc.img
 
-$VG ./guestfish alloc test-alloc.img 200000
+$VG guestfish alloc test-alloc.img 200000
 if [ "$(stat -c '%s' test-alloc.img)" -ne 200000 ]; then
     echo "$0: alloc command failed to create file of the correct
size"
     exit 1
@@ -33,7 +33,7 @@ if [ "$(stat -c '%b' test-alloc.img)" -eq 0
]; then
     exit 1
 fi
 
-$VG ./guestfish sparse test-alloc.img 100000
+$VG guestfish sparse test-alloc.img 100000
 if [ "$(stat -c '%s' test-alloc.img)" -ne 100000 ]; then
     echo "$0: sparse command failed to create file of the correct
size"
     exit 1
diff --git a/fish/test-copy.sh b/fish/test-copy.sh
index ecf5a4f..f72de9b 100755
--- a/fish/test-copy.sh
+++ b/fish/test-copy.sh
@@ -36,7 +36,7 @@ cp $srcdir/../tests/data/known* test-copy-original
 cp -P ../tests/data/abssymlink* test-copy-original
 
 output=$(
-$VG ./guestfish -N test-copy.img=fs -m /dev/sda1 <<EOF
+$VG guestfish -N test-copy.img=fs -m /dev/sda1 <<EOF
 mkdir /data
 # This creates a directory /data/data/
 copy-in test-copy-original /data
@@ -63,7 +63,7 @@ fi
 
 mkdir test-copy-copy
 
-$VG ./guestfish --ro -a test-copy.img -m /dev/sda1 <<EOF
+$VG guestfish --ro -a test-copy.img -m /dev/sda1 <<EOF
 copy-out /data/test-copy-original test-copy-copy
 EOF
 
diff --git a/fish/test-d.sh b/fish/test-d.sh
index 1e16bdc..4c41ce0 100755
--- a/fish/test-d.sh
+++ b/fish/test-d.sh
@@ -25,10 +25,10 @@ rm -f test-d.xml test-d.out
 
 cwd="$(pwd)"
 
-$VG ./guestfish sparse test-d-1.img 1M
-$VG ./guestfish sparse test-d-2.img 1M
-$VG ./guestfish disk-create test-d-3.img qcow2 1M
-$VG ./guestfish sparse test-d-4.img 1M
+$VG guestfish sparse test-d-1.img 1M
+$VG guestfish sparse test-d-2.img 1M
+$VG guestfish disk-create test-d-3.img qcow2 1M
+$VG guestfish sparse test-d-4.img 1M
 
 # Libvirt test XML, see libvirt.git/examples/xml/test/testnode.xml
 cat > test-d.xml <<EOF
@@ -66,7 +66,7 @@ cat > test-d.xml <<EOF
 </node>
 EOF
 
-$VG ./guestfish -c "test://$cwd/test-d.xml" --ro -d guest \
+$VG guestfish -c "test://$cwd/test-d.xml" --ro -d guest \
   debug-drives </dev/null >test-d.out
 grep -sq "test-d-1.img readonly" test-d.out
 ! grep -sq "test-d-1.img.*format" test-d.out
diff --git a/fish/test-edit.sh b/fish/test-edit.sh
index 9d7ab9d..9242617 100755
--- a/fish/test-edit.sh
+++ b/fish/test-edit.sh
@@ -34,7 +34,7 @@ rm -f test-edit.img
 export EDITOR="echo second line of text >>"
 
 output=$(
-$VG ./guestfish -N test-edit.img=fs -m /dev/sda1 <<EOF
+$VG guestfish -N test-edit.img=fs -m /dev/sda1 <<EOF
 write /file.txt "this is a test\n"
 chmod 0600 /file.txt
 chown 10 11 /file.txt
diff --git a/fish/test-escapes.sh b/fish/test-escapes.sh
index 9a9fe7c..18c6e03 100755
--- a/fish/test-escapes.sh
+++ b/fish/test-escapes.sh
@@ -22,7 +22,7 @@ set -e
 
 rm -f test.output test.error test.error.old
 
-$VG ./guestfish <<'EOF' 2>test.error | od -b > test.output
+$VG guestfish <<'EOF' 2>test.error | od -b > test.output
 echo ""
 echo " "
 echo "  "
diff --git a/fish/test-events.sh b/fish/test-events.sh
index 18e503f..3f65164 100755
--- a/fish/test-events.sh
+++ b/fish/test-events.sh
@@ -22,7 +22,7 @@ set -e
 
 rm -f test.out
 
-$VG ./guestfish -a /dev/null <<'EOF' | grep -v get_verbose | grep
-v get_trace | grep -v 'library .*0x' | grep -v 'library
command' | grep -v 'get_path' > test.out
+$VG guestfish -a /dev/null <<'EOF' | grep -v get_verbose | grep
-v get_trace | grep -v 'library .*0x' | grep -v 'library
command' | grep -v 'get_path' > test.out
 trace true
 
 event ev1 * "echo $EVENT $@"
diff --git a/fish/test-file-attrs.sh b/fish/test-file-attrs.sh
index 78bd817..55d602c 100755
--- a/fish/test-file-attrs.sh
+++ b/fish/test-file-attrs.sh
@@ -23,7 +23,7 @@ export LANG=C
 
 rm -f test.out
 
-$VG ./guestfish > test.out <<EOF
+$VG guestfish > test.out <<EOF
 scratch 50MB
 run
 part-disk /dev/sda mbr
diff --git a/fish/test-find0.sh b/fish/test-find0.sh
index 9ca6a31..07daab3 100755
--- a/fish/test-find0.sh
+++ b/fish/test-find0.sh
@@ -22,7 +22,7 @@ set -e
 
 rm -f test.out
 
-$VG ./guestfish <<'EOF'
+$VG guestfish <<'EOF'
 add-ro ../tests/data/test.iso
 run
 mount-ro /dev/sda /
diff --git a/fish/test-glob.sh b/fish/test-glob.sh
index 0f41893..c520319 100755
--- a/fish/test-glob.sh
+++ b/fish/test-glob.sh
@@ -22,7 +22,7 @@ set -e
 
 rm -f test-glob.img test-glob.out
 
-$VG ./guestfish -N test-glob.img=disk:1G > test-glob.out <<EOF
+$VG guestfish -N test-glob.img=disk:1G > test-glob.out <<EOF
 
 pvcreate /dev/sda
 # Because glob doesn't do device name translation, we cannot test
diff --git a/fish/test-inspect.sh b/fish/test-inspect.sh
index 8f8abe6..126740d 100755
--- a/fish/test-inspect.sh
+++ b/fish/test-inspect.sh
@@ -18,4 +18,4 @@
 
 set -e
 
-$VG ./guestfish -a ../tests/guests/fedora.img -i exit
+$VG guestfish -a ../tests/guests/fedora.img -i exit
diff --git a/fish/test-invalid-params.sh b/fish/test-invalid-params.sh
index 60da094..7d02c65 100755
--- a/fish/test-invalid-params.sh
+++ b/fish/test-invalid-params.sh
@@ -23,7 +23,7 @@ set -e
 
 # Memory size
 output=$(
-$VG ./guestfish <<EOF
+$VG guestfish <<EOF
 set-memsize 400
 -set-memsize 0
 -set-memsize 100
@@ -42,7 +42,7 @@ fi
 
 # smp
 output=$(
-$VG ./guestfish <<EOF
+$VG guestfish <<EOF
 set-smp 2
 -set-smp 0
 -set-smp 300
@@ -58,7 +58,7 @@ fi
 
 # Backend
 output=$(
-$VG ./guestfish <<EOF
+$VG guestfish <<EOF
 set-backend direct
 -set-backend backend-which-does-not-exist
 get-backend
diff --git a/fish/test-mount-local.sh b/fish/test-mount-local.sh
index de308d3..845f707 100755
--- a/fish/test-mount-local.sh
+++ b/fish/test-mount-local.sh
@@ -61,7 +61,7 @@ rm -rf test-mount-local-mp
 
 mkdir test-mount-local-mp
 
-if ! ./guestfish -N test-mount-local.img=fs -m /dev/sda1
2>test-mount-local.errors <<EOF; then
+if ! guestfish -N test-mount-local.img=fs -m /dev/sda1
2>test-mount-local.errors <<EOF; then
 mount-local test-mount-local-mp
 ! $0 --run-test &
 mount-local-run
diff --git a/fish/test-prep.sh b/fish/test-prep.sh
index e52fca8..e2b972a 100755
--- a/fish/test-prep.sh
+++ b/fish/test-prep.sh
@@ -22,7 +22,7 @@ rm -f prep*.img
 
 # It would be nice if we could keep this automatically in sync
 # with the prepared disk types.  XXX
-$VG ./guestfish \
+$VG guestfish \
     -N prep1.img=disk \
     -N prep2.img=part \
     -N prep3.img=fs \
diff --git a/fish/test-read-file.sh b/fish/test-read-file.sh
index f1e28f1..8f35efb 100755
--- a/fish/test-read-file.sh
+++ b/fish/test-read-file.sh
@@ -22,7 +22,7 @@ set -e
 
 rm -f test.out
 
-$VG ./guestfish <<'EOF' > test.out
+$VG guestfish <<'EOF' > test.out
 add-ro ../tests/data/test.iso
 run
 mount-ro /dev/sda /
diff --git a/fish/test-remote-events.sh b/fish/test-remote-events.sh
index a3a13b1..c05f072 100755
--- a/fish/test-remote-events.sh
+++ b/fish/test-remote-events.sh
@@ -20,20 +20,20 @@
 
 set -e
 
-eval "$(./guestfish --listen)"
+eval "$(guestfish --listen)"
 
-$VG ./guestfish --remote event close_event close "echo closed"
+$VG guestfish --remote event close_event close "echo closed"
 
-output="$($VG ./guestfish --remote list-events)"
+output="$($VG guestfish --remote list-events)"
 if [ "$output" != '"close_event" (0): close: echo
closed' ]; then
     echo "$0: list-events failed:"
     echo "$output"
-    ./guestfish --remote exit
+    guestfish --remote exit
     exit 1
 fi
 
 # Test close event (RHBZ#802389).
-output="$($VG ./guestfish --remote quit)"
+output="$($VG guestfish --remote quit)"
 
 if [ "$output" != "closed" ]; then
     echo "$0: close event failed:"
diff --git a/fish/test-remote.sh b/fish/test-remote.sh
index 442d927..28df682 100755
--- a/fish/test-remote.sh
+++ b/fish/test-remote.sh
@@ -22,24 +22,24 @@ set -e
 
 rm -f test-remote.img
 
-eval `./guestfish --listen`
+eval `guestfish --listen`
 
-$VG ./guestfish --remote alloc test-remote.img 10M
-$VG ./guestfish --remote run
-$VG ./guestfish --remote part-disk /dev/sda mbr
-$VG ./guestfish --remote mkfs ext2 /dev/sda1
-$VG ./guestfish --remote mount /dev/sda1 /
+$VG guestfish --remote alloc test-remote.img 10M
+$VG guestfish --remote run
+$VG guestfish --remote part-disk /dev/sda mbr
+$VG guestfish --remote mkfs ext2 /dev/sda1
+$VG guestfish --remote mount /dev/sda1 /
 
 # Failure of the above commands will cause the guestfish listener to exit.
 # Incorrect return from echo_daemon will not, so need to ensure the listener
 # exits in any case, while still reporting an error.
 error=0
-echo=$($VG ./guestfish --remote echo_daemon "This is a test")
+echo=$($VG guestfish --remote echo_daemon "This is a test")
 if [ "$echo" != "This is a test" ]; then
     error=1;
 fi
 
-$VG ./guestfish --remote exit
+$VG guestfish --remote exit
 
 rm test-remote.img
 
diff --git a/fish/test-reopen.sh b/fish/test-reopen.sh
index a6b5289..d8966d4 100755
--- a/fish/test-reopen.sh
+++ b/fish/test-reopen.sh
@@ -23,7 +23,7 @@ set -e
 
 rm -f test-reopen.img
 
-$VG ./guestfish <<'EOF'
+$VG guestfish <<'EOF'
 reopen
 reopen
 reopen
diff --git a/fish/test-run.sh b/fish/test-run.sh
index ec6e0d3..a66ad9c 100755
--- a/fish/test-run.sh
+++ b/fish/test-run.sh
@@ -18,4 +18,4 @@
 
 set -e
 
-$VG ./guestfish -a ../tests/guests/fedora.img run
+$VG guestfish -a ../tests/guests/fedora.img run
diff --git a/fish/test-stringlist.sh b/fish/test-stringlist.sh
index 416c092..ab23cb9 100755
--- a/fish/test-stringlist.sh
+++ b/fish/test-stringlist.sh
@@ -22,7 +22,7 @@ set -e
 
 rm -f test-stringlist.img
 
-eval `./guestfish --listen`
+eval `guestfish --listen`
 
 error=0
 
@@ -32,15 +32,15 @@ function check_echo {
 
     local echo
 
-    echo=$($VG ./guestfish --remote echo_daemon "$test")
+    echo=$($VG guestfish --remote echo_daemon "$test")
     if [ "$echo" != "$expected" ]; then
         echo "Expected \"$expected\", got
\"$echo\""
         error=1
     fi
 }
 
-$VG ./guestfish --remote alloc test-stringlist.img 10M
-$VG ./guestfish --remote run
+$VG guestfish --remote alloc test-stringlist.img 10M
+$VG guestfish --remote run
 
 check_echo "' '"            " "
 check_echo "\'"             "'"
@@ -53,7 +53,7 @@ check_echo "'foo' 'bar'"   
"foo bar"
 check_echo "'foo' "         "foo"
 check_echo " 'foo'"         "foo"
 
-$VG ./guestfish --remote exit
+$VG guestfish --remote exit
 
 rm test-stringlist.img
 
diff --git a/fish/test-tilde.sh b/fish/test-tilde.sh
index a2bf1fa..ca4af73 100755
--- a/fish/test-tilde.sh
+++ b/fish/test-tilde.sh
@@ -27,12 +27,12 @@ set -e
 HOME=$(pwd)
 export HOME
 
-if [ `echo 'echo ~' | $VG ./guestfish` != "$HOME" ]; then
+if [ `echo 'echo ~' | $VG guestfish` != "$HOME" ]; then
     echo "$0: failed: did not expand ~ correctly"
     exit 1
 fi
 
-if [ `echo 'echo ~/foo' | $VG ./guestfish` != "$HOME/foo" ];
then
+if [ `echo 'echo ~/foo' | $VG guestfish` != "$HOME/foo" ];
then
     echo "$0: failed: did not expand ~/foo correctly"
     exit 1
 fi
@@ -41,12 +41,12 @@ fi
 # should have a home directory.
 root="$(echo ~root)"
 
-if [ `echo 'echo ~root' | $VG ./guestfish` != "$root" ]; then
+if [ `echo 'echo ~root' | $VG guestfish` != "$root" ]; then
     echo "$0: failed: did not expand ~root correctly"
     exit 1
 fi
 
-if [ `echo 'echo ~root/foo' | $VG ./guestfish` != "$root/foo"
]; then
+if [ `echo 'echo ~root/foo' | $VG guestfish` != "$root/foo"
]; then
     echo "$0: failed: did not expand ~root/foo correctly"
     exit 1
 fi
@@ -55,12 +55,12 @@ fi
 unset HOME
 home="$(echo ~)"
 
-if [ `echo 'echo ~' | $VG ./guestfish` != "$home" ]; then
+if [ `echo 'echo ~' | $VG guestfish` != "$home" ]; then
     echo "$0: failed: did not expand ~ correctly when \$HOME unset"
     exit 1
 fi
 
-if [ `echo 'echo ~/foo' | $VG ./guestfish` != "$home/foo" ];
then
+if [ `echo 'echo ~/foo' | $VG guestfish` != "$home/foo" ];
then
     echo "$0: failed: did not expand ~/foo correctly when \$HOME
unset"
     exit 1
 fi
diff --git a/fish/test-upload-to-dir.sh b/fish/test-upload-to-dir.sh
index 6e3f009..0bacd75 100755
--- a/fish/test-upload-to-dir.sh
+++ b/fish/test-upload-to-dir.sh
@@ -24,7 +24,7 @@ set -e
 
 rm -f test-upload-to-dir.img test-upload-to-dir.out
 
-if $VG ./guestfish -N test-upload-to-dir.img=fs -m /dev/sda1 upload
../tests/data/test.iso / 2>test-upload-to-dir.out
+if $VG guestfish -N test-upload-to-dir.img=fs -m /dev/sda1 upload
../tests/data/test.iso / 2>test-upload-to-dir.out
 then
   echo "$0: expecting guestfish to return an error"
   exit 1
diff --git a/format/test-virt-format.sh b/format/test-virt-format.sh
index 71cc802..2383c71 100755
--- a/format/test-virt-format.sh
+++ b/format/test-virt-format.sh
@@ -27,11 +27,11 @@ fi
 
 rm -f test-virt-format.img
 
-$VG ../fish/guestfish -N test-virt-format.img=bootrootlv exit
+$VG guestfish -N test-virt-format.img=bootrootlv exit
 
-$VG ./virt-format --filesystem=ext3 -a test-virt-format.img
+$VG virt-format --filesystem=ext3 -a test-virt-format.img
 
-if [ "$($VG ../cat/virt-filesystems -a test-virt-format.img)" !=
"/dev/sda1" ]; then
+if [ "$($VG virt-filesystems -a test-virt-format.img)" !=
"/dev/sda1" ]; then
     echo "$0: unexpected output after using virt-format"
     exit 1
 fi
diff --git a/fuse/test-fuse-umount-race.sh b/fuse/test-fuse-umount-race.sh
index 008e980..e789122 100755
--- a/fuse/test-fuse-umount-race.sh
+++ b/fuse/test-fuse-umount-race.sh
@@ -38,7 +38,7 @@ if [ ! -f ../tests/guests/fedora.img ]; then
     exit 77
 fi
 
-if [ "$(../fish/guestfish get-backend)" = "uml" ]; then
+if [ "$(guestfish get-backend)" = "uml" ]; then
     echo "$0: test skipped because uml backend does not support
qcow2"
     exit 77
 fi
@@ -47,7 +47,7 @@ rm -f test.qcow2 test-copy.qcow2 test.pid
 rm -rf mp
 
 # Make a copy of the Fedora image so we can write to it then discard it.
-../fish/guestfish -- \
+guestfish -- \
     disk-create test.qcow2 qcow2 -1 \
       backingfile:../tests/guests/fedora.img backingformat:raw
 
@@ -77,7 +77,7 @@ fi
 # It should now be safe to copy and read the disk image.
 cp test.qcow2 test-copy.qcow2
 
-if [ "$(../fish/guestfish -a test-copy.qcow2 --ro -i is-file
/test-umount)" != "true" ]; then
+if [ "$(guestfish -a test-copy.qcow2 --ro -i is-file /test-umount)"
!= "true" ]; then
     echo "$0: test failed"
     exit 1
 fi
diff --git a/fuse/test-fuse.sh b/fuse/test-fuse.sh
index f46c29c..13d1bd3 100755
--- a/fuse/test-fuse.sh
+++ b/fuse/test-fuse.sh
@@ -46,14 +46,11 @@ nr_stages=$(grep "^stage " $0 | wc -l)
 # and move to that directory for the initial phase of the script.
 top_builddir=$(cd "$top_builddir" > /dev/null; pwd)
 
-# Paths to the other programs and files.  NB: Must be absolute paths.
-guestfish="$top_builddir/fish/guestfish"
-guestmount="$top_builddir/fuse/guestmount"
-guestunmount="$top_builddir/fuse/guestunmount"
+# Paths to the other files.  NB: Must be absolute paths.
 image="$top_builddir/fuse/test-fuse.img"
 mp="$top_builddir/fuse/test-fuse-mp"
 
-if [ ! -x "$guestfish" -o ! -x "$guestmount" -o ! -x
"$guestunmount" ]
+if ! guestfish --help >/dev/null 2>&1 || ! guestmount --help
>/dev/null 2>&1 || ! guestunmount --help >/dev/null 2>&1
 then
     echo "$0: error: guestfish, guestmount or guestunmount are not
available"
     exit 1
@@ -82,7 +79,7 @@ function cleanup ()
     if [ -x /sbin/fuser ]; then /sbin/fuser "$mp"; fi
 
     if [ -n "$mounted" ]; then
-        $guestunmount "$mp"
+        guestunmount "$mp"
     fi
 
     rm -f "$image"
@@ -99,7 +96,7 @@ function stage ()
 }
 
 stage Create filesystem with some initial content
-$guestfish <<EOF
+guestfish <<EOF
   sparse "$image" 10M
   run
   part-disk /dev/sda mbr
@@ -116,7 +113,7 @@ $guestfish <<EOF
 EOF
 
 stage Mounting the filesystem
-$guestmount \
+guestmount \
     -a "$image" -m /dev/sda1:/:acl,user_xattr \
     -o uid="$(id -u)" -o gid="$(id -g)" "$mp"
 # To debug guestmount, add this to the end of the preceding command:
diff --git a/inspector/test-virt-inspector.sh b/inspector/test-virt-inspector.sh
index b400e20..6fab253 100755
--- a/inspector/test-virt-inspector.sh
+++ b/inspector/test-virt-inspector.sh
@@ -33,7 +33,7 @@ for f in ../tests/guests/{debian,fedora,ubuntu,windows}.img;
do
     # Ignore zero-sized windows.img if ntfs-3g is not installed.
     if [ -s "$f" ]; then
         b=$(basename "$f" .xml)
-	$VG ./virt-inspector -a "$f" > "actual-$b.xml"
+	$VG virt-inspector -a "$f" > "actual-$b.xml"
         # This 'diff' command will fail (because of -e option) if there
         # are any differences.
         diff -ur $diff_ignore "expected-$b.xml"
"actual-$b.xml"
@@ -42,6 +42,6 @@ done
 
 # We could also test this image, but mdadm is problematic for
 # many users.
-# $VG ./virt-inspector \
+# $VG virt-inspector \
 #   -a ../tests/guests/fedora-md1.img \
 #   -a ../tests/guests/fedora-md2.img
diff --git a/make-fs/test-virt-make-fs.sh b/make-fs/test-virt-make-fs.sh
index a05ef9f..2ed3ce9 100755
--- a/make-fs/test-virt-make-fs.sh
+++ b/make-fs/test-virt-make-fs.sh
@@ -40,7 +40,7 @@ if [ -n "$SKIP_TEST_VIRT_MAKE_FS_BTRFS" ]; then
 fi
 
 # UML backend doesn't support qcow2.
-if [ "$(../fish/guestfish get-backend)" != "uml" ]; then
+if [ "$(guestfish get-backend)" != "uml" ]; then
     qcow2_supported=yes
 fi
 
@@ -94,6 +94,6 @@ dd if=/dev/zero of=test.file bs=1024 count=$tarsize
 tar -c -f test.tar test.file
 rm test.file
 
-$VG ./virt-make-fs $params -- test.tar output.img
+$VG virt-make-fs $params -- test.tar output.img
 
 rm test.tar output.img
diff --git a/p2v/test-virt-p2v.sh b/p2v/test-virt-p2v.sh
index 2f66c7c..f4d28d1 100755
--- a/p2v/test-virt-p2v.sh
+++ b/p2v/test-virt-p2v.sh
@@ -27,7 +27,7 @@ if [ -n "$SKIP_TEST_VIRT_P2V_SH" ]; then
     exit 77
 fi
 
-if [ "$(../fish/guestfish get-backend)" = "uml" ]; then
+if [ "$(guestfish get-backend)" = "uml" ]; then
     echo "$0: test skipped because UML backend does not support
network"
     exit 77
 fi
@@ -61,7 +61,7 @@ export PATH=$d:$PATH
 # The Linux kernel command line.
 cmdline="p2v.server=localhost p2v.name=windows p2v.debug p2v.disks=$f
p2v.o=local p2v.os=$d p2v.network=em1:wired,other"
 
-./virt-p2v --cmdline="$cmdline"
+virt-p2v --cmdline="$cmdline"
 
 # Test the libvirt XML metadata and a disk was created.
 test -f $d/windows.xml
diff --git a/rescue/test-virt-rescue-suggest.sh
b/rescue/test-virt-rescue-suggest.sh
index c3f5d91..f79e4f8 100755
--- a/rescue/test-virt-rescue-suggest.sh
+++ b/rescue/test-virt-rescue-suggest.sh
@@ -28,7 +28,7 @@ fi
 
 rm -f virt-rescue-suggest.out
 
-$VG ./virt-rescue --suggest "$guest" |
+$VG virt-rescue --suggest "$guest" |
   grep '^mount ' |
   sed -r 's,/dev/[abce-ln-z]+d,/dev/sd,' > virt-rescue-suggest.out
 
diff --git a/resize/test-virt-resize.sh b/resize/test-virt-resize.sh
index 29c1e4c..9a1c24f 100755
--- a/resize/test-virt-resize.sh
+++ b/resize/test-virt-resize.sh
@@ -19,7 +19,7 @@
 export LANG=C
 set -e
 
-if [ "$(../fish/guestfish get-backend)" = "uml" ]; then
+if [ "$(guestfish get-backend)" = "uml" ]; then
     echo "$0: skipping test because uml backend does not support
qcow2"
     exit 77
 fi
@@ -29,13 +29,13 @@ fi
 # This exercises a number of interesting codepaths including resizing
 # LV content, handling GPT, and using qcow2 as a target.
 
-$VG ../fish/guestfish \
+$VG guestfish \
     -N test-virt-resize-1.img=bootrootlv:/dev/VG/LV:ext2:ext4:400M:32M:gpt
</dev/null
 
-$VG ../fish/guestfish \
+$VG guestfish \
     disk-create test-virt-resize-2.img qcow2 500M preallocation:metadata
 
-$VG ./virt-resize -d --debug-gc \
+$VG virt-resize -d --debug-gc \
     --expand /dev/sda2 \
     --lv-expand /dev/VG/LV \
     --format raw --output-format qcow2 \
@@ -45,7 +45,7 @@ $VG ./virt-resize -d --debug-gc \
 # image created above contains no data, we will nevertheless use
 # similar operations to ones that might be used by a real admin.
 
-../fish/guestfish -a test-virt-resize-1.img <<EOF
+guestfish -a test-virt-resize-1.img <<EOF
 run
 resize2fs-size /dev/VG/LV 190M
 lvresize /dev/VG/LV 190
@@ -53,8 +53,8 @@ pvresize-size /dev/sda2 200M
 fsck ext4 /dev/VG/LV
 EOF
 
-rm -f test-virt-resize-2.img; ../fish/guestfish sparse test-virt-resize-2.img
300M
-$VG ./virt-resize -d --debug-gc \
+rm -f test-virt-resize-2.img; guestfish sparse test-virt-resize-2.img 300M
+$VG virt-resize -d --debug-gc \
     --shrink /dev/sda2 \
     --format raw --output-format raw \
     test-virt-resize-1.img test-virt-resize-2.img
diff --git a/sparsify/test-virt-sparsify-in-place.sh
b/sparsify/test-virt-sparsify-in-place.sh
index e454e79..d085032 100755
--- a/sparsify/test-virt-sparsify-in-place.sh
+++ b/sparsify/test-virt-sparsify-in-place.sh
@@ -24,7 +24,7 @@ if [ -n "$SKIP_TEST_VIRT_SPARSIFY_IN_PLACE_SH" ];
then
     exit 77
 fi
 
-if [ "$(../fish/guestfish get-backend)" = "uml" ]; then
+if [ "$(guestfish get-backend)" = "uml" ]; then
     echo "$0: skipping test because uml backend does not support
discard"
     exit 77
 fi
@@ -34,7 +34,7 @@ rm -f test-virt-sparsify-in-place.img
 # Create a filesystem, fill it with data, then delete the data.  Then
 # prove that sparsifying it reduces the size of the final filesystem.
 
-$VG ../fish/guestfish \
+$VG guestfish \
     -N
test-virt-sparsify-in-place.img=bootrootlv:/dev/VG/LV:ext4:ext4:400M:32M:gpt
<<EOF
 mount /dev/VG/LV /
 mkdir /boot
@@ -49,7 +49,7 @@ EOF
 
 size_before=$(du -s test-virt-sparsify-in-place.img | awk '{print $1}')
 
-$VG ./virt-sparsify --debug-gc --in-place test-virt-sparsify-in-place.img || {
+$VG virt-sparsify --debug-gc --in-place test-virt-sparsify-in-place.img || {
     if [ "$?" -eq 3 ]; then
         rm test-virt-sparsify-in-place.img
         echo "$0: discard not supported in virt-sparsify"
diff --git a/sparsify/test-virt-sparsify.sh b/sparsify/test-virt-sparsify.sh
index fae5bee..0404424 100755
--- a/sparsify/test-virt-sparsify.sh
+++ b/sparsify/test-virt-sparsify.sh
@@ -19,7 +19,7 @@
 export LANG=C
 set -e
 
-if [ "$(../fish/guestfish get-backend)" = "uml" ]; then
+if [ "$(guestfish get-backend)" = "uml" ]; then
     echo "$0: skipping test because uml backend does not support
qcow2"
     exit 77
 fi
@@ -29,7 +29,7 @@ rm -f test-virt-sparsify-1.img test-virt-sparsify-2.img
 # Create a filesystem, fill it with data, then delete the data.  Then
 # prove that sparsifying it reduces the size of the final filesystem.
 
-$VG ../fish/guestfish \
+$VG guestfish \
     -N test-virt-sparsify-1.img=bootrootlv:/dev/VG/LV:ext2:ext4:400M:32M:gpt
<<EOF
 mount /dev/VG/LV /
 mkdir /boot
@@ -42,7 +42,7 @@ rm /boot/big
 umount-all
 EOF
 
-$VG ./virt-sparsify --debug-gc test-virt-sparsify-1.img --convert qcow2
test-virt-sparsify-2.img
+$VG virt-sparsify --debug-gc test-virt-sparsify-1.img --convert qcow2
test-virt-sparsify-2.img
 
 size_before=$(du -s test-virt-sparsify-1.img | awk '{print $1}')
 size_after=$(du -s test-virt-sparsify-2.img | awk '{print $1}')
diff --git a/sysprep/test-virt-sysprep-passwords.sh
b/sysprep/test-virt-sysprep-passwords.sh
index d56758a..b5189c8 100755
--- a/sysprep/test-virt-sysprep-passwords.sh
+++ b/sysprep/test-virt-sysprep-passwords.sh
@@ -35,11 +35,11 @@ fi
 # so we fake that now.
 
 rm -f passwords.qcow2 password
-../fish/guestfish -- \
+guestfish -- \
     disk-create passwords.qcow2 qcow2 -1 \
       backingfile:../tests/guests/fedora.img backingformat:raw
 
-../fish/guestfish -a passwords.qcow2 -i <<'EOF'
+guestfish -a passwords.qcow2 -i <<'EOF'
 write-append /etc/shadow "test01::15677:0:99999:7:::\n"
 write-append /etc/shadow "test02::15677:0:99999:7:::\n"
 write-append /etc/shadow "test03::15677:0:99999:7:::\n"
@@ -57,7 +57,7 @@ echo 123456 > password
 
 # Run virt-sysprep password operation.
 
-./virt-sysprep \
+virt-sysprep \
     -a passwords.qcow2 \
     --enable customize \
     --password test01:password:123456 \
diff --git a/sysprep/test-virt-sysprep-script.sh
b/sysprep/test-virt-sysprep-script.sh
index 8193af0..10ba1d1 100755
--- a/sysprep/test-virt-sysprep-script.sh
+++ b/sysprep/test-virt-sysprep-script.sh
@@ -32,7 +32,7 @@ fi
 
 # Check that multiple scripts can run.
 rm -f stamp-script1.sh stamp-script2.sh stamp-script4.sh
-if ! ./virt-sysprep -q -n -a ../tests/guests/fedora.img --enable script \
+if ! virt-sysprep -q -n -a ../tests/guests/fedora.img --enable script \
         --script $abs_srcdir/script1.sh --script $abs_srcdir/script2.sh; then
     echo "$0: virt-sysprep wasn't expected to exit with error."
     exit 1
@@ -43,19 +43,19 @@ if [ ! -f stamp-script1.sh -o ! -f stamp-script2.sh ]; then
 fi
 
 # Check that if a script fails, virt-sysprep exits with an error.
-if ./virt-sysprep -q -n -a ../tests/guests/fedora.img --enable script \
+if virt-sysprep -q -n -a ../tests/guests/fedora.img --enable script \
         --script $abs_srcdir/script3.sh; then
     echo "$0: virt-sysprep didn't exit with an error."
     exit 1
 fi
 
 # Check that virt-sysprep uses a new temporary directory every time.
-if ! ./virt-sysprep -q -n -a ../tests/guests/fedora.img --enable script \
+if ! virt-sysprep -q -n -a ../tests/guests/fedora.img --enable script \
         --script $abs_srcdir/script4.sh; then
     echo "$0: virt-sysprep (script4.sh, try #1) wasn't expected to
exit with error."
     exit 1
 fi
-if ! ./virt-sysprep -q -n -a ../tests/guests/fedora.img --enable script \
+if ! virt-sysprep -q -n -a ../tests/guests/fedora.img --enable script \
         --script $abs_srcdir/script4.sh; then
     echo "$0: virt-sysprep (script4.sh, try #2) wasn't expected to
exit with error."
     exit 1
diff --git a/sysprep/test-virt-sysprep.sh b/sysprep/test-virt-sysprep.sh
index 5d1b714..7ec96d0 100755
--- a/sysprep/test-virt-sysprep.sh
+++ b/sysprep/test-virt-sysprep.sh
@@ -21,7 +21,7 @@ set -e
 
 # Get a comma-separated list of the enabled-by-default operations.
 operations=$(
-  ./virt-sysprep --list-operations |
+  virt-sysprep --list-operations |
     fgrep '*' |
     awk '{printf ("%s,",$1)}' |
     sed 's/,$//'
@@ -36,13 +36,13 @@ for f in ../tests/guests/{debian,fedora,ubuntu,windows}.img;
do
     # Ignore zero-sized windows.img if ntfs-3g is not installed.
     if [ -s "$f" ]; then
 	echo "Running virt-sysprep on $f ..."
-	$VG ./virt-sysprep -q -n --enable "$operations" -a $f
+	$VG virt-sysprep -q -n --enable "$operations" -a $f
 	echo
     fi
 done
 
 # We could also test this image, but mdadm is problematic for
 # many users.
-# $VG ./virt-sysprep -q -n \
+# $VG virt-sysprep -q -n \
 #   -a ../tests/guests/fedora-md1.img \
 #   -a ../tests/guests/fedora-md2.img
diff --git a/tests/9p/test-9p.sh b/tests/9p/test-9p.sh
index 6206609..9e396a4 100755
--- a/tests/9p/test-9p.sh
+++ b/tests/9p/test-9p.sh
@@ -26,7 +26,7 @@ if [ -n "$SKIP_TEST_9P_SH" ]; then
     exit 77
 fi
 
-backend="$(../../fish/guestfish get-backend)"
+backend="$(guestfish get-backend)"
 if [[ "$backend" != "direct" ]]; then
     echo "$0: test skipped because backend ($backend) is not
'direct'."
     exit 77
@@ -45,7 +45,7 @@ fi
 
 rm -f test-9p.img test-9p.out
 
-../../fish/guestfish <<EOF
+guestfish <<EOF
 # This dummy disk is not actually used, but libguestfs requires one.
 sparse test-9p.img 1M
 
diff --git a/tests/btrfs/test-btrfs-devices.sh
b/tests/btrfs/test-btrfs-devices.sh
index 7ef7008..3935c60 100755
--- a/tests/btrfs/test-btrfs-devices.sh
+++ b/tests/btrfs/test-btrfs-devices.sh
@@ -24,8 +24,6 @@
 
 set -e
 
-guestfish=../../fish/guestfish
-
 # Allow the test to be skipped since btrfs is often broken.
 if [ -n "$SKIP_TEST_BTRFS_DEVICES_SH" ]; then
     echo "$0: skipping test because environment variable is set."
@@ -33,14 +31,14 @@ if [ -n "$SKIP_TEST_BTRFS_DEVICES_SH" ]; then
 fi
 
 # If btrfs is not available, bail.
-if ! $guestfish -a /dev/null run : available btrfs; then
+if ! guestfish -a /dev/null run : available btrfs; then
     echo "$0: skipping test because btrfs is not available"
     exit 77
 fi
 
 rm -f test-btrfs-devices-{1,2,3,4}.img
 
-$guestfish <<EOF
+guestfish <<EOF
 # Add four empty disks
 sparse test-btrfs-devices-1.img 1G
 sparse test-btrfs-devices-2.img 1G
diff --git a/tests/create/test-disk-create.sh b/tests/create/test-disk-create.sh
index 967ceba..93dc706 100755
--- a/tests/create/test-disk-create.sh
+++ b/tests/create/test-disk-create.sh
@@ -25,7 +25,7 @@ rm -f disk*.img file:*.img
 
 # XXX We should also test failure paths.
 
-../../fish/guestfish <<EOF
+guestfish <<EOF
   disk-create disk1.img  raw   256K
   disk-create disk2.img  raw   256K preallocation:sparse
   disk-create disk3.img  raw   256K preallocation:full
@@ -45,7 +45,7 @@ rm -f disk*.img file:*.img
   disk-create disk,,0.img qcow2 256K
 EOF
 
-output="$(../../fish/guestfish <<EOF
+output="$(guestfish <<EOF
   disk-format disk1.img
   disk-format disk2.img
   disk-format disk3.img
diff --git a/tests/disks/test-qemu-drive-libvirt.sh
b/tests/disks/test-qemu-drive-libvirt.sh
index 1ba014b..9930865 100755
--- a/tests/disks/test-qemu-drive-libvirt.sh
+++ b/tests/disks/test-qemu-drive-libvirt.sh
@@ -41,8 +41,7 @@ if ! ../../src/libvirt-is-version 1 1 3; then
     exit 77
 fi
 
-guestfish="\
-  ../../fish/guestfish -c
test://$abs_builddir/test-qemu-drive-libvirt.xml"
+guestfish="guestfish -c
test://$abs_builddir/test-qemu-drive-libvirt.xml"
 
 export LIBGUESTFS_BACKEND=direct
 export LIBGUESTFS_HV="${abs_srcdir}/debug-qemu.sh"
diff --git a/tests/disks/test-qemu-drive.sh b/tests/disks/test-qemu-drive.sh
index 91677bd..b530e7d 100755
--- a/tests/disks/test-qemu-drive.sh
+++ b/tests/disks/test-qemu-drive.sh
@@ -21,8 +21,6 @@ export LANG=C
 
 set -e
 
-guestfish=../../fish/guestfish
-
 export LIBGUESTFS_BACKEND=direct
 export LIBGUESTFS_HV="${abs_srcdir}/debug-qemu.sh"
 export DEBUG_QEMU_FILE="${abs_builddir}/test-qemu-drive.out"
@@ -46,7 +44,7 @@ rm -f "$DEBUG_QEMU_FILE"
 
 # Ceph (RBD).
 
-$guestfish <<EOF ||:
+guestfish <<EOF ||:
   add "abc-def/ghi-jkl" "format:raw"
"protocol:rbd" \
     "server:1.2.3.4:1234 1.2.3.5:1235 1.2.3.6:1236"
   run
@@ -55,7 +53,7 @@ check_output
 grep -sq -- '-drive
file=rbd:abc-def/ghi-jkl:mon_host=1.2.3.4\\:1234\\;1.2.3.5\\:1235\\;1.2.3.6\\:1236:auth_supported=none,'
"$DEBUG_QEMU_FILE" || fail
 rm "$DEBUG_QEMU_FILE"
 
-$guestfish <<EOF ||:
+guestfish <<EOF ||:
   add "abc-def/ghi-jkl" "format:raw"
"protocol:rbd"
   run
 EOF
@@ -65,7 +63,7 @@ rm "$DEBUG_QEMU_FILE"
 
 # HTTP.
 
-$guestfish <<EOF ||:
+guestfish <<EOF ||:
   add "/disk.img" "format:raw" "protocol:http"
"server:www.example.com"
   run
 EOF
@@ -75,7 +73,7 @@ rm "$DEBUG_QEMU_FILE"
 
 # Gluster.
 
-$guestfish <<EOF ||:
+guestfish <<EOF ||:
   add "volname/image" "format:raw"
"protocol:gluster" "server:www.example.com:24007"
   run
 EOF
@@ -85,7 +83,7 @@ rm "$DEBUG_QEMU_FILE"
 
 # iSCSI.
 
-$guestfish <<EOF ||:
+guestfish <<EOF ||:
   add "target-iqn-name/lun" "format:raw"
"protocol:iscsi" "server:www.example.com:3000"
   run
 EOF
@@ -95,7 +93,7 @@ rm "$DEBUG_QEMU_FILE"
 
 # NBD.
 
-$guestfish <<EOF ||:
+guestfish <<EOF ||:
   add "" "format:raw" "protocol:nbd"
"server:1.2.3.4:1234"
   run
 EOF
@@ -103,7 +101,7 @@ check_output
 grep -sq -- '-drive file=nbd:1.2.3.4:1234,'
"$DEBUG_QEMU_FILE" || fail
 rm "$DEBUG_QEMU_FILE"
 
-$guestfish <<EOF ||:
+guestfish <<EOF ||:
   add "" "format:raw" "protocol:nbd"
"server:unix:/socket"
   run
 EOF
@@ -113,7 +111,7 @@ rm "$DEBUG_QEMU_FILE"
 
 # Sheepdog.
 
-$guestfish <<EOF ||:
+guestfish <<EOF ||:
   add "volume" "format:raw" "protocol:sheepdog"
   run
 EOF
@@ -123,7 +121,7 @@ rm "$DEBUG_QEMU_FILE"
 
 # SSH.
 
-$guestfish <<EOF ||:
+guestfish <<EOF ||:
   add "/disk.img" "format:raw" "protocol:ssh"
"server:example.com" \
     "username:rich"
   run
diff --git a/tests/guests/guest-aux/make-debian-img.sh
b/tests/guests/guest-aux/make-debian-img.sh
index c3db56e..95228ab 100755
--- a/tests/guests/guest-aux/make-debian-img.sh
+++ b/tests/guests/guest-aux/make-debian-img.sh
@@ -31,7 +31,7 @@ LABEL=BOOT /boot ext2 default 0 0
 EOF
 
 # Create a disk image.
-../../fish/guestfish <<EOF
+guestfish <<EOF
 sparse debian.img.tmp.$$ 512M
 run
 
diff --git a/tests/guests/guest-aux/make-ubuntu-img.sh
b/tests/guests/guest-aux/make-ubuntu-img.sh
index 445141f..183985b 100755
--- a/tests/guests/guest-aux/make-ubuntu-img.sh
+++ b/tests/guests/guest-aux/make-ubuntu-img.sh
@@ -39,7 +39,7 @@ DISTRIB_DESCRIPTION="Ubuntu 10.10 (Phony Pharaoh)"
 EOF
 
 # Create a disk image.
-../../fish/guestfish <<EOF
+guestfish <<EOF
 sparse ubuntu.img.tmp.$$ 512M
 run
 
diff --git a/tests/guests/guest-aux/make-windows-img.sh
b/tests/guests/guest-aux/make-windows-img.sh
index 860ec06..9d477fa 100755
--- a/tests/guests/guest-aux/make-windows-img.sh
+++ b/tests/guests/guest-aux/make-windows-img.sh
@@ -25,7 +25,7 @@ set -e
 # ntfs-3g/ntfsprogs then we cannot create a Windows phony image.
 # Nothing actually uses windows.img in the standard build so we can
 # just 'touch' it and emit a warning.
-if ! ../../fish/guestfish -a /dev/null run : available "ntfs3g
ntfsprogs"; then
+if ! guestfish -a /dev/null run : available "ntfs3g ntfsprogs"; then
   echo "***"
   echo "Warning: cannot create windows.img because there is no NTFS"
   echo "support in this build of libguestfs.  Just touching the
output"
@@ -36,7 +36,7 @@ if ! ../../fish/guestfish -a /dev/null run : available
"ntfs3g ntfsprogs"; then
 fi
 
 # Create a disk image.
-../../fish/guestfish <<EOF
+guestfish <<EOF
 sparse windows.img.tmp.$$ 512M
 run
 
diff --git a/tests/luks/test-luks-list.sh b/tests/luks/test-luks-list.sh
index bb8389c..be22e8b 100755
--- a/tests/luks/test-luks-list.sh
+++ b/tests/luks/test-luks-list.sh
@@ -26,14 +26,14 @@ set -e
 }
 
 # If luks is not available, bail.
-if ! ../../fish/guestfish -a /dev/null run : available luks; then
+if ! guestfish -a /dev/null run : available luks; then
     echo "$0: skipping test because luks is not available"
     exit 77
 fi
 
 rm -f test-luks-list.img test-luks-list.out
 
-../../fish/guestfish --keys-from-stdin > test-luks-list.out
<<'EOF'
+guestfish --keys-from-stdin > test-luks-list.out <<'EOF'
 sparse test-luks-list.img 1G
 run
 part-init /dev/sda mbr
diff --git a/tests/luks/test-luks.sh b/tests/luks/test-luks.sh
index 5d8e8b2..2f65750 100755
--- a/tests/luks/test-luks.sh
+++ b/tests/luks/test-luks.sh
@@ -26,14 +26,14 @@ set -e
 }
 
 # If luks is not available, bail.
-if ! ../../fish/guestfish -a /dev/null run : available luks; then
+if ! guestfish -a /dev/null run : available luks; then
     echo "$0: skipping test because luks is not available"
     exit 77
 fi
 
 rm -f test-luks.img
 
-../../fish/guestfish --keys-from-stdin <<EOF
+guestfish --keys-from-stdin <<EOF
 sparse test-luks.img 1G
 run
 part-disk /dev/sda mbr
diff --git a/tests/lvm/test-lvm-filtering.sh b/tests/lvm/test-lvm-filtering.sh
index 3744021..f00d712 100755
--- a/tests/lvm/test-lvm-filtering.sh
+++ b/tests/lvm/test-lvm-filtering.sh
@@ -27,7 +27,7 @@ fi
 
 rm -f test-lvm-filtering-1.img test-lvm-filtering-2.img
 
-actual=$(../../fish/guestfish <<'EOF'
+actual=$(guestfish <<'EOF'
 sparse test-lvm-filtering-1.img 1G
 sparse test-lvm-filtering-2.img 1G
 
diff --git a/tests/md/test-inspect-fstab-md.sh
b/tests/md/test-inspect-fstab-md.sh
index ac2e0a9..43e1d3a 100755
--- a/tests/md/test-inspect-fstab-md.sh
+++ b/tests/md/test-inspect-fstab-md.sh
@@ -26,15 +26,13 @@ if [ -n "$SKIP_TEST_INSPECT_FSTAB_MD_SH" ]; then
     exit 77
 fi
 
-guestfish=../../fish/guestfish
-
 rm -f inspect-fstab-md-{1,2}.img inspect-fstab-md.fstab inspect-fstab-md.output
 
 # First, test the regular fedora image, which specifies /boot as /dev/md0
 cp ../guests/fedora-md1.img inspect-fstab-md-1.img
 cp ../guests/fedora-md2.img inspect-fstab-md-2.img
 
-$guestfish -i inspect-fstab-md-[12].img <<'EOF' | sort >
inspect-fstab-md.output
+guestfish -i inspect-fstab-md-[12].img <<'EOF' | sort >
inspect-fstab-md.output
   exists /boot/grub/grub.conf
 EOF
 
@@ -49,13 +47,13 @@ cat <<'EOF' > inspect-fstab-md.fstab
 /dev/md/boot /boot ext2 default 0 0
 EOF
 
-$guestfish -a inspect-fstab-md-1.img -a inspect-fstab-md-2.img
<<'EOF'
+guestfish -a inspect-fstab-md-1.img -a inspect-fstab-md-2.img
<<'EOF'
   run
   mount /dev/VG/Root /
   upload inspect-fstab-md.fstab /etc/fstab
 EOF
 
-$guestfish -i inspect-fstab-md-[12].img <<'EOF' | sort >
inspect-fstab-md.output
+guestfish -i inspect-fstab-md-[12].img <<'EOF' | sort >
inspect-fstab-md.output
   exists /boot/grub/grub.conf
 EOF
 
diff --git a/tests/md/test-inspect-fstab.sh b/tests/md/test-inspect-fstab.sh
index 04ee9d1..f31ec2e 100755
--- a/tests/md/test-inspect-fstab.sh
+++ b/tests/md/test-inspect-fstab.sh
@@ -22,10 +22,9 @@
 set -e
 export LANG=C
 
-guestfish=../../fish/guestfish
 canonical="sed -r s,/dev/[abce-ln-z]+d,/dev/sd,g"
 
-if [ "$($guestfish get-backend)" = "uml" ]; then
+if [ "$(guestfish get-backend)" = "uml" ]; then
     echo "$0: skipping test because uml backend does not support
qcow2"
     exit 77
 fi
@@ -34,7 +33,7 @@ rm -f inspect-fstab-1.qcow2 inspect-fstab.fstab
inspect-fstab.output
 
 # Start with the regular (good) fedora image, modify /etc/fstab
 # and then inspect it.
-$guestfish -- \
+guestfish -- \
   disk-create inspect-fstab-1.qcow2 qcow2 -1 \
     backingfile:../guests/fedora.img backingformat:raw
 
@@ -56,14 +55,14 @@ cat <<'EOF' > inspect-fstab.fstab
 /dev/disk/by-id/ata-QEMU_HARDDISK_QM00001-part3 /id3 ext2 default 0 0
 EOF
 
-$guestfish -a inspect-fstab-1.qcow2 <<'EOF'
+guestfish -a inspect-fstab-1.qcow2 <<'EOF'
   run
   mount /dev/VG/Root /
   upload inspect-fstab.fstab /etc/fstab
 EOF
 
 # This will give a warning, but should not fail.
-$guestfish -a inspect-fstab-1.qcow2 -i <<'EOF' | sort |
$canonical > inspect-fstab.output
+guestfish -a inspect-fstab-1.qcow2 -i <<'EOF' | sort | $canonical
> inspect-fstab.output
   inspect-get-mountpoints /dev/VG/Root
 EOF
 
@@ -88,13 +87,13 @@ cat <<'EOF' > inspect-fstab.fstab
 /dev/xvdg1 /boot ext2 default 0 0
 EOF
 
-$guestfish -a inspect-fstab-1.qcow2 <<'EOF'
+guestfish -a inspect-fstab-1.qcow2 <<'EOF'
   run
   mount /dev/VG/Root /
   upload inspect-fstab.fstab /etc/fstab
 EOF
 
-$guestfish <<'EOF' | $canonical > inspect-fstab.output
+guestfish <<'EOF' | $canonical > inspect-fstab.output
   add inspect-fstab-1.qcow2 readonly:true name:xvdg
   run
   inspect-os
@@ -119,13 +118,13 @@ cat <<'EOF' > inspect-fstab.fstab
 /dev/cciss/c1d3 /var ext2 default 0 0
 EOF
 
-$guestfish -a inspect-fstab-1.qcow2 <<'EOF'
+guestfish -a inspect-fstab-1.qcow2 <<'EOF'
   run
   mount /dev/VG/Root /
   upload inspect-fstab.fstab /etc/fstab
 EOF
 
-$guestfish <<'EOF' | $canonical > inspect-fstab.output
+guestfish <<'EOF' | $canonical > inspect-fstab.output
   add inspect-fstab-1.qcow2 readonly:true name:cciss/c1d3
   run
   inspect-os
diff --git a/tests/md/test-list-filesystems.sh
b/tests/md/test-list-filesystems.sh
index 9f54182..2bfa6f3 100755
--- a/tests/md/test-list-filesystems.sh
+++ b/tests/md/test-list-filesystems.sh
@@ -37,7 +37,7 @@ rm -f list-fs.output
 # md127 : 20M ext4
 # vg0 : 16M LV (lv0)
 # lv0 : 16M vfat
-../../fish/guestfish <<EOF | sed -r s,/dev/[abce-ln-z]+d,/dev/sd,g >
list-fs.output
+guestfish <<EOF | sed -r s,/dev/[abce-ln-z]+d,/dev/sd,g >
list-fs.output
 # Add 2 empty disks
 scratch 50M
 scratch 50M
diff --git a/tests/md/test-list-md-devices.sh b/tests/md/test-list-md-devices.sh
index 511f6be..5a9cbe8 100755
--- a/tests/md/test-list-md-devices.sh
+++ b/tests/md/test-list-md-devices.sh
@@ -26,7 +26,7 @@ if [ -n "$SKIP_TEST_LIST_MD_DEVICES_SH" ]; then
 fi
 
 output=$(
-../../fish/guestfish <<EOF
+guestfish <<EOF
 # Add 2 empty disks
 sparse list-md-devices-1.img 100M
 sparse list-md-devices-2.img 100M
@@ -49,7 +49,7 @@ fi
 
 # Ensure list-md-devices now returns the newly created md device
 output=$(
-../../fish/guestfish -a list-md-devices-1.img -a list-md-devices-2.img
<<EOF
+guestfish -a list-md-devices-1.img -a list-md-devices-2.img <<EOF
 run
 list-md-devices
 EOF
diff --git a/tests/md/test-mdadm.sh b/tests/md/test-mdadm.sh
index 0e1de05..05b2432 100755
--- a/tests/md/test-mdadm.sh
+++ b/tests/md/test-mdadm.sh
@@ -27,7 +27,7 @@ fi
 
 rm -f mdadm-{1,2,3,4}.img
 
-../../fish/guestfish <<EOF
+guestfish <<EOF
 # Add four empty disks
 sparse mdadm-1.img 100M
 sparse mdadm-2.img 100M
@@ -97,15 +97,15 @@ write /r5t3/baz "testing"
 
 EOF
 
-eval `../../fish/guestfish --listen`
-../../fish/guestfish --remote add-ro mdadm-1.img
-../../fish/guestfish --remote add-ro mdadm-2.img
-../../fish/guestfish --remote add-ro mdadm-3.img
-../../fish/guestfish --remote add-ro mdadm-4.img
-../../fish/guestfish --remote run
+eval `guestfish --listen`
+guestfish --remote add-ro mdadm-1.img
+guestfish --remote add-ro mdadm-2.img
+guestfish --remote add-ro mdadm-3.img
+guestfish --remote add-ro mdadm-4.img
+guestfish --remote run
 
-for md in `../../fish/guestfish --remote list-md-devices`; do
-  ../../fish/guestfish --remote md-detail "$md" > md-detail.out
+for md in `guestfish --remote list-md-devices`; do
+  guestfish --remote md-detail "$md" > md-detail.out
 
   sed 's/:\s*/=/' md-detail.out > md-detail.out.sh
   . md-detail.out.sh
@@ -148,24 +148,24 @@ for md in `../../fish/guestfish --remote list-md-devices`;
do
   if [ "$error" -eq 1 ]; then
     echo "$0: Unexpected output from md-detail for device $md"
     cat md-detail.out
-    ../../fish/guestfish --remote exit
+    guestfish --remote exit
     exit 1
   fi
 done
 
-../../fish/guestfish --remote exit
+guestfish --remote exit
 
-eval `../../fish/guestfish --listen`
-../../fish/guestfish --remote add-ro mdadm-1.img
-../../fish/guestfish --remote add-ro mdadm-2.img
-../../fish/guestfish --remote add-ro mdadm-3.img
-../../fish/guestfish --remote add-ro mdadm-4.img
-../../fish/guestfish --remote run
+eval `guestfish --listen`
+guestfish --remote add-ro mdadm-1.img
+guestfish --remote add-ro mdadm-2.img
+guestfish --remote add-ro mdadm-3.img
+guestfish --remote add-ro mdadm-4.img
+guestfish --remote run
 
-for md in `../../fish/guestfish --remote list-md-devices`; do
-  ../../fish/guestfish --remote md-stop "$md"
+for md in `guestfish --remote list-md-devices`; do
+  guestfish --remote md-stop "$md"
 done
 
-../../fish/guestfish --remote exit
+guestfish --remote exit
 
 rm md-detail.out mdadm-1.img mdadm-2.img mdadm-3.img mdadm-4.img
diff --git a/tests/mountable/test-mountable-inspect.sh
b/tests/mountable/test-mountable-inspect.sh
index b248b01..3b81fd0 100755
--- a/tests/mountable/test-mountable-inspect.sh
+++ b/tests/mountable/test-mountable-inspect.sh
@@ -19,7 +19,6 @@
 set -e
 export LANG=C
 
-guestfish=../../fish/guestfish
 canonical="sed s,/dev/vd,/dev/sd,g"
 
 # Allow the test to be skipped since btrfs is often broken.
@@ -28,13 +27,13 @@ if [ -n "$SKIP_TEST_MOUNTABLE_INSPECT_SH" ]; then
     exit 77
 fi
 
-if [ "$($guestfish get-backend)" = "uml" ]; then
+if [ "$(guestfish get-backend)" = "uml" ]; then
     echo "$0: skipping test because uml backend does not support
qcow2"
     exit 77
 fi
 
 # Bail if btrfs is not available.
-if ! $guestfish -a /dev/null run : available btrfs; then
+if ! guestfish -a /dev/null run : available btrfs; then
     echo "$0: skipping test because btrfs is not available"
     exit 77
 fi
@@ -43,13 +42,13 @@ rm -f root.tmp test.qcow2 test.output
 
 # Start with the regular (good) fedora image, modify /etc/fstab
 # and then inspect it.
-$guestfish -- \
+guestfish -- \
   disk-create test.qcow2 qcow2 -1 \
     backingfile:../guests/fedora-btrfs.img backingformat:raw
 
 # Test that basic inspection works and the expected filesystems are
 # found
-$guestfish -a test.qcow2 -i <<'EOF' | sort | $canonical >
test.output
+guestfish -a test.qcow2 -i <<'EOF' | sort | $canonical >
test.output
   inspect-get-roots | head -1 > root.tmp
   <! echo inspect-get-mountpoints "`cat root.tmp`"
 EOF
@@ -63,7 +62,7 @@ if [ "$(cat test.output)" != "/:
btrfsvol:/dev/sda2/root
 fi
 
 # Additional sanity check: did we get the release name right?
-$guestfish -a test.qcow2 -i <<'EOF' > test.output
+guestfish -a test.qcow2 -i <<'EOF' > test.output
   inspect-get-roots | head -1 > root.tmp
   <! echo inspect-get-product-name "`cat root.tmp`"
 EOF
diff --git a/tests/network/test-network.sh b/tests/network/test-network.sh
index be260a8..f24ef2e 100755
--- a/tests/network/test-network.sh
+++ b/tests/network/test-network.sh
@@ -28,10 +28,10 @@ if [ -n "$SKIP_TEST_RHBZ690819_SH" ]; then
     exit 77
 fi
 
-backend="$(../../fish/guestfish get-backend)"
+backend="$(guestfish get-backend)"
 if [[ "$backend" =~ ^uml ]]; then
     echo "$0: test skipped because backend ($backend) is
'uml'."
     exit 77
 fi
 
-../../fish/guestfish --network -a /dev/null run
+guestfish --network -a /dev/null run
diff --git a/tests/ntfsclone/test-ntfsclone.sh
b/tests/ntfsclone/test-ntfsclone.sh
index 985ea72..30c21bf 100755
--- a/tests/ntfsclone/test-ntfsclone.sh
+++ b/tests/ntfsclone/test-ntfsclone.sh
@@ -27,10 +27,8 @@ fi
 
 rm -f test-ntfsclone.img ntfsclone-backup1 ntfsclone-backup2
 
-guestfish=../../fish/guestfish
-
 # Skip if ntfs-3g is not supported by the appliance.
-if ! $guestfish add /dev/null : run : available "ntfs3g"; then
+if ! guestfish add /dev/null : run : available "ntfs3g"; then
     echo "$0: skipped because ntfs-3g is not supported by the
appliance"
     exit 77
 fi
@@ -41,14 +39,14 @@ if [ ! -s ../guests/windows.img ]; then
 fi
 
 # Export the filesystems to the backup file.
-$guestfish --ro -a ../guests/windows.img <<EOF
+guestfish --ro -a ../guests/windows.img <<EOF
 run
 ntfsclone-out /dev/sda1 ntfsclone-backup1 preservetimestamps:true force:true
 ntfsclone-out /dev/sda2 ntfsclone-backup2 metadataonly:true ignorefscheck:true
 EOF
 
 # Restore to another disk image.
-output=$($guestfish -N test-ntfsclone.img=part:300M <<EOF
+output=$(guestfish -N test-ntfsclone.img=part:300M <<EOF
 ntfsclone-in ntfsclone-backup1 /dev/sda1
 vfs-type /dev/sda1
 EOF
diff --git a/tests/protocol/test-both-ends-cancel.sh
b/tests/protocol/test-both-ends-cancel.sh
index 7c489ca..6301186 100755
--- a/tests/protocol/test-both-ends-cancel.sh
+++ b/tests/protocol/test-both-ends-cancel.sh
@@ -22,7 +22,7 @@
 
 set -e
 
-../../fish/guestfish <<EOF
+guestfish <<EOF
 scratch 100M
 run
 -tar-in /tmp/nosuchfile /blah
diff --git a/tests/protocol/test-cancellation-download-librarycancels.sh
b/tests/protocol/test-cancellation-download-librarycancels.sh
index 9b255ad..ddaa87d 100755
--- a/tests/protocol/test-cancellation-download-librarycancels.sh
+++ b/tests/protocol/test-cancellation-download-librarycancels.sh
@@ -31,7 +31,7 @@ tmpfile=`mktemp`
 size=$(awk 'BEGIN{ srand(); print int(16*1024*rand()) }')
 echo "$0: test size $size (bytes)"
 
-../../fish/guestfish <<EOF
+guestfish <<EOF
 # We want the file to be fully allocated.
 alloc $tmpfile 10M
 run
diff --git a/tests/protocol/test-cancellation-upload-daemoncancels.sh
b/tests/protocol/test-cancellation-upload-daemoncancels.sh
index a5364c7..f6de479 100755
--- a/tests/protocol/test-cancellation-upload-daemoncancels.sh
+++ b/tests/protocol/test-cancellation-upload-daemoncancels.sh
@@ -22,7 +22,7 @@
 
 set -e
 
-../../fish/guestfish \
+guestfish \
     -N test-cancellation-upload-daemoncancels.img=fs:ext2:10M \
     -m /dev/sda1 <<'EOF'
 # Upload image, daemon should cancel because the image is too large
diff --git a/tests/protocol/test-qemudie-killsub.sh
b/tests/protocol/test-qemudie-killsub.sh
index 928cbef..45e8b2d 100755
--- a/tests/protocol/test-qemudie-killsub.sh
+++ b/tests/protocol/test-qemudie-killsub.sh
@@ -20,12 +20,12 @@
 
 set -e
 
-if [ "$(../../fish/guestfish get-backend)" != "direct" ];
then
+if [ "$(guestfish get-backend)" != "direct" ]; then
     echo "$0: test skipped because default backend is not
'direct'"
     exit 77
 fi
 
-../../fish/guestfish <<'EOF'
+guestfish <<'EOF'
 scratch 100M
 run
 # Kill the subprocess.
diff --git a/tests/protocol/test-qemudie-midcommand.sh
b/tests/protocol/test-qemudie-midcommand.sh
index ac41fb2..058df2c 100755
--- a/tests/protocol/test-qemudie-midcommand.sh
+++ b/tests/protocol/test-qemudie-midcommand.sh
@@ -20,14 +20,14 @@
 
 set -e
 
-if [ "$(../../fish/guestfish get-backend)" != "direct" ];
then
+if [ "$(guestfish get-backend)" != "direct" ]; then
     echo "$0: test skipped because default backend is not
'direct'"
     exit 77
 fi
 
 rm -f qemudie-midcommand.pid
 
-../../fish/guestfish <<'EOF'
+guestfish <<'EOF'
 scratch 100M
 run
 # Kill the subprocess after a short wait.
diff --git a/tests/protocol/test-qemudie-synch.sh
b/tests/protocol/test-qemudie-synch.sh
index e9431a3..a7066ed 100755
--- a/tests/protocol/test-qemudie-synch.sh
+++ b/tests/protocol/test-qemudie-synch.sh
@@ -20,14 +20,14 @@
 
 set -e
 
-if [ "$(../../fish/guestfish get-backend)" != "direct" ];
then
+if [ "$(guestfish get-backend)" != "direct" ]; then
     echo "$0: test skipped because default backend is not
'direct'"
     exit 77
 fi
 
 rm -f qemudie-synch.pid
 
-../../fish/guestfish <<'EOF'
+guestfish <<'EOF'
 scratch 100M
 run
 # Kill subprocess.
diff --git a/tests/qemu/qemu-force-tcg.sh b/tests/qemu/qemu-force-tcg.sh
index 90d7683..79b32b7 100755
--- a/tests/qemu/qemu-force-tcg.sh
+++ b/tests/qemu/qemu-force-tcg.sh
@@ -24,7 +24,7 @@ if [ -n "$SKIP_QEMU_FORCE_TCG_SH" ]; then
 fi
 
 # Only applicable to the direct and libvirt backends:
-if [ "$(../../fish/guestfish get-backend)" = "uml" ]; then
+if [ "$(guestfish get-backend)" = "uml" ]; then
     echo "$0: skipping test because it is only applicable when qemu is
being used."
     exit 77
 fi
@@ -33,7 +33,7 @@ set -e
 
 rm -f qemu-force-tcg.out
 
-../../fish/guestfish -a /dev/null <<EOF
+guestfish -a /dev/null <<EOF
 set-backend-setting force_tcg 1
 run
 debug sh "cat
/sys/devices/system/clocksource/clocksource0/current_clocksource" | cat
> qemu-force-tcg.out
diff --git a/tests/qemu/qemu-liveness.sh b/tests/qemu/qemu-liveness.sh
index fe8396a..4db71bd 100755
--- a/tests/qemu/qemu-liveness.sh
+++ b/tests/qemu/qemu-liveness.sh
@@ -24,10 +24,10 @@ set -e
 
 rm -f liveness1.img
 
-../../fish/guestfish sparse liveness1.img 100M
+guestfish sparse liveness1.img 100M
 liveness1_md5sum="$(md5sum liveness1.img | awk '{print $1}')"
 
-../../fish/guestfish <<'EOF'
+guestfish <<'EOF'
 add liveness1.img format:raw
 run
 
diff --git a/tests/qemu/qemu-snapshot-isolation.sh
b/tests/qemu/qemu-snapshot-isolation.sh
index 82b3892..daa210f 100755
--- a/tests/qemu/qemu-snapshot-isolation.sh
+++ b/tests/qemu/qemu-snapshot-isolation.sh
@@ -22,23 +22,21 @@
 
 set -e
 
-guestfish=../../fish/guestfish
-
 # UML backend doesn't support qcow2 format.
 supports_qcow2=yes
-if [ "$($guestfish get-backend)" = "uml" ]; then
+if [ "$(guestfish get-backend)" = "uml" ]; then
     supports_qcow2=no
 fi
 
 rm -f isolation1.img isolation2.img isolation3.img
 
-../../fish/guestfish sparse isolation1.img 100M
+guestfish sparse isolation1.img 100M
 isolation1_md5sum="$(md5sum isolation1.img | awk '{print
$1}')"
-../../fish/guestfish sparse isolation2.img 100M
+guestfish sparse isolation2.img 100M
 isolation2_md5sum="$(md5sum isolation2.img | awk '{print
$1}')"
 
 if [ "$supports_qcow2" = "yes" ]; then
-    ../../fish/guestfish \
+    guestfish \
         disk-create isolation3.img qcow2 100M preallocation:metadata
     isolation3_md5sum="$(md5sum isolation3.img | awk '{print
$1}')"
     add3="add-drive-opts isolation3.img format:qcow2 readonly:true"
@@ -53,7 +51,7 @@ fi
 
 # The vitally important calls are 'add-drive-ro' and
 # 'add-drive-opts ... readonly:true'.
-../../fish/guestfish <<EOF
+guestfish <<EOF
 add-drive-ro isolation1.img
 add-drive-opts isolation2.img format:raw readonly:true
 $add3
diff --git a/tests/regressions/rhbz1001875.sh b/tests/regressions/rhbz1001875.sh
index 1d16873..885fd8c 100755
--- a/tests/regressions/rhbz1001875.sh
+++ b/tests/regressions/rhbz1001875.sh
@@ -30,7 +30,7 @@ fi
 
 rm -f rhbz1001875.img rhbz1001875-[123].tar
 
-../../fish/guestfish -N rhbz1001875.img=fs -m /dev/sda1 <<EOF
+guestfish -N rhbz1001875.img=fs -m /dev/sda1 <<EOF
 touch /hello
 touch /world
 touch /helloworld
diff --git a/tests/regressions/rhbz1044014.sh b/tests/regressions/rhbz1044014.sh
index ce1be76..8e0df2a 100755
--- a/tests/regressions/rhbz1044014.sh
+++ b/tests/regressions/rhbz1044014.sh
@@ -28,7 +28,7 @@ if [ -n "$SKIP_TEST_RHBZ1044014_SH" ]; then
 fi
 
 # Check we are running against the libvirt backend.
-backend="$(../../fish/guestfish get-backend)"
+backend="$(guestfish get-backend)"
 if [[ ! ( "$backend" =~ ^libvirt ) ]]; then
     echo "$0: test skipped because backend ($backend) is not
libvirt."
     exit 77
@@ -49,7 +49,7 @@ export
LIBGUESTFS_BACKEND="libvirt:test://$(pwd)/$srcdir/rhbz1044014.xml"
 
 rm -f rhbz1044014.out
 
-../../fish/guestfish -- -run < $srcdir/rhbz1044014.in > rhbz1044014.out
2>&1 || {
+guestfish -- -run < $srcdir/rhbz1044014.in > rhbz1044014.out 2>&1
|| {
     r=$?
     if [ $r -ne 0 ]; then
         cat rhbz1044014.out
diff --git a/tests/regressions/rhbz1054761.sh b/tests/regressions/rhbz1054761.sh
index f7f49df..344479d 100755
--- a/tests/regressions/rhbz1054761.sh
+++ b/tests/regressions/rhbz1054761.sh
@@ -30,14 +30,14 @@ fi
 
 rm -f rhbz1054761-[ab].img
 
-../../fish/guestfish -N rhbz1054761-a.img=disk -N rhbz1054761-b.img=disk
<<EOF
+guestfish -N rhbz1054761-a.img=disk -N rhbz1054761-b.img=disk <<EOF
 pvcreate /dev/sda
 pvcreate /dev/sdb
 vgcreate VG "/dev/sda /dev/sdb"
 EOF
 
 output="$(
-    ../../fish/guestfish -a rhbz1054761-a.img run : pvs |
+    guestfish -a rhbz1054761-a.img run : pvs |
         sed -r 's,^/dev/[abce-ln-z]+d,/dev/sd,'
 )"
 if [ "$output" != "/dev/sda" ]; then
diff --git a/tests/regressions/rhbz1091803.sh b/tests/regressions/rhbz1091803.sh
index e9be95d..6851a1c 100755
--- a/tests/regressions/rhbz1091803.sh
+++ b/tests/regressions/rhbz1091803.sh
@@ -28,7 +28,7 @@ if [ -n "$SKIP_TEST_RHBZ1091803_SH" ]; then
     exit 77
 fi
 
-../../fish/guestfish <<EOF
+guestfish <<EOF
 scratch 100M
 run
 mkfs ext2 /dev/sda
diff --git a/tests/regressions/rhbz503169c13.sh
b/tests/regressions/rhbz503169c13.sh
index 44ff2d9..b0ee77b 100755
--- a/tests/regressions/rhbz503169c13.sh
+++ b/tests/regressions/rhbz503169c13.sh
@@ -26,7 +26,7 @@
 
 set -e
 
-../../fish/guestfish -N rhbz503169c13.img=fs -m /dev/sda1 <<EOF
+guestfish -N rhbz503169c13.img=fs -m /dev/sda1 <<EOF
 mkdir /dev
 -command /ignore-this-error
 unmount-all
diff --git a/tests/regressions/rhbz557655.sh b/tests/regressions/rhbz557655.sh
index 87eb279..fd723bf 100755
--- a/tests/regressions/rhbz557655.sh
+++ b/tests/regressions/rhbz557655.sh
@@ -24,7 +24,7 @@ set -e
 rm -f rhbz557655.out rhbz557655.err
 export LANG=C
 
-../../fish/guestfish >> rhbz557655.out 2>> rhbz557655.err
<<EOF
+guestfish >> rhbz557655.out 2>> rhbz557655.err <<EOF
 # set-memsize is just a convenient non-daemon function that
 # takes a single integer argument.
 set-memsize 500
@@ -46,7 +46,7 @@ get-memsize
 -set-memsize 123L
 EOF
 
-../../fish/guestfish -N rhbz557655.img=fs -m /dev/sda1 >> rhbz557655.out
2>> rhbz557655.err <<EOF
+guestfish -N rhbz557655.img=fs -m /dev/sda1 >> rhbz557655.out 2>>
rhbz557655.err <<EOF
 touch /test
 
 # truncate-size takes an Int64 argument
diff --git a/tests/regressions/rhbz563450.sh b/tests/regressions/rhbz563450.sh
index 96fca8c..d7cf751 100755
--- a/tests/regressions/rhbz563450.sh
+++ b/tests/regressions/rhbz563450.sh
@@ -29,7 +29,7 @@ fi
 
 rm -f test.out
 
-../../fish/guestfish --ro > test.out <<EOF
+guestfish --ro > test.out <<EOF
 add-drive-ro ../guests/fedora.img
 add-cdrom ../data/test.iso
 add-drive-ro ../guests/debian.img
diff --git a/tests/regressions/rhbz563450b.sh b/tests/regressions/rhbz563450b.sh
index 7b890b1..26aaf6f 100755
--- a/tests/regressions/rhbz563450b.sh
+++ b/tests/regressions/rhbz563450b.sh
@@ -29,7 +29,7 @@ fi
 
 rm -f test.out
 
-../../fish/guestfish --ro > test.out <<EOF
+guestfish --ro > test.out <<EOF
 add-cdrom ../data/test.iso
 
 run
diff --git a/tests/regressions/rhbz576879.sh b/tests/regressions/rhbz576879.sh
index 2e803af..fece6b4 100755
--- a/tests/regressions/rhbz576879.sh
+++ b/tests/regressions/rhbz576879.sh
@@ -22,7 +22,7 @@
 
 set -e
 
-../../fish/guestfish <<EOF
+guestfish <<EOF
 scratch 100M
 run
 -upload $srcdir/rhbz576879.sh /test.sh
diff --git a/tests/regressions/rhbz578407.sh b/tests/regressions/rhbz578407.sh
index 5fe2cc1..fb7ba93 100755
--- a/tests/regressions/rhbz578407.sh
+++ b/tests/regressions/rhbz578407.sh
@@ -23,21 +23,19 @@
 
 set -e
 
-guestfish=../../fish/guestfish
-
 # Start remote guestfish.
-eval `$guestfish --listen 2>/dev/null`
+eval `guestfish --listen 2>/dev/null`
 
 # This should succeed.
-$guestfish --remote version > /dev/null
+guestfish --remote version > /dev/null
 
 # This command will fail (because appliance not launched), but
 # prefixing with '-' should make remote guestfish ignore the failure.
-$guestfish --remote -- -lvs
+guestfish --remote -- -lvs
 
 # Remote guestfish should still be running.
-$guestfish --remote version > /dev/null
-$guestfish --remote exit
+guestfish --remote version > /dev/null
+guestfish --remote exit
 
 # Try some other command line argument tests which are related the fix.
-$guestfish -- version : -lvs : version > /dev/null 2>&1
+guestfish -- version : -lvs : version > /dev/null 2>&1
diff --git a/tests/regressions/rhbz580246.sh b/tests/regressions/rhbz580246.sh
index 5ab8e19..218dd96 100755
--- a/tests/regressions/rhbz580246.sh
+++ b/tests/regressions/rhbz580246.sh
@@ -29,7 +29,7 @@ dd if=/dev/zero of=rhbz580246.img bs=1M count=2
 tar cf rhbz580246.tar rhbz580246.img
 
 output=$(
-../../fish/guestfish 2>&1 <<'EOF'
+guestfish 2>&1 <<'EOF'
 add rhbz580246.img
 run
 mkfs ext2 /dev/sda
diff --git a/tests/regressions/rhbz602997.sh b/tests/regressions/rhbz602997.sh
index 2231fe7..d48693b 100755
--- a/tests/regressions/rhbz602997.sh
+++ b/tests/regressions/rhbz602997.sh
@@ -22,11 +22,9 @@
 set -e
 export LANG=C
 
-guestfish=../../fish/guestfish
-
 rm -f test.output
 
-$guestfish > test.output <<EOF
+guestfish > test.output <<EOF
 scratch 100M
 run
 part-init /dev/sda mbr
@@ -48,7 +46,7 @@ false" ]; then
     exit 1
 fi
 
-$guestfish > test.output <<EOF
+guestfish > test.output <<EOF
 scratch 100M
 run
 part-init /dev/sda mbr
diff --git a/tests/regressions/rhbz690819.sh b/tests/regressions/rhbz690819.sh
index 5b29813..0af0b64 100755
--- a/tests/regressions/rhbz690819.sh
+++ b/tests/regressions/rhbz690819.sh
@@ -38,7 +38,7 @@ if [[ "$arch" =~ ^ppc ]]; then
     exit 77
 fi
 
-backend="$(../../fish/guestfish get-backend)"
+backend="$(guestfish get-backend)"
 if [[ "$backend" =~ ^libvirt ]]; then
     echo "$0: test skipped because backend ($backend) is
'libvirt'."
     exit 77
@@ -51,9 +51,9 @@ fi
 
 rm -f rhbz690819.img
 
-../../fish/guestfish sparse rhbz690819.img 100M
+guestfish sparse rhbz690819.img 100M
 
-../../fish/guestfish <<EOF
+guestfish <<EOF
 add-drive-with-if rhbz690819.img ide
 run
 mkfs ext3 /dev/sda
diff --git a/tests/regressions/rhbz727178.sh b/tests/regressions/rhbz727178.sh
index 90b5994..639fc32 100755
--- a/tests/regressions/rhbz727178.sh
+++ b/tests/regressions/rhbz727178.sh
@@ -23,20 +23,19 @@
 set -e
 export LANG=C
 
-guestfish=../../fish/guestfish
 output=rhbz727178.output
 
 rm -f binaries.tmp $output
 
-eval `$guestfish -a /dev/null --listen`
+eval `guestfish -a /dev/null --listen`
 
-$guestfish --remote -- run
-$guestfish --remote -- debug binaries "" |
+guestfish --remote -- run
+guestfish --remote -- debug binaries "" |
     grep -E '^/(bin|sbin|usr/bin|usr/sbin|usr/libexec)/' >
binaries.tmp
 
 while read ex; do
     echo ldd $ex
-    $guestfish --remote -- -debug ldd $ex
+    guestfish --remote -- -debug ldd $ex
 done < binaries.tmp > $output
 
 if grep -E '\bnot found\b|undefined symbol' $output; then
diff --git a/tests/regressions/rhbz789960.sh b/tests/regressions/rhbz789960.sh
index ac66c4a..056b7ed 100755
--- a/tests/regressions/rhbz789960.sh
+++ b/tests/regressions/rhbz789960.sh
@@ -24,7 +24,7 @@ export LANG=C
 
 rm -f test.out
 
-../../fish/guestfish -a ../guests/fedora.img --ro > test.out <<EOF
+guestfish -a ../guests/fedora.img --ro > test.out <<EOF
 run
 
 # Not a device at all, should fail.
diff --git a/tests/regressions/rhbz811649.sh b/tests/regressions/rhbz811649.sh
index cfc7298..d48d2bf 100755
--- a/tests/regressions/rhbz811649.sh
+++ b/tests/regressions/rhbz811649.sh
@@ -36,11 +36,11 @@ filenames[9]='raw:'
 
 rm -f -- rhbz811649.img "${filenames[@]}"
 
-../../fish/guestfish sparse rhbz811649.img 10M
+guestfish sparse rhbz811649.img 10M
 
 for f in "${filenames[@]}"; do
     ln -- rhbz811649.img "$f"
-    ../../fish/guestfish <<EOF
+    guestfish <<EOF
 add "$f"
 run
 EOF
diff --git a/tests/regressions/rhbz895904.sh b/tests/regressions/rhbz895904.sh
index f239986..fb7dae9 100755
--- a/tests/regressions/rhbz895904.sh
+++ b/tests/regressions/rhbz895904.sh
@@ -25,7 +25,7 @@ export LANG=C
 
 rm -f rhbz895904.img rhbz895904.out
 
-../../fish/guestfish -N rhbz895904.img=fs -m /dev/sda1 <<EOF | sort -k 3
> rhbz895904.out
+guestfish -N rhbz895904.img=fs -m /dev/sda1 <<EOF | sort -k 3 >
rhbz895904.out
 mkdir /test
 touch /test/file1
 mkdir /test/subdir
diff --git a/tests/regressions/rhbz909624.sh b/tests/regressions/rhbz909624.sh
index a2e93e4..ad419b9 100755
--- a/tests/regressions/rhbz909624.sh
+++ b/tests/regressions/rhbz909624.sh
@@ -26,7 +26,7 @@
 set -e
 export LANG=C
 
-../../fish/guestfish <<EOF
+guestfish <<EOF
 
 add-ro /dev/null
 run
diff --git a/tests/regressions/rhbz957772.sh b/tests/regressions/rhbz957772.sh
index d06d47e..553cab8 100755
--- a/tests/regressions/rhbz957772.sh
+++ b/tests/regressions/rhbz957772.sh
@@ -23,7 +23,7 @@
 set -e
 export LANG=C
 
-../../fish/guestfish -N rhbz957772.img=fs -m /dev/sda1 <<EOF
+guestfish -N rhbz957772.img=fs -m /dev/sda1 <<EOF
 mkdir "/test 1"
 touch "/test 2"
 tar-out "/test 1" /dev/null
diff --git a/tests/regressions/rhbz975797.sh b/tests/regressions/rhbz975797.sh
index cc66438..ebd23ea 100755
--- a/tests/regressions/rhbz975797.sh
+++ b/tests/regressions/rhbz975797.sh
@@ -38,7 +38,7 @@ if [[ "$arch" =~ ^ppc ]]; then
     exit 77
 fi
 
-backend="$(../../fish/guestfish get-backend)"
+backend="$(guestfish get-backend)"
 if [[ "$backend" =~ ^libvirt ]]; then
     echo "$0: test skipped because backend ($backend) is
'libvirt'."
     exit 77
@@ -58,11 +58,11 @@ fi
 
 # Use real disk images here since the code for adding /dev/null may
 # take shortcuts.
-../../fish/guestfish sparse rhbz975797-1.img 1G
-../../fish/guestfish sparse rhbz975797-2.img 1G
-../../fish/guestfish sparse rhbz975797-3.img 1G
+guestfish sparse rhbz975797-1.img 1G
+guestfish sparse rhbz975797-2.img 1G
+guestfish sparse rhbz975797-3.img 1G
 
-$timeout ../../fish/guestfish <<EOF
+$timeout guestfish <<EOF
 add-drive rhbz975797-1.img iface:virtio
 add-drive rhbz975797-2.img iface:ide
 add-drive rhbz975797-3.img
diff --git a/tests/relative-paths/test-relative-paths.sh
b/tests/relative-paths/test-relative-paths.sh
index 67d3181..4924cc3 100755
--- a/tests/relative-paths/test-relative-paths.sh
+++ b/tests/relative-paths/test-relative-paths.sh
@@ -25,7 +25,7 @@ fi
 
 # UML doesn't support qcow2.  Conceivably there might be a similar
 # problem with UML COW images which would require a separate test.
-if [ "$(../../fish/guestfish get-backend)" = "uml" ]; then
+if [ "$(guestfish get-backend)" = "uml" ]; then
     echo "$0: skipping test because uml backend does not support
qcow2"
     exit 77
 fi
@@ -115,7 +115,7 @@ popd
 # codepaths in most backends, so we should test each separately.
 for ro in readonly:true readonly:false; do
     for prefix in "./" "" "$(pwd)/"; do
-        $VG ../../fish/guestfish <<EOF
+        $VG guestfish <<EOF
             add-drive ${prefix}overlay1            $ro format:qcow2
             add-drive ${prefix}overlay2            $ro format:qcow2
             add-drive ${prefix}overlay3            $ro format:qcow2
diff --git a/tests/rsync/test-rsync.sh b/tests/rsync/test-rsync.sh
index 6e792e4..793d59d 100755
--- a/tests/rsync/test-rsync.sh
+++ b/tests/rsync/test-rsync.sh
@@ -22,8 +22,6 @@
 unset CDPATH
 set -e
 
-guestfish=../../fish/guestfish
-
 if [ -n "$SKIP_TEST_RSYNC_SH" ]; then
     echo "$0: test skipped because environment variable is set."
     exit 77
@@ -35,13 +33,13 @@ if ! rsync --help >/dev/null 2>&1; then
     exit 77
 fi
 
-if [ "$($guestfish get-backend)" = "uml" ]; then
+if [ "$(guestfish get-backend)" = "uml" ]; then
     echo "$0: skipping test because networking is not available in the UML
backend"
     exit 77
 fi
 
 # If rsync is not available, bail.
-if ! $guestfish -a /dev/null run : available rsync; then
+if ! guestfish -a /dev/null run : available rsync; then
     echo "$0: skipping test because rsync is not available in the
appliance"
     exit 77
 fi
@@ -86,7 +84,7 @@ trap cleanup INT TERM QUIT EXIT
 ip=169.254.2.2
 user="$(id -un)"
 
-$guestfish --network -N test-rsync.img=fs -m /dev/sda1 <<EOF
+guestfish --network -N test-rsync.img=fs -m /dev/sda1 <<EOF
 mkdir /dir1
 rsync-in "rsync://$user@$ip:$port/src/" /dir1/ archive:true
 mkdir /dir2
diff --git a/v2v/test-v2v-i-disk.sh b/v2v/test-v2v-i-disk.sh
index dbf6f94..b15e0d0 100755
--- a/v2v/test-v2v-i-disk.sh
+++ b/v2v/test-v2v-i-disk.sh
@@ -27,7 +27,7 @@ if [ -n "$SKIP_TEST_V2V_I_DISK_SH" ]; then
     exit 77
 fi
 
-if [ "$(../fish/guestfish get-backend)" = "uml" ]; then
+if [ "$(guestfish get-backend)" = "uml" ]; then
     echo "$0: test skipped because UML backend does not support
network"
     exit 77
 fi
@@ -48,7 +48,7 @@ d=test-v2v-i-disk.d
 rm -rf $d
 mkdir $d
 
-$VG ./virt-v2v --debug-gc \
+$VG virt-v2v --debug-gc \
     -i disk $f \
     -o local -os $d
 
diff --git a/v2v/test-v2v-i-ova.sh b/v2v/test-v2v-i-ova.sh
index 59fd77b..a0e35a3 100755
--- a/v2v/test-v2v-i-ova.sh
+++ b/v2v/test-v2v-i-ova.sh
@@ -27,7 +27,7 @@ if [ -n "$SKIP_TEST_V2V_I_OVA_SH" ]; then
     exit 77
 fi
 
-if [ "$(../fish/guestfish get-backend)" = "uml" ]; then
+if [ "$(guestfish get-backend)" = "uml" ]; then
     echo "$0: test skipped because UML backend does not support
network"
     exit 77
 fi
@@ -68,7 +68,7 @@ tar -cf $ova $ovf $mf $vmdk
 rm -rf $ovf $mf $vmdk
 popd
 
-$VG ./virt-v2v --debug-gc \
+$VG virt-v2v --debug-gc \
     -i ova $d/$ova \
     -o local -of raw -os $d
 
diff --git a/v2v/test-v2v-machine-readable.sh b/v2v/test-v2v-machine-readable.sh
index 5771d9e..3e94ae5 100755
--- a/v2v/test-v2v-machine-readable.sh
+++ b/v2v/test-v2v-machine-readable.sh
@@ -27,7 +27,7 @@ if [ -n "$SKIP_TEST_V2V_MACHINE_READABLE_SH" ]; then
     exit 77
 fi
 
-$VG ./virt-v2v --debug-gc --machine-readable > test-v2v-machine-readable.out
+$VG virt-v2v --debug-gc --machine-readable > test-v2v-machine-readable.out
 grep virt-v2v test-v2v-machine-readable.out
 grep libguestfs-rewrite test-v2v-machine-readable.out
 
diff --git a/v2v/test-v2v-networks-and-bridges.sh
b/v2v/test-v2v-networks-and-bridges.sh
index d7b7749..5974dcb 100755
--- a/v2v/test-v2v-networks-and-bridges.sh
+++ b/v2v/test-v2v-networks-and-bridges.sh
@@ -27,7 +27,7 @@ if [ -n "$SKIP_TEST_V2V_NETWORKS_AND_BRIDGES_SH" ];
then
     exit 77
 fi
 
-if [ "$(../fish/guestfish get-backend)" = "uml" ]; then
+if [ "$(guestfish get-backend)" = "uml" ]; then
     echo "$0: test skipped because UML backend does not support
network"
     exit 77
 fi
@@ -52,7 +52,7 @@ rm -rf $d
 mkdir $d
 
 # Use --no-copy because we only care about metadata for this test.
-$VG ./virt-v2v --debug-gc \
+$VG virt-v2v --debug-gc \
     -i libvirt -ic "$libvirt_uri" windows \
     -o local -os $d --no-copy \
     --bridge "VM Network:bridge1" \
diff --git a/v2v/test-v2v-no-copy.sh b/v2v/test-v2v-no-copy.sh
index a7b97d0..35177c9 100755
--- a/v2v/test-v2v-no-copy.sh
+++ b/v2v/test-v2v-no-copy.sh
@@ -27,7 +27,7 @@ if [ -n "$SKIP_TEST_V2V_NO_COPY_SH" ]; then
     exit 77
 fi
 
-if [ "$(../fish/guestfish get-backend)" = "uml" ]; then
+if [ "$(guestfish get-backend)" = "uml" ]; then
     echo "$0: test skipped because UML backend does not support
network"
     exit 77
 fi
@@ -52,7 +52,7 @@ rm -rf $d
 mkdir $d
 
 # No copy with -o local.
-$VG ./virt-v2v --debug-gc --no-copy \
+$VG virt-v2v --debug-gc --no-copy \
     -i libvirt -ic "$libvirt_uri" windows \
     -o local -os $d
 
@@ -68,7 +68,7 @@ mkdir $d/12345678-1234-1234-1234-123456789abc/images
 mkdir $d/12345678-1234-1234-1234-123456789abc/master
 mkdir $d/12345678-1234-1234-1234-123456789abc/master/vms
 
-$VG ./virt-v2v --debug-gc --no-copy \
+$VG virt-v2v --debug-gc --no-copy \
     -i libvirt -ic "$libvirt_uri" windows \
     -o rhev -os $d
 
diff --git a/v2v/test-v2v-o-glance.sh b/v2v/test-v2v-o-glance.sh
index 4960f69..121177f 100755
--- a/v2v/test-v2v-o-glance.sh
+++ b/v2v/test-v2v-o-glance.sh
@@ -27,7 +27,7 @@ if [ -n "$SKIP_TEST_V2V_O_GLANCE_SH" ]; then
     exit 77
 fi
 
-if [ "$(../fish/guestfish get-backend)" = "uml" ]; then
+if [ "$(guestfish get-backend)" = "uml" ]; then
     echo "$0: test skipped because UML backend does not support
network"
     exit 77
 fi
@@ -51,7 +51,7 @@ fi
 # glance binary.
 ln -sf "$(which echo)" glance
 
-$VG ./virt-v2v --debug-gc \
+$VG virt-v2v --debug-gc \
     -i libvirt -ic "$libvirt_uri" windows \
     -o glance -on test
 
diff --git a/v2v/test-v2v-o-libvirt.sh b/v2v/test-v2v-o-libvirt.sh
index 60f53c0..77b38e0 100755
--- a/v2v/test-v2v-o-libvirt.sh
+++ b/v2v/test-v2v-o-libvirt.sh
@@ -27,7 +27,7 @@ if [ -n "$SKIP_TEST_V2V_O_LIBVIRT_SH" ]; then
     exit 77
 fi
 
-if [ "$(../fish/guestfish get-backend)" = "uml" ]; then
+if [ "$(guestfish get-backend)" = "uml" ]; then
     echo "$0: test skipped because UML backend does not support
network"
     exit 77
 fi
@@ -66,7 +66,7 @@ mkdir $d
 virsh pool-destroy test-v2v-libvirt ||:
 virsh pool-create-as test-v2v-libvirt dir - - - - $(pwd)/$d
 
-$VG ./virt-v2v --debug-gc \
+$VG virt-v2v --debug-gc \
     -i libvirt -ic "$libvirt_uri" windows \
     -o libvirt -os test-v2v-libvirt -on $guestname
 
diff --git a/v2v/test-v2v-o-null.sh b/v2v/test-v2v-o-null.sh
index 8b2c612..9ed581b 100755
--- a/v2v/test-v2v-o-null.sh
+++ b/v2v/test-v2v-o-null.sh
@@ -27,7 +27,7 @@ if [ -n "$SKIP_TEST_V2V_O_NULL_SH" ]; then
     exit 77
 fi
 
-if [ "$(../fish/guestfish get-backend)" = "uml" ]; then
+if [ "$(guestfish get-backend)" = "uml" ]; then
     echo "$0: test skipped because UML backend does not support
network"
     exit 77
 fi
@@ -47,6 +47,6 @@ if ! test -r $virt_tools_data_dir/rhsrvany.exe; then
     exit 77
 fi
 
-$VG ./virt-v2v --debug-gc \
+$VG virt-v2v --debug-gc \
     -i libvirt -ic "$libvirt_uri" windows \
     -o null
diff --git a/v2v/test-v2v-o-rhev.sh b/v2v/test-v2v-o-rhev.sh
index 6dcbb1a..6d21320 100755
--- a/v2v/test-v2v-o-rhev.sh
+++ b/v2v/test-v2v-o-rhev.sh
@@ -27,7 +27,7 @@ if [ -n "$SKIP_TEST_V2V_O_RHEV_SH" ]; then
     exit 77
 fi
 
-if [ "$(../fish/guestfish get-backend)" = "uml" ]; then
+if [ "$(guestfish get-backend)" = "uml" ]; then
     echo "$0: test skipped because UML backend does not support
network"
     exit 77
 fi
@@ -57,7 +57,7 @@ mkdir $d/12345678-1234-1234-1234-123456789abc/images
 mkdir $d/12345678-1234-1234-1234-123456789abc/master
 mkdir $d/12345678-1234-1234-1234-123456789abc/master/vms
 
-$VG ./virt-v2v --debug-gc \
+$VG virt-v2v --debug-gc \
     -i libvirt -ic "$libvirt_uri" windows \
     -o rhev -os $d
 
diff --git a/v2v/test-v2v-o-vdsm-options.sh b/v2v/test-v2v-o-vdsm-options.sh
index e5bf764..cf8fe06 100755
--- a/v2v/test-v2v-o-vdsm-options.sh
+++ b/v2v/test-v2v-o-vdsm-options.sh
@@ -27,7 +27,7 @@ if [ -n "$SKIP_TEST_V2V_O_VDSM_OPTIONS_SH" ]; then
     exit 77
 fi
 
-if [ "$(../fish/guestfish get-backend)" = "uml" ]; then
+if [ "$(guestfish get-backend)" = "uml" ]; then
     echo "$0: test skipped because UML backend does not support
network"
     exit 77
 fi
@@ -62,7 +62,7 @@ mkdir $d/12345678-1234-1234-1234-123456789abc/master/vms/VM
 # The --vdsm-*-uuid options don't actually check that the
 # parameter is a UUID, which is useful here.
 
-$VG ./virt-v2v --debug-gc \
+$VG virt-v2v --debug-gc \
     -i libvirt -ic "$libvirt_uri" windows \
     -o vdsm -os $d \
     --vmtype desktop \
diff --git a/v2v/test-v2v-of-option.sh b/v2v/test-v2v-of-option.sh
index 07e7e63..27441cf 100755
--- a/v2v/test-v2v-of-option.sh
+++ b/v2v/test-v2v-of-option.sh
@@ -27,7 +27,7 @@ if [ -n "$SKIP_TEST_V2V_OF_OPTION_SH" ]; then
     exit 77
 fi
 
-if [ "$(../fish/guestfish get-backend)" = "uml" ]; then
+if [ "$(guestfish get-backend)" = "uml" ]; then
     echo "$0: test skipped because UML backend does not support network or
qcow2"
     exit 77
 fi
@@ -51,12 +51,12 @@ d=test-v2v-windows-conversion.d
 rm -rf $d
 mkdir $d
 
-$VG ./virt-v2v --debug-gc \
+$VG virt-v2v --debug-gc \
     -i libvirt -ic "$libvirt_uri" windows \
     -o local -os $d -of qcow2
 
 # Test the disk is qcow2 format.
-if [ "$(../fish/guestfish disk-format $d/windows-sda)" != qcow2 ];
then
+if [ "$(guestfish disk-format $d/windows-sda)" != qcow2 ]; then
     echo "$0: test failed: output is not qcow2"
     exit 1
 fi
diff --git a/v2v/test-v2v-on-option.sh b/v2v/test-v2v-on-option.sh
index 0591e91..e3edb67 100755
--- a/v2v/test-v2v-on-option.sh
+++ b/v2v/test-v2v-on-option.sh
@@ -27,7 +27,7 @@ if [ -n "$SKIP_TEST_V2V_ON_OPTION_SH" ]; then
     exit 77
 fi
 
-if [ "$(../fish/guestfish get-backend)" = "uml" ]; then
+if [ "$(guestfish get-backend)" = "uml" ]; then
     echo "$0: test skipped because UML backend does not support
network"
     exit 77
 fi
@@ -51,7 +51,7 @@ d=test-v2v-windows-conversion.d
 rm -rf $d
 mkdir $d
 
-$VG ./virt-v2v --debug-gc \
+$VG virt-v2v --debug-gc \
     -i libvirt -ic "$libvirt_uri" windows \
     -o local -os $d -on this-is-not-windows
 
diff --git a/v2v/test-v2v-print-source.sh b/v2v/test-v2v-print-source.sh
index 9cd96d6..a3baca7 100755
--- a/v2v/test-v2v-print-source.sh
+++ b/v2v/test-v2v-print-source.sh
@@ -40,7 +40,7 @@ d=test-v2v-print-source.d
 rm -rf $d
 mkdir $d
 
-$VG ./virt-v2v --debug-gc \
+$VG virt-v2v --debug-gc \
     -i libvirt -ic "$libvirt_uri" windows \
     -o local -os $d \
     --print-source > $d/output
diff --git a/v2v/test-v2v-real-conversions.sh b/v2v/test-v2v-real-conversions.sh
index 9c1c281..e4e4a67 100755
--- a/v2v/test-v2v-real-conversions.sh
+++ b/v2v/test-v2v-real-conversions.sh
@@ -58,7 +58,7 @@ for file in *.img; do
 </domain>
 EOF
 
-      ./virt-v2v --debug-gc \
+      virt-v2v --debug-gc \
           -i libvirtxml $d/$n-input.xml \
           -o local -os $d
 
diff --git a/v2v/test-v2v-windows-conversion.sh
b/v2v/test-v2v-windows-conversion.sh
index 7525251..7e8e628 100755
--- a/v2v/test-v2v-windows-conversion.sh
+++ b/v2v/test-v2v-windows-conversion.sh
@@ -27,7 +27,7 @@ if [ -n "$SKIP_TEST_V2V_WINDOWS_CONVERSION_SH" ];
then
     exit 77
 fi
 
-if [ "$(../fish/guestfish get-backend)" = "uml" ]; then
+if [ "$(guestfish get-backend)" = "uml" ]; then
     echo "$0: test skipped because UML backend does not support
network"
     exit 77
 fi
@@ -61,7 +61,7 @@ d=test-v2v-windows-conversion.d
 rm -rf $d
 mkdir $d
 
-$VG ./virt-v2v --debug-gc \
+$VG virt-v2v --debug-gc \
     -i libvirt -ic "$libvirt_uri" windows \
     -o local -os $d \
     --root $root
@@ -71,7 +71,7 @@ test -f $d/windows.xml
 test -f $d/windows-sda
 
 # Test some aspects of the target disk image.
-../fish/guestfish --ro -a $d/windows-sda -i <<EOF
+guestfish --ro -a $d/windows-sda -i <<EOF
   is-dir "/Program Files/Red Hat/Firstboot"
   is-file "/Program Files/Red Hat/Firstboot/firstboot.bat"
   is-dir "/Program Files/Red Hat/Firstboot/scripts"
-- 
2.0.4
Richard W.M. Jones
2014-Sep-16  14:05 UTC
[Libguestfs] [PATCH 2/3] generator: Change type of 'tests' to 'c_api_tests'.
Just a code refactoring, has no functional effect.
---
 generator/main.ml        |  2 +-
 generator/tests_c_api.ml |  4 ++--
 generator/types.ml       | 12 ++++++------
 generator/utils.mli      |  2 +-
 4 files changed, 10 insertions(+), 10 deletions(-)
diff --git a/generator/main.ml b/generator/main.ml
index 63ddb9a..c0ad146 100644
--- a/generator/main.ml
+++ b/generator/main.ml
@@ -115,7 +115,7 @@ Run it from the top source directory using the command
   output_to "daemon/names.c" generate_daemon_names;
   output_to "daemon/optgroups.c" generate_daemon_optgroups_c;
   output_to "daemon/optgroups.h" generate_daemon_optgroups_h;
-  output_to "tests/c-api/tests.c" generate_tests;
+  output_to "tests/c-api/tests.c" generate_c_api_tests;
   output_to "fish/cmds-gperf.gperf" generate_fish_cmds_gperf;
   output_to "fish/cmds.c" generate_fish_cmds;
   output_to "fish/completion.c" generate_fish_completion;
diff --git a/generator/tests_c_api.ml b/generator/tests_c_api.ml
index c0ebcb9..88aa07e 100644
--- a/generator/tests_c_api.ml
+++ b/generator/tests_c_api.ml
@@ -28,8 +28,8 @@ open Optgroups
 open Actions
 open Structs
 
-(* Generate the tests. *)
-let rec generate_tests () +(* Generate the C API tests. *)
+let rec generate_c_api_tests ()    generate_header CStyle GPLv2plus;
 
   pr "\
diff --git a/generator/types.ml b/generator/types.ml
index 48ac32a..63aa235 100644
--- a/generator/types.ml
+++ b/generator/types.ml
@@ -208,8 +208,8 @@ type fish_output_t    | FishOutputHexadecimal (* for int
return, print in hex *)
 
 (* See guestfs(3)/EXTENDING LIBGUESTFS. *)
-type tests = (test_init * test_prereq * test * test_cleanup) list
-and test +type c_api_tests = (c_api_test_init * c_api_test_prereq * c_api_test
* c_api_test_cleanup) list
+and c_api_test      (* Run the command sequence and just expect nothing to
fail. *)
   | TestRun of seq
 
@@ -241,7 +241,7 @@ and test    | TestLastFail of seq
 
 (* Test prerequisites. *)
-and test_prereq +and c_api_test_prereq      (* Test always runs. *)
   | Always
 
@@ -254,7 +254,7 @@ and test_prereq    | IfAvailable of string
 
 (* Some initial scenarios for testing. *)
-and test_init +and c_api_test_init      (* Do nothing, block devices could
contain random stuff including
      * LVM PVs, and some filesystems might be mounted.  This is usually
      * a bad idea.
@@ -309,7 +309,7 @@ and test_init    | InitScratchFS
 
 (* Cleanup commands which are run whether the test succeeds or fails. *)
-and test_cleanup = cmd list
+and c_api_test_cleanup = cmd list
 
 (* Sequence of commands for testing. *)
 and seq = cmd list
@@ -328,7 +328,7 @@ type action = {
   name : string;                  (* name, not including "guestfs_"
*)
   style : style;                  (* args and return value *)
   proc_nr : int option;           (* proc number, None for non-daemon *)
-  tests : tests;                  (* tests *)
+  tests : c_api_tests;            (* C API tests *)
   test_excuse : string;           (* if there's no tests ... *)
   shortdesc : string;             (* single line description *)
   longdesc : string;              (* longer documentation *)
diff --git a/generator/utils.mli b/generator/utils.mli
index c96bde4..8dca20b 100644
--- a/generator/utils.mli
+++ b/generator/utils.mli
@@ -99,7 +99,7 @@ val name_of_argt : Types.argt -> string
 val name_of_optargt : Types.optargt -> string
 (** Extract optional argument name. *)
 
-val seq_of_test : Types.test -> Types.seq
+val seq_of_test : Types.c_api_test -> Types.seq
 (** Extract test sequence from a test. *)
 
 val c_quote : string -> string
-- 
2.0.4
Richard W.M. Jones
2014-Sep-16  14:05 UTC
[Libguestfs] [PATCH 3/3] tests: Introduce test harness for running tests.
We would like to have a more flexible way to run tests, including
running them on an installed copy of libguestfs, running them in
parallel, and being able to express dependencies and ordering between
tests and test files properly.
Therefore introduce a test harness (generator/test-harness) program
which can run tests either from the locally built copy, or from an
installed copy of the tests (in @libdir@/guestfs/tests).
The test harness is backwards compatible on the command line, ie.
'make check', 'make -C inspector check-valgrind' etc. will still
work.
But in addition, you can now run the tests on an installed copy of
libguestfs by doing:
  cd /usr/lib/guestfs/tests
  ./test-harness
The test-harness script supports various options, see 'test-harness
--help'
for full details.
Other notable features:
 - Checking SKIP_* environment variables in tests is no longer
   necessary.  The test harness deals with these.
 - Every test runs in its own temporary directory.  There is no need
   to clean up output files.  On the other hand, tests must use
   $srcdir to refer to test data.
This is only implemented for a single directory at the moment
(ie. inspector/)
---
 .gitignore                                    |   3 +-
 Makefile.am                                   |   1 +
 common-rules.mk                               |   3 +
 generator/Makefile.am                         |   2 +
 generator/main.ml                             |   9 +
 generator/tests.ml                            | 560 ++++++++++++++++++++++++++
 generator/types.ml                            |   9 +
 inspector/Makefile.am                         |  17 +-
 inspector/test-virt-inspector-local-guests.sh |  25 ++
 inspector/test-virt-inspector.sh              |  12 +-
 inspector/test-xmllint.sh.in                  |   5 +
 11 files changed, 623 insertions(+), 23 deletions(-)
 create mode 100644 generator/tests.ml
 create mode 100755 inspector/test-virt-inspector-local-guests.sh
diff --git a/.gitignore b/.gitignore
index 86158eb..342b06a 100644
--- a/.gitignore
+++ b/.gitignore
@@ -26,6 +26,7 @@ cscope.out
 .libs
 Makefile
 Makefile.in
+tests.mk
 
 /.sc-*
 /ABOUT-NLS
@@ -262,7 +263,6 @@ Makefile.in
 /html/virt-tar-out.1.html
 /html/virt-v2v.1.html
 /html/virt-win-reg.1.html
-/inspector/actual-*.xml
 /inspector/stamp-virt-inspector.pod
 /inspector/test-xmllint.sh
 /inspector/virt-inspector
@@ -474,6 +474,7 @@ Makefile.in
 /sysprep/virt-sysprep.1
 /test.err
 /test.out
+/test-harness
 /tests/c-api/test-add-drive-opts
 /tests/c-api/test-add-libvirt-dom
 /tests/c-api/test-backend-settings
diff --git a/Makefile.am b/Makefile.am
index 097ba80..11b7a2d 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -201,6 +201,7 @@ EXTRA_DIST = \
 	logo/fish-5yrs.svg logo/fish-5yrs.png \
 	logo/virt-builder.svg \
 	m4/.gitignore \
+	test-harness \
 	tests/run-xml-to-junit.sh \
 	tests/run-xml-to-junit.xsl \
 	tmp/.gitignore \
diff --git a/common-rules.mk b/common-rules.mk
index 312107e..e9fc7c6 100644
--- a/common-rules.mk
+++ b/common-rules.mk
@@ -27,3 +27,6 @@ builddir     ?= @builddir@
 abs_builddir ?= @abs_builddir@
 srcdir       ?= @srcdir@
 abs_srcdir   ?= @abs_srcdir@
+
+# Tests directory.
+testsdir      = $(libdir)/guestfs/tests
diff --git a/generator/Makefile.am b/generator/Makefile.am
index 3716c77..610b078 100644
--- a/generator/Makefile.am
+++ b/generator/Makefile.am
@@ -52,6 +52,7 @@ sources = \
 	ruby.ml \
 	structs.ml \
 	structs.mli \
+	tests.ml \
 	tests_c_api.ml \
 	types.ml \
 	utils.ml \
@@ -71,6 +72,7 @@ objects = \
 	pr.cmo \
 	docstrings.cmo \
 	checks.cmo \
+	tests.cmo \
 	c.cmo \
 	xdr.cmo \
 	daemon.cmo \
diff --git a/generator/main.ml b/generator/main.ml
index c0ad146..3aef124 100644
--- a/generator/main.ml
+++ b/generator/main.ml
@@ -30,6 +30,7 @@ open Types
 open C
 open Xdr
 open Daemon
+open Tests
 open Tests_c_api
 open Fish
 open Ocaml
@@ -48,6 +49,8 @@ open Bindtests
 open Errnostring
 open Customize
 
+let (//) = Filename.concat
+
 let perror msg = function
   | Unix_error (err, _, _) ->
       eprintf "%s: %s\n" msg (error_message err)
@@ -214,6 +217,12 @@ Run it from the top source directory using the command
   output_to "customize/customize-synopsis.pod"
generate_customize_synopsis_pod;
   output_to "customize/customize-options.pod"
generate_customize_options_pod;
 
+  List.iter (
+    fun (dir, tests) ->
+      output_to (dir // "tests.mk") (generate_tests_mk dir tests)
+  ) tests;
+  output_to ~perm:0o555 "test-harness" generate_test_harness;
+
   (* Generate the list of files generated -- last. *)
   printf "generated %d lines of code\n" (get_lines_generated ());
   let files = List.sort compare (get_files_generated ()) in
diff --git a/generator/tests.ml b/generator/tests.ml
new file mode 100644
index 0000000..838f282
--- /dev/null
+++ b/generator/tests.ml
@@ -0,0 +1,560 @@
+(* libguestfs
+ * Copyright (C) 2014 Red Hat Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *)
+
+(* Please read generator/README first. *)
+
+open Printf
+
+open Types
+open Utils
+open Pr
+open Docstrings
+
+(* Tests and their dependencies. *)
+let tests = [
+  "inspector", {
+    check = [
+      "test-virt-inspector.sh";
+    ];
+    check_fast = [
+      "test-xmllint.sh";
+    ];
+    check_slow = [];
+    check_local_guests = [
+      "test-virt-inspector-local-guests.sh";
+    ];
+    check_data = [
+      "example-debian-netinst-cd.xml";
+      "example-debian.xml";
+      "example-fedora-dvd.xml";
+      "example-fedora-netinst-cd.xml";
+      "example-fedora.xml";
+      "example-rhel-6-dvd.xml";
+      "example-rhel-6-netinst-cd.xml";
+      "example-rhel-6.xml";
+      "example-ubuntu-live-cd.xml";
+      "example-ubuntu.xml";
+      "example-windows-2003-x64-cd.xml";
+      "example-windows-2003-x86-cd.xml";
+      "example-windows.xml";
+      "example-windows-xp-cd.xml";
+      "expected-debian.img.xml";
+      "expected-fedora.img.xml";
+      "expected-ubuntu.img.xml";
+      "expected-windows.img.xml";
+    ]
+  };
+
+]
+
+(* Generate the tests.mk files in each subdirectory. *)
+let generate_tests_mk dir tests () +  generate_header HashStyle GPLv2plus;
+
+  let all_test_files +    tests.check @ tests.check_fast @ tests.check_slow @
tests.check_local_guests
+  in
+
+  pr "localtestsdir = $(alltestsdir)/%s\n" dir;
+
+  if tests.check_data <> [] then (
+    pr "\n";
+    pr "localtests_DATA =";
+    List.iter (fun n -> pr " \\\n\t%s" n) tests.check_data;
+    pr "\n";
+  );
+
+  pr "\n";
+  pr "localtests_SCRIPTS =";
+  List.iter (fun n -> pr " \\\n\t%s" n) all_test_files;
+  pr "\n";
+
+  (* Create rules so that 'make -C dir check' etc will do something. *)
+  if tests.check <> [] then (
+    pr "\n";
+    (* Note that we cannot create a simple 'check' target since
+     * automake will (silently) overrule it.
+     *)
+    pr "TESTS_ENVIRONMENT = $(top_builddir)/run\n";
+    pr "TESTS = $(top_builddir)/test-harness\n";
+    pr "\n";
+    pr "check-valgrind:\n";
+    pr "\t$(top_builddir)/run $(top_builddir)/test-harness
--valgrind\n";
+    pr "\n";
+    pr "check-direct:\n";
+    pr "\t$(top_builddir)/run $(top_builddir)/test-harness
--direct\n";
+    pr "\n";
+    pr "check-valgrind-direct:\n";
+    pr "\t$(top_builddir)/run $(top_builddir)/test-harness --valgrind
--direct\n";
+    pr "\n";
+    pr "check-uml:\n";
+    pr "\t$(top_builddir)/run $(top_builddir)/test-harness --uml\n";
+    pr "\n";
+    pr "check-valgrind-uml:\n";
+    pr "\t$(top_builddir)/run $(top_builddir)/test-harness --valgrind
--uml\n";
+    pr "\n";
+    pr "check-with-upstream-qemu:\n";
+    pr "\t$(top_builddir)/run $(top_builddir)/test-harness
--with-upstream-qemu\n";
+    pr "\n";
+    pr "check-with-upstream-libvirt:\n";
+    pr "\t$(top_builddir)/run $(top_builddir)/test-harness
--with-upstream-libvirt\n";
+  );
+
+  if tests.check_fast <> [] then (
+    pr "\n";
+    pr "check-fast:\n";
+    pr "\t$(top_builddir)/run $(top_builddir)/test-harness --fast\n"
+  );
+
+  if tests.check_slow <> [] then (
+    pr "\n";
+    pr "check-slow:\n";
+    pr "\t$(top_builddir)/run $(top_builddir)/test-harness --slow\n"
+  );
+
+  if tests.check_local_guests <> [] then (
+    pr "\n";
+    pr "check-local-guests:\n";
+    pr "\t$(top_builddir)/run $(top_builddir)/test-harness
--local-guests\n";
+    pr "\n";
+    pr "check-valgrind-local-guests:\n";
+    pr "\t$(top_builddir)/run $(top_builddir)/test-harness --valgrind
--local-guests\n"
+  );
+
+  pr "\n";
+  pr "EXTRA_DIST += tests.mk\n"
+
+let generate_test_harness () +  pr "#!/bin/bash -\n";
+  generate_header HashStyle GPLv2plus;
+
+  pr "\
+unset CDPATH
+
+usage ()
+{
+    echo \"test-harness: Run the libguestfs test suite, or parts of
it.\"
+    echo
+    echo \"Usage:\"
+    echo \"  $0 [--options] [directory]\"
+    echo
+    echo \"Normally tests in the current directory are run.  If the
current\"
+    echo \"directory is the top level of the test suite then the whole
test\"
+    echo \"suite is run.  If the current directory is a leaf directory,
then\"
+    echo \"only tests in that directory are run.  If you specify a
directory\"
+    echo \"name on the command line, then we 'cd' into that
directory first.\"
+    echo
+    echo \"Options to select which tests to run:\"
+    echo \"  --fast       Run only test which don't need the
appliance\"
+    echo \"  --slow       Run only very long-running tests\"
+    echo \"(if neither --fast or --slow, then --fast + normal tests are
run)\"
+    echo \"  --local-guests\"
+    echo \"               Run tests that use locally installed guests
r/o\"
+    echo
+    echo \"Options to run the selected tests under different
conditions:\"
+    echo \"  --debug      Run tests with debugging enabled
(recommended)\"
+    echo \"  --valgrind   Run tests under valgrind\"
+    echo \"  --direct     Run tests using the direct backend\"
+    echo \"  --uml[=UML]  Run tests using the UML backend [default
~/d/linux-um/vmlinux]\"
+    echo \"  --with-upstream-qemu[=QEMU]\"
+    echo \"               Run tests using upstream qemu\"
+    echo \"                 [default
~/d/qemu/x86_64-softmmu/qemu-system-x86_64]\"
+    echo \"  --with-upstream-libvirt[=LIBVIRTDIR]\"
+    echo \"               Run tests using upstream libvirt [default
~/d/libvirt]\"
+    exit 0
+}
+
+TEMP=`getopt \\
+        -o '?' \\
+        -l
'help,debug,direct,fast,local-guests,slow,uml::,valgrind,with-upstream-libvirt::,with-upstream-qemu::'
\\
+        -- \"$@\"`
+if [ $? != 0 ]; then
+    echo \"$0: problem parsing the command line arguments\"
+    exit 1
+fi
+eval set -- \"$TEMP\"
+
+fast=0
+normal=0
+slow=0
+local_guests=0
+
+while true ; do
+    case \"$1\" in
+        --debug)
+            debug=1
+            shift
+            ;;
+        --direct)
+            direct=1
+            shift
+            ;;
+        --fast)
+            fast=1
+            shift
+            ;;
+        --local-guests)
+            local_guests=1
+            shift
+            ;;
+        --slow)
+            slow=1
+            shift
+            ;;
+        --uml)
+            if [ \"x$1\" != \"x\" ]; then
+                uml=$HOME/d/linux-um/vmlinux
+            else
+                uml=\"$1\"
+            fi
+            shift 2
+            ;;
+        --valgrind)
+            valgrind=1
+            shift
+            ;;
+        --with-upstream-libvirt)
+            if [ \"x$1\" != \"x\" ]; then
+                libvirt=$HOME/d/libvirt
+            else
+                libvirt=\"$1\"
+            fi
+            shift 2
+            ;;
+        --with-upstream-qemu)
+            if [ \"x$1\" != \"x\" ]; then
+                qemu=$HOME/d/qemu/x86_64-softmmu/qemu-system-x86_64
+            else
+                qemu=\"$1\"
+            fi
+            shift 2
+            ;;
+        --help)
+            usage
+            ;;
+        --)
+            shift
+            break
+            ;;
+        *)
+            echo \"$0: internal error ($1)\"
+            exit 1
+            ;;
+    esac
+done
+
+# Some combinations are not permitted.
+if [ $(( fast + slow + local_guests )) -gt 1 ]; then
+    echo \"$0: cannot use --fast, --slow and --local-guests options
together\"
+    exit 1
+fi
+
+# If none of the selection options are used, select fast + normal.
+if [ $(( fast + slow + local_guests )) -eq 0 ]; then
+    fast=1
+    normal=1
+fi
+
+# --direct and --uml cannot be combined.
+if [ -n \"$direct\" -a -n \"$uml\" ]; then
+    echo \"$0: cannot use --direct and --uml options together\"
+    exit 1
+fi
+
+# A single parameter on the command line means start the tests in
+# that directory.
+if [ \"$#\" -eq 1 ]; then
+    cd \"$1\"
+elif [ \"$#\" -gt 1 ]; then
+    echo \"$0: too many command line arguments\"
+    exit 1
+fi
+
+# Debugging.
+if [ -n \"$debug\" ]; then
+    export LIBGUESTFS_DEBUG=1
+    export LIBGUESTFS_TRACE=1
+fi
+
+# Direct.
+if [ -n \"$direct\" ]; then
+    export LIBGUESTFS_BACKEND=direct
+fi
+
+# UML
+if [ -n \"$uml\" ]; then
+    export LIBGUESTFS_BACKEND=uml
+    export LIBGUESTFS_HV=\"$uml\"
+fi
+
+# Valgrind - just check it exists here.
+if [ -n \"$valgrind\" ]; then
+    if ! valgrind --help >/dev/null 2>&1; then
+        echo \"$0: valgrind is not installed\"
+        exit 1
+    fi
+fi
+
+# Timeouts.
+timeout_period=4h
+timeout_kill=30s
+
+# Do we have Padraig's timeout utility (from coreutils)?
+if timeout --help >/dev/null 2>&1; then
+    # Must use the --foreground option (RHBZ#1025269).
+    if timeout --foreground 2 sleep 0 >/dev/null 2>&1; then
+        # Does this version of timeout have the -k option?  (Not on RHEL 6)
+        if timeout -k 10s 10s true >/dev/null 2>&1; then
+            timeout=\"timeout --foreground -k $timeout_kill
$timeout_period\"
+        fi
+    fi
+fi
+
+# QEMU.
+if [ -n \"$qemu\" ]; then
+    export LIBGUESTFS_HV=\"$qemu\"
+fi
+
+# libvirt.
+if [ -n \"$libvirt\" ]; then
+    libvirt=\"$libvirt/run\"
+    if [ ! -x \"$libvirt\" ]; then
+        echo \"$0: --with-libvirt: script '$libvirt' not
found\"
+        exit 1
+    fi
+fi
+
+# Count total tests, skipped, timed out, errors.
+total=0
+skipped=0
+timedout=0
+errors=0
+
+# Wrapper function to run one ordinary test.
+run_one_test ()
+{
+    if [ -n \"$valgrind\" ]; then
+        export VG=\"valgrind --vgdb=no
--log-file=/tmp/valgrind-%%q{T}-%%p.log --leak-check=full --error-exitcode=119
--suppressions=$abs_top_srcdir/valgrind-suppressions\"
+    else
+        unset VG
+    fi
+
+    # The test runs inside a temporary directory which is deleted
+    # as soon as the test finishes, UNLESS it fails in which case we
+    # leave it around for you to examine.
+    tmpdir=\"$(mktemp -d)\"
+
+    echo \"test-harness:\" \"$@\"
+    pushd \"$tmpdir\" >/dev/null
+    start_t=\"$(date +'%%s')\"
+    $timeout $libvirt \"$@\" >output 2>&1
+    r=$?
+    end_t=\"$(date +'%%s')\"
+    popd >/dev/null
+
+    ((total++))
+
+    case $r in
+        0)
+            echo \"test-harness:\" \"$@\" \"took $((
$end_t - $start_t )) second(s)\"
+            rm -r \"$tmpdir\"
+            ;;
+        77)
+            ((skipped++))
+            cat $tmpdir/output
+            rm -r \"$tmpdir\"
+            ;;
+        124)
+            ((timedout++))
+            cat $tmpdir/output
+            echo \"$0: command timed out after $timeout_period\"
+            rm -r \"$tmpdir\"
+            ;;
+        *)
+            ((errors++))
+            cat $tmpdir/output
+            echo \"$0: command failed with exit code $r\"
+            echo \"$0: test results left in $tmpdir\"
+            ;;
+    esac
+}
+
+# Wrapper function to run one 'local guests' test.
+run_local_guests_test ()
+{
+    run_one_test \"$1\" $( $top_builddir/pick-guests.pl 5 )
+}
+
+";
+
+  (* Define shell functions to run the tests in one subdirectory. *)
+  List.iter (
+    fun (dir, tests) ->
+      let dir_safe = replace_char dir '/' '_' in
+
+      (* Calculate a ../.. path to take us to the top build directory. *)
+      let dot_dot = ref ".." in
+      for i = 0 to String.length dir-1 do
+        if dir.[i] = '/' then dot_dot := !dot_dot ^ "/.."
+      done;
+      let dot_dot = !dot_dot in
+
+      pr "\
+run_%s ()
+{
+    echo \"test-harness: entering directory %s\"
+
+    top_builddir=\"$(cd %s; pwd)\"
+    # Was srcdir passed by automake?
+    if [ -n \"$srcdir\" -a \"$srcdir\" != \".\"
]; then
+        top_srcdir=\"(cd $top_builddir; cd $srcdir; pwd)\"
+    else
+        top_srcdir=\"$top_builddir\"
+    fi
+    builddir=\"$top_builddir/%s\"
+    srcdir=\"$top_srcdir/%s\"
+    abs_top_srcdir=\"$top_srcdir\"
+    abs_top_builddir=\"$top_builddir\"
+    abs_srcdir=\"$srcdir\"
+    abs_builddir=\"$builddir\"
+    export srcdir builddir top_srcdir top_builddir
+    export abs_srcdir abs_builddir abs_top_srcdir abs_top_builddir
+
+    # XXX Not set correctly yet.
+    datadir=\"$top_builddir/tests/guests\"
+    export datadir
+
+" dir dir_safe dot_dot dir dir;
+
+      let emit_tests run_wrapper +        List.iter (
+          fun name ->
+            let skip_name = replace_char name '-' '_' in
+            let skip_name = replace_char skip_name '.' '_' in
+            let skip_name = "SKIP_" ^ String.uppercase skip_name in
+            pr "        if [ -n \"$%s\" ]; then\n"
skip_name;
+            pr "            ((skipped++))\n";
+            pr "            echo \"test-harness: %s
skipped\"\n" name;
+            pr "        else\n";
+            pr "            %s \"%s\"\n" run_wrapper name;
+            pr "        fi\n";
+        )
+      in
+
+      if tests.check_fast <> [] then (
+        pr "    if [ \"$fast\" -eq 1 ]; then\n";
+        emit_tests "run_one_test" tests.check_fast;
+        pr "    fi\n"
+      );
+      if tests.check <> [] then (
+        pr "    if [ \"$normal\" -eq 1 ]; then\n";
+        emit_tests "run_one_test" tests.check;
+        pr "    fi\n"
+      );
+      if tests.check_slow <> [] then (
+        pr "    if [ \"$slow\" -eq 1 ]; then\n";
+        emit_tests "run_one_test" tests.check_slow;
+        pr "    fi\n"
+      );
+      if tests.check_local_guests <> [] then (
+        pr "    if [ \"$local_guests\" -eq 1 ]; then\n";
+        emit_tests "run_local_guests_test" tests.check_local_guests;
+        pr "    fi\n"
+      );
+      pr "\n";
+      pr "    echo \"test-harness: leaving directory
%s\"\n" dir;
+      pr "}\n";
+      pr "\n"
+  ) tests;
+
+  (* Define a shell function 'run_all_tests' which runs all of the
+   * above tests.
+   *)
+  pr "run_all_tests ()\n";
+  pr "{\n";
+  List.iter (
+    fun (dir, _) ->
+      let dir_safe = replace_char dir '/' '_' in
+      pr "    pushd %s >/dev/null\n" dir;
+      pr "    run_%s\n" dir_safe;
+      pr "    popd >/dev/null\n";
+  ) tests;
+  pr "}\n";
+  pr "\n";
+
+  (* Define a shell function 'run_subdirectory_tests' which has to
+   * work out which subdir it is in, then run only the tests from that
+   * subdirectory.
+   *)
+  pr "run_subdirectory_tests ()\n";
+  pr "{\n";
+  pr "    b=\"$(basename $(pwd))\"\n";
+  pr "    if false; then : ;\n";
+  List.iter (
+    fun (dir, tests) ->
+      let dir_safe = replace_char dir '/' '_' in
+
+      (* Match just the last element of the path with the basename ... *)
+      let dir_base +        try
+          let i = String.rindex dir '/' in
+          String.sub dir (i+1) (String.length dir - (i+1))
+        with Not_found -> dir in
+      (* ... and any file in the directory. *)
+      let any_file +        if tests.check <> [] then List.hd tests.check
+        else if tests.check_fast <> [] then List.hd tests.check_fast
+        else if tests.check_slow <> [] then List.hd tests.check_slow
+        else if tests.check_local_guests <> [] then
+          List.hd tests.check_local_guests
+        else (
+          assert (tests.check_data <> []);
+          List.hd tests.check_data
+        ) in
+
+      pr "    elif [ \"$b\" = \"%s\" -a -f
\"%s\" ]; then\n" dir_base any_file;
+      pr "        run_%s\n" dir_safe;
+  ) tests;
+  pr "    else\n";
+  pr "        echo \"$0: current directory ($b) is not a libguestfs
test directory.\"\n";
+  pr "        exit 1\n";
+  pr "    fi\n";
+  pr "}\n";
+  pr "\n";
+
+  pr "\
+# Are we in the top-level directory of the test suite, or
+# in a subdirectory?  Top-level means run the whole suite.
+if [ -x test-harness -a -d inspector ]; then
+    run_all_tests
+else
+    run_subdirectory_tests
+fi
+
+echo \"--------------------------------------------------\"
+echo \"Test summary\"
+echo \"--------------------------------------------------\"
+echo \"Total tests run . . . . . .  $total\"
+echo \"Errors  . . . . . . . . . .  $errors\"
+echo \"Timed out . . . . . . . . .  $timedout\"
+echo \"Skipped . . . . . . . . . .  $skipped\"
+echo \"--------------------------------------------------\"
+if [ $errors -gt 0 -o $timedout -gt 0 ]; then
+    exit 1
+fi
+"
diff --git a/generator/types.ml b/generator/types.ml
index 63aa235..3f1f682 100644
--- a/generator/types.ml
+++ b/generator/types.ml
@@ -207,6 +207,15 @@ type fish_output_t    | FishOutputOctal       (* for int
return, print in octal *)
   | FishOutputHexadecimal (* for int return, print in hex *)
 
+type test = {
+  check : string list;
+  (* "fast" here means the appliance is not needed *)
+  check_fast : string list;
+  check_slow : string list;
+  check_local_guests : string list;
+  check_data : string list;
+}
+
 (* See guestfs(3)/EXTENDING LIBGUESTFS. *)
 type c_api_tests = (c_api_test_init * c_api_test_prereq * c_api_test *
c_api_test_cleanup) list
 and c_api_test diff --git a/inspector/Makefile.am b/inspector/Makefile.am
index 86e0cd7..2f51d79 100644
--- a/inspector/Makefile.am
+++ b/inspector/Makefile.am
@@ -17,6 +17,8 @@
 
 include $(top_srcdir)/subdir-rules.mk
 
+generator_built = tests.mk
+
 example_xml = \
 	example-debian.xml \
 	example-fedora.xml \
@@ -38,6 +40,7 @@ EXTRA_DIST = \
 	expected-fedora.img.xml \
 	expected-ubuntu.img.xml \
 	expected-windows.img.xml \
+	test-virt-inspector-local-guests.sh \
 	test-virt-inspector.sh \
 	test-xmllint.sh.in \
 	virt-inspector.pod
@@ -100,16 +103,4 @@ stamp-virt-inspector.pod: virt-inspector.pod
 	  $<
 	touch $@
 
-TESTS_ENVIRONMENT = $(top_builddir)/run --test
-TESTS = test-virt-inspector.sh
-if HAVE_XMLLINT
-TESTS += test-xmllint.sh
-endif
-
-check-valgrind:
-	$(MAKE) TESTS="test-virt-inspector.sh" VG="$(top_builddir)/run
@VG@" check
-
-check-valgrind-local-guests:
-	for g in $(GUESTS); do \
-	  $(top_builddir)/run --test @VG@ ./virt-inspector -c
"$(libvirt_ro_uri)" -d "$$g" || exit $$?; \
-	done
+-include tests.mk
diff --git a/inspector/test-virt-inspector-local-guests.sh
b/inspector/test-virt-inspector-local-guests.sh
new file mode 100755
index 0000000..9af378a
--- /dev/null
+++ b/inspector/test-virt-inspector-local-guests.sh
@@ -0,0 +1,25 @@
+#!/bin/bash -
+# libguestfs virt-inspector test script
+# Copyright (C) 2012-2014 Red Hat Inc.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+
+export LANG=C
+set -e
+set -x
+
+for g in "$@"; do
+    virt-inspector -c "$libvirt_ro_uri" -d "$g" || exit 1
+done
diff --git a/inspector/test-virt-inspector.sh b/inspector/test-virt-inspector.sh
index 6fab253..58f8d47 100755
--- a/inspector/test-virt-inspector.sh
+++ b/inspector/test-virt-inspector.sh
@@ -20,23 +20,17 @@ export LANG=C
 set -e
 set -x
 
-# Allow this test to be skipped.
-if [ -n "$SKIP_TEST_VIRT_INSPECTOR_SH" ]; then
-    echo "$0: skipping test because SKIP_TEST_VIRT_INSPECTOR_SH is
set."
-    exit 77
-fi
-
 # ntfs-3g can't set UUIDs right now, so ignore just that <uuid>.
 diff_ignore="-I
<uuid>[0-9A-F][0-9A-F][0-9A-F][0-9A-F][0-9A-F][0-9A-F][0-9A-F][0-9A-F][0-9A-F][0-9A-F][0-9A-F][0-9A-F][0-9A-F][0-9A-F][0-9A-F][0-9A-F]</uuid>"
 
-for f in ../tests/guests/{debian,fedora,ubuntu,windows}.img; do
+for f in $datadir/{debian,fedora,ubuntu,windows}.img; do
     # Ignore zero-sized windows.img if ntfs-3g is not installed.
     if [ -s "$f" ]; then
         b=$(basename "$f" .xml)
-	$VG virt-inspector -a "$f" > "actual-$b.xml"
+	$VG virt-inspector -a "$f" > actual-$b.xml
         # This 'diff' command will fail (because of -e option) if there
         # are any differences.
-        diff -ur $diff_ignore "expected-$b.xml"
"actual-$b.xml"
+        diff -ur $diff_ignore $srcdir/expected-$b.xml actual-$b.xml
     fi
 done
 
diff --git a/inspector/test-xmllint.sh.in b/inspector/test-xmllint.sh.in
index aef5ebc..f1195fd 100755
--- a/inspector/test-xmllint.sh.in
+++ b/inspector/test-xmllint.sh.in
@@ -19,6 +19,11 @@
 export LANG=C
 set -e
 
+if ! "@XMLLINT@" --version >/dev/null 2>&1; then
+    echo "$0: test skipped before xmllint is not installed"
+    exit 77
+fi
+
 for f in $srcdir/example-*.xml; do
     @XMLLINT@ --noout --relaxng $srcdir/virt-inspector.rng $f
 done
-- 
2.0.4
Pino Toscano
2014-Sep-17  16:18 UTC
Re: [Libguestfs] [PATCH 1/3] tests: Don't use relative paths to binaries in tests.
On Tuesday 16 September 2014 15:05:56 Richard W.M. Jones wrote:> All tests run under the ./run binary. For a long time the ./run > binary has set the $PATH environment variable to contain all of the > directories with binaries in them. > > Therefore there is no reason to use ../fish/guestfish instead of just > plain guestfish (and the same applies to other built binaries).LGTM, makes sense. -- Pino Toscano
Possibly Parallel Threads
- [PATCH 0/3] tests: Define common test functions.
- [PATCH 0/3] misc tests-only changes
- [PATCH v3 01/16] tests: Introduce test harness for running tests.
- [PATCH v2 00/14] tests: Introduce test harness for running tests.
- [PATCH v4 00/17] tests: Introduce test harness for running tests.