Skip to content

Commit

Permalink
Merge pull request #807 from weaveworks/increase-test-replicas
Browse files Browse the repository at this point in the history
Speed up integration tests
  • Loading branch information
paulbellamy committed Jan 13, 2016
2 parents cf41ec3 + e952301 commit 14899ad
Show file tree
Hide file tree
Showing 12 changed files with 548 additions and 14 deletions.
5 changes: 1 addition & 4 deletions circle.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,6 @@ machine:
PATH: $PATH:$HOME/.local/bin
CLOUDSDK_CORE_DISABLE_PROMPTS: 1
SCOPE_UI_BUILD: $HOME/docker/scope_ui_build.tar
WEAVE_REPO: github.com/weaveworks/weave
WEAVE_ROOT: /home/ubuntu/src/github.com/weaveworks/weave

dependencies:
cache_directories:
Expand All @@ -22,12 +20,10 @@ dependencies:
- "sudo apt-get update && sudo apt-get install jq pv"
- curl https://sdk.cloud.google.com | bash
- test -z "$SECRET_PASSWORD" || bin/setup-circleci-secrets "$SECRET_PASSWORD"
- mkdir -p $GOPATH/src/$WEAVE_REPO; git clone http://github.com/weaveworks/weave $GOPATH/src/$WEAVE_REPO
- make deps
- "mkdir -p $(dirname $SRCDIR) && cp -r $(pwd)/ $SRCDIR"
- "cd $SRCDIR/client; ../tools/rebuild-image weaveworks/scope-ui-build . Dockerfile package.json webpack.production.config.js .eslintrc .babelrc && touch $SRCDIR/.scope_ui_build.uptodate"
- "cd $SRCDIR/backend; ../tools/rebuild-image weaveworks/scope-backend-build . Dockerfile build.sh && touch $SRCDIR/.scope_backend_build.uptodate"
- "make -C $SRCDIR/tools/runner && mkdir -p $WEAVE_ROOT/tools/runner && cp $SRCDIR/tools/runner/runner $WEAVE_ROOT/tools/runner"
- cd $SRCDIR/integration; ./gce.sh make_template:
parallel: false

Expand All @@ -50,6 +46,7 @@ test:
- "test -z \"$SECRET_PASSWORD\" || (cd $SRCDIR/integration; ./gce.sh setup && eval $(./gce.sh hosts); ./setup.sh)":
parallel: true
- test -z "$SECRET_PASSWORD" || (cd $SRCDIR/integration; eval $(./gce.sh hosts); ./run_all.sh):
parallel: true
timeout: 300
post:
- test -z "$SECRET_PASSWORD" || (cd $SRCDIR/integration; ./gce.sh destroy):
Expand Down
2 changes: 1 addition & 1 deletion integration/330_application_edge_test.sh
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ weave_on $HOST1 run -dti --name client alpine /bin/sh -c "while true; do \
sleep 1; \
done"

wait_for applications $HOST1 60 nginx client
wait_for applications $HOST1 60 "nginx: worker process" nc

has applications $HOST1 "nginx: worker process"
has applications $HOST1 nc
Expand Down
5 changes: 1 addition & 4 deletions integration/config.sh
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,7 @@ set -e
export SSH_DIR="$PWD"
export HOSTS

: ${WEAVE_REPO:=github.com/weaveworks/weave}
: ${WEAVE_ROOT:="$(go list -e -f {{.Dir}} $WEAVE_REPO)"}

. "$WEAVE_ROOT/test/config.sh"
. "../tools/integration/config.sh"

WEAVE="./weave"
SCOPE="../scope"
Expand Down
2 changes: 1 addition & 1 deletion integration/gce.sh
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,4 @@ set -e
export PROJECT=scope-integration-tests
export TEMPLATE_NAME="test-template-4"
export NUM_HOSTS=2
. "$WEAVE_ROOT/test/gce.sh" "$@"
. "../tools/integration/gce.sh" "$@"
2 changes: 1 addition & 1 deletion integration/run_all.sh
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,4 @@ set -e

. ./config.sh

NO_SCHEDULER=1 $WEAVE_ROOT/test/run_all.sh "$@"
../tools/integration/run_all.sh "$@"
2 changes: 0 additions & 2 deletions integration/setup.sh
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,6 @@ echo Copying scope images and scripts to hosts
for HOST in $HOSTS; do
SIZE=$(stat --printf="%s" ../scope.tar)
cat ../scope.tar | pv -N "scope.tar" -s $SIZE | $SSH -C $HOST sudo docker load
upload_executable $HOST ../scope
upload_executable $HOST ../scope /usr/local/scope/bin/scope
done

setup_host() {
Expand Down
186 changes: 186 additions & 0 deletions tools/integration/assert.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,186 @@
#!/bin/bash
# assert.sh 1.1 - bash unit testing framework
# Copyright (C) 2009-2015 Robert Lehmann
#
# http://github.com/lehmannro/assert.sh
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as published
# by the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.

export DISCOVERONLY=${DISCOVERONLY:-}
export DEBUG=${DEBUG:-}
export STOP=${STOP:-}
export INVARIANT=${INVARIANT:-}
export CONTINUE=${CONTINUE:-}

args="$(getopt -n "$0" -l \
verbose,help,stop,discover,invariant,continue vhxdic $*)" \
|| exit -1
for arg in $args; do
case "$arg" in
-h)
echo "$0 [-vxidc]" \
"[--verbose] [--stop] [--invariant] [--discover] [--continue]"
echo "`sed 's/./ /g' <<< "$0"` [-h] [--help]"
exit 0;;
--help)
cat <<EOF
Usage: $0 [options]
Language-agnostic unit tests for subprocesses.
Options:
-v, --verbose generate output for every individual test case
-x, --stop stop running tests after the first failure
-i, --invariant do not measure timings to remain invariant between runs
-d, --discover collect test suites only, do not run any tests
-c, --continue do not modify exit code to test suite status
-h show brief usage information and exit
--help show this help message and exit
EOF
exit 0;;
-v|--verbose)
DEBUG=1;;
-x|--stop)
STOP=1;;
-i|--invariant)
INVARIANT=1;;
-d|--discover)
DISCOVERONLY=1;;
-c|--continue)
CONTINUE=1;;
esac
done

_indent=$'\n\t' # local format helper

_assert_reset() {
tests_ran=0
tests_failed=0
tests_errors=()
tests_starttime="$(date +%s%N)" # nanoseconds_since_epoch
}

assert_end() {
# assert_end [suite ..]
tests_endtime="$(date +%s%N)"
# required visible decimal place for seconds (leading zeros if needed)
tests_time="$( \
printf "%010d" "$(( ${tests_endtime/%N/000000000}
- ${tests_starttime/%N/000000000} ))")" # in ns
tests="$tests_ran ${*:+$* }tests"
[[ -n "$DISCOVERONLY" ]] && echo "collected $tests." && _assert_reset && return
[[ -n "$DEBUG" ]] && echo
# to get report_time split tests_time on 2 substrings:
# ${tests_time:0:${#tests_time}-9} - seconds
# ${tests_time:${#tests_time}-9:3} - milliseconds
[[ -z "$INVARIANT" ]] \
&& report_time=" in ${tests_time:0:${#tests_time}-9}.${tests_time:${#tests_time}-9:3}s" \
|| report_time=

if [[ "$tests_failed" -eq 0 ]]; then
echo "all $tests passed$report_time."
else
for error in "${tests_errors[@]}"; do echo "$error"; done
echo "$tests_failed of $tests failed$report_time."
fi
tests_failed_previous=$tests_failed
[[ $tests_failed -gt 0 ]] && tests_suite_status=1
_assert_reset
}

assert() {
# assert <command> <expected stdout> [stdin]
(( tests_ran++ )) || :
[[ -z "$DISCOVERONLY" ]] || return
expected=$(echo -ne "${2:-}")
result="$(eval 2>/dev/null $1 <<< ${3:-})" || true
if [[ "$result" == "$expected" ]]; then
[[ -z "$DEBUG" ]] || echo -n .
return
fi
result="$(sed -e :a -e '$!N;s/\n/\\n/;ta' <<< "$result")"
[[ -z "$result" ]] && result="nothing" || result="\"$result\""
[[ -z "$2" ]] && expected="nothing" || expected="\"$2\""
_assert_fail "expected $expected${_indent}got $result" "$1" "$3"
}

assert_raises() {
# assert_raises <command> <expected code> [stdin]
(( tests_ran++ )) || :
[[ -z "$DISCOVERONLY" ]] || return
status=0
(eval $1 <<< ${3:-}) > /dev/null 2>&1 || status=$?
expected=${2:-0}
if [[ "$status" -eq "$expected" ]]; then
[[ -z "$DEBUG" ]] || echo -n .
return
fi
_assert_fail "program terminated with code $status instead of $expected" "$1" "$3"
}

_assert_fail() {
# _assert_fail <failure> <command> <stdin>
[[ -n "$DEBUG" ]] && echo -n X
report="test #$tests_ran \"$2${3:+ <<< $3}\" failed:${_indent}$1"
if [[ -n "$STOP" ]]; then
[[ -n "$DEBUG" ]] && echo
echo "$report"
exit 1
fi
tests_errors[$tests_failed]="$report"
(( tests_failed++ )) || :
}

skip_if() {
# skip_if <command ..>
(eval $@) > /dev/null 2>&1 && status=0 || status=$?
[[ "$status" -eq 0 ]] || return
skip
}

skip() {
# skip (no arguments)
shopt -q extdebug && tests_extdebug=0 || tests_extdebug=1
shopt -q -o errexit && tests_errexit=0 || tests_errexit=1
# enable extdebug so returning 1 in a DEBUG trap handler skips next command
shopt -s extdebug
# disable errexit (set -e) so we can safely return 1 without causing exit
set +o errexit
tests_trapped=0
trap _skip DEBUG
}
_skip() {
if [[ $tests_trapped -eq 0 ]]; then
# DEBUG trap for command we want to skip. Do not remove the handler
# yet because *after* the command we need to reset extdebug/errexit (in
# another DEBUG trap.)
tests_trapped=1
[[ -z "$DEBUG" ]] || echo -n s
return 1
else
trap - DEBUG
[[ $tests_extdebug -eq 0 ]] || shopt -u extdebug
[[ $tests_errexit -eq 1 ]] || set -o errexit
return 0
fi
}


_assert_reset
: ${tests_suite_status:=0} # remember if any of the tests failed so far
_assert_cleanup() {
local status=$?
# modify exit code if it's not already non-zero
[[ $status -eq 0 && -z $CONTINUE ]] && exit $tests_suite_status
}
trap _assert_cleanup EXIT
125 changes: 125 additions & 0 deletions tools/integration/config.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
# NB only to be sourced

set -e

DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"

# Protect against being sourced multiple times to prevent
# overwriting assert.sh global state
if ! [ -z "$SOURCED_CONFIG_SH" ]; then
return
fi
SOURCED_CONFIG_SH=true

# these ought to match what is in Vagrantfile
N_MACHINES=${N_MACHINES:-3}
IP_PREFIX=${IP_PREFIX:-192.168.48}
IP_SUFFIX_BASE=${IP_SUFFIX_BASE:-10}

if [ -z "$HOSTS" ] ; then
for i in $(seq 1 $N_MACHINES); do
IP="${IP_PREFIX}.$((${IP_SUFFIX_BASE}+$i))"
HOSTS="$HOSTS $IP"
done
fi

# these are used by the tests
HOST1=$(echo $HOSTS | cut -f 1 -d ' ')
HOST2=$(echo $HOSTS | cut -f 2 -d ' ')
HOST3=$(echo $HOSTS | cut -f 3 -d ' ')

. "$DIR/assert.sh"

SSH_DIR=${SSH_DIR:-$DIR}
SSH=${SSH:-ssh -l vagrant -i "$SSH_DIR/insecure_private_key" -o "UserKnownHostsFile=$SSH_DIR/.ssh_known_hosts" -o CheckHostIP=no -o StrictHostKeyChecking=no}

SMALL_IMAGE="alpine"
TEST_IMAGES="$SMALL_IMAGE"

PING="ping -nq -W 1 -c 1"
DOCKER_PORT=2375

remote() {
rem=$1
shift 1
"$@" > >(while read line; do echo -e $'\e[0;34m'"$rem>"$'\e[0m'" $line"; done)
}

colourise() {
[ -t 0 ] && echo -ne $'\e['$1'm' || true
shift
# It's important that we don't do this in a subshell, as some
# commands we execute need to modify global state
"$@"
[ -t 0 ] && echo -ne $'\e[0m' || true
}

whitely() {
colourise '1;37' "$@"
}

greyly () {
colourise '0;37' "$@"
}

redly() {
colourise '1;31' "$@"
}

greenly() {
colourise '1;32' "$@"
}

run_on() {
host=$1
shift 1
[ -z "$DEBUG" ] || greyly echo "Running on $host: $@" >&2
remote $host $SSH $host "$@"
}

docker_on() {
host=$1
shift 1
[ -z "$DEBUG" ] || greyly echo "Docker on $host:$DOCKER_PORT: $@" >&2
docker -H tcp://$host:$DOCKER_PORT "$@"
}

weave_on() {
host=$1
shift 1
[ -z "$DEBUG" ] || greyly echo "Weave on $host:$DOCKER_PORT: $@" >&2
DOCKER_HOST=tcp://$host:$DOCKER_PORT $WEAVE "$@"
}

exec_on() {
host=$1
container=$2
shift 2
docker -H tcp://$host:$DOCKER_PORT exec $container "$@"
}

rm_containers() {
host=$1
shift
[ $# -eq 0 ] || docker_on $host rm -f "$@" >/dev/null
}

start_suite() {
for host in $HOSTS; do
[ -z "$DEBUG" ] || echo "Cleaning up on $host: removing all containers and resetting weave"
PLUGIN_ID=$(docker_on $host ps -aq --filter=name=weaveplugin)
PLUGIN_FILTER="cat"
[ -n "$PLUGIN_ID" ] && PLUGIN_FILTER="grep -v $PLUGIN_ID"
rm_containers $host $(docker_on $host ps -aq 2>/dev/null | $PLUGIN_FILTER)
run_on $host "docker network ls | grep -q ' weave ' && docker network rm weave" || true
weave_on $host reset 2>/dev/null
done
whitely echo "$@"
}

end_suite() {
whitely assert_end
}

WEAVE=$DIR/../weave

Loading

0 comments on commit 14899ad

Please sign in to comment.