Files
trivy/pkg/oci/artifact_test.go

137 lines
3.3 KiB
Go

package oci_test
import (
"errors"
"os"
"path/filepath"
"testing"
v1 "github.com/google/go-containerregistry/pkg/v1"
fakei "github.com/google/go-containerregistry/pkg/v1/fake"
"github.com/google/go-containerregistry/pkg/v1/tarball"
"github.com/google/go-containerregistry/pkg/v1/types"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
ftypes "github.com/aquasecurity/trivy/pkg/fanal/types"
"github.com/aquasecurity/trivy/pkg/oci"
)
type fakeLayer struct {
v1.Layer
}
func (f fakeLayer) MediaType() (types.MediaType, error) {
return "application/vnd.cncf.openpolicyagent.layer.v1.tar+gzip", nil
}
func TestArtifact_Download(t *testing.T) {
layer, err := tarball.LayerFromFile("testdata/test.tar.gz")
require.NoError(t, err)
txtLayer, err := tarball.LayerFromFile("testdata/test.txt")
require.NoError(t, err)
flayer := fakeLayer{layer}
type layersReturns struct {
layers []v1.Layer
err error
}
tests := []struct {
name string
input string
mediaType string
layersReturns layersReturns
want string
wantErr string
}{
{
name: "happy path",
input: "testdata/test.tar.gz",
mediaType: "application/vnd.cncf.openpolicyagent.layer.v1.tar+gzip",
layersReturns: layersReturns{
layers: []v1.Layer{flayer},
},
want: "Hello, world",
},
{
name: "sad: two layers",
mediaType: "application/vnd.cncf.openpolicyagent.layer.v1.tar+gzip",
layersReturns: layersReturns{
layers: []v1.Layer{
layer,
layer,
},
},
wantErr: "OCI artifact must be a single layer",
},
{
name: "sad: Layers returns an error",
mediaType: "application/vnd.cncf.openpolicyagent.layer.v1.tar+gzip",
layersReturns: layersReturns{
err: errors.New("error"),
},
wantErr: "OCI layer error",
},
{
name: "invalid gzip",
input: "testdata/test.txt",
layersReturns: layersReturns{
layers: []v1.Layer{txtLayer},
},
wantErr: "unexpected EOF",
},
{
name: "sad: media type doesn't match",
mediaType: "unknown",
layersReturns: layersReturns{
layers: []v1.Layer{layer},
},
wantErr: "unacceptable media type",
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
tempDir := t.TempDir()
// Mock image
img := new(fakei.FakeImage)
img.LayersReturns(tt.layersReturns.layers, tt.layersReturns.err)
img.ManifestReturns(&v1.Manifest{
Layers: []v1.Descriptor{
{
MediaType: "application/vnd.cncf.openpolicyagent.layer.v1.tar+gzip",
Size: 100,
Digest: v1.Hash{
Algorithm: "sha256",
Hex: "cba33656188782852f58993f45b68bfb8577f64cdcf02a604e3fc2afbeb5f2d8",
},
Annotations: map[string]string{
"org.opencontainers.image.title": "bundle.tar.gz",
},
},
},
}, nil)
artifact := oci.NewArtifact("repo", ftypes.RegistryOptions{}, oci.WithImage(img))
err = artifact.Download(t.Context(), tempDir, oci.DownloadOption{
MediaType: tt.mediaType,
Quiet: true,
})
if tt.wantErr != "" {
assert.ErrorContains(t, err, tt.wantErr)
return
}
require.NoError(t, err)
// Assert
got, err := os.ReadFile(filepath.Join(tempDir, "test.txt"))
require.NoError(t, err)
assert.Equal(t, tt.want, string(got))
})
}
}