diff --git a/pkg/services/ngalert/api/api_prometheus_test.go b/pkg/services/ngalert/api/api_prometheus_test.go index e08152d7441..bfbbf235b05 100644 --- a/pkg/services/ngalert/api/api_prometheus_test.go +++ b/pkg/services/ngalert/api/api_prometheus_test.go @@ -47,9 +47,7 @@ func Test_FormatValues(t *testing.T) { name: "with no value, it renders the evaluation string", alertState: &state.State{ LastEvaluationString: "[ var='A' metric='vector(10) + time() % 50' labels={} value=1.1 ]", - Results: []state.Evaluation{ - {Condition: "A", Values: map[string]*float64{}}, - }, + LatestResult: &state.Evaluation{Condition: "A", Values: map[string]*float64{}}, }, expected: "[ var='A' metric='vector(10) + time() % 50' labels={} value=1.1 ]", }, @@ -57,9 +55,7 @@ func Test_FormatValues(t *testing.T) { name: "with one value, it renders the single value", alertState: &state.State{ LastEvaluationString: "[ var='A' metric='vector(10) + time() % 50' labels={} value=1.1 ]", - Results: []state.Evaluation{ - {Condition: "A", Values: map[string]*float64{"A": &val1}}, - }, + LatestResult: &state.Evaluation{Condition: "A", Values: map[string]*float64{"A": &val1}}, }, expected: "1.1e+00", }, @@ -67,9 +63,7 @@ func Test_FormatValues(t *testing.T) { name: "with two values, it renders the value based on their refID and position", alertState: &state.State{ LastEvaluationString: "[ var='B0' metric='vector(10) + time() % 50' labels={} value=1.1 ], [ var='B1' metric='vector(10) + time() % 50' labels={} value=1.4 ]", - Results: []state.Evaluation{ - {Condition: "B", Values: map[string]*float64{"B0": &val1, "B1": &val2}}, - }, + LatestResult: &state.Evaluation{Condition: "B", Values: map[string]*float64{"B0": &val1, "B1": &val2}}, }, expected: "B0: 1.1e+00, B1: 1.4e+00", }, @@ -77,9 +71,7 @@ func Test_FormatValues(t *testing.T) { name: "with a high number of values, it renders the value based on their refID and position using a natural order", alertState: &state.State{ LastEvaluationString: "[ var='B0' metric='vector(10) + time() % 50' labels={} value=1.1 ], [ var='B1' metric='vector(10) + time() % 50' labels={} value=1.4 ]", - Results: []state.Evaluation{ - {Condition: "B", Values: map[string]*float64{"B0": &val1, "B1": &val2, "B2": &val1, "B10": &val2, "B11": &val1}}, - }, + LatestResult: &state.Evaluation{Condition: "B", Values: map[string]*float64{"B0": &val1, "B1": &val2, "B2": &val1, "B10": &val2, "B11": &val1}}, }, expected: "B0: 1.1e+00, B10: 1.4e+00, B11: 1.1e+00, B1: 1.4e+00, B2: 1.1e+00", }, @@ -248,12 +240,12 @@ func withAlertingState() forEachState { return func(s *state.State) *state.State { s.State = eval.Alerting value := float64(1.1) - s.Results = append(s.Results, state.Evaluation{ + s.LatestResult = &state.Evaluation{ EvaluationState: eval.Alerting, EvaluationTime: timeNow(), Values: map[string]*float64{"B": &value}, Condition: "B", - }) + } return s } } diff --git a/pkg/services/ngalert/api/testing.go b/pkg/services/ngalert/api/testing.go index 2e9b2cee6e0..93434729e2f 100644 --- a/pkg/services/ngalert/api/testing.go +++ b/pkg/services/ngalert/api/testing.go @@ -83,17 +83,10 @@ func (f *fakeAlertInstanceManager) GenerateAlertInstances(orgID int64, alertRule "instance_label": "test", }, State: eval.Normal, - Results: []state.Evaluation{ - { - EvaluationTime: evaluationTime, - EvaluationState: eval.Normal, - Values: make(map[string]*float64), - }, - { - EvaluationTime: evaluationTime.Add(1 * time.Minute), - EvaluationState: eval.Normal, - Values: make(map[string]*float64), - }, + LatestResult: &state.Evaluation{ + EvaluationTime: evaluationTime.Add(1 * time.Minute), + EvaluationState: eval.Normal, + Values: make(map[string]*float64), }, LastEvaluationTime: evaluationTime.Add(1 * time.Minute), EvaluationDuration: evaluationDuration, diff --git a/pkg/services/ngalert/schedule/alert_rule_test.go b/pkg/services/ngalert/schedule/alert_rule_test.go index f910376cfba..f1ed576736a 100644 --- a/pkg/services/ngalert/schedule/alert_rule_test.go +++ b/pkg/services/ngalert/schedule/alert_rule_test.go @@ -308,13 +308,13 @@ func TestRuleRoutine(t *testing.T) { require.Len(t, states, 1) s := states[0] require.Equal(t, rule.UID, s.AlertRuleUID) - require.Len(t, s.Results, 1) + require.NotNil(t, s.LatestResult) var expectedStatus = evalState if evalState == eval.Pending { expectedStatus = eval.Alerting } - require.Equal(t, expectedStatus.String(), s.Results[0].EvaluationState.String()) - require.Equal(t, expectedTime, s.Results[0].EvaluationTime) + require.Equal(t, expectedStatus.String(), s.LatestResult.EvaluationState.String()) + require.Equal(t, expectedTime, s.LatestResult.EvaluationTime) }) t.Run("it should save alert instances to storage", func(t *testing.T) { // TODO rewrite when we are able to mock/fake state manager diff --git a/pkg/services/ngalert/state/manager.go b/pkg/services/ngalert/state/manager.go index da6d614ff5e..5c447afbb38 100644 --- a/pkg/services/ngalert/state/manager.go +++ b/pkg/services/ngalert/state/manager.go @@ -355,14 +355,13 @@ func (st *Manager) setNextState(ctx context.Context, alertRule *ngModels.AlertRu currentState.LastEvaluationTime = result.EvaluatedAt currentState.EvaluationDuration = result.EvaluationDuration - currentState.Results = append(currentState.Results, Evaluation{ + currentState.LatestResult = &Evaluation{ EvaluationTime: result.EvaluatedAt, EvaluationState: result.State, Values: NewEvaluationValues(result.Values), Condition: alertRule.Condition, - }) + } currentState.LastEvaluationString = result.EvaluationString - currentState.TrimResults(alertRule) oldState := currentState.State oldReason := currentState.StateReason diff --git a/pkg/services/ngalert/state/manager_private_test.go b/pkg/services/ngalert/state/manager_private_test.go index 798b37a0720..6db71cf15e9 100644 --- a/pkg/services/ngalert/state/manager_private_test.go +++ b/pkg/services/ngalert/state/manager_private_test.go @@ -153,8 +153,8 @@ func TestProcessEvalResults_StateTransitions(t *testing.T) { return r } - newEvaluation := func(evalTime time.Time, evalState eval.State) Evaluation { - return Evaluation{ + newEvaluation := func(evalTime time.Time, evalState eval.State) *Evaluation { + return &Evaluation{ EvaluationTime: evalTime, EvaluationState: evalState, Values: make(map[string]*float64), @@ -329,11 +329,9 @@ func TestProcessEvalResults_StateTransitions(t *testing.T) { { PreviousState: eval.Normal, State: &State{ - Labels: labels["system + rule + labels1"], - State: eval.Normal, - Results: []Evaluation{ - newEvaluation(t1, eval.Normal), - }, + Labels: labels["system + rule + labels1"], + State: eval.Normal, + LatestResult: newEvaluation(t1, eval.Normal), StartsAt: t1, EndsAt: t1, LastEvaluationTime: t1, @@ -342,11 +340,9 @@ func TestProcessEvalResults_StateTransitions(t *testing.T) { { PreviousState: eval.Normal, State: &State{ - Labels: labels["system + rule + labels2"], - State: eval.Normal, - Results: []Evaluation{ - newEvaluation(t1, eval.Normal), - }, + Labels: labels["system + rule + labels2"], + State: eval.Normal, + LatestResult: newEvaluation(t1, eval.Normal), StartsAt: t1, EndsAt: t1, LastEvaluationTime: t1, @@ -369,11 +365,9 @@ func TestProcessEvalResults_StateTransitions(t *testing.T) { { PreviousState: eval.Normal, State: &State{ - Labels: labels["system + rule + labels1"], - State: eval.Alerting, - Results: []Evaluation{ - newEvaluation(t1, eval.Alerting), - }, + Labels: labels["system + rule + labels1"], + State: eval.Alerting, + LatestResult: newEvaluation(t1, eval.Alerting), StartsAt: t1, EndsAt: t1.Add(ResendDelay * 4), LastEvaluationTime: t1, @@ -382,11 +376,9 @@ func TestProcessEvalResults_StateTransitions(t *testing.T) { { PreviousState: eval.Normal, State: &State{ - Labels: labels["system + rule + labels2"], - State: eval.Normal, - Results: []Evaluation{ - newEvaluation(t1, eval.Normal), - }, + Labels: labels["system + rule + labels2"], + State: eval.Normal, + LatestResult: newEvaluation(t1, eval.Normal), StartsAt: t1, EndsAt: t1, LastEvaluationTime: t1, @@ -409,11 +401,9 @@ func TestProcessEvalResults_StateTransitions(t *testing.T) { { PreviousState: eval.Normal, State: &State{ - Labels: labels["system + rule + labels1"], - State: eval.Pending, - Results: []Evaluation{ - newEvaluation(t1, eval.Alerting), - }, + Labels: labels["system + rule + labels1"], + State: eval.Pending, + LatestResult: newEvaluation(t1, eval.Alerting), StartsAt: t1, EndsAt: t1.Add(ResendDelay * 4), LastEvaluationTime: t1, @@ -422,11 +412,9 @@ func TestProcessEvalResults_StateTransitions(t *testing.T) { { PreviousState: eval.Normal, State: &State{ - Labels: labels["system + rule + labels2"], - State: eval.Normal, - Results: []Evaluation{ - newEvaluation(t1, eval.Normal), - }, + Labels: labels["system + rule + labels2"], + State: eval.Normal, + LatestResult: newEvaluation(t1, eval.Normal), StartsAt: t1, EndsAt: t1, LastEvaluationTime: t1, @@ -453,12 +441,9 @@ func TestProcessEvalResults_StateTransitions(t *testing.T) { { PreviousState: eval.Normal, State: &State{ - Labels: labels["system + rule + labels1"], - State: eval.Alerting, - Results: []Evaluation{ - newEvaluation(t1, eval.Normal), - newEvaluation(t2, eval.Alerting), - }, + Labels: labels["system + rule + labels1"], + State: eval.Alerting, + LatestResult: newEvaluation(t2, eval.Alerting), StartsAt: t2, EndsAt: t2.Add(ResendDelay * 4), LastEvaluationTime: t2, @@ -467,12 +452,9 @@ func TestProcessEvalResults_StateTransitions(t *testing.T) { { PreviousState: eval.Normal, State: &State{ - Labels: labels["system + rule + labels2"], - State: eval.Normal, - Results: []Evaluation{ - newEvaluation(t1, eval.Normal), - newEvaluation(t2, eval.Normal), - }, + Labels: labels["system + rule + labels2"], + State: eval.Normal, + LatestResult: newEvaluation(t2, eval.Normal), StartsAt: t1, EndsAt: t1, LastEvaluationTime: t2, @@ -500,11 +482,9 @@ func TestProcessEvalResults_StateTransitions(t *testing.T) { { PreviousState: eval.Normal, State: &State{ - Labels: labels["system + rule + labels1"], - State: eval.Pending, - Results: []Evaluation{ - newEvaluation(t1, eval.Alerting), - }, + Labels: labels["system + rule + labels1"], + State: eval.Pending, + LatestResult: newEvaluation(t1, eval.Alerting), StartsAt: t1, EndsAt: t1.Add(ResendDelay * 4), LastEvaluationTime: t1, @@ -515,12 +495,9 @@ func TestProcessEvalResults_StateTransitions(t *testing.T) { { PreviousState: eval.Pending, State: &State{ - Labels: labels["system + rule + labels1"], - State: eval.Pending, - Results: []Evaluation{ - newEvaluation(t1, eval.Alerting), - newEvaluation(t2, eval.Alerting), - }, + Labels: labels["system + rule + labels1"], + State: eval.Pending, + LatestResult: newEvaluation(t2, eval.Alerting), StartsAt: t1, EndsAt: t1.Add(ResendDelay * 4), // TODO probably it should be t1 (semantic of Normal)? LastEvaluationTime: t2, @@ -531,12 +508,9 @@ func TestProcessEvalResults_StateTransitions(t *testing.T) { { PreviousState: eval.Pending, State: &State{ - Labels: labels["system + rule + labels1"], - State: eval.Alerting, - Results: []Evaluation{ - newEvaluation(t2, eval.Alerting), - newEvaluation(t3, eval.Alerting), - }, + Labels: labels["system + rule + labels1"], + State: eval.Alerting, + LatestResult: newEvaluation(t3, eval.Alerting), StartsAt: t3, EndsAt: t3.Add(ResendDelay * 4), LastEvaluationTime: t3, @@ -561,12 +535,9 @@ func TestProcessEvalResults_StateTransitions(t *testing.T) { { PreviousState: eval.Pending, State: &State{ - Labels: labels["system + rule + labels1"], - State: eval.Normal, - Results: []Evaluation{ - newEvaluation(t1, eval.Alerting), - newEvaluation(t2, eval.Normal), - }, + Labels: labels["system + rule + labels1"], + State: eval.Normal, + LatestResult: newEvaluation(t2, eval.Normal), StartsAt: t2, EndsAt: t2, LastEvaluationTime: t2, @@ -590,12 +561,9 @@ func TestProcessEvalResults_StateTransitions(t *testing.T) { t2: {{ PreviousState: eval.Alerting, State: &State{ - Labels: labels["system + rule + labels1"], - State: eval.Normal, - Results: []Evaluation{ - newEvaluation(t1, eval.Alerting), - newEvaluation(t2, eval.Normal), - }, + Labels: labels["system + rule + labels1"], + State: eval.Normal, + LatestResult: newEvaluation(t2, eval.Normal), StartsAt: t2, EndsAt: t2, LastEvaluationTime: t2, @@ -626,12 +594,9 @@ func TestProcessEvalResults_StateTransitions(t *testing.T) { { PreviousState: eval.Normal, State: &State{ - Labels: labels["system + rule + labels3"], - State: eval.Normal, - Results: []Evaluation{ - newEvaluation(t1, eval.Normal), - newEvaluation(t2, eval.Normal), - }, + Labels: labels["system + rule + labels3"], + State: eval.Normal, + LatestResult: newEvaluation(t2, eval.Normal), StartsAt: t1, EndsAt: t1, LastEvaluationTime: t2, @@ -642,12 +607,10 @@ func TestProcessEvalResults_StateTransitions(t *testing.T) { { PreviousState: eval.Normal, State: &State{ - Labels: labels["system + rule + labels1"], - State: eval.Normal, - StateReason: ngmodels.StateReasonMissingSeries, - Results: []Evaluation{ - newEvaluation(t1, eval.Normal), - }, + Labels: labels["system + rule + labels1"], + State: eval.Normal, + StateReason: ngmodels.StateReasonMissingSeries, + LatestResult: newEvaluation(t1, eval.Normal), StartsAt: t1, EndsAt: t3, LastEvaluationTime: t3, @@ -656,12 +619,10 @@ func TestProcessEvalResults_StateTransitions(t *testing.T) { { PreviousState: eval.Alerting, State: &State{ - Labels: labels["system + rule + labels2"], - State: eval.Normal, - StateReason: ngmodels.StateReasonMissingSeries, - Results: []Evaluation{ - newEvaluation(t1, eval.Alerting), - }, + Labels: labels["system + rule + labels2"], + State: eval.Normal, + StateReason: ngmodels.StateReasonMissingSeries, + LatestResult: newEvaluation(t1, eval.Alerting), StartsAt: t1, EndsAt: t3, LastEvaluationTime: t3, @@ -671,13 +632,9 @@ func TestProcessEvalResults_StateTransitions(t *testing.T) { { PreviousState: eval.Normal, State: &State{ - Labels: labels["system + rule + labels3"], - State: eval.Normal, - Results: []Evaluation{ - newEvaluation(t1, eval.Normal), - newEvaluation(t2, eval.Normal), - newEvaluation(t3, eval.Normal), - }, + Labels: labels["system + rule + labels3"], + State: eval.Normal, + LatestResult: newEvaluation(t3, eval.Normal), StartsAt: t1, EndsAt: t1, LastEvaluationTime: t3, @@ -699,11 +656,9 @@ func TestProcessEvalResults_StateTransitions(t *testing.T) { { PreviousState: eval.Normal, State: &State{ - Labels: labels["system + rule"], - State: eval.Normal, - Results: []Evaluation{ - newEvaluation(t1, eval.Normal), - }, + Labels: labels["system + rule"], + State: eval.Normal, + LatestResult: newEvaluation(t1, eval.Normal), StartsAt: t1, EndsAt: t1, LastEvaluationTime: t1, @@ -725,11 +680,9 @@ func TestProcessEvalResults_StateTransitions(t *testing.T) { { PreviousState: eval.Normal, State: &State{ - Labels: labels["system + rule"], - State: eval.Alerting, - Results: []Evaluation{ - newEvaluation(t1, eval.Alerting), - }, + Labels: labels["system + rule"], + State: eval.Alerting, + LatestResult: newEvaluation(t1, eval.Alerting), StartsAt: t1, EndsAt: t1.Add(ResendDelay * 4), LastEvaluationTime: t1, @@ -751,11 +704,9 @@ func TestProcessEvalResults_StateTransitions(t *testing.T) { { PreviousState: eval.Normal, State: &State{ - Labels: labels["system + rule"], - State: eval.Pending, - Results: []Evaluation{ - newEvaluation(t1, eval.Alerting), - }, + Labels: labels["system + rule"], + State: eval.Pending, + LatestResult: newEvaluation(t1, eval.Alerting), StartsAt: t1, EndsAt: t1.Add(ResendDelay * 4), LastEvaluationTime: t1, @@ -780,12 +731,9 @@ func TestProcessEvalResults_StateTransitions(t *testing.T) { { PreviousState: eval.Normal, State: &State{ - Labels: labels["system + rule"], - State: eval.Alerting, - Results: []Evaluation{ - newEvaluation(t1, eval.Normal), - newEvaluation(t2, eval.Alerting), - }, + Labels: labels["system + rule"], + State: eval.Alerting, + LatestResult: newEvaluation(t2, eval.Alerting), StartsAt: t2, EndsAt: t2.Add(ResendDelay * 4), LastEvaluationTime: t2, @@ -872,11 +820,9 @@ func TestProcessEvalResults_StateTransitions(t *testing.T) { { PreviousState: eval.Normal, State: &State{ - Labels: labels["system + rule + no-data"], - State: eval.NoData, - Results: []Evaluation{ - newEvaluation(t1, eval.NoData), - }, + Labels: labels["system + rule + no-data"], + State: eval.NoData, + LatestResult: newEvaluation(t1, eval.NoData), StartsAt: t1, EndsAt: t1.Add(ResendDelay * 4), LastEvaluationTime: t1, @@ -889,12 +835,10 @@ func TestProcessEvalResults_StateTransitions(t *testing.T) { { PreviousState: eval.Normal, State: &State{ - Labels: labels["system + rule + no-data"], - State: eval.Alerting, - StateReason: eval.NoData.String(), - Results: []Evaluation{ - newEvaluation(t1, eval.NoData), - }, + Labels: labels["system + rule + no-data"], + State: eval.Alerting, + StateReason: eval.NoData.String(), + LatestResult: newEvaluation(t1, eval.NoData), StartsAt: t1, EndsAt: t1.Add(ResendDelay * 4), LastEvaluationTime: t1, @@ -907,12 +851,10 @@ func TestProcessEvalResults_StateTransitions(t *testing.T) { { PreviousState: eval.Normal, State: &State{ - Labels: labels["system + rule + no-data"], - State: eval.Normal, - StateReason: eval.NoData.String(), - Results: []Evaluation{ - newEvaluation(t1, eval.NoData), - }, + Labels: labels["system + rule + no-data"], + State: eval.Normal, + StateReason: eval.NoData.String(), + LatestResult: newEvaluation(t1, eval.NoData), StartsAt: t1, EndsAt: t1, LastEvaluationTime: t1, @@ -925,12 +867,10 @@ func TestProcessEvalResults_StateTransitions(t *testing.T) { { PreviousState: eval.Normal, State: &State{ - Labels: labels["system + rule + no-data"], - State: eval.Normal, - StateReason: ngmodels.ConcatReasons(eval.NoData.String(), ngmodels.StateReasonKeepLast), - Results: []Evaluation{ - newEvaluation(t1, eval.NoData), - }, + Labels: labels["system + rule + no-data"], + State: eval.Normal, + StateReason: ngmodels.ConcatReasons(eval.NoData.String(), ngmodels.StateReasonKeepLast), + LatestResult: newEvaluation(t1, eval.NoData), StartsAt: t1, EndsAt: t1, LastEvaluationTime: t1, @@ -956,11 +896,9 @@ func TestProcessEvalResults_StateTransitions(t *testing.T) { { PreviousState: eval.Normal, State: &State{ - Labels: labels["system + rule + no-data"], - State: eval.NoData, - Results: []Evaluation{ - newEvaluation(t2, eval.NoData), - }, + Labels: labels["system + rule + no-data"], + State: eval.NoData, + LatestResult: newEvaluation(t2, eval.NoData), StartsAt: t2, EndsAt: t2.Add(ResendDelay * 4), LastEvaluationTime: t2, @@ -973,12 +911,10 @@ func TestProcessEvalResults_StateTransitions(t *testing.T) { { PreviousState: eval.Normal, State: &State{ - Labels: labels["system + rule + no-data"], - State: eval.Alerting, - StateReason: eval.NoData.String(), - Results: []Evaluation{ - newEvaluation(t2, eval.NoData), - }, + Labels: labels["system + rule + no-data"], + State: eval.Alerting, + StateReason: eval.NoData.String(), + LatestResult: newEvaluation(t2, eval.NoData), StartsAt: t2, EndsAt: t2.Add(ResendDelay * 4), LastEvaluationTime: t2, @@ -991,12 +927,10 @@ func TestProcessEvalResults_StateTransitions(t *testing.T) { { PreviousState: eval.Normal, State: &State{ - Labels: labels["system + rule + no-data"], - State: eval.Normal, - StateReason: eval.NoData.String(), - Results: []Evaluation{ - newEvaluation(t2, eval.NoData), - }, + Labels: labels["system + rule + no-data"], + State: eval.Normal, + StateReason: eval.NoData.String(), + LatestResult: newEvaluation(t2, eval.NoData), StartsAt: t2, EndsAt: t2, LastEvaluationTime: t2, @@ -1009,12 +943,10 @@ func TestProcessEvalResults_StateTransitions(t *testing.T) { { PreviousState: eval.Normal, State: &State{ - Labels: labels["system + rule + no-data"], - State: eval.Normal, - StateReason: ngmodels.ConcatReasons(eval.NoData.String(), ngmodels.StateReasonKeepLast), - Results: []Evaluation{ - newEvaluation(t2, eval.NoData), - }, + Labels: labels["system + rule + no-data"], + State: eval.Normal, + StateReason: ngmodels.ConcatReasons(eval.NoData.String(), ngmodels.StateReasonKeepLast), + LatestResult: newEvaluation(t2, eval.NoData), StartsAt: t2, EndsAt: t2, LastEvaluationTime: t2, @@ -1029,13 +961,10 @@ func TestProcessEvalResults_StateTransitions(t *testing.T) { { PreviousState: eval.Normal, State: &State{ - Labels: labels["system + rule + labels1"], - State: eval.Alerting, - StateReason: eval.NoData.String(), - Results: []Evaluation{ - newEvaluation(t1, eval.Normal), - newEvaluation(t2, eval.NoData), - }, + Labels: labels["system + rule + labels1"], + State: eval.Alerting, + StateReason: eval.NoData.String(), + LatestResult: newEvaluation(t2, eval.NoData), StartsAt: t2, EndsAt: t2.Add(ResendDelay * 4), LastEvaluationTime: t2, @@ -1048,13 +977,10 @@ func TestProcessEvalResults_StateTransitions(t *testing.T) { { PreviousState: eval.Normal, State: &State{ - Labels: labels["system + rule + labels1"], - State: eval.Normal, - StateReason: eval.NoData.String(), - Results: []Evaluation{ - newEvaluation(t1, eval.Normal), - newEvaluation(t2, eval.NoData), - }, + Labels: labels["system + rule + labels1"], + State: eval.Normal, + StateReason: eval.NoData.String(), + LatestResult: newEvaluation(t2, eval.NoData), StartsAt: t1, EndsAt: t1, LastEvaluationTime: t2, @@ -1067,13 +993,10 @@ func TestProcessEvalResults_StateTransitions(t *testing.T) { { PreviousState: eval.Normal, State: &State{ - Labels: labels["system + rule + labels1"], - State: eval.Normal, - StateReason: ngmodels.ConcatReasons(eval.NoData.String(), ngmodels.StateReasonKeepLast), - Results: []Evaluation{ - newEvaluation(t1, eval.Normal), - newEvaluation(t2, eval.NoData), - }, + Labels: labels["system + rule + labels1"], + State: eval.Normal, + StateReason: ngmodels.ConcatReasons(eval.NoData.String(), ngmodels.StateReasonKeepLast), + LatestResult: newEvaluation(t2, eval.NoData), StartsAt: t1, EndsAt: t1, LastEvaluationTime: t2, @@ -1103,11 +1026,9 @@ func TestProcessEvalResults_StateTransitions(t *testing.T) { { PreviousState: eval.Normal, State: &State{ - Labels: labels["system + rule + no-data"], - State: eval.NoData, - Results: []Evaluation{ - newEvaluation(t2, eval.NoData), - }, + Labels: labels["system + rule + no-data"], + State: eval.NoData, + LatestResult: newEvaluation(t2, eval.NoData), StartsAt: t2, EndsAt: t2.Add(ResendDelay * 4), LastEvaluationTime: t2, @@ -1118,12 +1039,10 @@ func TestProcessEvalResults_StateTransitions(t *testing.T) { { PreviousState: eval.Normal, State: &State{ - Labels: labels["system + rule + labels1"], - State: eval.Normal, - StateReason: ngmodels.StateReasonMissingSeries, - Results: []Evaluation{ - newEvaluation(t1, eval.Normal), - }, + Labels: labels["system + rule + labels1"], + State: eval.Normal, + StateReason: ngmodels.StateReasonMissingSeries, + LatestResult: newEvaluation(t1, eval.Normal), StartsAt: t1, EndsAt: t3, LastEvaluationTime: t3, @@ -1132,12 +1051,10 @@ func TestProcessEvalResults_StateTransitions(t *testing.T) { { PreviousState: eval.Alerting, State: &State{ - Labels: labels["system + rule + labels2"], - State: eval.Normal, - StateReason: ngmodels.StateReasonMissingSeries, - Results: []Evaluation{ - newEvaluation(t1, eval.Alerting), - }, + Labels: labels["system + rule + labels2"], + State: eval.Normal, + StateReason: ngmodels.StateReasonMissingSeries, + LatestResult: newEvaluation(t1, eval.Alerting), StartsAt: t1, EndsAt: t3, LastEvaluationTime: t3, @@ -1147,12 +1064,9 @@ func TestProcessEvalResults_StateTransitions(t *testing.T) { { PreviousState: eval.NoData, State: &State{ - Labels: labels["system + rule + no-data"], - State: eval.NoData, - Results: []Evaluation{ - newEvaluation(t2, eval.NoData), - newEvaluation(t3, eval.NoData), - }, + Labels: labels["system + rule + no-data"], + State: eval.NoData, + LatestResult: newEvaluation(t3, eval.NoData), StartsAt: t2, EndsAt: t3.Add(ResendDelay * 4), LastEvaluationTime: t3, @@ -1165,12 +1079,10 @@ func TestProcessEvalResults_StateTransitions(t *testing.T) { { PreviousState: eval.Normal, State: &State{ - Labels: labels["system + rule + labels1"], - State: eval.Normal, - StateReason: ngmodels.StateReasonMissingSeries, - Results: []Evaluation{ - newEvaluation(t1, eval.Normal), - }, + Labels: labels["system + rule + labels1"], + State: eval.Normal, + StateReason: ngmodels.StateReasonMissingSeries, + LatestResult: newEvaluation(t1, eval.Normal), StartsAt: t1, EndsAt: t3, LastEvaluationTime: t3, @@ -1179,12 +1091,10 @@ func TestProcessEvalResults_StateTransitions(t *testing.T) { { PreviousState: eval.Alerting, State: &State{ - Labels: labels["system + rule + labels2"], - State: eval.Normal, - StateReason: ngmodels.StateReasonMissingSeries, - Results: []Evaluation{ - newEvaluation(t1, eval.Alerting), - }, + Labels: labels["system + rule + labels2"], + State: eval.Normal, + StateReason: ngmodels.StateReasonMissingSeries, + LatestResult: newEvaluation(t1, eval.Alerting), StartsAt: t1, EndsAt: t3, LastEvaluationTime: t3, @@ -1195,13 +1105,10 @@ func TestProcessEvalResults_StateTransitions(t *testing.T) { PreviousState: eval.Alerting, PreviousStateReason: eval.NoData.String(), State: &State{ - Labels: labels["system + rule + no-data"], - State: eval.Alerting, - StateReason: eval.NoData.String(), - Results: []Evaluation{ - newEvaluation(t2, eval.NoData), - newEvaluation(t3, eval.NoData), - }, + Labels: labels["system + rule + no-data"], + State: eval.Alerting, + StateReason: eval.NoData.String(), + LatestResult: newEvaluation(t3, eval.NoData), StartsAt: t2, EndsAt: t3.Add(ResendDelay * 4), LastEvaluationTime: t3, @@ -1214,12 +1121,10 @@ func TestProcessEvalResults_StateTransitions(t *testing.T) { { PreviousState: eval.Normal, State: &State{ - Labels: labels["system + rule + labels1"], - State: eval.Normal, - StateReason: ngmodels.StateReasonMissingSeries, - Results: []Evaluation{ - newEvaluation(t1, eval.Normal), - }, + Labels: labels["system + rule + labels1"], + State: eval.Normal, + StateReason: ngmodels.StateReasonMissingSeries, + LatestResult: newEvaluation(t1, eval.Normal), StartsAt: t1, EndsAt: t3, LastEvaluationTime: t3, @@ -1228,12 +1133,10 @@ func TestProcessEvalResults_StateTransitions(t *testing.T) { { PreviousState: eval.Alerting, State: &State{ - Labels: labels["system + rule + labels2"], - State: eval.Normal, - StateReason: ngmodels.StateReasonMissingSeries, - Results: []Evaluation{ - newEvaluation(t1, eval.Alerting), - }, + Labels: labels["system + rule + labels2"], + State: eval.Normal, + StateReason: ngmodels.StateReasonMissingSeries, + LatestResult: newEvaluation(t1, eval.Alerting), StartsAt: t1, EndsAt: t3, LastEvaluationTime: t3, @@ -1244,13 +1147,10 @@ func TestProcessEvalResults_StateTransitions(t *testing.T) { PreviousState: eval.Normal, PreviousStateReason: eval.NoData.String(), State: &State{ - Labels: labels["system + rule + no-data"], - State: eval.Normal, - StateReason: eval.NoData.String(), - Results: []Evaluation{ - newEvaluation(t2, eval.NoData), - newEvaluation(t3, eval.NoData), - }, + Labels: labels["system + rule + no-data"], + State: eval.Normal, + StateReason: eval.NoData.String(), + LatestResult: newEvaluation(t3, eval.NoData), StartsAt: t2, EndsAt: t2, LastEvaluationTime: t3, @@ -1263,12 +1163,10 @@ func TestProcessEvalResults_StateTransitions(t *testing.T) { { PreviousState: eval.Normal, State: &State{ - Labels: labels["system + rule + labels1"], - State: eval.Normal, - StateReason: ngmodels.StateReasonMissingSeries, - Results: []Evaluation{ - newEvaluation(t1, eval.Normal), - }, + Labels: labels["system + rule + labels1"], + State: eval.Normal, + StateReason: ngmodels.StateReasonMissingSeries, + LatestResult: newEvaluation(t1, eval.Normal), StartsAt: t1, EndsAt: t3, LastEvaluationTime: t3, @@ -1277,12 +1175,10 @@ func TestProcessEvalResults_StateTransitions(t *testing.T) { { PreviousState: eval.Alerting, State: &State{ - Labels: labels["system + rule + labels2"], - State: eval.Normal, - StateReason: ngmodels.StateReasonMissingSeries, - Results: []Evaluation{ - newEvaluation(t1, eval.Alerting), - }, + Labels: labels["system + rule + labels2"], + State: eval.Normal, + StateReason: ngmodels.StateReasonMissingSeries, + LatestResult: newEvaluation(t1, eval.Alerting), StartsAt: t1, EndsAt: t3, LastEvaluationTime: t3, @@ -1293,13 +1189,10 @@ func TestProcessEvalResults_StateTransitions(t *testing.T) { PreviousState: eval.Normal, PreviousStateReason: ngmodels.ConcatReasons(eval.NoData.String(), ngmodels.StateReasonKeepLast), State: &State{ - Labels: labels["system + rule + no-data"], - State: eval.Normal, - StateReason: ngmodels.ConcatReasons(eval.NoData.String(), ngmodels.StateReasonKeepLast), - Results: []Evaluation{ - newEvaluation(t2, eval.NoData), - newEvaluation(t3, eval.NoData), - }, + Labels: labels["system + rule + no-data"], + State: eval.Normal, + StateReason: ngmodels.ConcatReasons(eval.NoData.String(), ngmodels.StateReasonKeepLast), + LatestResult: newEvaluation(t3, eval.NoData), StartsAt: t2, EndsAt: t2, LastEvaluationTime: t3, @@ -1314,13 +1207,10 @@ func TestProcessEvalResults_StateTransitions(t *testing.T) { { PreviousState: eval.Normal, State: &State{ - Labels: labels["system + rule + labels1"], - State: eval.Alerting, - StateReason: eval.NoData.String(), - Results: []Evaluation{ - newEvaluation(t1, eval.Normal), - newEvaluation(t2, eval.NoData), - }, + Labels: labels["system + rule + labels1"], + State: eval.Alerting, + StateReason: eval.NoData.String(), + LatestResult: newEvaluation(t2, eval.NoData), StartsAt: t2, EndsAt: t2.Add(ResendDelay * 4), LastEvaluationTime: t2, @@ -1329,13 +1219,10 @@ func TestProcessEvalResults_StateTransitions(t *testing.T) { { PreviousState: eval.Alerting, State: &State{ - Labels: labels["system + rule + labels2"], - State: eval.Alerting, - StateReason: eval.NoData.String(), - Results: []Evaluation{ - newEvaluation(t1, eval.Alerting), - newEvaluation(t2, eval.NoData), - }, + Labels: labels["system + rule + labels2"], + State: eval.Alerting, + StateReason: eval.NoData.String(), + LatestResult: newEvaluation(t2, eval.NoData), StartsAt: t1, EndsAt: t2.Add(ResendDelay * 4), LastEvaluationTime: t2, @@ -1347,14 +1234,10 @@ func TestProcessEvalResults_StateTransitions(t *testing.T) { PreviousState: eval.Alerting, PreviousStateReason: eval.NoData.String(), State: &State{ - Labels: labels["system + rule + labels1"], - State: eval.Alerting, - StateReason: eval.NoData.String(), - Results: []Evaluation{ - newEvaluation(t1, eval.Normal), - newEvaluation(t2, eval.NoData), - newEvaluation(t3, eval.NoData), - }, + Labels: labels["system + rule + labels1"], + State: eval.Alerting, + StateReason: eval.NoData.String(), + LatestResult: newEvaluation(t3, eval.NoData), StartsAt: t2, EndsAt: t3.Add(ResendDelay * 4), LastEvaluationTime: t3, @@ -1364,14 +1247,10 @@ func TestProcessEvalResults_StateTransitions(t *testing.T) { PreviousState: eval.Alerting, PreviousStateReason: eval.NoData.String(), State: &State{ - Labels: labels["system + rule + labels2"], - State: eval.Alerting, - StateReason: eval.NoData.String(), - Results: []Evaluation{ - newEvaluation(t1, eval.Alerting), - newEvaluation(t2, eval.NoData), - newEvaluation(t3, eval.NoData), - }, + Labels: labels["system + rule + labels2"], + State: eval.Alerting, + StateReason: eval.NoData.String(), + LatestResult: newEvaluation(t3, eval.NoData), StartsAt: t1, EndsAt: t3.Add(ResendDelay * 4), LastEvaluationTime: t3, @@ -1384,13 +1263,10 @@ func TestProcessEvalResults_StateTransitions(t *testing.T) { { PreviousState: eval.Normal, State: &State{ - Labels: labels["system + rule + labels1"], - State: eval.Normal, - StateReason: eval.NoData.String(), - Results: []Evaluation{ - newEvaluation(t1, eval.Normal), - newEvaluation(t2, eval.NoData), - }, + Labels: labels["system + rule + labels1"], + State: eval.Normal, + StateReason: eval.NoData.String(), + LatestResult: newEvaluation(t2, eval.NoData), StartsAt: t1, EndsAt: t1, LastEvaluationTime: t2, @@ -1399,13 +1275,10 @@ func TestProcessEvalResults_StateTransitions(t *testing.T) { { PreviousState: eval.Alerting, State: &State{ - Labels: labels["system + rule + labels2"], - State: eval.Normal, - StateReason: eval.NoData.String(), - Results: []Evaluation{ - newEvaluation(t1, eval.Alerting), - newEvaluation(t2, eval.NoData), - }, + Labels: labels["system + rule + labels2"], + State: eval.Normal, + StateReason: eval.NoData.String(), + LatestResult: newEvaluation(t2, eval.NoData), StartsAt: t2, EndsAt: t2, LastEvaluationTime: t2, @@ -1418,14 +1291,10 @@ func TestProcessEvalResults_StateTransitions(t *testing.T) { PreviousState: eval.Normal, PreviousStateReason: eval.NoData.String(), State: &State{ - Labels: labels["system + rule + labels1"], - State: eval.Normal, - StateReason: eval.NoData.String(), - Results: []Evaluation{ - newEvaluation(t1, eval.Normal), - newEvaluation(t2, eval.NoData), - newEvaluation(t3, eval.NoData), - }, + Labels: labels["system + rule + labels1"], + State: eval.Normal, + StateReason: eval.NoData.String(), + LatestResult: newEvaluation(t3, eval.NoData), StartsAt: t1, EndsAt: t1, LastEvaluationTime: t3, @@ -1435,14 +1304,10 @@ func TestProcessEvalResults_StateTransitions(t *testing.T) { PreviousState: eval.Normal, PreviousStateReason: eval.NoData.String(), State: &State{ - Labels: labels["system + rule + labels2"], - State: eval.Normal, - StateReason: eval.NoData.String(), - Results: []Evaluation{ - newEvaluation(t1, eval.Alerting), - newEvaluation(t2, eval.NoData), - newEvaluation(t3, eval.NoData), - }, + Labels: labels["system + rule + labels2"], + State: eval.Normal, + StateReason: eval.NoData.String(), + LatestResult: newEvaluation(t3, eval.NoData), StartsAt: t2, EndsAt: t2, LastEvaluationTime: t3, @@ -1455,13 +1320,10 @@ func TestProcessEvalResults_StateTransitions(t *testing.T) { { PreviousState: eval.Normal, State: &State{ - Labels: labels["system + rule + labels1"], - State: eval.Normal, - StateReason: ngmodels.ConcatReasons(eval.NoData.String(), ngmodels.StateReasonKeepLast), - Results: []Evaluation{ - newEvaluation(t1, eval.Normal), - newEvaluation(t2, eval.NoData), - }, + Labels: labels["system + rule + labels1"], + State: eval.Normal, + StateReason: ngmodels.ConcatReasons(eval.NoData.String(), ngmodels.StateReasonKeepLast), + LatestResult: newEvaluation(t2, eval.NoData), StartsAt: t1, EndsAt: t1, LastEvaluationTime: t2, @@ -1470,13 +1332,10 @@ func TestProcessEvalResults_StateTransitions(t *testing.T) { { PreviousState: eval.Alerting, State: &State{ - Labels: labels["system + rule + labels2"], - State: eval.Alerting, - StateReason: ngmodels.ConcatReasons(eval.NoData.String(), ngmodels.StateReasonKeepLast), - Results: []Evaluation{ - newEvaluation(t1, eval.Alerting), - newEvaluation(t2, eval.NoData), - }, + Labels: labels["system + rule + labels2"], + State: eval.Alerting, + StateReason: ngmodels.ConcatReasons(eval.NoData.String(), ngmodels.StateReasonKeepLast), + LatestResult: newEvaluation(t2, eval.NoData), StartsAt: t1, EndsAt: t2.Add(ResendDelay * 4), LastEvaluationTime: t2, @@ -1488,14 +1347,10 @@ func TestProcessEvalResults_StateTransitions(t *testing.T) { PreviousState: eval.Normal, PreviousStateReason: ngmodels.ConcatReasons(eval.NoData.String(), ngmodels.StateReasonKeepLast), State: &State{ - Labels: labels["system + rule + labels1"], - State: eval.Normal, - StateReason: ngmodels.ConcatReasons(eval.NoData.String(), ngmodels.StateReasonKeepLast), - Results: []Evaluation{ - newEvaluation(t1, eval.Normal), - newEvaluation(t2, eval.NoData), - newEvaluation(t3, eval.NoData), - }, + Labels: labels["system + rule + labels1"], + State: eval.Normal, + StateReason: ngmodels.ConcatReasons(eval.NoData.String(), ngmodels.StateReasonKeepLast), + LatestResult: newEvaluation(t3, eval.NoData), StartsAt: t1, EndsAt: t1, LastEvaluationTime: t3, @@ -1505,14 +1360,10 @@ func TestProcessEvalResults_StateTransitions(t *testing.T) { PreviousState: eval.Alerting, PreviousStateReason: ngmodels.ConcatReasons(eval.NoData.String(), ngmodels.StateReasonKeepLast), State: &State{ - Labels: labels["system + rule + labels2"], - State: eval.Alerting, - StateReason: ngmodels.ConcatReasons(eval.NoData.String(), ngmodels.StateReasonKeepLast), - Results: []Evaluation{ - newEvaluation(t1, eval.Alerting), - newEvaluation(t2, eval.NoData), - newEvaluation(t3, eval.NoData), - }, + Labels: labels["system + rule + labels2"], + State: eval.Alerting, + StateReason: ngmodels.ConcatReasons(eval.NoData.String(), ngmodels.StateReasonKeepLast), + LatestResult: newEvaluation(t3, eval.NoData), StartsAt: t1, EndsAt: t3.Add(ResendDelay * 4), LastEvaluationTime: t3, @@ -1543,11 +1394,9 @@ func TestProcessEvalResults_StateTransitions(t *testing.T) { { PreviousState: eval.Normal, State: &State{ - Labels: labels["system + rule + no-data"], - State: eval.NoData, - Results: []Evaluation{ - newEvaluation(t2, eval.NoData), - }, + Labels: labels["system + rule + no-data"], + State: eval.NoData, + LatestResult: newEvaluation(t2, eval.NoData), StartsAt: t2, EndsAt: t2.Add(ResendDelay * 4), LastEvaluationTime: t2, @@ -1558,12 +1407,10 @@ func TestProcessEvalResults_StateTransitions(t *testing.T) { { PreviousState: eval.Normal, State: &State{ - Labels: labels["system + rule + labels1"], - State: eval.Normal, - StateReason: ngmodels.StateReasonMissingSeries, - Results: []Evaluation{ - newEvaluation(t1, eval.Normal), - }, + Labels: labels["system + rule + labels1"], + State: eval.Normal, + StateReason: ngmodels.StateReasonMissingSeries, + LatestResult: newEvaluation(t1, eval.Normal), StartsAt: t1, EndsAt: t3, LastEvaluationTime: t3, @@ -1572,12 +1419,10 @@ func TestProcessEvalResults_StateTransitions(t *testing.T) { { PreviousState: eval.Pending, State: &State{ - Labels: labels["system + rule + labels2"], - State: eval.Normal, - StateReason: ngmodels.StateReasonMissingSeries, - Results: []Evaluation{ - newEvaluation(t1, eval.Alerting), - }, + Labels: labels["system + rule + labels2"], + State: eval.Normal, + StateReason: ngmodels.StateReasonMissingSeries, + LatestResult: newEvaluation(t1, eval.Alerting), StartsAt: t1, EndsAt: t3, LastEvaluationTime: t3, @@ -1586,11 +1431,9 @@ func TestProcessEvalResults_StateTransitions(t *testing.T) { { PreviousState: eval.NoData, State: &State{ - Labels: labels["system + rule + no-data"], - State: eval.NoData, - Results: []Evaluation{ - newEvaluation(t3, eval.NoData), - }, + Labels: labels["system + rule + no-data"], + State: eval.NoData, + LatestResult: newEvaluation(t3, eval.NoData), StartsAt: t2, EndsAt: t3.Add(ResendDelay * 4), LastEvaluationTime: t3, @@ -1603,12 +1446,10 @@ func TestProcessEvalResults_StateTransitions(t *testing.T) { { PreviousState: eval.Normal, State: &State{ - Labels: labels["system + rule + no-data"], - State: eval.Pending, - StateReason: eval.NoData.String(), - Results: []Evaluation{ - newEvaluation(t2, eval.NoData), - }, + Labels: labels["system + rule + no-data"], + State: eval.Pending, + StateReason: eval.NoData.String(), + LatestResult: newEvaluation(t2, eval.NoData), StartsAt: t2, EndsAt: t2.Add(ResendDelay * 4), LastEvaluationTime: t2, @@ -1619,12 +1460,10 @@ func TestProcessEvalResults_StateTransitions(t *testing.T) { { PreviousState: eval.Normal, State: &State{ - Labels: labels["system + rule + labels1"], - State: eval.Normal, - StateReason: ngmodels.StateReasonMissingSeries, - Results: []Evaluation{ - newEvaluation(t1, eval.Normal), - }, + Labels: labels["system + rule + labels1"], + State: eval.Normal, + StateReason: ngmodels.StateReasonMissingSeries, + LatestResult: newEvaluation(t1, eval.Normal), StartsAt: t1, EndsAt: t3, LastEvaluationTime: t3, @@ -1633,12 +1472,10 @@ func TestProcessEvalResults_StateTransitions(t *testing.T) { { PreviousState: eval.Pending, State: &State{ - Labels: labels["system + rule + labels2"], - State: eval.Normal, - StateReason: ngmodels.StateReasonMissingSeries, - Results: []Evaluation{ - newEvaluation(t1, eval.Alerting), - }, + Labels: labels["system + rule + labels2"], + State: eval.Normal, + StateReason: ngmodels.StateReasonMissingSeries, + LatestResult: newEvaluation(t1, eval.Alerting), StartsAt: t1, EndsAt: t3, LastEvaluationTime: t3, @@ -1648,12 +1485,10 @@ func TestProcessEvalResults_StateTransitions(t *testing.T) { PreviousState: eval.Pending, PreviousStateReason: eval.NoData.String(), State: &State{ - Labels: labels["system + rule + no-data"], - State: eval.Alerting, - StateReason: eval.NoData.String(), - Results: []Evaluation{ - newEvaluation(t3, eval.NoData), - }, + Labels: labels["system + rule + no-data"], + State: eval.Alerting, + StateReason: eval.NoData.String(), + LatestResult: newEvaluation(t3, eval.NoData), StartsAt: t3, EndsAt: t3.Add(ResendDelay * 4), LastEvaluationTime: t3, @@ -1666,12 +1501,10 @@ func TestProcessEvalResults_StateTransitions(t *testing.T) { { PreviousState: eval.Normal, State: &State{ - Labels: labels["system + rule + labels1"], - State: eval.Normal, - StateReason: ngmodels.StateReasonMissingSeries, - Results: []Evaluation{ - newEvaluation(t1, eval.Normal), - }, + Labels: labels["system + rule + labels1"], + State: eval.Normal, + StateReason: ngmodels.StateReasonMissingSeries, + LatestResult: newEvaluation(t1, eval.Normal), StartsAt: t1, EndsAt: t3, LastEvaluationTime: t3, @@ -1680,12 +1513,10 @@ func TestProcessEvalResults_StateTransitions(t *testing.T) { { PreviousState: eval.Pending, State: &State{ - Labels: labels["system + rule + labels2"], - State: eval.Normal, - StateReason: ngmodels.StateReasonMissingSeries, - Results: []Evaluation{ - newEvaluation(t1, eval.Alerting), - }, + Labels: labels["system + rule + labels2"], + State: eval.Normal, + StateReason: ngmodels.StateReasonMissingSeries, + LatestResult: newEvaluation(t1, eval.Alerting), StartsAt: t1, EndsAt: t3, LastEvaluationTime: t3, @@ -1695,12 +1526,10 @@ func TestProcessEvalResults_StateTransitions(t *testing.T) { PreviousState: eval.Normal, PreviousStateReason: eval.NoData.String(), State: &State{ - Labels: labels["system + rule + no-data"], - State: eval.Normal, - StateReason: eval.NoData.String(), - Results: []Evaluation{ - newEvaluation(t3, eval.NoData), - }, + Labels: labels["system + rule + no-data"], + State: eval.Normal, + StateReason: eval.NoData.String(), + LatestResult: newEvaluation(t3, eval.NoData), StartsAt: t2, EndsAt: t2, LastEvaluationTime: t3, @@ -1713,12 +1542,10 @@ func TestProcessEvalResults_StateTransitions(t *testing.T) { { PreviousState: eval.Normal, State: &State{ - Labels: labels["system + rule + labels1"], - State: eval.Normal, - StateReason: ngmodels.StateReasonMissingSeries, - Results: []Evaluation{ - newEvaluation(t1, eval.Normal), - }, + Labels: labels["system + rule + labels1"], + State: eval.Normal, + StateReason: ngmodels.StateReasonMissingSeries, + LatestResult: newEvaluation(t1, eval.Normal), StartsAt: t1, EndsAt: t3, LastEvaluationTime: t3, @@ -1727,12 +1554,10 @@ func TestProcessEvalResults_StateTransitions(t *testing.T) { { PreviousState: eval.Pending, State: &State{ - Labels: labels["system + rule + labels2"], - State: eval.Normal, - StateReason: ngmodels.StateReasonMissingSeries, - Results: []Evaluation{ - newEvaluation(t1, eval.Alerting), - }, + Labels: labels["system + rule + labels2"], + State: eval.Normal, + StateReason: ngmodels.StateReasonMissingSeries, + LatestResult: newEvaluation(t1, eval.Alerting), StartsAt: t1, EndsAt: t3, LastEvaluationTime: t3, @@ -1742,12 +1567,10 @@ func TestProcessEvalResults_StateTransitions(t *testing.T) { PreviousState: eval.Normal, PreviousStateReason: ngmodels.ConcatReasons(eval.NoData.String(), ngmodels.StateReasonKeepLast), State: &State{ - Labels: labels["system + rule + no-data"], - State: eval.Normal, - StateReason: ngmodels.ConcatReasons(eval.NoData.String(), ngmodels.StateReasonKeepLast), - Results: []Evaluation{ - newEvaluation(t3, eval.NoData), - }, + Labels: labels["system + rule + no-data"], + State: eval.Normal, + StateReason: ngmodels.ConcatReasons(eval.NoData.String(), ngmodels.StateReasonKeepLast), + LatestResult: newEvaluation(t3, eval.NoData), StartsAt: t2, EndsAt: t2, LastEvaluationTime: t3, @@ -1762,12 +1585,10 @@ func TestProcessEvalResults_StateTransitions(t *testing.T) { { PreviousState: eval.Normal, State: &State{ - Labels: labels["system + rule + labels1"], - State: eval.Pending, - StateReason: eval.NoData.String(), - Results: []Evaluation{ - newEvaluation(t2, eval.NoData), - }, + Labels: labels["system + rule + labels1"], + State: eval.Pending, + StateReason: eval.NoData.String(), + LatestResult: newEvaluation(t2, eval.NoData), StartsAt: t2, EndsAt: t2.Add(ResendDelay * 4), LastEvaluationTime: t2, @@ -1776,12 +1597,10 @@ func TestProcessEvalResults_StateTransitions(t *testing.T) { { PreviousState: eval.Pending, State: &State{ - Labels: labels["system + rule + labels2"], - State: eval.Alerting, - StateReason: eval.NoData.String(), - Results: []Evaluation{ - newEvaluation(t2, eval.NoData), - }, + Labels: labels["system + rule + labels2"], + State: eval.Alerting, + StateReason: eval.NoData.String(), + LatestResult: newEvaluation(t2, eval.NoData), StartsAt: t2, EndsAt: t2.Add(ResendDelay * 4), LastEvaluationTime: t2, @@ -1793,12 +1612,10 @@ func TestProcessEvalResults_StateTransitions(t *testing.T) { PreviousState: eval.Pending, PreviousStateReason: eval.NoData.String(), State: &State{ - Labels: labels["system + rule + labels1"], - State: eval.Alerting, - StateReason: eval.NoData.String(), - Results: []Evaluation{ - newEvaluation(t3, eval.NoData), - }, + Labels: labels["system + rule + labels1"], + State: eval.Alerting, + StateReason: eval.NoData.String(), + LatestResult: newEvaluation(t3, eval.NoData), StartsAt: t3, EndsAt: t3.Add(ResendDelay * 4), LastEvaluationTime: t3, @@ -1808,12 +1625,10 @@ func TestProcessEvalResults_StateTransitions(t *testing.T) { PreviousState: eval.Alerting, PreviousStateReason: eval.NoData.String(), State: &State{ - Labels: labels["system + rule + labels2"], - State: eval.Alerting, - StateReason: eval.NoData.String(), - Results: []Evaluation{ - newEvaluation(t3, eval.NoData), - }, + Labels: labels["system + rule + labels2"], + State: eval.Alerting, + StateReason: eval.NoData.String(), + LatestResult: newEvaluation(t3, eval.NoData), StartsAt: t2, EndsAt: t3.Add(ResendDelay * 4), LastEvaluationTime: t3, @@ -1826,12 +1641,10 @@ func TestProcessEvalResults_StateTransitions(t *testing.T) { { PreviousState: eval.Normal, State: &State{ - Labels: labels["system + rule + labels1"], - State: eval.Normal, - StateReason: eval.NoData.String(), - Results: []Evaluation{ - newEvaluation(t2, eval.NoData), - }, + Labels: labels["system + rule + labels1"], + State: eval.Normal, + StateReason: eval.NoData.String(), + LatestResult: newEvaluation(t2, eval.NoData), StartsAt: t1, EndsAt: t1, LastEvaluationTime: t2, @@ -1840,12 +1653,10 @@ func TestProcessEvalResults_StateTransitions(t *testing.T) { { PreviousState: eval.Pending, State: &State{ - Labels: labels["system + rule + labels2"], - State: eval.Normal, - StateReason: eval.NoData.String(), - Results: []Evaluation{ - newEvaluation(t2, eval.NoData), - }, + Labels: labels["system + rule + labels2"], + State: eval.Normal, + StateReason: eval.NoData.String(), + LatestResult: newEvaluation(t2, eval.NoData), StartsAt: t2, EndsAt: t2, LastEvaluationTime: t2, @@ -1857,12 +1668,10 @@ func TestProcessEvalResults_StateTransitions(t *testing.T) { PreviousState: eval.Normal, PreviousStateReason: eval.NoData.String(), State: &State{ - Labels: labels["system + rule + labels1"], - State: eval.Normal, - StateReason: eval.NoData.String(), - Results: []Evaluation{ - newEvaluation(t3, eval.NoData), - }, + Labels: labels["system + rule + labels1"], + State: eval.Normal, + StateReason: eval.NoData.String(), + LatestResult: newEvaluation(t3, eval.NoData), StartsAt: t1, EndsAt: t1, LastEvaluationTime: t3, @@ -1872,12 +1681,10 @@ func TestProcessEvalResults_StateTransitions(t *testing.T) { PreviousState: eval.Normal, PreviousStateReason: eval.NoData.String(), State: &State{ - Labels: labels["system + rule + labels2"], - State: eval.Normal, - StateReason: eval.NoData.String(), - Results: []Evaluation{ - newEvaluation(t3, eval.NoData), - }, + Labels: labels["system + rule + labels2"], + State: eval.Normal, + StateReason: eval.NoData.String(), + LatestResult: newEvaluation(t3, eval.NoData), StartsAt: t2, EndsAt: t2, LastEvaluationTime: t3, @@ -1890,12 +1697,10 @@ func TestProcessEvalResults_StateTransitions(t *testing.T) { { PreviousState: eval.Normal, State: &State{ - Labels: labels["system + rule + labels1"], - State: eval.Normal, - StateReason: ngmodels.ConcatReasons(eval.NoData.String(), ngmodels.StateReasonKeepLast), - Results: []Evaluation{ - newEvaluation(t2, eval.NoData), - }, + Labels: labels["system + rule + labels1"], + State: eval.Normal, + StateReason: ngmodels.ConcatReasons(eval.NoData.String(), ngmodels.StateReasonKeepLast), + LatestResult: newEvaluation(t2, eval.NoData), StartsAt: t1, EndsAt: t1, LastEvaluationTime: t2, @@ -1904,12 +1709,10 @@ func TestProcessEvalResults_StateTransitions(t *testing.T) { { PreviousState: eval.Pending, State: &State{ - Labels: labels["system + rule + labels2"], - State: eval.Alerting, - StateReason: ngmodels.ConcatReasons(eval.NoData.String(), ngmodels.StateReasonKeepLast), - Results: []Evaluation{ - newEvaluation(t2, eval.NoData), - }, + Labels: labels["system + rule + labels2"], + State: eval.Alerting, + StateReason: ngmodels.ConcatReasons(eval.NoData.String(), ngmodels.StateReasonKeepLast), + LatestResult: newEvaluation(t2, eval.NoData), StartsAt: t2, EndsAt: t2.Add(ResendDelay * 4), LastEvaluationTime: t2, @@ -1921,12 +1724,10 @@ func TestProcessEvalResults_StateTransitions(t *testing.T) { PreviousState: eval.Normal, PreviousStateReason: ngmodels.ConcatReasons(eval.NoData.String(), ngmodels.StateReasonKeepLast), State: &State{ - Labels: labels["system + rule + labels1"], - State: eval.Normal, - StateReason: ngmodels.ConcatReasons(eval.NoData.String(), ngmodels.StateReasonKeepLast), - Results: []Evaluation{ - newEvaluation(t3, eval.NoData), - }, + Labels: labels["system + rule + labels1"], + State: eval.Normal, + StateReason: ngmodels.ConcatReasons(eval.NoData.String(), ngmodels.StateReasonKeepLast), + LatestResult: newEvaluation(t3, eval.NoData), StartsAt: t1, EndsAt: t1, LastEvaluationTime: t3, @@ -1936,12 +1737,10 @@ func TestProcessEvalResults_StateTransitions(t *testing.T) { PreviousState: eval.Alerting, PreviousStateReason: ngmodels.ConcatReasons(eval.NoData.String(), ngmodels.StateReasonKeepLast), State: &State{ - Labels: labels["system + rule + labels2"], - State: eval.Alerting, - StateReason: ngmodels.ConcatReasons(eval.NoData.String(), ngmodels.StateReasonKeepLast), - Results: []Evaluation{ - newEvaluation(t3, eval.NoData), - }, + Labels: labels["system + rule + labels2"], + State: eval.Alerting, + StateReason: ngmodels.ConcatReasons(eval.NoData.String(), ngmodels.StateReasonKeepLast), + LatestResult: newEvaluation(t3, eval.NoData), StartsAt: t2, EndsAt: t3.Add(ResendDelay * 4), LastEvaluationTime: t3, @@ -1971,12 +1770,9 @@ func TestProcessEvalResults_StateTransitions(t *testing.T) { { PreviousState: eval.Pending, State: &State{ - Labels: labels["system + rule + labels1"], - State: eval.Alerting, - Results: []Evaluation{ - newEvaluation(t1, eval.Alerting), - newEvaluation(t3, eval.Alerting), - }, + Labels: labels["system + rule + labels1"], + State: eval.Alerting, + LatestResult: newEvaluation(t3, eval.Alerting), StartsAt: t3, EndsAt: t3.Add(ResendDelay * 4), LastEvaluationTime: t3, @@ -1989,12 +1785,9 @@ func TestProcessEvalResults_StateTransitions(t *testing.T) { { PreviousState: eval.Pending, State: &State{ - Labels: labels["system + rule + labels1"], - State: eval.Alerting, - Results: []Evaluation{ - newEvaluation(t1, eval.Alerting), - newEvaluation(t3, eval.Alerting), - }, + Labels: labels["system + rule + labels1"], + State: eval.Alerting, + LatestResult: newEvaluation(t3, eval.Alerting), StartsAt: t3, EndsAt: t3.Add(ResendDelay * 4), LastEvaluationTime: t3, @@ -2007,12 +1800,9 @@ func TestProcessEvalResults_StateTransitions(t *testing.T) { { PreviousState: eval.Pending, State: &State{ - Labels: labels["system + rule + labels1"], - State: eval.Alerting, - Results: []Evaluation{ - newEvaluation(t1, eval.Alerting), - newEvaluation(t3, eval.Alerting), - }, + Labels: labels["system + rule + labels1"], + State: eval.Alerting, + LatestResult: newEvaluation(t3, eval.Alerting), StartsAt: t3, EndsAt: t3.Add(ResendDelay * 4), LastEvaluationTime: t3, @@ -2025,12 +1815,9 @@ func TestProcessEvalResults_StateTransitions(t *testing.T) { { PreviousState: eval.Pending, State: &State{ - Labels: labels["system + rule + labels1"], - State: eval.Alerting, - Results: []Evaluation{ - newEvaluation(t1, eval.Alerting), - newEvaluation(t3, eval.Alerting), - }, + Labels: labels["system + rule + labels1"], + State: eval.Alerting, + LatestResult: newEvaluation(t3, eval.Alerting), StartsAt: t3, EndsAt: t3.Add(ResendDelay * 4), LastEvaluationTime: t3, @@ -2046,12 +1833,9 @@ func TestProcessEvalResults_StateTransitions(t *testing.T) { PreviousState: eval.Pending, PreviousStateReason: eval.NoData.String(), State: &State{ - Labels: labels["system + rule + labels1"], - State: eval.Alerting, - Results: []Evaluation{ - newEvaluation(t2, eval.NoData), - newEvaluation(t3, eval.Alerting), - }, + Labels: labels["system + rule + labels1"], + State: eval.Alerting, + LatestResult: newEvaluation(t3, eval.Alerting), StartsAt: t3, EndsAt: t3.Add(ResendDelay * 4), LastEvaluationTime: t3, @@ -2065,12 +1849,9 @@ func TestProcessEvalResults_StateTransitions(t *testing.T) { PreviousState: eval.Normal, PreviousStateReason: eval.NoData.String(), State: &State{ - Labels: labels["system + rule + labels1"], - State: eval.Pending, - Results: []Evaluation{ - newEvaluation(t2, eval.NoData), - newEvaluation(t3, eval.Alerting), - }, + Labels: labels["system + rule + labels1"], + State: eval.Pending, + LatestResult: newEvaluation(t3, eval.Alerting), StartsAt: t3, EndsAt: t3.Add(ResendDelay * 4), LastEvaluationTime: t3, @@ -2084,12 +1865,9 @@ func TestProcessEvalResults_StateTransitions(t *testing.T) { PreviousState: eval.Pending, PreviousStateReason: ngmodels.ConcatReasons(eval.NoData.String(), ngmodels.StateReasonKeepLast), State: &State{ - Labels: labels["system + rule + labels1"], - State: eval.Alerting, - Results: []Evaluation{ - newEvaluation(t2, eval.NoData), - newEvaluation(t3, eval.Alerting), - }, + Labels: labels["system + rule + labels1"], + State: eval.Alerting, + LatestResult: newEvaluation(t3, eval.Alerting), StartsAt: t3, EndsAt: t3.Add(ResendDelay * 4), LastEvaluationTime: t3, @@ -2118,12 +1896,9 @@ func TestProcessEvalResults_StateTransitions(t *testing.T) { { PreviousState: eval.Normal, State: &State{ - Labels: labels["system + rule + labels1"], - State: eval.Normal, - Results: []Evaluation{ - newEvaluation(t2, eval.Normal), - newEvaluation(t3, eval.Normal), - }, + Labels: labels["system + rule + labels1"], + State: eval.Normal, + LatestResult: newEvaluation(t3, eval.Normal), StartsAt: t2, EndsAt: t2, LastEvaluationTime: t3, @@ -2132,12 +1907,10 @@ func TestProcessEvalResults_StateTransitions(t *testing.T) { { PreviousState: eval.NoData, State: &State{ - Labels: labels["system + rule + no-data"], - State: eval.Normal, - StateReason: ngmodels.StateReasonMissingSeries, - Results: []Evaluation{ - newEvaluation(t1, eval.NoData), - }, + Labels: labels["system + rule + no-data"], + State: eval.Normal, + StateReason: ngmodels.StateReasonMissingSeries, + LatestResult: newEvaluation(t1, eval.NoData), StartsAt: t1, EndsAt: t3, LastEvaluationTime: t3, @@ -2150,12 +1923,9 @@ func TestProcessEvalResults_StateTransitions(t *testing.T) { { PreviousState: eval.Normal, State: &State{ - Labels: labels["system + rule + labels1"], - State: eval.Normal, - Results: []Evaluation{ - newEvaluation(t2, eval.Normal), - newEvaluation(t3, eval.Normal), - }, + Labels: labels["system + rule + labels1"], + State: eval.Normal, + LatestResult: newEvaluation(t3, eval.Normal), StartsAt: t2, EndsAt: t2, LastEvaluationTime: t3, @@ -2165,12 +1935,10 @@ func TestProcessEvalResults_StateTransitions(t *testing.T) { PreviousState: eval.Alerting, PreviousStateReason: eval.NoData.String(), State: &State{ - Labels: labels["system + rule + no-data"], - State: eval.Normal, - StateReason: ngmodels.StateReasonMissingSeries, - Results: []Evaluation{ - newEvaluation(t1, eval.NoData), - }, + Labels: labels["system + rule + no-data"], + State: eval.Normal, + StateReason: ngmodels.StateReasonMissingSeries, + LatestResult: newEvaluation(t1, eval.NoData), StartsAt: t1, EndsAt: t3, LastEvaluationTime: t3, @@ -2184,12 +1952,9 @@ func TestProcessEvalResults_StateTransitions(t *testing.T) { { PreviousState: eval.Normal, State: &State{ - Labels: labels["system + rule + labels1"], - State: eval.Normal, - Results: []Evaluation{ - newEvaluation(t2, eval.Normal), - newEvaluation(t3, eval.Normal), - }, + Labels: labels["system + rule + labels1"], + State: eval.Normal, + LatestResult: newEvaluation(t3, eval.Normal), StartsAt: t2, EndsAt: t2, LastEvaluationTime: t3, @@ -2199,12 +1964,10 @@ func TestProcessEvalResults_StateTransitions(t *testing.T) { PreviousState: eval.Normal, PreviousStateReason: eval.NoData.String(), State: &State{ - Labels: labels["system + rule + no-data"], - State: eval.Normal, - StateReason: ngmodels.StateReasonMissingSeries, - Results: []Evaluation{ - newEvaluation(t1, eval.NoData), - }, + Labels: labels["system + rule + no-data"], + State: eval.Normal, + StateReason: ngmodels.StateReasonMissingSeries, + LatestResult: newEvaluation(t1, eval.NoData), StartsAt: t1, EndsAt: t3, LastEvaluationTime: t3, @@ -2217,12 +1980,9 @@ func TestProcessEvalResults_StateTransitions(t *testing.T) { { PreviousState: eval.Normal, State: &State{ - Labels: labels["system + rule + labels1"], - State: eval.Normal, - Results: []Evaluation{ - newEvaluation(t2, eval.Normal), - newEvaluation(t3, eval.Normal), - }, + Labels: labels["system + rule + labels1"], + State: eval.Normal, + LatestResult: newEvaluation(t3, eval.Normal), StartsAt: t2, EndsAt: t2, LastEvaluationTime: t3, @@ -2232,12 +1992,10 @@ func TestProcessEvalResults_StateTransitions(t *testing.T) { PreviousState: eval.Normal, PreviousStateReason: ngmodels.ConcatReasons(eval.NoData.String(), ngmodels.StateReasonKeepLast), State: &State{ - Labels: labels["system + rule + no-data"], - State: eval.Normal, - StateReason: ngmodels.StateReasonMissingSeries, - Results: []Evaluation{ - newEvaluation(t1, eval.NoData), - }, + Labels: labels["system + rule + no-data"], + State: eval.Normal, + StateReason: ngmodels.StateReasonMissingSeries, + LatestResult: newEvaluation(t1, eval.NoData), StartsAt: t1, EndsAt: t3, LastEvaluationTime: t3, @@ -2263,11 +2021,9 @@ func TestProcessEvalResults_StateTransitions(t *testing.T) { { PreviousState: eval.Normal, State: &State{ - Labels: labels["system + rule + no-data"], - State: eval.NoData, - Results: []Evaluation{ - newEvaluation(t2, eval.NoData), - }, + Labels: labels["system + rule + no-data"], + State: eval.NoData, + LatestResult: newEvaluation(t2, eval.NoData), StartsAt: t2, EndsAt: t2.Add(ResendDelay * 4), LastEvaluationTime: t2, @@ -2280,12 +2036,10 @@ func TestProcessEvalResults_StateTransitions(t *testing.T) { { PreviousState: eval.Normal, State: &State{ - Labels: labels["system + rule + no-data"], - State: eval.Alerting, - StateReason: eval.NoData.String(), - Results: []Evaluation{ - newEvaluation(t2, eval.NoData), - }, + Labels: labels["system + rule + no-data"], + State: eval.Alerting, + StateReason: eval.NoData.String(), + LatestResult: newEvaluation(t2, eval.NoData), StartsAt: t2, EndsAt: t2.Add(ResendDelay * 4), LastEvaluationTime: t2, @@ -2298,12 +2052,10 @@ func TestProcessEvalResults_StateTransitions(t *testing.T) { { PreviousState: eval.Normal, State: &State{ - Labels: labels["system + rule + no-data"], - State: eval.Normal, - StateReason: eval.NoData.String(), - Results: []Evaluation{ - newEvaluation(t2, eval.NoData), - }, + Labels: labels["system + rule + no-data"], + State: eval.Normal, + StateReason: eval.NoData.String(), + LatestResult: newEvaluation(t2, eval.NoData), StartsAt: t2, EndsAt: t2, LastEvaluationTime: t2, @@ -2316,12 +2068,10 @@ func TestProcessEvalResults_StateTransitions(t *testing.T) { { PreviousState: eval.Normal, State: &State{ - Labels: labels["system + rule + no-data"], - State: eval.Normal, - StateReason: ngmodels.ConcatReasons(eval.NoData.String(), ngmodels.StateReasonKeepLast), - Results: []Evaluation{ - newEvaluation(t2, eval.NoData), - }, + Labels: labels["system + rule + no-data"], + State: eval.Normal, + StateReason: ngmodels.ConcatReasons(eval.NoData.String(), ngmodels.StateReasonKeepLast), + LatestResult: newEvaluation(t2, eval.NoData), StartsAt: t2, EndsAt: t2, LastEvaluationTime: t2, @@ -2336,13 +2086,10 @@ func TestProcessEvalResults_StateTransitions(t *testing.T) { { PreviousState: eval.Normal, State: &State{ - Labels: labels["system + rule"], - State: eval.Alerting, - StateReason: eval.NoData.String(), - Results: []Evaluation{ - newEvaluation(t1, eval.Normal), - newEvaluation(t2, eval.NoData), - }, + Labels: labels["system + rule"], + State: eval.Alerting, + StateReason: eval.NoData.String(), + LatestResult: newEvaluation(t2, eval.NoData), StartsAt: t2, EndsAt: t2.Add(ResendDelay * 4), LastEvaluationTime: t2, @@ -2355,13 +2102,10 @@ func TestProcessEvalResults_StateTransitions(t *testing.T) { { PreviousState: eval.Normal, State: &State{ - Labels: labels["system + rule"], - State: eval.Normal, - StateReason: eval.NoData.String(), - Results: []Evaluation{ - newEvaluation(t1, eval.Normal), - newEvaluation(t2, eval.NoData), - }, + Labels: labels["system + rule"], + State: eval.Normal, + StateReason: eval.NoData.String(), + LatestResult: newEvaluation(t2, eval.NoData), StartsAt: t1, EndsAt: t1, LastEvaluationTime: t2, @@ -2374,13 +2118,10 @@ func TestProcessEvalResults_StateTransitions(t *testing.T) { { PreviousState: eval.Normal, State: &State{ - Labels: labels["system + rule"], - State: eval.Normal, - StateReason: ngmodels.ConcatReasons(eval.NoData.String(), ngmodels.StateReasonKeepLast), - Results: []Evaluation{ - newEvaluation(t1, eval.Normal), - newEvaluation(t2, eval.NoData), - }, + Labels: labels["system + rule"], + State: eval.Normal, + StateReason: ngmodels.ConcatReasons(eval.NoData.String(), ngmodels.StateReasonKeepLast), + LatestResult: newEvaluation(t2, eval.NoData), StartsAt: t1, EndsAt: t1, LastEvaluationTime: t2, @@ -2409,11 +2150,9 @@ func TestProcessEvalResults_StateTransitions(t *testing.T) { { PreviousState: eval.Normal, State: &State{ - Labels: labels["system + rule + no-data"], - State: eval.NoData, - Results: []Evaluation{ - newEvaluation(t2, eval.NoData), - }, + Labels: labels["system + rule + no-data"], + State: eval.NoData, + LatestResult: newEvaluation(t2, eval.NoData), StartsAt: t2, EndsAt: t2.Add(ResendDelay * 4), LastEvaluationTime: t2, @@ -2424,12 +2163,10 @@ func TestProcessEvalResults_StateTransitions(t *testing.T) { { PreviousState: eval.Alerting, State: &State{ - Labels: labels["system + rule"], - State: eval.Normal, - StateReason: ngmodels.StateReasonMissingSeries, - Results: []Evaluation{ - newEvaluation(t1, eval.Alerting), - }, + Labels: labels["system + rule"], + State: eval.Normal, + StateReason: ngmodels.StateReasonMissingSeries, + LatestResult: newEvaluation(t1, eval.Alerting), StartsAt: t1, EndsAt: t3, LastEvaluationTime: t3, @@ -2439,12 +2176,9 @@ func TestProcessEvalResults_StateTransitions(t *testing.T) { { PreviousState: eval.NoData, State: &State{ - Labels: labels["system + rule + no-data"], - State: eval.NoData, - Results: []Evaluation{ - newEvaluation(t2, eval.NoData), - newEvaluation(t3, eval.NoData), - }, + Labels: labels["system + rule + no-data"], + State: eval.NoData, + LatestResult: newEvaluation(t3, eval.NoData), StartsAt: t2, EndsAt: t3.Add(ResendDelay * 4), LastEvaluationTime: t3, @@ -2457,12 +2191,10 @@ func TestProcessEvalResults_StateTransitions(t *testing.T) { { PreviousState: eval.Alerting, State: &State{ - Labels: labels["system + rule"], - State: eval.Normal, - StateReason: ngmodels.StateReasonMissingSeries, - Results: []Evaluation{ - newEvaluation(t1, eval.Alerting), - }, + Labels: labels["system + rule"], + State: eval.Normal, + StateReason: ngmodels.StateReasonMissingSeries, + LatestResult: newEvaluation(t1, eval.Alerting), StartsAt: t1, EndsAt: t3, LastEvaluationTime: t3, @@ -2473,13 +2205,10 @@ func TestProcessEvalResults_StateTransitions(t *testing.T) { PreviousState: eval.Alerting, PreviousStateReason: eval.NoData.String(), State: &State{ - Labels: labels["system + rule + no-data"], - State: eval.Alerting, - StateReason: eval.NoData.String(), - Results: []Evaluation{ - newEvaluation(t2, eval.NoData), - newEvaluation(t3, eval.NoData), - }, + Labels: labels["system + rule + no-data"], + State: eval.Alerting, + StateReason: eval.NoData.String(), + LatestResult: newEvaluation(t3, eval.NoData), StartsAt: t2, EndsAt: t3.Add(ResendDelay * 4), LastEvaluationTime: t3, @@ -2492,12 +2221,10 @@ func TestProcessEvalResults_StateTransitions(t *testing.T) { { PreviousState: eval.Alerting, State: &State{ - Labels: labels["system + rule"], - State: eval.Normal, - StateReason: ngmodels.StateReasonMissingSeries, - Results: []Evaluation{ - newEvaluation(t1, eval.Alerting), - }, + Labels: labels["system + rule"], + State: eval.Normal, + StateReason: ngmodels.StateReasonMissingSeries, + LatestResult: newEvaluation(t1, eval.Alerting), StartsAt: t1, EndsAt: t3, LastEvaluationTime: t3, @@ -2508,13 +2235,10 @@ func TestProcessEvalResults_StateTransitions(t *testing.T) { PreviousState: eval.Normal, PreviousStateReason: eval.NoData.String(), State: &State{ - Labels: labels["system + rule + no-data"], - State: eval.Normal, - StateReason: eval.NoData.String(), - Results: []Evaluation{ - newEvaluation(t2, eval.NoData), - newEvaluation(t3, eval.NoData), - }, + Labels: labels["system + rule + no-data"], + State: eval.Normal, + StateReason: eval.NoData.String(), + LatestResult: newEvaluation(t3, eval.NoData), StartsAt: t2, EndsAt: t2, LastEvaluationTime: t3, @@ -2527,12 +2251,10 @@ func TestProcessEvalResults_StateTransitions(t *testing.T) { { PreviousState: eval.Alerting, State: &State{ - Labels: labels["system + rule"], - State: eval.Normal, - StateReason: ngmodels.StateReasonMissingSeries, - Results: []Evaluation{ - newEvaluation(t1, eval.Alerting), - }, + Labels: labels["system + rule"], + State: eval.Normal, + StateReason: ngmodels.StateReasonMissingSeries, + LatestResult: newEvaluation(t1, eval.Alerting), StartsAt: t1, EndsAt: t3, LastEvaluationTime: t3, @@ -2543,13 +2265,10 @@ func TestProcessEvalResults_StateTransitions(t *testing.T) { PreviousState: eval.Normal, PreviousStateReason: ngmodels.ConcatReasons(eval.NoData.String(), ngmodels.StateReasonKeepLast), State: &State{ - Labels: labels["system + rule + no-data"], - State: eval.Normal, - StateReason: ngmodels.ConcatReasons(eval.NoData.String(), ngmodels.StateReasonKeepLast), - Results: []Evaluation{ - newEvaluation(t2, eval.NoData), - newEvaluation(t3, eval.NoData), - }, + Labels: labels["system + rule + no-data"], + State: eval.Normal, + StateReason: ngmodels.ConcatReasons(eval.NoData.String(), ngmodels.StateReasonKeepLast), + LatestResult: newEvaluation(t3, eval.NoData), StartsAt: t2, EndsAt: t2, LastEvaluationTime: t3, @@ -2564,13 +2283,10 @@ func TestProcessEvalResults_StateTransitions(t *testing.T) { { PreviousState: eval.Alerting, State: &State{ - Labels: labels["system + rule"], - State: eval.Alerting, - StateReason: eval.NoData.String(), - Results: []Evaluation{ - newEvaluation(t1, eval.Alerting), - newEvaluation(t2, eval.NoData), - }, + Labels: labels["system + rule"], + State: eval.Alerting, + StateReason: eval.NoData.String(), + LatestResult: newEvaluation(t2, eval.NoData), StartsAt: t1, EndsAt: t2.Add(ResendDelay * 4), LastEvaluationTime: t2, @@ -2582,14 +2298,10 @@ func TestProcessEvalResults_StateTransitions(t *testing.T) { PreviousState: eval.Alerting, PreviousStateReason: eval.NoData.String(), State: &State{ - Labels: labels["system + rule"], - State: eval.Alerting, - StateReason: eval.NoData.String(), - Results: []Evaluation{ - newEvaluation(t1, eval.Alerting), - newEvaluation(t2, eval.NoData), - newEvaluation(t3, eval.NoData), - }, + Labels: labels["system + rule"], + State: eval.Alerting, + StateReason: eval.NoData.String(), + LatestResult: newEvaluation(t3, eval.NoData), StartsAt: t1, EndsAt: t3.Add(ResendDelay * 4), LastEvaluationTime: t3, @@ -2602,13 +2314,10 @@ func TestProcessEvalResults_StateTransitions(t *testing.T) { { PreviousState: eval.Alerting, State: &State{ - Labels: labels["system + rule"], - State: eval.Normal, - StateReason: eval.NoData.String(), - Results: []Evaluation{ - newEvaluation(t1, eval.Alerting), - newEvaluation(t2, eval.NoData), - }, + Labels: labels["system + rule"], + State: eval.Normal, + StateReason: eval.NoData.String(), + LatestResult: newEvaluation(t2, eval.NoData), StartsAt: t2, EndsAt: t2, LastEvaluationTime: t2, @@ -2621,14 +2330,10 @@ func TestProcessEvalResults_StateTransitions(t *testing.T) { PreviousState: eval.Normal, PreviousStateReason: eval.NoData.String(), State: &State{ - Labels: labels["system + rule"], - State: eval.Normal, - StateReason: eval.NoData.String(), - Results: []Evaluation{ - newEvaluation(t1, eval.Alerting), - newEvaluation(t2, eval.NoData), - newEvaluation(t3, eval.NoData), - }, + Labels: labels["system + rule"], + State: eval.Normal, + StateReason: eval.NoData.String(), + LatestResult: newEvaluation(t3, eval.NoData), StartsAt: t2, EndsAt: t2, LastEvaluationTime: t3, @@ -2641,13 +2346,10 @@ func TestProcessEvalResults_StateTransitions(t *testing.T) { { PreviousState: eval.Alerting, State: &State{ - Labels: labels["system + rule"], - State: eval.Alerting, - StateReason: ngmodels.ConcatReasons(eval.NoData.String(), ngmodels.StateReasonKeepLast), - Results: []Evaluation{ - newEvaluation(t1, eval.Alerting), - newEvaluation(t2, eval.NoData), - }, + Labels: labels["system + rule"], + State: eval.Alerting, + StateReason: ngmodels.ConcatReasons(eval.NoData.String(), ngmodels.StateReasonKeepLast), + LatestResult: newEvaluation(t2, eval.NoData), StartsAt: t1, EndsAt: t2.Add(ResendDelay * 4), LastEvaluationTime: t2, @@ -2659,14 +2361,10 @@ func TestProcessEvalResults_StateTransitions(t *testing.T) { PreviousState: eval.Alerting, PreviousStateReason: ngmodels.ConcatReasons(eval.NoData.String(), ngmodels.StateReasonKeepLast), State: &State{ - Labels: labels["system + rule"], - State: eval.Alerting, - StateReason: ngmodels.ConcatReasons(eval.NoData.String(), ngmodels.StateReasonKeepLast), - Results: []Evaluation{ - newEvaluation(t1, eval.Alerting), - newEvaluation(t2, eval.NoData), - newEvaluation(t3, eval.NoData), - }, + Labels: labels["system + rule"], + State: eval.Alerting, + StateReason: ngmodels.ConcatReasons(eval.NoData.String(), ngmodels.StateReasonKeepLast), + LatestResult: newEvaluation(t3, eval.NoData), StartsAt: t1, EndsAt: t3.Add(ResendDelay * 4), LastEvaluationTime: t3, @@ -2696,11 +2394,9 @@ func TestProcessEvalResults_StateTransitions(t *testing.T) { { PreviousState: eval.Normal, State: &State{ - Labels: labels["system + rule + no-data"], - State: eval.NoData, - Results: []Evaluation{ - newEvaluation(t2, eval.NoData), - }, + Labels: labels["system + rule + no-data"], + State: eval.NoData, + LatestResult: newEvaluation(t2, eval.NoData), StartsAt: t2, EndsAt: t2.Add(ResendDelay * 4), LastEvaluationTime: t2, @@ -2711,12 +2407,9 @@ func TestProcessEvalResults_StateTransitions(t *testing.T) { { PreviousState: eval.Pending, State: &State{ - Labels: labels["system + rule"], - State: eval.Alerting, - Results: []Evaluation{ - newEvaluation(t1, eval.Alerting), - newEvaluation(t3, eval.Alerting), - }, + Labels: labels["system + rule"], + State: eval.Alerting, + LatestResult: newEvaluation(t3, eval.Alerting), StartsAt: t3, EndsAt: t3.Add(ResendDelay * 4), LastEvaluationTime: t3, @@ -2729,12 +2422,9 @@ func TestProcessEvalResults_StateTransitions(t *testing.T) { { PreviousState: eval.Pending, State: &State{ - Labels: labels["system + rule"], - State: eval.Alerting, - Results: []Evaluation{ - newEvaluation(t1, eval.Alerting), - newEvaluation(t3, eval.Alerting), - }, + Labels: labels["system + rule"], + State: eval.Alerting, + LatestResult: newEvaluation(t3, eval.Alerting), StartsAt: t3, EndsAt: t3.Add(ResendDelay * 4), LastEvaluationTime: t3, @@ -2747,12 +2437,9 @@ func TestProcessEvalResults_StateTransitions(t *testing.T) { { PreviousState: eval.Pending, State: &State{ - Labels: labels["system + rule"], - State: eval.Alerting, - Results: []Evaluation{ - newEvaluation(t1, eval.Alerting), - newEvaluation(t3, eval.Alerting), - }, + Labels: labels["system + rule"], + State: eval.Alerting, + LatestResult: newEvaluation(t3, eval.Alerting), StartsAt: t3, EndsAt: t3.Add(ResendDelay * 4), LastEvaluationTime: t3, @@ -2765,12 +2452,9 @@ func TestProcessEvalResults_StateTransitions(t *testing.T) { { PreviousState: eval.Pending, State: &State{ - Labels: labels["system + rule"], - State: eval.Alerting, - Results: []Evaluation{ - newEvaluation(t1, eval.Alerting), - newEvaluation(t3, eval.Alerting), - }, + Labels: labels["system + rule"], + State: eval.Alerting, + LatestResult: newEvaluation(t3, eval.Alerting), StartsAt: t3, EndsAt: t3.Add(ResendDelay * 4), LastEvaluationTime: t3, @@ -2786,12 +2470,9 @@ func TestProcessEvalResults_StateTransitions(t *testing.T) { PreviousState: eval.Pending, PreviousStateReason: eval.NoData.String(), State: &State{ - Labels: labels["system + rule"], - State: eval.Alerting, - Results: []Evaluation{ - newEvaluation(t2, eval.NoData), - newEvaluation(t3, eval.Alerting), - }, + Labels: labels["system + rule"], + State: eval.Alerting, + LatestResult: newEvaluation(t3, eval.Alerting), StartsAt: t3, EndsAt: t3.Add(ResendDelay * 4), LastEvaluationTime: t3, @@ -2805,12 +2486,9 @@ func TestProcessEvalResults_StateTransitions(t *testing.T) { PreviousState: eval.Normal, PreviousStateReason: eval.NoData.String(), State: &State{ - Labels: labels["system + rule"], - State: eval.Pending, - Results: []Evaluation{ - newEvaluation(t2, eval.NoData), - newEvaluation(t3, eval.Alerting), - }, + Labels: labels["system + rule"], + State: eval.Pending, + LatestResult: newEvaluation(t3, eval.Alerting), StartsAt: t3, EndsAt: t3.Add(ResendDelay * 4), LastEvaluationTime: t3, @@ -2824,12 +2502,9 @@ func TestProcessEvalResults_StateTransitions(t *testing.T) { PreviousState: eval.Pending, PreviousStateReason: ngmodels.ConcatReasons(eval.NoData.String(), ngmodels.StateReasonKeepLast), State: &State{ - Labels: labels["system + rule"], - State: eval.Alerting, - Results: []Evaluation{ - newEvaluation(t2, eval.NoData), - newEvaluation(t3, eval.Alerting), - }, + Labels: labels["system + rule"], + State: eval.Alerting, + LatestResult: newEvaluation(t3, eval.Alerting), StartsAt: t3, EndsAt: t3.Add(ResendDelay * 4), LastEvaluationTime: t3, @@ -2922,13 +2597,11 @@ func TestProcessEvalResults_StateTransitions(t *testing.T) { { PreviousState: eval.Normal, State: &State{ - CacheID: cacheID(labels["system + rule"]), - Labels: labels["system + rule + datasource-error"], - State: eval.Error, - Error: datasourceError, - Results: []Evaluation{ - newEvaluation(t1, eval.Error), - }, + CacheID: cacheID(labels["system + rule"]), + Labels: labels["system + rule + datasource-error"], + State: eval.Error, + Error: datasourceError, + LatestResult: newEvaluation(t1, eval.Error), StartsAt: t1, EndsAt: t1.Add(ResendDelay * 4), LastEvaluationTime: t1, @@ -2944,13 +2617,11 @@ func TestProcessEvalResults_StateTransitions(t *testing.T) { { PreviousState: eval.Normal, State: &State{ - Labels: labels["system + rule"], - State: eval.Alerting, - StateReason: eval.Error.String(), - Error: datasourceError, - Results: []Evaluation{ - newEvaluation(t1, eval.Error), - }, + Labels: labels["system + rule"], + State: eval.Alerting, + StateReason: eval.Error.String(), + Error: datasourceError, + LatestResult: newEvaluation(t1, eval.Error), StartsAt: t1, EndsAt: t1.Add(ResendDelay * 4), LastEvaluationTime: t1, @@ -2963,12 +2634,10 @@ func TestProcessEvalResults_StateTransitions(t *testing.T) { { PreviousState: eval.Normal, State: &State{ - Labels: labels["system + rule"], - State: eval.Normal, - StateReason: eval.Error.String(), - Results: []Evaluation{ - newEvaluation(t1, eval.Error), - }, + Labels: labels["system + rule"], + State: eval.Normal, + StateReason: eval.Error.String(), + LatestResult: newEvaluation(t1, eval.Error), StartsAt: t1, EndsAt: t1, LastEvaluationTime: t1, @@ -2981,12 +2650,10 @@ func TestProcessEvalResults_StateTransitions(t *testing.T) { { PreviousState: eval.Normal, State: &State{ - Labels: labels["system + rule"], - State: eval.Normal, - StateReason: ngmodels.ConcatReasons(eval.Error.String(), ngmodels.StateReasonKeepLast), - Results: []Evaluation{ - newEvaluation(t1, eval.Error), - }, + Labels: labels["system + rule"], + State: eval.Normal, + StateReason: ngmodels.ConcatReasons(eval.Error.String(), ngmodels.StateReasonKeepLast), + LatestResult: newEvaluation(t1, eval.Error), StartsAt: t1, EndsAt: t1, LastEvaluationTime: t1, @@ -3009,12 +2676,10 @@ func TestProcessEvalResults_StateTransitions(t *testing.T) { { PreviousState: eval.Normal, State: &State{ - Labels: labels["system + rule"], - State: eval.Error, - Error: genericError, - Results: []Evaluation{ - newEvaluation(t1, eval.Error), - }, + Labels: labels["system + rule"], + State: eval.Error, + Error: genericError, + LatestResult: newEvaluation(t1, eval.Error), StartsAt: t1, EndsAt: t1.Add(ResendDelay * 4), LastEvaluationTime: t1, @@ -3030,13 +2695,11 @@ func TestProcessEvalResults_StateTransitions(t *testing.T) { { PreviousState: eval.Normal, State: &State{ - Labels: labels["system + rule"], - State: eval.Alerting, - StateReason: eval.Error.String(), - Error: genericError, - Results: []Evaluation{ - newEvaluation(t1, eval.Error), - }, + Labels: labels["system + rule"], + State: eval.Alerting, + StateReason: eval.Error.String(), + Error: genericError, + LatestResult: newEvaluation(t1, eval.Error), StartsAt: t1, EndsAt: t1.Add(ResendDelay * 4), LastEvaluationTime: t1, @@ -3049,12 +2712,10 @@ func TestProcessEvalResults_StateTransitions(t *testing.T) { { PreviousState: eval.Normal, State: &State{ - Labels: labels["system + rule"], - State: eval.Normal, - StateReason: eval.Error.String(), - Results: []Evaluation{ - newEvaluation(t1, eval.Error), - }, + Labels: labels["system + rule"], + State: eval.Normal, + StateReason: eval.Error.String(), + LatestResult: newEvaluation(t1, eval.Error), StartsAt: t1, EndsAt: t1, LastEvaluationTime: t1, @@ -3067,12 +2728,10 @@ func TestProcessEvalResults_StateTransitions(t *testing.T) { { PreviousState: eval.Normal, State: &State{ - Labels: labels["system + rule"], - State: eval.Normal, - StateReason: ngmodels.ConcatReasons(eval.Error.String(), ngmodels.StateReasonKeepLast), - Results: []Evaluation{ - newEvaluation(t1, eval.Error), - }, + Labels: labels["system + rule"], + State: eval.Normal, + StateReason: ngmodels.ConcatReasons(eval.Error.String(), ngmodels.StateReasonKeepLast), + LatestResult: newEvaluation(t1, eval.Error), StartsAt: t1, EndsAt: t1, LastEvaluationTime: t1, @@ -3099,13 +2758,11 @@ func TestProcessEvalResults_StateTransitions(t *testing.T) { { PreviousState: eval.Normal, State: &State{ - CacheID: cacheID(labels["system + rule"]), - Labels: labels["system + rule + datasource-error"], - State: eval.Error, - Error: datasourceError, - Results: []Evaluation{ - newEvaluation(t2, eval.Error), - }, + CacheID: cacheID(labels["system + rule"]), + Labels: labels["system + rule + datasource-error"], + State: eval.Error, + Error: datasourceError, + LatestResult: newEvaluation(t2, eval.Error), StartsAt: t2, EndsAt: t2.Add(ResendDelay * 4), LastEvaluationTime: t2, @@ -3121,13 +2778,11 @@ func TestProcessEvalResults_StateTransitions(t *testing.T) { { PreviousState: eval.Normal, State: &State{ - Labels: labels["system + rule"], - State: eval.Pending, - StateReason: eval.Error.String(), - Error: datasourceError, - Results: []Evaluation{ - newEvaluation(t2, eval.Error), - }, + Labels: labels["system + rule"], + State: eval.Pending, + StateReason: eval.Error.String(), + Error: datasourceError, + LatestResult: newEvaluation(t2, eval.Error), StartsAt: t2, EndsAt: t2.Add(ResendDelay * 4), LastEvaluationTime: t2, @@ -3140,12 +2795,10 @@ func TestProcessEvalResults_StateTransitions(t *testing.T) { { PreviousState: eval.Normal, State: &State{ - Labels: labels["system + rule"], - State: eval.Normal, - StateReason: eval.Error.String(), - Results: []Evaluation{ - newEvaluation(t2, eval.Error), - }, + Labels: labels["system + rule"], + State: eval.Normal, + StateReason: eval.Error.String(), + LatestResult: newEvaluation(t2, eval.Error), StartsAt: t2, EndsAt: t2, LastEvaluationTime: t2, @@ -3158,12 +2811,10 @@ func TestProcessEvalResults_StateTransitions(t *testing.T) { { PreviousState: eval.Normal, State: &State{ - Labels: labels["system + rule"], - State: eval.Normal, - StateReason: ngmodels.ConcatReasons(eval.Error.String(), ngmodels.StateReasonKeepLast), - Results: []Evaluation{ - newEvaluation(t2, eval.Error), - }, + Labels: labels["system + rule"], + State: eval.Normal, + StateReason: ngmodels.ConcatReasons(eval.Error.String(), ngmodels.StateReasonKeepLast), + LatestResult: newEvaluation(t2, eval.Error), StartsAt: t2, EndsAt: t2, LastEvaluationTime: t2, @@ -3178,13 +2829,11 @@ func TestProcessEvalResults_StateTransitions(t *testing.T) { { PreviousState: eval.Pending, State: &State{ - Labels: labels["system + rule + labels1"], - State: eval.Alerting, - StateReason: eval.Error.String(), - Error: datasourceError, - Results: []Evaluation{ - newEvaluation(t2, eval.Error), - }, + Labels: labels["system + rule + labels1"], + State: eval.Alerting, + StateReason: eval.Error.String(), + Error: datasourceError, + LatestResult: newEvaluation(t2, eval.Error), StartsAt: t2, EndsAt: t2.Add(ResendDelay * 4), LastEvaluationTime: t2, @@ -3197,12 +2846,10 @@ func TestProcessEvalResults_StateTransitions(t *testing.T) { { PreviousState: eval.Pending, State: &State{ - Labels: labels["system + rule + labels1"], - State: eval.Normal, - StateReason: eval.Error.String(), - Results: []Evaluation{ - newEvaluation(t2, eval.Error), - }, + Labels: labels["system + rule + labels1"], + State: eval.Normal, + StateReason: eval.Error.String(), + LatestResult: newEvaluation(t2, eval.Error), StartsAt: t2, EndsAt: t2, LastEvaluationTime: t2, @@ -3215,12 +2862,10 @@ func TestProcessEvalResults_StateTransitions(t *testing.T) { { PreviousState: eval.Pending, State: &State{ - Labels: labels["system + rule + labels1"], - State: eval.Alerting, - StateReason: ngmodels.ConcatReasons(eval.Error.String(), ngmodels.StateReasonKeepLast), - Results: []Evaluation{ - newEvaluation(t2, eval.Error), - }, + Labels: labels["system + rule + labels1"], + State: eval.Alerting, + StateReason: ngmodels.ConcatReasons(eval.Error.String(), ngmodels.StateReasonKeepLast), + LatestResult: newEvaluation(t2, eval.Error), StartsAt: t2, EndsAt: t2.Add(ResendDelay * 4), LastEvaluationTime: t2, @@ -3246,13 +2891,11 @@ func TestProcessEvalResults_StateTransitions(t *testing.T) { { PreviousState: eval.Normal, State: &State{ - CacheID: cacheID(labels["system + rule"]), - Labels: labels["system + rule + datasource-error"], - State: eval.Error, - Error: datasourceError, - Results: []Evaluation{ - newEvaluation(t2, eval.Error), - }, + CacheID: cacheID(labels["system + rule"]), + Labels: labels["system + rule + datasource-error"], + State: eval.Error, + Error: datasourceError, + LatestResult: newEvaluation(t2, eval.Error), StartsAt: t2, EndsAt: t2.Add(ResendDelay * 4), LastEvaluationTime: t2, @@ -3268,13 +2911,11 @@ func TestProcessEvalResults_StateTransitions(t *testing.T) { { PreviousState: eval.Normal, State: &State{ - Labels: labels["system + rule"], - State: eval.Alerting, - StateReason: eval.Error.String(), - Error: datasourceError, - Results: []Evaluation{ - newEvaluation(t2, eval.Error), - }, + Labels: labels["system + rule"], + State: eval.Alerting, + StateReason: eval.Error.String(), + Error: datasourceError, + LatestResult: newEvaluation(t2, eval.Error), StartsAt: t2, EndsAt: t2.Add(ResendDelay * 4), LastEvaluationTime: t2, @@ -3287,12 +2928,10 @@ func TestProcessEvalResults_StateTransitions(t *testing.T) { { PreviousState: eval.Normal, State: &State{ - Labels: labels["system + rule"], - State: eval.Normal, - StateReason: eval.Error.String(), - Results: []Evaluation{ - newEvaluation(t2, eval.Error), - }, + Labels: labels["system + rule"], + State: eval.Normal, + StateReason: eval.Error.String(), + LatestResult: newEvaluation(t2, eval.Error), StartsAt: t2, EndsAt: t2, LastEvaluationTime: t2, @@ -3305,12 +2944,10 @@ func TestProcessEvalResults_StateTransitions(t *testing.T) { { PreviousState: eval.Normal, State: &State{ - Labels: labels["system + rule"], - State: eval.Normal, - StateReason: ngmodels.ConcatReasons(eval.Error.String(), ngmodels.StateReasonKeepLast), - Results: []Evaluation{ - newEvaluation(t2, eval.Error), - }, + Labels: labels["system + rule"], + State: eval.Normal, + StateReason: ngmodels.ConcatReasons(eval.Error.String(), ngmodels.StateReasonKeepLast), + LatestResult: newEvaluation(t2, eval.Error), StartsAt: t2, EndsAt: t2, LastEvaluationTime: t2, @@ -3325,14 +2962,11 @@ func TestProcessEvalResults_StateTransitions(t *testing.T) { { PreviousState: eval.Normal, State: &State{ - Labels: labels["system + rule + labels1"], - State: eval.Alerting, - StateReason: eval.Error.String(), - Error: datasourceError, - Results: []Evaluation{ - newEvaluation(t1, eval.Normal), - newEvaluation(t2, eval.Error), - }, + Labels: labels["system + rule + labels1"], + State: eval.Alerting, + StateReason: eval.Error.String(), + Error: datasourceError, + LatestResult: newEvaluation(t2, eval.Error), StartsAt: t2, EndsAt: t2.Add(ResendDelay * 4), LastEvaluationTime: t2, @@ -3345,13 +2979,10 @@ func TestProcessEvalResults_StateTransitions(t *testing.T) { { PreviousState: eval.Normal, State: &State{ - Labels: labels["system + rule + labels1"], - State: eval.Normal, - StateReason: eval.Error.String(), - Results: []Evaluation{ - newEvaluation(t1, eval.Normal), - newEvaluation(t2, eval.Error), - }, + Labels: labels["system + rule + labels1"], + State: eval.Normal, + StateReason: eval.Error.String(), + LatestResult: newEvaluation(t2, eval.Error), StartsAt: t1, EndsAt: t1, LastEvaluationTime: t2, @@ -3364,13 +2995,10 @@ func TestProcessEvalResults_StateTransitions(t *testing.T) { { PreviousState: eval.Normal, State: &State{ - Labels: labels["system + rule + labels1"], - State: eval.Normal, - StateReason: ngmodels.ConcatReasons(eval.Error.String(), ngmodels.StateReasonKeepLast), - Results: []Evaluation{ - newEvaluation(t1, eval.Normal), - newEvaluation(t2, eval.Error), - }, + Labels: labels["system + rule + labels1"], + State: eval.Normal, + StateReason: ngmodels.ConcatReasons(eval.Error.String(), ngmodels.StateReasonKeepLast), + LatestResult: newEvaluation(t2, eval.Error), StartsAt: t1, EndsAt: t1, LastEvaluationTime: t2, @@ -3399,12 +3027,9 @@ func TestProcessEvalResults_StateTransitions(t *testing.T) { { PreviousState: eval.Normal, State: &State{ - Labels: labels["system + rule + labels1"], - State: eval.Normal, - Results: []Evaluation{ - newEvaluation(t2, eval.Normal), - newEvaluation(t3, eval.Normal), - }, + Labels: labels["system + rule + labels1"], + State: eval.Normal, + LatestResult: newEvaluation(t3, eval.Normal), StartsAt: t2, EndsAt: t2, LastEvaluationTime: t3, @@ -3413,14 +3038,12 @@ func TestProcessEvalResults_StateTransitions(t *testing.T) { { PreviousState: eval.Error, State: &State{ - CacheID: cacheID(labels["system + rule"]), - Labels: labels["system + rule + datasource-error"], - Error: datasourceError, - State: eval.Normal, - StateReason: ngmodels.StateReasonMissingSeries, - Results: []Evaluation{ - newEvaluation(t1, eval.Error), - }, + CacheID: cacheID(labels["system + rule"]), + Labels: labels["system + rule + datasource-error"], + Error: datasourceError, + State: eval.Normal, + StateReason: ngmodels.StateReasonMissingSeries, + LatestResult: newEvaluation(t1, eval.Error), StartsAt: t1, EndsAt: t3, LastEvaluationTime: t3, @@ -3436,12 +3059,9 @@ func TestProcessEvalResults_StateTransitions(t *testing.T) { { PreviousState: eval.Normal, State: &State{ - Labels: labels["system + rule + labels1"], - State: eval.Normal, - Results: []Evaluation{ - newEvaluation(t2, eval.Normal), - newEvaluation(t3, eval.Normal), - }, + Labels: labels["system + rule + labels1"], + State: eval.Normal, + LatestResult: newEvaluation(t3, eval.Normal), StartsAt: t2, EndsAt: t2, LastEvaluationTime: t3, @@ -3451,13 +3071,11 @@ func TestProcessEvalResults_StateTransitions(t *testing.T) { PreviousState: eval.Alerting, PreviousStateReason: eval.Error.String(), State: &State{ - Labels: labels["system + rule"], - Error: datasourceError, - State: eval.Normal, - StateReason: ngmodels.StateReasonMissingSeries, - Results: []Evaluation{ - newEvaluation(t1, eval.Error), - }, + Labels: labels["system + rule"], + Error: datasourceError, + State: eval.Normal, + StateReason: ngmodels.StateReasonMissingSeries, + LatestResult: newEvaluation(t1, eval.Error), StartsAt: t1, EndsAt: t3, LastEvaluationTime: t3, @@ -3471,12 +3089,9 @@ func TestProcessEvalResults_StateTransitions(t *testing.T) { { PreviousState: eval.Normal, State: &State{ - Labels: labels["system + rule + labels1"], - State: eval.Normal, - Results: []Evaluation{ - newEvaluation(t2, eval.Normal), - newEvaluation(t3, eval.Normal), - }, + Labels: labels["system + rule + labels1"], + State: eval.Normal, + LatestResult: newEvaluation(t3, eval.Normal), StartsAt: t2, EndsAt: t2, LastEvaluationTime: t3, @@ -3486,12 +3101,10 @@ func TestProcessEvalResults_StateTransitions(t *testing.T) { PreviousState: eval.Normal, PreviousStateReason: eval.Error.String(), State: &State{ - Labels: labels["system + rule"], - State: eval.Normal, - StateReason: ngmodels.StateReasonMissingSeries, - Results: []Evaluation{ - newEvaluation(t1, eval.Error), - }, + Labels: labels["system + rule"], + State: eval.Normal, + StateReason: ngmodels.StateReasonMissingSeries, + LatestResult: newEvaluation(t1, eval.Error), StartsAt: t1, EndsAt: t3, LastEvaluationTime: t3, @@ -3504,12 +3117,9 @@ func TestProcessEvalResults_StateTransitions(t *testing.T) { { PreviousState: eval.Normal, State: &State{ - Labels: labels["system + rule + labels1"], - State: eval.Normal, - Results: []Evaluation{ - newEvaluation(t2, eval.Normal), - newEvaluation(t3, eval.Normal), - }, + Labels: labels["system + rule + labels1"], + State: eval.Normal, + LatestResult: newEvaluation(t3, eval.Normal), StartsAt: t2, EndsAt: t2, LastEvaluationTime: t3, @@ -3519,12 +3129,10 @@ func TestProcessEvalResults_StateTransitions(t *testing.T) { PreviousState: eval.Normal, PreviousStateReason: ngmodels.ConcatReasons(eval.Error.String(), ngmodels.StateReasonKeepLast), State: &State{ - Labels: labels["system + rule"], - State: eval.Normal, - StateReason: ngmodels.StateReasonMissingSeries, - Results: []Evaluation{ - newEvaluation(t1, eval.Error), - }, + Labels: labels["system + rule"], + State: eval.Normal, + StateReason: ngmodels.StateReasonMissingSeries, + LatestResult: newEvaluation(t1, eval.Error), StartsAt: t1, EndsAt: t3, LastEvaluationTime: t3, @@ -3550,14 +3158,11 @@ func TestProcessEvalResults_StateTransitions(t *testing.T) { { PreviousState: eval.Normal, State: &State{ - CacheID: cacheID(labels["system + rule"]), - Labels: labels["system + rule + datasource-error"], - State: eval.Error, - Error: datasourceError, - Results: []Evaluation{ - newEvaluation(t1, eval.Normal), - newEvaluation(t2, eval.Error), - }, + CacheID: cacheID(labels["system + rule"]), + Labels: labels["system + rule + datasource-error"], + State: eval.Error, + Error: datasourceError, + LatestResult: newEvaluation(t2, eval.Error), StartsAt: t2, EndsAt: t2.Add(ResendDelay * 4), LastEvaluationTime: t2, @@ -3573,14 +3178,11 @@ func TestProcessEvalResults_StateTransitions(t *testing.T) { { PreviousState: eval.Normal, State: &State{ - Labels: labels["system + rule"], - State: eval.Alerting, - StateReason: eval.Error.String(), - Error: datasourceError, - Results: []Evaluation{ - newEvaluation(t1, eval.Normal), - newEvaluation(t2, eval.Error), - }, + Labels: labels["system + rule"], + State: eval.Alerting, + StateReason: eval.Error.String(), + Error: datasourceError, + LatestResult: newEvaluation(t2, eval.Error), StartsAt: t2, EndsAt: t2.Add(ResendDelay * 4), LastEvaluationTime: t2, @@ -3593,13 +3195,10 @@ func TestProcessEvalResults_StateTransitions(t *testing.T) { { PreviousState: eval.Normal, State: &State{ - Labels: labels["system + rule"], - State: eval.Normal, - StateReason: eval.Error.String(), - Results: []Evaluation{ - newEvaluation(t1, eval.Normal), - newEvaluation(t2, eval.Error), - }, + Labels: labels["system + rule"], + State: eval.Normal, + StateReason: eval.Error.String(), + LatestResult: newEvaluation(t2, eval.Error), StartsAt: t1, EndsAt: t1, LastEvaluationTime: t2, @@ -3612,13 +3211,10 @@ func TestProcessEvalResults_StateTransitions(t *testing.T) { { PreviousState: eval.Normal, State: &State{ - Labels: labels["system + rule"], - State: eval.Normal, - StateReason: ngmodels.ConcatReasons(eval.Error.String(), ngmodels.StateReasonKeepLast), - Results: []Evaluation{ - newEvaluation(t1, eval.Normal), - newEvaluation(t2, eval.Error), - }, + Labels: labels["system + rule"], + State: eval.Normal, + StateReason: ngmodels.ConcatReasons(eval.Error.String(), ngmodels.StateReasonKeepLast), + LatestResult: newEvaluation(t2, eval.Error), StartsAt: t1, EndsAt: t1, LastEvaluationTime: t2, @@ -3645,11 +3241,9 @@ func TestProcessEvalResults_StateTransitions(t *testing.T) { { PreviousState: eval.Normal, State: &State{ - Labels: labels["system + rule"], - State: eval.Pending, - Results: []Evaluation{ - newEvaluation(t1, eval.Alerting), - }, + Labels: labels["system + rule"], + State: eval.Pending, + LatestResult: newEvaluation(t1, eval.Alerting), StartsAt: t1, EndsAt: t1.Add(ResendDelay * 4), LastEvaluationTime: t1, @@ -3660,13 +3254,11 @@ func TestProcessEvalResults_StateTransitions(t *testing.T) { { PreviousState: eval.Pending, State: &State{ - CacheID: cacheID(labels["system + rule"]), - Labels: labels["system + rule + datasource-error"], - State: eval.Error, - Error: datasourceError, - Results: []Evaluation{ - newEvaluation(t2, eval.Error), - }, + CacheID: cacheID(labels["system + rule"]), + Labels: labels["system + rule + datasource-error"], + State: eval.Error, + Error: datasourceError, + LatestResult: newEvaluation(t2, eval.Error), StartsAt: t2, EndsAt: t2.Add(ResendDelay * 4), LastEvaluationTime: t2, @@ -3682,13 +3274,11 @@ func TestProcessEvalResults_StateTransitions(t *testing.T) { { PreviousState: eval.Pending, State: &State{ - Labels: labels["system + rule"], - State: eval.Alerting, - StateReason: eval.Error.String(), - Error: datasourceError, - Results: []Evaluation{ - newEvaluation(t2, eval.Error), - }, + Labels: labels["system + rule"], + State: eval.Alerting, + StateReason: eval.Error.String(), + Error: datasourceError, + LatestResult: newEvaluation(t2, eval.Error), StartsAt: t2, EndsAt: t2.Add(ResendDelay * 4), LastEvaluationTime: t2, @@ -3701,12 +3291,10 @@ func TestProcessEvalResults_StateTransitions(t *testing.T) { { PreviousState: eval.Pending, State: &State{ - Labels: labels["system + rule"], - State: eval.Normal, - StateReason: eval.Error.String(), - Results: []Evaluation{ - newEvaluation(t2, eval.Error), - }, + Labels: labels["system + rule"], + State: eval.Normal, + StateReason: eval.Error.String(), + LatestResult: newEvaluation(t2, eval.Error), StartsAt: t2, EndsAt: t2, LastEvaluationTime: t2, @@ -3719,12 +3307,10 @@ func TestProcessEvalResults_StateTransitions(t *testing.T) { { PreviousState: eval.Pending, State: &State{ - Labels: labels["system + rule"], - State: eval.Alerting, - StateReason: ngmodels.ConcatReasons(eval.Error.String(), ngmodels.StateReasonKeepLast), - Results: []Evaluation{ - newEvaluation(t2, eval.Error), - }, + Labels: labels["system + rule"], + State: eval.Alerting, + StateReason: ngmodels.ConcatReasons(eval.Error.String(), ngmodels.StateReasonKeepLast), + LatestResult: newEvaluation(t2, eval.Error), StartsAt: t2, EndsAt: t2.Add(ResendDelay * 4), LastEvaluationTime: t2, @@ -3754,14 +3340,11 @@ func TestProcessEvalResults_StateTransitions(t *testing.T) { { PreviousState: eval.Pending, State: &State{ - CacheID: cacheID(labels["system + rule"]), - Labels: labels["system + rule + datasource-error"], - State: eval.Error, - Error: datasourceError, - Results: []Evaluation{ - newEvaluation(t1, eval.Alerting), - newEvaluation(t2, eval.Error), - }, + CacheID: cacheID(labels["system + rule"]), + Labels: labels["system + rule + datasource-error"], + State: eval.Error, + Error: datasourceError, + LatestResult: newEvaluation(t2, eval.Error), StartsAt: t2, EndsAt: t2.Add(ResendDelay * 4), LastEvaluationTime: t2, @@ -3775,12 +3358,9 @@ func TestProcessEvalResults_StateTransitions(t *testing.T) { { PreviousState: eval.Error, State: &State{ - Labels: labels["system + rule"], - State: eval.Pending, - Results: []Evaluation{ - newEvaluation(t2, eval.Error), - newEvaluation(t3, eval.Alerting), - }, + Labels: labels["system + rule"], + State: eval.Pending, + LatestResult: newEvaluation(t3, eval.Alerting), StartsAt: t3, EndsAt: t3.Add(ResendDelay * 4), LastEvaluationTime: t3, @@ -3793,14 +3373,11 @@ func TestProcessEvalResults_StateTransitions(t *testing.T) { { PreviousState: eval.Pending, State: &State{ - Labels: labels["system + rule"], - State: eval.Pending, - StateReason: eval.Error.String(), - Error: datasourceError, - Results: []Evaluation{ - newEvaluation(t1, eval.Alerting), - newEvaluation(t2, eval.Error), - }, + Labels: labels["system + rule"], + State: eval.Pending, + StateReason: eval.Error.String(), + Error: datasourceError, + LatestResult: newEvaluation(t2, eval.Error), StartsAt: t1, EndsAt: t1.Add(ResendDelay * 4), // TODO probably it should be t1 (semantic of Normal)? LastEvaluationTime: t2, @@ -3812,12 +3389,9 @@ func TestProcessEvalResults_StateTransitions(t *testing.T) { PreviousState: eval.Pending, PreviousStateReason: eval.Error.String(), State: &State{ - Labels: labels["system + rule"], - State: eval.Alerting, - Results: []Evaluation{ - newEvaluation(t2, eval.Error), - newEvaluation(t3, eval.Alerting), - }, + Labels: labels["system + rule"], + State: eval.Alerting, + LatestResult: newEvaluation(t3, eval.Alerting), StartsAt: t3, EndsAt: t3.Add(ResendDelay * 4), LastEvaluationTime: t3, @@ -3830,13 +3404,10 @@ func TestProcessEvalResults_StateTransitions(t *testing.T) { { PreviousState: eval.Pending, State: &State{ - Labels: labels["system + rule"], - State: eval.Normal, - StateReason: eval.Error.String(), - Results: []Evaluation{ - newEvaluation(t1, eval.Alerting), - newEvaluation(t2, eval.Error), - }, + Labels: labels["system + rule"], + State: eval.Normal, + StateReason: eval.Error.String(), + LatestResult: newEvaluation(t2, eval.Error), StartsAt: t2, EndsAt: t2, LastEvaluationTime: t2, @@ -3848,12 +3419,9 @@ func TestProcessEvalResults_StateTransitions(t *testing.T) { PreviousState: eval.Normal, PreviousStateReason: eval.Error.String(), State: &State{ - Labels: labels["system + rule"], - State: eval.Pending, - Results: []Evaluation{ - newEvaluation(t2, eval.Error), - newEvaluation(t3, eval.Alerting), - }, + Labels: labels["system + rule"], + State: eval.Pending, + LatestResult: newEvaluation(t3, eval.Alerting), StartsAt: t3, EndsAt: t3.Add(ResendDelay * 4), LastEvaluationTime: t3, @@ -3866,13 +3434,10 @@ func TestProcessEvalResults_StateTransitions(t *testing.T) { { PreviousState: eval.Pending, State: &State{ - Labels: labels["system + rule"], - State: eval.Pending, - StateReason: ngmodels.ConcatReasons(eval.Error.String(), ngmodels.StateReasonKeepLast), - Results: []Evaluation{ - newEvaluation(t1, eval.Alerting), - newEvaluation(t2, eval.Error), - }, + Labels: labels["system + rule"], + State: eval.Pending, + StateReason: ngmodels.ConcatReasons(eval.Error.String(), ngmodels.StateReasonKeepLast), + LatestResult: newEvaluation(t2, eval.Error), StartsAt: t1, EndsAt: t1.Add(ResendDelay * 4), LastEvaluationTime: t2, @@ -3884,12 +3449,9 @@ func TestProcessEvalResults_StateTransitions(t *testing.T) { PreviousState: eval.Pending, PreviousStateReason: ngmodels.ConcatReasons(eval.Error.String(), ngmodels.StateReasonKeepLast), State: &State{ - Labels: labels["system + rule"], - State: eval.Alerting, - Results: []Evaluation{ - newEvaluation(t2, eval.Error), - newEvaluation(t3, eval.Alerting), - }, + Labels: labels["system + rule"], + State: eval.Alerting, + LatestResult: newEvaluation(t3, eval.Alerting), StartsAt: t3, EndsAt: t3.Add(ResendDelay * 4), LastEvaluationTime: t3, @@ -3915,12 +3477,9 @@ func TestProcessEvalResults_StateTransitions(t *testing.T) { { PreviousState: eval.Error, State: &State{ - Labels: labels["system + rule"], - State: eval.Normal, - Results: []Evaluation{ - newEvaluation(t1, eval.Error), - newEvaluation(t2, eval.Normal), - }, + Labels: labels["system + rule"], + State: eval.Normal, + LatestResult: newEvaluation(t2, eval.Normal), StartsAt: t2, EndsAt: t2, LastEvaluationTime: t2, @@ -3934,12 +3493,9 @@ func TestProcessEvalResults_StateTransitions(t *testing.T) { PreviousState: eval.Alerting, PreviousStateReason: eval.Error.String(), State: &State{ - Labels: labels["system + rule"], - State: eval.Normal, - Results: []Evaluation{ - newEvaluation(t1, eval.Error), - newEvaluation(t2, eval.Normal), - }, + Labels: labels["system + rule"], + State: eval.Normal, + LatestResult: newEvaluation(t2, eval.Normal), StartsAt: t2, EndsAt: t2, LastEvaluationTime: t2, @@ -3954,12 +3510,9 @@ func TestProcessEvalResults_StateTransitions(t *testing.T) { PreviousState: eval.Normal, PreviousStateReason: eval.Error.String(), State: &State{ - Labels: labels["system + rule"], - State: eval.Normal, - Results: []Evaluation{ - newEvaluation(t1, eval.Error), - newEvaluation(t2, eval.Normal), - }, + Labels: labels["system + rule"], + State: eval.Normal, + LatestResult: newEvaluation(t2, eval.Normal), StartsAt: t1, EndsAt: t1, LastEvaluationTime: t2, @@ -3973,12 +3526,9 @@ func TestProcessEvalResults_StateTransitions(t *testing.T) { PreviousState: eval.Normal, PreviousStateReason: ngmodels.ConcatReasons(eval.Error.String(), ngmodels.StateReasonKeepLast), State: &State{ - Labels: labels["system + rule"], - State: eval.Normal, - Results: []Evaluation{ - newEvaluation(t1, eval.Error), - newEvaluation(t2, eval.Normal), - }, + Labels: labels["system + rule"], + State: eval.Normal, + LatestResult: newEvaluation(t2, eval.Normal), StartsAt: t1, EndsAt: t1, LastEvaluationTime: t2, diff --git a/pkg/services/ngalert/state/manager_test.go b/pkg/services/ngalert/state/manager_test.go index 38a7519f846..358dda190c4 100644 --- a/pkg/services/ngalert/state/manager_test.go +++ b/pkg/services/ngalert/state/manager_test.go @@ -53,26 +53,22 @@ func TestWarmStateCache(t *testing.T) { expectedEntries := []*state.State{ { - AlertRuleUID: rule.UID, - OrgID: rule.OrgID, - Labels: data.Labels{"test1": "testValue1"}, - State: eval.Normal, - Results: []state.Evaluation{ - {EvaluationTime: evaluationTime, EvaluationState: eval.Normal}, - }, + AlertRuleUID: rule.UID, + OrgID: rule.OrgID, + Labels: data.Labels{"test1": "testValue1"}, + State: eval.Normal, + LatestResult: &state.Evaluation{EvaluationTime: evaluationTime, EvaluationState: eval.Normal}, StartsAt: evaluationTime.Add(-1 * time.Minute), EndsAt: evaluationTime.Add(1 * time.Minute), LastEvaluationTime: evaluationTime, Annotations: map[string]string{"testAnnoKey": "testAnnoValue"}, ResultFingerprint: data.Fingerprint(math.MaxUint64), }, { - AlertRuleUID: rule.UID, - OrgID: rule.OrgID, - Labels: data.Labels{"test2": "testValue2"}, - State: eval.Alerting, - Results: []state.Evaluation{ - {EvaluationTime: evaluationTime, EvaluationState: eval.Alerting}, - }, + AlertRuleUID: rule.UID, + OrgID: rule.OrgID, + Labels: data.Labels{"test2": "testValue2"}, + State: eval.Alerting, + LatestResult: &state.Evaluation{EvaluationTime: evaluationTime, EvaluationState: eval.Alerting}, StartsAt: evaluationTime.Add(-1 * time.Minute), EndsAt: evaluationTime.Add(1 * time.Minute), LastEvaluationTime: evaluationTime, @@ -80,13 +76,11 @@ func TestWarmStateCache(t *testing.T) { ResultFingerprint: data.Fingerprint(math.MaxUint64 - 1), }, { - AlertRuleUID: rule.UID, - OrgID: rule.OrgID, - Labels: data.Labels{"test3": "testValue3"}, - State: eval.NoData, - Results: []state.Evaluation{ - {EvaluationTime: evaluationTime, EvaluationState: eval.NoData}, - }, + AlertRuleUID: rule.UID, + OrgID: rule.OrgID, + Labels: data.Labels{"test3": "testValue3"}, + State: eval.NoData, + LatestResult: &state.Evaluation{EvaluationTime: evaluationTime, EvaluationState: eval.NoData}, StartsAt: evaluationTime.Add(-1 * time.Minute), EndsAt: evaluationTime.Add(1 * time.Minute), LastEvaluationTime: evaluationTime, @@ -94,13 +88,11 @@ func TestWarmStateCache(t *testing.T) { ResultFingerprint: data.Fingerprint(0), }, { - AlertRuleUID: rule.UID, - OrgID: rule.OrgID, - Labels: data.Labels{"test4": "testValue4"}, - State: eval.Error, - Results: []state.Evaluation{ - {EvaluationTime: evaluationTime, EvaluationState: eval.Error}, - }, + AlertRuleUID: rule.UID, + OrgID: rule.OrgID, + Labels: data.Labels{"test4": "testValue4"}, + State: eval.Error, + LatestResult: &state.Evaluation{EvaluationTime: evaluationTime, EvaluationState: eval.Error}, StartsAt: evaluationTime.Add(-1 * time.Minute), EndsAt: evaluationTime.Add(1 * time.Minute), LastEvaluationTime: evaluationTime, @@ -108,13 +100,11 @@ func TestWarmStateCache(t *testing.T) { ResultFingerprint: data.Fingerprint(1), }, { - AlertRuleUID: rule.UID, - OrgID: rule.OrgID, - Labels: data.Labels{"test5": "testValue5"}, - State: eval.Pending, - Results: []state.Evaluation{ - {EvaluationTime: evaluationTime, EvaluationState: eval.Pending}, - }, + AlertRuleUID: rule.UID, + OrgID: rule.OrgID, + Labels: data.Labels{"test5": "testValue5"}, + State: eval.Pending, + LatestResult: &state.Evaluation{EvaluationTime: evaluationTime, EvaluationState: eval.Pending}, StartsAt: evaluationTime.Add(-1 * time.Minute), EndsAt: evaluationTime.Add(1 * time.Minute), LastEvaluationTime: evaluationTime, @@ -226,7 +216,7 @@ func TestWarmStateCache(t *testing.T) { setCacheID(entry) cacheEntry := st.Get(entry.OrgID, entry.AlertRuleUID, entry.CacheID) - if diff := cmp.Diff(entry, cacheEntry, cmpopts.IgnoreFields(state.State{}, "Results")); diff != "" { + if diff := cmp.Diff(entry, cacheEntry, cmpopts.IgnoreFields(state.State{}, "LatestResult")); diff != "" { t.Errorf("Result mismatch (-want +got):\n%s", diff) t.FailNow() } @@ -331,8 +321,8 @@ func TestProcessEvalResults(t *testing.T) { ExecErrState: models.ErrorErrState, } - newEvaluation := func(evalTime time.Time, evalState eval.State) state.Evaluation { - return state.Evaluation{ + newEvaluation := func(evalTime time.Time, evalState eval.State) *state.Evaluation { + return &state.Evaluation{ EvaluationTime: evalTime, EvaluationState: evalState, Values: make(map[string]*float64), @@ -398,12 +388,10 @@ func TestProcessEvalResults(t *testing.T) { }, expectedStates: []*state.State{ { - Labels: labels["system + rule + labels1"], - ResultFingerprint: labels1.Fingerprint(), - State: eval.Normal, - Results: []state.Evaluation{ - newEvaluation(t1, eval.Normal), - }, + Labels: labels["system + rule + labels1"], + ResultFingerprint: labels1.Fingerprint(), + State: eval.Normal, + LatestResult: newEvaluation(t1, eval.Normal), StartsAt: t1, EndsAt: t1, LastEvaluationTime: t1, @@ -422,23 +410,19 @@ func TestProcessEvalResults(t *testing.T) { expectedAnnotations: 1, expectedStates: []*state.State{ { - Labels: labels["system + rule + labels1"], - ResultFingerprint: labels1.Fingerprint(), - State: eval.Normal, - Results: []state.Evaluation{ - newEvaluation(t1, eval.Normal), - }, + Labels: labels["system + rule + labels1"], + ResultFingerprint: labels1.Fingerprint(), + State: eval.Normal, + LatestResult: newEvaluation(t1, eval.Normal), StartsAt: t1, EndsAt: t1, LastEvaluationTime: t1, }, { - Labels: labels["system + rule + labels2"], - ResultFingerprint: labels2.Fingerprint(), - State: eval.Alerting, - Results: []state.Evaluation{ - newEvaluation(t1, eval.Alerting), - }, + Labels: labels["system + rule + labels2"], + ResultFingerprint: labels2.Fingerprint(), + State: eval.Alerting, + LatestResult: newEvaluation(t1, eval.Alerting), StartsAt: t1, EndsAt: t1.Add(state.ResendDelay * 4), LastEvaluationTime: t1, @@ -458,13 +442,10 @@ func TestProcessEvalResults(t *testing.T) { }, expectedStates: []*state.State{ { - Labels: labels["system + rule + labels1"], - ResultFingerprint: labels1.Fingerprint(), - State: eval.Normal, - Results: []state.Evaluation{ - newEvaluation(t1, eval.Normal), - newEvaluation(tn(6), eval.Normal), - }, + Labels: labels["system + rule + labels1"], + ResultFingerprint: labels1.Fingerprint(), + State: eval.Normal, + LatestResult: newEvaluation(tn(6), eval.Normal), StartsAt: t1, EndsAt: t1, LastEvaluationTime: tn(6), @@ -485,13 +466,10 @@ func TestProcessEvalResults(t *testing.T) { expectedAnnotations: 1, expectedStates: []*state.State{ { - Labels: labels["system + rule + labels1"], - ResultFingerprint: labels1.Fingerprint(), - State: eval.Alerting, - Results: []state.Evaluation{ - newEvaluation(t1, eval.Normal), - newEvaluation(t2, eval.Alerting), - }, + Labels: labels["system + rule + labels1"], + ResultFingerprint: labels1.Fingerprint(), + State: eval.Alerting, + LatestResult: newEvaluation(t2, eval.Alerting), StartsAt: t2, EndsAt: t2.Add(state.ResendDelay * 4), LastEvaluationTime: t2, @@ -518,13 +496,10 @@ func TestProcessEvalResults(t *testing.T) { expectedAnnotations: 2, expectedStates: []*state.State{ { - Labels: labels["system + rule + labels1"], - ResultFingerprint: labels1.Fingerprint(), - State: eval.Alerting, - Results: []state.Evaluation{ - newEvaluation(t3, eval.Alerting), - newEvaluation(tn(4), eval.Alerting), - }, + Labels: labels["system + rule + labels1"], + ResultFingerprint: labels1.Fingerprint(), + State: eval.Alerting, + LatestResult: newEvaluation(tn(4), eval.Alerting), StartsAt: tn(4), EndsAt: tn(4).Add(state.ResendDelay * 4), LastEvaluationTime: tn(4), @@ -554,13 +529,10 @@ func TestProcessEvalResults(t *testing.T) { expectedAnnotations: 3, // Normal -> Pending, Pending -> NoData, NoData -> Pending expectedStates: []*state.State{ { - Labels: labels["system + rule + labels1"], - ResultFingerprint: labels1.Fingerprint(), - State: eval.Pending, - Results: []state.Evaluation{ - newEvaluation(tn(4), eval.Alerting), - newEvaluation(tn(5), eval.Alerting), - }, + Labels: labels["system + rule + labels1"], + ResultFingerprint: labels1.Fingerprint(), + State: eval.Pending, + LatestResult: newEvaluation(tn(5), eval.Alerting), StartsAt: tn(4), EndsAt: tn(4).Add(state.ResendDelay * 4), LastEvaluationTime: tn(5), @@ -587,13 +559,10 @@ func TestProcessEvalResults(t *testing.T) { expectedAnnotations: 3, expectedStates: []*state.State{ { - Labels: labels["system + rule + labels1"], - ResultFingerprint: labels1.Fingerprint(), - State: eval.NoData, - Results: []state.Evaluation{ - newEvaluation(t3, eval.Alerting), - newEvaluation(tn(4), eval.NoData), - }, + Labels: labels["system + rule + labels1"], + ResultFingerprint: labels1.Fingerprint(), + State: eval.NoData, + LatestResult: newEvaluation(tn(4), eval.NoData), StartsAt: tn(4), EndsAt: tn(4).Add(state.ResendDelay * 4), LastEvaluationTime: tn(4), @@ -617,11 +586,8 @@ func TestProcessEvalResults(t *testing.T) { Labels: labels["system + rule + labels1"], ResultFingerprint: labels1.Fingerprint(), - State: eval.Pending, - Results: []state.Evaluation{ - newEvaluation(t1, eval.Normal), - newEvaluation(t2, eval.Alerting), - }, + State: eval.Pending, + LatestResult: newEvaluation(t2, eval.Alerting), StartsAt: t2, EndsAt: t2.Add(state.ResendDelay * 4), LastEvaluationTime: t2, @@ -642,13 +608,10 @@ func TestProcessEvalResults(t *testing.T) { expectedAnnotations: 1, expectedStates: []*state.State{ { - Labels: labels["system + rule + labels1"], - ResultFingerprint: labels1.Fingerprint(), - State: eval.Pending, - Results: []state.Evaluation{ - newEvaluation(t1, eval.Alerting), - newEvaluation(t2, eval.Alerting), - }, + Labels: labels["system + rule + labels1"], + ResultFingerprint: labels1.Fingerprint(), + State: eval.Pending, + LatestResult: newEvaluation(t2, eval.Alerting), StartsAt: t1, EndsAt: t1.Add(state.ResendDelay * 4), LastEvaluationTime: t2, @@ -669,14 +632,11 @@ func TestProcessEvalResults(t *testing.T) { expectedAnnotations: 1, expectedStates: []*state.State{ { - Labels: labels["system + rule + labels1"], - ResultFingerprint: labels1.Fingerprint(), - State: eval.Pending, - StateReason: eval.NoData.String(), - Results: []state.Evaluation{ - newEvaluation(t1, eval.Normal), - newEvaluation(t2, eval.NoData), - }, + Labels: labels["system + rule + labels1"], + ResultFingerprint: labels1.Fingerprint(), + State: eval.Pending, + StateReason: eval.NoData.String(), + LatestResult: newEvaluation(t2, eval.NoData), StartsAt: t2, EndsAt: t2.Add(state.ResendDelay * 4), LastEvaluationTime: t2, @@ -706,15 +666,11 @@ func TestProcessEvalResults(t *testing.T) { expectedAnnotations: 2, expectedStates: []*state.State{ { - Labels: labels["system + rule + labels1"], - ResultFingerprint: labels1.Fingerprint(), - State: eval.Alerting, - StateReason: eval.NoData.String(), - Results: []state.Evaluation{ - newEvaluation(t3, eval.NoData), - newEvaluation(tn(4), eval.NoData), - newEvaluation(tn(5), eval.NoData), - }, + Labels: labels["system + rule + labels1"], + ResultFingerprint: labels1.Fingerprint(), + State: eval.Alerting, + StateReason: eval.NoData.String(), + LatestResult: newEvaluation(tn(5), eval.NoData), StartsAt: tn(5), EndsAt: tn(5).Add(state.ResendDelay * 4), LastEvaluationTime: tn(5), @@ -735,13 +691,10 @@ func TestProcessEvalResults(t *testing.T) { expectedAnnotations: 1, expectedStates: []*state.State{ { - Labels: labels["system + rule + labels1"], - ResultFingerprint: labels1.Fingerprint(), - State: eval.NoData, - Results: []state.Evaluation{ - newEvaluation(t1, eval.Normal), - newEvaluation(t2, eval.NoData), - }, + Labels: labels["system + rule + labels1"], + ResultFingerprint: labels1.Fingerprint(), + State: eval.NoData, + LatestResult: newEvaluation(t2, eval.NoData), StartsAt: t2, EndsAt: t2.Add(state.ResendDelay * 4), LastEvaluationTime: t2, @@ -762,23 +715,19 @@ func TestProcessEvalResults(t *testing.T) { expectedAnnotations: 1, expectedStates: []*state.State{ { - Labels: labels["system + rule + labels1"], - ResultFingerprint: labels1.Fingerprint(), - State: eval.Normal, - Results: []state.Evaluation{ - newEvaluation(t1, eval.Normal), - }, + Labels: labels["system + rule + labels1"], + ResultFingerprint: labels1.Fingerprint(), + State: eval.Normal, + LatestResult: newEvaluation(t1, eval.Normal), StartsAt: t1, EndsAt: t1, LastEvaluationTime: t1, }, { - Labels: labels["system + rule"], - ResultFingerprint: data.Labels{}.Fingerprint(), - State: eval.NoData, - Results: []state.Evaluation{ - newEvaluation(t2, eval.NoData), - }, + Labels: labels["system + rule"], + ResultFingerprint: data.Labels{}.Fingerprint(), + State: eval.NoData, + LatestResult: newEvaluation(t2, eval.NoData), StartsAt: t2, EndsAt: t2.Add(state.ResendDelay * 4), LastEvaluationTime: t2, @@ -800,34 +749,28 @@ func TestProcessEvalResults(t *testing.T) { expectedAnnotations: 1, expectedStates: []*state.State{ { - Labels: labels["system + rule + labels1"], - ResultFingerprint: labels1.Fingerprint(), - State: eval.Normal, - Results: []state.Evaluation{ - newEvaluation(t1, eval.Normal), - }, + Labels: labels["system + rule + labels1"], + ResultFingerprint: labels1.Fingerprint(), + State: eval.Normal, + LatestResult: newEvaluation(t1, eval.Normal), StartsAt: t1, EndsAt: t1, LastEvaluationTime: t1, }, { - Labels: labels["system + rule + labels2"], - ResultFingerprint: labels2.Fingerprint(), - State: eval.Normal, - Results: []state.Evaluation{ - newEvaluation(t1, eval.Normal), - }, + Labels: labels["system + rule + labels2"], + ResultFingerprint: labels2.Fingerprint(), + State: eval.Normal, + LatestResult: newEvaluation(t1, eval.Normal), StartsAt: t1, EndsAt: t1, LastEvaluationTime: t1, }, { - Labels: labels["system + rule"], - ResultFingerprint: data.Labels{}.Fingerprint(), - State: eval.NoData, - Results: []state.Evaluation{ - newEvaluation(t2, eval.NoData), - }, + Labels: labels["system + rule"], + ResultFingerprint: data.Labels{}.Fingerprint(), + State: eval.NoData, + LatestResult: newEvaluation(t2, eval.NoData), StartsAt: t2, EndsAt: t2.Add(state.ResendDelay * 4), LastEvaluationTime: t2, @@ -851,24 +794,19 @@ func TestProcessEvalResults(t *testing.T) { expectedAnnotations: 1, expectedStates: []*state.State{ { - Labels: labels["system + rule + labels1"], - ResultFingerprint: labels1.Fingerprint(), - State: eval.Normal, - Results: []state.Evaluation{ - newEvaluation(t1, eval.Normal), - newEvaluation(t3, eval.Normal), - }, + Labels: labels["system + rule + labels1"], + ResultFingerprint: labels1.Fingerprint(), + State: eval.Normal, + LatestResult: newEvaluation(t3, eval.Normal), StartsAt: t1, EndsAt: t1, LastEvaluationTime: t3, }, { - Labels: labels["system + rule + no-data"], - ResultFingerprint: noDataLabels.Fingerprint(), - State: eval.NoData, - Results: []state.Evaluation{ - newEvaluation(t2, eval.NoData), - }, + Labels: labels["system + rule + no-data"], + ResultFingerprint: noDataLabels.Fingerprint(), + State: eval.NoData, + LatestResult: newEvaluation(t2, eval.NoData), StartsAt: t2, EndsAt: t2.Add(state.ResendDelay * 4), LastEvaluationTime: t2, @@ -895,16 +833,11 @@ func TestProcessEvalResults(t *testing.T) { expectedAnnotations: 1, expectedStates: []*state.State{ { - Labels: labels["system + rule + labels1"], - ResultFingerprint: labels1.Fingerprint(), - State: eval.Alerting, - StateReason: models.ConcatReasons(eval.NoData.String(), models.StateReasonKeepLast), - Results: []state.Evaluation{ - newEvaluation(t1, eval.Normal), - newEvaluation(t2, eval.NoData), - newEvaluation(t3, eval.Alerting), - newEvaluation(tn(4), eval.NoData), - }, + Labels: labels["system + rule + labels1"], + ResultFingerprint: labels1.Fingerprint(), + State: eval.Alerting, + StateReason: models.ConcatReasons(eval.NoData.String(), models.StateReasonKeepLast), + LatestResult: newEvaluation(tn(4), eval.NoData), StartsAt: t3, EndsAt: tn(4).Add(state.ResendDelay * 4), LastEvaluationTime: tn(4), @@ -931,14 +864,11 @@ func TestProcessEvalResults(t *testing.T) { expectedAnnotations: 2, expectedStates: []*state.State{ { - Labels: labels["system + rule + labels1"], - ResultFingerprint: labels1.Fingerprint(), - State: eval.Alerting, - StateReason: models.ConcatReasons(eval.NoData.String(), models.StateReasonKeepLast), - Results: []state.Evaluation{ - newEvaluation(t3, eval.NoData), - newEvaluation(tn(4), eval.NoData), - }, + Labels: labels["system + rule + labels1"], + ResultFingerprint: labels1.Fingerprint(), + State: eval.Alerting, + StateReason: models.ConcatReasons(eval.NoData.String(), models.StateReasonKeepLast), + LatestResult: newEvaluation(tn(4), eval.NoData), StartsAt: tn(4), EndsAt: tn(4).Add(state.ResendDelay * 4), LastEvaluationTime: tn(4), @@ -959,14 +889,11 @@ func TestProcessEvalResults(t *testing.T) { expectedAnnotations: 0, expectedStates: []*state.State{ { - Labels: labels["system + rule + labels1"], - ResultFingerprint: labels1.Fingerprint(), - State: eval.Normal, - StateReason: eval.NoData.String(), - Results: []state.Evaluation{ - newEvaluation(t1, eval.Normal), - newEvaluation(t2, eval.NoData), - }, + Labels: labels["system + rule + labels1"], + ResultFingerprint: labels1.Fingerprint(), + State: eval.Normal, + StateReason: eval.NoData.String(), + LatestResult: newEvaluation(t2, eval.NoData), StartsAt: t1, EndsAt: t1, LastEvaluationTime: t2, @@ -987,15 +914,12 @@ func TestProcessEvalResults(t *testing.T) { expectedAnnotations: 1, expectedStates: []*state.State{ { - Labels: labels["system + rule + labels1"], - ResultFingerprint: labels1.Fingerprint(), - State: eval.Pending, - StateReason: eval.Error.String(), - Error: errors.New("with_state_error"), - Results: []state.Evaluation{ - newEvaluation(t1, eval.Normal), - newEvaluation(t2, eval.Error), - }, + Labels: labels["system + rule + labels1"], + ResultFingerprint: labels1.Fingerprint(), + State: eval.Pending, + StateReason: eval.Error.String(), + Error: errors.New("with_state_error"), + LatestResult: newEvaluation(t2, eval.Error), StartsAt: t2, EndsAt: t2.Add(state.ResendDelay * 4), LastEvaluationTime: t2, @@ -1025,16 +949,12 @@ func TestProcessEvalResults(t *testing.T) { expectedAnnotations: 2, expectedStates: []*state.State{ { - Labels: labels["system + rule + labels1"], - ResultFingerprint: labels1.Fingerprint(), - State: eval.Alerting, - StateReason: eval.Error.String(), - Error: errors.New("with_state_error"), - Results: []state.Evaluation{ - newEvaluation(t3, eval.Error), - newEvaluation(tn(4), eval.Error), - newEvaluation(tn(5), eval.Error), - }, + Labels: labels["system + rule + labels1"], + ResultFingerprint: labels1.Fingerprint(), + State: eval.Alerting, + StateReason: eval.Error.String(), + Error: errors.New("with_state_error"), + LatestResult: newEvaluation(tn(5), eval.Error), StartsAt: tn(5), EndsAt: tn(5).Add(state.ResendDelay * 4), LastEvaluationTime: tn(5), @@ -1067,13 +987,10 @@ func TestProcessEvalResults(t *testing.T) { "datasource_uid": "datasource_uid_1", "ref_id": "A", }), - ResultFingerprint: labels1.Fingerprint(), - State: eval.Error, - Error: expr.MakeQueryError("A", "datasource_uid_1", errors.New("this is an error")), - Results: []state.Evaluation{ - newEvaluation(t1, eval.Normal), - newEvaluation(t2, eval.Error), - }, + ResultFingerprint: labels1.Fingerprint(), + State: eval.Error, + Error: expr.MakeQueryError("A", "datasource_uid_1", errors.New("this is an error")), + LatestResult: newEvaluation(t2, eval.Error), StartsAt: t2, EndsAt: t2.Add(state.ResendDelay * 4), LastEvaluationTime: t2, @@ -1102,16 +1019,11 @@ func TestProcessEvalResults(t *testing.T) { expectedAnnotations: 1, expectedStates: []*state.State{ { - Labels: labels["system + rule + labels1"], - ResultFingerprint: labels1.Fingerprint(), - State: eval.Alerting, - StateReason: models.ConcatReasons(eval.Error.String(), models.StateReasonKeepLast), - Results: []state.Evaluation{ - newEvaluation(t1, eval.Normal), - newEvaluation(t2, eval.Error), - newEvaluation(t3, eval.Alerting), - newEvaluation(tn(4), eval.Error), - }, + Labels: labels["system + rule + labels1"], + ResultFingerprint: labels1.Fingerprint(), + State: eval.Alerting, + StateReason: models.ConcatReasons(eval.Error.String(), models.StateReasonKeepLast), + LatestResult: newEvaluation(tn(4), eval.Error), StartsAt: t3, EndsAt: tn(4).Add(state.ResendDelay * 4), LastEvaluationTime: tn(4), @@ -1138,14 +1050,11 @@ func TestProcessEvalResults(t *testing.T) { expectedAnnotations: 2, expectedStates: []*state.State{ { - Labels: labels["system + rule + labels1"], - ResultFingerprint: labels1.Fingerprint(), - State: eval.Alerting, - StateReason: models.ConcatReasons(eval.Error.String(), models.StateReasonKeepLast), - Results: []state.Evaluation{ - newEvaluation(t3, eval.Error), - newEvaluation(tn(4), eval.Error), - }, + Labels: labels["system + rule + labels1"], + ResultFingerprint: labels1.Fingerprint(), + State: eval.Alerting, + StateReason: models.ConcatReasons(eval.Error.String(), models.StateReasonKeepLast), + LatestResult: newEvaluation(tn(4), eval.Error), StartsAt: tn(4), EndsAt: tn(4).Add(state.ResendDelay * 4), LastEvaluationTime: tn(4), @@ -1166,14 +1075,11 @@ func TestProcessEvalResults(t *testing.T) { expectedAnnotations: 1, expectedStates: []*state.State{ { - Labels: labels["system + rule + labels1"], - ResultFingerprint: labels1.Fingerprint(), - State: eval.Normal, - StateReason: eval.Error.String(), - Results: []state.Evaluation{ - newEvaluation(t1, eval.Normal), - newEvaluation(t2, eval.Error), - }, + Labels: labels["system + rule + labels1"], + ResultFingerprint: labels1.Fingerprint(), + State: eval.Normal, + StateReason: eval.Error.String(), + LatestResult: newEvaluation(t2, eval.Error), StartsAt: t1, EndsAt: t1, LastEvaluationTime: t2, @@ -1194,14 +1100,11 @@ func TestProcessEvalResults(t *testing.T) { expectedAnnotations: 2, expectedStates: []*state.State{ { - Labels: labels["system + rule + labels1"], - ResultFingerprint: labels1.Fingerprint(), - State: eval.Normal, - StateReason: eval.Error.String(), - Results: []state.Evaluation{ - newEvaluation(t1, eval.Alerting), - newEvaluation(t2, eval.Error), - }, + Labels: labels["system + rule + labels1"], + ResultFingerprint: labels1.Fingerprint(), + State: eval.Normal, + StateReason: eval.Error.String(), + LatestResult: newEvaluation(t2, eval.Error), StartsAt: t2, EndsAt: t2, LastEvaluationTime: t2, @@ -1234,14 +1137,11 @@ func TestProcessEvalResults(t *testing.T) { expectedAnnotations: 3, expectedStates: []*state.State{ { - Labels: labels["system + rule + labels1"], - ResultFingerprint: labels1.Fingerprint(), - State: eval.Error, - Error: fmt.Errorf("with_state_error"), - Results: []state.Evaluation{ - newEvaluation(tn(5), eval.Error), - newEvaluation(tn(6), eval.Error), - }, + Labels: labels["system + rule + labels1"], + ResultFingerprint: labels1.Fingerprint(), + State: eval.Error, + Error: fmt.Errorf("with_state_error"), + LatestResult: newEvaluation(tn(6), eval.Error), StartsAt: tn(4), EndsAt: tn(6).Add(state.ResendDelay * 4), LastEvaluationTime: tn(6), @@ -1268,14 +1168,10 @@ func TestProcessEvalResults(t *testing.T) { expectedAnnotations: 3, expectedStates: []*state.State{ { - Labels: labels["system + rule + labels1"], - ResultFingerprint: labels1.Fingerprint(), - State: eval.Pending, - Results: []state.Evaluation{ - newEvaluation(tn(4), eval.Alerting), - newEvaluation(tn(5), eval.Error), - newEvaluation(tn(8), eval.Alerting), - }, + Labels: labels["system + rule + labels1"], + ResultFingerprint: labels1.Fingerprint(), + State: eval.Pending, + LatestResult: newEvaluation(tn(8), eval.Alerting), StartsAt: tn(8), EndsAt: tn(8).Add(state.ResendDelay * 4), LastEvaluationTime: tn(8), @@ -1302,14 +1198,10 @@ func TestProcessEvalResults(t *testing.T) { expectedAnnotations: 3, expectedStates: []*state.State{ { - Labels: labels["system + rule + labels1"], - ResultFingerprint: labels1.Fingerprint(), - State: eval.NoData, - Results: []state.Evaluation{ - newEvaluation(tn(4), eval.Alerting), - newEvaluation(tn(5), eval.Error), - newEvaluation(tn(6), eval.NoData), - }, + Labels: labels["system + rule + labels1"], + ResultFingerprint: labels1.Fingerprint(), + State: eval.NoData, + LatestResult: newEvaluation(tn(6), eval.NoData), StartsAt: tn(6), EndsAt: tn(6).Add(state.ResendDelay * 4), LastEvaluationTime: tn(6), @@ -1340,10 +1232,8 @@ func TestProcessEvalResults(t *testing.T) { "label": "test", "job": "prod/grafana", }), - State: eval.Normal, - Results: []state.Evaluation{ - newEvaluation(t1, eval.Normal), - }, + State: eval.Normal, + LatestResult: newEvaluation(t1, eval.Normal), StartsAt: t1, EndsAt: t1, LastEvaluationTime: t1, @@ -1374,14 +1264,10 @@ func TestProcessEvalResults(t *testing.T) { }, expectedStates: []*state.State{ { - Labels: labels["system + rule"], - ResultFingerprint: data.Labels{}.Fingerprint(), - State: eval.Alerting, - Results: []state.Evaluation{ - newEvaluation(t1, eval.Alerting), - newEvaluation(t2, eval.Error), - newEvaluation(t3, eval.Alerting), - }, + Labels: labels["system + rule"], + ResultFingerprint: data.Labels{}.Fingerprint(), + State: eval.Alerting, + LatestResult: newEvaluation(t3, eval.Alerting), StartsAt: t3, EndsAt: t3.Add(state.ResendDelay * 4), LastEvaluationTime: t3, @@ -1630,13 +1516,11 @@ func TestStaleResultsHandler(t *testing.T) { }, Values: make(map[string]float64), State: eval.Normal, - Results: []state.Evaluation{ - { - EvaluationTime: evaluationTime, - EvaluationState: eval.Normal, - Values: make(map[string]*float64), - Condition: "A", - }, + LatestResult: &state.Evaluation{ + EvaluationTime: evaluationTime, + EvaluationState: eval.Normal, + Values: make(map[string]*float64), + Condition: "A", }, StartsAt: evaluationTime, EndsAt: evaluationTime, diff --git a/pkg/services/ngalert/state/state.go b/pkg/services/ngalert/state/state.go index 11c86f6b10e..cb6cf0767a9 100644 --- a/pkg/services/ngalert/state/state.go +++ b/pkg/services/ngalert/state/state.go @@ -38,8 +38,8 @@ type State struct { // ResultFingerprint is a hash of labels of the result before it is processed by ResultFingerprint data.Fingerprint - // Results contains the result of the current and previous evaluations. - Results []Evaluation + // LatestResult contains the result of the most recent evaluation, if available. + LatestResult *Evaluation // Error is set if the current evaluation returned an error. If error is non-nil results // can still contain the results of previous evaluations. @@ -427,20 +427,6 @@ func (a *State) Equals(b *State) bool { data.Labels(a.Annotations).String() == data.Labels(b.Annotations).String() } -func (a *State) TrimResults(alertRule *models.AlertRule) { - numBuckets := int64(alertRule.For.Seconds()) / alertRule.IntervalSeconds - if numBuckets == 0 { - numBuckets = 10 // keep at least 10 evaluations in the event For is set to 0 - } - - if len(a.Results) < int(numBuckets) { - return - } - newResults := make([]Evaluation, numBuckets) - copy(newResults, a.Results[len(a.Results)-int(numBuckets):]) - a.Results = newResults -} - func nextEndsTime(interval int64, evaluatedAt time.Time) time.Time { ends := ResendDelay intv := time.Second * time.Duration(interval) @@ -464,11 +450,11 @@ func (a *State) GetLabels(opts ...models.LabelOption) map[string]string { } func (a *State) GetLastEvaluationValuesForCondition() map[string]float64 { - if len(a.Results) <= 0 { + if a.LatestResult == nil { return nil } - lastResult := a.Results[len(a.Results)-1] + lastResult := *a.LatestResult r := make(map[string]float64, len(lastResult.Values)) for refID, value := range lastResult.Values { diff --git a/pkg/services/ngalert/state/state_test.go b/pkg/services/ngalert/state/state_test.go index 1684b7036c1..458bd64bacf 100644 --- a/pkg/services/ngalert/state/state_test.go +++ b/pkg/services/ngalert/state/state_test.go @@ -475,9 +475,9 @@ func TestNeedsSending(t *testing.T) { } func TestGetLastEvaluationValuesForCondition(t *testing.T) { - genState := func(results []Evaluation) *State { + genState := func(latestResult *Evaluation) *State { return &State{ - Results: results, + LatestResult: latestResult, } } @@ -487,57 +487,43 @@ func TestGetLastEvaluationValuesForCondition(t *testing.T) { }) 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": util.Pointer(rand.Float64()), - }, - Condition: "A", - }, - { - EvaluationTime: time.Time{}, - EvaluationState: 0, - Values: map[string]*float64{ - "B": util.Pointer(rand.Float64()), - "A": util.Pointer(expected), - }, - Condition: "A", + eval := &Evaluation{ + EvaluationTime: time.Time{}, + EvaluationState: 0, + Values: map[string]*float64{ + "B": util.Pointer(rand.Float64()), + "A": util.Pointer(expected), }, + Condition: "A", } - result := genState(evals).GetLastEvaluationValuesForCondition() + result := genState(eval).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": util.Pointer(rand.Float64()), - }, - Condition: "A", + eval := &Evaluation{ + EvaluationTime: time.Time{}, + EvaluationState: 0, + Values: map[string]*float64{ + "C": util.Pointer(rand.Float64()), }, + Condition: "A", } - result := genState(evals).GetLastEvaluationValuesForCondition() + result := genState(eval).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", + eval := &Evaluation{ + EvaluationTime: time.Time{}, + EvaluationState: 0, + Values: map[string]*float64{ + "A": nil, }, + Condition: "A", } - result := genState(evals).GetLastEvaluationValuesForCondition() + result := genState(eval).GetLastEvaluationValuesForCondition() require.NotNil(t, result) require.Len(t, result, 1) require.Contains(t, result, "A")