Skip to content

Commit 95aaabd

Browse files
jedevctonistiigi
authored andcommitted
client: add tests for layerID in comment field
Signed-off-by: Justin Chadwell <[email protected]> (cherry picked from commit 1c55dc2)
1 parent f0c74da commit 95aaabd

File tree

1 file changed

+150
-0
lines changed

1 file changed

+150
-0
lines changed

client/client_test.go

Lines changed: 150 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@ import (
6262
digest "github.com/opencontainers/go-digest"
6363
ocispecs "github.com/opencontainers/image-spec/specs-go/v1"
6464
"github.com/pkg/errors"
65+
spdx "github.com/spdx/tools-golang/spdx/v2_3"
6566
"github.com/stretchr/testify/require"
6667
"golang.org/x/crypto/ssh/agent"
6768
"golang.org/x/sync/errgroup"
@@ -189,6 +190,7 @@ func TestIntegration(t *testing.T) {
189190
testAttestationBundle,
190191
testSBOMScan,
191192
testSBOMScanSingleRef,
193+
testSBOMSupplements,
192194
testMultipleCacheExports,
193195
testMountStubsDirectory,
194196
testMountStubsTimestamp,
@@ -8199,6 +8201,154 @@ EOF
81998201
require.Subset(t, attest.Predicate, map[string]interface{}{"name": "fallback"})
82008202
}
82018203

8204+
func testSBOMSupplements(t *testing.T, sb integration.Sandbox) {
8205+
integration.CheckFeatureCompat(t, sb, integration.FeatureDirectPush, integration.FeatureSBOM)
8206+
requiresLinux(t)
8207+
c, err := New(sb.Context(), sb.Address())
8208+
require.NoError(t, err)
8209+
8210+
registry, err := sb.NewRegistry()
8211+
if errors.Is(err, integration.ErrRequirements) {
8212+
t.Skip(err.Error())
8213+
}
8214+
8215+
p := platforms.MustParse("linux/amd64")
8216+
pk := platforms.Format(p)
8217+
8218+
frontend := func(ctx context.Context, c gateway.Client) (*gateway.Result, error) {
8219+
res := gateway.NewResult()
8220+
8221+
// build image
8222+
st := llb.Scratch().File(
8223+
llb.Mkfile("/foo", 0600, []byte{}),
8224+
)
8225+
def, err := st.Marshal(ctx)
8226+
if err != nil {
8227+
return nil, err
8228+
}
8229+
r, err := c.Solve(ctx, gateway.SolveRequest{
8230+
Definition: def.ToPB(),
8231+
})
8232+
if err != nil {
8233+
return nil, err
8234+
}
8235+
ref, err := r.SingleRef()
8236+
if err != nil {
8237+
return nil, err
8238+
}
8239+
_, err = ref.ToState()
8240+
if err != nil {
8241+
return nil, err
8242+
}
8243+
res.AddRef(pk, ref)
8244+
8245+
expPlatforms := &exptypes.Platforms{
8246+
Platforms: []exptypes.Platform{{ID: pk, Platform: p}},
8247+
}
8248+
dt, err := json.Marshal(expPlatforms)
8249+
if err != nil {
8250+
return nil, err
8251+
}
8252+
res.AddMeta(exptypes.ExporterPlatformsKey, dt)
8253+
8254+
// build attestations
8255+
doc := spdx.Document{
8256+
SPDXIdentifier: "DOCUMENT",
8257+
Files: []*spdx.File{
8258+
{
8259+
// foo exists...
8260+
FileSPDXIdentifier: "SPDXRef-File-foo",
8261+
FileName: "/foo",
8262+
},
8263+
{
8264+
// ...but bar doesn't
8265+
FileSPDXIdentifier: "SPDXRef-File-bar",
8266+
FileName: "/bar",
8267+
},
8268+
},
8269+
}
8270+
docBytes, err := json.Marshal(doc)
8271+
if err != nil {
8272+
return nil, err
8273+
}
8274+
st = llb.Scratch().
8275+
File(llb.Mkfile("/result.spdx", 0600, docBytes))
8276+
def, err = st.Marshal(ctx)
8277+
if err != nil {
8278+
return nil, err
8279+
}
8280+
r, err = c.Solve(ctx, gateway.SolveRequest{
8281+
Definition: def.ToPB(),
8282+
})
8283+
if err != nil {
8284+
return nil, err
8285+
}
8286+
refAttest, err := r.SingleRef()
8287+
if err != nil {
8288+
return nil, err
8289+
}
8290+
_, err = ref.ToState()
8291+
if err != nil {
8292+
return nil, err
8293+
}
8294+
8295+
res.AddAttestation(pk, gateway.Attestation{
8296+
Kind: gatewaypb.AttestationKindInToto,
8297+
Ref: refAttest,
8298+
Path: "/result.spdx",
8299+
InToto: result.InTotoAttestation{
8300+
PredicateType: intoto.PredicateSPDX,
8301+
},
8302+
Metadata: map[string][]byte{
8303+
result.AttestationSBOMCore: []byte("result"),
8304+
},
8305+
})
8306+
8307+
return res, nil
8308+
}
8309+
8310+
// test the default fallback scanner
8311+
target := registry + "/buildkit/testsbom:latest"
8312+
_, err = c.Build(sb.Context(), SolveOpt{
8313+
FrontendAttrs: map[string]string{
8314+
"attest:sbom": "",
8315+
},
8316+
Exports: []ExportEntry{
8317+
{
8318+
Type: ExporterImage,
8319+
Attrs: map[string]string{
8320+
"name": target,
8321+
"push": "true",
8322+
},
8323+
},
8324+
},
8325+
}, "", frontend, nil)
8326+
require.NoError(t, err)
8327+
8328+
desc, provider, err := contentutil.ProviderFromRef(target)
8329+
require.NoError(t, err)
8330+
8331+
imgs, err := testutil.ReadImages(sb.Context(), provider, desc)
8332+
require.NoError(t, err)
8333+
require.Equal(t, 2, len(imgs.Images))
8334+
8335+
att := imgs.Find("unknown/unknown")
8336+
attest := struct {
8337+
intoto.StatementHeader
8338+
Predicate spdx.Document
8339+
}{}
8340+
require.NoError(t, json.Unmarshal(att.LayersRaw[0], &attest))
8341+
require.Equal(t, "https://in-toto.io/Statement/v0.1", attest.Type)
8342+
require.Equal(t, intoto.PredicateSPDX, attest.PredicateType)
8343+
8344+
require.Equal(t, "DOCUMENT", string(attest.Predicate.SPDXIdentifier))
8345+
require.Len(t, attest.Predicate.Files, 2)
8346+
require.Equal(t, attest.Predicate.Files[0].FileName, "/foo")
8347+
require.Regexp(t, "^layerID: sha256:", attest.Predicate.Files[0].FileComment)
8348+
require.Equal(t, attest.Predicate.Files[1].FileName, "/bar")
8349+
require.Empty(t, attest.Predicate.Files[1].FileComment)
8350+
}
8351+
82028352
func testMultipleCacheExports(t *testing.T, sb integration.Sandbox) {
82038353
integration.CheckFeatureCompat(t, sb, integration.FeatureMultiCacheExport)
82048354
c, err := New(sb.Context(), sb.Address())

0 commit comments

Comments
 (0)