Feat/swarm 3 acc test infra (#39)

* Set up test infrastructure with local registry and custom images.

* Updated travis docker version and usage of new test infra.

* Made acc tests constantly output test results.

* Tmp acc test files are ignored.

* Fixed tests with new infra.

* Allowing insecure registries for acc tests. Added fallback for v1 registries.

* Added private image cleanup after tests.

* Refined acc test structure to confirm tf provider standards with make testacc.
This commit is contained in:
Manuel Vogel 2018-02-09 20:11:30 +01:00 committed by Clint
parent 5a40076c95
commit d7038e7560
14 changed files with 201 additions and 12 deletions

2
.gitignore vendored
View file

@ -29,3 +29,5 @@ website/vendor
# Test exclusions
!command/test-fixtures/**/*.tfstate
!command/test-fixtures/**/.terraform/
scripts/testing/auth
scripts/testing/certs

View file

@ -1,8 +1,18 @@
dist: trusty
sudo: false
sudo: required
services:
- docker
language: go
go:
- 1.8.1
- 1.9.1
before_install:
- curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
- sudo add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable"
- sudo apt-get update
- sudo apt-get -y install docker-ce
- docker version
- export TRAVIS="true"
install:
# This script is used by the Travis build to install a cookie for
@ -11,9 +21,13 @@ install:
# See: https://github.com/golang/go/issues/12933
- bash scripts/gogetcookie.sh
- go get github.com/kardianos/govendor
- sudo sed 's/DOCKER_OPTS="/DOCKER_OPTS="--insecure-registry=127.0.0.1:5000 /g' -i /etc/default/docker
- sudo cat /etc/default/docker
- sudo service docker restart
script:
- make test
- make testacc
- make vendor-status
- make vet

View file

@ -12,7 +12,7 @@ test: fmtcheck
xargs -t -n4 go test $(TESTARGS) -timeout=30s -parallel=4
testacc: fmtcheck
TF_ACC=1 go test $(TEST) -v $(TESTARGS) -timeout 120m
@sh -c "'$(CURDIR)/scripts/runAccTests.sh'"
vet:
@echo "go vet ."

View file

@ -1,11 +1,14 @@
package docker
import (
"crypto/tls"
"encoding/json"
"fmt"
"io/ioutil"
"net/http"
"net/url"
"os"
"strconv"
"strings"
"github.com/hashicorp/terraform/helper/schema"
@ -60,11 +63,14 @@ func dataSourceDockerRegistryImageRead(d *schema.ResourceData, meta interface{})
password = auth.Password
}
digest, err := getImageDigest(pullOpts.Registry, pullOpts.Repository, pullOpts.Tag, username, password)
digest, err := getImageDigest(pullOpts.Registry, pullOpts.Repository, pullOpts.Tag, username, password, false)
if err != nil {
digest, err = getImageDigest(pullOpts.Registry, pullOpts.Repository, pullOpts.Tag, username, password, true)
if err != nil {
return fmt.Errorf("Got error when attempting to fetch image version from registry: %s", err)
}
}
d.SetId(digest)
d.Set("sha256_digest", digest)
@ -72,11 +78,23 @@ func dataSourceDockerRegistryImageRead(d *schema.ResourceData, meta interface{})
return nil
}
func getImageDigest(registry, image, tag, username, password string) (string, error) {
func getImageDigest(registry, image, tag, username, password string, fallback bool) (string, error) {
client := http.DefaultClient
req, err := http.NewRequest("GET", "https://"+registry+"/v2/"+image+"/manifests/"+tag, nil)
// Allow insecure registries only for ACC tests
// cuz we don't have a valid certs for this case
if env, okEnv := os.LookupEnv("TF_ACC"); okEnv {
if i, errConv := strconv.Atoi(env); errConv == nil && i >= 1 {
cfg := &tls.Config{
InsecureSkipVerify: true,
}
client.Transport = &http.Transport{
TLSClientConfig: cfg,
}
}
}
req, err := http.NewRequest("GET", "https://"+registry+"/v2/"+image+"/manifests/"+tag, nil)
if err != nil {
return "", fmt.Errorf("Error creating registry request: %s", err)
}
@ -87,6 +105,10 @@ func getImageDigest(registry, image, tag, username, password string) (string, er
// Set this header so that we get the v2 manifest back from the registry.
req.Header.Set("Accept", "application/vnd.docker.distribution.manifest.v2+json")
if fallback {
// Fallback to this header if the registry does not support the v2 manifest like gcr.io
req.Header.Set("Accept", "application/vnd.docker.distribution.manifest.v1+prettyjws")
}
resp, err := client.Do(req)

View file

@ -195,12 +195,12 @@ func TestAccDockerContainer_customized(t *testing.T) {
return fmt.Errorf("Container does not have correct number of extra host entries, got %d", len(c.HostConfig.ExtraHosts))
}
if c.HostConfig.ExtraHosts[0] != "testhost2:10.0.2.0" {
return fmt.Errorf("Container has incorrect extra host string: %q", c.HostConfig.ExtraHosts[0])
if c.HostConfig.ExtraHosts[0] != "testhost:10.0.1.0" {
return fmt.Errorf("Container has incorrect extra host string at 0: %q", c.HostConfig.ExtraHosts[0])
}
if c.HostConfig.ExtraHosts[1] != "testhost:10.0.1.0" {
return fmt.Errorf("Container has incorrect extra host string: %q", c.HostConfig.ExtraHosts[1])
if c.HostConfig.ExtraHosts[1] != "testhost2:10.0.2.0" {
return fmt.Errorf("Container has incorrect extra host string at 1: %q", c.HostConfig.ExtraHosts[1])
}
if _, ok := c.NetworkSettings.Networks["test"]; !ok {

View file

@ -195,6 +195,7 @@ data "docker_registry_image" "foo_private" {
resource "docker_image" "foo_private" {
provider = "docker.private"
name = "${data.docker_registry_image.foo_private.name}"
keep_locally = true
pull_triggers = ["${data.docker_registry_image.foo_private.sha256_digest}"]
}
`

57
scripts/runAccTests.sh Executable file
View file

@ -0,0 +1,57 @@
#!/bin/bash
set -e
log() {
echo ""
echo "##################################"
echo "-------> $1"
echo "##################################"
}
setup() {
export DOCKER_REGISTRY_ADDRESS="127.0.0.1:5000"
export DOCKER_REGISTRY_USER="testuser"
export DOCKER_REGISTRY_PASS="testpwd"
export DOCKER_PRIVATE_IMAGE="127.0.0.1:5000/my-private-service:v1"
sh scripts/testing/setup_private_registry.sh
}
run() {
# Run the acc test suite
TF_ACC=1 go test ./docker -v -timeout 120m
# for a single test
# TF_LOG=INFO TF_ACC=1 go test -v github.com/terraform-providers/terraform-provider-docker/docker -run ^TestAccDockerContainer_basic$ -timeout 360s
# keep the return for the scripts to fail and clean properly
return $?
}
cleanup() {
unset DOCKER_REGISTRY_ADDRESS DOCKER_REGISTRY_USER DOCKER_REGISTRY_PASS DOCKER_PRIVATE_IMAGE
echo "### unsetted env ###"
rm -f scripts/testing/auth/htpasswd
rm -f scripts/testing/certs/registry_auth.*
echo "### removed auth and certs ###"
docker stop private_registry
echo "### stopped private registry ###"
docker rmi -f $(docker images -aq 127.0.0.1:5000/my-private-service)
echo "### removed my-private-service images ###"
# consider running this manually to clean up the
# updateabe configs and secrets
#docker config rm $(docker config ls -q)
#docker secret rm $(docker secret ls -q)
}
## main
log "setup" && setup
log "run" && run && echo $?
if [ $? -ne 0 ]; then
log "cleanup" && cleanup
exit 1
fi
# we only clean on local envs. travis fails from time to time there
# cuz it cannot remove the images
if [ "$TRAVIS" != "true" ]; then
log "cleanup" && cleanup
fi

View file

@ -0,0 +1,6 @@
FROM node:6.12.3-slim
EXPOSE 8080
COPY configs.json .
COPY secrets.json .
COPY server.js .
CMD node server.js

View file

@ -0,0 +1,6 @@
FROM node:6.12.3-slim
EXPOSE 8080
COPY configs.json .
COPY secrets.json .
COPY server_v2.js .
CMD node server_v2.js

View file

@ -0,0 +1,3 @@
{
"prefix": "123"
}

View file

@ -0,0 +1,3 @@
{
"key": "QWERTY"
}

17
scripts/testing/server.js Normal file
View file

@ -0,0 +1,17 @@
var http = require('http');
var configs = require('./configs')
var secrets = require('./secrets')
var handleRequest = function(request, response) {
console.log('Received request for URL: ' + request.url);
if(request.url === '/health') {
response.writeHead(200);
response.end('ok');
} else {
response.writeHead(200);
response.end(configs.prefix + ' - Hello World!');
}
};
var www = http.createServer(handleRequest);
www.listen(8080);

View file

@ -0,0 +1,20 @@
var http = require('http');
var configs = require('./configs')
var secrets = require('./secrets')
var handleRequest = function(request, response) {
console.log('Received request for URL: ' + request.url);
if(request.url === '/health') {
response.writeHead(200);
response.end('ok');
} else if(request.url === '/newroute') {
response.writeHead(200);
response.end('new Route!');
} else {
response.writeHead(200);
response.end(configs.prefix + ' - Hello World!');
}
};
var www = http.createServer(handleRequest);
www.listen(8080);

View file

@ -0,0 +1,38 @@
set -e
# Create private registry
## Create self signed certs
mkdir -p scripts/testing/certs
openssl req \
-newkey rsa:2048 \
-nodes \
-x509 \
-days 365 \
-subj "/C=US/ST=Denial/L=Springfield/O=Dis/CN=127.0.0.1" \
-keyout scripts/testing/certs/registry_auth.key \
-out scripts/testing/certs/registry_auth.crt
## Create auth
mkdir -p scripts/testing/auth
# Start registry
docker run --entrypoint htpasswd registry:2 -Bbn testuser testpwd > scripts/testing/auth/htpasswd
docker run -d -p 5000:5000 --rm --name private_registry \
-v "$(pwd)"/scripts/testing/auth:/auth \
-e "REGISTRY_AUTH=htpasswd" \
-e "REGISTRY_AUTH_HTPASSWD_REALM=Registry Realm" \
-e "REGISTRY_AUTH_HTPASSWD_PATH=/auth/htpasswd" \
-v "$(pwd)"/scripts/testing/certs:/certs \
-e "REGISTRY_HTTP_TLS_CERTIFICATE=/certs/registry_auth.crt" \
-e "REGISTRY_HTTP_TLS_KEY=/certs/registry_auth.key" \
registry:2
# wait a bit for travis...
sleep 5
# Login to private registry
docker login -u testuser -p testpwd 127.0.0.1:5000
# Build private images
docker build -t my-private-service ./scripts/testing -f ./scripts/testing/Dockerfile_v1
docker tag my-private-service 127.0.0.1:5000/my-private-service:v1
docker build -t my-private-service ./scripts/testing -f ./scripts/testing/Dockerfile_v2
docker tag my-private-service 127.0.0.1:5000/my-private-service:v2
# Push private images into private registry
docker push 127.0.0.1:5000/my-private-service:v1
docker push 127.0.0.1:5000/my-private-service:v2