Skip to content

Commit

Permalink
Added "end2end" whitebox integration testing
Browse files Browse the repository at this point in the history
  • Loading branch information
ivanilves committed Nov 11, 2017
1 parent 9402602 commit 2dc36d8
Show file tree
Hide file tree
Showing 3 changed files with 179 additions and 23 deletions.
2 changes: 1 addition & 1 deletion Gopkg.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

42 changes: 42 additions & 0 deletions docker/client/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,9 @@ import (
"io/ioutil"

"github.com/docker/docker/api/types"
"github.com/docker/docker/api/types/container"
"github.com/docker/docker/api/types/filters"
"github.com/docker/go-connections/nat"
"github.com/moby/moby/client"

"golang.org/x/net/context"
Expand Down Expand Up @@ -106,3 +108,43 @@ func (dc *DockerClient) Push(ref string) error {
func (dc *DockerClient) Tag(src, dst string) error {
return dc.cli.ImageTag(context.Background(), src, dst)
}

// Run runs Docker container from the image specified (like "docker run")
func (dc *DockerClient) Run(ref, name string, portSpecs []string) (string, error) {
exposedPorts, portBindings, err := nat.ParsePortSpecs(portSpecs)
if err != nil {
return "", err
}

ctx := context.Background()

if err := dc.Pull(ref); err != nil {
return "", err
}

resp, err := dc.cli.ContainerCreate(
ctx,
&container.Config{Image: ref, ExposedPorts: exposedPorts},
&container.HostConfig{PortBindings: portBindings},
nil,
name,
)
if err != nil {
return "", err
}

if err := dc.cli.ContainerStart(ctx, resp.ID, types.ContainerStartOptions{}); err != nil {
return "", err
}

return resp.ID, nil
}

// ForceRemove kills & removes Docker container having the ID specified (like "docker rm -f")
func (dc *DockerClient) ForceRemove(id string) error {
return dc.cli.ContainerRemove(
context.Background(),
id,
types.ContainerRemoveOptions{Force: true},
)
}
158 changes: 136 additions & 22 deletions main_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,51 +11,165 @@ package main
import (
"testing"

"math/rand"
"os"
"strconv"

"github.com/ivanilves/lstags/docker"
dockerclient "github.com/ivanilves/lstags/docker/client"
dockerconfig "github.com/ivanilves/lstags/docker/config"
"github.com/ivanilves/lstags/tag/remote"
)

const dockerHub = "registry.hub.docker.com"
//
// Here we check the ability to fetch tags from remote registry
//
func runTestForFetchTags(
t *testing.T,
repository, filter string,
username, password string,
checkTagNames []string,
) {
registry := docker.GetRegistry(repository)
repoPath := docker.GetRepoPath(repository, registry)

const dockerJSON = "./fixtures/docker/config.json"

func TestDockerHubWithPublicRepo(t *testing.T) {
const repo = "library/alpine"

tags, err := remote.FetchTags(dockerHub, repo, ".*", "", "")
tags, err := remote.FetchTags(registry, repoPath, filter, username, password)
if err != nil {
t.Fatalf("Failed to list DockerHub public repo (%s) tags: %s", repo, err.Error())
t.Fatalf(
"Failed to fetch tags (%s~/%s/) from '%s' registry: %s",
repoPath,
filter,
registry,
err.Error(),
)
}

_, defined := tags["latest"]
if !defined {
t.Fatalf("DockerHub public repo (%s) tag 'latest' not found: %#v", repo, tags)
for _, name := range checkTagNames {
_, defined := tags[name]
if !defined {
t.Fatalf(
"Tag '%s' not found in query (%s~/%s/) to '%s' registry.\nTags: %#v",
name,
repoPath,
filter,
registry,
tags,
)
}
}
}

func TestDockerHubWithPrivateRepo(t *testing.T) {
func TestFetchTags_DockerHub_PublicRepo(t *testing.T) {
runTestForFetchTags(
t,
"alpine",
"^(3.6|latest)$",
"",
"",
[]string{"3.6", "latest"},
)
}

func TestFetchTags_DockerHub_PrivateRepo(t *testing.T) {
if os.Getenv("DOCKERHUB_PRIVATE_REPO") == "" {
t.Skipf("DOCKERHUB_PRIVATE_REPO environment variable not set!")
}
if os.Getenv("DOCKERHUB_USERNAME") == "" {
t.Skipf("DOCKERHUB_USERNAME environment variable not set!")
}
if os.Getenv("DOCKERHUB_PASSWORD") == "" {
t.Skipf("DOCKERHUB_PASSWORD environment variable not set!")
}
if os.Getenv("DOCKERHUB_PRIVATE_REPO") == "" {
t.Skipf("DOCKERHUB_PRIVATE_REPO environment variable not set!")

repository := os.Getenv("DOCKERHUB_PRIVATE_REPO")
username := os.Getenv("DOCKERHUB_USERNAME")
password := os.Getenv("DOCKERHUB_PASSWORD")

runTestForFetchTags(
t,
repository,
".*",
username,
password,
[]string{"latest"},
)
}

//
// Here we check if we could:
// * Pull specified images from remote registry
// * Push them to the local registry then (ephemeral container used to run registry)
// * Check if images pushed to the local registry are present there
//
func runTestForPullPush(
t *testing.T,
srcRepository, filter string,
username, password string,
checkTagNames []string,
) {
const dockerJSON = "./fixtures/docker/config.json"
const registryImageRef = "registry:2"
const registryContainerName = "lstags-ephemeral-registry"

hostPort := strconv.Itoa(5000 + rand.Intn(1000))
localRegistry := "127.0.0.1:" + hostPort
localPortSpec := localRegistry + ":5000"

dockerConfig, err := dockerconfig.Load(dockerJSON)
if err != nil {
t.Fatal(err)
}

user := os.Getenv("DOCKERHUB_USERNAME")
pass := os.Getenv("DOCKERHUB_PASSWORD")
repo := os.Getenv("DOCKERHUB_PRIVATE_REPO")
dc, err := dockerclient.New(dockerConfig)
if err != nil {
t.Fatal(err)
}

tags, err := remote.FetchTags(dockerHub, repo, ".*", user, pass)
dc.ForceRemove(registryContainerName)

id, err := dc.Run(
registryImageRef,
registryContainerName,
[]string{localPortSpec},
)
if err != nil {
t.Fatalf("Failed to list DockerHub private repo (%s) tags: %s", repo, err.Error())
t.Fatal(err)
}

_, defined := tags["latest"]
if !defined {
t.Fatalf("DockerHub private repo (%s) tag 'latest' not found: %#v", repo, tags)
srcRegistry := docker.GetRegistry(srcRepository)
srcRepoPath := docker.GetRepoPath(srcRepository, srcRegistry)
dstRepoPath := "lstags/" + srcRepoPath
dstRepository := localRegistry + "/" + dstRepoPath

for _, name := range checkTagNames {
src := srcRepository + ":" + name
dst := dstRepository + ":" + name

if err := dc.Pull(src); err != nil {
t.Fatal(err)
}

if err := dc.Tag(src, dst); err != nil {
t.Fatal(err)
}

if err := dc.Push(dst); err != nil {
t.Fatal(err)
}
}

runTestForFetchTags(
t,
dstRepository,
".*",
"",
"",
checkTagNames,
)

dc.ForceRemove(id)
}

func TestPullPush_DockerHub_PublicRegistry(t *testing.T) {
runTestForPullPush(t, "alpine", ".*", "", "", []string{"3.6", "latest"})
}

0 comments on commit 2dc36d8

Please sign in to comment.