mirror of
https://github.com/moby/buildkit.git
synced 2026-08-05 15:20:22 +00:00
Reject unknown SecurityMode values before generating executor specs. Ensure only SecurityMode_INSECURE takes the insecure path, while validated non-insecure modes keep sandbox security options. Add gateway, raw LLB, and LLB marshal regression coverage for invalid enum values. Signed-off-by: Tonis Tiigi <tonistiigi@gmail.com> (cherry picked from commit 972895718f963c71388aeebb7cff423ef6963a92)
175 lines
4.9 KiB
Go
175 lines
4.9 KiB
Go
package llb
|
|
|
|
import (
|
|
"context"
|
|
"testing"
|
|
|
|
"github.com/moby/buildkit/solver/pb"
|
|
"github.com/stretchr/testify/require"
|
|
)
|
|
|
|
func TestTmpfsMountError(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
st := Image("foo").Run(Shlex("args")).AddMount("/tmp", Scratch(), Tmpfs())
|
|
_, err := st.Marshal(context.TODO())
|
|
|
|
require.Error(t, err)
|
|
require.Contains(t, err.Error(), "can't be used as a parent")
|
|
|
|
st = Image("foo").Run(Shlex("args"), AddMount("/tmp", Scratch(), Tmpfs())).Root()
|
|
_, err = st.Marshal(context.TODO())
|
|
require.NoError(t, err)
|
|
|
|
st = Image("foo").Run(Shlex("args"), AddMount("/tmp", Image("bar"), Tmpfs())).Root()
|
|
_, err = st.Marshal(context.TODO())
|
|
require.Error(t, err)
|
|
require.Contains(t, err.Error(), "must use scratch")
|
|
}
|
|
|
|
func TestInvalidSecurityModeMarshalError(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
st := Image("busybox:latest").
|
|
Run(Shlex("true"), Security(pb.SecurityMode(2))).Root()
|
|
|
|
_, err := st.Marshal(context.TODO())
|
|
require.Error(t, err)
|
|
require.Contains(t, err.Error(), "invalid security mode")
|
|
}
|
|
|
|
func TestValidGetMountIndex(t *testing.T) {
|
|
// tests for https://github.com/moby/buildkit/issues/1520
|
|
|
|
// tmpfs mount /c will sort later than target mount /b, /b will have output index==1
|
|
st := Image("foo").Run(Shlex("args"), AddMount("/b", Scratch()), AddMount("/c", Scratch(), Tmpfs())).GetMount("/b")
|
|
|
|
mountOutput, ok := st.Output().(*output)
|
|
require.True(t, ok, "mount output is expected type")
|
|
|
|
mountIndex, err := mountOutput.getIndex()
|
|
require.NoError(t, err, "failed to getIndex")
|
|
require.Equal(t, pb.OutputIndex(1), mountIndex, "unexpected mount index")
|
|
|
|
// now swapping so the tmpfs mount /a will sort earlier than the target mount /b, /b should still have output index==1
|
|
st = Image("foo").Run(Shlex("args"), AddMount("/b", Scratch()), AddMount("/a", Scratch(), Tmpfs())).GetMount("/b")
|
|
|
|
mountOutput, ok = st.Output().(*output)
|
|
require.True(t, ok, "mount output is expected type")
|
|
|
|
mountIndex, err = mountOutput.getIndex()
|
|
require.NoError(t, err, "failed to getIndex")
|
|
require.Equal(t, pb.OutputIndex(1), mountIndex, "unexpected mount index")
|
|
}
|
|
|
|
func TestLinuxResourcesMarshal(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
st := Image("busybox:latest").
|
|
Run(
|
|
Shlex("true"),
|
|
MemoryLimit(64*1024*1024),
|
|
CPUShares(512),
|
|
CPUQuota(50000),
|
|
CPUPeriod(100000),
|
|
CpusetCpus("0-3"),
|
|
CpusetMems("0"),
|
|
).Root()
|
|
|
|
def, err := st.Marshal(context.TODO())
|
|
require.NoError(t, err)
|
|
|
|
// Resources should be in OpMetadata (not in the Op bytes / cache key)
|
|
var found bool
|
|
for _, md := range def.Metadata {
|
|
if md.LinuxResources == nil {
|
|
continue
|
|
}
|
|
found = true
|
|
res := md.LinuxResources
|
|
require.Equal(t, int64(64*1024*1024), res.Memory)
|
|
require.Equal(t, uint64(512), res.CpuShares)
|
|
require.Equal(t, int64(50000), res.CpuQuota)
|
|
require.Equal(t, uint64(100000), res.CpuPeriod)
|
|
require.Equal(t, "0-3", res.CpusetCpus)
|
|
require.Equal(t, "0", res.CpusetMems)
|
|
}
|
|
require.True(t, found, "LinuxResources not found in OpMetadata")
|
|
}
|
|
|
|
func TestLinuxResourcesNotInCacheKey(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
// Two ops with same command but different resource limits must produce the same digest
|
|
st1 := Image("busybox:latest").
|
|
Run(Shlex("echo hello"), MemoryLimit(64*1024*1024)).Root()
|
|
|
|
st2 := Image("busybox:latest").
|
|
Run(Shlex("echo hello"), MemoryLimit(128*1024*1024)).Root()
|
|
|
|
st3 := Image("busybox:latest").
|
|
Run(Shlex("echo hello")).Root()
|
|
|
|
def1, err := st1.Marshal(context.TODO())
|
|
require.NoError(t, err)
|
|
|
|
def2, err := st2.Marshal(context.TODO())
|
|
require.NoError(t, err)
|
|
|
|
def3, err := st3.Marshal(context.TODO())
|
|
require.NoError(t, err)
|
|
|
|
// All three should produce the same definition bytes (same cache key)
|
|
require.Equal(t, def1.Def, def2.Def, "different resource limits should produce same digest")
|
|
require.Equal(t, def1.Def, def3.Def, "resource limits vs no limits should produce same digest")
|
|
}
|
|
|
|
func TestLinuxResourcesMerge(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
// Test that individual resource limit functions merge correctly
|
|
st := Image("busybox:latest").
|
|
Run(
|
|
Shlex("true"),
|
|
MemoryLimit(64*1024*1024),
|
|
CPUShares(512),
|
|
).Root()
|
|
|
|
def, err := st.Marshal(context.TODO())
|
|
require.NoError(t, err)
|
|
|
|
for _, md := range def.Metadata {
|
|
if md.LinuxResources == nil {
|
|
continue
|
|
}
|
|
res := md.LinuxResources
|
|
require.Equal(t, int64(64*1024*1024), res.Memory)
|
|
require.Equal(t, uint64(512), res.CpuShares)
|
|
// Unset fields should be zero
|
|
require.Equal(t, int64(0), res.CpuQuota)
|
|
require.Equal(t, uint64(0), res.CpuPeriod)
|
|
return
|
|
}
|
|
t.Fatal("LinuxResources not found in OpMetadata")
|
|
}
|
|
|
|
func TestExecOpMarshalConsistency(t *testing.T) {
|
|
var prevDef [][]byte
|
|
st := Image("busybox:latest").
|
|
Run(
|
|
Args([]string{"ls /a; ls /b"}),
|
|
AddMount("/b", Scratch().File(Mkfile("file1", 0644, []byte("file1 contents")))),
|
|
).AddMount("/a", Scratch().File(Mkfile("file2", 0644, []byte("file2 contents"))))
|
|
|
|
for range 100 {
|
|
def, err := st.Marshal(context.TODO())
|
|
require.NoError(t, err)
|
|
|
|
if prevDef != nil {
|
|
require.Equal(t, def.Def, prevDef)
|
|
}
|
|
|
|
prevDef = def.Def
|
|
}
|
|
}
|