1
0
mirror of https://github.com/SAP/jenkins-library.git synced 2024-12-14 11:03:09 +02:00
sap-jenkins-library/pkg/cnbutils/sbom_test.go
Pavel Busko 14ce92b4fb
cnbBuild: create CycloneDX SBOM file (#3959)
Co-authored-by: Johannes Dillmann <j.dillmann@sap.com>
Co-authored-by: Ralf Pannemans <ralf.pannemans@sap.com>
2022-08-18 10:03:24 +02:00

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")
}