compose integration tests
Signed-off-by: CrazyMax <1951866+crazy-max@users.noreply.github.com>
This commit is contained in:
@@ -12,6 +12,7 @@ ARG DOCKER_CLI_VERSION=${DOCKER_VERSION}
|
|||||||
ARG GOTESTSUM_VERSION=v1.12.0
|
ARG GOTESTSUM_VERSION=v1.12.0
|
||||||
ARG REGISTRY_VERSION=3.0.0
|
ARG REGISTRY_VERSION=3.0.0
|
||||||
ARG BUILDKIT_VERSION=v0.23.2
|
ARG BUILDKIT_VERSION=v0.23.2
|
||||||
|
ARG COMPOSE_VERSION=v2.39.0
|
||||||
ARG UNDOCK_VERSION=0.9.0
|
ARG UNDOCK_VERSION=0.9.0
|
||||||
|
|
||||||
FROM --platform=$BUILDPLATFORM tonistiigi/xx:${XX_VERSION} AS xx
|
FROM --platform=$BUILDPLATFORM tonistiigi/xx:${XX_VERSION} AS xx
|
||||||
@@ -24,6 +25,7 @@ FROM dockereng/cli-bin:$DOCKER_VERSION_ALT_27 AS docker-cli-alt27
|
|||||||
FROM dockereng/cli-bin:$DOCKER_VERSION_ALT_26 AS docker-cli-alt26
|
FROM dockereng/cli-bin:$DOCKER_VERSION_ALT_26 AS docker-cli-alt26
|
||||||
FROM registry:$REGISTRY_VERSION AS registry
|
FROM registry:$REGISTRY_VERSION AS registry
|
||||||
FROM moby/buildkit:$BUILDKIT_VERSION AS buildkit
|
FROM moby/buildkit:$BUILDKIT_VERSION AS buildkit
|
||||||
|
FROM docker/compose-bin:$COMPOSE_VERSION AS compose
|
||||||
FROM crazymax/undock:$UNDOCK_VERSION AS undock
|
FROM crazymax/undock:$UNDOCK_VERSION AS undock
|
||||||
|
|
||||||
FROM golatest AS gobase
|
FROM golatest AS gobase
|
||||||
@@ -137,8 +139,10 @@ COPY --link --from=docker-cli-alt27 / /opt/docker-alt-27/
|
|||||||
COPY --link --from=docker-cli-alt26 / /opt/docker-alt-26/
|
COPY --link --from=docker-cli-alt26 / /opt/docker-alt-26/
|
||||||
COPY --link --from=buildkit /usr/bin/buildkitd /usr/bin/
|
COPY --link --from=buildkit /usr/bin/buildkitd /usr/bin/
|
||||||
COPY --link --from=buildkit /usr/bin/buildctl /usr/bin/
|
COPY --link --from=buildkit /usr/bin/buildctl /usr/bin/
|
||||||
|
COPY --link --from=compose /docker-compose /usr/bin/compose
|
||||||
COPY --link --from=undock /usr/local/bin/undock /usr/bin/
|
COPY --link --from=undock /usr/local/bin/undock /usr/bin/
|
||||||
COPY --link --from=binaries /buildx /usr/bin/
|
COPY --link --from=binaries /buildx /usr/bin/
|
||||||
|
RUN mkdir -p /usr/local/lib/docker/cli-plugins && ln -s /usr/bin/buildx /usr/local/lib/docker/cli-plugins/docker-buildx
|
||||||
ENV TEST_DOCKER_EXTRA="docker@27.5=/opt/docker-alt-27,docker@26.1=/opt/docker-alt-26"
|
ENV TEST_DOCKER_EXTRA="docker@27.5=/opt/docker-alt-27,docker@26.1=/opt/docker-alt-26"
|
||||||
|
|
||||||
FROM integration-test-base AS integration-test
|
FROM integration-test-base AS integration-test
|
||||||
|
|||||||
+6
-6
@@ -72,9 +72,9 @@ var bakeTests = []func(t *testing.T, sb integration.Sandbox){
|
|||||||
testBakeMetadataWarningsDedup,
|
testBakeMetadataWarningsDedup,
|
||||||
testBakeMultiExporters,
|
testBakeMultiExporters,
|
||||||
testBakeLoadPush,
|
testBakeLoadPush,
|
||||||
testListTargets,
|
testBakeListTargets,
|
||||||
testListVariables,
|
testBakeListVariables,
|
||||||
testListTypedVariables,
|
testBakeListTypedVariables,
|
||||||
testBakeCallCheck,
|
testBakeCallCheck,
|
||||||
testBakeCallCheckFlag,
|
testBakeCallCheckFlag,
|
||||||
testBakeCallMetadata,
|
testBakeCallMetadata,
|
||||||
@@ -1691,7 +1691,7 @@ target "default" {
|
|||||||
// TODO: test metadata file when supported by multi exporters https://github.com/docker/buildx/issues/2181
|
// TODO: test metadata file when supported by multi exporters https://github.com/docker/buildx/issues/2181
|
||||||
}
|
}
|
||||||
|
|
||||||
func testListTargets(t *testing.T, sb integration.Sandbox) {
|
func testBakeListTargets(t *testing.T, sb integration.Sandbox) {
|
||||||
bakefile := []byte(`
|
bakefile := []byte(`
|
||||||
target "foo" {
|
target "foo" {
|
||||||
description = "This builds foo"
|
description = "This builds foo"
|
||||||
@@ -1714,7 +1714,7 @@ target "abc" {
|
|||||||
require.Equal(t, "TARGET\tDESCRIPTION\nabc\t\nfoo\tThis builds foo", strings.TrimSpace(out))
|
require.Equal(t, "TARGET\tDESCRIPTION\nabc\t\nfoo\tThis builds foo", strings.TrimSpace(out))
|
||||||
}
|
}
|
||||||
|
|
||||||
func testListVariables(t *testing.T, sb integration.Sandbox) {
|
func testBakeListVariables(t *testing.T, sb integration.Sandbox) {
|
||||||
bakefile := []byte(`
|
bakefile := []byte(`
|
||||||
variable "foo" {
|
variable "foo" {
|
||||||
default = "bar"
|
default = "bar"
|
||||||
@@ -1743,7 +1743,7 @@ target "default" {
|
|||||||
require.Equal(t, "VARIABLE\tTYPE\tVALUE\tDESCRIPTION\nabc\t\t\t<null>\t\ndef\t\t\t\t\nfoo\t\t\tbar\tThis is foo", strings.TrimSpace(out))
|
require.Equal(t, "VARIABLE\tTYPE\tVALUE\tDESCRIPTION\nabc\t\t\t<null>\t\ndef\t\t\t\t\nfoo\t\t\tbar\tThis is foo", strings.TrimSpace(out))
|
||||||
}
|
}
|
||||||
|
|
||||||
func testListTypedVariables(t *testing.T, sb integration.Sandbox) {
|
func testBakeListTypedVariables(t *testing.T, sb integration.Sandbox) {
|
||||||
bakefile := []byte(`
|
bakefile := []byte(`
|
||||||
variable "abc" {
|
variable "abc" {
|
||||||
type = string
|
type = string
|
||||||
|
|||||||
+2
-2
@@ -76,7 +76,7 @@ var buildTests = []func(t *testing.T, sb integration.Sandbox){
|
|||||||
testBuildSecret,
|
testBuildSecret,
|
||||||
testBuildDefaultLoad,
|
testBuildDefaultLoad,
|
||||||
testBuildCall,
|
testBuildCall,
|
||||||
testCheckCallOutput,
|
testBuildCheckCallOutput,
|
||||||
testBuildExtraHosts,
|
testBuildExtraHosts,
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1241,7 +1241,7 @@ COPy --from=base \
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func testCheckCallOutput(t *testing.T, sb integration.Sandbox) {
|
func testBuildCheckCallOutput(t *testing.T, sb integration.Sandbox) {
|
||||||
t.Run("check for warning count msg in check without warnings", func(t *testing.T) {
|
t.Run("check for warning count msg in check without warnings", func(t *testing.T) {
|
||||||
dockerfile := []byte(`
|
dockerfile := []byte(`
|
||||||
FROM busybox AS base
|
FROM busybox AS base
|
||||||
|
|||||||
@@ -0,0 +1,172 @@
|
|||||||
|
package tests
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"os"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/containerd/continuity/fs/fstest"
|
||||||
|
"github.com/moby/buildkit/identity"
|
||||||
|
"github.com/moby/buildkit/util/contentutil"
|
||||||
|
"github.com/moby/buildkit/util/testutil"
|
||||||
|
"github.com/moby/buildkit/util/testutil/integration"
|
||||||
|
"github.com/pkg/errors"
|
||||||
|
"github.com/stretchr/testify/require"
|
||||||
|
)
|
||||||
|
|
||||||
|
var composeTests = []func(t *testing.T, sb integration.Sandbox){
|
||||||
|
testComposeBuildLocalStore,
|
||||||
|
testComposeBuildRegistry,
|
||||||
|
testComposeBuildMultiPlatform,
|
||||||
|
testComposeBuildCheck,
|
||||||
|
}
|
||||||
|
|
||||||
|
func testComposeBuildLocalStore(t *testing.T, sb integration.Sandbox) {
|
||||||
|
if !isDockerWorker(sb) && !isDockerContainerWorker(sb) {
|
||||||
|
t.Skip("only testing with docker and docker-container worker")
|
||||||
|
}
|
||||||
|
|
||||||
|
target := "buildx:local-" + identity.NewID()
|
||||||
|
dir := composeTestProject(target, t)
|
||||||
|
|
||||||
|
t.Cleanup(func() {
|
||||||
|
cmd := dockerCmd(sb, withArgs("image", "rm", target))
|
||||||
|
cmd.Stderr = os.Stderr
|
||||||
|
require.NoError(t, cmd.Run())
|
||||||
|
})
|
||||||
|
|
||||||
|
cmd := composeCmd(sb, withDir(dir), withArgs("build"))
|
||||||
|
out, err := cmd.CombinedOutput()
|
||||||
|
require.NoError(t, err, string(out))
|
||||||
|
|
||||||
|
cmd = dockerCmd(sb, withArgs("image", "inspect", target))
|
||||||
|
cmd.Stderr = os.Stderr
|
||||||
|
require.NoError(t, cmd.Run())
|
||||||
|
}
|
||||||
|
|
||||||
|
func testComposeBuildRegistry(t *testing.T, sb integration.Sandbox) {
|
||||||
|
registry, err := sb.NewRegistry()
|
||||||
|
if errors.Is(err, integration.ErrRequirements) {
|
||||||
|
t.Skip(err.Error())
|
||||||
|
}
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
target := registry + "/buildx/registry:latest"
|
||||||
|
dir := composeTestProject(target, t)
|
||||||
|
|
||||||
|
cmd := composeCmd(sb, withDir(dir), withArgs("build", "--push"))
|
||||||
|
out, err := cmd.CombinedOutput()
|
||||||
|
require.NoError(t, err, string(out))
|
||||||
|
|
||||||
|
desc, provider, err := contentutil.ProviderFromRef(target)
|
||||||
|
require.NoError(t, err)
|
||||||
|
_, err = testutil.ReadImages(sb.Context(), provider, desc)
|
||||||
|
require.NoError(t, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
func testComposeBuildMultiPlatform(t *testing.T, sb integration.Sandbox) {
|
||||||
|
registry, err := sb.NewRegistry()
|
||||||
|
if errors.Is(err, integration.ErrRequirements) {
|
||||||
|
t.Skip(err.Error())
|
||||||
|
}
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
target := registry + "/buildx/registry:latest"
|
||||||
|
|
||||||
|
dockerfile := []byte(`
|
||||||
|
FROM busybox:latest
|
||||||
|
COPY foo /etc/foo
|
||||||
|
`)
|
||||||
|
composefile := fmt.Appendf([]byte{}, `
|
||||||
|
services:
|
||||||
|
bar:
|
||||||
|
build:
|
||||||
|
context: .
|
||||||
|
platforms:
|
||||||
|
- linux/amd64
|
||||||
|
- linux/arm64
|
||||||
|
image: %s
|
||||||
|
`, target)
|
||||||
|
|
||||||
|
dir := tmpdir(
|
||||||
|
t,
|
||||||
|
fstest.CreateFile("compose.yml", composefile, 0600),
|
||||||
|
fstest.CreateFile("Dockerfile", dockerfile, 0600),
|
||||||
|
fstest.CreateFile("foo", []byte("foo"), 0600),
|
||||||
|
)
|
||||||
|
|
||||||
|
cmd := composeCmd(sb, withDir(dir), withArgs("build", "--push"))
|
||||||
|
out, err := cmd.CombinedOutput()
|
||||||
|
|
||||||
|
if !isMobyWorker(sb) {
|
||||||
|
require.NoError(t, err, string(out))
|
||||||
|
|
||||||
|
desc, provider, err := contentutil.ProviderFromRef(target)
|
||||||
|
require.NoError(t, err)
|
||||||
|
imgs, err := testutil.ReadImages(sb.Context(), provider, desc)
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
img := imgs.Find("linux/amd64")
|
||||||
|
require.NotNil(t, img)
|
||||||
|
img = imgs.Find("linux/arm64")
|
||||||
|
require.NotNil(t, img)
|
||||||
|
} else {
|
||||||
|
require.Error(t, err, string(out))
|
||||||
|
require.Contains(t, string(out), "Multi-platform build is not supported")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func testComposeBuildCheck(t *testing.T, sb integration.Sandbox) {
|
||||||
|
dockerfile := []byte(`
|
||||||
|
frOM busybox as base
|
||||||
|
cOpy Dockerfile .
|
||||||
|
from scratch
|
||||||
|
COPy --from=base \
|
||||||
|
/Dockerfile \
|
||||||
|
/
|
||||||
|
`)
|
||||||
|
|
||||||
|
composefile := []byte(`
|
||||||
|
services:
|
||||||
|
bar:
|
||||||
|
build:
|
||||||
|
context: .
|
||||||
|
`)
|
||||||
|
|
||||||
|
dir := tmpdir(
|
||||||
|
t,
|
||||||
|
fstest.CreateFile("compose.yml", composefile, 0600),
|
||||||
|
fstest.CreateFile("Dockerfile", dockerfile, 0600),
|
||||||
|
)
|
||||||
|
|
||||||
|
cmd := composeCmd(sb, withDir(dir), withArgs("build", "--check"))
|
||||||
|
out, err := cmd.CombinedOutput()
|
||||||
|
require.Error(t, err, string(out))
|
||||||
|
require.Contains(t, string(out), "Check complete, 3 warnings have been found!")
|
||||||
|
}
|
||||||
|
|
||||||
|
func composeTestProject(imageName string, t *testing.T) string {
|
||||||
|
dockerfile := []byte(`
|
||||||
|
FROM busybox:latest AS base
|
||||||
|
COPY foo /etc/foo
|
||||||
|
RUN cp /etc/foo /etc/bar
|
||||||
|
|
||||||
|
FROM scratch
|
||||||
|
COPY --from=base /etc/bar /bar
|
||||||
|
`)
|
||||||
|
|
||||||
|
composefile := fmt.Appendf([]byte{}, `
|
||||||
|
services:
|
||||||
|
bar:
|
||||||
|
build:
|
||||||
|
context: .
|
||||||
|
image: %s
|
||||||
|
`, imageName)
|
||||||
|
|
||||||
|
return tmpdir(
|
||||||
|
t,
|
||||||
|
fstest.CreateFile("compose.yml", composefile, 0600),
|
||||||
|
fstest.CreateFile("Dockerfile", dockerfile, 0600),
|
||||||
|
fstest.CreateFile("foo", []byte("foo"), 0600),
|
||||||
|
)
|
||||||
|
}
|
||||||
@@ -75,6 +75,30 @@ func buildxCmd(sb integration.Sandbox, opts ...cmdOpt) *exec.Cmd {
|
|||||||
return cmd
|
return cmd
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func composeCmd(sb integration.Sandbox, opts ...cmdOpt) *exec.Cmd {
|
||||||
|
cmd := exec.Command("compose")
|
||||||
|
cmd.Env = os.Environ()
|
||||||
|
for _, opt := range opts {
|
||||||
|
opt(cmd)
|
||||||
|
}
|
||||||
|
|
||||||
|
if builder := sb.Address(); builder != "" {
|
||||||
|
cmd.Env = append(cmd.Env,
|
||||||
|
"BUILDX_CONFIG="+buildxConfig(sb),
|
||||||
|
"BUILDX_BUILDER="+builder,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
if context := sb.DockerAddress(); context != "" {
|
||||||
|
cmd.Env = append(cmd.Env, "DOCKER_CONTEXT="+context)
|
||||||
|
}
|
||||||
|
if v := os.Getenv("GO_TEST_COVERPROFILE"); v != "" {
|
||||||
|
coverDir := filepath.Join(filepath.Dir(v), "helpers")
|
||||||
|
cmd.Env = append(cmd.Env, "GOCOVERDIR="+coverDir)
|
||||||
|
}
|
||||||
|
cmd.Env = append(cmd.Env, "COMPOSE_BAKE=true")
|
||||||
|
return cmd
|
||||||
|
}
|
||||||
|
|
||||||
func dockerCmd(sb integration.Sandbox, opts ...cmdOpt) *exec.Cmd {
|
func dockerCmd(sb integration.Sandbox, opts ...cmdOpt) *exec.Cmd {
|
||||||
cmd := exec.Command("docker")
|
cmd := exec.Command("docker")
|
||||||
cmd.Env = os.Environ()
|
cmd.Env = os.Environ()
|
||||||
|
|||||||
@@ -32,6 +32,7 @@ func TestIntegration(t *testing.T) {
|
|||||||
tests = append(tests, createTests...)
|
tests = append(tests, createTests...)
|
||||||
tests = append(tests, rmTests...)
|
tests = append(tests, rmTests...)
|
||||||
tests = append(tests, dialstdioTests...)
|
tests = append(tests, dialstdioTests...)
|
||||||
|
tests = append(tests, composeTests...)
|
||||||
testIntegration(t, tests...)
|
testIntegration(t, tests...)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user