mirror of
https://github.com/project-zot/zot.git
synced 2025-01-06 22:40:28 -05:00
6222dae1f0
wait for workers to finish before exiting should fix tests reporting they couldn't remove rootDir because it's being written by tasks Signed-off-by: Petu Eusebiu <peusebiu@cisco.com>
327 lines
10 KiB
Go
327 lines
10 KiB
Go
//go:build search
|
|
// +build search
|
|
|
|
package cveinfo_test
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"sort"
|
|
"testing"
|
|
"time"
|
|
|
|
ispec "github.com/opencontainers/image-spec/specs-go/v1"
|
|
. "github.com/smartystreets/goconvey/convey"
|
|
|
|
cveinfo "zotregistry.io/zot/pkg/extensions/search/cve"
|
|
cvemodel "zotregistry.io/zot/pkg/extensions/search/cve/model"
|
|
"zotregistry.io/zot/pkg/log"
|
|
"zotregistry.io/zot/pkg/meta/boltdb"
|
|
. "zotregistry.io/zot/pkg/test/image-utils"
|
|
"zotregistry.io/zot/pkg/test/mocks"
|
|
)
|
|
|
|
func TestCVEPagination(t *testing.T) {
|
|
Convey("CVE Pagination", t, func() {
|
|
params := boltdb.DBParameters{
|
|
RootDir: t.TempDir(),
|
|
}
|
|
boltDriver, err := boltdb.GetBoltDriver(params)
|
|
So(err, ShouldBeNil)
|
|
|
|
metaDB, err := boltdb.New(boltDriver, log.NewLogger("debug", ""))
|
|
So(err, ShouldBeNil)
|
|
|
|
// Create metadb data for scannable image with vulnerabilities
|
|
timeStamp11 := time.Date(2008, 1, 1, 12, 0, 0, 0, time.UTC)
|
|
|
|
image := CreateImageWith().
|
|
Layers([]Layer{{
|
|
MediaType: ispec.MediaTypeImageLayerGzip,
|
|
Digest: ispec.DescriptorEmptyJSON.Digest,
|
|
Blob: ispec.DescriptorEmptyJSON.Data,
|
|
}}).ImageConfig(ispec.Image{Created: &timeStamp11}).Build()
|
|
|
|
err = metaDB.SetRepoReference(context.Background(), "repo1", "0.1.0", image.AsImageMeta())
|
|
So(err, ShouldBeNil)
|
|
|
|
timeStamp12 := time.Date(2009, 1, 1, 12, 0, 0, 0, time.UTC)
|
|
|
|
image2 := CreateImageWith().
|
|
Layers([]Layer{{
|
|
MediaType: ispec.MediaTypeImageLayerGzip,
|
|
Digest: ispec.DescriptorEmptyJSON.Digest,
|
|
Blob: ispec.DescriptorEmptyJSON.Data,
|
|
}}).ImageConfig(ispec.Image{Created: &timeStamp12}).Build()
|
|
|
|
err = metaDB.SetRepoReference(context.Background(), "repo1", "1.0.0", image2.AsImageMeta())
|
|
So(err, ShouldBeNil)
|
|
|
|
// MetaDB loaded with initial data, mock the scanner
|
|
severityToInt := map[string]int{
|
|
"UNKNOWN": 0,
|
|
"LOW": 1,
|
|
"MEDIUM": 2,
|
|
"HIGH": 3,
|
|
"CRITICAL": 4,
|
|
}
|
|
|
|
intToSeverity := make(map[int]string, len(severityToInt))
|
|
for k, v := range severityToInt {
|
|
intToSeverity[v] = k
|
|
}
|
|
|
|
// Setup test CVE data in mock scanner
|
|
scanner := mocks.CveScannerMock{
|
|
ScanImageFn: func(ctx context.Context, image string) (map[string]cvemodel.CVE, error) {
|
|
cveMap := map[string]cvemodel.CVE{}
|
|
|
|
if image == "repo1:0.1.0" {
|
|
for i := 0; i < 5; i++ {
|
|
cveMap[fmt.Sprintf("CVE%d", i)] = cvemodel.CVE{
|
|
ID: fmt.Sprintf("CVE%d", i),
|
|
Severity: intToSeverity[i%5],
|
|
Title: fmt.Sprintf("Title for CVE%d", i),
|
|
Description: fmt.Sprintf("Description for CVE%d", i),
|
|
}
|
|
}
|
|
}
|
|
|
|
if image == "repo1:1.0.0" {
|
|
for i := 0; i < 30; i++ {
|
|
cveMap[fmt.Sprintf("CVE%d", i)] = cvemodel.CVE{
|
|
ID: fmt.Sprintf("CVE%d", i),
|
|
Severity: intToSeverity[i%5],
|
|
Title: fmt.Sprintf("Title for CVE%d", i),
|
|
Description: fmt.Sprintf("Description for CVE%d", i),
|
|
}
|
|
}
|
|
}
|
|
|
|
// By default the image has no vulnerabilities
|
|
return cveMap, nil
|
|
},
|
|
}
|
|
|
|
log := log.NewLogger("debug", "")
|
|
cveInfo := cveinfo.BaseCveInfo{Log: log, Scanner: scanner, MetaDB: metaDB}
|
|
|
|
ctx := context.Background()
|
|
|
|
Convey("create new paginator errors", func() {
|
|
paginator, err := cveinfo.NewCvePageFinder(-1, 10, cveinfo.AlphabeticAsc)
|
|
So(paginator, ShouldBeNil)
|
|
So(err, ShouldNotBeNil)
|
|
|
|
paginator, err = cveinfo.NewCvePageFinder(2, -1, cveinfo.AlphabeticAsc)
|
|
So(paginator, ShouldBeNil)
|
|
So(err, ShouldNotBeNil)
|
|
|
|
paginator, err = cveinfo.NewCvePageFinder(2, 1, "wrong sorting criteria")
|
|
So(paginator, ShouldBeNil)
|
|
So(err, ShouldNotBeNil)
|
|
})
|
|
|
|
Convey("Reset", func() {
|
|
paginator, err := cveinfo.NewCvePageFinder(1, 0, cveinfo.AlphabeticAsc)
|
|
So(err, ShouldBeNil)
|
|
So(paginator, ShouldNotBeNil)
|
|
|
|
paginator.Add(cvemodel.CVE{})
|
|
paginator.Add(cvemodel.CVE{})
|
|
paginator.Add(cvemodel.CVE{})
|
|
|
|
paginator.Reset()
|
|
|
|
result, _ := paginator.Page()
|
|
So(result, ShouldBeEmpty)
|
|
})
|
|
|
|
Convey("Page", func() {
|
|
Convey("defaults", func() {
|
|
// By default expect unlimitted results sorted by severity
|
|
cves, pageInfo, err := cveInfo.GetCVEListForImage(ctx, "repo1", "0.1.0", "", cvemodel.PageInput{})
|
|
So(err, ShouldBeNil)
|
|
So(len(cves), ShouldEqual, 5)
|
|
So(pageInfo.ItemCount, ShouldEqual, 5)
|
|
So(pageInfo.TotalCount, ShouldEqual, 5)
|
|
previousSeverity := 4
|
|
for _, cve := range cves {
|
|
So(severityToInt[cve.Severity], ShouldBeLessThanOrEqualTo, previousSeverity)
|
|
previousSeverity = severityToInt[cve.Severity]
|
|
}
|
|
|
|
cves, pageInfo, err = cveInfo.GetCVEListForImage(ctx, "repo1", "1.0.0", "", cvemodel.PageInput{})
|
|
So(err, ShouldBeNil)
|
|
So(len(cves), ShouldEqual, 30)
|
|
So(pageInfo.ItemCount, ShouldEqual, 30)
|
|
So(pageInfo.TotalCount, ShouldEqual, 30)
|
|
previousSeverity = 4
|
|
for _, cve := range cves {
|
|
So(severityToInt[cve.Severity], ShouldBeLessThanOrEqualTo, previousSeverity)
|
|
previousSeverity = severityToInt[cve.Severity]
|
|
}
|
|
})
|
|
|
|
Convey("no limit or offset", func() {
|
|
cveIds := []string{}
|
|
for i := 0; i < 30; i++ {
|
|
cveIds = append(cveIds, fmt.Sprintf("CVE%d", i))
|
|
}
|
|
|
|
cves, pageInfo, err := cveInfo.GetCVEListForImage(ctx, "repo1", "0.1.0", "",
|
|
cvemodel.PageInput{SortBy: cveinfo.AlphabeticAsc})
|
|
So(err, ShouldBeNil)
|
|
So(len(cves), ShouldEqual, 5)
|
|
So(pageInfo.ItemCount, ShouldEqual, 5)
|
|
So(pageInfo.TotalCount, ShouldEqual, 5)
|
|
for i, cve := range cves {
|
|
So(cve.ID, ShouldEqual, cveIds[i])
|
|
}
|
|
|
|
sort.Strings(cveIds)
|
|
cves, pageInfo, err = cveInfo.GetCVEListForImage(ctx, "repo1", "1.0.0", "",
|
|
cvemodel.PageInput{SortBy: cveinfo.AlphabeticAsc})
|
|
So(err, ShouldBeNil)
|
|
So(len(cves), ShouldEqual, 30)
|
|
So(pageInfo.ItemCount, ShouldEqual, 30)
|
|
So(pageInfo.TotalCount, ShouldEqual, 30)
|
|
for i, cve := range cves {
|
|
So(cve.ID, ShouldEqual, cveIds[i])
|
|
}
|
|
|
|
sort.Sort(sort.Reverse(sort.StringSlice(cveIds)))
|
|
cves, pageInfo, err = cveInfo.GetCVEListForImage(ctx, "repo1", "1.0.0", "",
|
|
cvemodel.PageInput{SortBy: cveinfo.AlphabeticDsc})
|
|
So(err, ShouldBeNil)
|
|
So(len(cves), ShouldEqual, 30)
|
|
So(pageInfo.ItemCount, ShouldEqual, 30)
|
|
So(pageInfo.TotalCount, ShouldEqual, 30)
|
|
for i, cve := range cves {
|
|
So(cve.ID, ShouldEqual, cveIds[i])
|
|
}
|
|
|
|
cves, pageInfo, err = cveInfo.GetCVEListForImage(ctx, "repo1", "1.0.0", "",
|
|
cvemodel.PageInput{SortBy: cveinfo.SeverityDsc})
|
|
So(err, ShouldBeNil)
|
|
So(len(cves), ShouldEqual, 30)
|
|
So(pageInfo.ItemCount, ShouldEqual, 30)
|
|
So(pageInfo.TotalCount, ShouldEqual, 30)
|
|
previousSeverity := 4
|
|
for _, cve := range cves {
|
|
So(severityToInt[cve.Severity], ShouldBeLessThanOrEqualTo, previousSeverity)
|
|
previousSeverity = severityToInt[cve.Severity]
|
|
}
|
|
})
|
|
|
|
Convey("limit < len(cves)", func() {
|
|
cveIds := []string{}
|
|
for i := 0; i < 30; i++ {
|
|
cveIds = append(cveIds, fmt.Sprintf("CVE%d", i))
|
|
}
|
|
|
|
cves, pageInfo, err := cveInfo.GetCVEListForImage(ctx, "repo1", "0.1.0", "", cvemodel.PageInput{
|
|
Limit: 3,
|
|
Offset: 1,
|
|
SortBy: cveinfo.AlphabeticAsc,
|
|
},
|
|
)
|
|
So(err, ShouldBeNil)
|
|
So(len(cves), ShouldEqual, 3)
|
|
So(pageInfo.ItemCount, ShouldEqual, 3)
|
|
So(pageInfo.TotalCount, ShouldEqual, 5)
|
|
So(cves[0].ID, ShouldEqual, "CVE1") // CVE0 is first ID and is not part of the page
|
|
So(cves[1].ID, ShouldEqual, "CVE2")
|
|
So(cves[2].ID, ShouldEqual, "CVE3")
|
|
|
|
cves, pageInfo, err = cveInfo.GetCVEListForImage(ctx, "repo1", "0.1.0", "", cvemodel.PageInput{
|
|
Limit: 2,
|
|
Offset: 1,
|
|
SortBy: cveinfo.AlphabeticDsc,
|
|
},
|
|
)
|
|
So(err, ShouldBeNil)
|
|
So(len(cves), ShouldEqual, 2)
|
|
So(pageInfo.ItemCount, ShouldEqual, 2)
|
|
So(pageInfo.TotalCount, ShouldEqual, 5)
|
|
So(cves[0].ID, ShouldEqual, "CVE3")
|
|
So(cves[1].ID, ShouldEqual, "CVE2")
|
|
|
|
cves, pageInfo, err = cveInfo.GetCVEListForImage(ctx, "repo1", "0.1.0", "", cvemodel.PageInput{
|
|
Limit: 3,
|
|
Offset: 1,
|
|
SortBy: cveinfo.SeverityDsc,
|
|
},
|
|
)
|
|
So(err, ShouldBeNil)
|
|
So(len(cves), ShouldEqual, 3)
|
|
So(pageInfo.ItemCount, ShouldEqual, 3)
|
|
So(pageInfo.TotalCount, ShouldEqual, 5)
|
|
previousSeverity := 4
|
|
for _, cve := range cves {
|
|
So(severityToInt[cve.Severity], ShouldBeLessThanOrEqualTo, previousSeverity)
|
|
previousSeverity = severityToInt[cve.Severity]
|
|
}
|
|
|
|
sort.Strings(cveIds)
|
|
cves, pageInfo, err = cveInfo.GetCVEListForImage(ctx, "repo1", "1.0.0", "", cvemodel.PageInput{
|
|
Limit: 5,
|
|
Offset: 20,
|
|
SortBy: cveinfo.AlphabeticAsc,
|
|
},
|
|
)
|
|
So(err, ShouldBeNil)
|
|
So(len(cves), ShouldEqual, 5)
|
|
So(pageInfo.ItemCount, ShouldEqual, 5)
|
|
So(pageInfo.TotalCount, ShouldEqual, 30)
|
|
for i, cve := range cves {
|
|
So(cve.ID, ShouldEqual, cveIds[i+20])
|
|
}
|
|
})
|
|
|
|
Convey("limit > len(cves)", func() {
|
|
cves, pageInfo, err := cveInfo.GetCVEListForImage(ctx, "repo1", "0.1.0", "", cvemodel.PageInput{
|
|
Limit: 6,
|
|
Offset: 3,
|
|
SortBy: cveinfo.AlphabeticAsc,
|
|
},
|
|
)
|
|
So(err, ShouldBeNil)
|
|
So(len(cves), ShouldEqual, 2)
|
|
So(pageInfo.ItemCount, ShouldEqual, 2)
|
|
So(pageInfo.TotalCount, ShouldEqual, 5)
|
|
So(cves[0].ID, ShouldEqual, "CVE3")
|
|
So(cves[1].ID, ShouldEqual, "CVE4")
|
|
|
|
cves, pageInfo, err = cveInfo.GetCVEListForImage(ctx, "repo1", "0.1.0", "", cvemodel.PageInput{
|
|
Limit: 6,
|
|
Offset: 3,
|
|
SortBy: cveinfo.AlphabeticDsc,
|
|
},
|
|
)
|
|
So(err, ShouldBeNil)
|
|
So(len(cves), ShouldEqual, 2)
|
|
So(pageInfo.ItemCount, ShouldEqual, 2)
|
|
So(pageInfo.TotalCount, ShouldEqual, 5)
|
|
So(cves[0].ID, ShouldEqual, "CVE1")
|
|
So(cves[1].ID, ShouldEqual, "CVE0")
|
|
|
|
cves, pageInfo, err = cveInfo.GetCVEListForImage(ctx, "repo1", "0.1.0", "", cvemodel.PageInput{
|
|
Limit: 6,
|
|
Offset: 3,
|
|
SortBy: cveinfo.SeverityDsc,
|
|
},
|
|
)
|
|
So(err, ShouldBeNil)
|
|
So(len(cves), ShouldEqual, 2)
|
|
So(pageInfo.ItemCount, ShouldEqual, 2)
|
|
So(pageInfo.TotalCount, ShouldEqual, 5)
|
|
previousSeverity := 4
|
|
for _, cve := range cves {
|
|
So(severityToInt[cve.Severity], ShouldBeLessThanOrEqualTo, previousSeverity)
|
|
previousSeverity = severityToInt[cve.Severity]
|
|
}
|
|
})
|
|
})
|
|
})
|
|
}
|