crowdsec/pkg/csprofiles/csprofiles_test.go
Thibault "bui" Koechlin 950759f6d6
Output plugins (#878)
* Add plugin system for notifications (#857)
2021-08-25 11:43:29 +02:00

104 lines
2.9 KiB
Go

package csprofiles
import (
"fmt"
"reflect"
"testing"
"github.com/antonmedv/expr"
"github.com/antonmedv/expr/vm"
"github.com/crowdsecurity/crowdsec/pkg/csconfig"
"github.com/crowdsecurity/crowdsec/pkg/exprhelpers"
"github.com/crowdsecurity/crowdsec/pkg/models"
)
var (
scope = "Country"
typ = "ban"
simulated = false
duration = "1h"
value = "CH"
scenario = "ssh-bf"
)
func TestEvaluateProfile(t *testing.T) {
type args struct {
profile *csconfig.ProfileCfg
Alert *models.Alert
}
tests := []struct {
name string
args args
expectedDecisionCount int // count of expected decisions
expectedMatchStatus bool
}{
{
name: "simple pass single expr",
args: args{
profile: &csconfig.ProfileCfg{
Filters: []string{fmt.Sprintf("Alert.GetScenario() == \"%s\"", scenario)},
RuntimeFilters: []*vm.Program{},
},
Alert: &models.Alert{Remediation: true, Scenario: &scenario},
},
expectedDecisionCount: 0,
expectedMatchStatus: true,
},
{
name: "simple fail single expr",
args: args{
profile: &csconfig.ProfileCfg{
Filters: []string{"Alert.GetScenario() == \"Foo\""},
RuntimeFilters: []*vm.Program{},
},
Alert: &models.Alert{Remediation: true},
},
expectedDecisionCount: 0,
expectedMatchStatus: false,
},
{
name: "1 expr fail 1 expr pass should still eval to match",
args: args{
profile: &csconfig.ProfileCfg{
Filters: []string{"1==1", "1!=1"},
RuntimeFilters: []*vm.Program{},
},
Alert: &models.Alert{Remediation: true},
},
expectedDecisionCount: 0,
expectedMatchStatus: true,
},
{
name: "simple filter with 2 decision",
args: args{
profile: &csconfig.ProfileCfg{
Filters: []string{"1==1"},
RuntimeFilters: []*vm.Program{},
Decisions: []models.Decision{
{Type: &typ, Scope: &scope, Simulated: &simulated, Duration: &duration},
{Type: &typ, Scope: &scope, Simulated: &simulated, Duration: &duration},
},
},
Alert: &models.Alert{Remediation: true, Scenario: &scenario, Source: &models.Source{Value: &value}},
},
expectedDecisionCount: 2,
expectedMatchStatus: true,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
for _, filter := range tt.args.profile.Filters {
runtimeFilter, _ := expr.Compile(filter, expr.Env(exprhelpers.GetExprEnv(map[string]interface{}{"Alert": &models.Alert{}})))
tt.args.profile.RuntimeFilters = append(tt.args.profile.RuntimeFilters, runtimeFilter)
}
got, got1, _ := EvaluateProfile(tt.args.profile, tt.args.Alert)
if !reflect.DeepEqual(len(got), tt.expectedDecisionCount) {
t.Errorf("EvaluateProfile() got = %+v, want %+v", got, tt.expectedDecisionCount)
}
if got1 != tt.expectedMatchStatus {
t.Errorf("EvaluateProfile() got1 = %v, want %v", got1, tt.expectedMatchStatus)
}
})
}
}