mirror of
https://gitea.com/Lydanne/buildx.git
synced 2025-05-18 00:47:48 +08:00
195 lines
4.8 KiB
Go
195 lines
4.8 KiB
Go
package imagetools
|
|
|
|
import (
|
|
"context"
|
|
"encoding/base64"
|
|
"fmt"
|
|
"reflect"
|
|
"testing"
|
|
|
|
"github.com/opencontainers/go-digest"
|
|
|
|
"github.com/stretchr/testify/assert"
|
|
"github.com/stretchr/testify/require"
|
|
)
|
|
|
|
func TestLoad(t *testing.T) {
|
|
loader := newLoader(getMockResolver())
|
|
ctx := context.Background()
|
|
|
|
r := getImageNoAttestation()
|
|
indexDigest := reflect.ValueOf(r.indexes).MapKeys()[0].String()
|
|
result, err := loader.Load(ctx, fmt.Sprintf("test@%s", indexDigest))
|
|
require.NoError(t, err)
|
|
if err == nil {
|
|
assert.Equal(t, 1, len(result.indexes))
|
|
assert.Equal(t, 2, len(result.images))
|
|
assert.Equal(t, 2, len(result.platforms))
|
|
assert.Equal(t, 2, len(result.manifests))
|
|
assert.Equal(t, 2, len(result.assets))
|
|
assert.Equal(t, 0, len(result.refs))
|
|
}
|
|
|
|
r = getImageWithAttestation(plainSpdx)
|
|
indexDigest = reflect.ValueOf(r.indexes).MapKeys()[0].String()
|
|
result, err = loader.Load(ctx, fmt.Sprintf("test@%s", indexDigest))
|
|
require.NoError(t, err)
|
|
if err == nil {
|
|
assert.Equal(t, 1, len(result.indexes))
|
|
assert.Equal(t, 2, len(result.images))
|
|
assert.Equal(t, 2, len(result.platforms))
|
|
assert.Equal(t, 4, len(result.manifests))
|
|
assert.Equal(t, 2, len(result.assets))
|
|
assert.Equal(t, 2, len(result.refs))
|
|
|
|
for d1, m := range r.manifests {
|
|
if _, ok := m.desc.Annotations["vnd.docker.reference.digest"]; ok {
|
|
d2 := digest.Digest(m.desc.Annotations["vnd.docker.reference.digest"])
|
|
assert.Equal(t, d1, result.refs[d2][0])
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestSBOM(t *testing.T) {
|
|
tests := []struct {
|
|
name string
|
|
contentType attestationType
|
|
}{
|
|
{
|
|
name: "Plain SPDX",
|
|
contentType: plainSpdx,
|
|
},
|
|
{
|
|
name: "SPDX in DSSE envelope",
|
|
contentType: dsseEmbeded,
|
|
},
|
|
{
|
|
name: "Plain SPDX and SPDX in DSSE envelope",
|
|
contentType: plainSpdxAndDSSEEmbed,
|
|
},
|
|
}
|
|
|
|
for _, test := range tests {
|
|
t.Run(test.name, func(t *testing.T) {
|
|
loader := newLoader(getMockResolver())
|
|
ctx := context.Background()
|
|
fetcher, _ := loader.resolver.Fetcher(ctx, "")
|
|
|
|
r := getImageWithAttestation(test.contentType)
|
|
imageDigest := r.images["linux/amd64"]
|
|
|
|
// Manual mapping
|
|
for d, m := range r.manifests {
|
|
if m.desc.Annotations["vnd.docker.reference.digest"] == string(imageDigest) {
|
|
r.refs[imageDigest] = []digest.Digest{
|
|
d,
|
|
}
|
|
}
|
|
}
|
|
|
|
a := asset{}
|
|
loader.scanSBOM(ctx, fetcher, r, r.refs[imageDigest], &a)
|
|
r.assets["linux/amd64"] = a
|
|
actual, err := r.SBOM()
|
|
|
|
require.NoError(t, err)
|
|
assert.Equal(t, 1, len(actual))
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestProvenance(t *testing.T) {
|
|
tests := []struct {
|
|
name string
|
|
contentType attestationType
|
|
}{
|
|
{
|
|
name: "Plain SPDX",
|
|
contentType: plainSpdx,
|
|
},
|
|
{
|
|
name: "SPDX in DSSE envelope",
|
|
contentType: dsseEmbeded,
|
|
},
|
|
{
|
|
name: "Plain SPDX and SPDX in DSSE envelope",
|
|
contentType: plainSpdxAndDSSEEmbed,
|
|
},
|
|
}
|
|
|
|
for _, test := range tests {
|
|
t.Run(test.name, func(t *testing.T) {
|
|
loader := newLoader(getMockResolver())
|
|
ctx := context.Background()
|
|
fetcher, _ := loader.resolver.Fetcher(ctx, "")
|
|
|
|
r := getImageWithAttestation(test.contentType)
|
|
imageDigest := r.images["linux/amd64"]
|
|
|
|
// Manual mapping
|
|
for d, m := range r.manifests {
|
|
if m.desc.Annotations["vnd.docker.reference.digest"] == string(imageDigest) {
|
|
r.refs[imageDigest] = []digest.Digest{
|
|
d,
|
|
}
|
|
}
|
|
}
|
|
|
|
a := asset{}
|
|
loader.scanProvenance(ctx, fetcher, r, r.refs[imageDigest], &a)
|
|
r.assets["linux/amd64"] = a
|
|
actual, err := r.Provenance()
|
|
|
|
require.NoError(t, err)
|
|
assert.Equal(t, 1, len(actual))
|
|
})
|
|
}
|
|
}
|
|
|
|
func Test_isInTotoDSSE(t *testing.T) {
|
|
tests := []struct {
|
|
mime string
|
|
expected bool
|
|
}{
|
|
{
|
|
mime: "application/vnd.in-toto.spdx+dsse",
|
|
expected: true,
|
|
},
|
|
{
|
|
mime: "application/vnd.in-toto.provenance+dsse",
|
|
expected: true,
|
|
},
|
|
{
|
|
mime: "application/vnd.in-toto+json",
|
|
expected: false,
|
|
},
|
|
}
|
|
|
|
for _, test := range tests {
|
|
t.Run(test.mime, func(t *testing.T) {
|
|
assert.Equal(t, test.expected, isInTotoDSSE(test.mime))
|
|
})
|
|
}
|
|
}
|
|
|
|
func Test_decodeDSSE(t *testing.T) {
|
|
// Returns input when mime isn't a DSSE type
|
|
actual, err := decodeDSSE([]byte("foobar"), "application/vnd.in-toto+json")
|
|
require.NoError(t, err)
|
|
assert.Equal(t, []byte("foobar"), actual)
|
|
|
|
// Returns the base64 decoded payload if is a DSSE
|
|
payload := base64.StdEncoding.EncodeToString([]byte("hello world"))
|
|
envelope := fmt.Sprintf("{\"payload\":\"%s\"}", payload)
|
|
actual, err = decodeDSSE([]byte(envelope), "application/vnd.in-toto.spdx+dsse")
|
|
require.NoError(t, err)
|
|
assert.Equal(t, "hello world", string(actual))
|
|
|
|
_, err = decodeDSSE([]byte("not a json"), "application/vnd.in-toto.spdx+dsse")
|
|
require.Error(t, err)
|
|
|
|
_, err = decodeDSSE([]byte("{\"payload\": \"not base64\"}"), "application/vnd.in-toto.spdx+dsse")
|
|
require.Error(t, err)
|
|
}
|