Files
trivy/pkg/vulnerability/vulnerability_test.go
Teppei Fukuda 74717b888e feat: support client/server mode (#295)
* chore(app): change dir

* feat(rpc): add a proto file and auto-generated files

* chore(dep): add dependencies

* fix(app): fix import path

* fix(integration): fix import path

* fix(protoc): use enum for severity

* chore(Makefile): add fmt andd protoc

* chore(clang): add .clang-format

* refactor: split functions for client/server (#296)

* refactor(db): split db.Download

* refactor(standalone): create a different package

* refactor(vulnerability): split FillAndFilter

* fix(protoc): use enum for severity

* chore(Makefile): add fmt andd protoc

* chore(clang): add .clang-format

* fix(db): remove an unused variable

* fix(db): expose the github client as an argument of constructor

* refactor(vulnerability): add the detail message

* feat(rpc): add rpc client (#302)

* fix(protoc): use enum for severity

* chore(Makefile): add fmt andd protoc

* chore(clang): add .clang-format

* feat(rpc): convert types

* feat(rpc): add rpc client

* token: Refactor to handle bad headers being set

Signed-off-by: Simarpreet Singh <simar@linux.com>

* feat(rpc): add rpc server (#303)

* feat(rpc): add rpc server

* feat(utils): add CopyFile

* feat(server/config): add config struct

* feat(detector): add detector

* feat(scanner): delegate procedures to detector

* fix(scanner): fix the interface

* test(mock): add mocks

* test(rpc/server): add tests

* test(rpc/ospkg/server): add tests

* tets(os/detector): add tests

* refactor(library): move directories

* chore(dependency): add google/wire

* refactor(library): introduce google/wire

* refactor(ospkg/detector): move directory

* feat(rpc): add eosl

* refactor(ospkg): introduce google/wire

* refactor(wire): bind an interface

* refactor(client): use wire.Struct

* chore(Makefile): fix wire

* test(server): add AssertExpectations

* test(server): add AssertExpectations

* refactor(server): remove debug log

* refactor(error): add more context messages

* test(server): fix error message

* refactor(test): create a constructor of mock

* refactor(config): remove an unused variable

* test(config): add an assertion to test the config struct

* feat(client/server): add sub commands (#304)

* feat(rpc): add rpc server

* feat(utils): add CopyFile

* feat(server/config): add config struct

* feat(detector): add detector

* feat(scanner): delegate procedures to detector

* fix(scanner): fix the interface

* feat(client/server): add sub commands

* merge(server3)

* test(scan): remove an unused mock

* refactor(client): generate the constructor by wire

* fix(cli): change the default port

* fix(server): use auto-generated constructor

* feat(ospkg): return eosl

* test(integration): add integration tests for client/server (#306)

* fix(server): remove unnecessary options

* test(integration): add integration tests for client/server

* fix(server): wrap an error

* fix(server): change the update interval

* fix(server): display the error detail

* test(config): add an assertion to test the config struct

* fix(client): returns an error when failing to initizlie a logger

* test(ospkg/server): add eosl

* Squashed commit of the following:

* test(server): refactor and add tests (#307)

* test(github): create a mock

* test(db): create a mock

* test(server): add tests for DB hot update

* chore(db): add a log message

* refactor(db): introduce google/wire

* refactor(rpc): move directory

* refactor(injector): fix import name

* refactor(import): remove new lines

* fix(server): display the error detail

* fix(server): change the update interval

* fix(server): wrap an error

* test(integration): add integration tests for client/server

* fix(server): remove unnecessary options

* refactor(server): return an error when failing to initialize a logger

* refactor(server): remove unused error

* fix(client/server): fix default port

* chore(README): add client/server

* chore(README): update
2019-12-13 15:00:11 +02:00

387 lines
9.2 KiB
Go

package vulnerability
import (
"os"
"testing"
"github.com/aquasecurity/trivy/pkg/log"
"golang.org/x/xerrors"
"github.com/aquasecurity/trivy/pkg/types"
"github.com/aquasecurity/trivy-db/pkg/db"
"github.com/stretchr/testify/assert"
dbTypes "github.com/aquasecurity/trivy-db/pkg/types"
)
func TestMain(m *testing.M) {
if err := log.InitLogger(false, true); err != nil {
log.Fatal(err)
}
code := m.Run()
os.Exit(code)
}
func TestClient_FillInfo(t *testing.T) {
type getSeverityOutput struct {
severity dbTypes.Severity
err error
}
type getSeverity struct {
input string
output getSeverityOutput
}
type getVulnerabilityOutput struct {
vulnerability dbTypes.Vulnerability
err error
}
type getVulnerability struct {
input string
output getVulnerabilityOutput
}
type args struct {
vulns []types.DetectedVulnerability
light bool
}
tests := []struct {
name string
getSeverity []getSeverity
getVulnerability []getVulnerability
args args
expected []types.DetectedVulnerability
}{
{
name: "happy path",
getVulnerability: []getVulnerability{
{
input: "CVE-2019-0001",
output: getVulnerabilityOutput{
vulnerability: dbTypes.Vulnerability{
Title: "dos",
Description: "dos vulnerability",
Severity: dbTypes.SeverityMedium.String(),
References: []string{"http://example.com"},
},
},
},
},
args: args{
vulns: []types.DetectedVulnerability{
{VulnerabilityID: "CVE-2019-0001"},
},
light: false,
},
expected: []types.DetectedVulnerability{
{
VulnerabilityID: "CVE-2019-0001",
Vulnerability: dbTypes.Vulnerability{
Title: "dos",
Description: "dos vulnerability",
Severity: dbTypes.SeverityMedium.String(),
References: []string{"http://example.com"},
},
},
},
},
{
name: "happy path with light option",
getSeverity: []getSeverity{
{
input: "CVE-2019-0001",
output: getSeverityOutput{
severity: dbTypes.SeverityCritical,
},
},
{
input: "CVE-2019-0002",
output: getSeverityOutput{
severity: dbTypes.SeverityHigh,
},
},
},
args: args{
vulns: []types.DetectedVulnerability{
{VulnerabilityID: "CVE-2019-0001"},
{VulnerabilityID: "CVE-2019-0002"},
},
light: true,
},
expected: []types.DetectedVulnerability{
{
VulnerabilityID: "CVE-2019-0001",
Vulnerability: dbTypes.Vulnerability{
Severity: dbTypes.SeverityCritical.String(),
},
},
{
VulnerabilityID: "CVE-2019-0002",
Vulnerability: dbTypes.Vulnerability{
Severity: dbTypes.SeverityHigh.String(),
},
},
},
},
{
name: "GetVulnerability returns an error",
getVulnerability: []getVulnerability{
{
input: "CVE-2019-0004",
output: getVulnerabilityOutput{
err: xerrors.New("failed"),
},
},
},
args: args{
vulns: []types.DetectedVulnerability{
{VulnerabilityID: "CVE-2019-0004"},
},
light: false,
},
expected: []types.DetectedVulnerability{
{VulnerabilityID: "CVE-2019-0004"},
},
},
{
name: "GetSeverity returns an error",
getSeverity: []getSeverity{
{
input: "CVE-2019-0003",
output: getSeverityOutput{
err: xerrors.New("failed"),
},
},
},
args: args{
vulns: []types.DetectedVulnerability{
{VulnerabilityID: "CVE-2019-0003"},
},
light: true,
},
expected: []types.DetectedVulnerability{
{
VulnerabilityID: "CVE-2019-0003",
Vulnerability: dbTypes.Vulnerability{
Severity: dbTypes.SeverityUnknown.String(),
},
},
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
mockDBConfig := new(db.MockDBConfig)
c := Client{
dbc: mockDBConfig,
}
for _, gs := range tt.getSeverity {
mockDBConfig.On("GetSeverity", gs.input).Return(
gs.output.severity, gs.output.err)
}
for _, gv := range tt.getVulnerability {
mockDBConfig.On("GetVulnerability", gv.input).Return(
gv.output.vulnerability, gv.output.err)
}
c.FillInfo(tt.args.vulns, tt.args.light)
assert.Equal(t, tt.expected, tt.args.vulns, tt.name)
mockDBConfig.AssertExpectations(t)
})
}
}
func TestClient_Filter(t *testing.T) {
type args struct {
vulns []types.DetectedVulnerability
severities []dbTypes.Severity
ignoreUnfixed bool
ignoreFile string
}
tests := []struct {
name string
args args
want []types.DetectedVulnerability
}{
{
name: "happy path",
args: args{
vulns: []types.DetectedVulnerability{
{
VulnerabilityID: "CVE-2019-0001",
PkgName: "foo",
InstalledVersion: "1.2.3",
FixedVersion: "1.2.4",
Vulnerability: dbTypes.Vulnerability{
Severity: dbTypes.SeverityLow.String(),
},
},
{
VulnerabilityID: "CVE-2019-0002",
PkgName: "bar",
InstalledVersion: "1.2.3",
FixedVersion: "1.2.4",
Vulnerability: dbTypes.Vulnerability{
Severity: dbTypes.SeverityCritical.String(),
},
},
{
VulnerabilityID: "CVE-2018-0001",
PkgName: "baz",
InstalledVersion: "1.2.3",
FixedVersion: "",
Vulnerability: dbTypes.Vulnerability{
Severity: dbTypes.SeverityHigh.String(),
},
},
{
VulnerabilityID: "CVE-2018-0001",
PkgName: "bar",
InstalledVersion: "1.2.3",
FixedVersion: "",
Vulnerability: dbTypes.Vulnerability{
Severity: dbTypes.SeverityCritical.String(),
},
},
{
VulnerabilityID: "CVE-2018-0002",
PkgName: "bar",
InstalledVersion: "1.2.3",
FixedVersion: "",
Vulnerability: dbTypes.Vulnerability{
Severity: dbTypes.SeverityHigh.String(),
},
},
},
severities: []dbTypes.Severity{dbTypes.SeverityCritical, dbTypes.SeverityHigh},
ignoreUnfixed: false,
},
want: []types.DetectedVulnerability{
{
VulnerabilityID: "CVE-2018-0001",
PkgName: "bar",
InstalledVersion: "1.2.3",
FixedVersion: "",
Vulnerability: dbTypes.Vulnerability{
Severity: dbTypes.SeverityCritical.String(),
},
},
{
VulnerabilityID: "CVE-2019-0002",
PkgName: "bar",
InstalledVersion: "1.2.3",
FixedVersion: "1.2.4",
Vulnerability: dbTypes.Vulnerability{
Severity: dbTypes.SeverityCritical.String(),
},
},
{
VulnerabilityID: "CVE-2018-0002",
PkgName: "bar",
InstalledVersion: "1.2.3",
FixedVersion: "",
Vulnerability: dbTypes.Vulnerability{
Severity: dbTypes.SeverityHigh.String(),
},
},
{
VulnerabilityID: "CVE-2018-0001",
PkgName: "baz",
InstalledVersion: "1.2.3",
FixedVersion: "",
Vulnerability: dbTypes.Vulnerability{
Severity: dbTypes.SeverityHigh.String(),
},
},
},
},
{
name: "happy path with ignore-unfixed",
args: args{
vulns: []types.DetectedVulnerability{
{
VulnerabilityID: "CVE-2019-0001",
PkgName: "foo",
InstalledVersion: "1.2.3",
FixedVersion: "1.2.4",
Vulnerability: dbTypes.Vulnerability{
Severity: dbTypes.SeverityLow.String(),
},
},
{
VulnerabilityID: "CVE-2018-0002",
PkgName: "bar",
InstalledVersion: "1.2.3",
FixedVersion: "",
Vulnerability: dbTypes.Vulnerability{
Severity: dbTypes.SeverityHigh.String(),
},
},
},
severities: []dbTypes.Severity{dbTypes.SeverityHigh},
ignoreUnfixed: true,
},
},
{
name: "happy path with ignore-file",
args: args{
vulns: []types.DetectedVulnerability{
{
// this vulnerability is ignored
VulnerabilityID: "CVE-2019-0001",
PkgName: "foo",
InstalledVersion: "1.2.3",
FixedVersion: "1.2.4",
Vulnerability: dbTypes.Vulnerability{
Severity: dbTypes.SeverityLow.String(),
},
},
{
// this vulnerability is ignored
VulnerabilityID: "CVE-2019-0002",
PkgName: "foo",
InstalledVersion: "1.2.3",
FixedVersion: "1.2.4",
Vulnerability: dbTypes.Vulnerability{
Severity: dbTypes.SeverityLow.String(),
},
},
{
VulnerabilityID: "CVE-2019-0003",
PkgName: "foo",
InstalledVersion: "1.2.3",
FixedVersion: "1.2.4",
Vulnerability: dbTypes.Vulnerability{
Severity: dbTypes.SeverityLow.String(),
},
},
},
severities: []dbTypes.Severity{dbTypes.SeverityLow},
ignoreUnfixed: false,
ignoreFile: "testdata/.trivyignore",
},
want: []types.DetectedVulnerability{
{
VulnerabilityID: "CVE-2019-0003",
PkgName: "foo",
InstalledVersion: "1.2.3",
FixedVersion: "1.2.4",
Vulnerability: dbTypes.Vulnerability{
Severity: dbTypes.SeverityLow.String(),
},
},
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
c := Client{}
got := c.Filter(tt.args.vulns, tt.args.severities, tt.args.ignoreUnfixed, tt.args.ignoreFile)
assert.Equal(t, tt.want, got, tt.name)
})
}
}