diff --git a/common/dockertest_helper.go b/common/dockertest_helper.go new file mode 100644 index 0000000..f1f4007 --- /dev/null +++ b/common/dockertest_helper.go @@ -0,0 +1,61 @@ +package common + +import ( + "bytes" + "fmt" + "os" + + "github.com/ory/dockertest/v3" +) + +// DockerPool is a docker pool resource +var dockerpool *dockertest.Pool + +// GetDockerPool initializes a docker pool +func GetDockerPool() (*dockertest.Pool, error) { + var err error + if dockerpool == nil { + dockerpool, err = dockertest.NewPool("") + if err != nil { + err = fmt.Errorf("cannot attach to docker: %v", err) + return nil, err + } + } + err = dockerpool.Client.Ping() + if err != nil { + err = fmt.Errorf("could not connect to Docker: %s", err) + return nil, err + } + return dockerpool, nil +} + +// GetContainerHostAndPort returns the mapped host and port of a docker container for a given portID +func GetContainerHostAndPort(container *dockertest.Resource, portID string) (server string, port int) { + dockerURL := os.Getenv("DOCKER_HOST") + containerAddress := container.GetHostPort(portID) + s, p, _ := GetHostPort(containerAddress) + if dockerURL == "" { + server = s + } else { + // replace server with docker host + server, _, _ = GetHostPort(dockerURL) + } + port = p + return +} + +// DestroyDockerContainer destroys a docker container +func DestroyDockerContainer(container *dockertest.Resource) { + if err := dockerpool.Purge(container); err != nil { + fmt.Printf("Could not purge resource: %s\n", err) + } +} + +// ExecDockerCmd executes an OS cmd within container and print output +func ExecDockerCmd(container *dockertest.Resource, cmd []string) (out string, code int, err error) { + var cmdout bytes.Buffer + cmdout.Reset() + code, err = container.Exec(cmd, dockertest.ExecOptions{StdOut: &cmdout}) + out = cmdout.String() + return +} diff --git a/common/dockertest_helper_test.go b/common/dockertest_helper_test.go new file mode 100644 index 0000000..41e1b06 --- /dev/null +++ b/common/dockertest_helper_test.go @@ -0,0 +1,54 @@ +package common + +import ( + "os" + "testing" + + "github.com/ory/dockertest/v3" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" +) + +func TestGetDockerHelper(t *testing.T) { + var pool *dockertest.Pool + var err error + var container *dockertest.Resource + var server string + var port int + t.Run("Test GetDockerPool", func(t *testing.T) { + pool, err = GetDockerPool() + assert.NoErrorf(t, err, "GetDockerPool() should not return error") + require.NotNil(t, pool, "GetDockerPool() should not return nil") + }) + t.Run("Test GetDockerContainer", func(t *testing.T) { + container, err = pool.Run("nginx", "latest", []string{}) + assert.NoErrorf(t, err, "Container should start without error") + require.NotNil(t, container, "Container should not be nil") + }) + t.Run("Test GetContainerHostAndPort", func(t *testing.T) { + server, port = GetContainerHostAndPort(container, "80/tcp") + t.Logf("server: %s, port: %d", server, port) + assert.Greaterf(t, port, 30000, "GetContainerHostAndPort() should return a port >30000") + assert.True(t, server == "localhost" || server == "docker", "GetContainerHostAndPort() should return localhost or docker as server") + }) + t.Run("Test GetContainerHostAndPort other docker", func(t *testing.T) { + _ = os.Setenv("DOCKER_HOST", "tcp://web:2375") + server, port = GetContainerHostAndPort(container, "80/tcp") + t.Logf("server: %s, port: %d", server, port) + assert.Greaterf(t, port, 30000, "GetContainerHostAndPort() should return a port >30000") + assert.True(t, server == "web", "GetContainerHostAndPort() should return localhost or docker as server") + }) + t.Run("Test Exec on Container", func(t *testing.T) { + var cmdout string + cmd := []string{"ls", "-ld", "/etc/nginx"} + cmdout, _, err = ExecDockerCmd(container, cmd) + t.Logf("cmdout: %s", cmdout) + assert.NoErrorf(t, err, "ExecDockerCmd() should not return error") + assert.Contains(t, cmdout, "/etc/nginx", "ExecDockerCmd() should return /etc/nginx") + }) + t.Run("Test DestroyDockerContainer", func(t *testing.T) { + DestroyDockerContainer(container) + _, ok := pool.ContainerByName(container.Container.Name) + assert.False(t, ok, "Container should not be found in pool after DestroyDockerContainer()") + }) +}