Files
aquasecurity-trivy/pkg/iac/ignore/rule_test.go
2026-01-05 06:51:30 +00:00

362 lines
7.9 KiB
Go

package ignore_test
import (
"fmt"
"testing"
"time"
"github.com/stretchr/testify/assert"
"github.com/aquasecurity/trivy/pkg/iac/ignore"
"github.com/aquasecurity/trivy/pkg/iac/types"
)
func metadataWithLine(path string, line int) types.Metadata {
return types.NewMetadata(types.NewRange(path, line, line, "", nil), "")
}
func TestRules_Ignore(t *testing.T) {
const filename = "test"
type args struct {
metadata types.Metadata
ids []string
}
tests := []struct {
name string
src string
args args
shouldIgnore bool
}{
{
name: "no ignore",
src: `#test`,
shouldIgnore: false,
},
{
name: "one ignore rule",
src: `#trivy:ignore:rule-1`,
args: args{
metadata: metadataWithLine(filename, 2),
ids: []string{"rule-1"},
},
shouldIgnore: true,
},
{
name: "blank line between rule and finding",
src: `#trivy:ignore:rule-1`,
args: args{
metadata: metadataWithLine(filename, 3),
ids: []string{"rule-1"},
},
shouldIgnore: false,
},
{
name: "blank line between rules",
src: `#trivy:ignore:rule-1
#trivy:ignore:rule-2
`,
args: args{
metadata: metadataWithLine(filename, 4),
ids: []string{"rule-1"},
},
shouldIgnore: false,
},
{
name: "rule and a finding on the same line",
src: `#trivy:ignore:rule-1`,
args: args{
metadata: metadataWithLine(filename, 1),
ids: []string{"rule-1"},
},
shouldIgnore: true,
},
{
name: "rule and a finding on the same line",
src: `test #trivy:ignore:rule-1`,
args: args{
metadata: metadataWithLine(filename, 1),
ids: []string{"rule-1"},
},
shouldIgnore: true,
},
{
name: "multiple rules on one line",
src: `test #trivy:ignore:rule-1 #trivy:ignore:rule-2`,
args: args{
metadata: metadataWithLine(filename, 1),
ids: []string{"rule-2"},
},
shouldIgnore: true,
},
{
name: "rule and find from different files",
src: `test #trivy:ignore:rule-1`,
args: args{
metadata: metadataWithLine("another-file", 1),
ids: []string{"rule-2"},
},
shouldIgnore: false,
},
{
name: "multiple ignore rule",
src: `#trivy:ignore:rule-1
#trivy:ignore:rule-2
`,
args: args{
metadata: metadataWithLine(filename, 3),
ids: []string{"rule-1"},
},
shouldIgnore: true,
},
{
name: "ignore section with params",
src: `#trivy:ignore:rule-1[param1=1]`,
args: args{
metadata: metadataWithLine(filename, 2),
ids: []string{"rule-1"},
},
shouldIgnore: true,
},
{
name: "id's don't match",
src: `#trivy:ignore:rule-1`,
args: args{
metadata: metadataWithLine(filename, 2),
ids: []string{"rule-2"},
},
shouldIgnore: false,
},
{
name: "without ignore section",
src: `#trivy:exp:2022-01-01`,
args: args{
metadata: metadataWithLine(filename, 2),
ids: []string{"rule-2"},
},
shouldIgnore: false,
},
{
name: "non valid ignore section",
src: `#trivy:ignore`,
args: args{
metadata: metadataWithLine(filename, 2),
ids: []string{"rule-2"},
},
shouldIgnore: false,
},
{
name: "ignore rule with expiry date passed",
src: `#trivy:ignore:rule-1:exp:2022-01-01`,
args: args{
metadata: metadataWithLine(filename, 2),
ids: []string{"rule-1"},
},
shouldIgnore: false,
},
{
name: "ignore rule with expiry date not passed",
src: fmt.Sprintf(`#trivy:ignore:rule-1:exp:%d-01-01`, time.Now().Year()+1),
args: args{
metadata: metadataWithLine(filename, 2),
ids: []string{"rule-1"},
},
shouldIgnore: true,
},
{
name: "ignore rule with invalid expiry date",
src: `#trivy:ignore:rule-1:exp:2026-99-01`,
args: args{
metadata: metadataWithLine(filename, 2),
ids: []string{"rule-1"},
},
shouldIgnore: false,
},
{
name: "with valid wildcard",
src: `#trivy:ignore:rule-*`,
args: args{
metadata: metadataWithLine(filename, 2),
ids: []string{"rule-1"},
},
shouldIgnore: true,
},
{
name: "with non-valid wildcard",
src: `#trivy:ignore:rule-1-*d`,
args: args{
metadata: metadataWithLine(filename, 2),
ids: []string{"rule-1-abc"},
},
shouldIgnore: false,
},
{
name: "multiple ignore rules on the same line",
src: `test #trivy:ignore:rule-1
test #trivy:ignore:rule-2
`,
args: args{
metadata: metadataWithLine(filename, 1),
ids: []string{"rule-1"},
},
shouldIgnore: true,
},
{
name: "multiple ignore rules on the same line",
src: `# trivy:ignore:rule-1
# trivy:ignore:rule-2
test #trivy:ignore:rule-3
`,
args: args{
metadata: metadataWithLine(filename, 3),
ids: []string{"rule-1"},
},
shouldIgnore: true,
},
{
name: "multiple ignore rules on the same line",
src: `# trivy:ignore:rule-1 # trivy:ignore:rule-2
# trivy:ignore:rule-3
test #trivy:ignore:rule-4
`,
args: args{
metadata: metadataWithLine(filename, 3),
ids: []string{"rule-2"},
},
shouldIgnore: true,
},
{
name: "multiple ids",
src: `# trivy:ignore:rule-1`,
args: args{
metadata: metadataWithLine(filename, 1),
ids: []string{"rule-1", "rule-2"},
},
shouldIgnore: true,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
rules := ignore.Parse(tt.src, "", filename)
got := rules.Ignore(tt.args.metadata, tt.args.ids, nil)
assert.Equal(t, tt.shouldIgnore, got)
})
}
}
func TestRules_IgnoreWithCustomIgnorer(t *testing.T) {
const filename = "test"
type args struct {
metadata types.Metadata
ids []string
ignorers map[string]ignore.Ignorer
}
tests := []struct {
name string
src string
parser ignore.RuleSectionParser
args args
shouldIgnore bool
}{
{
name: "happy",
src: `#trivy:ignore:rule-1:ws:dev`,
parser: &ignore.StringMatchParser{
SectionKey: "ws",
},
args: args{
metadata: metadataWithLine(filename, 2),
ids: []string{"rule-1"},
ignorers: map[string]ignore.Ignorer{
"ws": func(_ types.Metadata, param any) bool {
ws, ok := param.(string)
if !ok {
return false
}
return ws == "dev"
},
},
},
shouldIgnore: true,
},
{
name: "with wildcard",
src: `#trivy:ignore:rule-1:ws:dev-*`,
parser: &ignore.StringMatchParser{
SectionKey: "ws",
},
args: args{
metadata: metadataWithLine(filename, 2),
ids: []string{"rule-1"},
ignorers: map[string]ignore.Ignorer{
"ws": func(_ types.Metadata, param any) bool {
ws, ok := param.(string)
if !ok {
return false
}
return ignore.MatchPattern("dev-stage1", ws)
},
},
},
shouldIgnore: true,
},
{
name: "bad",
src: `#trivy:ignore:rule-1:ws:prod`,
parser: &ignore.StringMatchParser{
SectionKey: "ws",
},
args: args{
metadata: metadataWithLine(filename, 2),
ids: []string{"rule-1"},
ignorers: map[string]ignore.Ignorer{
"ws": func(_ types.Metadata, param any) bool {
ws, ok := param.(string)
if !ok {
return false
}
return ws == "dev"
},
},
},
shouldIgnore: false,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
rules := ignore.Parse(tt.src, filename, "", tt.parser)
got := rules.Ignore(tt.args.metadata, tt.args.ids, tt.args.ignorers)
assert.Equal(t, tt.shouldIgnore, got)
})
}
}
func TestMatchPattern(t *testing.T) {
tests := []struct {
input string
pattern string
expected bool
}{
{"foo-test-bar", "*-test-*", true},
{"foo-test-bar", "*-example-*", false},
{"test", "*test", true},
{"example", "test", false},
{"example-test", "*-test*", true},
{"example-test", "*example-*", true},
}
for _, tc := range tests {
t.Run(tc.input+":"+tc.pattern, func(t *testing.T) {
got := ignore.MatchPattern(tc.input, tc.pattern)
assert.Equal(t, tc.expected, got)
})
}
}