diff --git a/bddtests/compose-defaults.yml b/bddtests/compose-defaults.yml index d8631dfa2d3..0c3be5a8698 100644 --- a/bddtests/compose-defaults.yml +++ b/bddtests/compose-defaults.yml @@ -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 diff --git a/bddtests/docker-compose-1-devmode.yml b/bddtests/docker-compose-1-devmode.yml index f89d03cf025..7f506bd1dd8 100755 --- a/bddtests/docker-compose-1-devmode.yml +++ b/bddtests/docker-compose-1-devmode.yml @@ -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 diff --git a/bddtests/scripts/start-peer.sh b/bddtests/scripts/start-peer.sh new file mode 100755 index 00000000000..cd6965fdfd9 --- /dev/null +++ b/bddtests/scripts/start-peer.sh @@ -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 + diff --git a/bddtests/scripts/wait-for-it.sh b/bddtests/scripts/wait-for-it.sh new file mode 100755 index 00000000000..46bbf271ffe --- /dev/null +++ b/bddtests/scripts/wait-for-it.sh @@ -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 \ No newline at end of file