mirror of https://github.com/docker/buildx.git
158 lines
4.2 KiB
Go
158 lines
4.2 KiB
Go
package tests
|
|
|
|
import (
|
|
"bytes"
|
|
"encoding/json"
|
|
"errors"
|
|
"fmt"
|
|
"os"
|
|
"path/filepath"
|
|
"strings"
|
|
"testing"
|
|
|
|
"github.com/containerd/containerd/platforms"
|
|
"github.com/containerd/continuity/fs/fstest"
|
|
"github.com/moby/buildkit/util/contentutil"
|
|
"github.com/moby/buildkit/util/testutil"
|
|
"github.com/moby/buildkit/util/testutil/integration"
|
|
"github.com/opencontainers/go-digest"
|
|
"github.com/stretchr/testify/require"
|
|
)
|
|
|
|
func buildCmd(sb integration.Sandbox, opts ...cmdOpt) (string, error) {
|
|
opts = append([]cmdOpt{withArgs("build", "--progress=quiet")}, opts...)
|
|
cmd := buildxCmd(sb, opts...)
|
|
out, err := cmd.CombinedOutput()
|
|
return string(out), err
|
|
}
|
|
|
|
var buildTests = []func(t *testing.T, sb integration.Sandbox){
|
|
testBuild,
|
|
testImageIDOutput,
|
|
testBuildLocalExport,
|
|
testBuildRegistryExport,
|
|
testBuildTarExport,
|
|
}
|
|
|
|
func testBuild(t *testing.T, sb integration.Sandbox) {
|
|
dir := createTestProject(t)
|
|
out, err := buildCmd(sb, withArgs(dir))
|
|
require.NoError(t, err, string(out))
|
|
}
|
|
|
|
func testBuildLocalExport(t *testing.T, sb integration.Sandbox) {
|
|
dir := createTestProject(t)
|
|
out, err := buildCmd(sb, withArgs(fmt.Sprintf("--output=type=local,dest=%s/result", dir), dir))
|
|
require.NoError(t, err, string(out))
|
|
|
|
dt, err := os.ReadFile(dir + "/result/bar")
|
|
require.NoError(t, err)
|
|
require.Equal(t, "foo", string(dt))
|
|
}
|
|
|
|
func testBuildTarExport(t *testing.T, sb integration.Sandbox) {
|
|
dir := createTestProject(t)
|
|
out, err := buildCmd(sb, withArgs(fmt.Sprintf("--output=type=tar,dest=%s/result.tar", dir), dir))
|
|
require.NoError(t, err, string(out))
|
|
|
|
dt, err := os.ReadFile(fmt.Sprintf("%s/result.tar", dir))
|
|
require.NoError(t, err)
|
|
m, err := testutil.ReadTarToMap(dt, false)
|
|
require.NoError(t, err)
|
|
|
|
require.Contains(t, m, "bar")
|
|
require.Equal(t, "foo", string(m["bar"].Data))
|
|
}
|
|
|
|
func testBuildRegistryExport(t *testing.T, sb integration.Sandbox) {
|
|
dir := createTestProject(t)
|
|
|
|
registry, err := sb.NewRegistry()
|
|
if errors.Is(err, integration.ErrRequirements) {
|
|
t.Skip(err.Error())
|
|
}
|
|
require.NoError(t, err)
|
|
target := registry + "/buildx/registry:latest"
|
|
|
|
out, err := buildCmd(sb, withArgs(fmt.Sprintf("--output=type=image,name=%s,push=true", target), dir))
|
|
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)
|
|
|
|
pk := platforms.Format(platforms.Normalize(platforms.DefaultSpec()))
|
|
img := imgs.Find(pk)
|
|
require.NotNil(t, img)
|
|
require.Len(t, img.Layers, 1)
|
|
require.Equal(t, img.Layers[0]["bar"].Data, []byte("foo"))
|
|
}
|
|
|
|
func testImageIDOutput(t *testing.T, sb integration.Sandbox) {
|
|
dockerfile := []byte(`FROM busybox:latest`)
|
|
|
|
dir := tmpdir(t,
|
|
fstest.CreateFile("Dockerfile", dockerfile, 0600),
|
|
)
|
|
targetDir := t.TempDir()
|
|
|
|
outFlag := "--output=type=docker"
|
|
|
|
if sb.Name() == "remote" {
|
|
// there is no Docker atm to load the image
|
|
outFlag += ",dest=" + targetDir + "/image.tar"
|
|
}
|
|
|
|
cmd := buildxCmd(
|
|
sb,
|
|
withArgs("build", "-q", "--provenance", "false", outFlag, "--iidfile", filepath.Join(targetDir, "iid.txt"), "--metadata-file", filepath.Join(targetDir, "md.json"), dir),
|
|
)
|
|
stdout := bytes.NewBuffer(nil)
|
|
cmd.Stdout = stdout
|
|
cmd.Stderr = os.Stderr
|
|
err := cmd.Run()
|
|
require.NoError(t, err)
|
|
|
|
dt, err := os.ReadFile(filepath.Join(targetDir, "iid.txt"))
|
|
require.NoError(t, err)
|
|
|
|
imageID := string(dt)
|
|
require.NotEmpty(t, imageID)
|
|
|
|
dgst, err := digest.Parse(string(dt))
|
|
require.NoError(t, err)
|
|
|
|
require.Equal(t, dgst.String(), strings.TrimSpace(stdout.String()))
|
|
|
|
dt, err = os.ReadFile(filepath.Join(targetDir, "md.json"))
|
|
require.NoError(t, err)
|
|
|
|
type mdT struct {
|
|
ConfigDigest string `json:"containerimage.config.digest"`
|
|
}
|
|
var md mdT
|
|
err = json.Unmarshal(dt, &md)
|
|
require.NoError(t, err)
|
|
|
|
require.NotEmpty(t, md.ConfigDigest)
|
|
require.Equal(t, dgst, digest.Digest(md.ConfigDigest))
|
|
}
|
|
|
|
func createTestProject(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
|
|
`)
|
|
dir := tmpdir(
|
|
t,
|
|
fstest.CreateFile("Dockerfile", dockerfile, 0600),
|
|
fstest.CreateFile("foo", []byte("foo"), 0600),
|
|
)
|
|
return dir
|
|
}
|