mirror of
				https://gitea.com/Lydanne/buildx.git
				synced 2025-10-31 16:13:45 +08:00 
			
		
		
		
	
		
			
				
	
	
		
			200 lines
		
	
	
		
			4.7 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			200 lines
		
	
	
		
			4.7 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
| 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()
 | |
| 	err := fstest.Apply(appliers...).Apply(tmpdir)
 | |
| 	require.NoError(t, err)
 | |
| 	return tmpdir
 | |
| }
 | |
| 
 | |
| type cmdOpt func(*exec.Cmd)
 | |
| 
 | |
| func withEnv(env ...string) cmdOpt {
 | |
| 	return func(cmd *exec.Cmd) {
 | |
| 		cmd.Env = append(cmd.Env, env...)
 | |
| 	}
 | |
| }
 | |
| 
 | |
| func withArgs(args ...string) cmdOpt {
 | |
| 	return func(cmd *exec.Cmd) {
 | |
| 		cmd.Args = append(cmd.Args, args...)
 | |
| 	}
 | |
| }
 | |
| 
 | |
| func withDir(dir string) cmdOpt {
 | |
| 	return func(cmd *exec.Cmd) {
 | |
| 		cmd.Dir = dir
 | |
| 	}
 | |
| }
 | |
| 
 | |
| func buildxCmd(sb integration.Sandbox, opts ...cmdOpt) *exec.Cmd {
 | |
| 	cmd := exec.Command("buildx")
 | |
| 	cmd.Env = append([]string{}, os.Environ()...)
 | |
| 	for _, opt := range opts {
 | |
| 		opt(cmd)
 | |
| 	}
 | |
| 
 | |
| 	if builder := sb.Address(); builder != "" {
 | |
| 		cmd.Env = append(cmd.Env,
 | |
| 			"BUILDX_CONFIG=/tmp/buildx-"+builder,
 | |
| 			"BUILDX_BUILDER="+builder,
 | |
| 		)
 | |
| 	}
 | |
| 	if context := sb.DockerAddress(); context != "" {
 | |
| 		cmd.Env = append(cmd.Env, "DOCKER_CONTEXT="+context)
 | |
| 	}
 | |
| 	if isExperimental() {
 | |
| 		cmd.Env = append(cmd.Env, "BUILDX_EXPERIMENTAL=1")
 | |
| 	}
 | |
| 
 | |
| 	return cmd
 | |
| }
 | |
| 
 | |
| func dockerCmd(sb integration.Sandbox, opts ...cmdOpt) *exec.Cmd {
 | |
| 	cmd := exec.Command("docker")
 | |
| 	cmd.Env = append([]string{}, os.Environ()...)
 | |
| 	for _, opt := range opts {
 | |
| 		opt(cmd)
 | |
| 	}
 | |
| 	if context := sb.DockerAddress(); context != "" {
 | |
| 		cmd.Env = append(cmd.Env, "DOCKER_CONTEXT="+context)
 | |
| 	}
 | |
| 	return cmd
 | |
| }
 | |
| 
 | |
| func isMobyWorker(sb integration.Sandbox) bool {
 | |
| 	name, hasFeature := driverName(sb.Name())
 | |
| 	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"
 | |
| }
 | |
| 
 | |
| func isDockerContainerWorker(sb integration.Sandbox) bool {
 | |
| 	name, _ := driverName(sb.Name())
 | |
| 	return name == "docker-container"
 | |
| }
 | |
| 
 | |
| func driverName(sbName string) (string, bool) {
 | |
| 	name := sbName
 | |
| 	var hasFeature bool
 | |
| 	if b, _, ok := strings.Cut(name, "+"); ok {
 | |
| 		name = b
 | |
| 		hasFeature = true
 | |
| 	}
 | |
| 	return name, hasFeature
 | |
| }
 | |
| 
 | |
| func isExperimental() bool {
 | |
| 	if v, ok := os.LookupEnv("TEST_BUILDX_EXPERIMENTAL"); ok {
 | |
| 		vv, _ := strconv.ParseBool(v)
 | |
| 		return vv
 | |
| 	}
 | |
| 	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)
 | |
| 	}
 | |
| }
 | 
