mirror of
https://github.com/prymitive/karma
synced 2026-08-23 11:56:20 +00:00
fix(tests): add more tests
This commit is contained in:
committed by
Łukasz Mierzwa
parent
7f9be48800
commit
4265d9a5df
@@ -331,6 +331,75 @@ func TestAlerts(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestAlertsFilterValues(t *testing.T) {
|
||||
// verifies that the Value field in the API response is correctly populated
|
||||
// for all filter types, including those with custom Value() overrides
|
||||
type filterValueTest struct {
|
||||
expression string
|
||||
expectedValue string
|
||||
isValid bool
|
||||
}
|
||||
tests := []filterValueTest{
|
||||
// labelFilter — uses filterBase.Value()
|
||||
{expression: "alertname=HTTP_Probe_Failed", expectedValue: "HTTP_Probe_Failed", isValid: true},
|
||||
// receiverFilter — uses filterBase.Value()
|
||||
{expression: "@receiver=by-cluster-service", expectedValue: "by-cluster-service", isValid: true},
|
||||
// ageFilter — custom Value() returns formatted duration
|
||||
{expression: "@age>1h", expectedValue: "-1h0m0s", isValid: true},
|
||||
// inhibitedFilter — custom Value() returns strconv.FormatBool
|
||||
{expression: "@inhibited=true", expectedValue: "true", isValid: true},
|
||||
// limitFilter — custom Value() returns strconv.Itoa
|
||||
{expression: "@limit=5", expectedValue: "5", isValid: true},
|
||||
// fuzzyFilter — custom Value() returns the compiled regex pattern
|
||||
{expression: "abc", expectedValue: "(?i)abc", isValid: true},
|
||||
// invalid filter — filterBase.Value() returns empty string
|
||||
{expression: "@state=bogus", expectedValue: "", isValid: false},
|
||||
}
|
||||
|
||||
mockConfig(t.Setenv)
|
||||
for _, version := range mock.ListAllMocks() {
|
||||
mockAlerts(version)
|
||||
r := testRouter()
|
||||
setupRouter(r, nil)
|
||||
|
||||
for _, ft := range tests {
|
||||
t.Run(fmt.Sprintf("%s/%s", version, ft.expression), func(t *testing.T) {
|
||||
payload, err := json.Marshal(models.AlertsRequest{
|
||||
Filters: []string{ft.expression},
|
||||
GridLimits: map[string]int{},
|
||||
DefaultGroupLimit: 5,
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
apiCache.Purge()
|
||||
req := httptest.NewRequest("POST", "/alerts.json", bytes.NewReader(payload))
|
||||
resp := httptest.NewRecorder()
|
||||
r.ServeHTTP(resp, req)
|
||||
if resp.Code != http.StatusOK {
|
||||
t.Fatalf("POST /alerts.json returned status %d", resp.Code)
|
||||
}
|
||||
|
||||
ur := models.AlertsResponse{}
|
||||
err = json.Unmarshal(resp.Body.Bytes(), &ur)
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to unmarshal response: %s", err)
|
||||
}
|
||||
if len(ur.Filters) != 1 {
|
||||
t.Fatalf("expected 1 filter in response, got %d", len(ur.Filters))
|
||||
}
|
||||
if ur.Filters[0].Value != ft.expectedValue {
|
||||
t.Errorf("filter Value = %q, want %q", ur.Filters[0].Value, ft.expectedValue)
|
||||
}
|
||||
if ur.Filters[0].IsValid != ft.isValid {
|
||||
t.Errorf("filter IsValid = %v, want %v", ur.Filters[0].IsValid, ft.isValid)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestAlertsBadRequest(t *testing.T) {
|
||||
mockConfig(t.Setenv)
|
||||
for _, version := range mock.ListAllMocks() {
|
||||
|
||||
@@ -40,10 +40,8 @@ func newAgeFilter(name, operator, rawText, value string) Filter {
|
||||
if dur > 0 {
|
||||
dur = -dur
|
||||
}
|
||||
m, ok := buildMatcher(operator, value)
|
||||
if !ok {
|
||||
return &filterBase{rawText: rawText}
|
||||
}
|
||||
// operator is pre-validated by the registry, buildMatcher cannot fail here
|
||||
m, _ := buildMatcher(operator, value)
|
||||
return &ageFilter{
|
||||
filterBase: filterBase{
|
||||
matcher: m,
|
||||
|
||||
@@ -26,10 +26,8 @@ func (filter *fingerprintFilter) MatchAlertmanager(am *models.AlertmanagerInstan
|
||||
}
|
||||
|
||||
func newFingerprintFilter(name, operator, rawText, value string) Filter {
|
||||
m, ok := buildMatcher(operator, value)
|
||||
if !ok {
|
||||
return &filterBase{rawText: rawText}
|
||||
}
|
||||
// operator is pre-validated by the registry, buildMatcher cannot fail here
|
||||
m, _ := buildMatcher(operator, value)
|
||||
return &fingerprintFilter{
|
||||
filterBase: filterBase{
|
||||
matcher: m,
|
||||
|
||||
@@ -47,10 +47,8 @@ func newInhibitedFilter(name, operator, rawText, value string) Filter {
|
||||
default:
|
||||
return &filterBase{rawText: rawText}
|
||||
}
|
||||
m, ok := buildMatcher(operator, value)
|
||||
if !ok {
|
||||
return &filterBase{rawText: rawText}
|
||||
}
|
||||
// operator is pre-validated by the registry, buildMatcher cannot fail here
|
||||
m, _ := buildMatcher(operator, value)
|
||||
return &inhibitedFilter{
|
||||
filterBase: filterBase{
|
||||
matcher: m,
|
||||
|
||||
@@ -35,10 +35,8 @@ func (filter *inhibitedByFilter) MatchAlertmanager(am *models.AlertmanagerInstan
|
||||
}
|
||||
|
||||
func newInhibitedByFilter(name, operator, rawText, value string) Filter {
|
||||
m, ok := buildMatcher(operator, value)
|
||||
if !ok {
|
||||
return &filterBase{rawText: rawText}
|
||||
}
|
||||
// operator is pre-validated by the registry, buildMatcher cannot fail here
|
||||
m, _ := buildMatcher(operator, value)
|
||||
return &inhibitedByFilter{
|
||||
filterBase: filterBase{
|
||||
matcher: m,
|
||||
|
||||
@@ -30,10 +30,8 @@ func newLimitFilter(name, operator, rawText, value string) Filter {
|
||||
if err != nil || val < 1 {
|
||||
return &filterBase{rawText: rawText}
|
||||
}
|
||||
m, ok := buildMatcher(operator, value)
|
||||
if !ok {
|
||||
return &filterBase{rawText: rawText}
|
||||
}
|
||||
// operator is pre-validated by the registry, buildMatcher cannot fail here
|
||||
m, _ := buildMatcher(operator, value)
|
||||
return &limitFilter{
|
||||
filterBase: filterBase{
|
||||
matcher: m,
|
||||
|
||||
@@ -35,10 +35,8 @@ func (filter *silenceIDFilter) MatchAlertmanager(am *models.AlertmanagerInstance
|
||||
}
|
||||
|
||||
func newSilenceIDFilter(name, operator, rawText, value string) Filter {
|
||||
m, ok := buildMatcher(operator, value)
|
||||
if !ok {
|
||||
return &filterBase{rawText: rawText}
|
||||
}
|
||||
// operator is pre-validated by the registry, buildMatcher cannot fail here
|
||||
m, _ := buildMatcher(operator, value)
|
||||
return &silenceIDFilter{
|
||||
filterBase: filterBase{
|
||||
matcher: m,
|
||||
|
||||
@@ -31,10 +31,8 @@ func newStateFilter(name, operator, rawText, value string) Filter {
|
||||
if _, ok := models.AlertStateFromString(value); !ok {
|
||||
return &filterBase{rawText: rawText}
|
||||
}
|
||||
m, ok := buildMatcher(operator, value)
|
||||
if !ok {
|
||||
return &filterBase{rawText: rawText}
|
||||
}
|
||||
// operator is pre-validated by the registry, buildMatcher cannot fail here
|
||||
m, _ := buildMatcher(operator, value)
|
||||
return &stateFilter{
|
||||
filterBase: filterBase{
|
||||
matcher: m,
|
||||
|
||||
@@ -1028,6 +1028,32 @@ var tests = []filterTest{
|
||||
},
|
||||
IsMatch: true,
|
||||
},
|
||||
|
||||
// invalid regex pattern triggers buildMatcher failure in regex-capable filters
|
||||
{
|
||||
Expression: "@alertmanager=~[",
|
||||
IsValid: false,
|
||||
},
|
||||
{
|
||||
Expression: "@cluster=~[",
|
||||
IsValid: false,
|
||||
},
|
||||
{
|
||||
Expression: "@receiver=~[",
|
||||
IsValid: false,
|
||||
},
|
||||
{
|
||||
Expression: "@silence_ticket=~[",
|
||||
IsValid: false,
|
||||
},
|
||||
{
|
||||
Expression: "@silence_author=~[",
|
||||
IsValid: false,
|
||||
},
|
||||
{
|
||||
Expression: "node=~[",
|
||||
IsValid: false,
|
||||
},
|
||||
}
|
||||
|
||||
func TestFilters(t *testing.T) {
|
||||
|
||||
Reference in New Issue
Block a user