mirror of
https://github.com/prymitive/karma
synced 2026-05-11 03:46:48 +00:00
562 lines
14 KiB
Go
562 lines
14 KiB
Go
package filters_test
|
|
|
|
import (
|
|
"encoding/json"
|
|
"testing"
|
|
"time"
|
|
|
|
"github.com/cloudflare/unsee/filters"
|
|
"github.com/cloudflare/unsee/models"
|
|
"github.com/cloudflare/unsee/store"
|
|
)
|
|
|
|
type filterTest struct {
|
|
Expression string
|
|
IsValid bool
|
|
Alert models.Alert
|
|
Silence models.Silence
|
|
IsMatch bool
|
|
}
|
|
|
|
var tests = []filterTest{
|
|
filterTest{
|
|
Expression: "@silenced=true",
|
|
IsValid: true,
|
|
Alert: models.Alert{},
|
|
IsMatch: false,
|
|
},
|
|
filterTest{
|
|
Expression: "@silenced!=true",
|
|
IsValid: true,
|
|
Alert: models.Alert{},
|
|
IsMatch: true,
|
|
},
|
|
filterTest{
|
|
Expression: "@silenced=true",
|
|
IsValid: true,
|
|
Alert: models.Alert{Status: "suppressed", SilencedBy: []string{"1"}},
|
|
IsMatch: true,
|
|
},
|
|
filterTest{
|
|
Expression: "@silenced!=true",
|
|
IsValid: true,
|
|
Alert: models.Alert{Status: "suppressed", SilencedBy: []string{"1"}},
|
|
IsMatch: false,
|
|
},
|
|
filterTest{
|
|
Expression: "@silenced=xx",
|
|
IsValid: false,
|
|
},
|
|
filterTest{
|
|
Expression: "@silenced=:xx",
|
|
IsValid: false,
|
|
},
|
|
filterTest{
|
|
Expression: "@silenced==xx",
|
|
IsValid: false,
|
|
},
|
|
filterTest{
|
|
Expression: "@silenced=~true",
|
|
IsValid: false,
|
|
},
|
|
filterTest{
|
|
Expression: "@silenced=~false",
|
|
IsValid: false,
|
|
},
|
|
|
|
filterTest{
|
|
Expression: "@inhibited=true",
|
|
IsValid: true,
|
|
Alert: models.Alert{},
|
|
IsMatch: false,
|
|
},
|
|
filterTest{
|
|
Expression: "@inhibited!=true",
|
|
IsValid: true,
|
|
Alert: models.Alert{},
|
|
IsMatch: true,
|
|
},
|
|
filterTest{
|
|
Expression: "@inhibited=true",
|
|
IsValid: true,
|
|
Alert: models.Alert{Status: "suppressed", InhibitedBy: []string{"999"}},
|
|
IsMatch: true,
|
|
},
|
|
filterTest{
|
|
Expression: "@inhibited=true",
|
|
IsValid: true,
|
|
Alert: models.Alert{Status: "active"},
|
|
IsMatch: false,
|
|
},
|
|
filterTest{
|
|
Expression: "@inhibited!=true",
|
|
IsValid: true,
|
|
Alert: models.Alert{Status: "suppressed", InhibitedBy: []string{"999"}},
|
|
IsMatch: false,
|
|
},
|
|
filterTest{
|
|
Expression: "@inhibited=xx",
|
|
IsValid: false,
|
|
},
|
|
filterTest{
|
|
Expression: "@inhibited=:xx",
|
|
IsValid: false,
|
|
},
|
|
filterTest{
|
|
Expression: "@inhibited==xx",
|
|
IsValid: false,
|
|
},
|
|
filterTest{
|
|
Expression: "@inhibited=~true",
|
|
IsValid: false,
|
|
},
|
|
filterTest{
|
|
Expression: "@inhibited=~false",
|
|
IsValid: false,
|
|
},
|
|
|
|
filterTest{
|
|
Expression: "@silence_jira=1",
|
|
IsValid: true,
|
|
Alert: models.Alert{Status: "suppressed", SilencedBy: []string{"1"}},
|
|
Silence: models.Silence{ID: "1", JiraID: "1"},
|
|
IsMatch: true,
|
|
},
|
|
filterTest{
|
|
Expression: "@silence_jira=2",
|
|
IsValid: true,
|
|
Alert: models.Alert{Status: "suppressed", SilencedBy: []string{"1"}},
|
|
Silence: models.Silence{ID: "1"},
|
|
IsMatch: false,
|
|
},
|
|
filterTest{
|
|
Expression: "@silence_jira!=3",
|
|
IsValid: true,
|
|
Alert: models.Alert{Status: "suppressed", SilencedBy: []string{"1"}},
|
|
Silence: models.Silence{ID: "1", JiraID: "x"},
|
|
IsMatch: true,
|
|
},
|
|
filterTest{
|
|
Expression: "@silence_jira!=4",
|
|
IsValid: true,
|
|
Alert: models.Alert{Status: "suppressed", SilencedBy: []string{"1"}},
|
|
Silence: models.Silence{ID: "1", JiraID: "4"},
|
|
IsMatch: false,
|
|
},
|
|
filterTest{
|
|
Expression: "@silence_jira!=5",
|
|
IsValid: true,
|
|
Alert: models.Alert{Status: "suppressed", SilencedBy: []string{"1"}},
|
|
Silence: models.Silence{ID: "1"},
|
|
IsMatch: true,
|
|
},
|
|
filterTest{
|
|
Expression: "@silence_jira=~abc",
|
|
IsValid: true,
|
|
Alert: models.Alert{Status: "suppressed", SilencedBy: []string{"1"}},
|
|
Silence: models.Silence{ID: "1", JiraID: "xxabcxx"},
|
|
IsMatch: true,
|
|
},
|
|
filterTest{
|
|
Expression: "@silence_jira=~abc",
|
|
IsValid: true,
|
|
Alert: models.Alert{Status: "suppressed", SilencedBy: []string{"1"}},
|
|
Silence: models.Silence{ID: "1", JiraID: "xxx"},
|
|
IsMatch: false,
|
|
},
|
|
filterTest{
|
|
Expression: "@silence_jira=~",
|
|
IsValid: false,
|
|
Alert: models.Alert{Status: "suppressed", SilencedBy: []string{"1"}},
|
|
Silence: models.Silence{ID: "1", JiraID: "xxx"},
|
|
IsMatch: false,
|
|
},
|
|
filterTest{
|
|
Expression: "@silence_jira~=",
|
|
IsValid: false,
|
|
Alert: models.Alert{Status: "suppressed", SilencedBy: []string{"1"}},
|
|
Silence: models.Silence{ID: "1", JiraID: "xxx"},
|
|
IsMatch: false,
|
|
},
|
|
filterTest{
|
|
Expression: "@silence_jira~=1",
|
|
IsValid: false,
|
|
Alert: models.Alert{Status: "suppressed", SilencedBy: []string{"1"}},
|
|
Silence: models.Silence{ID: "1", JiraID: "xxx"},
|
|
IsMatch: false,
|
|
},
|
|
|
|
filterTest{
|
|
Expression: "@silence_author=john",
|
|
IsValid: true,
|
|
Alert: models.Alert{Status: "suppressed", SilencedBy: []string{"1"}},
|
|
Silence: models.Silence{ID: "1", CreatedBy: "john"},
|
|
IsMatch: true,
|
|
},
|
|
filterTest{
|
|
Expression: "@silence_author=john",
|
|
IsValid: true,
|
|
Alert: models.Alert{Status: "suppressed", SilencedBy: []string{"1"}},
|
|
Silence: models.Silence{ID: "1", CreatedBy: "bob"},
|
|
IsMatch: false,
|
|
},
|
|
filterTest{
|
|
Expression: "@silence_author!=john",
|
|
IsValid: true,
|
|
Alert: models.Alert{Status: "suppressed", SilencedBy: []string{"1"}},
|
|
Silence: models.Silence{ID: "1", CreatedBy: "bob"},
|
|
IsMatch: true,
|
|
},
|
|
filterTest{
|
|
Expression: "@silence_author!=john",
|
|
IsValid: true,
|
|
Alert: models.Alert{Status: "suppressed", SilencedBy: []string{"1"}},
|
|
Silence: models.Silence{ID: "1", CreatedBy: "john"},
|
|
IsMatch: false,
|
|
},
|
|
filterTest{
|
|
Expression: "@silence_author!=john",
|
|
IsValid: true,
|
|
Alert: models.Alert{Status: "suppressed", SilencedBy: []string{"1"}},
|
|
Silence: models.Silence{ID: "1"},
|
|
IsMatch: true,
|
|
},
|
|
filterTest{
|
|
Expression: "@silence_author=~",
|
|
IsValid: false,
|
|
Alert: models.Alert{Status: "suppressed", SilencedBy: []string{"1"}},
|
|
Silence: models.Silence{ID: "1"},
|
|
IsMatch: false,
|
|
},
|
|
filterTest{
|
|
Expression: "@silence_author===x",
|
|
IsValid: false,
|
|
Alert: models.Alert{Status: "suppressed", SilencedBy: []string{"1"}},
|
|
Silence: models.Silence{ID: "1"},
|
|
IsMatch: false,
|
|
},
|
|
filterTest{
|
|
Expression: "@silence_author=!!xxx",
|
|
IsValid: false,
|
|
Alert: models.Alert{Status: "suppressed", SilencedBy: []string{"1"}},
|
|
Silence: models.Silence{ID: "1"},
|
|
IsMatch: false,
|
|
},
|
|
|
|
filterTest{
|
|
Expression: "@age<1h",
|
|
IsValid: true,
|
|
Alert: models.Alert{StartsAt: time.Now().Add(time.Minute * -55)},
|
|
IsMatch: true,
|
|
},
|
|
filterTest{
|
|
Expression: "@age>1h",
|
|
IsValid: true,
|
|
Alert: models.Alert{StartsAt: time.Now().Add(time.Hour * -2)},
|
|
IsMatch: true,
|
|
},
|
|
filterTest{
|
|
Expression: "@age<-1h",
|
|
IsValid: true,
|
|
Alert: models.Alert{StartsAt: time.Now().Add(time.Minute * -55)},
|
|
IsMatch: true,
|
|
},
|
|
filterTest{
|
|
Expression: "@age>-1h",
|
|
IsValid: true,
|
|
Alert: models.Alert{StartsAt: time.Now().Add(time.Hour * -2)},
|
|
IsMatch: true,
|
|
},
|
|
filterTest{
|
|
Expression: "@age=1h",
|
|
IsValid: false,
|
|
Alert: models.Alert{StartsAt: time.Now().Add(time.Minute * -55)},
|
|
IsMatch: false,
|
|
},
|
|
filterTest{
|
|
Expression: "@age=~1h",
|
|
IsValid: false,
|
|
Alert: models.Alert{StartsAt: time.Now().Add(time.Minute * -55)},
|
|
IsMatch: false,
|
|
},
|
|
filterTest{
|
|
Expression: "@age>",
|
|
IsValid: false,
|
|
Alert: models.Alert{StartsAt: time.Now().Add(time.Minute * -55)},
|
|
IsMatch: false,
|
|
},
|
|
filterTest{
|
|
Expression: "@age<",
|
|
IsValid: false,
|
|
Alert: models.Alert{StartsAt: time.Now().Add(time.Minute * -55)},
|
|
IsMatch: false,
|
|
},
|
|
filterTest{
|
|
Expression: "@age>a",
|
|
IsValid: false,
|
|
Alert: models.Alert{StartsAt: time.Now().Add(time.Minute * -55)},
|
|
IsMatch: false,
|
|
},
|
|
filterTest{
|
|
Expression: "@age<10v",
|
|
IsValid: false,
|
|
Alert: models.Alert{StartsAt: time.Now().Add(time.Minute * -55)},
|
|
IsMatch: false,
|
|
},
|
|
|
|
filterTest{
|
|
Expression: "node=vps1",
|
|
IsValid: true,
|
|
Alert: models.Alert{Labels: map[string]string{"node": "vps1"}},
|
|
IsMatch: true,
|
|
},
|
|
filterTest{
|
|
Expression: "node=vps1",
|
|
IsValid: true,
|
|
Alert: models.Alert{},
|
|
IsMatch: false,
|
|
},
|
|
filterTest{
|
|
Expression: "node!=vps1",
|
|
IsValid: true,
|
|
Alert: models.Alert{Labels: map[string]string{"node": "vps1"}},
|
|
IsMatch: false,
|
|
},
|
|
filterTest{
|
|
Expression: "node!=vps1",
|
|
IsValid: true,
|
|
Alert: models.Alert{Labels: map[string]string{"node": "vps2"}},
|
|
IsMatch: true,
|
|
},
|
|
filterTest{
|
|
Expression: "node=~vps",
|
|
IsValid: true,
|
|
Alert: models.Alert{Labels: map[string]string{"node": "vps1"}},
|
|
IsMatch: true,
|
|
},
|
|
filterTest{
|
|
Expression: "node!~vps",
|
|
IsValid: true,
|
|
Alert: models.Alert{Labels: map[string]string{"node": "vps1"}},
|
|
IsMatch: false,
|
|
},
|
|
filterTest{
|
|
Expression: "node!~abc",
|
|
IsValid: true,
|
|
Alert: models.Alert{Labels: map[string]string{"node": "vps1"}},
|
|
IsMatch: true,
|
|
},
|
|
filterTest{
|
|
Expression: "node!~",
|
|
IsValid: false,
|
|
Alert: models.Alert{Labels: map[string]string{"node": "vps1"}},
|
|
IsMatch: false,
|
|
},
|
|
filterTest{
|
|
Expression: "node=",
|
|
IsValid: false,
|
|
Alert: models.Alert{Labels: map[string]string{"node": "vps1"}},
|
|
IsMatch: false,
|
|
},
|
|
filterTest{
|
|
Expression: "node===",
|
|
IsValid: false,
|
|
Alert: models.Alert{Labels: map[string]string{"node": "vps1"}},
|
|
IsMatch: false,
|
|
},
|
|
|
|
filterTest{
|
|
Expression: "abc",
|
|
IsValid: true,
|
|
Alert: models.Alert{Labels: map[string]string{"key": "abc"}},
|
|
IsMatch: true,
|
|
},
|
|
filterTest{
|
|
Expression: "abc",
|
|
IsValid: true,
|
|
Alert: models.Alert{Labels: map[string]string{"key": "XXXabcx"}},
|
|
IsMatch: true,
|
|
},
|
|
filterTest{
|
|
Expression: "abc",
|
|
IsValid: true,
|
|
Alert: models.Alert{Labels: map[string]string{"abc": "xxxab"}},
|
|
IsMatch: false,
|
|
},
|
|
filterTest{
|
|
Expression: "abc",
|
|
IsValid: true,
|
|
Alert: models.Alert{Annotations: map[string]string{"key": "abc"}},
|
|
IsMatch: true,
|
|
},
|
|
filterTest{
|
|
Expression: "abc",
|
|
IsValid: true,
|
|
Alert: models.Alert{Annotations: map[string]string{"key": "ccc abc"}},
|
|
IsMatch: true,
|
|
},
|
|
filterTest{
|
|
Expression: "abc",
|
|
IsValid: true,
|
|
Alert: models.Alert{Annotations: map[string]string{"abc": "zzz"}},
|
|
IsMatch: false,
|
|
},
|
|
filterTest{
|
|
Expression: "abc",
|
|
IsValid: true,
|
|
Alert: models.Alert{Status: "suppressed", SilencedBy: []string{"1"}},
|
|
Silence: models.Silence{ID: "1", Comment: "abc"},
|
|
IsMatch: true,
|
|
},
|
|
filterTest{
|
|
Expression: "abc",
|
|
IsValid: true,
|
|
Alert: models.Alert{Status: "suppressed", SilencedBy: []string{"1"}},
|
|
Silence: models.Silence{ID: "1", Comment: "abcxxx"},
|
|
IsMatch: true,
|
|
},
|
|
filterTest{
|
|
Expression: "abc",
|
|
IsValid: true,
|
|
Alert: models.Alert{Status: "suppressed", SilencedBy: []string{"1"}},
|
|
Silence: models.Silence{ID: "1", Comment: "ABCD"},
|
|
IsMatch: true,
|
|
},
|
|
filterTest{
|
|
Expression: "abc",
|
|
IsValid: true,
|
|
Alert: models.Alert{Status: "suppressed", SilencedBy: []string{"1"}},
|
|
Silence: models.Silence{ID: "1", Comment: "xzc"},
|
|
IsMatch: false,
|
|
},
|
|
filterTest{
|
|
Expression: "abc",
|
|
IsValid: true,
|
|
Alert: models.Alert{},
|
|
IsMatch: false,
|
|
},
|
|
filterTest{
|
|
Expression: "^abb[****].*****",
|
|
IsValid: false,
|
|
},
|
|
}
|
|
|
|
func TestFilters(t *testing.T) {
|
|
for _, ft := range tests {
|
|
if &ft.Silence != nil {
|
|
store.Store.SetSilences(map[string]models.Silence{
|
|
ft.Silence.ID: ft.Silence,
|
|
})
|
|
} else {
|
|
store.Store.SetSilences(map[string]models.Silence{})
|
|
}
|
|
f := filters.NewFilter(ft.Expression)
|
|
if f == nil {
|
|
t.Errorf("[%s] No filter found", ft.Expression)
|
|
}
|
|
if f.GetHits() != 0 {
|
|
t.Errorf("[%s] Hits = %#v after init(), expected 0", ft.Expression, f.GetHits())
|
|
}
|
|
if f.GetIsValid() != ft.IsValid {
|
|
t.Errorf("[%s] GetIsValid() returned %#v while %#v was expected", ft.Expression, f.GetIsValid(), ft.IsValid)
|
|
}
|
|
if f.GetIsValid() {
|
|
m := f.Match(&ft.Alert, 0)
|
|
if m != ft.IsMatch {
|
|
j, _ := json.Marshal(ft.Alert)
|
|
s, _ := json.Marshal(ft.Silence)
|
|
t.Errorf("[%s] Match() returned %#v while %#v was expected\nalert used: %s\nsilence used: %s", ft.Expression, m, ft.IsMatch, j, s)
|
|
}
|
|
if ft.IsMatch && f.GetHits() != 1 {
|
|
t.Errorf("[%s] GetHits() returned %#v after match, expected 1", ft.Expression, f.GetHits())
|
|
}
|
|
if !ft.IsMatch && f.GetHits() != 0 {
|
|
t.Errorf("[%s] GetHits() returned %#v after non-match, expected 0", ft.Expression, f.GetHits())
|
|
}
|
|
if f.GetRawText() != ft.Expression {
|
|
t.Errorf("[%s] GetRawText() returned %#v != %s passed as the expression", ft.Expression, f.GetRawText(), ft.Expression)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
type limitFilterTest struct {
|
|
Expression string
|
|
IsValid bool
|
|
IsMatch []bool
|
|
Hits int
|
|
}
|
|
|
|
var limitTests = []limitFilterTest{
|
|
limitFilterTest{
|
|
Expression: "@limit=3",
|
|
IsValid: true,
|
|
IsMatch: []bool{true, true, true},
|
|
Hits: 0,
|
|
},
|
|
limitFilterTest{
|
|
Expression: "@limit=1",
|
|
IsValid: true,
|
|
IsMatch: []bool{true, false, false},
|
|
Hits: 2,
|
|
},
|
|
limitFilterTest{
|
|
Expression: "@limit=5",
|
|
IsValid: true,
|
|
IsMatch: []bool{true, true, true, true, true, false, false, false},
|
|
Hits: 3,
|
|
},
|
|
limitFilterTest{
|
|
Expression: "@limit=0",
|
|
IsValid: false,
|
|
},
|
|
limitFilterTest{
|
|
Expression: "@limit=abc",
|
|
IsValid: false,
|
|
},
|
|
limitFilterTest{
|
|
Expression: "@limit==0",
|
|
IsValid: false,
|
|
},
|
|
limitFilterTest{
|
|
Expression: "@limit>0",
|
|
IsValid: false,
|
|
},
|
|
limitFilterTest{
|
|
Expression: "@limit<0",
|
|
IsValid: false,
|
|
},
|
|
}
|
|
|
|
func TestLimitFilter(t *testing.T) {
|
|
for _, ft := range limitTests {
|
|
f := filters.NewFilter(ft.Expression)
|
|
if f == nil {
|
|
t.Errorf("[%s] No filter found", ft.Expression)
|
|
}
|
|
if f.GetHits() != 0 {
|
|
t.Errorf("[%s] Hits = %#v after init(), expected 0", ft.Expression, f.GetHits())
|
|
}
|
|
if f.GetIsValid() != ft.IsValid {
|
|
t.Errorf("[%s] GetIsValid() returned %#v while %#v was expected", ft.Expression, f.GetIsValid(), ft.IsValid)
|
|
}
|
|
if f.GetIsValid() {
|
|
alert := models.Alert{}
|
|
var index int = 0
|
|
for _, isMatch := range ft.IsMatch {
|
|
m := f.Match(&alert, index)
|
|
if m != isMatch {
|
|
t.Errorf("[%s] Match() returned %#v while %#v was expected, index %d", ft.Expression, m, isMatch, index)
|
|
}
|
|
if f.GetRawText() != ft.Expression {
|
|
t.Errorf("[%s] GetRawText() returned %#v != %s passed as the expression", ft.Expression, f.GetRawText(), ft.Expression)
|
|
}
|
|
index++
|
|
}
|
|
if f.GetHits() != ft.Hits {
|
|
t.Errorf("[%s] GetHits() returned %#v hits, expected %d", ft.Expression, f.GetHits(), ft.Hits)
|
|
}
|
|
}
|
|
}
|
|
}
|