From 69c8200fc95935949af4fdb3cbeb009fe37a978f Mon Sep 17 00:00:00 2001 From: Yuri Tseretyan Date: Wed, 9 Aug 2023 12:21:12 -0400 Subject: [PATCH] Alerting: Add more tests for state manager ProcessEvalResults (#73019) Co-authored-by: Matthew Jacobson --- .../ngalert/state/manager_private_test.go | 2494 +++++++++++++++++ 1 file changed, 2494 insertions(+) diff --git a/pkg/services/ngalert/state/manager_private_test.go b/pkg/services/ngalert/state/manager_private_test.go index e4ddb5ff6b4..ff03833545c 100644 --- a/pkg/services/ngalert/state/manager_private_test.go +++ b/pkg/services/ngalert/state/manager_private_test.go @@ -2,20 +2,32 @@ package state import ( "context" + "errors" "fmt" "math/rand" + "sort" "testing" "time" + "github.com/benbjohnson/clock" + "github.com/google/go-cmp/cmp" + "github.com/google/go-cmp/cmp/cmpopts" + "github.com/grafana/grafana-plugin-sdk-go/data" + "github.com/prometheus/client_golang/prometheus" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" + "github.com/grafana/grafana/pkg/expr" "github.com/grafana/grafana/pkg/infra/log/logtest" "github.com/grafana/grafana/pkg/services/ngalert/eval" + "github.com/grafana/grafana/pkg/services/ngalert/metrics" ngmodels "github.com/grafana/grafana/pkg/services/ngalert/models" + "github.com/grafana/grafana/pkg/util" ) +var testMetrics = metrics.NewNGAlert(prometheus.NewPedanticRegistry()).GetStateMetrics() + // Not for parallel tests. type CountingImageService struct { Called int @@ -147,3 +159,2485 @@ func TestManager_saveAlertStates(t *testing.T) { } }) } + +// TestProcessEvalResults_StateTransitions tests how state.Manager's ProcessEvalResults processes results and creates or changes states. +// In other words, it tests the state transition. +// +// The tests use a micro-framework that has the following features: +// 1. It uses a base rule definition and allows each test case mutate its copy. +// 2. Expected State definition omits several fields which are patched before assertion +// if they are not specified explicitly (see function "patchState" for patched fields). +// This allows specifications to be more condense and mention only important fields. +// 3. Expected State definition uses some shortcut functions to make the specification more clear. +// Expected labels are populated from a labels map where keys = description of what labels included in its values. +// This allows us to specify the list of labels expected to be in the state in one line, e.g. "system + rule + labels1" +// Evaluations are populated using function `newEvaluation` that pre-set all important fields. +// 4. Each test case can contain multiple consecutive evaluations at different times with assertions at every interval. +// The framework offers variables t1, t2, t3 and function tN(n) that provide timestamps of different evaluations. +// 5. NoData and Error tests require assertions for all possible execution options for the same input. +// +// # Naming convention for tests cases. +// +// The tests are formatted to the input characteristics, such as rule definition, +// result format (multi- or single- dimensional) and at which times the assertions are defined. +// +//