Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(coverage): add coverage for boltdb and dynamo #2018

Merged
merged 1 commit into from
Nov 8, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions errors/errors.go
Original file line number Diff line number Diff line change
Expand Up @@ -118,9 +118,9 @@ var (
ErrEmptyTag = errors.New("metadb: tag can't be empty string")
ErrEmptyDigest = errors.New("metadb: digest can't be empty string")
ErrInvalidRepoRefFormat = errors.New("invalid image reference format [repo:tag] or [repo@digest]")
ErrLimitIsNegative = errors.New("pageturner: limit has negative value")
ErrOffsetIsNegative = errors.New("pageturner: offset has negative value")
ErrSortCriteriaNotSupported = errors.New("pageturner: the sort criteria is not supported")
ErrLimitIsNegative = errors.New("pagination: limit has negative value")
ErrOffsetIsNegative = errors.New("pagination: offset has negative value")
ErrSortCriteriaNotSupported = errors.New("pagination: the sort criteria is not supported")
ErrMediaTypeNotSupported = errors.New("metadb: media type is not supported")
ErrTimeout = errors.New("operation timeout")
ErrNotImplemented = errors.New("not implemented")
Expand Down
21 changes: 21 additions & 0 deletions pkg/extensions/search/convert/convert_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -796,3 +796,24 @@ func TestIndexAnnotations(t *testing.T) {
So(err, ShouldBeNil)
})
}

func TestConvertErrors(t *testing.T) {
ctx := context.Background()
log := log.NewLogger("debug", "")

Convey("Errors", t, func() {
Convey("RepoMeta2ExpandedRepoInfo", func() {
_, imgSums := convert.RepoMeta2ExpandedRepoInfo(ctx,
mTypes.RepoMeta{
Tags: map[string]mTypes.Descriptor{"tag": {MediaType: "bad-type", Digest: "digest"}},
},
map[string]mTypes.ImageMeta{
"digest": {},
},
convert.SkipQGLField{}, nil,
log,
)
So(len(imgSums), ShouldEqual, 0)
})
})
}
11 changes: 6 additions & 5 deletions pkg/extensions/search/convert/metadb.go
Original file line number Diff line number Diff line change
Expand Up @@ -175,12 +175,12 @@ func GetFullImageMeta(tag string, repoMeta mTypes.RepoMeta, imageMeta mTypes.Ima
}
}

func GetFullManifestMeta(repoMeta mTypes.RepoMeta, manifests []mTypes.ManifestData) []mTypes.FullManifestMeta {
func GetFullManifestMeta(repoMeta mTypes.RepoMeta, manifests []mTypes.ManifestMeta) []mTypes.FullManifestMeta {
results := make([]mTypes.FullManifestMeta, 0, len(manifests))

for i := range manifests {
results = append(results, mTypes.FullManifestMeta{
ManifestData: manifests[i],
ManifestMeta: manifests[i],
Referrers: repoMeta.Referrers[manifests[i].Digest.String()],
Statistics: repoMeta.Statistics[manifests[i].Digest.String()],
Signatures: repoMeta.Signatures[manifests[i].Digest.String()],
Expand Down Expand Up @@ -321,16 +321,17 @@ func RepoMeta2RepoSummary(ctx context.Context, repoMeta mTypes.RepoMeta,
) *gql_generated.RepoSummary {
var (
repoName = repoMeta.Name
repoLastUpdatedTimestamp = deref(repoMeta.LastUpdatedImage, mTypes.LastUpdatedImage{}).LastUpdated
lastUpdatedImage = deref(repoMeta.LastUpdatedImage, mTypes.LastUpdatedImage{})
lastUpdatedImageMeta = imageMetaMap[lastUpdatedImage.Digest]
lastUpdatedTag = lastUpdatedImage.Tag
repoLastUpdatedTimestamp = lastUpdatedImage.LastUpdated
repoPlatforms = repoMeta.Platforms
repoVendors = repoMeta.Vendors
repoDownloadCount = repoMeta.DownloadCount
repoStarCount = repoMeta.StarCount
repoIsUserStarred = repoMeta.IsStarred // value specific to the current user
repoIsUserBookMarked = repoMeta.IsBookmarked // value specific to the current user
repoSize = repoMeta.Size
lastUpdatedImageMeta = imageMetaMap[repoMeta.LastUpdatedImage.Digest]
lastUpdatedTag = repoMeta.LastUpdatedImage.Tag
)

if repoLastUpdatedTimestamp == nil {
Expand Down
47 changes: 47 additions & 0 deletions pkg/extensions/search/cve/cve_internal_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,64 @@
package cveinfo

import (
"errors"
"testing"
"time"

"github.com/opencontainers/go-digest"
ispec "github.com/opencontainers/image-spec/specs-go/v1"
. "github.com/smartystreets/goconvey/convey"

cvemodel "zotregistry.io/zot/pkg/extensions/search/cve/model"
"zotregistry.io/zot/pkg/meta/types"
"zotregistry.io/zot/pkg/test/mocks"
)

var ErrTestError = errors.New("test error")

func TestUtils(t *testing.T) {
Convey("Utils", t, func() {
Convey("getConfigAndDigest", func() {
_, _, err := getConfigAndDigest(mocks.MetaDBMock{}, "bad-digest")
So(err, ShouldNotBeNil)

_, _, err = getConfigAndDigest(mocks.MetaDBMock{
GetImageMetaFn: func(digest digest.Digest) (types.ImageMeta, error) {
return types.ImageMeta{}, ErrTestError
},
}, ispec.DescriptorEmptyJSON.Digest.String())
So(err, ShouldNotBeNil)

// bad media type of config
_, _, err = getConfigAndDigest(mocks.MetaDBMock{
GetImageMetaFn: func(digest digest.Digest) (types.ImageMeta, error) {
return types.ImageMeta{Manifests: []types.ManifestMeta{
{Manifest: ispec.Manifest{Config: ispec.Descriptor{MediaType: "bad-type"}}},
}}, nil
},
}, ispec.DescriptorEmptyJSON.Digest.String())
So(err, ShouldNotBeNil)
})
Convey("getIndexContent", func() {
_, err := getIndexContent(mocks.MetaDBMock{}, "bad-digest")
So(err, ShouldNotBeNil)

_, err = getIndexContent(mocks.MetaDBMock{
GetImageMetaFn: func(digest digest.Digest) (types.ImageMeta, error) {
return types.ImageMeta{}, ErrTestError
},
}, ispec.DescriptorEmptyJSON.Digest.String())
So(err, ShouldNotBeNil)

// nil index
_, err = getIndexContent(mocks.MetaDBMock{
GetImageMetaFn: func(digest digest.Digest) (types.ImageMeta, error) {
return types.ImageMeta{}, nil
},
}, ispec.DescriptorEmptyJSON.Digest.String())
So(err, ShouldNotBeNil)
})

Convey("mostRecentUpdate", func() {
// empty
timestamp := mostRecentUpdate([]cvemodel.DescriptorInfo{})
Expand Down
12 changes: 2 additions & 10 deletions pkg/extensions/search/cve/trivy/scanner.go
Original file line number Diff line number Diff line change
Expand Up @@ -243,10 +243,6 @@ func (scanner Scanner) isManifestScanable(digestStr string) (bool, error) {
return false, err
}

if manifestData.MediaType != ispec.MediaTypeImageManifest {
return false, zerr.ErrUnexpectedMediaType
}

for _, imageLayer := range manifestData.Manifests[0].Manifest.Layers {
switch imageLayer.MediaType {
case ispec.MediaTypeImageLayerGzip, ispec.MediaTypeImageLayer, string(regTypes.DockerLayer):
Expand All @@ -259,15 +255,11 @@ func (scanner Scanner) isManifestScanable(digestStr string) (bool, error) {
return true, nil
}

func (scanner Scanner) isManifestDataScannable(manifestData mTypes.ManifestData) (bool, error) {
func (scanner Scanner) isManifestDataScannable(manifestData mTypes.ManifestMeta) (bool, error) {
if scanner.cache.Get(manifestData.Digest.String()) != nil {
return true, nil
}

if manifestData.Manifest.MediaType != ispec.MediaTypeImageManifest {
return false, zerr.ErrScanNotSupported
}

for _, imageLayer := range manifestData.Manifest.Layers {
switch imageLayer.MediaType {
case ispec.MediaTypeImageLayerGzip, ispec.MediaTypeImageLayer, string(regTypes.DockerLayer):
Expand All @@ -290,7 +282,7 @@ func (scanner Scanner) isIndexScannable(digestStr string) (bool, error) {
return false, err
}

if indexData.MediaType != ispec.MediaTypeImageIndex || indexData.Index == nil {
if indexData.Index == nil {
return false, zerr.ErrUnexpectedMediaType
}

Expand Down
76 changes: 76 additions & 0 deletions pkg/extensions/search/cve/trivy/scanner_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
package trivy_test

import (
"errors"
"path/filepath"
"testing"
"time"
Expand All @@ -19,13 +20,17 @@ import (
"zotregistry.io/zot/pkg/log"
"zotregistry.io/zot/pkg/meta"
"zotregistry.io/zot/pkg/meta/boltdb"
"zotregistry.io/zot/pkg/meta/types"
"zotregistry.io/zot/pkg/storage"
"zotregistry.io/zot/pkg/storage/local"
. "zotregistry.io/zot/pkg/test/common"
"zotregistry.io/zot/pkg/test/deprecated"
. "zotregistry.io/zot/pkg/test/image-utils"
"zotregistry.io/zot/pkg/test/mocks"
)

var ErrTestError = errors.New("test error")

func TestScanBigTestFile(t *testing.T) {
Convey("Scan zot-test", t, func() {
projRootDir, err := GetProjectRootDir()
Expand Down Expand Up @@ -200,3 +205,74 @@ func TestVulnerableLayer(t *testing.T) {
So(cveMap, ShouldContainKey, "CVE-2023-3446")
})
}

func TestScannerErrors(t *testing.T) {
Convey("Errors", t, func() {
storeController := storage.StoreController{}
metaDB := mocks.MetaDBMock{}
log := log.NewLogger("debug", "")

Convey("IsImageFormatScannable", func() {
storeController.DefaultStore = mocks.MockedImageStore{}
metaDB.GetImageMetaFn = func(digest godigest.Digest) (types.ImageMeta, error) {
return types.ImageMeta{}, ErrTestError
}
scanner := trivy.NewScanner(storeController, metaDB, "ghcr.io/project-zot/trivy-db", "", log)

_, err := scanner.IsImageFormatScannable("repo", godigest.FromString("dig").String())
So(err, ShouldNotBeNil)
})
Convey("IsImageMediaScannable", func() {
storeController.DefaultStore = mocks.MockedImageStore{}
metaDB.GetImageMetaFn = func(digest godigest.Digest) (types.ImageMeta, error) {
return types.ImageMeta{}, ErrTestError
}
scanner := trivy.NewScanner(storeController, metaDB, "ghcr.io/project-zot/trivy-db", "", log)

Convey("Manifest", func() {
_, err := scanner.IsImageMediaScannable("repo", godigest.FromString("dig").String(), ispec.MediaTypeImageManifest)
So(err, ShouldNotBeNil)
})
Convey("Index", func() {
_, err := scanner.IsImageMediaScannable("repo", godigest.FromString("dig").String(), ispec.MediaTypeImageIndex)
So(err, ShouldNotBeNil)
})
Convey("Index with nil index", func() {
metaDB.GetImageMetaFn = func(digest godigest.Digest) (types.ImageMeta, error) {
return types.ImageMeta{}, nil
}
scanner := trivy.NewScanner(storeController, metaDB, "ghcr.io/project-zot/trivy-db", "", log)

_, err := scanner.IsImageMediaScannable("repo", godigest.FromString("dig").String(), ispec.MediaTypeImageIndex)
So(err, ShouldNotBeNil)
})
Convey("Index with good index", func() {
metaDB.GetImageMetaFn = func(digest godigest.Digest) (types.ImageMeta, error) {
return types.ImageMeta{
Index: &ispec.Index{
Manifests: []ispec.Descriptor{{MediaType: ispec.MediaTypeImageLayer}},
},
Manifests: []types.ManifestMeta{{Manifest: ispec.Manifest{
Layers: []ispec.Descriptor{{MediaType: ispec.MediaTypeImageLayer}},
}}},
}, nil
}
scanner := trivy.NewScanner(storeController, metaDB, "ghcr.io/project-zot/trivy-db", "", log)

_, err := scanner.IsImageMediaScannable("repo", godigest.FromString("dig").String(), ispec.MediaTypeImageIndex)
So(err, ShouldBeNil)
})
})
Convey("ScanImage", func() {
storeController.DefaultStore = mocks.MockedImageStore{}
metaDB.GetImageMetaFn = func(digest godigest.Digest) (types.ImageMeta, error) {
return types.ImageMeta{}, ErrTestError
}

scanner := trivy.NewScanner(storeController, metaDB, "ghcr.io/project-zot/trivy-db", "", log)

_, err := scanner.ScanImage("image@" + godigest.FromString("digest").String())
So(err, ShouldNotBeNil)
})
})
}
87 changes: 87 additions & 0 deletions pkg/extensions/search/resolver_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -244,6 +244,39 @@ func TestRepoListWithNewestImage(t *testing.T) {
})
}

func TestGetFilteredPaginatedRepos(t *testing.T) {
ctx := context.Background()
log := log.NewLogger("debug", "")

Convey("getFilteredPaginatedRepos", t, func() {
metaDB := mocks.MetaDBMock{}

Convey("FilterRepos", func() {
metaDB.FilterReposFn = func(ctx context.Context, rankName mTypes.FilterRepoNameFunc,
filterFunc mTypes.FilterFullRepoFunc,
) ([]mTypes.RepoMeta, error) {
return nil, ErrTestError
}
_, err := getFilteredPaginatedRepos(ctx, nil, func(repo string) bool { return true }, log,
&gql_generated.PageInput{}, metaDB)
So(err, ShouldNotBeNil)
})
Convey("FilterImageMeta", func() {
metaDB.FilterImageMetaFn = func(ctx context.Context, digests []string) (map[string]mTypes.ImageMeta, error) {
return nil, ErrTestError
}
_, err := getFilteredPaginatedRepos(ctx, nil, func(repo string) bool { return true }, log,
&gql_generated.PageInput{}, metaDB)
So(err, ShouldNotBeNil)
})
Convey("PaginatedRepoMeta2RepoSummaries", func() {
_, err := getFilteredPaginatedRepos(ctx, nil, func(repo string) bool { return true }, log,
&gql_generated.PageInput{Limit: ref(-10)}, metaDB)
So(err, ShouldNotBeNil)
})
})
}

func TestGetBookmarkedRepos(t *testing.T) {
Convey("getBookmarkedRepos", t, func() {
responseContext := graphql.WithResponseContext(context.Background(), graphql.DefaultErrorPresenter,
Expand Down Expand Up @@ -426,6 +459,24 @@ func TestImageListForDigest(t *testing.T) {
})
}

func TestGetImageSummaryError(t *testing.T) {
Convey("getImageSummary", t, func() {
metaDB := mocks.MetaDBMock{
GetRepoMetaFn: func(ctx context.Context, repo string) (mTypes.RepoMeta, error) {
return mTypes.RepoMeta{Tags: map[string]mTypes.Descriptor{"tag": {}}}, nil
},
FilterImageMetaFn: func(ctx context.Context, digests []string) (map[string]mTypes.ImageMeta, error) {
return nil, ErrTestError
},
}
log := log.NewLogger("debug", "")

_, err := getImageSummary(context.Background(), "repo", "tag", nil, convert.SkipQGLField{},
metaDB, nil, log)
So(err, ShouldNotBeNil)
})
}

func TestImageListError(t *testing.T) {
Convey("getImageList", t, func() {
testLogger := log.NewLogger("debug", "/dev/null")
Expand Down Expand Up @@ -588,6 +639,18 @@ func TestQueryResolverErrors(t *testing.T) {
So(err, ShouldNotBeNil)
})

Convey("GlobalSearch error filte image meta", func() {
resolverConfig := NewResolver(log, storage.StoreController{}, mocks.MetaDBMock{
FilterImageMetaFn: func(ctx context.Context, digests []string) (map[string]mTypes.ImageMeta, error) {
return nil, ErrTestError
},
}, mocks.CveInfoMock{})
resolver := queryResolver{resolverConfig}

_, err := resolver.GlobalSearch(ctx, "some_string", &gql_generated.Filter{}, getPageInput(1, 1))
So(err, ShouldNotBeNil)
})

Convey("ImageListForCve error in GetMultipleRepoMeta", func() {
resolverConfig := NewResolver(
log,
Expand Down Expand Up @@ -651,6 +714,30 @@ func TestQueryResolverErrors(t *testing.T) {
So(err, ShouldNotBeNil)
})

Convey("RepoListWithNewestImage repoListWithNewestImage() filter image meta error", func() {
resolverConfig := NewResolver(
log,
storage.StoreController{
DefaultStore: mocks.MockedImageStore{},
},
mocks.MetaDBMock{
SearchReposFn: func(ctx context.Context, searchText string,
) ([]mTypes.RepoMeta, error) {
return []mTypes.RepoMeta{}, nil
},
FilterImageMetaFn: func(ctx context.Context, digests []string) (map[string]mTypes.ImageMeta, error) {
return nil, ErrTestError
},
},
mocks.CveInfoMock{},
)

qr := queryResolver{resolverConfig}

_, err := qr.RepoListWithNewestImage(ctx, &gql_generated.PageInput{})
So(err, ShouldNotBeNil)
})

Convey("RepoListWithNewestImage repoListWithNewestImage() errors mocked StoreController", func() {
resolverConfig := NewResolver(
log,
Expand Down
Loading