Skip to content

Commit

Permalink
Start BDD Test Containers intelligently
Browse files Browse the repository at this point in the history
Rather than sleeping and 'hoping' the membersrvc is ready once the
thread wakes up, add a script which polls the membersrvc rpc port to
check if it is open, and if it is, run the peer. For docker-compose
configurations that don't use the membersrvc, the peers will start
immediately.

Change-Id: I65aff6a6432fbca7168309719893ec8a9f4e290f
Signed-off-by: Julian Carrivick <cjulian@au1.ibm.com>
  • Loading branch information
juliancarrivick-ibm committed Aug 16, 2016
1 parent 457635a commit 17ab179
Show file tree
Hide file tree
Showing 4 changed files with 189 additions and 5 deletions.
9 changes: 5 additions & 4 deletions bddtests/compose-defaults.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,11 @@ vp:
- CORE_VM_ENDPOINT=http://172.17.0.1:2375
# TODO: This is currently required due to BUG in variant logic based upon log level.
- CORE_LOGGING_LEVEL=DEBUG
# Startup of peer must be delayed to allow membersrvc to come up first
command: sh -c "sleep 5; peer node start"
#command: peer node start

# Script will wait until membersrvc is up (if it exists) before starting
# $$GOPATH (double dollar) required to prevent docker-compose doing its own
# substitution before the value gets to the container
command: sh -c '$$GOPATH/src/github.com/hyperledger/fabric/bddtests/scripts/start-peer.sh'

# Use these options if coverage desired for peers
#image: hyperledger/fabric-peer-coverage
#command: ./peer.test --test.coverprofile=coverage.cov node start
Expand Down
4 changes: 3 additions & 1 deletion bddtests/docker-compose-1-devmode.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ ccenv:
environment:
- CORE_CHAINCODE_ID_NAME=testCC
- CORE_PEER_ADDRESS=vp0:7051
command: bash -c "GOBIN=/opt/gopath/bin go install github.com/hyperledger/fabric/examples/chaincode/go/chaincode_example02 && /opt/gopath/bin/chaincode_example02"
# $$GOPATH (double dollar) required to prevent docker-compose doing its own
# substitution before the value gets to the container
command: bash -c 'go install github.com/hyperledger/fabric/examples/chaincode/go/chaincode_example02 && $$GOPATH/bin/chaincode_example02'
links:
- vp0
20 changes: 20 additions & 0 deletions bddtests/scripts/start-peer.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
#!/bin/sh

SCRIPT_DIR=$(dirname $0)
MEMBERSHIP_IP=$(cat /etc/hosts | grep membersrvc | head -n 1 | cut -f1)
TIMEOUT=10

if [ -n "$MEMBERSHIP_IP" ]; then
echo "membersrvc detected, waiting for it before starting with a $TIMEOUT second timout"
"$SCRIPT_DIR"/wait-for-it.sh -t "$TIMEOUT" "$MEMBERSHIP_IP":7054

if [ $? -ne 0 ]; then
echo "Failed to contact membersrvc within $TIMEOUT seconds"
exit 1
fi
else
echo "No membersrvc to wait for, starting immediately"
fi

peer node start

161 changes: 161 additions & 0 deletions bddtests/scripts/wait-for-it.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,161 @@
#!/bin/sh
# Modified from https://github.com/vishnubob/wait-for-it to be POSIX compatible
# Use this script to test if a given TCP host/port are available

cmdname=$(basename $0)

TIMEOUT=${TIMEOUT:-15}
STRICT=${STRICT:-0}
CHILD=${CHILD:-0}
QUIET=${QUIET:-0}

echoerr() { if [ $QUIET -ne 1 ]; then echo "$@" 1>&2; fi }

usage()
{
cat << USAGE >&2
Usage:
$cmdname host:port [-s] [-t timeout] [-- command args]
-h HOST | --host=HOST Host or IP under test
-p PORT | --port=PORT TCP port under test
Alternatively, you specify the host and port as host:port
-s | --strict Only execute subcommand if the test succeeds
-q | --quiet Don't output any status messages
-t TIMEOUT | --timeout=TIMEOUT
Timeout in seconds, zero for no timeout
-- COMMAND ARGS Execute command with args after the test finishes
USAGE
exit 1
}

wait_for()
{
if [ $TIMEOUT -gt 0 ]; then
echoerr "$cmdname: waiting $TIMEOUT seconds for $HOST:$PORT"
else
echoerr "$cmdname: waiting for $HOST:$PORT without a timeout"
fi
start_ts=$(date +%s)
while :
do
nc -z $HOST $PORT >/dev/null 2>&1
result=$?
if [ $result -eq 0 ]; then
end_ts=$(date +%s)
echoerr "$cmdname: $HOST:$PORT is available after $((end_ts - start_ts)) seconds"
break
fi
sleep 1
done
return $result
}

wait_for_wrapper()
{
# In order to support SIGINT during timeout: http://unix.stackexchange.com/a/57692
if [ $QUIET -eq 1 ]; then
timeout $TIMEOUT $0 --quiet --child --host=$HOST --port=$PORT --timeout=$TIMEOUT &
else
timeout $TIMEOUT $0 --child --host=$HOST --port=$PORT --timeout=$TIMEOUT &
fi
PID=$!
trap "kill -INT -$PID" INT
wait $PID
RESULT=$?
if [ $RESULT -ne 0 ]; then
echoerr "$cmdname: timeout occurred after waiting $TIMEOUT seconds for $HOST:$PORT"
fi
return $RESULT
}

# process arguments
while [ $# -gt 0 ]
do
case "$1" in
*:* )
HOST=$(echo $1 | cut --fields=1 --delimiter=:)
PORT=$(echo $1 | cut --fields=2- --delimiter=:)
shift 1
;;
--child)
CHILD=1
shift 1
;;
-q | --quiet)
QUIET=1
shift 1
;;
-s | --strict)
STRICT=1
shift 1
;;
-h)
HOST="$2"
if [ "$HOST" = "" ]; then break; fi
shift 2
;;
--host=*)
HOST="${1#*=}"
shift 1
;;
-p)
PORT="$2"
if [ "$PORT" = "" ]; then break; fi
shift 2
;;
--port=*)
PORT="${1#*=}"
shift 1
;;
-t)
TIMEOUT="$2"
if [ "$TIMEOUT" = "" ]; then break; fi
shift 2
;;
--timeout=*)
TIMEOUT="${1#*=}"
shift 1
;;
--)
shift
CLI="$@"
break
;;
--help)
usage
;;
*)
echoerr "Unknown argument: $1"
usage
;;
esac
done

if [ "$HOST" = "" ] || [ "$PORT" = "" ]; then
echoerr "Error: you need to provide a host and port to test."
usage
fi

if [ $CHILD -gt 0 ]; then
wait_for
RESULT=$?
exit $RESULT
else
if [ $TIMEOUT -gt 0 ]; then
wait_for_wrapper
RESULT=$?
else
wait_for
RESULT=$?
fi
fi

if [ "$CLI" != "" ]; then
if [ $RESULT -ne 0 ] && [ $STRICT -eq 1 ]; then
echoerr "$cmdname: strict mode, refusing to execute subprocess"
exit $RESULT
fi
exec $CLI
else
exit $RESULT
fi

0 comments on commit 17ab179

Please sign in to comment.