mirror of
https://github.com/moby/buildkit.git
synced 2026-08-05 23:30:22 +00:00
Replace context.TODO/background calls in targeted unit tests with t.Context(). Signed-off-by: Tonis Tiigi <tonistiigi@gmail.com>
152 lines
3.9 KiB
Go
152 lines
3.9 KiB
Go
package llb
|
|
|
|
import (
|
|
"bytes"
|
|
"context"
|
|
"fmt"
|
|
"testing"
|
|
|
|
"github.com/containerd/platforms"
|
|
digest "github.com/opencontainers/go-digest"
|
|
"github.com/stretchr/testify/require"
|
|
"golang.org/x/sync/errgroup"
|
|
)
|
|
|
|
func TestDefinitionEquivalence(t *testing.T) {
|
|
for _, tc := range []struct {
|
|
name string
|
|
state State
|
|
}{
|
|
{"scratch", Scratch()},
|
|
{"image op", Image("ref")},
|
|
{"exec op", Image("ref").Run(Shlex("args")).Root()},
|
|
{"local op", Local("name")},
|
|
{"git op", Git("remote", "ref")},
|
|
{"http op", HTTP("url")},
|
|
{"file op", Scratch().File(Mkdir("foo", 0600).Mkfile("foo/bar", 0600, []byte("data")).Copy(Scratch(), "src", "dst"))},
|
|
{"platform constraint", Image("ref", LinuxArm64)},
|
|
{"mount", Image("busybox").Run(Shlex(`sh -c "echo foo > /out/foo"`)).AddMount("/out", Scratch())},
|
|
} {
|
|
t.Run(tc.name, func(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
ctx := t.Context()
|
|
|
|
def, err := tc.state.Marshal(ctx)
|
|
require.NoError(t, err)
|
|
|
|
op, err := NewDefinitionOp(def.ToPB())
|
|
require.NoError(t, err)
|
|
|
|
err = op.Validate(ctx, nil)
|
|
require.NoError(t, err)
|
|
|
|
st2 := NewState(op.Output())
|
|
|
|
def2, err := st2.Marshal(ctx)
|
|
require.NoError(t, err)
|
|
require.Equal(t, len(def.Def), len(def2.Def))
|
|
require.Equal(t, len(def.Metadata), len(def2.Metadata))
|
|
|
|
for i := range def.Def {
|
|
res := bytes.Compare(def.Def[i], def2.Def[i])
|
|
require.Equal(t, 0, res)
|
|
}
|
|
|
|
for dgst := range def.Metadata {
|
|
require.Equal(t, def.Metadata[dgst], def2.Metadata[dgst])
|
|
}
|
|
|
|
expectedPlatform, err := tc.state.GetPlatform(ctx)
|
|
require.NoError(t, err)
|
|
actualPlatform, err := st2.GetPlatform(ctx)
|
|
require.NoError(t, err)
|
|
|
|
if expectedPlatform == nil && actualPlatform != nil {
|
|
defaultPlatform := platforms.Normalize(platforms.DefaultSpec())
|
|
expectedPlatform = &defaultPlatform
|
|
}
|
|
|
|
require.Equal(t, expectedPlatform, actualPlatform)
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestDefinitionInputCache(t *testing.T) {
|
|
src := HTTP("url")
|
|
|
|
stA := Scratch().Run(
|
|
Shlex("A"),
|
|
AddMount("/mnt", src),
|
|
)
|
|
|
|
stB := Scratch().Run(
|
|
Shlex("B"),
|
|
AddMount("/mnt", src),
|
|
)
|
|
|
|
st := Scratch().Run(
|
|
Shlex("args"),
|
|
AddMount("/a", stA.Root()),
|
|
AddMount("/a2", stA.GetMount("/mnt")),
|
|
AddMount("/b", stB.Root()),
|
|
AddMount("/b2", stB.GetMount("/mnt")),
|
|
).Root()
|
|
|
|
ctx := t.Context()
|
|
|
|
def, err := st.Marshal(ctx)
|
|
require.NoError(t, err)
|
|
|
|
op, err := NewDefinitionOp(def.ToPB())
|
|
require.NoError(t, err)
|
|
|
|
err = op.Validate(ctx, nil)
|
|
require.NoError(t, err)
|
|
|
|
st2 := NewState(op.Output())
|
|
marshalDef := &Definition{
|
|
Metadata: make(map[digest.Digest]OpMetadata, 0),
|
|
}
|
|
constraints := &Constraints{}
|
|
smc := newSourceMapCollector()
|
|
|
|
// verify the expected number of vertexes gets marshalled
|
|
vertexCache := make(map[Vertex]struct{})
|
|
_, err = marshal(ctx, st2.Output().Vertex(ctx, constraints), marshalDef, smc, map[digest.Digest]struct{}{}, vertexCache, constraints)
|
|
require.NoError(t, err)
|
|
// 1 exec + 2x2 mounts from stA and stB + 1 src = 6 vertexes
|
|
require.Equal(t, 6, len(vertexCache))
|
|
|
|
// make sure that walking vertices in parallel doesn't cause panic
|
|
var all []RunOption
|
|
for i := range 100 {
|
|
var sts []RunOption
|
|
for j := range 100 {
|
|
sts = append(sts, AddMount("/mnt", Scratch().Run(Shlex(fmt.Sprintf("%d-%d", i, j))).Root()))
|
|
}
|
|
all = append(all, AddMount("/mnt", Scratch().Run(append([]RunOption{Shlex("args")}, sts...)...).Root()))
|
|
}
|
|
def, err = Scratch().Run(append([]RunOption{Shlex("args")}, all...)...).Root().Marshal(ctx)
|
|
require.NoError(t, err)
|
|
op, err = NewDefinitionOp(def.ToPB())
|
|
require.NoError(t, err)
|
|
require.NoError(t, testParallelWalk(ctx, op.Output()))
|
|
}
|
|
|
|
func TestDefinitionNil(t *testing.T) {
|
|
// should be an error, not a panic
|
|
_, err := NewDefinitionOp(nil)
|
|
require.Error(t, err)
|
|
}
|
|
|
|
func testParallelWalk(ctx context.Context, out Output) error {
|
|
eg, egCtx := errgroup.WithContext(ctx)
|
|
for _, o := range out.Vertex(ctx, nil).Inputs() {
|
|
eg.Go(func() error {
|
|
return testParallelWalk(egCtx, o)
|
|
})
|
|
}
|
|
return eg.Wait()
|
|
}
|