Merge pull request #2322 from crazy-max/test-buildkit-multi-ver

tests: matrix with buildkit versions
This commit is contained in:
CrazyMax 2024-04-11 10:10:21 +02:00 committed by GitHub
commit d2ac1f2d6e
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
9 changed files with 157 additions and 143 deletions

View File

@ -30,35 +30,8 @@ env:
GOTESTSUM_VERSION: "v1.9.0" # same as one in Dockerfile
jobs:
prepare-test-integration:
runs-on: ubuntu-22.04
steps:
-
name: Checkout
uses: actions/checkout@v4
-
name: Set up QEMU
uses: docker/setup-qemu-action@v3
-
name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
with:
version: ${{ env.BUILDX_VERSION }}
driver-opts: image=${{ env.BUILDKIT_IMAGE }}
buildkitd-flags: --debug
-
name: Build
uses: docker/bake-action@v4
with:
targets: integration-test-base
set: |
*.cache-from=type=gha,scope=${{ env.TEST_CACHE_SCOPE }}
*.cache-to=type=gha,scope=${{ env.TEST_CACHE_SCOPE }}
test-integration:
runs-on: ubuntu-22.04
needs:
- prepare-test-integration
env:
TESTFLAGS_DOCKER: "-v --parallel=1 --timeout=30m"
TEST_IMAGE_BUILD: "0"
@ -66,21 +39,55 @@ jobs:
strategy:
fail-fast: false
matrix:
buildkit:
- master
- latest
- buildx-stable-1
- v0.13.1
- v0.12.5
- v0.11.6
worker:
- docker
- docker\+containerd # same as docker, but with containerd snapshotter
- docker-container
- remote
pkg:
- ./tests
experimental:
mode:
- ""
- 1
- experimental
include:
- worker: docker
pkg: ./tests
- worker: docker+containerd # same as docker, but with containerd snapshotter
pkg: ./tests
- worker: docker
pkg: ./tests
mode: experimental
- worker: docker+containerd # same as docker, but with containerd snapshotter
pkg: ./tests
mode: experimental
steps:
-
name: Prepare
run: |
echo "TESTREPORTS_NAME=${{ github.job }}-$(echo "${{ matrix.pkg }}-${{ matrix.worker }}-${{ matrix.experimental }}" | tr -dc '[:alnum:]-\n\r' | tr '[:upper:]' '[:lower:]')" >> $GITHUB_ENV
echo "TESTREPORTS_NAME=${{ github.job }}-$(echo "${{ matrix.pkg }}-${{ matrix.buildkit }}-${{ matrix.worker }}-${{ matrix.mode }}" | tr -dc '[:alnum:]-\n\r' | tr '[:upper:]' '[:lower:]')" >> $GITHUB_ENV
if [ -n "${{ matrix.buildkit }}" ]; then
echo "TEST_BUILDKIT_TAG=${{ matrix.buildkit }}" >> $GITHUB_ENV
fi
testFlags="--run=//worker=$(echo "${{ matrix.worker }}" | sed 's/\+/\\+/g')$"
case "${{ matrix.worker }}" in
docker | docker+containerd)
echo "TESTFLAGS=${{ env.TESTFLAGS_DOCKER }} $testFlags" >> $GITHUB_ENV
;;
*)
echo "TESTFLAGS=${{ env.TESTFLAGS }} $testFlags" >> $GITHUB_ENV
;;
esac
if [[ "${{ matrix.worker }}" == "docker"* ]]; then
echo "TEST_DOCKERD=1" >> $GITHUB_ENV
fi
if [ "${{ matrix.mode }}" = "experimental" ]; then
echo "TEST_BUILDX_EXPERIMENTAL=1" >> $GITHUB_ENV
fi
-
name: Checkout
uses: actions/checkout@v4
@ -102,7 +109,6 @@ jobs:
with:
targets: integration-test
set: |
*.cache-from=type=gha,scope=${{ env.TEST_CACHE_SCOPE }}
*.output=type=docker,name=${{ env.TEST_IMAGE_ID }}
-
name: Test
@ -110,9 +116,6 @@ jobs:
./hack/test
env:
TEST_REPORT_SUFFIX: "-${{ env.TESTREPORTS_NAME }}"
TEST_BUILDX_EXPERIMENTAL: ${{ matrix.experimental }}
TEST_DOCKERD: "${{ startsWith(matrix.worker, 'docker') && '1' || '0' }}"
TESTFLAGS: "${{ (matrix.worker == 'docker' || matrix.worker == 'docker\\+containerd') && env.TESTFLAGS_DOCKER || env.TESTFLAGS }} --run=//worker=${{ matrix.worker }}$"
TESTPKGS: "${{ matrix.pkg }}"
-
name: Send to Codecov
@ -359,27 +362,3 @@ jobs:
with:
draft: true
files: ${{ env.DESTDIR }}/*
buildkit-edge:
runs-on: ubuntu-22.04
continue-on-error: true
steps:
-
name: Checkout
uses: actions/checkout@v4
-
name: Set up QEMU
uses: docker/setup-qemu-action@v3
-
name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
with:
version: ${{ env.BUILDX_VERSION }}
driver-opts: image=moby/buildkit:master
buildkitd-flags: --debug
-
# Just run a bake target to check eveything runs fine
name: Build
uses: docker/bake-action@v4
with:
targets: binaries

View File

@ -7,7 +7,8 @@ ARG XX_VERSION=1.4.0
ARG DOCKER_VERSION=26.0.0
ARG GOTESTSUM_VERSION=v1.9.0
ARG REGISTRY_VERSION=2.8.0
ARG BUILDKIT_VERSION=v0.12.5
ARG BUILDKIT_VERSION=v0.13.1
ARG UNDOCK_VERSION=0.7.0
FROM --platform=$BUILDPLATFORM tonistiigi/xx:${XX_VERSION} AS xx
FROM --platform=$BUILDPLATFORM golang:${GO_VERSION}-alpine AS golatest
@ -15,6 +16,7 @@ FROM moby/moby-bin:$DOCKER_VERSION AS docker-engine
FROM dockereng/cli-bin:$DOCKER_VERSION AS docker-cli
FROM registry:$REGISTRY_VERSION AS registry
FROM moby/buildkit:$BUILDKIT_VERSION AS buildkit
FROM crazymax/undock:$UNDOCK_VERSION AS undock
FROM golatest AS gobase
COPY --from=xx / /
@ -92,6 +94,7 @@ COPY --link --from=docker-engine / /usr/bin/
COPY --link --from=docker-cli / /usr/bin/
COPY --link --from=buildkit /usr/bin/buildkitd /usr/bin/
COPY --link --from=buildkit /usr/bin/buildctl /usr/bin/
COPY --link --from=undock /usr/local/bin/undock /usr/bin/
COPY --link --from=binaries /buildx /usr/bin/
FROM integration-test-base AS integration-test

View File

@ -180,6 +180,9 @@ variable "HTTPS_PROXY" {
variable "NO_PROXY" {
default = ""
}
variable "TEST_BUILDKIT_TAG" {
default = null
}
target "integration-test-base" {
inherits = ["_common"]
@ -187,6 +190,7 @@ target "integration-test-base" {
HTTP_PROXY = HTTP_PROXY
HTTPS_PROXY = HTTPS_PROXY
NO_PROXY = NO_PROXY
BUILDKIT_VERSION = TEST_BUILDKIT_TAG
}
target = "integration-test-base"
output = ["type=cacheonly"]

View File

@ -10,6 +10,7 @@ set -eu -o pipefail
: "${TEST_REPORT_SUFFIX=}"
: "${TEST_KEEP_CACHE=}"
: "${TEST_DOCKERD=}"
: "${TEST_BUILDKIT_TAG=}"
: "${TEST_BUILDKIT_IMAGE=}"
: "${TEST_BUILDX_EXPERIMENTAL=}"
@ -25,11 +26,11 @@ gotestArgs="-mod=vendor -coverprofile=/testreports/coverage-report$TEST_REPORT_S
cacheVolume="buildx-test-cache"
if ! docker container inspect "$cacheVolume" >/dev/null 2>/dev/null; then
docker create -v /root/.cache -v /root/.cache/registry -v /go/pkg/mod --name "$cacheVolume" alpine
docker create -v /root/.cache -v /root/.cache/registry -v /root/.cache/undock -v /go/pkg/mod --name "$cacheVolume" alpine
fi
if [ "$TEST_KEEP_CACHE" != "1" ]; then
trap 'docker rm -v $cacheVolume' EXIT
fi
cid=$(docker create --rm -v /tmp $testReportsVol --volumes-from=$cacheVolume -e GITHUB_REF -e TEST_DOCKERD -e TEST_BUILDKIT_IMAGE -e TEST_BUILDX_EXPERIMENTAL -e SKIP_INTEGRATION_TESTS -e GOTESTSUM_FORMAT ${BUILDKIT_INTEGRATION_SNAPSHOTTER:+"-eBUILDKIT_INTEGRATION_SNAPSHOTTER"} -e BUILDKIT_REGISTRY_MIRROR_DIR=/root/.cache/registry --privileged $TEST_IMAGE_ID gotestsum $gotestsumArgs --packages="${TESTPKGS:-./...}" -- $gotestArgs ${TESTFLAGS:--v})
cid=$(docker create --rm -v /tmp $testReportsVol --volumes-from=$cacheVolume -e GITHUB_REF -e TEST_DOCKERD -e TEST_BUILDKIT_IMAGE -e TEST_BUILDKIT_TAG -e TEST_BUILDX_EXPERIMENTAL -e SKIP_INTEGRATION_TESTS -e GOTESTSUM_FORMAT ${BUILDKIT_INTEGRATION_SNAPSHOTTER:+"-eBUILDKIT_INTEGRATION_SNAPSHOTTER"} -e BUILDKIT_REGISTRY_MIRROR_DIR=/root/.cache/registry --privileged $TEST_IMAGE_ID gotestsum $gotestsumArgs --packages="${TESTPKGS:-./...}" -- $gotestArgs ${TESTFLAGS:--v})
docker start -a -i $cid

View File

@ -5,7 +5,6 @@ import (
"fmt"
"os"
"path/filepath"
"strings"
"testing"
"github.com/containerd/continuity/fs/fstest"
@ -680,6 +679,7 @@ func testBakeMultiExporters(t *testing.T, sb integration.Sandbox) {
if !isDockerContainerWorker(sb) {
t.Skip("only testing with docker-container worker")
}
skipNoCompatBuildKit(t, sb, ">= 0.13.0-0", "multi exporters")
registry, err := sb.NewRegistry()
if errors.Is(err, integration.ErrRequirements) {
@ -690,30 +690,12 @@ func testBakeMultiExporters(t *testing.T, sb integration.Sandbox) {
targetReg := registry + "/buildx/registry:latest"
targetStore := "buildx:local-" + identity.NewID()
var builderName string
t.Cleanup(func() {
if builderName == "" {
return
}
cmd := dockerCmd(sb, withArgs("image", "rm", targetStore))
cmd.Stderr = os.Stderr
require.NoError(t, cmd.Run())
out, err := rmCmd(sb, withArgs(builderName))
require.NoError(t, err, out)
})
// TODO: use stable buildkit image when v0.13.0 released
out, err := createCmd(sb, withArgs(
"--driver", "docker-container",
"--buildkitd-flags=--allow-insecure-entitlement=network.host",
"--driver-opt", "network=host",
"--driver-opt", "image=moby/buildkit:v0.13.0-rc3",
))
require.NoError(t, err, out)
builderName = strings.TrimSpace(out)
dockerfile := []byte(`
FROM scratch
COPY foo /foo
@ -735,7 +717,6 @@ target "default" {
"--set", fmt.Sprintf("*.output=type=oci,dest=%s/result", dir),
}
cmd := buildxCmd(sb, withDir(dir), withArgs("bake"), withArgs(outputs...))
cmd.Env = append(cmd.Env, "BUILDX_BUILDER="+builderName)
outb, err := cmd.CombinedOutput()
require.NoError(t, err, string(outb))
@ -761,6 +742,7 @@ func testBakeLoadPush(t *testing.T, sb integration.Sandbox) {
if !isDockerContainerWorker(sb) {
t.Skip("only testing with docker-container worker")
}
skipNoCompatBuildKit(t, sb, ">= 0.13.0-0", "multi exporters")
registry, err := sb.NewRegistry()
if errors.Is(err, integration.ErrRequirements) {
@ -770,30 +752,12 @@ func testBakeLoadPush(t *testing.T, sb integration.Sandbox) {
target := registry + "/buildx/registry:" + identity.NewID()
var builderName string
t.Cleanup(func() {
if builderName == "" {
return
}
cmd := dockerCmd(sb, withArgs("image", "rm", target))
cmd.Stderr = os.Stderr
require.NoError(t, cmd.Run())
out, err := rmCmd(sb, withArgs(builderName))
require.NoError(t, err, out)
})
// TODO: use stable buildkit image when v0.13.0 released
out, err := createCmd(sb, withArgs(
"--driver", "docker-container",
"--buildkitd-flags=--allow-insecure-entitlement=network.host",
"--driver-opt", "network=host",
"--driver-opt", "image=moby/buildkit:v0.13.0-rc3",
))
require.NoError(t, err, out)
builderName = strings.TrimSpace(out)
dockerfile := []byte(`
FROM scratch
COPY foo /foo
@ -810,7 +774,6 @@ target "default" {
)
cmd := buildxCmd(sb, withDir(dir), withArgs("bake", "--push", "--load", fmt.Sprintf("--set=*.tags=%s", target)))
cmd.Env = append(cmd.Env, "BUILDX_BUILDER="+builderName)
outb, err := cmd.CombinedOutput()
require.NoError(t, err, string(outb))

View File

@ -152,6 +152,10 @@ func testBuildRegistryExportAttestations(t *testing.T, sb integration.Sandbox) {
require.Error(t, err)
require.Contains(t, out, "Attestation is not supported")
return
} else if !isMobyContainerdSnapWorker(sb) && !matchesBuildKitVersion(t, sb, ">= 0.11.0-0") {
require.Error(t, err)
require.Contains(t, out, "Attestations are not supported by the current BuildKit daemon")
return
}
require.NoError(t, err, string(out))
@ -270,6 +274,7 @@ RUN busybox | head -1 | grep v1.36.1
}
func testBuildDetailsLink(t *testing.T, sb integration.Sandbox) {
skipNoCompatBuildKit(t, sb, ">= 0.11.0-0", "build details link")
buildDetailsPattern := regexp.MustCompile(`(?m)^View build details: docker-desktop://dashboard/build/[^/]+/[^/]+/[^/]+\n$`)
// build simple dockerfile
@ -346,6 +351,7 @@ func testBuildAnnotations(t *testing.T, sb integration.Sandbox) {
if isMobyWorker(sb) {
t.Skip("annotations not supported on docker worker")
}
skipNoCompatBuildKit(t, sb, ">= 0.11.0-0", "annotations")
dir := createTestProject(t)
@ -457,6 +463,7 @@ func testBuildNetworkModeBridge(t *testing.T, sb integration.Sandbox) {
if !isDockerContainerWorker(sb) {
t.Skip("only testing with docker-container worker")
}
skipNoCompatBuildKit(t, sb, ">= 0.13.0-0", "network bridge")
var builderName string
t.Cleanup(func() {
@ -467,8 +474,10 @@ func testBuildNetworkModeBridge(t *testing.T, sb integration.Sandbox) {
require.NoError(t, err, out)
})
// TODO: use stable buildkit image when v0.13.0 released
out, err := createCmd(sb, withArgs("--driver", "docker-container", "--buildkitd-flags=--oci-worker-net=bridge --allow-insecure-entitlement=network.host", "--driver-opt", "image=moby/buildkit:v0.13.0-rc3"))
out, err := createCmd(sb, withArgs(
"--driver", "docker-container",
"--buildkitd-flags=--oci-worker-net=bridge --allow-insecure-entitlement=network.host",
))
require.NoError(t, err, out)
builderName = strings.TrimSpace(out)
@ -577,6 +586,7 @@ func testBuildMultiExporters(t *testing.T, sb integration.Sandbox) {
if !isDockerContainerWorker(sb) {
t.Skip("only testing with docker-container worker")
}
skipNoCompatBuildKit(t, sb, ">= 0.13.0-0", "multi exporters")
registry, err := sb.NewRegistry()
if errors.Is(err, integration.ErrRequirements) {
@ -587,30 +597,12 @@ func testBuildMultiExporters(t *testing.T, sb integration.Sandbox) {
targetReg := registry + "/buildx/registry:latest"
targetStore := "buildx:local-" + identity.NewID()
var builderName string
t.Cleanup(func() {
if builderName == "" {
return
}
cmd := dockerCmd(sb, withArgs("image", "rm", targetStore))
cmd.Stderr = os.Stderr
require.NoError(t, cmd.Run())
out, err := rmCmd(sb, withArgs(builderName))
require.NoError(t, err, out)
})
// TODO: use stable buildkit image when v0.13.0 released
out, err := createCmd(sb, withArgs(
"--driver", "docker-container",
"--buildkitd-flags=--allow-insecure-entitlement=network.host",
"--driver-opt", "network=host",
"--driver-opt", "image=moby/buildkit:v0.13.0-rc3",
))
require.NoError(t, err, out)
builderName = strings.TrimSpace(out)
dir := createTestProject(t)
outputs := []string{
@ -619,7 +611,6 @@ func testBuildMultiExporters(t *testing.T, sb integration.Sandbox) {
"--output", fmt.Sprintf("type=oci,dest=%s/result", dir),
}
cmd := buildxCmd(sb, withArgs("build"), withArgs(outputs...), withArgs(dir))
cmd.Env = append(cmd.Env, "BUILDX_BUILDER="+builderName)
outb, err := cmd.CombinedOutput()
require.NoError(t, err, string(outb))
@ -645,6 +636,7 @@ func testBuildLoadPush(t *testing.T, sb integration.Sandbox) {
if !isDockerContainerWorker(sb) {
t.Skip("only testing with docker-container worker")
}
skipNoCompatBuildKit(t, sb, ">= 0.13.0-0", "multi exporters")
registry, err := sb.NewRegistry()
if errors.Is(err, integration.ErrRequirements) {
@ -654,30 +646,12 @@ func testBuildLoadPush(t *testing.T, sb integration.Sandbox) {
target := registry + "/buildx/registry:" + identity.NewID()
var builderName string
t.Cleanup(func() {
if builderName == "" {
return
}
cmd := dockerCmd(sb, withArgs("image", "rm", target))
cmd.Stderr = os.Stderr
require.NoError(t, cmd.Run())
out, err := rmCmd(sb, withArgs(builderName))
require.NoError(t, err, out)
})
// TODO: use stable buildkit image when v0.13.0 released
out, err := createCmd(sb, withArgs(
"--driver", "docker-container",
"--buildkitd-flags=--allow-insecure-entitlement=network.host",
"--driver-opt", "network=host",
"--driver-opt", "image=moby/buildkit:v0.13.0-rc3",
))
require.NoError(t, err, out)
builderName = strings.TrimSpace(out)
dir := createTestProject(t)
cmd := buildxCmd(sb, withArgs(
@ -685,7 +659,6 @@ func testBuildLoadPush(t *testing.T, sb integration.Sandbox) {
fmt.Sprintf("-t=%s", target),
dir,
))
cmd.Env = append(cmd.Env, "BUILDX_BUILDER="+builderName)
outb, err := cmd.CombinedOutput()
require.NoError(t, err, string(outb))

View File

@ -61,6 +61,7 @@ func testDialStdio(t *testing.T, sb integration.Sandbox) {
}
}()
skipNoCompatBuildKit(t, sb, ">= 0.11.0-0", "unknown method Info for service moby.buildkit.v1.Control")
_, err = c.Info(sb.Context())
require.NoError(t, err)

View File

@ -3,15 +3,22 @@ package tests
import (
"os"
"os/exec"
"path/filepath"
"strconv"
"strings"
"sync"
"testing"
"github.com/Masterminds/semver/v3"
"github.com/containerd/continuity/fs/fstest"
"github.com/moby/buildkit/util/testutil/integration"
"github.com/stretchr/testify/require"
)
const defaultBuildKitTag = "buildx-stable-1"
var buildkitImage string
func tmpdir(t *testing.T, appliers ...fstest.Applier) string {
t.Helper()
tmpdir := t.TempDir()
@ -80,6 +87,11 @@ func isMobyWorker(sb integration.Sandbox) bool {
return name == "docker" && !hasFeature
}
func isMobyContainerdSnapWorker(sb integration.Sandbox) bool {
name, hasFeature := driverName(sb.Name())
return name == "docker" && hasFeature
}
func isDockerWorker(sb integration.Sandbox) bool {
name, _ := driverName(sb.Name())
return name == "docker"
@ -107,3 +119,81 @@ func isExperimental() bool {
}
return false
}
func buildkitTag() string {
if v := os.Getenv("TEST_BUILDKIT_TAG"); v != "" {
return v
}
return defaultBuildKitTag
}
var (
bkvers map[string]string
bkversMu sync.Mutex
)
func buildkitVersion(t *testing.T, sb integration.Sandbox) string {
bkversMu.Lock()
defer bkversMu.Unlock()
if bkvers == nil {
bkvers = make(map[string]string)
}
ver, ok := bkvers[sb.Name()]
if !ok {
out, err := inspectCmd(sb, withArgs(sb.Address()))
require.NoError(t, err, out)
for _, line := range strings.Split(out, "\n") {
if v, ok := strings.CutPrefix(line, "BuildKit version:"); ok {
ver = strings.TrimSpace(v)
bkvers[sb.Name()] = ver
}
}
if ver == "" {
t.Logf("BuildKit version not found in inspect output, extract it from the image.\n%s", out)
undockBin, err := exec.LookPath("undock")
require.NoError(t, err, "undock not found")
destDir := t.TempDir()
t.Cleanup(func() {
os.RemoveAll(destDir)
})
cmd := exec.Command(undockBin, "--cachedir", "/root/.cache/undock", "--include", "/usr/bin/buildkitd", "--rm-dist", buildkitImage, destDir)
require.NoErrorf(t, cmd.Run(), "failed to extract buildkitd binary from %q", buildkitImage)
cmd = exec.Command(filepath.Join(destDir, "usr", "bin", "buildkitd"), "--version")
out, err := cmd.CombinedOutput()
require.NoErrorf(t, err, "failed to get BuildKit version from %q: %s", buildkitImage, string(out))
v := strings.Fields(strings.TrimSpace(string(out)))
if len(v) != 4 {
require.Fail(t, "unexpected version format: "+strings.TrimSpace(string(out)))
}
ver = v[2]
bkvers[sb.Name()] = ver
}
}
return ver
}
func matchesBuildKitVersion(t *testing.T, sb integration.Sandbox, constraint string) bool {
c, err := semver.NewConstraint(constraint)
if err != nil {
return false
}
v, err := semver.NewVersion(buildkitVersion(t, sb))
if err != nil {
// if the version is not a valid semver, we assume it matches (master)
return true
}
return c.Check(v)
}
func skipNoCompatBuildKit(t *testing.T, sb integration.Sandbox, constraint string, msg string) {
if !matchesBuildKitVersion(t, sb, constraint) {
t.Skipf("buildkit version %s does not match %s constraint (%s)", buildkitVersion(t, sb), constraint, msg)
}
}

View File

@ -35,7 +35,7 @@ func TestIntegration(t *testing.T) {
func testIntegration(t *testing.T, funcs ...func(t *testing.T, sb integration.Sandbox)) {
mirroredImages := integration.OfficialImages("busybox:latest", "alpine:latest")
buildkitImage := "docker.io/moby/buildkit:buildx-stable-1"
buildkitImage = "docker.io/moby/buildkit:" + buildkitTag()
if bkworkers.IsTestDockerd() {
if img, ok := os.LookupEnv("TEST_BUILDKIT_IMAGE"); ok {
ref, err := reference.ParseNormalizedNamed(img)