فهرست منبع

fix(alerting): fixes bug that prevents noData from triggering

closes #6631
bergquist 9 سال پیش
والد
کامیت
50811c80ea
2فایلهای تغییر یافته به همراه42 افزوده شده و 1 حذف شده
  1. 4 0
      pkg/services/alerting/eval_handler.go
  2. 38 1
      pkg/services/alerting/eval_handler_test.go

+ 4 - 0
pkg/services/alerting/eval_handler.go

@@ -23,6 +23,7 @@ func NewEvalHandler() *DefaultEvalHandler {
 
 func (e *DefaultEvalHandler) Eval(context *EvalContext) {
 	firing := true
+	noDataFound := true
 	conditionEvals := ""
 
 	for i := 0; i < len(context.Rule.Conditions); i++ {
@@ -40,8 +41,10 @@ func (e *DefaultEvalHandler) Eval(context *EvalContext) {
 		// calculating Firing based on operator
 		if cr.Operator == "or" {
 			firing = firing || cr.Firing
+			noDataFound = noDataFound || cr.NoDataFound
 		} else {
 			firing = firing && cr.Firing
+			noDataFound = noDataFound && cr.NoDataFound
 		}
 
 		if i > 0 {
@@ -55,6 +58,7 @@ func (e *DefaultEvalHandler) Eval(context *EvalContext) {
 
 	context.ConditionEvals = conditionEvals + " = " + strconv.FormatBool(firing)
 	context.Firing = firing
+	context.NoDataFound = noDataFound
 	context.EndTime = time.Now()
 	elapsedTime := context.EndTime.Sub(context.StartTime) / time.Millisecond
 	metrics.M_Alerting_Exeuction_Time.Update(elapsedTime)

+ 38 - 1
pkg/services/alerting/eval_handler_test.go

@@ -11,10 +11,11 @@ type conditionStub struct {
 	firing   bool
 	operator string
 	matches  []*EvalMatch
+	noData   bool
 }
 
 func (c *conditionStub) Eval(context *EvalContext) (*ConditionResult, error) {
-	return &ConditionResult{Firing: c.firing, EvalMatches: c.matches, Operator: c.operator}, nil
+	return &ConditionResult{Firing: c.firing, EvalMatches: c.matches, Operator: c.operator, NoDataFound: c.noData}, nil
 }
 
 func TestAlertingExecutor(t *testing.T) {
@@ -127,5 +128,41 @@ func TestAlertingExecutor(t *testing.T) {
 			So(context.Firing, ShouldEqual, true)
 			So(context.ConditionEvals, ShouldEqual, "[[true OR false] OR true] = true")
 		})
+
+		Convey("Should return no data if one condition has nodata", func() {
+			context := NewEvalContext(context.TODO(), &Rule{
+				Conditions: []Condition{
+					&conditionStub{operator: "and", noData: true},
+				},
+			})
+
+			handler.Eval(context)
+			So(context.Firing, ShouldEqual, false)
+			So(context.NoDataFound, ShouldBeTrue)
+		})
+
+		Convey("Should return no data if both conditions have no data and using AND", func() {
+			context := NewEvalContext(context.TODO(), &Rule{
+				Conditions: []Condition{
+					&conditionStub{operator: "and", noData: true},
+					&conditionStub{operator: "and", noData: false},
+				},
+			})
+
+			handler.Eval(context)
+			So(context.NoDataFound, ShouldBeFalse)
+		})
+
+		Convey("Should not return no data if both conditions have no data and using OR", func() {
+			context := NewEvalContext(context.TODO(), &Rule{
+				Conditions: []Condition{
+					&conditionStub{operator: "or", noData: true},
+					&conditionStub{operator: "or", noData: false},
+				},
+			})
+
+			handler.Eval(context)
+			So(context.NoDataFound, ShouldBeTrue)
+		})
 	})
 }