From acfa066ba293b33b35f911e04f2129ce9f8367f4 Mon Sep 17 00:00:00 2001 From: George Robinson Date: Wed, 9 Nov 2022 16:07:43 +0000 Subject: [PATCH] Alerting: Change TestConditionsCmd to assert on mathexp.Results (#58434) --- pkg/expr/classic/classic_test.go | 496 +++++++++++++++---------------- pkg/expr/mathexp/types.go | 4 + 2 files changed, 246 insertions(+), 254 deletions(-) diff --git a/pkg/expr/classic/classic_test.go b/pkg/expr/classic/classic_test.go index 21be1ab8503..19ff3a3d589 100644 --- a/pkg/expr/classic/classic_test.go +++ b/pkg/expr/classic/classic_test.go @@ -15,300 +15,288 @@ import ( func TestConditionsCmd(t *testing.T) { tests := []struct { - name string - vars mathexp.Vars - conditionsCmd *ConditionsCmd - resultNumber func() mathexp.Number - }{ - { - name: "single query and single condition", - vars: mathexp.Vars{ - "A": mathexp.Results{ - Values: []mathexp.Value{ - valBasedSeries(ptr.Float64(30), ptr.Float64(40)), - }, + name string + cmd *ConditionsCmd + vars mathexp.Vars + expected func() mathexp.Results + }{{ + name: "single query and single condition", + vars: mathexp.Vars{ + "A": mathexp.Results{ + Values: []mathexp.Value{ + valBasedSeries(ptr.Float64(30), ptr.Float64(40)), }, }, - conditionsCmd: &ConditionsCmd{ - Conditions: []condition{ - { - InputRefID: "A", - Reducer: reducer("avg"), - Operator: "and", - Evaluator: &thresholdEvaluator{Type: "gt", Threshold: 34}, - }, - }}, - resultNumber: func() mathexp.Number { - v := valBasedNumber(ptr.Float64(1)) - v.SetMeta([]EvalMatch{{Value: ptr.Float64(35)}}) - return v - }, }, - { - name: "single query and single condition - empty series", - vars: mathexp.Vars{ - "A": mathexp.Results{ - Values: []mathexp.Value{ - valBasedSeries(), - }, + cmd: &ConditionsCmd{ + Conditions: []condition{ + { + InputRefID: "A", + Reducer: reducer("avg"), + Operator: "and", + Evaluator: &thresholdEvaluator{Type: "gt", Threshold: 34}, + }, + }}, + expected: func() mathexp.Results { + v := valBasedNumber(ptr.Float64(1)) + v.SetMeta([]EvalMatch{{Value: ptr.Float64(35)}}) + return mathexp.NewResults(v) + }, + }, { + name: "single query and single condition - empty series", + vars: mathexp.Vars{ + "A": mathexp.Results{ + Values: []mathexp.Value{ + valBasedSeries(), }, - }, - conditionsCmd: &ConditionsCmd{ - Conditions: []condition{ - { - InputRefID: "A", - Reducer: reducer("avg"), - Operator: "and", - Evaluator: &thresholdEvaluator{Type: "gt", Threshold: 34}, - }, - }}, - resultNumber: func() mathexp.Number { - v := valBasedNumber(nil) - v.SetMeta([]EvalMatch{{Metric: "NoData"}}) - return v }, }, - { - name: "single query and single condition - empty series and not empty series", - vars: mathexp.Vars{ - "A": mathexp.Results{ - Values: []mathexp.Value{ - valBasedSeries(), - valBasedSeries(ptr.Float64(3)), - }, + cmd: &ConditionsCmd{ + Conditions: []condition{ + { + InputRefID: "A", + Reducer: reducer("avg"), + Operator: "and", + Evaluator: &thresholdEvaluator{Type: "gt", Threshold: 34}, + }, + }}, + expected: func() mathexp.Results { + v := valBasedNumber(nil) + v.SetMeta([]EvalMatch{{Metric: "NoData"}}) + return mathexp.NewResults(v) + }, + }, { + name: "single query and single condition - empty series and not empty series", + vars: mathexp.Vars{ + "A": mathexp.Results{ + Values: []mathexp.Value{ + valBasedSeries(), + valBasedSeries(ptr.Float64(3)), }, - }, - conditionsCmd: &ConditionsCmd{ - Conditions: []condition{ - { - InputRefID: "A", - Reducer: reducer("avg"), - Operator: "and", - Evaluator: &thresholdEvaluator{Type: "gt", Threshold: .5}, - }, - }}, - resultNumber: func() mathexp.Number { - v := valBasedNumber(ptr.Float64(1)) - v.SetMeta([]EvalMatch{{Value: ptr.Float64(3)}}) - return v }, }, - { - name: "single query and two conditions", - vars: mathexp.Vars{ - "A": mathexp.Results{ - Values: []mathexp.Value{ - valBasedSeries(ptr.Float64(30), ptr.Float64(40)), - }, + cmd: &ConditionsCmd{ + Conditions: []condition{ + { + InputRefID: "A", + Reducer: reducer("avg"), + Operator: "and", + Evaluator: &thresholdEvaluator{Type: "gt", Threshold: .5}, + }, + }}, + expected: func() mathexp.Results { + v := valBasedNumber(ptr.Float64(1)) + v.SetMeta([]EvalMatch{{Value: ptr.Float64(3)}}) + return mathexp.NewResults(v) + }, + }, { + name: "single query and two conditions", + vars: mathexp.Vars{ + "A": mathexp.Results{ + Values: []mathexp.Value{ + valBasedSeries(ptr.Float64(30), ptr.Float64(40)), }, - }, - conditionsCmd: &ConditionsCmd{ - Conditions: []condition{ - { - InputRefID: "A", - Reducer: reducer("max"), - Evaluator: &thresholdEvaluator{Type: "gt", Threshold: 34}, - }, - { - InputRefID: "A", - Reducer: reducer("min"), - Operator: "or", - Evaluator: &thresholdEvaluator{Type: "gt", Threshold: 12}, - }, - }}, - resultNumber: func() mathexp.Number { - v := valBasedNumber(ptr.Float64(1)) - v.SetMeta([]EvalMatch{{Value: ptr.Float64(40)}, {Value: ptr.Float64(30)}}) - return v }, }, - { - name: "single query and single condition - multiple series (one true, one not == true)", - vars: mathexp.Vars{ - "A": mathexp.Results{ - Values: []mathexp.Value{ - valBasedSeriesWithLabels(data.Labels{"h": "1"}, ptr.Float64(30), ptr.Float64(40)), - valBasedSeries(ptr.Float64(0), ptr.Float64(10)), - }, + cmd: &ConditionsCmd{ + Conditions: []condition{ + { + InputRefID: "A", + Reducer: reducer("max"), + Evaluator: &thresholdEvaluator{Type: "gt", Threshold: 34}, + }, + { + InputRefID: "A", + Reducer: reducer("min"), + Operator: "or", + Evaluator: &thresholdEvaluator{Type: "gt", Threshold: 12}, + }, + }}, + expected: func() mathexp.Results { + v := valBasedNumber(ptr.Float64(1)) + v.SetMeta([]EvalMatch{{Value: ptr.Float64(40)}, {Value: ptr.Float64(30)}}) + return mathexp.NewResults(v) + }, + }, { + name: "single query and single condition - multiple series (one true, one not == true)", + vars: mathexp.Vars{ + "A": mathexp.Results{ + Values: []mathexp.Value{ + valBasedSeriesWithLabels(data.Labels{"h": "1"}, ptr.Float64(30), ptr.Float64(40)), + valBasedSeries(ptr.Float64(0), ptr.Float64(10)), }, - }, - conditionsCmd: &ConditionsCmd{ - Conditions: []condition{ - { - InputRefID: "A", - Reducer: reducer("avg"), - Operator: "and", - Evaluator: &thresholdEvaluator{Type: "gt", Threshold: 34}, - }, - }}, - resultNumber: func() mathexp.Number { - v := valBasedNumber(ptr.Float64(1)) - v.SetMeta([]EvalMatch{{Value: ptr.Float64(35), Labels: data.Labels{"h": "1"}}}) - return v }, }, - { - name: "single query and single condition - multiple series (one not true, one true == true)", - vars: mathexp.Vars{ - "A": mathexp.Results{ - Values: []mathexp.Value{ - valBasedSeries(ptr.Float64(0), ptr.Float64(10)), - valBasedSeries(ptr.Float64(30), ptr.Float64(40)), - }, + cmd: &ConditionsCmd{ + Conditions: []condition{ + { + InputRefID: "A", + Reducer: reducer("avg"), + Operator: "and", + Evaluator: &thresholdEvaluator{Type: "gt", Threshold: 34}, + }, + }}, + expected: func() mathexp.Results { + v := valBasedNumber(ptr.Float64(1)) + v.SetMeta([]EvalMatch{{Value: ptr.Float64(35), Labels: data.Labels{"h": "1"}}}) + return mathexp.NewResults(v) + }, + }, { + name: "single query and single condition - multiple series (one not true, one true == true)", + vars: mathexp.Vars{ + "A": mathexp.Results{ + Values: []mathexp.Value{ + valBasedSeries(ptr.Float64(0), ptr.Float64(10)), + valBasedSeries(ptr.Float64(30), ptr.Float64(40)), }, - }, - conditionsCmd: &ConditionsCmd{ - Conditions: []condition{ - { - InputRefID: "A", - Reducer: reducer("avg"), - Operator: "and", - Evaluator: &thresholdEvaluator{Type: "gt", Threshold: 34}, - }, - }}, - resultNumber: func() mathexp.Number { - v := valBasedNumber(ptr.Float64(1)) - v.SetMeta([]EvalMatch{{Value: ptr.Float64(35)}}) - return v }, }, - { - name: "single query and single condition - multiple series (2 not true == false)", - vars: mathexp.Vars{ - "A": mathexp.Results{ - Values: []mathexp.Value{ - valBasedSeries(ptr.Float64(0), ptr.Float64(10)), - valBasedSeries(ptr.Float64(20), ptr.Float64(30)), - }, + cmd: &ConditionsCmd{ + Conditions: []condition{ + { + InputRefID: "A", + Reducer: reducer("avg"), + Operator: "and", + Evaluator: &thresholdEvaluator{Type: "gt", Threshold: 34}, + }, + }}, + expected: func() mathexp.Results { + v := valBasedNumber(ptr.Float64(1)) + v.SetMeta([]EvalMatch{{Value: ptr.Float64(35)}}) + return mathexp.NewResults(v) + }, + }, { + name: "single query and single condition - multiple series (2 not true == false)", + vars: mathexp.Vars{ + "A": mathexp.Results{ + Values: []mathexp.Value{ + valBasedSeries(ptr.Float64(0), ptr.Float64(10)), + valBasedSeries(ptr.Float64(20), ptr.Float64(30)), }, - }, - conditionsCmd: &ConditionsCmd{ - Conditions: []condition{ - { - InputRefID: "A", - Reducer: reducer("avg"), - Operator: "and", - Evaluator: &thresholdEvaluator{Type: "gt", Threshold: 34}, - }, - }}, - resultNumber: func() mathexp.Number { - v := valBasedNumber(ptr.Float64(0)) - v.SetMeta([]EvalMatch{}) - return v }, }, - { - name: "single query and single ranged condition", - vars: mathexp.Vars{ - "A": mathexp.Results{ - Values: []mathexp.Value{ - valBasedSeries(ptr.Float64(30), ptr.Float64(40)), - }, + cmd: &ConditionsCmd{ + Conditions: []condition{ + { + InputRefID: "A", + Reducer: reducer("avg"), + Operator: "and", + Evaluator: &thresholdEvaluator{Type: "gt", Threshold: 34}, }, - }, - conditionsCmd: &ConditionsCmd{ - Conditions: []condition{ - { - InputRefID: "A", - Reducer: reducer("diff"), - Operator: "and", - Evaluator: &rangedEvaluator{Type: "within_range", Lower: 2, Upper: 3}, - }, + }}, + expected: func() mathexp.Results { + v := valBasedNumber(ptr.Float64(0)) + v.SetMeta([]EvalMatch{}) + return mathexp.Results{Values: mathexp.Values{v}} + }, + }, { + name: "single query and single ranged condition", + vars: mathexp.Vars{ + "A": mathexp.Results{ + Values: []mathexp.Value{ + valBasedSeries(ptr.Float64(30), ptr.Float64(40)), }, }, - resultNumber: func() mathexp.Number { - v := valBasedNumber(ptr.Float64(0)) - v.SetMeta([]EvalMatch{}) - return v - }, }, - { - name: "single query with no data", - vars: mathexp.Vars{ - "A": mathexp.Results{ - Values: []mathexp.Value{mathexp.NoData{}.New()}, + cmd: &ConditionsCmd{ + Conditions: []condition{ + { + InputRefID: "A", + Reducer: reducer("diff"), + Operator: "and", + Evaluator: &rangedEvaluator{Type: "within_range", Lower: 2, Upper: 3}, }, }, - conditionsCmd: &ConditionsCmd{ - Conditions: []condition{ - { - InputRefID: "A", - Reducer: reducer("avg"), - Operator: "and", - Evaluator: &thresholdEvaluator{"gt", 1}, - }, - }, - }, - resultNumber: func() mathexp.Number { - v := valBasedNumber(nil) - v.SetMeta([]EvalMatch{{Metric: "NoData"}}) - return v - }, }, - { - name: "single query with no values", - vars: mathexp.Vars{ - "A": mathexp.Results{ - Values: []mathexp.Value{}, - }, - }, - conditionsCmd: &ConditionsCmd{ - Conditions: []condition{ - { - InputRefID: "A", - Reducer: reducer("avg"), - Operator: "and", - Evaluator: &thresholdEvaluator{"gt", 1}, - }, - }, - }, - resultNumber: func() mathexp.Number { - v := valBasedNumber(nil) - v.SetMeta([]EvalMatch{{Metric: "NoData"}}) - return v + expected: func() mathexp.Results { + v := valBasedNumber(ptr.Float64(0)) + v.SetMeta([]EvalMatch{}) + return mathexp.NewResults(v) + }, + }, { + name: "single query with no data", + vars: mathexp.Vars{ + "A": mathexp.Results{ + Values: []mathexp.Value{mathexp.NoData{}.New()}, }, }, - { - name: "should accept numbers", - vars: mathexp.Vars{ - "A": mathexp.Results{ - Values: []mathexp.Value{ - valBasedNumber(ptr.Float64(5)), - valBasedNumber(ptr.Float64(10)), - valBasedNumber(ptr.Float64(15)), - }, + cmd: &ConditionsCmd{ + Conditions: []condition{ + { + InputRefID: "A", + Reducer: reducer("avg"), + Operator: "and", + Evaluator: &thresholdEvaluator{"gt", 1}, }, }, - conditionsCmd: &ConditionsCmd{ - Conditions: []condition{ - { - InputRefID: "A", - Reducer: reducer("avg"), - Operator: "and", - Evaluator: &thresholdEvaluator{"gt", 1}, - }, - }, - }, - resultNumber: func() mathexp.Number { - v := valBasedNumber(ptr.Float64(1)) - v.SetMeta([]EvalMatch{ - {Value: ptr.Float64(5)}, - {Value: ptr.Float64(10)}, - {Value: ptr.Float64(15)}, - }) - return v - }, }, - } + expected: func() mathexp.Results { + v := valBasedNumber(nil) + v.SetMeta([]EvalMatch{{Metric: "NoData"}}) + return mathexp.NewResults(v) + }, + }, { + name: "single query with no values", + vars: mathexp.Vars{ + "A": mathexp.Results{ + Values: []mathexp.Value{}, + }, + }, + cmd: &ConditionsCmd{ + Conditions: []condition{ + { + InputRefID: "A", + Reducer: reducer("avg"), + Operator: "and", + Evaluator: &thresholdEvaluator{"gt", 1}, + }, + }, + }, + expected: func() mathexp.Results { + v := valBasedNumber(nil) + v.SetMeta([]EvalMatch{{Metric: "NoData"}}) + return mathexp.NewResults(v) + }, + }, { + name: "should accept numbers", + vars: mathexp.Vars{ + "A": mathexp.Results{ + Values: []mathexp.Value{ + valBasedNumber(ptr.Float64(5)), + valBasedNumber(ptr.Float64(10)), + valBasedNumber(ptr.Float64(15)), + }, + }, + }, + cmd: &ConditionsCmd{ + Conditions: []condition{ + { + InputRefID: "A", + Reducer: reducer("avg"), + Operator: "and", + Evaluator: &thresholdEvaluator{"gt", 1}, + }, + }, + }, + expected: func() mathexp.Results { + v := valBasedNumber(ptr.Float64(1)) + v.SetMeta([]EvalMatch{ + {Value: ptr.Float64(5)}, + {Value: ptr.Float64(10)}, + {Value: ptr.Float64(15)}, + }) + return mathexp.NewResults(v) + }, + }} for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - res, err := tt.conditionsCmd.Execute(context.Background(), time.Now(), tt.vars) + res, err := tt.cmd.Execute(context.Background(), time.Now(), tt.vars) require.NoError(t, err) require.Equal(t, 1, len(res.Values)) - require.Equal(t, tt.resultNumber(), res.Values[0]) + require.Equal(t, tt.expected(), res) }) } } diff --git a/pkg/expr/mathexp/types.go b/pkg/expr/mathexp/types.go index 3e020d85d5a..8c668e8b8ee 100644 --- a/pkg/expr/mathexp/types.go +++ b/pkg/expr/mathexp/types.go @@ -11,6 +11,10 @@ type Results struct { Values Values } +func NewResults(values ...Value) Results { + return Results{Values: values} +} + // Values is a slice of Value interfaces type Values []Value