mirror of
https://github.com/SAP/jenkins-library.git
synced 2024-12-14 11:03:09 +02:00
14ce92b4fb
Co-authored-by: Johannes Dillmann <j.dillmann@sap.com> Co-authored-by: Ralf Pannemans <ralf.pannemans@sap.com>
119 lines
3.2 KiB
Go
119 lines
3.2 KiB
Go
package cnbutils_test
|
|
|
|
import (
|
|
"archive/tar"
|
|
"bytes"
|
|
"crypto/sha256"
|
|
"encoding/hex"
|
|
"io"
|
|
"os"
|
|
"testing"
|
|
|
|
"github.com/SAP/jenkins-library/pkg/cnbutils"
|
|
"github.com/SAP/jenkins-library/pkg/mock"
|
|
v1 "github.com/google/go-containerregistry/pkg/v1"
|
|
"github.com/google/go-containerregistry/pkg/v1/fake"
|
|
"github.com/google/go-containerregistry/pkg/v1/partial"
|
|
"github.com/google/go-containerregistry/pkg/v1/types"
|
|
"github.com/stretchr/testify/assert"
|
|
)
|
|
|
|
type uncompressedLayer struct {
|
|
diffID v1.Hash
|
|
mediaType types.MediaType
|
|
content []byte
|
|
}
|
|
|
|
// DiffID implements partial.UncompressedLayer
|
|
func (ul *uncompressedLayer) DiffID() (v1.Hash, error) {
|
|
return ul.diffID, nil
|
|
}
|
|
|
|
// Uncompressed implements partial.UncompressedLayer
|
|
func (ul *uncompressedLayer) Uncompressed() (io.ReadCloser, error) {
|
|
return io.NopCloser(bytes.NewBuffer(ul.content)), nil
|
|
}
|
|
|
|
// MediaType returns the media type of the layer
|
|
func (ul *uncompressedLayer) MediaType() (types.MediaType, error) {
|
|
return ul.mediaType, nil
|
|
}
|
|
|
|
func fakeLayer(path string, content []byte) (v1.Layer, error) {
|
|
var b bytes.Buffer
|
|
hasher := sha256.New()
|
|
mw := io.MultiWriter(&b, hasher)
|
|
|
|
// Write a single file with a random name and random contents.
|
|
tw := tar.NewWriter(mw)
|
|
if err := tw.WriteHeader(&tar.Header{
|
|
Name: path,
|
|
Size: int64(len(content)),
|
|
Typeflag: tar.TypeRegA,
|
|
}); err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
if _, err := io.WriteString(tw, string(content)); err != nil {
|
|
return nil, err
|
|
}
|
|
if err := tw.Close(); err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
h := v1.Hash{
|
|
Algorithm: "sha256",
|
|
Hex: hex.EncodeToString(hasher.Sum(make([]byte, 0, hasher.Size()))),
|
|
}
|
|
|
|
return partial.UncompressedToLayer(&uncompressedLayer{
|
|
mediaType: types.DockerLayer,
|
|
diffID: h,
|
|
content: b.Bytes(),
|
|
})
|
|
}
|
|
|
|
func TestMergeSBOMFiles(t *testing.T) {
|
|
var mockUtils = &cnbutils.MockUtils{
|
|
ExecMockRunner: &mock.ExecMockRunner{},
|
|
FilesMock: &mock.FilesMock{},
|
|
DownloadMock: &mock.DownloadMock{},
|
|
}
|
|
|
|
fakeImg := &fake.FakeImage{}
|
|
fakeImg.ConfigFileReturns(&v1.ConfigFile{
|
|
Config: v1.Config{Labels: map[string]string{"io.buildpacks.base.sbom": "sha256:9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08"}},
|
|
}, nil)
|
|
|
|
baseSBOM, err := os.ReadFile("testdata/base.syft.json")
|
|
assert.NoError(t, err)
|
|
fLayer, err := fakeLayer("cnb/sbom/test.syft.json", baseSBOM)
|
|
assert.NoError(t, err)
|
|
fakeImg.LayerByDiffIDReturns(fLayer, nil)
|
|
|
|
mockUtils.ReturnImage = fakeImg
|
|
mockUtils.RemoteImageInfo = fakeImg
|
|
|
|
sbom1, err := os.ReadFile("testdata/sbom1.syft.json")
|
|
assert.NoError(t, err)
|
|
mockUtils.FilesMock.AddFile("/layer/1/sbom.syft.json", sbom1)
|
|
sbom2, err := os.ReadFile("testdata/sbom2.syft.json")
|
|
assert.NoError(t, err)
|
|
mockUtils.FilesMock.AddFile("/layer/2/sbom.syft.json", sbom2)
|
|
|
|
err = cnbutils.MergeSBOMFiles("layer/**/sbom.syft.json", "sbom.xml", "imageName", "", mockUtils)
|
|
assert.NoError(t, err)
|
|
|
|
exists, err := mockUtils.FileExists("/sbom.xml")
|
|
assert.NoError(t, err)
|
|
assert.True(t, exists)
|
|
|
|
content, err := mockUtils.ReadFile("/sbom.xml")
|
|
assert.NoError(t, err)
|
|
|
|
assert.Contains(t, string(content), "base-files")
|
|
assert.Contains(t, string(content), "operating-system")
|
|
assert.Contains(t, string(content), "component1")
|
|
assert.Contains(t, string(content), "component2")
|
|
}
|