Update to docker-gen 0.7.0

Since [1] some timings seem to have changed. This caused the unit tests
to fail intermittently, from my testings especially on Ubuntu systems
(much less often on e.g. Arch).

This commit adds the `dockergen_wait_for_event` helper-function to try
and wait for the configuration to be generated by docker-gen before
continuing on with the actual tests themselves.

Additionally, at the end of every test file, all containers spun up by
the bats-tests will be stopped. This required adding the `bats-type`
label to every container started during the bats-tests.

The stopping of the containers reduces the amount of events docker-gen
has to process, thus resulting in lower wait times for the generation to
happen.

[1]: 50435652b1
This commit is contained in:
Pit Kleyersburg 2016-03-22 22:47:42 +01:00
parent f2966c5db1
commit 86aea653c8
9 changed files with 95 additions and 32 deletions

View file

@ -17,7 +17,7 @@ RUN echo "daemon off;" >> /etc/nginx/nginx.conf \
RUN wget -P /usr/local/bin https://godist.herokuapp.com/projects/ddollar/forego/releases/current/linux-amd64/forego \ RUN wget -P /usr/local/bin https://godist.herokuapp.com/projects/ddollar/forego/releases/current/linux-amd64/forego \
&& chmod u+x /usr/local/bin/forego && chmod u+x /usr/local/bin/forego
ENV DOCKER_GEN_VERSION 0.4.2 ENV DOCKER_GEN_VERSION 0.7.0
RUN wget https://github.com/jwilder/docker-gen/releases/download/$DOCKER_GEN_VERSION/docker-gen-linux-amd64-$DOCKER_GEN_VERSION.tar.gz \ RUN wget https://github.com/jwilder/docker-gen/releases/download/$DOCKER_GEN_VERSION/docker-gen-linux-amd64-$DOCKER_GEN_VERSION.tar.gz \
&& tar -C /usr/local/bin -xvzf docker-gen-linux-amd64-$DOCKER_GEN_VERSION.tar.gz \ && tar -C /usr/local/bin -xvzf docker-gen-linux-amd64-$DOCKER_GEN_VERSION.tar.gz \

View file

@ -2,8 +2,8 @@
.PHONY : test .PHONY : test
update-dependencies: update-dependencies:
docker pull jwilder/docker-gen:latest docker pull jwilder/docker-gen:0.7.0
docker pull nginx:latest docker pull nginx:1.9.12
docker pull python:3 docker pull python:3
docker pull rancher/socat-docker:latest docker pull rancher/socat-docker:latest
docker pull appropriate/curl:latest docker pull appropriate/curl:latest

View file

@ -4,10 +4,7 @@ load test_helpers
function setup { function setup {
# make sure to stop any web container before each test so we don't # make sure to stop any web container before each test so we don't
# have any unexpected contaiener running with VIRTUAL_HOST or VIRUTAL_PORT set # have any unexpected contaiener running with VIRTUAL_HOST or VIRUTAL_PORT set
CIDS=( $(docker ps -q --filter "label=bats-type=web") ) stop_bats_containers web
if [ ${#CIDS[@]} -gt 0 ]; then
docker stop ${CIDS[@]} >&2
fi
} }
@ -20,7 +17,7 @@ function setup {
# WHEN nginx-proxy runs with DEFAULT_HOST set to web.bats # WHEN nginx-proxy runs with DEFAULT_HOST set to web.bats
run nginxproxy $SUT_CONTAINER -v /var/run/docker.sock:/tmp/docker.sock:ro -e DEFAULT_HOST=web.bats run nginxproxy $SUT_CONTAINER -v /var/run/docker.sock:/tmp/docker.sock:ro -e DEFAULT_HOST=web.bats
assert_success assert_success
docker_wait_for_log $SUT_CONTAINER 3 "Watching docker events" docker_wait_for_log $SUT_CONTAINER 9 "Watching docker events"
# THEN querying the proxy without Host header → 200 # THEN querying the proxy without Host header → 200
run curl_container $SUT_CONTAINER / --head run curl_container $SUT_CONTAINER / --head
@ -30,3 +27,7 @@ function setup {
run curl_container $SUT_CONTAINER / --head --header "Host: something.I.just.made.up" run curl_container $SUT_CONTAINER / --head --header "Host: something.I.just.made.up"
assert_output -l 0 $'HTTP/1.1 200 OK\r' assert_output -l 0 $'HTTP/1.1 200 OK\r'
} }
@test "[$TEST_FILE] stop all bats containers" {
stop_bats_containers
}

View file

@ -14,7 +14,7 @@ load test_helpers
# WHEN nginx-proxy runs on our docker host using the default unix socket # WHEN nginx-proxy runs on our docker host using the default unix socket
run nginxproxy $SUT_CONTAINER -v /var/run/docker.sock:/tmp/docker.sock:ro run nginxproxy $SUT_CONTAINER -v /var/run/docker.sock:/tmp/docker.sock:ro
assert_success assert_success
docker_wait_for_log $SUT_CONTAINER 3 "Watching docker events" docker_wait_for_log $SUT_CONTAINER 9 "Watching docker events"
# THEN # THEN
assert_nginxproxy_behaves $SUT_CONTAINER assert_nginxproxy_behaves $SUT_CONTAINER
@ -27,7 +27,7 @@ load test_helpers
# WHEN nginx-proxy runs on our docker host using a custom unix socket # WHEN nginx-proxy runs on our docker host using a custom unix socket
run nginxproxy $SUT_CONTAINER -v /var/run/docker.sock:/f00.sock:ro -e DOCKER_HOST=unix:///f00.sock run nginxproxy $SUT_CONTAINER -v /var/run/docker.sock:/f00.sock:ro -e DOCKER_HOST=unix:///f00.sock
assert_success assert_success
docker_wait_for_log $SUT_CONTAINER 3 "Watching docker events" docker_wait_for_log $SUT_CONTAINER 9 "Watching docker events"
# THEN # THEN
assert_nginxproxy_behaves $SUT_CONTAINER assert_nginxproxy_behaves $SUT_CONTAINER
@ -44,7 +44,7 @@ load test_helpers
# WHEN nginx-proxy runs on our docker host using tcp to connect to our docker host # WHEN nginx-proxy runs on our docker host using tcp to connect to our docker host
run nginxproxy $SUT_CONTAINER -e DOCKER_HOST="tcp://bats-docker-tcp:2375" --link bats-docker-tcp:bats-docker-tcp run nginxproxy $SUT_CONTAINER -e DOCKER_HOST="tcp://bats-docker-tcp:2375" --link bats-docker-tcp:bats-docker-tcp
assert_success assert_success
docker_wait_for_log $SUT_CONTAINER 3 "Watching docker events" docker_wait_for_log $SUT_CONTAINER 9 "Watching docker events"
# THEN # THEN
assert_nginxproxy_behaves $SUT_CONTAINER assert_nginxproxy_behaves $SUT_CONTAINER
@ -57,28 +57,30 @@ load test_helpers
# GIVEN a simple nginx container # GIVEN a simple nginx container
run docker run -d \ run docker run -d \
--label bats-type="nginx" \
--name bats-nginx \ --name bats-nginx \
-v /etc/nginx/conf.d/ \ -v /etc/nginx/conf.d/ \
-v /etc/nginx/certs/ \ -v /etc/nginx/certs/ \
nginx:latest nginx:latest
assert_success assert_success
run retry 5 1s docker run appropriate/curl --silent --fail --head http://$(docker_ip bats-nginx)/ run retry 5 1s docker run --label bats-type="curl" appropriate/curl --silent --fail --head http://$(docker_ip bats-nginx)/
assert_output -l 0 $'HTTP/1.1 200 OK\r' assert_output -l 0 $'HTTP/1.1 200 OK\r'
# WHEN docker-gen runs on our docker host # WHEN docker-gen runs on our docker host
run docker run -d \ run docker run -d \
--label bats-type="docker-gen" \
--name bats-docker-gen \ --name bats-docker-gen \
-v /var/run/docker.sock:/tmp/docker.sock:ro \ -v /var/run/docker.sock:/tmp/docker.sock:ro \
-v $BATS_TEST_DIRNAME/../nginx.tmpl:/etc/docker-gen/templates/nginx.tmpl:ro \ -v $BATS_TEST_DIRNAME/../nginx.tmpl:/etc/docker-gen/templates/nginx.tmpl:ro \
--volumes-from bats-nginx \ --volumes-from bats-nginx \
jwilder/docker-gen:latest \ jwilder/docker-gen:0.7.0 \
-notify-sighup bats-nginx \ -notify-sighup bats-nginx \
-watch \ -watch \
-only-exposed \ -only-exposed \
/etc/docker-gen/templates/nginx.tmpl \ /etc/docker-gen/templates/nginx.tmpl \
/etc/nginx/conf.d/default.conf /etc/nginx/conf.d/default.conf
assert_success assert_success
docker_wait_for_log bats-docker-gen 6 "Watching docker events" docker_wait_for_log bats-docker-gen 9 "Watching docker events"
# Give some time to the docker-gen container to notify bats-nginx so it # Give some time to the docker-gen container to notify bats-nginx so it
# reloads its config # reloads its config
@ -94,6 +96,10 @@ load test_helpers
assert_nginxproxy_behaves bats-nginx assert_nginxproxy_behaves bats-nginx
} }
@test "[$TEST_FILE] stop all bats containers" {
stop_bats_containers
}
# $1 nginx-proxy container # $1 nginx-proxy container
function assert_nginxproxy_behaves { function assert_nginxproxy_behaves {

View file

@ -13,6 +13,11 @@ function docker_ip {
docker inspect --format '{{ .NetworkSettings.IPAddress }}' $1 docker inspect --format '{{ .NetworkSettings.IPAddress }}' $1
} }
# get the ip of docker container $1
function docker_id {
docker inspect --format '{{ .ID }}' $1
}
# get the running state of container $1 # get the running state of container $1
# → true/false # → true/false
# fails if the container does not exist # fails if the container does not exist
@ -52,9 +57,10 @@ function docker_tcp {
local container_name="$1" local container_name="$1"
docker_clean $container_name docker_clean $container_name
docker run -d \ docker run -d \
--label bats-type="socat" \
--name $container_name \ --name $container_name \
--expose 2375 \ --expose 2375 \
-v /var/run/docker.sock:/var/run/docker.sock \ -v /var/run/docker.sock:/var/run/docker.sock \
rancher/socat-docker rancher/socat-docker
docker run --link "$container_name:docker" docker:1.9 version docker run --label bats-type="docker" --link "$container_name:docker" docker:1.9 version
} }

View file

@ -5,22 +5,21 @@ SUT_CONTAINER=bats-nginx-proxy-${TEST_FILE}
function setup { function setup {
# make sure to stop any web container before each test so we don't # make sure to stop any web container before each test so we don't
# have any unexpected contaiener running with VIRTUAL_HOST or VIRUTAL_PORT set # have any unexpected contaiener running with VIRTUAL_HOST or VIRUTAL_PORT set
CIDS=( $(docker ps -q --filter "label=bats-type=web") ) stop_bats_containers web
if [ ${#CIDS[@]} -gt 0 ]; then
docker stop ${CIDS[@]} >&2
fi
} }
@test "[$TEST_FILE] start a nginx-proxy container" { @test "[$TEST_FILE] start a nginx-proxy container" {
run nginxproxy $SUT_CONTAINER -v /var/run/docker.sock:/tmp/docker.sock:ro run nginxproxy $SUT_CONTAINER -v /var/run/docker.sock:/tmp/docker.sock:ro
assert_success assert_success
docker_wait_for_log $SUT_CONTAINER 3 "Watching docker events" docker_wait_for_log $SUT_CONTAINER 9 "Watching docker events"
} }
@test "[$TEST_FILE] nginx-proxy forwards requests for 2 hosts" { @test "[$TEST_FILE] nginx-proxy forwards requests for 2 hosts" {
# WHEN a container runs a web server with VIRTUAL_HOST set for multiple hosts # WHEN a container runs a web server with VIRTUAL_HOST set for multiple hosts
prepare_web_container bats-multiple-hosts-1 80 -e VIRTUAL_HOST=multiple-hosts-1-A.bats,multiple-hosts-1-B.bats prepare_web_container bats-multiple-hosts-1 80 -e VIRTUAL_HOST=multiple-hosts-1-A.bats,multiple-hosts-1-B.bats
dockergen_wait_for_event $SUT_CONTAINER start bats-multiple-hosts-1
sleep 1
# THEN querying the proxy without Host header → 503 # THEN querying the proxy without Host header → 503
run curl_container $SUT_CONTAINER / --head run curl_container $SUT_CONTAINER / --head
@ -38,3 +37,7 @@ function setup {
run curl_container $SUT_CONTAINER /data --header 'Host: multiple-hosts-1-B.bats' run curl_container $SUT_CONTAINER /data --header 'Host: multiple-hosts-1-B.bats'
assert_output "answer from port 80" assert_output "answer from port 80"
} }
@test "[$TEST_FILE] stop all bats containers" {
stop_bats_containers
}

View file

@ -5,10 +5,7 @@ SUT_CONTAINER=bats-nginx-proxy-${TEST_FILE}
function setup { function setup {
# make sure to stop any web container before each test so we don't # make sure to stop any web container before each test so we don't
# have any unexpected contaiener running with VIRTUAL_HOST or VIRUTAL_PORT set # have any unexpected contaiener running with VIRTUAL_HOST or VIRUTAL_PORT set
CIDS=( $(docker ps -q --filter "label=bats-type=web") ) stop_bats_containers web
if [ ${#CIDS[@]} -gt 0 ]; then
docker stop ${CIDS[@]} >&2
fi
} }
@ -16,13 +13,15 @@ function setup {
# GIVEN nginx-proxy # GIVEN nginx-proxy
run nginxproxy $SUT_CONTAINER -v /var/run/docker.sock:/tmp/docker.sock:ro run nginxproxy $SUT_CONTAINER -v /var/run/docker.sock:/tmp/docker.sock:ro
assert_success assert_success
docker_wait_for_log $SUT_CONTAINER 3 "Watching docker events" docker_wait_for_log $SUT_CONTAINER 9 "Watching docker events"
} }
@test "[$TEST_FILE] nginx-proxy defaults to the service running on port 80" { @test "[$TEST_FILE] nginx-proxy defaults to the service running on port 80" {
# WHEN # WHEN
prepare_web_container bats-web-${TEST_FILE}-1 "80 90" -e VIRTUAL_HOST=web.bats prepare_web_container bats-web-${TEST_FILE}-1 "80 90" -e VIRTUAL_HOST=web.bats
dockergen_wait_for_event $SUT_CONTAINER start bats-web-${TEST_FILE}-1
sleep 1
# THEN # THEN
assert_response_is_from_port 80 assert_response_is_from_port 80
@ -32,6 +31,8 @@ function setup {
@test "[$TEST_FILE] VIRTUAL_PORT=90 while port 80 is also exposed" { @test "[$TEST_FILE] VIRTUAL_PORT=90 while port 80 is also exposed" {
# GIVEN # GIVEN
prepare_web_container bats-web-${TEST_FILE}-2 "80 90" -e VIRTUAL_HOST=web.bats -e VIRTUAL_PORT=90 prepare_web_container bats-web-${TEST_FILE}-2 "80 90" -e VIRTUAL_HOST=web.bats -e VIRTUAL_PORT=90
dockergen_wait_for_event $SUT_CONTAINER start bats-web-${TEST_FILE}-2
sleep 1
# THEN # THEN
assert_response_is_from_port 90 assert_response_is_from_port 90
@ -41,11 +42,17 @@ function setup {
@test "[$TEST_FILE] single exposed port != 80" { @test "[$TEST_FILE] single exposed port != 80" {
# GIVEN # GIVEN
prepare_web_container bats-web-${TEST_FILE}-3 1234 -e VIRTUAL_HOST=web.bats prepare_web_container bats-web-${TEST_FILE}-3 1234 -e VIRTUAL_HOST=web.bats
dockergen_wait_for_event $SUT_CONTAINER start bats-web-${TEST_FILE}-3
sleep 1
# THEN # THEN
assert_response_is_from_port 1234 assert_response_is_from_port 1234
} }
@test "[$TEST_FILE] stop all bats containers" {
stop_bats_containers
}
# assert querying nginx-proxy provides a response from the expected port of the web container # assert querying nginx-proxy provides a response from the expected port of the web container
# $1 port we are expecting an response from # $1 port we are expecting an response from

View file

@ -33,6 +33,7 @@ function nginxproxy {
shift shift
docker_clean $container_name \ docker_clean $container_name \
&& docker run -d \ && docker run -d \
--label bats-type="nginx-proxy" \
--name $container_name \ --name $container_name \
"$@" \ "$@" \
$SUT_IMAGE \ $SUT_IMAGE \
@ -66,7 +67,7 @@ function curl_container {
local -r container=$1 local -r container=$1
local -r path=$2 local -r path=$2
shift 2 shift 2
docker run appropriate/curl --silent \ docker run --label bats-type="curl" appropriate/curl --silent \
--connect-timeout 5 \ --connect-timeout 5 \
--max-time 20 \ --max-time 20 \
"$@" \ "$@" \
@ -128,7 +129,39 @@ function prepare_web_container {
# THEN querying directly port works # THEN querying directly port works
IFS=$' \t\n' # See https://github.com/sstephenson/bats/issues/89 IFS=$' \t\n' # See https://github.com/sstephenson/bats/issues/89
for port in $ports; do for port in $ports; do
run retry 5 1s docker run appropriate/curl --silent --fail http://$(docker_ip $container_name):$port/data run retry 5 1s docker run --label bats-type="curl" appropriate/curl --silent --fail http://$(docker_ip $container_name):$port/data
assert_output "answer from port $port" assert_output "answer from port $port"
done done
} }
# stop all containers with the "bats-type" label (matching the optionally supplied value)
#
# $1 optional label value
function stop_bats_containers {
local -r value=$1
if [ -z "$value" ]; then
CIDS=( $(docker ps -q --filter "label=bats-type") )
else
CIDS=( $(docker ps -q --filter "label=bats-type=$value") )
fi
if [ ${#CIDS[@]} -gt 0 ]; then
docker stop ${CIDS[@]} >&2
fi
}
# wait for a docker-gen container to receive a specified event from a
# container with the specified ID/name
#
# $1 docker-gen container name
# $2 event
# $3 ID/name of container to receive event from
function dockergen_wait_for_event {
local -r container=$1
local -r event=$2
local -r other=$3
local -r did=$(docker_id "$other")
docker_wait_for_log "$container" 9 "Received event $event for container ${did:0:12}"
}

View file

@ -5,10 +5,7 @@ SUT_CONTAINER=bats-nginx-proxy-${TEST_FILE}
function setup { function setup {
# make sure to stop any web container before each test so we don't # make sure to stop any web container before each test so we don't
# have any unexpected contaiener running with VIRTUAL_HOST or VIRUTAL_PORT set # have any unexpected contaiener running with VIRTUAL_HOST or VIRUTAL_PORT set
CIDS=( $(docker ps -q --filter "label=bats-type=web") ) stop_bats_containers web
if [ ${#CIDS[@]} -gt 0 ]; then
docker stop ${CIDS[@]} >&2
fi
} }
@ -16,13 +13,15 @@ function setup {
# GIVEN # GIVEN
run nginxproxy $SUT_CONTAINER -v /var/run/docker.sock:/tmp/docker.sock:ro run nginxproxy $SUT_CONTAINER -v /var/run/docker.sock:/tmp/docker.sock:ro
assert_success assert_success
docker_wait_for_log $SUT_CONTAINER 3 "Watching docker events" docker_wait_for_log $SUT_CONTAINER 9 "Watching docker events"
} }
@test "[$TEST_FILE] VIRTUAL_HOST=*.wildcard.bats" { @test "[$TEST_FILE] VIRTUAL_HOST=*.wildcard.bats" {
# WHEN # WHEN
prepare_web_container bats-wildcard-hosts-1 80 -e VIRTUAL_HOST=*.wildcard.bats prepare_web_container bats-wildcard-hosts-1 80 -e VIRTUAL_HOST=*.wildcard.bats
dockergen_wait_for_event $SUT_CONTAINER start bats-wildcard-hosts-1
sleep 1
# THEN # THEN
assert_200 f00.wildcard.bats assert_200 f00.wildcard.bats
@ -33,6 +32,8 @@ function setup {
@test "[$TEST_FILE] VIRTUAL_HOST=wildcard.bats.*" { @test "[$TEST_FILE] VIRTUAL_HOST=wildcard.bats.*" {
# WHEN # WHEN
prepare_web_container bats-wildcard-hosts-2 80 -e VIRTUAL_HOST=wildcard.bats.* prepare_web_container bats-wildcard-hosts-2 80 -e VIRTUAL_HOST=wildcard.bats.*
dockergen_wait_for_event $SUT_CONTAINER start bats-wildcard-hosts-2
sleep 1
# THEN # THEN
assert_200 wildcard.bats.f00 assert_200 wildcard.bats.f00
@ -43,6 +44,8 @@ function setup {
@test "[$TEST_FILE] VIRTUAL_HOST=~^foo\.bar\..*\.bats" { @test "[$TEST_FILE] VIRTUAL_HOST=~^foo\.bar\..*\.bats" {
# WHEN # WHEN
prepare_web_container bats-wildcard-hosts-2 80 -e VIRTUAL_HOST=~^foo\.bar\..*\.bats prepare_web_container bats-wildcard-hosts-2 80 -e VIRTUAL_HOST=~^foo\.bar\..*\.bats
dockergen_wait_for_event $SUT_CONTAINER start bats-wildcard-hosts-2
sleep 1
# THEN # THEN
assert_200 foo.bar.whatever.bats assert_200 foo.bar.whatever.bats
@ -51,6 +54,10 @@ function setup {
} }
@test "[$TEST_FILE] stop all bats containers" {
stop_bats_containers
}
# assert that querying nginx-proxy with the given Host header produces a `HTTP 200` response # assert that querying nginx-proxy with the given Host header produces a `HTTP 200` response
# $1 Host HTTP header to use when querying nginx-proxy # $1 Host HTTP header to use when querying nginx-proxy