#!/bin/bash # Basic integration tests with postgres. Requires docker to work. SOURCE="${BASH_SOURCE[0]}" while [ -h "$SOURCE" ]; do # resolve $SOURCE until the file is no longer a symlink DIR="$( cd -P "$( dirname "$SOURCE" )" && pwd )" SOURCE="$(readlink "$SOURCE")" [[ $SOURCE != /* ]] && SOURCE="$DIR/$SOURCE" # if $SOURCE was a relative symlink, we need to resolve it relative to the path where the symlink file was located done DIR="$( cd -P "$( dirname "$SOURCE" )" && pwd )" METRICS_DIR=$(pwd) # Read the absolute path to the exporter postgres_exporter=$(readlink -f $1) test_binary=$(readlink -f $2) export POSTGRES_PASSWORD=postgres exporter_port=9187 cd $DIR VERSIONS=( \ 9.1 \ 9.2 \ 9.3 \ 9.4 \ 9.5 \ 9.6 \ 10 \ ) wait_for_postgres(){ local ip=$1 local port=$2 if [ -z $ip ]; then echo "No IP specified." 1>&2 exit 1 fi if [ -z $port ]; then echo "No port specified." 1>&2 exit 1 fi local wait_start=$(date +%s) echo "Waiting for postgres to start listening..." while ! pg_isready --host=$ip --port=$port &> /dev/null; do if [ $(( $(date +%s) - $wait_start )) -gt $TIMEOUT ]; then echo "Timed out waiting for postgres to start!" 1>&2 exit 1 fi sleep 1 done } wait_for_exporter() { local wait_start=$(date +%s) echo "Waiting for exporter to start..." while ! nc -z localhost $exporter_port ; do if [ $(( $(date +%s) - $wait_start )) -gt $TIMEOUT ]; then echo "Timed out waiting for exporter!" 1>&2 exit 1 fi sleep 1 done } smoketest_postgres() { local version=$1 local CONTAINER_NAME=postgres_exporter-test-smoke local TIMEOUT=30 local IMAGE_NAME=postgres local CUR_IMAGE=$IMAGE_NAME:$version echo "#######################" echo "Standalone Postgres $version" echo "#######################" local docker_cmd="docker run -d -e POSTGRES_PASSWORD=$POSTGRES_PASSWORD $CUR_IMAGE" echo "Docker Cmd: $docker_cmd" CONTAINER_NAME=$($docker_cmd) standalone_ip=$(docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' $CONTAINER_NAME) trap "docker logs $CONTAINER_NAME ; docker kill $CONTAINER_NAME ; docker rm -v $CONTAINER_NAME; exit 1" EXIT INT TERM wait_for_postgres $standalone_ip 5432 # Run the test binary. DATA_SOURCE_NAME="postgresql://postgres:$POSTGRES_PASSWORD@$standalone_ip:5432/?sslmode=disable" $test_binary --log.level=debug || exit $? # Extract a raw metric list. DATA_SOURCE_NAME="postgresql://postgres:$POSTGRES_PASSWORD@$standalone_ip:5432/?sslmode=disable" $postgres_exporter --log.level=debug --web.listen-address=:$exporter_port & exporter_pid=$! trap "docker logs $CONTAINER_NAME ; docker kill $CONTAINER_NAME ; docker rm -v $CONTAINER_NAME; kill $exporter_pid; exit 1" EXIT INT TERM wait_for_exporter # Dump the metrics to a file. wget -q -O - http://localhost:$exporter_port/metrics 1> $METRICS_DIR/.metrics.single.$version.prom if [ "$?" != "0" ]; then echo "Failed on postgres $version ($DOCKER_IMAGE)" 1>&2 kill $exporter_pid exit 1 fi kill $exporter_pid docker kill $CONTAINER_NAME docker rm -v $CONTAINER_NAME trap - EXIT INT TERM echo "#######################" echo "Replicated Postgres $version" echo "#######################" old_pwd=$(pwd) cd docker-postgres-replication VERSION=$version p2 -t Dockerfile.p2 -o Dockerfile if [ "$?" != "0" ]; then echo "Templating failed" 1>&2 exit 1 fi trap "docker-compose logs; docker-compose down ; docker-compose rm -v; exit 1" EXIT INT TERM local compose_cmd="POSTGRES_PASSWORD=$POSTGRES_PASSWORD docker-compose up -d --force-recreate --build" echo "Compose Cmd: $compose_cmd" eval $compose_cmd master_container=$(docker-compose ps -q pg-master) slave_container=$(docker-compose ps -q pg-slave) master_ip=$(docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' $master_container) slave_ip=$(docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' $slave_container) echo "Got master IP: $master_ip" wait_for_postgres $master_ip 5432 wait_for_postgres $slave_ip 5432 DATA_SOURCE_NAME="postgresql://postgres:$POSTGRES_PASSWORD@$master_ip:5432/?sslmode=disable" $test_binary --log.level=debug || exit $? DATA_SOURCE_NAME="postgresql://postgres:$POSTGRES_PASSWORD@$master_ip:5432/?sslmode=disable" $postgres_exporter --log.level=debug --web.listen-address=:$exporter_port & exporter_pid=$! trap "docker-compose logs; docker-compose down ; docker-compose rm -v ; kill $exporter_pid; exit 1" EXIT INT TERM wait_for_exporter wget -q -O - http://localhost:$exporter_port/metrics 1> $METRICS_DIR/.metrics.replicated.$version.prom if [ "$?" != "0" ]; then echo "Failed on postgres $version ($DOCKER_IMAGE)" 1>&2 exit 1 fi kill $exporter_pid docker-compose down docker-compose rm -v trap - EXIT INT TERM cd $old_pwd } # Start pulling the docker images in advance for version in ${VERSIONS[@]}; do docker pull postgres:$version > /dev/null & done for version in ${VERSIONS[@]}; do echo "Testing postgres version $version" smoketest_postgres $version done