diff options
| author | Alan Conway <aconway@apache.org> | 2008-02-08 15:01:30 +0000 |
|---|---|---|
| committer | Alan Conway <aconway@apache.org> | 2008-02-08 15:01:30 +0000 |
| commit | 2b1f0e248873a041f7fe5bda724a0d7e13617372 (patch) | |
| tree | 44d734f4c475a9eada3df0dd002e79de450e3ffa | |
| parent | 942b577d5047b3617d00a375235400e275bfe1ff (diff) | |
| download | qpid-python-2b1f0e248873a041f7fe5bda724a0d7e13617372.tar.gz | |
Refactored verify scripts, added verify for python Examples.
To verify an example: <qpid-trunk>/bin/verify <example-dir>
See comments in bin/verify for more details.
Changes:
- Each example dir has its own verify script and verify.in.
- Added sys.stdout.flush() to som python examples so verify can tell when they're ready.
- Made python examples svn:executable.
- C++ examples/Makefile.am runs python examples
git-svn-id: https://svn.apache.org/repos/asf/incubator/qpid/trunk/qpid@619903 13f79535-47bb-0310-9956-ffa450edef68
27 files changed, 252 insertions, 120 deletions
diff --git a/bin/verify b/bin/verify new file mode 100755 index 0000000000..fc86c3d896 --- /dev/null +++ b/bin/verify @@ -0,0 +1,74 @@ +#!/bin/sh +# Driver script to verify installed examples (also used for build tests.) +# +# Usage: verify example_dir [ example_dir ...] +# Where each example_dir must contain a verify sub-script to include. +# +# If $QPIDD is set, run a private QPIDD and use it. +# If $QPID_HOST or $QPID_PORT are set, use them to connect. +# + +export QPID_DATA_DIR= + +cleanup() { + test -n "$QPIDD" && $QPIDD -q # Private broker + kill %% > /dev/null 2>&1 # Leftover background jobs +} + +trap cleanup EXIT + +ARGS="${QPID_HOST:-localhost} $QPID_PORT" + +outfile() { echo $1.out; } + +fail() { test -n "$*" && echo $* 1>&2 ; FAIL=1; return 1; } + +client() { "$@" $ARGS > `outfile $*` || fail; } + +clients() { for cmd in "$@"; do client $cmd; done; } + +waitfor() { until grep -a -l "$2" $1 >/dev/null 2>&1 ; do sleep 1 ; done ; } + +background() { + pattern=$1; shift + out=`outfile $*` + eval "$* $ARGS > $out &" || { fail; return 1; } + waitfor $out "$pattern" +} + +outputs() { + wait 2> /dev/null # Wait for all backgroud processes to complete + for f in "$@"; do + { echo "==== $f"; eval "cat $f"; } >> verify.out || fail + done +} + +verify() { + FAIL= + dir=$1 + cd $dir || return 1 + rm -f *.out + { source ./verify && diff -ac verify.out verify.in ; } || fail + test -z "$FAIL" && rm -f *.out + return $FAIL +} + +HEX="[a-fA-F0-9]" +remove_uuid() { + sed "s/$HEX\{8\}-$HEX\{4\}-$HEX\{4\}-$HEX\{4\}-$HEX\{12\}//g" $* +} +remove_uuid64() { + sed 's/[-A-Za-z0-9_]\{22\}==$//' $* +} + +# Start private broker if QPIDD is set. +if [ -n "$QPIDD" ] ; then + export QPID_PORT=`$QPIDD -dp0` || { echo "Cannot start $QPIDD" ; exit 1; } + trap "$QPIDD -q" EXIT +fi + +for dir in "$@"; do + echo -n "$dir : " + if ( verify $dir; ) then echo "PASS"; else echo "FAIL"; RET=1; fi + done +exit $RET diff --git a/cpp/examples/Makefile.am b/cpp/examples/Makefile.am index 933a6de26a..f4882d2c7d 100644 --- a/cpp/examples/Makefile.am +++ b/cpp/examples/Makefile.am @@ -17,7 +17,11 @@ nobase_pkgdata_DATA= \ examples/direct/listener.cpp \ examples/direct/declare_queues.cpp -VERIFY_SCRIPT=verify \ +VERIFY_SCRIPT= \ + examples/request-response/verify \ + examples/fanout/verify \ + examples/pub-sub/verify \ + examples/direct/verify \ examples/request-response/verify.in \ examples/fanout/verify.in \ examples/pub-sub/verify.in \ @@ -35,7 +39,17 @@ clean-local: abs_top_builddir=@abs_top_builddir@ abs_top_srcdir=@abs_top_srcdir@ -VERIFY=$(abs_top_srcdir)/examples/verify +VERIFY=$(top_srcdir)/../bin/verify +PYTHON_EXAMPLES=$(top_srcdir)/../python/examples +EXAMPLES= \ + examples/pub-sub \ + examples/fanout \ + examples/direct \ + examples/request-response \ + $(PYTHON_EXAMPLES)/pubsub \ + $(PYTHON_EXAMPLES)/fanout \ + $(PYTHON_EXAMPLES)/direct \ + $(PYTHON_EXAMPLES)/request-response # Build the examples in the source tree. all-local: @@ -43,7 +57,7 @@ all-local: # Verify the examples in the buid tree. check-local: all-local - cd examples && QPID_DATA_DIR= QPIDD=$(abs_top_builddir)/src/qpidd $(VERIFY) + QPID_DATA_DIR= QPIDD=$(top_builddir)/src/qpidd $(VERIFY) $(EXAMPLES) # Build and verify the installed examples, then clean up to avoid rpmbuild warnings. EXAMPLE_FLAGS=-I$(DESTDIR)$(includedir) -L$(DESTDIR)$(libdir) -Wl,-rpath,$(DESTDIR)$(libdir) diff --git a/cpp/examples/examples/direct/verify b/cpp/examples/examples/direct/verify new file mode 100644 index 0000000000..ac0464ef80 --- /dev/null +++ b/cpp/examples/examples/direct/verify @@ -0,0 +1,3 @@ +# See https://svn.apache.org/repos/asf/incubator/qpid/trunk/qpid/bin/verify +clients ./declare_queues ./direct_producer ./listener +outputs ./declare_queues.out ./direct_producer.out ./listener.out diff --git a/cpp/examples/examples/fanout/verify b/cpp/examples/examples/fanout/verify new file mode 100644 index 0000000000..9febd5777c --- /dev/null +++ b/cpp/examples/examples/fanout/verify @@ -0,0 +1,2 @@ +clients ./declare_queues ./fanout_producer ./listener +outputs ./declare_queues.out ./fanout_producer.out ./listener.out diff --git a/cpp/examples/examples/pub-sub/verify b/cpp/examples/examples/pub-sub/verify new file mode 100644 index 0000000000..3589a4c9da --- /dev/null +++ b/cpp/examples/examples/pub-sub/verify @@ -0,0 +1,4 @@ +# See https://svn.apache.org/repos/asf/incubator/qpid/trunk/qpid/bin/verify +background "Listening" ./topic_listener +clients ./topic_publisher +outputs ./topic_publisher.out "topic_listener.out | remove_uuid | sort" diff --git a/cpp/examples/examples/request-response/verify b/cpp/examples/examples/request-response/verify new file mode 100644 index 0000000000..a8c942b5e6 --- /dev/null +++ b/cpp/examples/examples/request-response/verify @@ -0,0 +1,5 @@ +# See https://svn.apache.org/repos/asf/incubator/qpid/trunk/qpid/bin/verify +background "Waiting" ./server +clients ./client +kill %% # Must kill the server. +outputs "./client.out | remove_uuid" " server.out | remove_uuid" diff --git a/cpp/examples/verify b/cpp/examples/verify deleted file mode 100755 index 9271d8d972..0000000000 --- a/cpp/examples/verify +++ /dev/null @@ -1,90 +0,0 @@ -#!/bin/sh -# Run from the installed examples/ dir with a full path to this script. -# If $QPIDD is set, run a private QPIDD and use it. -# If $QPID_HOST or $QPID_PORT are set, use them to connect. - -DIR=$PWD -SRC=`dirname $0 | sed 's|^\([^/].*\)|'$PWD'/\1|'`/examples - -# Start private broker if QPIDD is set. -if [ -n "$QPIDD" ] ; then - export QPID_PORT=`$QPIDD -dp0` || { echo "Cannot start $QPIDD" ; exit 1; } - trap "$QPIDD -q" EXIT -fi - -cleanup() { - test -n "$QPIDD" && $QPIDD -q # Private broker - kill %% > /dev/null 2>&1 # Leftover background jobs -} - -trap cleanup EXIT - -ARGS="${QPID_HOST:-localhost} $QPID_PORT" - - -client() { "$@" $ARGS > $1.out; } -clients() { for cmd in "$@"; do client $cmd; done; } - -waitfor() { until grep -a -l "$2" $1 >/dev/null 2>&1 ; do sleep 1 ; done ; } - -background() { - pattern=$1; shift - eval "$@ $ARGS > $1.out &" - waitfor $1.out $pattern -} - -outputs() { - wait 2> /dev/null # Wait for all backgroud processes to complete - for f in "$@"; do - { echo "==== $f"; eval "cat $f"; } >> verify.out ; - done -} - -verify() { - dir=$1 - func=`echo $dir | tr - _` - cd $dir || return 1 - rm -f *.out - { $func && diff -ac verify.out $SRC/$dir/verify.in ; } || return 1 - rm -f *.out -} - -HEX="[a-fA-F0-9]" -remove_uuid() { - sed "s/$HEX\{8\}-$HEX\{4\}-$HEX\{4\}-$HEX\{4\}-$HEX\{12\}//g" $* -} - -# Scripts for each example - -direct() { - clients ./declare_queues ./direct_producer ./listener - outputs ./declare_queues.out ./direct_producer.out ./listener.out -} - -fanout() { - clients ./declare_queues ./fanout_producer ./listener - outputs ./declare_queues.out ./fanout_producer.out ./listener.out -} - -pub_sub() { - background "Listening" ./topic_listener - clients ./topic_publisher - outputs ./topic_publisher.out "topic_listener.out | remove_uuid | sort" -} - -request_response() { - background "Waiting" ./server - clients ./client - kill %% # Must kill the server. - outputs "./client.out | remove_uuid" " server.out | remove_uuid" -} - -# Main -EXAMPLES=${*:-direct fanout pub-sub request-response} -for ex in $EXAMPLES ; do - if ( verify $ex; ) then echo "PASS: $ex"; else - echo "FAIL: $ex"; RET=1; fi -done - -exit $RET - diff --git a/python/examples/direct/declare_queues.py b/python/examples/direct/declare_queues.py index 0160f66a1d..f39f0c3349 100644..100755 --- a/python/examples/direct/declare_queues.py +++ b/python/examples/direct/declare_queues.py @@ -9,6 +9,7 @@ """ import qpid +import sys from qpid.client import Client from qpid.content import Content from qpid.queue import Empty @@ -17,8 +18,8 @@ from qpid.queue import Empty # Set parameters for login -host="127.0.0.1" -port=5672 +host=len(sys.argv) > 1 and sys.argv[1] or "127.0.0.1" +port=len(sys.argv) > 2 and int(sys.argv[2]) or 5672 amqp_spec="/usr/share/amqp/amqp.0-10-preview.xml" user="guest" password="guest" diff --git a/python/examples/direct/direct_consumer.py b/python/examples/direct/direct_consumer.py index 38b1ba30a0..85c1db0a93 100644..100755 --- a/python/examples/direct/direct_consumer.py +++ b/python/examples/direct/direct_consumer.py @@ -7,6 +7,7 @@ """ import qpid +import sys from qpid.client import Client from qpid.content import Content from qpid.queue import Empty @@ -16,8 +17,8 @@ from qpid.queue import Empty # Set parameters for login -host="127.0.0.1" -port=5672 +host=len(sys.argv) > 1 and sys.argv[1] or "127.0.0.1" +port=len(sys.argv) > 2 and int(sys.argv[2]) or 5672 amqp_spec="/usr/share/amqp/amqp.0-10-preview.xml" user="guest" password="guest" diff --git a/python/examples/direct/direct_producer.py b/python/examples/direct/direct_producer.py index ff662477ce..2c07bfd8e7 100644..100755 --- a/python/examples/direct/direct_producer.py +++ b/python/examples/direct/direct_producer.py @@ -7,6 +7,7 @@ """ import qpid +import sys from qpid.client import Client from qpid.content import Content from qpid.queue import Empty @@ -15,8 +16,8 @@ from qpid.queue import Empty # Set parameters for login -host="127.0.0.1" -port=5672 +host=len(sys.argv) > 1 and sys.argv[1] or "127.0.0.1" +port=len(sys.argv) > 2 and int(sys.argv[2]) or 5672 amqp_spec="/usr/share/amqp/amqp.0-10-preview.xml" user="guest" password="guest" diff --git a/python/examples/direct/listener.py b/python/examples/direct/listener.py index 8324cc76a6..2dbd502fa0 100644..100755 --- a/python/examples/direct/listener.py +++ b/python/examples/direct/listener.py @@ -8,6 +8,7 @@ """ import qpid +import sys from qpid.client import Client from qpid.content import Content from qpid.queue import Empty @@ -40,8 +41,8 @@ class Receiver: # Set parameters for login -host="127.0.0.1" -port=5672 +host=len(sys.argv) > 1 and sys.argv[1] or "127.0.0.1" +port=len(sys.argv) > 2 and int(sys.argv[2]) or 5672 amqp_spec="/usr/share/amqp/amqp.0-10-preview.xml" user="guest" password="guest" diff --git a/python/examples/direct/verify b/python/examples/direct/verify new file mode 100644 index 0000000000..01d81a18a1 --- /dev/null +++ b/python/examples/direct/verify @@ -0,0 +1,3 @@ +# See https://svn.apache.org/repos/asf/incubator/qpid/trunk/qpid/bin/verify +clients ./declare_queues.py ./direct_producer.py ./direct_consumer.py +outputs ./declare_queues.py.out ./direct_producer.py.out ./direct_consumer.py.out diff --git a/python/examples/direct/verify.in b/python/examples/direct/verify.in new file mode 100644 index 0000000000..e0dca33039 --- /dev/null +++ b/python/examples/direct/verify.in @@ -0,0 +1,14 @@ +==== ./declare_queues.py.out +==== ./direct_producer.py.out +==== ./direct_consumer.py.out +message 0 +message 1 +message 2 +message 3 +message 4 +message 5 +message 6 +message 7 +message 8 +message 9 +That's all, folks! diff --git a/python/examples/fanout/declare_queues.py b/python/examples/fanout/declare_queues.py index 8840ea38e1..52f23f4f9a 100644..100755 --- a/python/examples/fanout/declare_queues.py +++ b/python/examples/fanout/declare_queues.py @@ -9,6 +9,7 @@ """ import qpid +import sys from qpid.client import Client from qpid.content import Content from qpid.queue import Empty @@ -17,8 +18,8 @@ from qpid.queue import Empty # Set parameters for login -host="127.0.0.1" -port=5672 +host=len(sys.argv) > 1 and sys.argv[1] or "127.0.0.1" +port=len(sys.argv) > 2 and int(sys.argv[2]) or 5672 amqp_spec="/usr/share/amqp/amqp.0-10-preview.xml" user="guest" password="guest" diff --git a/python/examples/fanout/fanout_consumer.py b/python/examples/fanout/fanout_consumer.py index 8d852ca753..b91ea35c0d 100644..100755 --- a/python/examples/fanout/fanout_consumer.py +++ b/python/examples/fanout/fanout_consumer.py @@ -7,6 +7,7 @@ """ import qpid +import sys from qpid.client import Client from qpid.content import Content from qpid.queue import Empty @@ -16,8 +17,8 @@ from qpid.queue import Empty # Set parameters for login -host="127.0.0.1" -port=5672 +host=len(sys.argv) > 1 and sys.argv[1] or "127.0.0.1" +port=len(sys.argv) > 2 and int(sys.argv[2]) or 5672 amqp_spec="/usr/share/amqp/amqp.0-10-preview.xml" user="guest" password="guest" diff --git a/python/examples/fanout/fanout_producer.py b/python/examples/fanout/fanout_producer.py index d9d8f454c8..9864c776c1 100644..100755 --- a/python/examples/fanout/fanout_producer.py +++ b/python/examples/fanout/fanout_producer.py @@ -7,6 +7,7 @@ """ import qpid +import sys from qpid.client import Client from qpid.content import Content from qpid.queue import Empty @@ -15,8 +16,8 @@ from qpid.queue import Empty # Set parameters for login -host="127.0.0.1" -port=5672 +host=len(sys.argv) > 1 and sys.argv[1] or "127.0.0.1" +port=len(sys.argv) > 2 and int(sys.argv[2]) or 5672 amqp_spec="/usr/share/amqp/amqp.0-10-preview.xml" user="guest" password="guest" diff --git a/python/examples/fanout/listener.py b/python/examples/fanout/listener.py index 09dd7ddb80..8997c3698f 100644..100755 --- a/python/examples/fanout/listener.py +++ b/python/examples/fanout/listener.py @@ -7,6 +7,7 @@ """ import qpid +import sys from qpid.client import Client from qpid.content import Content from qpid.queue import Empty @@ -39,8 +40,8 @@ class Receiver: # Set parameters for login -host="127.0.0.1" -port=5672 +host=len(sys.argv) > 1 and sys.argv[1] or "127.0.0.1" +port=len(sys.argv) > 2 and int(sys.argv[2]) or 5672 amqp_spec="/usr/share/amqp/amqp.0-10-preview.xml" user="guest" password="guest" diff --git a/python/examples/fanout/verify b/python/examples/fanout/verify new file mode 100644 index 0000000000..f136ccd39b --- /dev/null +++ b/python/examples/fanout/verify @@ -0,0 +1,3 @@ +# See https://svn.apache.org/repos/asf/incubator/qpid/trunk/qpid/bin/verify +clients ./declare_queues.py ./fanout_producer.py ./fanout_consumer.py +outputs ./declare_queues.py.out ./fanout_producer.py.out ./fanout_consumer.py.out diff --git a/python/examples/fanout/verify.in b/python/examples/fanout/verify.in new file mode 100644 index 0000000000..c625c30773 --- /dev/null +++ b/python/examples/fanout/verify.in @@ -0,0 +1,14 @@ +==== ./declare_queues.py.out +==== ./fanout_producer.py.out +==== ./fanout_consumer.py.out +message 0 +message 1 +message 2 +message 3 +message 4 +message 5 +message 6 +message 7 +message 8 +message 9 +That's all, folks! diff --git a/python/examples/pubsub/topic_publisher.py b/python/examples/pubsub/topic_publisher.py index 1ff983b315..e302d58ad4 100644..100755 --- a/python/examples/pubsub/topic_publisher.py +++ b/python/examples/pubsub/topic_publisher.py @@ -8,6 +8,7 @@ """ import qpid +import sys from qpid.client import Client from qpid.content import Content from qpid.queue import Empty @@ -15,9 +16,8 @@ from qpid.queue import Empty #----- Initialization ----------------------------------- # Set parameters for login. - -host="127.0.0.1" -port=5672 +host=len(sys.argv) > 1 and sys.argv[1] or "127.0.0.1" +port=len(sys.argv) > 2 and int(sys.argv[2]) or 5672 amqp_spec="/usr/share/amqp/amqp.0-10-preview.xml" user="guest" password="guest" diff --git a/python/examples/pubsub/topic_subscriber.py b/python/examples/pubsub/topic_subscriber.py index 52ec67b77c..a5c05ba177 100644..100755 --- a/python/examples/pubsub/topic_subscriber.py +++ b/python/examples/pubsub/topic_subscriber.py @@ -7,7 +7,7 @@ """ import base64 - +import sys import qpid from qpid.client import Client from qpid.content import Content @@ -60,8 +60,8 @@ def dump_queue(client, queue_name): # Set parameters for login -host="127.0.0.1" -port=5672 +host=len(sys.argv) > 1 and sys.argv[1] or "127.0.0.1" +port=len(sys.argv) > 2 and int(sys.argv[2]) or 5672 amqp_spec="/usr/share/amqp/amqp.0-10-preview.xml" user="guest" password="guest" @@ -108,7 +108,8 @@ session.queue_bind(exchange="amq.topic", queue=europe, routing_key="control") # Remind the user to start the topic producer -print "Queues create - please start the topic producer" +print "Queues created - please start the topic producer" +sys.stdout.flush() # Call dump_queue to print messages from each queue diff --git a/python/examples/pubsub/verify b/python/examples/pubsub/verify new file mode 100644 index 0000000000..bef233b4ff --- /dev/null +++ b/python/examples/pubsub/verify @@ -0,0 +1,4 @@ +# See https://svn.apache.org/repos/asf/incubator/qpid/trunk/qpid/bin/verify +background "Queues created" ./topic_subscriber.py +clients ./topic_publisher.py +outputs ./topic_publisher.py.out "topic_subscriber.py.out | remove_uuid64 | sort" diff --git a/python/examples/pubsub/verify.in b/python/examples/pubsub/verify.in new file mode 100644 index 0000000000..19dcf88312 --- /dev/null +++ b/python/examples/pubsub/verify.in @@ -0,0 +1,51 @@ +==== ./topic_publisher.py.out +==== topic_subscriber.py.out | remove_uuid64 | sort +message 0 +message 0 +message 0 +message 0 +message 0 +message 0 +message 0 +message 0 +message 1 +message 1 +message 1 +message 1 +message 1 +message 1 +message 1 +message 1 +message 2 +message 2 +message 2 +message 2 +message 2 +message 2 +message 2 +message 2 +message 3 +message 3 +message 3 +message 3 +message 3 +message 3 +message 3 +message 3 +message 4 +message 4 +message 4 +message 4 +message 4 +message 4 +message 4 +message 4 +Messages queue: europe +Messages queue: news +Messages queue: usa +Messages queue: weather +Queues created - please start the topic producer +That's all, folks! +That's all, folks! +That's all, folks! +That's all, folks! diff --git a/python/examples/request-response/client.py b/python/examples/request-response/client.py index e218acce3d..6561bb6fee 100644..100755 --- a/python/examples/request-response/client.py +++ b/python/examples/request-response/client.py @@ -9,6 +9,7 @@ import base64 import qpid +import sys from qpid.client import Client from qpid.content import Content from qpid.queue import Empty @@ -59,8 +60,8 @@ def dump_queue(client, queue_name): # Set parameters for login -host="127.0.0.1" -port=5672 +host=len(sys.argv) > 1 and sys.argv[1] or "127.0.0.1" +port=len(sys.argv) > 2 and int(sys.argv[2]) or 5672 amqp_spec="/usr/share/amqp/amqp.0-10-preview.xml" user="guest" password="guest" diff --git a/python/examples/request-response/server.py b/python/examples/request-response/server.py index 2730768a91..04b147d003 100644..100755 --- a/python/examples/request-response/server.py +++ b/python/examples/request-response/server.py @@ -6,6 +6,7 @@ """ import qpid +import sys from qpid.client import Client from qpid.content import Content from qpid.queue import Empty @@ -27,8 +28,8 @@ def respond(session, request): # Set parameters for login -host="127.0.0.1" -port=5672 +host=len(sys.argv) > 1 and sys.argv[1] or "127.0.0.1" +port=len(sys.argv) > 2 and int(sys.argv[2]) or 5672 amqp_spec="/usr/share/amqp/amqp.0-10-preview.xml" user="guest" password="guest" @@ -61,6 +62,7 @@ session.message_flow(dest, 1, 0xFFFFFFFF) print "Request server running - run your client now." print "(Times out after 100 seconds ...)" +sys.stdout.flush() # Respond to each request diff --git a/python/examples/request-response/verify b/python/examples/request-response/verify new file mode 100644 index 0000000000..2a2d479077 --- /dev/null +++ b/python/examples/request-response/verify @@ -0,0 +1,5 @@ +# See https://svn.apache.org/repos/asf/incubator/qpid/trunk/qpid/bin/verify +background "Request server running" ./server.py +clients ./client.py +kill %% # Must kill the server. +outputs "./client.py.out | remove_uuid64" " server.py.out | remove_uuid64" diff --git a/python/examples/request-response/verify.in b/python/examples/request-response/verify.in new file mode 100644 index 0000000000..c02a423bcb --- /dev/null +++ b/python/examples/request-response/verify.in @@ -0,0 +1,14 @@ +==== ./client.py.out | remove_uuid64 +Request: Twas brilling, and the slithy toves +Request: Did gyre and gimble in the wabe. +Request: All mimsy were the borogroves, +Request: And the mome raths outgrabe. +Messages queue: ReplyTo: +Response: TWAS BRILLING, AND THE SLITHY TOVES +Response: DID GYRE AND GIMBLE IN THE WABE. +Response: ALL MIMSY WERE THE BOROGROVES, +Response: AND THE MOME RATHS OUTGRABE. +No more messages! +==== server.py.out | remove_uuid64 +Request server running - run your client now. +(Times out after 100 seconds ...) |
