fix(tests): add more tests

This commit is contained in:
Lukasz Mierzwa
2026-03-11 13:10:15 +00:00
committed by Łukasz Mierzwa
parent 7f9be48800
commit 4265d9a5df
9 changed files with 109 additions and 28 deletions
+69
View File
@@ -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() {
+2 -4
View File
@@ -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,
+2 -4
View File
@@ -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,
+2 -4
View File
@@ -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,
+2 -4
View File
@@ -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,
+2 -4
View File
@@ -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,
+2 -4
View File
@@ -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,
+2 -4
View File
@@ -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,
+26
View File
@@ -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) {