github.com/chasestarr/deis@v1.13.5-0.20170519182049-1d9e59fbdbfc/tests/bin/test-integration-aws.sh (about)

     1  #!/usr/bin/env 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 -eo pipefail
     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 --disable-pip-version-check awscli boto docopt
    22  
    23  function cleanup_aws {
    24      if [ "$SKIP_CLEANUP" != true ]; then
    25          log_phase "Cleaning up"
    26          aws cloudformation delete-stack --stack-name $STACK_NAME
    27          python $DEIS_ROOT/contrib/aws/route53-wildcard.py delete $DEIS_TEST_DOMAIN $ELB_DNS_NAME
    28      fi
    29  }
    30  
    31  # setup callbacks on process exit and error
    32  trap cleanup_aws EXIT
    33  trap dump_logs ERR
    34  
    35  log_phase "Running style tests"
    36  
    37  make test-style
    38  
    39  log_phase "Running documentation tests"
    40  
    41  # test building documentation
    42  make -C docs/ test
    43  
    44  log_phase "Running unit tests"
    45  
    46  make test-unit
    47  
    48  log_phase "Building from current source tree"
    49  
    50  # build all docker images and client binaries
    51  make build
    52  
    53  # use the built client binaries
    54  export PATH=$DEIS_ROOT/deisctl:$DEIS_ROOT/client/dist:$PATH
    55  
    56  log_phase "Running functional tests"
    57  
    58  make test-functional
    59  
    60  export DEIS_NUM_INSTANCES=3
    61  log_phase "Provisioning $DEIS_NUM_INSTANCES-node CoreOS"
    62  
    63  # TODO: don't hardcode --key-names
    64  if ! aws ec2 describe-key-pairs --key-names "deis" >/dev/null ; then
    65      echo "Importing $DEIS_TEST_AUTH_KEY keypair to EC2"
    66      aws ec2 import-key-pair --key-name deis \
    67          --public-key-material file://~/.ssh/$DEIS_TEST_AUTH_KEY.pub \
    68          --output text
    69  fi
    70  
    71  make discovery-url
    72  
    73  # customize cloudformation.json to use m3.medium instances
    74  cat > $DEIS_ROOT/contrib/aws/cloudformation.json <<EOF
    75  [
    76      {
    77          "ParameterKey":     "KeyPair",
    78          "ParameterValue":   "deis"
    79      },
    80      {
    81          "ParameterKey":     "InstanceType",
    82          "ParameterValue":   "m3.medium"
    83      }
    84  ]
    85  EOF
    86  
    87  # add random characters after STACK_TAG to avoid collisions
    88  STACK_TAG=${STACK_TAG:-test}-$DEIS_TEST_ID
    89  STACK_NAME=deis-$STACK_TAG
    90  echo "Creating CloudFormation stack $STACK_NAME"
    91  $DEIS_ROOT/contrib/aws/provision-aws-cluster.sh $STACK_NAME
    92  
    93  # discard changes to cloudformation.json
    94  git checkout -- $DEIS_ROOT/contrib/aws/cloudformation.json
    95  
    96  # use the first cluster node for now
    97  INSTANCE_IDS=$(aws ec2 describe-instances \
    98      --filters Name=tag:aws:cloudformation:stack-name,Values=$STACK_NAME Name=instance-state-name,Values=running \
    99      --query 'Reservations[].Instances[].[ InstanceId ]' \
   100      --output text)
   101  export INSTANCE_ID=$(cut -d " " -f1 <<< $INSTANCE_IDS)
   102  export DEISCTL_TUNNEL=$(aws ec2 describe-instances \
   103      --instance-ids=$INSTANCE_ID \
   104      --filters Name=tag:aws:cloudformation:stack-name,Values=$STACK_NAME Name=instance-state-name,Values=running \
   105      --query 'Reservations[].Instances[].[ PublicDnsName ]' \
   106      --output text)
   107  
   108  log_phase "Waiting for etcd/fleet at $DEISCTL_TUNNEL"
   109  
   110  # wait for etcd up to 5 minutes
   111  WAIT_TIME=1
   112  until deisctl --request-timeout=1 list >/dev/null 2>&1; do
   113     (( WAIT_TIME += 1 ))
   114     if [ $WAIT_TIME -gt 300 ]; then
   115      log_phase "Timeout waiting for etcd/fleet"
   116      # run deisctl one last time without eating the error, so we can see what's up
   117      deisctl --request-timeout=1 list
   118      exit 1;
   119    fi
   120  done
   121  
   122  log_phase "etcd available after $WAIT_TIME seconds"
   123  
   124  log_phase "Publishing release from source tree"
   125  
   126  set +e
   127  trap - ERR
   128  
   129  RETRY_COUNT=1
   130  
   131  while [ $RETRY_COUNT -le 3 ]; do
   132    # TODO: detect where IMAGE_PREFIX=deis/ and DEV_REGISTRY=registry.hub.docker.com
   133    # and disallow it so we can't pollute the production account.
   134    make dev-release
   135    RESULT=$?
   136  
   137    if [ $RESULT -ne 0 ]; then
   138      echo "Docker Hub push failed. Attempt $RETRY_COUNT of 3."
   139    else
   140      break
   141    fi
   142  
   143    (( RETRY_COUNT += 1 ))
   144  done
   145  
   146  set -e
   147  trap dump_logs ERR
   148  
   149  if [ $RETRY_COUNT -gt 3 ]; then
   150    echo "Docker Hub push failed the maximum number of times, aborting."
   151    false
   152  fi
   153  
   154  log_phase "Provisioning Deis"
   155  
   156  export DEIS_TEST_DOMAIN=$STACK_TAG.$DEIS_TEST_DOMAIN
   157  
   158  # configure platform settings
   159  deisctl config platform set domain=$DEIS_TEST_DOMAIN
   160  deisctl config platform set sshPrivateKey=$DEIS_TEST_SSH_KEY
   161  
   162  time deisctl install platform
   163  time deisctl start platform
   164  
   165  # get ELB public DNS name through cloudformation
   166  # TODO: is "first output value" going to be reliable enough?
   167  ELB_DNS_NAME=$(aws cloudformation describe-stacks \
   168      --stack-name $STACK_NAME \
   169      --max-items 1 \
   170      --query 'Stacks[].[ Outputs[0].[ OutputValue ] ]' \
   171      --output=text)
   172  
   173  # get ELB friendly name through aws elb
   174  ELB_NAME=$(aws elb describe-load-balancers \
   175      --query 'LoadBalancerDescriptions[].[ DNSName,LoadBalancerName ]' \
   176      --output=text | grep -F $ELB_DNS_NAME | head -n1 | cut -f2)
   177  echo "Using ELB $ELB_NAME"
   178  
   179  # add or update a route53 alias record set to route queries to the ELB
   180  # this python script won't return until the wildcard domain is accessible
   181  python $DEIS_ROOT/contrib/aws/route53-wildcard.py create $DEIS_TEST_DOMAIN $ELB_DNS_NAME
   182  
   183  # loop until at least one instance is "in service" with the ELB
   184  ATTEMPTS=45
   185  SLEEPTIME=10
   186  COUNTER=1
   187  IN_SERVICE=0
   188  until [ $IN_SERVICE -ge 1 ]; do
   189      if [ $COUNTER -gt $ATTEMPTS ]; then exit 1; fi  # timeout after 7 1/2 minutes
   190      if [ $COUNTER -ne 1 ]; then sleep $SLEEPTIME; fi
   191      echo "Waiting for ELB to see an instance in service..."
   192      IN_SERVICE=$(aws elb describe-instance-health \
   193          --load-balancer-name $ELB_NAME \
   194          --query 'InstanceStates[].State' \
   195          | grep InService | wc -l)
   196  done
   197  
   198  log_phase "Running integration test suite"
   199  
   200  time make test-integration