|
| 1 | +#!/bin/bash |
| 2 | +# |
| 3 | +# Preps a test environment and runs `make test-integration` |
| 4 | +# against artifacts produced from the current source tree |
| 5 | +# |
| 6 | + |
| 7 | +# fail on any command exiting non-zero |
| 8 | +set -e |
| 9 | + |
| 10 | +# absolute path to current directory |
| 11 | +export THIS_DIR=$(cd $(dirname $0); pwd) |
| 12 | + |
| 13 | +# setup the test environment |
| 14 | +source $THIS_DIR/test-setup.sh |
| 15 | + |
| 16 | +# AWS credentials required for aws cli and boto |
| 17 | +export AWS_ACCESS_KEY_ID=${AWS_ACCESS_KEY_ID?} |
| 18 | +export AWS_SECRET_ACCESS_KEY=${AWS_SECRET_ACCESS_KEY?} |
| 19 | + |
| 20 | +# install python requirements for this script |
| 21 | +pip install awscli boto docopt |
| 22 | + |
| 23 | +function cleanup_ec2 { |
| 24 | + log_phase "Cleaning up" |
| 25 | + aws cloudformation delete-stack --stack-name $STACK_NAME |
| 26 | + python $DEIS_ROOT/tests/bin/route53-wildcard.py delete $DEIS_TEST_DOMAIN $ELB_DNS_NAME |
| 27 | +} |
| 28 | + |
| 29 | +# setup callbacks on process exit and error |
| 30 | +trap cleanup_ec2 EXIT |
| 31 | +trap dump_logs ERR |
| 32 | + |
| 33 | +log_phase "Running style tests" |
| 34 | + |
| 35 | +make test-style |
| 36 | + |
| 37 | +log_phase "Running documentation tests" |
| 38 | + |
| 39 | +# test building documentation |
| 40 | +make -C docs/ test |
| 41 | + |
| 42 | +log_phase "Running unit tests" |
| 43 | + |
| 44 | +make test-unit |
| 45 | + |
| 46 | +log_phase "Building from current source tree" |
| 47 | + |
| 48 | +# build all docker images and client binaries |
| 49 | +make build |
| 50 | + |
| 51 | +# use the built client binaries |
| 52 | +export PATH=$DEIS_ROOT/deisctl:$DEIS_ROOT/client/dist:$PATH |
| 53 | + |
| 54 | +log_phase "Running functional tests" |
| 55 | + |
| 56 | +make test-functional |
| 57 | + |
| 58 | +export DEIS_NUM_INSTANCES=3 |
| 59 | +log_phase "Provisioning $DEIS_NUM_INSTANCES-node CoreOS" |
| 60 | + |
| 61 | +# TODO: don't hardcode --key-names |
| 62 | +if ! aws ec2 describe-key-pairs --key-names "deis" >/dev/null ; then |
| 63 | + echo "Importing $DEIS_TEST_AUTH_KEY keypair to EC2" |
| 64 | + aws ec2 import-key-pair --key-name deis \ |
| 65 | + --public-key-material file://~/.ssh/$DEIS_TEST_AUTH_KEY.pub \ |
| 66 | + --output text |
| 67 | +fi |
| 68 | + |
| 69 | +make discovery-url |
| 70 | +# add random characters after STACK_TAG to avoid collisions |
| 71 | +# TODO: somehow this breaks "set -eo pipefail" |
| 72 | +STACK_TAG=${STACK_TAG:-test}-$(base64 /dev/urandom | tr -dc a-z0-9 | head -c 6) |
| 73 | +STACK_NAME=deis-$STACK_TAG |
| 74 | +echo "Creating CloudFormation stack $STACK_NAME" |
| 75 | +$DEIS_ROOT/contrib/ec2/provision-ec2-cluster.sh $STACK_NAME |
| 76 | + |
| 77 | +# use the first cluster node for now |
| 78 | +INSTANCE_IDS=$(aws ec2 describe-instances \ |
| 79 | + --filters Name=tag:aws:cloudformation:stack-name,Values=$STACK_NAME Name=instance-state-name,Values=running \ |
| 80 | + --query 'Reservations[].Instances[].[ InstanceId ]' \ |
| 81 | + --output text) |
| 82 | +export INSTANCE_ID=$(cut -d " " -f1 <<< $INSTANCE_IDS) |
| 83 | +export DEISCTL_TUNNEL=$(aws ec2 describe-instances \ |
| 84 | + --instance-ids=$INSTANCE_ID \ |
| 85 | + --filters Name=tag:aws:cloudformation:stack-name,Values=$STACK_NAME Name=instance-state-name,Values=running \ |
| 86 | + --query 'Reservations[].Instances[].[ PublicDnsName ]' \ |
| 87 | + --output text) |
| 88 | + |
| 89 | +log_phase "Waiting for etcd/fleet at $DEISCTL_TUNNEL" |
| 90 | + |
| 91 | +# wait for etcd up to 5 minutes |
| 92 | +WAIT_TIME=1 |
| 93 | +until deisctl --request-timeout=1 list >/dev/null 2>&1; do |
| 94 | + (( WAIT_TIME += 1 )) |
| 95 | + if [ $WAIT_TIME -gt 300 ]; then |
| 96 | + log_phase "Timeout waiting for etcd/fleet" |
| 97 | + # run deisctl one last time without eating the error, so we can see what's up |
| 98 | + deisctl --request-timeout=1 list |
| 99 | + exit 1; |
| 100 | + fi |
| 101 | +done |
| 102 | + |
| 103 | +log_phase "etcd available after $WAIT_TIME seconds" |
| 104 | + |
| 105 | +log_phase "Publishing release from source tree" |
| 106 | + |
| 107 | +# TODO: detect where IMAGE_PREFIX=deis/ and DEV_REGISTRY=registry.hub.docker.com |
| 108 | +# and disallow it so we can't pollute the production account. |
| 109 | +make dev-release |
| 110 | + |
| 111 | +log_phase "Provisioning Deis" |
| 112 | + |
| 113 | +export DEIS_TEST_DOMAIN=$STACK_TAG.deis.works |
| 114 | + |
| 115 | +# configure platform settings |
| 116 | +deisctl config platform set domain=$DEIS_TEST_DOMAIN |
| 117 | +deisctl config platform set sshPrivateKey=$DEIS_TEST_SSH_KEY |
| 118 | + |
| 119 | +time deisctl install platform |
| 120 | +time deisctl start platform |
| 121 | + |
| 122 | +# get ELB public DNS name through cloudformation |
| 123 | +# TODO: is "first output value" going to be reliable enough? |
| 124 | +ELB_DNS_NAME=$(aws cloudformation describe-stacks \ |
| 125 | + --stack-name $STACK_NAME \ |
| 126 | + --max-items 1 \ |
| 127 | + --query 'Stacks[].[ Outputs[0].[ OutputValue ] ]' \ |
| 128 | + --output=text) |
| 129 | + |
| 130 | +# get ELB friendly name through aws elb |
| 131 | +ELB_NAME=$(aws elb describe-load-balancers \ |
| 132 | + --query 'LoadBalancerDescriptions[].[ DNSName,LoadBalancerName ]' \ |
| 133 | + --output=text | grep -F $ELB_DNS_NAME | head -n1 | cut -f2) |
| 134 | +echo "Using ELB $ELB_NAME" |
| 135 | + |
| 136 | +# add or update a route53 alias record set to route queries to the ELB |
| 137 | +# this python script won't return until the wildcard domain is accessible |
| 138 | +python $DEIS_ROOT/tests/bin/route53-wildcard.py create $DEIS_TEST_DOMAIN $ELB_DNS_NAME |
| 139 | + |
| 140 | +# loop until at least one instance is "in service" with the ELB |
| 141 | +ATTEMPTS=45 |
| 142 | +SLEEPTIME=10 |
| 143 | +COUNTER=1 |
| 144 | +IN_SERVICE=0 |
| 145 | +until [ $IN_SERVICE -ge 1 ]; do |
| 146 | + if [ $COUNTER -gt $ATTEMPTS ]; then exit 1; fi # timeout after 7 1/2 minutes |
| 147 | + if [ $COUNTER -ne 1 ]; then sleep $SLEEPTIME; fi |
| 148 | + echo "Waiting for ELB to see an instance in service..." |
| 149 | + IN_SERVICE=$(aws elb describe-instance-health \ |
| 150 | + --load-balancer-name $ELB_NAME \ |
| 151 | + --query 'InstanceStates[].State' \ |
| 152 | + | grep InService | wc -l) |
| 153 | +done |
| 154 | + |
| 155 | +log_phase "Running integration suite" |
| 156 | + |
| 157 | +time make test-integration |
0 commit comments