eval_handler_test.go 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172
  1. package alerting
  2. import (
  3. "context"
  4. "testing"
  5. . "github.com/smartystreets/goconvey/convey"
  6. )
  7. type conditionStub struct {
  8. firing bool
  9. operator string
  10. matches []*EvalMatch
  11. noData bool
  12. }
  13. func (c *conditionStub) Eval(context *EvalContext) (*ConditionResult, error) {
  14. return &ConditionResult{Firing: c.firing, EvalMatches: c.matches, Operator: c.operator, NoDataFound: c.noData}, nil
  15. }
  16. func (c *conditionStub) GetDatasourceId() (datasourceId *int64, exist bool) {
  17. return nil, false
  18. }
  19. func TestAlertingExecutor(t *testing.T) {
  20. Convey("Test alert execution", t, func() {
  21. handler := NewEvalHandler()
  22. Convey("Show return triggered with single passing condition", func() {
  23. context := NewEvalContext(context.TODO(), &Rule{
  24. Conditions: []Condition{&conditionStub{
  25. firing: true,
  26. }},
  27. })
  28. handler.Eval(context)
  29. So(context.Firing, ShouldEqual, true)
  30. So(context.ConditionEvals, ShouldEqual, "true = true")
  31. })
  32. Convey("Show return false with not passing asdf", func() {
  33. context := NewEvalContext(context.TODO(), &Rule{
  34. Conditions: []Condition{
  35. &conditionStub{firing: true, operator: "and", matches: []*EvalMatch{&EvalMatch{}, &EvalMatch{}}},
  36. &conditionStub{firing: false, operator: "and"},
  37. },
  38. })
  39. handler.Eval(context)
  40. So(context.Firing, ShouldEqual, false)
  41. So(context.ConditionEvals, ShouldEqual, "[true AND false] = false")
  42. })
  43. Convey("Show return true if any of the condition is passing with OR operator", func() {
  44. context := NewEvalContext(context.TODO(), &Rule{
  45. Conditions: []Condition{
  46. &conditionStub{firing: true, operator: "and"},
  47. &conditionStub{firing: false, operator: "or"},
  48. },
  49. })
  50. handler.Eval(context)
  51. So(context.Firing, ShouldEqual, true)
  52. So(context.ConditionEvals, ShouldEqual, "[true OR false] = true")
  53. })
  54. Convey("Show return false if any of the condition is failing with AND operator", func() {
  55. context := NewEvalContext(context.TODO(), &Rule{
  56. Conditions: []Condition{
  57. &conditionStub{firing: true, operator: "and"},
  58. &conditionStub{firing: false, operator: "and"},
  59. },
  60. })
  61. handler.Eval(context)
  62. So(context.Firing, ShouldEqual, false)
  63. So(context.ConditionEvals, ShouldEqual, "[true AND false] = false")
  64. })
  65. Convey("Show return true if one condition is failing with nested OR operator", func() {
  66. context := NewEvalContext(context.TODO(), &Rule{
  67. Conditions: []Condition{
  68. &conditionStub{firing: true, operator: "and"},
  69. &conditionStub{firing: true, operator: "and"},
  70. &conditionStub{firing: false, operator: "or"},
  71. },
  72. })
  73. handler.Eval(context)
  74. So(context.Firing, ShouldEqual, true)
  75. So(context.ConditionEvals, ShouldEqual, "[[true AND true] OR false] = true")
  76. })
  77. Convey("Show return false if one condition is passing with nested OR operator", func() {
  78. context := NewEvalContext(context.TODO(), &Rule{
  79. Conditions: []Condition{
  80. &conditionStub{firing: true, operator: "and"},
  81. &conditionStub{firing: false, operator: "and"},
  82. &conditionStub{firing: false, operator: "or"},
  83. },
  84. })
  85. handler.Eval(context)
  86. So(context.Firing, ShouldEqual, false)
  87. So(context.ConditionEvals, ShouldEqual, "[[true AND false] OR false] = false")
  88. })
  89. Convey("Show return false if a condition is failing with nested AND operator", func() {
  90. context := NewEvalContext(context.TODO(), &Rule{
  91. Conditions: []Condition{
  92. &conditionStub{firing: true, operator: "and"},
  93. &conditionStub{firing: false, operator: "and"},
  94. &conditionStub{firing: true, operator: "and"},
  95. },
  96. })
  97. handler.Eval(context)
  98. So(context.Firing, ShouldEqual, false)
  99. So(context.ConditionEvals, ShouldEqual, "[[true AND false] AND true] = false")
  100. })
  101. Convey("Show return true if a condition is passing with nested OR operator", func() {
  102. context := NewEvalContext(context.TODO(), &Rule{
  103. Conditions: []Condition{
  104. &conditionStub{firing: true, operator: "and"},
  105. &conditionStub{firing: false, operator: "or"},
  106. &conditionStub{firing: true, operator: "or"},
  107. },
  108. })
  109. handler.Eval(context)
  110. So(context.Firing, ShouldEqual, true)
  111. So(context.ConditionEvals, ShouldEqual, "[[true OR false] OR true] = true")
  112. })
  113. Convey("Should return no data if one condition has nodata", func() {
  114. context := NewEvalContext(context.TODO(), &Rule{
  115. Conditions: []Condition{
  116. &conditionStub{operator: "and", noData: true},
  117. },
  118. })
  119. handler.Eval(context)
  120. So(context.Firing, ShouldEqual, false)
  121. So(context.NoDataFound, ShouldBeTrue)
  122. })
  123. Convey("Should return no data if both conditions have no data and using AND", func() {
  124. context := NewEvalContext(context.TODO(), &Rule{
  125. Conditions: []Condition{
  126. &conditionStub{operator: "and", noData: true},
  127. &conditionStub{operator: "and", noData: false},
  128. },
  129. })
  130. handler.Eval(context)
  131. So(context.NoDataFound, ShouldBeFalse)
  132. })
  133. Convey("Should not return no data if both conditions have no data and using OR", func() {
  134. context := NewEvalContext(context.TODO(), &Rule{
  135. Conditions: []Condition{
  136. &conditionStub{operator: "or", noData: true},
  137. &conditionStub{operator: "or", noData: false},
  138. },
  139. })
  140. handler.Eval(context)
  141. So(context.NoDataFound, ShouldBeTrue)
  142. })
  143. })
  144. }