From 4b417c8f3e7d77b6d790d77432bb8e60f634fdef Mon Sep 17 00:00:00 2001 From: Yuriy Tseretyan Date: Wed, 27 Apr 2022 14:59:13 -0400 Subject: [PATCH] use NaN if condition value is nil (#48370) --- pkg/services/ngalert/state/state.go | 7 ++- pkg/services/ngalert/state/state_test.go | 75 ++++++++++++++++++++++++ 2 files changed, 81 insertions(+), 1 deletion(-) diff --git a/pkg/services/ngalert/state/state.go b/pkg/services/ngalert/state/state.go index cf5c5b849d2..4684c70cce8 100644 --- a/pkg/services/ngalert/state/state.go +++ b/pkg/services/ngalert/state/state.go @@ -3,6 +3,7 @@ package state import ( "errors" "fmt" + "math" "strings" "time" @@ -223,7 +224,11 @@ func (a *State) GetLastEvaluationValuesForCondition() map[string]float64 { for refID, value := range lastResult.Values { if strings.Contains(refID, lastResult.Condition) { - r[refID] = *value + if value != nil { + r[refID] = *value + continue + } + r[refID] = math.NaN() } } diff --git a/pkg/services/ngalert/state/state_test.go b/pkg/services/ngalert/state/state_test.go index b5a3ee1e54d..d1d455f56ce 100644 --- a/pkg/services/ngalert/state/state_test.go +++ b/pkg/services/ngalert/state/state_test.go @@ -1,10 +1,14 @@ package state import ( + "math" "math/rand" "testing" "time" + "github.com/stretchr/testify/require" + ptr "github.com/xorcare/pointer" + "github.com/grafana/grafana/pkg/services/ngalert/eval" ngmodels "github.com/grafana/grafana/pkg/services/ngalert/models" @@ -230,3 +234,74 @@ func TestSetEndsAt(t *testing.T) { }) } } + +func TestGetLastEvaluationValuesForCondition(t *testing.T) { + genState := func(results []Evaluation) *State { + return &State{ + Results: results, + } + } + + t.Run("should return nil if no results", func(t *testing.T) { + result := genState(nil).GetLastEvaluationValuesForCondition() + require.Nil(t, result) + }) + t.Run("should return value of the condition of the last result", func(t *testing.T) { + expected := rand.Float64() + evals := []Evaluation{ + { + EvaluationTime: time.Time{}, + EvaluationState: 0, + Values: map[string]*float64{ + "A": ptr.Float64(rand.Float64()), + }, + Condition: "A", + }, + { + EvaluationTime: time.Time{}, + EvaluationState: 0, + Values: map[string]*float64{ + "B": ptr.Float64(rand.Float64()), + "A": ptr.Float64(expected), + }, + Condition: "A", + }, + } + result := genState(evals).GetLastEvaluationValuesForCondition() + require.Len(t, result, 1) + require.Contains(t, result, "A") + require.Equal(t, result["A"], expected) + }) + t.Run("should return empty map if there is no value for condition", func(t *testing.T) { + evals := []Evaluation{ + { + EvaluationTime: time.Time{}, + EvaluationState: 0, + Values: map[string]*float64{ + "C": ptr.Float64(rand.Float64()), + }, + Condition: "A", + }, + } + result := genState(evals).GetLastEvaluationValuesForCondition() + require.NotNil(t, result) + require.Len(t, result, 0) + }) + t.Run("should use NaN if value is not defined", func(t *testing.T) { + evals := []Evaluation{ + { + EvaluationTime: time.Time{}, + EvaluationState: 0, + Values: map[string]*float64{ + "A": nil, + }, + Condition: "A", + }, + } + result := genState(evals).GetLastEvaluationValuesForCondition() + require.NotNil(t, result) + require.Len(t, result, 1) + require.Contains(t, result, "A") + require.Truef(t, math.IsNaN(result["A"]), "expected NaN but got %v", result["A"]) + }) +}