grype/cmd/root_test.go
Weston Steimel 4cda526992
implement v5 db schema to support improved matching between rpm appstream modules (#944)
Adds support for a `package_qualifiers` column to allow evaluating package matches to vulnerabilities based on more than just version constraints. Currently adds an rpm-modularity qualifier in order to support matching to correct app stream module in order to reduce false positives within rpm-based distro ecosystems. In order to prevent an increase in false positive matches for previous versions of grype using the v4 schema, this change (along with the vulnerability source driver parser updates) requires bumping the schema to v5.

Signed-off-by: Weston Steimel <weston.steimel@anchore.com>
Signed-off-by: Alex Goodman <alex.goodman@anchore.com>
Co-authored-by: Alex Goodman <alex.goodman@anchore.com>
2022-10-18 00:34:47 +01:00

152 lines
3.6 KiB
Go

package cmd
import (
"testing"
"github.com/google/uuid"
"github.com/stretchr/testify/assert"
"github.com/anchore/grype/grype/db"
grypeDB "github.com/anchore/grype/grype/db/v5"
"github.com/anchore/grype/grype/match"
"github.com/anchore/grype/grype/pkg"
"github.com/anchore/grype/grype/vulnerability"
"github.com/anchore/grype/internal/config"
syftPkg "github.com/anchore/syft/syft/pkg"
)
type mockMetadataStore struct {
data map[string]map[string]*grypeDB.VulnerabilityMetadata
}
func newMockStore() *mockMetadataStore {
d := mockMetadataStore{
data: make(map[string]map[string]*grypeDB.VulnerabilityMetadata),
}
d.stub()
return &d
}
func (d *mockMetadataStore) stub() {
d.data["CVE-2014-fake-1"] = map[string]*grypeDB.VulnerabilityMetadata{
"source-1": {
Severity: "medium",
},
}
}
func (d *mockMetadataStore) GetVulnerabilityMetadata(id, recordSource string) (*grypeDB.VulnerabilityMetadata, error) {
return d.data[id][recordSource], nil
}
func (d *mockMetadataStore) GetAllVulnerabilityMetadata() (*[]grypeDB.VulnerabilityMetadata, error) {
return nil, nil
}
func TestAboveAllowableSeverity(t *testing.T) {
thePkg := pkg.Package{
ID: pkg.ID(uuid.NewString()),
Name: "the-package",
Version: "v0.1",
Type: syftPkg.RpmPkg,
}
matches := match.NewMatches()
matches.Add(match.Match{
Vulnerability: vulnerability.Vulnerability{
ID: "CVE-2014-fake-1",
Namespace: "source-1",
},
Package: thePkg,
Details: match.Details{
{
Type: match.ExactDirectMatch,
},
},
})
tests := []struct {
name string
failOnSeverity string
matches match.Matches
expectedResult bool
}{
{
name: "no-severity-set",
failOnSeverity: "",
matches: matches,
expectedResult: false,
},
{
name: "below-threshold",
failOnSeverity: "high",
matches: matches,
expectedResult: false,
},
{
name: "at-threshold",
failOnSeverity: "medium",
matches: matches,
expectedResult: true,
},
{
name: "above-threshold",
failOnSeverity: "low",
matches: matches,
expectedResult: true,
},
}
metadataProvider := db.NewVulnerabilityMetadataProvider(newMockStore())
for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
var failOnSeverity *vulnerability.Severity
if test.failOnSeverity != "" {
sev := vulnerability.ParseSeverity(test.failOnSeverity)
if sev == vulnerability.UnknownSeverity {
t.Fatalf("could not parse severity")
}
failOnSeverity = &sev
}
actual := hitSeverityThreshold(failOnSeverity, test.matches, metadataProvider)
if test.expectedResult != actual {
t.Errorf("expected: %v got : %v", test.expectedResult, actual)
}
})
}
}
func Test_applyDistroHint(t *testing.T) {
ctx := pkg.Context{}
cfg := config.Application{}
applyDistroHint([]pkg.Package{}, &ctx, &cfg)
assert.Nil(t, ctx.Distro)
// works when distro is nil
cfg.Distro = "alpine:3.10"
applyDistroHint([]pkg.Package{}, &ctx, &cfg)
assert.NotNil(t, ctx.Distro)
assert.Equal(t, "alpine", ctx.Distro.Name)
assert.Equal(t, "3.10", ctx.Distro.Version)
// does override an existing distro
cfg.Distro = "ubuntu:latest"
applyDistroHint([]pkg.Package{}, &ctx, &cfg)
assert.NotNil(t, ctx.Distro)
assert.Equal(t, "ubuntu", ctx.Distro.Name)
assert.Equal(t, "latest", ctx.Distro.Version)
// doesn't remove an existing distro when empty
cfg.Distro = ""
applyDistroHint([]pkg.Package{}, &ctx, &cfg)
assert.NotNil(t, ctx.Distro)
assert.Equal(t, "ubuntu", ctx.Distro.Name)
assert.Equal(t, "latest", ctx.Distro.Version)
}