---
tests/Makefile.am | 3 +
tests/test-python-thread-model.sh | 91 +++++++++++++++++++++++++++++++
tests/python-thread-model.py | 50 +++++++++++++++++
3 files changed, 144 insertions(+)
diff --git a/tests/Makefile.am b/tests/Makefile.am
index 79be5639..2aa9e14c 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -1020,15 +1020,18 @@ TESTS += \
test-python.sh \
test-python-exception.sh \
test-python-export-name.sh \
+ test-python-thread-model.sh \
test-shebang-python.sh \
$(NULL)
EXTRA_DIST += \
python-exception.py \
python-export-name.py \
+ python-thread-model.py \
shebang.py \
test-python-exception.sh \
test-python-export-name.sh \
test-python-plugin.py \
+ test-python-thread-model.sh \
test-python.sh \
test-shebang-python.sh \
test_python.py \
diff --git a/tests/test-python-thread-model.sh b/tests/test-python-thread-model.sh
new file mode 100755
index 00000000..e16ff154
--- /dev/null
+++ b/tests/test-python-thread-model.sh
@@ -0,0 +1,91 @@
+#!/usr/bin/env bash
+# nbdkit
+# Copyright (C) 2018-2020 Red Hat Inc.
+#
+# 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.
+
+source ./functions.sh
+set -e
+set -x
+
+SCRIPT="$SRCDIR/python-thread-model.py"
+if ! test -d "$SRCDIR" || ! test -f "$SCRIPT"; then
+ echo "$0: could not locate python-thread-model.py"
+ exit 1
+fi
+
+# Python has proven very difficult to valgrind, therefore it is disabled.
+if [ "$NBDKIT_VALGRIND" = "1" ]; then
+ echo "$0: skipping Python test under valgrind."
+ exit 77
+fi
+
+requires nbdsh --version
+
+out=test-python-thread-model.out
+pid=test-python-thread-model.pid
+sock=`mktemp -u`
+files="$out $pid $sock"
+rm -f $files
+cleanup_fn rm -f $files
+
+# Check the plugin is loadable and the effective thread model is parallel.
+nbdkit python $SCRIPT --dump-plugin >$out
+grep "^thread_model=parallel" $out
+
+start_nbdkit -P $pid -U $sock python $SCRIPT
+
+export sock
+nbdsh -c '
+import os
+import time
+
+h.connect_unix (os.environ["sock"])
+
+# We should be able to issue multiple requests in parallel,
+# and the total time taken should not be much more than 10 seconds
+# because all sleeps in the plugin should happen in parallel.
+start_t = time.time()
+for i in range (10):
+ buf = nbd.Buffer (512)
+ h.aio_pread (buf, 0)
+
+while h.aio_in_flight() > 0:
+ h.poll(-1)
+end_t = time.time()
+
+t = end_t - start_t
+print (t)
+
+# Since we launched 10 requests, if we serialized on them we
+# would have waited at least 100 seconds. We would expect to
+# wait around 10 seconds, but for flexibility on slow servers
+# any test < 100 should be fine.
+assert t <= 50
+'
diff --git a/tests/python-thread-model.py b/tests/python-thread-model.py
new file mode 100644
index 00000000..67879e04
--- /dev/null
+++ b/tests/python-thread-model.py
@@ -0,0 +1,50 @@
+# nbdkit
+# Copyright (C) 2018-2020 Red Hat Inc.
+#
+# 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.
+
+# Python plugin which uses the parallel thread model. Note that the
+# cpython implementation of time.sleep releases the GIL (see
+# Modules/timemodule.c:pysleep)
+
+import nbdkit
+import time
+
+def thread_model():
+ return nbdkit.THREAD_MODEL_PARALLEL
+
+def open(readonly):
+ return {}
+
+def get_size(h):
+ return 512
+
+def pread(h, count, offset):
+ time.sleep(10)
+ return bytearray(count)
--
2.27.0