forked from TrueCloudLab/distribution
Merge pull request #570 from dmcgowan/docker-integration
contrib: Docker integration tests
This commit is contained in:
commit
d0fda14e85
7 changed files with 318 additions and 144 deletions
46
contrib/docker-integration/Dockerfile
Normal file
46
contrib/docker-integration/Dockerfile
Normal file
|
@ -0,0 +1,46 @@
|
|||
FROM debian:jessie
|
||||
|
||||
MAINTAINER Docker Distribution Team <distribution@docker.com>
|
||||
|
||||
# compile and runtime deps
|
||||
# https://github.com/docker/docker/blob/master/project/PACKAGERS.md#runtime-dependencies
|
||||
RUN apt-get update && apt-get install -y --no-install-recommends \
|
||||
# For DIND
|
||||
ca-certificates \
|
||||
curl \
|
||||
iptables \
|
||||
procps \
|
||||
e2fsprogs \
|
||||
xz-utils \
|
||||
# For build
|
||||
build-essential \
|
||||
file \
|
||||
git \
|
||||
net-tools \
|
||||
&& apt-get clean && rm -rf /var/lib/apt/lists/*
|
||||
|
||||
# Install Docker
|
||||
ENV VERSION 1.7.0-rc1
|
||||
RUN curl -L -o /usr/local/bin/docker https://test.docker.com/builds/Linux/x86_64/docker-${VERSION} \
|
||||
&& chmod +x /usr/local/bin/docker
|
||||
|
||||
# Install DIND
|
||||
RUN curl -L -o /dind https://raw.githubusercontent.com/docker/docker/master/hack/dind \
|
||||
&& chmod +x /dind
|
||||
|
||||
# Install bats
|
||||
RUN cd /usr/local/src/ \
|
||||
&& git clone https://github.com/sstephenson/bats.git \
|
||||
&& cd bats \
|
||||
&& ./install.sh /usr/local
|
||||
|
||||
# Install docker-compose
|
||||
RUN curl -L https://github.com/docker/compose/releases/download/1.2.0/docker-compose-`uname -s`-`uname -m` > /usr/local/bin/docker-compose \
|
||||
&& chmod +x /usr/local/bin/docker-compose
|
||||
|
||||
RUN mkdir -p /go/src/github.com/docker/distribution
|
||||
WORKDIR /go/src/github.com/docker/distribution/contrib/docker-integration
|
||||
|
||||
VOLUME /var/lib/docker
|
||||
|
||||
ENTRYPOINT ["/dind"]
|
|
@ -1,24 +0,0 @@
|
|||
.PHONY: build test
|
||||
|
||||
build:
|
||||
docker-compose build
|
||||
|
||||
start: build
|
||||
docker-compose up -d
|
||||
|
||||
stop:
|
||||
docker-compose stop
|
||||
|
||||
clean:
|
||||
docker-compose kill
|
||||
docker-compose rm -f
|
||||
|
||||
install:
|
||||
sh ./install_certs.sh localhost
|
||||
sh ./install_certs.sh localregistry
|
||||
|
||||
test:
|
||||
@echo "!!!!Ensure /etc/hosts entry is updated for localregistry and make install has been run"
|
||||
sh ./test_docker.sh localregistry
|
||||
|
||||
all: build
|
|
@ -1,32 +1,88 @@
|
|||
# Docker Registry Multi-Configuration Testing
|
||||
# Docker Registry Integration Testing
|
||||
|
||||
This compose configuration is intended to setup a testing environment for Docker
|
||||
These integration tests cover interactions between the Docker daemon and the
|
||||
registry server. All tests are run using the docker cli.
|
||||
|
||||
The compose configuration is intended to setup a testing environment for Docker
|
||||
using multiple registry configurations. These configurations include different
|
||||
combinations of a v1 and v2 registry as well as TLS configurations.
|
||||
|
||||
### Limitations
|
||||
## Running inside of Docker
|
||||
### Get integration container
|
||||
The container image to run the integation tests will need to be pulled or built
|
||||
locally.
|
||||
|
||||
Currently this setup is configured to use localhost as the hostname which
|
||||
limits the ease of testing within Docker since localhost is always treated
|
||||
as an insecure registry. To treat localhost as secure the Docker code must
|
||||
be modified. Without localhost as secure, the test cases will not distinguish
|
||||
between a TLS configuration with a CA and self-signed.
|
||||
*Building locally*
|
||||
```
|
||||
$ docker build -t distribution/docker-integration .
|
||||
```
|
||||
|
||||
### Run script
|
||||
|
||||
Invoke the tests within Docker through the `run.sh` script.
|
||||
|
||||
```
|
||||
$ ./run.sh
|
||||
```
|
||||
|
||||
Run with aufs driver and tmp volume
|
||||
**NOTE: Using a volume will prevent multiple runs from needing to
|
||||
re-pull images**
|
||||
```
|
||||
$ DOCKER_GRAPHDRIVER=aufs DOCKER_VOLUME=/tmp/volume ./run.sh
|
||||
```
|
||||
|
||||
### Example developer flow
|
||||
|
||||
These tests are useful for developing both as a registry and docker
|
||||
core developer. The following setup may be used to do integration
|
||||
testing between development versions
|
||||
|
||||
Insert into your `.zshrc` or `.bashrc`
|
||||
|
||||
```
|
||||
# /usr/lib/docker for Docker-in-Docker
|
||||
# Set this directory to make each invocation run much faster, without
|
||||
# the need to repull images.
|
||||
export DOCKER_VOLUME=$HOME/.docker-test-volume
|
||||
|
||||
# Use overlay for all Docker testing, try aufs if overlay not supported
|
||||
export DOCKER_GRAPHDRIVER=overlay
|
||||
|
||||
# Name this according to personal preference
|
||||
function rdtest() {
|
||||
if [ "$1" != "" ]; then
|
||||
DOCKER_BINARY=$GOPATH/src/github.com/docker/docker/bundles/$1/binary/docker
|
||||
if [ ! -f $DOCKER_BINARY ]; then
|
||||
current_version=`cat $GOPATH/src/github.com/docker/docker/VERSION`
|
||||
echo "$DOCKER_BINARY does not exist"
|
||||
echo "Current checked out docker version: $current_version"
|
||||
echo "Checkout desired version and run 'make binary' from $GOPATH/src/github.com/docker/docker"
|
||||
return 1
|
||||
fi
|
||||
fi
|
||||
|
||||
$GOPATH/src/github.com/docker/distribution/contrib/docker-integration/run.sh
|
||||
}
|
||||
```
|
||||
|
||||
Run with Docker release version
|
||||
```
|
||||
$ rdtest
|
||||
```
|
||||
|
||||
Run using local development version of docker
|
||||
```
|
||||
$ cd $GOPATH/src/github.com/docker/docker
|
||||
$ make binary
|
||||
$ rdtest `cat VERSION`
|
||||
```
|
||||
|
||||
## Running manually outside of Docker
|
||||
|
||||
### Install Docker Compose
|
||||
|
||||
1. Open a new terminal on the host with your `distribution` source.
|
||||
|
||||
2. Get the `docker-compose` binary.
|
||||
|
||||
$ sudo wget https://github.com/docker/compose/releases/download/1.1.0/docker-compose-`uname -s`-`uname -m` -O /usr/local/bin/docker-compose
|
||||
|
||||
This command installs the binary in the `/usr/local/bin` directory.
|
||||
|
||||
3. Add executable permissions to the binary.
|
||||
|
||||
$ sudo chmod +x /usr/local/bin/docker-compose
|
||||
|
||||
## Usage
|
||||
[Docker Compose Installation Guide](http://docs.docker.com/compose/install/)
|
||||
|
||||
### Start compose setup
|
||||
```
|
||||
|
@ -34,7 +90,8 @@ docker-compose up
|
|||
```
|
||||
|
||||
### Install Certificates
|
||||
The certificates must be installed in /etc/docker/cert.d in order to use TLS client auth and use the CA certificate.
|
||||
The certificates must be installed in /etc/docker/cert.d in order to use TLS
|
||||
client auth and use the CA certificate.
|
||||
```
|
||||
sudo sh ./install_certs.sh
|
||||
```
|
||||
|
@ -52,6 +109,16 @@ docker push localhost:5441/hello-world
|
|||
# Perform login using user `testuser` and password `passpassword`
|
||||
```
|
||||
|
||||
### Set /etc/hosts entry
|
||||
Find the non-localhost ip address of local machine
|
||||
|
||||
### Run bats
|
||||
Run the bats tests after updating /etc/hosts, installing the certificates, and
|
||||
running the `docker-compose` script.
|
||||
```
|
||||
bats -p .
|
||||
```
|
||||
|
||||
## Configurations
|
||||
|
||||
Port | V2 | V1 | TLS | Authentication
|
||||
|
@ -59,6 +126,7 @@ Port | V2 | V1 | TLS | Authentication
|
|||
5000 | yes | yes | no | none
|
||||
5001 | no | yes | no | none
|
||||
5002 | yes | no | no | none
|
||||
5011 | no | yes | yes | none
|
||||
5440 | yes | yes | yes | none
|
||||
5441 | yes | yes | yes | basic (testuser/passpassword)
|
||||
5442 | yes | yes | yes | TLS client
|
||||
|
|
36
contrib/docker-integration/run.sh
Executable file
36
contrib/docker-integration/run.sh
Executable file
|
@ -0,0 +1,36 @@
|
|||
#!/usr/bin/env bash
|
||||
set -e
|
||||
|
||||
cd "$(dirname "$(readlink -f "$BASH_SOURCE")")"
|
||||
|
||||
# Root directory of Distribution
|
||||
DISTRIBUTION_ROOT=$(cd ../..; pwd -P)
|
||||
|
||||
volumeMount=""
|
||||
if [ "$DOCKER_VOLUME" != "" ]; then
|
||||
volumeMount="-v ${DOCKER_VOLUME}:/var/lib/docker"
|
||||
fi
|
||||
|
||||
dockerMount=""
|
||||
if [ "$DOCKER_BINARY" != "" ]; then
|
||||
dockerMount="-v ${DOCKER_BINARY}:/usr/local/bin/docker"
|
||||
fi
|
||||
|
||||
# Image containing the integration tests environment.
|
||||
INTEGRATION_IMAGE=${INTEGRATION_IMAGE:-distribution/docker-integration}
|
||||
|
||||
# Make sure we upgrade the integration environment.
|
||||
docker pull $INTEGRATION_IMAGE
|
||||
|
||||
# Start the integration tests in a Docker container.
|
||||
ID=$(docker run -d -t --privileged $volumeMount $dockerMount \
|
||||
-v ${DISTRIBUTION_ROOT}:/go/src/github.com/docker/distribution \
|
||||
-e "STORAGE_DRIVER=$DOCKER_GRAPHDRIVER" \
|
||||
-e "EXEC_DRIVER=$EXEC_DRIVER" \
|
||||
${INTEGRATION_IMAGE} \
|
||||
./test_runner.sh "$@")
|
||||
|
||||
# Clean it up when we exit.
|
||||
trap "docker rm -f -v $ID > /dev/null" EXIT
|
||||
|
||||
docker logs -f $ID
|
|
@ -1,98 +0,0 @@
|
|||
#!/bin/sh
|
||||
|
||||
hostname=$1
|
||||
if [ "$hostname" = "" ]; then
|
||||
hostname="localhost"
|
||||
fi
|
||||
|
||||
docker pull hello-world
|
||||
|
||||
# TLS Configuration chart
|
||||
# Username/Password: testuser/passpassword
|
||||
# | ca | client | basic | notes
|
||||
# 5440 | yes | no | no | Tests CA certificate
|
||||
# 5441 | yes | no | yes | Tests basic auth over TLS
|
||||
# 5442 | yes | yes | no | Tests client auth with client CA
|
||||
# 5443 | yes | yes | no | Tests client auth without client CA
|
||||
# 5444 | yes | yes | yes | Tests using basic auth + tls auth
|
||||
# 5445 | no | no | no | Tests insecure using TLS
|
||||
# 5446 | no | no | yes | Tests sending credentials to server with insecure TLS
|
||||
# 5447 | no | yes | no | Tests client auth to insecure
|
||||
# 5448 | yes | no | no | Bad SSL version
|
||||
docker tag -f hello-world $hostname:5440/hello-world
|
||||
docker push $hostname:5440/hello-world
|
||||
if [ $? -ne 0 ]; then
|
||||
echo "Fail to push"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
docker login -u testuser -p passpassword -e distribution@docker.com $hostname:5441
|
||||
if [ $? -ne 0 ]; then
|
||||
echo "Failed to login"
|
||||
exit 1
|
||||
fi
|
||||
docker tag -f hello-world $hostname:5441/hello-world
|
||||
docker push $hostname:5441/hello-world
|
||||
if [ $? -ne 0 ]; then
|
||||
echo "Fail to push"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
docker tag -f hello-world $hostname:5442/hello-world
|
||||
docker push $hostname:5442/hello-world
|
||||
if [ $? -ne 0 ]; then
|
||||
echo "Fail to push"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
docker tag -f hello-world $hostname:5443/hello-world
|
||||
docker push $hostname:5443/hello-world
|
||||
if [ $? -eq 0 ]; then
|
||||
echo "Expected failure"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
docker login -u testuser -p passpassword -e distribution@docker.com $hostname:5444
|
||||
if [ $? -ne 0 ]; then
|
||||
echo "Failed to login"
|
||||
exit 1
|
||||
fi
|
||||
docker tag -f hello-world $hostname:5444/hello-world
|
||||
docker push $hostname:5444/hello-world
|
||||
if [ $? -ne 0 ]; then
|
||||
echo "Fail to push"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
docker tag -f hello-world $hostname:5445/hello-world
|
||||
docker push $hostname:5445/hello-world
|
||||
if [ $? -eq 0 ]; then
|
||||
echo "Expected failure with insecure registry"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
docker login -u testuser -p passpassword -e distribution@docker.com $hostname:5446
|
||||
if [ $? -ne 0 ]; then
|
||||
echo "Failed to login"
|
||||
exit 1
|
||||
fi
|
||||
docker tag -f hello-world $hostname:5446/hello-world
|
||||
docker push $hostname:5446/hello-world
|
||||
if [ $? -eq 0 ]; then
|
||||
echo "Expected failure with insecure registry"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
docker tag -f hello-world $hostname:5447/hello-world
|
||||
docker push $hostname:5447/hello-world
|
||||
if [ $? -eq 0 ]; then
|
||||
echo "Expected failure with insecure registry"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
docker tag -f hello-world $hostname:5448/hello-world
|
||||
docker push $hostname:5448/hello-world
|
||||
if [ $? -eq 0 ]; then
|
||||
echo "Expected failure contacting with sslv3"
|
||||
exit 1
|
||||
fi
|
50
contrib/docker-integration/test_runner.sh
Executable file
50
contrib/docker-integration/test_runner.sh
Executable file
|
@ -0,0 +1,50 @@
|
|||
#!/usr/bin/env bash
|
||||
set -e
|
||||
|
||||
cd "$(dirname "$(readlink -f "$BASH_SOURCE")")"
|
||||
|
||||
# Load the helpers.
|
||||
#. helpers.bash
|
||||
|
||||
TESTS=${@:-.}
|
||||
|
||||
# Drivers to use for Docker engines the tests are going to create.
|
||||
STORAGE_DRIVER=${STORAGE_DRIVER:-overlay}
|
||||
EXEC_DRIVER=${EXEC_DRIVER:-native}
|
||||
|
||||
|
||||
function execute() {
|
||||
>&2 echo "++ $@"
|
||||
eval "$@"
|
||||
}
|
||||
|
||||
# Set IP address in /etc/hosts for localregistry
|
||||
IP=$(ifconfig eth0|grep "inet addr:"| cut -d: -f2 | awk '{ print $1}')
|
||||
execute echo "$IP localregistry" >> /etc/hosts
|
||||
|
||||
# Setup certificates
|
||||
execute sh install_certs.sh localregistry
|
||||
|
||||
# Start the docker engine.
|
||||
execute docker --daemon --log-level=panic \
|
||||
--storage-driver="$STORAGE_DRIVER" --exec-driver="$EXEC_DRIVER" &
|
||||
DOCKER_PID=$!
|
||||
|
||||
# Wait for it to become reachable.
|
||||
tries=10
|
||||
until docker version &> /dev/null; do
|
||||
(( tries-- ))
|
||||
if [ $tries -le 0 ]; then
|
||||
echo >&2 "error: daemon failed to start"
|
||||
exit 1
|
||||
fi
|
||||
sleep 1
|
||||
done
|
||||
|
||||
execute time docker-compose build
|
||||
|
||||
execute docker-compose up -d
|
||||
|
||||
# Run the tests.
|
||||
execute time bats -p $TESTS
|
||||
|
96
contrib/docker-integration/tls.bats
Normal file
96
contrib/docker-integration/tls.bats
Normal file
|
@ -0,0 +1,96 @@
|
|||
# Registry host name, should be set to non-localhost address and match
|
||||
# DNS name in nginx/ssl certificates and what is installed in /etc/docker/cert.d
|
||||
hostname="localregistry"
|
||||
|
||||
image="hello-world:latest"
|
||||
|
||||
# Login information, should match values in nginx/test.passwd
|
||||
user="testuser"
|
||||
password="passpassword"
|
||||
email="distribution@docker.com"
|
||||
|
||||
function setup() {
|
||||
docker pull $image
|
||||
}
|
||||
|
||||
# has_digest enforces the last output line is "Digest: sha256:..."
|
||||
# the input is the name of the array containing the output lines
|
||||
function has_digest() {
|
||||
name=$1[@]
|
||||
lines=("${!name}")
|
||||
length=${#lines[@]}
|
||||
digest_idx=$((length-1))
|
||||
value=${lines[$digest_idx]}
|
||||
result=$(echo "$value"|cut -d':' -f1,2)
|
||||
[ "$result" = "Digest: sha256" ]
|
||||
}
|
||||
|
||||
function login() {
|
||||
run docker login -u $user -p $password -e $email $1
|
||||
[ "$status" -eq 0 ]
|
||||
# First line is WARNING about credential save
|
||||
[ "${lines[1]}" = "Login Succeeded" ]
|
||||
}
|
||||
|
||||
@test "Test valid certificates" {
|
||||
docker tag -f $image $hostname:5440/$image
|
||||
run docker push $hostname:5440/$image
|
||||
[ "$status" -eq 0 ]
|
||||
has_digest lines
|
||||
}
|
||||
|
||||
@test "Test basic auth" {
|
||||
login $hostname:5441
|
||||
docker tag -f $image $hostname:5441/$image
|
||||
run docker push $hostname:5441/$image
|
||||
[ "$status" -eq 0 ]
|
||||
has_digest lines
|
||||
}
|
||||
|
||||
@test "Test TLS client auth" {
|
||||
docker tag -f $image $hostname:5442/$image
|
||||
run docker push $hostname:5442/$image
|
||||
[ "$status" -eq 0 ]
|
||||
has_digest lines
|
||||
}
|
||||
|
||||
@test "Test TLS client with invalid certificate authority fails" {
|
||||
docker tag -f $image $hostname:5443/$image
|
||||
run docker push $hostname:5443/$image
|
||||
[ "$status" -ne 0 ]
|
||||
}
|
||||
|
||||
@test "Test basic auth with TLS client auth" {
|
||||
login $hostname:5444
|
||||
docker tag -f $image $hostname:5444/$image
|
||||
run docker push $hostname:5444/$image
|
||||
[ "$status" -eq 0 ]
|
||||
has_digest lines
|
||||
}
|
||||
|
||||
@test "Test unknown certificate authority fails" {
|
||||
docker tag -f $image $hostname:5445/$image
|
||||
run docker push $hostname:5445/$image
|
||||
[ "$status" -ne 0 ]
|
||||
}
|
||||
|
||||
@test "Test basic auth with unknown certificate authority fails" {
|
||||
run login $hostname:5446
|
||||
[ "$status" -ne 0 ]
|
||||
docker tag -f $image $hostname:5446/$image
|
||||
run docker push $hostname:5446/$image
|
||||
[ "$status" -ne 0 ]
|
||||
}
|
||||
|
||||
@test "Test TLS client auth to server with unknown certificate authority fails" {
|
||||
docker tag -f $image $hostname:5447/$image
|
||||
run docker push $hostname:5447/$image
|
||||
[ "$status" -ne 0 ]
|
||||
}
|
||||
|
||||
@test "Test failure to connect to server fails to fallback to SSLv3" {
|
||||
docker tag -f $image $hostname:5448/$image
|
||||
run docker push $hostname:5448/$image
|
||||
[ "$status" -ne 0 ]
|
||||
}
|
||||
|
Loading…
Reference in a new issue