Codify the testing procedure mentioned during the addition of --threads
into a full-blown member of 'make check'. With the delay values I
chose, the test requires at least 5 seconds to complete; I don't know
if it is worth trying to fine-tune it to run faster while still being
robust in the presence of a heavy load.
This requires a slight refactoring of the Makefile.am to provide
file-data to more consumers.
Signed-off-by: Eric Blake <eblake(a)redhat.com>
---
configure.ac | 4 +++
tests/Makefile.am | 29 +++++++++++++-----
tests/test-parallel-file.sh | 71 +++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 96 insertions(+), 8 deletions(-)
create mode 100755 tests/test-parallel-file.sh
diff --git a/configure.ac b/configure.ac
index 130ab78..68b0938 100644
--- a/configure.ac
+++ b/configure.ac
@@ -407,6 +407,10 @@ dnl Check for guestfish (only needed for some of the tests).
AC_CHECK_PROG([GUESTFISH], [guestfish], [guestfish], [no])
AM_CONDITIONAL([HAVE_GUESTFISH], [test "x$GUESTFISH" != "xno"])
+dnl Check for qemu-io (only needed for some of the tests).
+AC_CHECK_PROG([QEMU_IO], [qemu-io], [qemu-io], [no])
+AM_CONDITIONAL([HAVE_QEMU_IO], [test "x$QEMU_IO" != "xno"])
+
dnl See plugins/vddk/README.VDDK.
AC_CHECK_SIZEOF([size_t])
AS_IF([test "x$ac_cv_sizeof_size_t" = "x4"],[bits=32],[bits=64])
diff --git a/tests/Makefile.am b/tests/Makefile.am
index 6522e05..c5429cb 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -47,6 +47,7 @@ EXTRA_DIST = \
test-ipv4.sh \
test_ocaml_plugin.ml \
test-ocaml.c \
+ test-parallel-file.sh \
test.pl \
test.py \
test.rb \
@@ -138,7 +139,26 @@ check_DATA += pki/.stamp
pki/.stamp: $(srcdir)/make-pki.sh
$(srcdir)/make-pki.sh
-# In-depth tests need libguestfs, since that is a convenient way to
+if HAVE_PLUGINS
+# Common data shared by multiple tests
+check_DATA += file-data
+MAINTAINERCLEANFILES += file-data
+file-data:
+ rm -f $@ $@-t
+ for f in `seq 1 512`; do echo -ne '\x01\x02\x03\x04\x05\x06\x07\x08'; done >
$@-t
+ mv $@-t $@
+
+# While most tests need libguestfs, testing parallel I/O is easier when
+# using qemu-io to kick off asynchronous requests.
+if HAVE_QEMU_IO
+TESTS_ENVIRONMENT += QEMU_IO=$(QEMU_IO)
+TESTS += test-parallel-file.sh
+endif HAVE_QEMU_IO
+
+endif HAVE_PLUGINS
+
+
+# Most in-depth tests need libguestfs, since that is a convenient way to
# drive qemu.
if HAVE_LIBGUESTFS
@@ -185,18 +205,11 @@ test_oldstyle_LDADD = libtest.la $(LIBGUESTFS_LIBS)
# file plugin test.
check_PROGRAMS += test-file
TESTS += test-file
-check_DATA += file-data
-MAINTAINERCLEANFILES += file-data
test_file_SOURCES = test-file.c test.h
test_file_CFLAGS = $(WARNINGS_CFLAGS) $(LIBGUESTFS_CFLAGS)
test_file_LDADD = libtest.la $(LIBGUESTFS_LIBS)
-file-data:
- rm -f $@ $@-t
- for f in `seq 1 512`; do echo -ne '\x01\x02\x03\x04\x05\x06\x07\x08'; done >
$@-t
- mv $@-t $@
-
# gzip plugin test.
if HAVE_ZLIB
if HAVE_GUESTFISH
diff --git a/tests/test-parallel-file.sh b/tests/test-parallel-file.sh
new file mode 100755
index 0000000..63b5684
--- /dev/null
+++ b/tests/test-parallel-file.sh
@@ -0,0 +1,71 @@
+#!/bin/bash -
+# nbdkit
+# Copyright (C) 2017 Red Hat Inc.
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met:
+#
+# * Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+#
+# * Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+#
+# * Neither the name of Red Hat nor the names of its contributors may be
+# used to endorse or promote products derived from this software without
+# specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY RED HAT AND CONTRIBUTORS ''AS IS'' AND
+# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+# PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL RED HAT OR
+# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+# USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+# OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+# SUCH DAMAGE.
+
+# Makefile sets $QEMU_IO and builds file-data, but it's also nice if the
+# script runs again standalone afterwards for diagnosing any failures
+test -f file-data || { echo "Missing file-data"; exit 77; }
+: ${QEMU_IO=qemu-io}
+
+# Sanity check that qemu-io can issue parallel requests
+$QEMU_IO -f raw -c "aio_read 0 1" -c "aio_write -P 2 1 1" -c
aio_flush \
+ file-data || exit 77;
+
+# Set up the file plugin to delay both reads and writes (for a good chance
+# that parallel requests are in flight), and with reads longer than writes
+# (to more easily detect if out-of-order completion happens). This test
+# may have spurious failures under heavy loads on the test machine, where
+# tuning the delays may help.
+
+trap 'rm -f test-parallel-file.out' 0 1 2 3 15
+
+# With --threads=1, the read should complete first because it was issued first
+nbdkit -v -t 1 -U - file file=file-data rdelay=2 wdelay=1 --run '
+ $QEMU_IO -f raw -c "aio_read 0 1" -c "aio_write -P 2 1 1" -c
aio_flush $nbd
+' | tee test-parallel-file.out
+if test "$(grep '1/1' test-parallel-file.out)" != \
+"read 1/1 bytes at offset 0
+wrote 1/1 bytes at offset 1"; then
+ exit 1
+fi
+
+# With default --threads, the faster write should complete first
+nbdkit -v -U - file file=file-data rdelay=2 wdelay=1 --run '
+ $QEMU_IO -f raw -c "aio_read 0 1" -c "aio_write -P 2 1 1" -c
aio_flush $nbd
+' | tee test-parallel-file.out
+if test "$(grep '1/1' test-parallel-file.out)" != \
+"wrote 1/1 bytes at offset 1
+read 1/1 bytes at offset 0"; then
+ exit 1
+fi
+
+exit 0
--
2.13.6