@ -1,10 +1,12 @@
package sta te
package tests
import (
"fmt"
"testing"
"time"
"github.com/grafana/grafana/pkg/services/ngalert/state"
"github.com/grafana/grafana/pkg/infra/log"
"github.com/grafana/grafana-plugin-sdk-go/data"
@ -18,16 +20,30 @@ func TestProcessEvalResults(t *testing.T) {
if err != nil {
t . Fatalf ( "error parsing date format: %s" , err . Error ( ) )
}
cacheId := "test_uid map[label1:value1 label2:value2]"
cacheId := "map[__alert_rule_namespace_uid__:test_namespace __alert_rule_title__:test_title __alert_rule_uid__:test_uid label1:value1 label2:value2]"
alertRule := models . AlertRule {
ID : 1 ,
OrgID : 123 ,
Title : "test_title" ,
Condition : "A" ,
UID : "test_uid" ,
NamespaceUID : "test_namespace" ,
}
expectedLabels := data . Labels {
"label1" : "value1" ,
"label2" : "value2" ,
"__alert_rule_uid__" : "test_uid" ,
"__alert_rule_namespace_uid__" : "test_namespace" ,
"__alert_rule_title__" : "test_title" ,
}
testCases := [ ] struct {
desc string
uid string
evalResults eval . Results
condition models . Condition
expectedState eval . State
expectedReturnedStateCount int
expectedResultCount int
expectedCacheEntries [ ] AlertState
expectedCacheEntries [ ] state . AlertState
} {
{
desc : "given a single evaluation result" ,
@ -39,21 +55,17 @@ func TestProcessEvalResults(t *testing.T) {
EvaluatedAt : evaluationTime ,
} ,
} ,
condition : models . Condition {
Condition : "A" ,
OrgID : 123 ,
} ,
expectedState : eval . Normal ,
expectedReturnedStateCount : 0 ,
expectedResultCount : 1 ,
expectedCacheEntries : [ ] AlertState {
expectedCacheEntries : [ ] state . AlertState {
{
UID : "test_uid" ,
OrgID : 123 ,
CacheId : cacheId ,
Labels : data . Labels { "label1" : "value1" , "label2" : "value2" } ,
Labels : expectedLabels ,
State : eval . Normal ,
Results : [ ] StateEvaluation {
Results : [ ] state . StateEvaluation {
{ EvaluationTime : evaluationTime , EvaluationState : eval . Normal } ,
} ,
StartsAt : time . Time { } ,
@ -77,21 +89,17 @@ func TestProcessEvalResults(t *testing.T) {
EvaluatedAt : evaluationTime . Add ( 1 * time . Minute ) ,
} ,
} ,
condition : models . Condition {
Condition : "A" ,
OrgID : 123 ,
} ,
expectedState : eval . Alerting ,
expectedReturnedStateCount : 1 ,
expectedResultCount : 2 ,
expectedCacheEntries : [ ] AlertState {
expectedCacheEntries : [ ] state . AlertState {
{
UID : "test_uid" ,
OrgID : 123 ,
CacheId : cacheId ,
Labels : data . Labels { "label1" : "value1" , "label2" : "value2" } ,
Labels : expectedLabels ,
State : eval . Alerting ,
Results : [ ] StateEvaluation {
Results : [ ] state . StateEvaluation {
{ EvaluationTime : evaluationTime , EvaluationState : eval . Normal } ,
{ EvaluationTime : evaluationTime . Add ( 1 * time . Minute ) , EvaluationState : eval . Alerting } ,
} ,
@ -116,21 +124,17 @@ func TestProcessEvalResults(t *testing.T) {
EvaluatedAt : evaluationTime . Add ( 1 * time . Minute ) ,
} ,
} ,
condition : models . Condition {
Condition : "A" ,
OrgID : 123 ,
} ,
expectedState : eval . Normal ,
expectedReturnedStateCount : 1 ,
expectedResultCount : 2 ,
expectedCacheEntries : [ ] AlertState {
expectedCacheEntries : [ ] state . AlertState {
{
UID : "test_uid" ,
OrgID : 123 ,
CacheId : cacheId ,
Labels : data . Labels { "label1" : "value1" , "label2" : "value2" } ,
Labels : expectedLabels ,
State : eval . Normal ,
Results : [ ] StateEvaluation {
Results : [ ] state . StateEvaluation {
{ EvaluationTime : evaluationTime , EvaluationState : eval . Alerting } ,
{ EvaluationTime : evaluationTime . Add ( 1 * time . Minute ) , EvaluationState : eval . Normal } ,
} ,
@ -155,21 +159,17 @@ func TestProcessEvalResults(t *testing.T) {
EvaluatedAt : evaluationTime . Add ( 1 * time . Minute ) ,
} ,
} ,
condition : models . Condition {
Condition : "A" ,
OrgID : 123 ,
} ,
expectedState : eval . Alerting ,
expectedReturnedStateCount : 0 ,
expectedResultCount : 2 ,
expectedCacheEntries : [ ] AlertState {
expectedCacheEntries : [ ] state . AlertState {
{
UID : "test_uid" ,
OrgID : 123 ,
CacheId : cacheId ,
Labels : data . Labels { "label1" : "value1" , "label2" : "value2" } ,
Labels : expectedLabels ,
State : eval . Alerting ,
Results : [ ] StateEvaluation {
Results : [ ] state . StateEvaluation {
{ EvaluationTime : evaluationTime , EvaluationState : eval . Alerting } ,
{ EvaluationTime : evaluationTime . Add ( 1 * time . Minute ) , EvaluationState : eval . Alerting } ,
} ,
@ -194,22 +194,18 @@ func TestProcessEvalResults(t *testing.T) {
EvaluatedAt : evaluationTime . Add ( 1 * time . Minute ) ,
} ,
} ,
condition : models . Condition {
Condition : "A" ,
OrgID : 123 ,
} ,
expectedState : eval . Normal ,
expectedReturnedStateCount : 0 ,
expectedResultCount : 2 ,
expectedCacheEntries : [ ] AlertState {
expectedCacheEntries : [ ] state . AlertState {
{
UID : "test_uid" ,
OrgID : 123 ,
CacheId : cacheId ,
Labels : data . Labels { "label1" : "value1" , "label2" : "value2" } ,
Labels : expectedLabels ,
State : eval . Normal ,
Results : [ ] StateEvaluation {
{ evaluationTime , eval . Normal } ,
Results : [ ] state . StateEvaluation {
{ EvaluationTime : evaluationTime , EvaluationState : eval . Normal } ,
{ EvaluationTime : evaluationTime . Add ( 1 * time . Minute ) , EvaluationState : eval . Normal } ,
} ,
StartsAt : time . Time { } ,
@ -222,8 +218,8 @@ func TestProcessEvalResults(t *testing.T) {
for _ , tc := range testCases {
t . Run ( "all fields for a cache entry are set correctly" , func ( t * testing . T ) {
st := NewStateTracker ( log . New ( "test_state_tracker" ) )
_ = st . ProcessEvalResults ( tc . uid , tc . evalResults , tc . condition )
st := state . NewStateTracker ( log . New ( "test_state_tracker" ) )
_ = st . ProcessEvalResults ( & alertRule , tc . evalResults )
for _ , entry := range tc . expectedCacheEntries {
if ! entry . Equals ( st . Get ( entry . CacheId ) ) {
t . Log ( tc . desc )
@ -234,23 +230,23 @@ func TestProcessEvalResults(t *testing.T) {
} )
t . Run ( "the expected number of entries are added to the cache" , func ( t * testing . T ) {
st := NewStateTracker ( log . New ( "test_state_tracker" ) )
st . ProcessEvalResults ( tc . uid , tc . evalResults , tc . condition )
assert . Equal ( t , len ( tc . expectedCacheEntries ) , len ( st . stateCache . cacheMap ) )
st := state . NewStateTracker ( log . New ( "test_state_tracker" ) )
st . ProcessEvalResults ( & alertRule , tc . evalResults )
assert . Equal ( t , len ( tc . expectedCacheEntries ) , len ( st . GetAll ( ) ) )
} )
//This test, as configured, does not quite represent the behavior of the system.
//It is expected that each batch of evaluation results will have only one result
//for a unique set of labels.
t . Run ( "the expected number of states are returned to the caller" , func ( t * testing . T ) {
st := NewStateTracker ( log . New ( "test_state_tracker" ) )
results := st . ProcessEvalResults ( tc . uid , tc . evalResults , tc . condition )
st := state . NewStateTracker ( log . New ( "test_state_tracker" ) )
results := st . ProcessEvalResults ( & alertRule , tc . evalResults )
assert . Equal ( t , len ( tc . evalResults ) , len ( results ) )
} )
}
}
func printEntryDiff ( a , b AlertState , t * testing . T ) {
func printEntryDiff ( a , b state . AlertState , t * testing . T ) {
if a . UID != b . UID {
t . Log ( fmt . Sprintf ( "%v \t %v\n" , a . UID , b . UID ) )
}