mirror of
https://github.com/SigNoz/signoz.git
synced 2025-12-17 15:36:48 +00:00
* chore: added custom distpatcher * feat(notification-grouping): added notification grouping * feat(notification-grouping): addded integration test dependency * feat(notification-grouping): linting and test cases * feat(notification-grouping): linting and test cases * feat(notification-grouping): linting and test cases * feat(notification-grouping): addded integration test dependency * feat(notification-grouping): debug log lines * feat(notification-grouping): debug log lines * feat(notification-grouping): debug log lines * feat(notification-grouping): addded integration test dependency * feat(notification-grouping): addded integration test dependency * feat(notification-grouping): addded integration test dependency * feat(notification-grouping): added structure changes * feat(notification-grouping): added structure changes * feat(notification-routing): added notification routing * chore(notification-grouping): added notificaiton grouping * Update pkg/alertmanager/nfmanager/rulebasednotification/provider.go Co-authored-by: ellipsis-dev[bot] <65095814+ellipsis-dev[bot]@users.noreply.github.com> * chore(notification-grouping): added renotification interval * fix(notification-grouping): added fix for renotification * chore(notificaiton-grouping): added no data renotify * chore(notificaiton-grouping): added no data renotify * chore(notificaiton-grouping): added no data renotify * chore(notification-grouping): added no data renotify interval * chore(notification-grouping): removed errors package from dispatcher * chore(notification-grouping): removed errors package from dispatcher * chore(notification-grouping): removed unwanted tests * chore(notification-grouping): removed unwanted pkg name * chore(notification-grouping): added delete notification setting * chore(notification-grouping): added delete notification setting * Update pkg/alertmanager/nfmanager/nfmanagertest/provider.go Co-authored-by: ellipsis-dev[bot] <65095814+ellipsis-dev[bot]@users.noreply.github.com> * chore(notification-grouping): removed nfmanager config| notification settings in postable rule * chore(notification-grouping): removed nfmanager config| notification settings in postable rule * chore(notification-grouping): added test for dispatcher * chore(notification-grouping): added test for dispatcher * chore(notification-grouping): go linting errors * chore(notification-grouping): added test cases for aggGroupPerRoute * chore(notification-grouping): added test cases for aggGroupPerRoute * chore(notification-grouping): corrected get notification config logic * Update pkg/alertmanager/nfmanager/rulebasednotification/provider_test.go Co-authored-by: ellipsis-dev[bot] <65095814+ellipsis-dev[bot]@users.noreply.github.com> * chore(notification-routing): added notification routing policies * feat(notification-routing): added test cases for dispatcher * chore(notification-routing): added notification routing policies * chore(notification-routing): added notification routing policies * Apply suggestions from code review Co-authored-by: ellipsis-dev[bot] <65095814+ellipsis-dev[bot]@users.noreply.github.com> * chore(notification-routing): added notification routing policies * chore(notification-routing): added notification routing policies * Update pkg/alertmanager/alertmanagerserver/distpatcher_test.go Co-authored-by: ellipsis-dev[bot] <65095814+ellipsis-dev[bot]@users.noreply.github.com> * chore(notification-routing): sorted imports * chore(notification-routing): minor edit |pr resolve comments * chore(notification-grouping): corrected dispatcher test cases * chore(notification-routing): added notification routing policies * chore(notification-routing): corrected race condition in test * chore: resolved pr comments * chore: passing threshold value to tempalte * chore: completed delete rule functionality * chore: added grouping disabled functionality * chore: added grouping disabled functionality * chore(notification-routing): resolved pr comments * chore(notification-routing): resolved pr comments * chore(notification-routing): resolved pr comments * chore(notification-routing): sorted imports * chore(notification-routing): fix linting errors * chore(notification-routing): removed enabled flags * fix: test rule multiple threhsold (#9224) * chore: corrected linting errors * chore: corrected linting errors * chore: corrected linting errors * chore: corrected linting errors * chore: corrected migration errors * chore: corrected migration errors * chore: corrected migration errors * chore: corrected migration errors * Update pkg/sqlmigration/049_add_route_policy.go Co-authored-by: ellipsis-dev[bot] <65095814+ellipsis-dev[bot]@users.noreply.github.com> * chore: added org_is as foreign key * chore: resolved pr comments * chore: removed route store unused --------- Co-authored-by: Srikanth Chekuri <srikanth.chekuri92@gmail.com> Co-authored-by: ellipsis-dev[bot] <65095814+ellipsis-dev[bot]@users.noreply.github.com>
729 lines
16 KiB
Go
729 lines
16 KiB
Go
package rules
|
|
|
|
import (
|
|
"testing"
|
|
"time"
|
|
|
|
"github.com/SigNoz/signoz/pkg/instrumentation/instrumentationtest"
|
|
v3 "github.com/SigNoz/signoz/pkg/query-service/model/v3"
|
|
ruletypes "github.com/SigNoz/signoz/pkg/types/ruletypes"
|
|
"github.com/SigNoz/signoz/pkg/valuer"
|
|
pql "github.com/prometheus/prometheus/promql"
|
|
"github.com/stretchr/testify/assert"
|
|
)
|
|
|
|
func getVectorValues(vectors []ruletypes.Sample) []float64 {
|
|
if len(vectors) == 0 {
|
|
return []float64{} // Return empty slice instead of nil
|
|
}
|
|
var values []float64
|
|
for _, v := range vectors {
|
|
values = append(values, v.V)
|
|
}
|
|
return values
|
|
}
|
|
|
|
func TestPromRuleShouldAlert(t *testing.T) {
|
|
postableRule := ruletypes.PostableRule{
|
|
AlertName: "Test Rule",
|
|
AlertType: ruletypes.AlertTypeMetric,
|
|
RuleType: ruletypes.RuleTypeProm,
|
|
Evaluation: &ruletypes.EvaluationEnvelope{Kind: ruletypes.RollingEvaluation, Spec: ruletypes.RollingWindow{
|
|
EvalWindow: ruletypes.Duration(5 * time.Minute),
|
|
Frequency: ruletypes.Duration(1 * time.Minute),
|
|
}},
|
|
RuleCondition: &ruletypes.RuleCondition{
|
|
CompositeQuery: &v3.CompositeQuery{
|
|
QueryType: v3.QueryTypePromQL,
|
|
PromQueries: map[string]*v3.PromQuery{
|
|
"A": {
|
|
Query: "dummy_query", // This is not used in the test
|
|
},
|
|
},
|
|
},
|
|
},
|
|
}
|
|
|
|
cases := []struct {
|
|
values pql.Series
|
|
expectAlert bool
|
|
compareOp string
|
|
matchType string
|
|
target float64
|
|
expectedAlertSample v3.Point
|
|
expectedVectorValues []float64 // Expected values in result vector
|
|
}{
|
|
// Test cases for Equals Always
|
|
{
|
|
values: pql.Series{
|
|
Floats: []pql.FPoint{
|
|
{F: 0.0},
|
|
{F: 0.0},
|
|
{F: 0.0},
|
|
{F: 0.0},
|
|
{F: 0.0},
|
|
},
|
|
},
|
|
expectAlert: true,
|
|
compareOp: "3", // Equals
|
|
matchType: "2", // Always
|
|
target: 0.0,
|
|
expectedAlertSample: v3.Point{Value: 0.0},
|
|
expectedVectorValues: []float64{0.0},
|
|
},
|
|
{
|
|
values: pql.Series{
|
|
Floats: []pql.FPoint{
|
|
{F: 0.0},
|
|
{F: 0.0},
|
|
{F: 0.0},
|
|
{F: 0.0},
|
|
{F: 1.0},
|
|
},
|
|
},
|
|
expectAlert: false,
|
|
compareOp: "3", // Equals
|
|
matchType: "2", // Always
|
|
target: 0.0,
|
|
expectedVectorValues: []float64{},
|
|
},
|
|
{
|
|
values: pql.Series{
|
|
Floats: []pql.FPoint{
|
|
{F: 0.0},
|
|
{F: 1.0},
|
|
{F: 0.0},
|
|
{F: 1.0},
|
|
{F: 1.0},
|
|
},
|
|
},
|
|
expectAlert: false,
|
|
compareOp: "3", // Equals
|
|
matchType: "2", // Always
|
|
target: 0.0,
|
|
expectedVectorValues: []float64{},
|
|
},
|
|
{
|
|
values: pql.Series{
|
|
Floats: []pql.FPoint{
|
|
{F: 1.0},
|
|
{F: 1.0},
|
|
{F: 1.0},
|
|
{F: 1.0},
|
|
{F: 1.0},
|
|
},
|
|
},
|
|
expectAlert: false,
|
|
compareOp: "3", // Equals
|
|
matchType: "2", // Always
|
|
target: 0.0,
|
|
},
|
|
// Test cases for Equals Once
|
|
{
|
|
values: pql.Series{
|
|
Floats: []pql.FPoint{
|
|
{F: 0.0},
|
|
{F: 0.0},
|
|
{F: 0.0},
|
|
{F: 0.0},
|
|
{F: 0.0},
|
|
},
|
|
},
|
|
expectAlert: true,
|
|
compareOp: "3", // Equals
|
|
matchType: "1", // Once
|
|
target: 0.0,
|
|
expectedAlertSample: v3.Point{Value: 0.0},
|
|
expectedVectorValues: []float64{0.0},
|
|
},
|
|
{
|
|
values: pql.Series{
|
|
Floats: []pql.FPoint{
|
|
{F: 0.0},
|
|
{F: 0.0},
|
|
{F: 0.0},
|
|
{F: 0.0},
|
|
{F: 1.0},
|
|
},
|
|
},
|
|
expectAlert: true,
|
|
compareOp: "3", // Equals
|
|
matchType: "1", // Once
|
|
target: 0.0,
|
|
expectedAlertSample: v3.Point{Value: 0.0},
|
|
},
|
|
{
|
|
values: pql.Series{
|
|
Floats: []pql.FPoint{
|
|
{F: 0.0},
|
|
{F: 1.0},
|
|
{F: 0.0},
|
|
{F: 1.0},
|
|
{F: 1.0},
|
|
},
|
|
},
|
|
expectAlert: true,
|
|
compareOp: "3", // Equals
|
|
matchType: "1", // Once
|
|
target: 0.0,
|
|
expectedAlertSample: v3.Point{Value: 0.0},
|
|
},
|
|
{
|
|
values: pql.Series{
|
|
Floats: []pql.FPoint{
|
|
{F: 1.0},
|
|
{F: 1.0},
|
|
{F: 1.0},
|
|
{F: 1.0},
|
|
{F: 1.0},
|
|
},
|
|
},
|
|
expectAlert: false,
|
|
compareOp: "3", // Equals
|
|
matchType: "1", // Once
|
|
target: 0.0,
|
|
expectedVectorValues: []float64{},
|
|
},
|
|
// Test cases for Greater Than Always
|
|
{
|
|
values: pql.Series{
|
|
Floats: []pql.FPoint{
|
|
{F: 10.0},
|
|
{F: 4.0},
|
|
{F: 6.0},
|
|
{F: 8.0},
|
|
{F: 2.0},
|
|
},
|
|
},
|
|
expectAlert: true,
|
|
compareOp: "1", // Greater Than
|
|
matchType: "2", // Always
|
|
target: 1.5,
|
|
expectedAlertSample: v3.Point{Value: 2.0},
|
|
expectedVectorValues: []float64{2.0},
|
|
},
|
|
{
|
|
values: pql.Series{
|
|
Floats: []pql.FPoint{
|
|
{F: 11.0},
|
|
{F: 4.0},
|
|
{F: 3.0},
|
|
{F: 7.0},
|
|
{F: 12.0},
|
|
},
|
|
},
|
|
expectAlert: true,
|
|
compareOp: "1", // Above
|
|
matchType: "2", // Always
|
|
target: 2.0,
|
|
expectedAlertSample: v3.Point{Value: 3.0},
|
|
},
|
|
{
|
|
values: pql.Series{
|
|
Floats: []pql.FPoint{
|
|
{F: 11.0},
|
|
{F: 4.0},
|
|
{F: 3.0},
|
|
{F: 7.0},
|
|
{F: 12.0},
|
|
},
|
|
},
|
|
expectAlert: true,
|
|
compareOp: "2", // Below
|
|
matchType: "2", // Always
|
|
target: 13.0,
|
|
expectedAlertSample: v3.Point{Value: 12.0},
|
|
},
|
|
{
|
|
values: pql.Series{
|
|
Floats: []pql.FPoint{
|
|
{F: 10.0},
|
|
{F: 4.0},
|
|
{F: 6.0},
|
|
{F: 8.0},
|
|
{F: 2.0},
|
|
},
|
|
},
|
|
expectAlert: false,
|
|
compareOp: "1", // Greater Than
|
|
matchType: "2", // Always
|
|
target: 4.5,
|
|
},
|
|
// Test cases for Greater Than Once
|
|
{
|
|
values: pql.Series{
|
|
Floats: []pql.FPoint{
|
|
{F: 10.0},
|
|
{F: 4.0},
|
|
{F: 6.0},
|
|
{F: 8.0},
|
|
{F: 2.0},
|
|
},
|
|
},
|
|
expectAlert: true,
|
|
compareOp: "1", // Greater Than
|
|
matchType: "1", // Once
|
|
target: 4.5,
|
|
expectedAlertSample: v3.Point{Value: 10.0},
|
|
expectedVectorValues: []float64{10.0},
|
|
},
|
|
{
|
|
values: pql.Series{
|
|
Floats: []pql.FPoint{
|
|
{F: 4.0},
|
|
{F: 4.0},
|
|
{F: 4.0},
|
|
{F: 4.0},
|
|
{F: 4.0},
|
|
},
|
|
},
|
|
expectAlert: false,
|
|
compareOp: "1", // Greater Than
|
|
matchType: "1", // Once
|
|
target: 4.5,
|
|
},
|
|
// Test cases for Not Equals Always
|
|
{
|
|
values: pql.Series{
|
|
Floats: []pql.FPoint{
|
|
{F: 0.0},
|
|
{F: 1.0},
|
|
{F: 0.0},
|
|
{F: 1.0},
|
|
{F: 0.0},
|
|
},
|
|
},
|
|
expectAlert: false,
|
|
compareOp: "4", // Not Equals
|
|
matchType: "2", // Always
|
|
target: 0.0,
|
|
},
|
|
{
|
|
values: pql.Series{
|
|
Floats: []pql.FPoint{
|
|
{F: 1.0},
|
|
{F: 1.0},
|
|
{F: 1.0},
|
|
{F: 1.0},
|
|
{F: 0.0},
|
|
},
|
|
},
|
|
expectAlert: false,
|
|
compareOp: "4", // Not Equals
|
|
matchType: "2", // Always
|
|
target: 0.0,
|
|
},
|
|
{
|
|
values: pql.Series{
|
|
Floats: []pql.FPoint{
|
|
{F: 1.0},
|
|
{F: 1.0},
|
|
{F: 1.0},
|
|
{F: 1.0},
|
|
{F: 1.0},
|
|
},
|
|
},
|
|
expectAlert: true,
|
|
compareOp: "4", // Not Equals
|
|
matchType: "2", // Always
|
|
target: 0.0,
|
|
expectedAlertSample: v3.Point{Value: 1.0},
|
|
},
|
|
{
|
|
values: pql.Series{
|
|
Floats: []pql.FPoint{
|
|
{F: 1.0},
|
|
{F: 0.0},
|
|
{F: 1.0},
|
|
{F: 1.0},
|
|
{F: 1.0},
|
|
},
|
|
},
|
|
expectAlert: false,
|
|
compareOp: "4", // Not Equals
|
|
matchType: "2", // Always
|
|
target: 0.0,
|
|
},
|
|
// Test cases for Not Equals Once
|
|
{
|
|
values: pql.Series{
|
|
Floats: []pql.FPoint{
|
|
{F: 0.0},
|
|
{F: 1.0},
|
|
{F: 0.0},
|
|
{F: 1.0},
|
|
{F: 0.0},
|
|
},
|
|
},
|
|
expectAlert: true,
|
|
compareOp: "4", // Not Equals
|
|
matchType: "1", // Once
|
|
target: 0.0,
|
|
expectedAlertSample: v3.Point{Value: 1.0},
|
|
},
|
|
{
|
|
values: pql.Series{
|
|
Floats: []pql.FPoint{
|
|
{F: 0.0},
|
|
{F: 0.0},
|
|
{F: 0.0},
|
|
{F: 0.0},
|
|
{F: 0.0},
|
|
},
|
|
},
|
|
expectAlert: false,
|
|
compareOp: "4", // Not Equals
|
|
matchType: "1", // Once
|
|
target: 0.0,
|
|
},
|
|
{
|
|
values: pql.Series{
|
|
Floats: []pql.FPoint{
|
|
{F: 0.0},
|
|
{F: 0.0},
|
|
{F: 1.0},
|
|
{F: 0.0},
|
|
{F: 1.0},
|
|
},
|
|
},
|
|
expectAlert: true,
|
|
compareOp: "4", // Not Equals
|
|
matchType: "1", // Once
|
|
target: 0.0,
|
|
expectedAlertSample: v3.Point{Value: 1.0},
|
|
},
|
|
{
|
|
values: pql.Series{
|
|
Floats: []pql.FPoint{
|
|
{F: 1.0},
|
|
{F: 1.0},
|
|
{F: 1.0},
|
|
{F: 1.0},
|
|
{F: 1.0},
|
|
},
|
|
},
|
|
expectAlert: true,
|
|
compareOp: "4", // Not Equals
|
|
matchType: "1", // Once
|
|
target: 0.0,
|
|
expectedAlertSample: v3.Point{Value: 1.0},
|
|
},
|
|
// Test cases for Less Than Always
|
|
{
|
|
values: pql.Series{
|
|
Floats: []pql.FPoint{
|
|
{F: 1.5},
|
|
{F: 1.5},
|
|
{F: 1.5},
|
|
{F: 1.5},
|
|
{F: 1.5},
|
|
},
|
|
},
|
|
expectAlert: true,
|
|
compareOp: "2", // Less Than
|
|
matchType: "2", // Always
|
|
target: 4,
|
|
expectedAlertSample: v3.Point{Value: 1.5},
|
|
},
|
|
{
|
|
values: pql.Series{
|
|
Floats: []pql.FPoint{
|
|
{F: 4.5},
|
|
{F: 4.5},
|
|
{F: 4.5},
|
|
{F: 4.5},
|
|
{F: 4.5},
|
|
},
|
|
},
|
|
expectAlert: false,
|
|
compareOp: "2", // Less Than
|
|
matchType: "2", // Always
|
|
target: 4,
|
|
},
|
|
// Test cases for Less Than Once
|
|
{
|
|
values: pql.Series{
|
|
Floats: []pql.FPoint{
|
|
{F: 4.5},
|
|
{F: 4.5},
|
|
{F: 4.5},
|
|
{F: 4.5},
|
|
{F: 2.5},
|
|
},
|
|
},
|
|
expectAlert: true,
|
|
compareOp: "2", // Less Than
|
|
matchType: "1", // Once
|
|
target: 4,
|
|
expectedAlertSample: v3.Point{Value: 2.5},
|
|
},
|
|
{
|
|
values: pql.Series{
|
|
Floats: []pql.FPoint{
|
|
{F: 4.5},
|
|
{F: 4.5},
|
|
{F: 4.5},
|
|
{F: 4.5},
|
|
{F: 4.5},
|
|
},
|
|
},
|
|
expectAlert: false,
|
|
compareOp: "2", // Less Than
|
|
matchType: "1", // Once
|
|
target: 4,
|
|
},
|
|
// Test cases for OnAverage
|
|
{
|
|
values: pql.Series{
|
|
Floats: []pql.FPoint{
|
|
{F: 10.0},
|
|
{F: 4.0},
|
|
{F: 6.0},
|
|
{F: 8.0},
|
|
{F: 2.0},
|
|
},
|
|
},
|
|
expectAlert: true,
|
|
compareOp: "3", // Equals
|
|
matchType: "3", // OnAverage
|
|
target: 6.0,
|
|
expectedAlertSample: v3.Point{Value: 6.0},
|
|
},
|
|
{
|
|
values: pql.Series{
|
|
Floats: []pql.FPoint{
|
|
{F: 10.0},
|
|
{F: 4.0},
|
|
{F: 6.0},
|
|
{F: 8.0},
|
|
{F: 2.0},
|
|
},
|
|
},
|
|
expectAlert: false,
|
|
compareOp: "3", // Equals
|
|
matchType: "3", // OnAverage
|
|
target: 4.5,
|
|
},
|
|
{
|
|
values: pql.Series{
|
|
Floats: []pql.FPoint{
|
|
{F: 10.0},
|
|
{F: 4.0},
|
|
{F: 6.0},
|
|
{F: 8.0},
|
|
{F: 2.0},
|
|
},
|
|
},
|
|
expectAlert: true,
|
|
compareOp: "4", // Not Equals
|
|
matchType: "3", // OnAverage
|
|
target: 4.5,
|
|
expectedAlertSample: v3.Point{Value: 6.0},
|
|
},
|
|
{
|
|
values: pql.Series{
|
|
Floats: []pql.FPoint{
|
|
{F: 10.0},
|
|
{F: 4.0},
|
|
{F: 6.0},
|
|
{F: 8.0},
|
|
{F: 2.0},
|
|
},
|
|
},
|
|
expectAlert: false,
|
|
compareOp: "4", // Not Equals
|
|
matchType: "3", // OnAverage
|
|
target: 6.0,
|
|
},
|
|
{
|
|
values: pql.Series{
|
|
Floats: []pql.FPoint{
|
|
{F: 10.0},
|
|
{F: 4.0},
|
|
{F: 6.0},
|
|
{F: 8.0},
|
|
{F: 2.0},
|
|
},
|
|
},
|
|
expectAlert: true,
|
|
compareOp: "1", // Greater Than
|
|
matchType: "3", // OnAverage
|
|
target: 4.5,
|
|
expectedAlertSample: v3.Point{Value: 6.0},
|
|
},
|
|
{
|
|
values: pql.Series{
|
|
Floats: []pql.FPoint{
|
|
{F: 10.0},
|
|
{F: 4.0},
|
|
{F: 6.0},
|
|
{F: 8.0},
|
|
{F: 2.0},
|
|
},
|
|
},
|
|
expectAlert: true,
|
|
compareOp: "2", // Less Than
|
|
matchType: "3", // OnAverage
|
|
target: 12.0,
|
|
expectedAlertSample: v3.Point{Value: 6.0},
|
|
},
|
|
// Test cases for InTotal
|
|
{
|
|
values: pql.Series{
|
|
Floats: []pql.FPoint{
|
|
{F: 10.0},
|
|
{F: 4.0},
|
|
{F: 6.0},
|
|
{F: 8.0},
|
|
{F: 2.0},
|
|
},
|
|
},
|
|
expectAlert: true,
|
|
compareOp: "3", // Equals
|
|
matchType: "4", // InTotal
|
|
target: 30.0,
|
|
expectedAlertSample: v3.Point{Value: 30.0},
|
|
},
|
|
{
|
|
values: pql.Series{
|
|
Floats: []pql.FPoint{
|
|
{F: 10.0},
|
|
{F: 4.0},
|
|
{F: 6.0},
|
|
{F: 8.0},
|
|
{F: 2.0},
|
|
},
|
|
},
|
|
expectAlert: false,
|
|
compareOp: "3", // Equals
|
|
matchType: "4", // InTotal
|
|
target: 20.0,
|
|
},
|
|
{
|
|
values: pql.Series{
|
|
Floats: []pql.FPoint{
|
|
{F: 10.0},
|
|
},
|
|
},
|
|
expectAlert: true,
|
|
compareOp: "4", // Not Equals
|
|
matchType: "4", // InTotal
|
|
target: 9.0,
|
|
expectedAlertSample: v3.Point{Value: 10.0},
|
|
},
|
|
{
|
|
values: pql.Series{
|
|
Floats: []pql.FPoint{
|
|
{F: 10.0},
|
|
},
|
|
},
|
|
expectAlert: false,
|
|
compareOp: "4", // Not Equals
|
|
matchType: "4", // InTotal
|
|
target: 10.0,
|
|
},
|
|
{
|
|
values: pql.Series{
|
|
Floats: []pql.FPoint{
|
|
{F: 10.0},
|
|
{F: 10.0},
|
|
},
|
|
},
|
|
expectAlert: true,
|
|
compareOp: "1", // Greater Than
|
|
matchType: "4", // InTotal
|
|
target: 10.0,
|
|
expectedAlertSample: v3.Point{Value: 20.0},
|
|
},
|
|
{
|
|
values: pql.Series{
|
|
Floats: []pql.FPoint{
|
|
{F: 10.0},
|
|
{F: 10.0},
|
|
},
|
|
},
|
|
expectAlert: false,
|
|
compareOp: "1", // Greater Than
|
|
matchType: "4", // InTotal
|
|
target: 20.0,
|
|
},
|
|
{
|
|
values: pql.Series{
|
|
Floats: []pql.FPoint{
|
|
{F: 10.0},
|
|
{F: 10.0},
|
|
},
|
|
},
|
|
expectAlert: true,
|
|
compareOp: "2", // Less Than
|
|
matchType: "4", // InTotal
|
|
target: 30.0,
|
|
expectedAlertSample: v3.Point{Value: 20.0},
|
|
},
|
|
{
|
|
values: pql.Series{
|
|
Floats: []pql.FPoint{
|
|
{F: 10.0},
|
|
{F: 10.0},
|
|
},
|
|
},
|
|
expectAlert: false,
|
|
compareOp: "2", // Less Than
|
|
matchType: "4", // InTotal
|
|
target: 20.0,
|
|
},
|
|
}
|
|
|
|
logger := instrumentationtest.New().Logger()
|
|
|
|
for idx, c := range cases {
|
|
postableRule.RuleCondition.CompareOp = ruletypes.CompareOp(c.compareOp)
|
|
postableRule.RuleCondition.MatchType = ruletypes.MatchType(c.matchType)
|
|
postableRule.RuleCondition.Target = &c.target
|
|
postableRule.RuleCondition.Thresholds = &ruletypes.RuleThresholdData{
|
|
Kind: ruletypes.BasicThresholdKind,
|
|
Spec: ruletypes.BasicRuleThresholds{
|
|
{
|
|
TargetValue: &c.target,
|
|
MatchType: ruletypes.MatchType(c.matchType),
|
|
CompareOp: ruletypes.CompareOp(c.compareOp),
|
|
},
|
|
},
|
|
}
|
|
|
|
rule, err := NewPromRule("69", valuer.GenerateUUID(), &postableRule, logger, nil, nil)
|
|
if err != nil {
|
|
assert.NoError(t, err)
|
|
}
|
|
|
|
resultVectors, err := rule.Threshold.ShouldAlert(toCommonSeries(c.values), rule.Unit())
|
|
assert.NoError(t, err)
|
|
|
|
// Compare full result vector with expected vector
|
|
actualValues := getVectorValues(resultVectors)
|
|
if c.expectedVectorValues != nil {
|
|
// If expected vector values are specified, compare them exactly
|
|
assert.Equal(t, c.expectedVectorValues, actualValues, "Result vector values don't match expected for case %d", idx)
|
|
} else {
|
|
// Fallback to the old logic for cases without expectedVectorValues
|
|
if c.expectAlert {
|
|
assert.NotEmpty(t, resultVectors, "Expected alert but got no result vectors for case %d", idx)
|
|
// Verify at least one of the result vectors matches the expected alert sample
|
|
if len(resultVectors) > 0 {
|
|
found := false
|
|
for _, sample := range resultVectors {
|
|
if sample.V == c.expectedAlertSample.Value {
|
|
found = true
|
|
break
|
|
}
|
|
}
|
|
assert.True(t, found, "Expected alert sample value %.2f not found in result vectors for case %d. Got values: %v", c.expectedAlertSample.Value, idx, actualValues)
|
|
}
|
|
} else {
|
|
assert.Empty(t, resultVectors, "Expected no alert but got result vectors for case %d", idx)
|
|
}
|
|
}
|
|
|
|
}
|
|
}
|