base_test.go 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214
  1. package notifiers
  2. import (
  3. "context"
  4. "testing"
  5. "time"
  6. "github.com/stretchr/testify/assert"
  7. "github.com/grafana/grafana/pkg/components/simplejson"
  8. "github.com/grafana/grafana/pkg/models"
  9. "github.com/grafana/grafana/pkg/services/alerting"
  10. . "github.com/smartystreets/goconvey/convey"
  11. )
  12. func TestShouldSendAlertNotification(t *testing.T) {
  13. tnow := time.Now()
  14. tcs := []struct {
  15. name string
  16. prevState models.AlertStateType
  17. newState models.AlertStateType
  18. sendReminder bool
  19. frequency time.Duration
  20. state *models.AlertNotificationState
  21. expect bool
  22. }{
  23. {
  24. name: "pending -> ok should not trigger an notification",
  25. newState: models.AlertStateOK,
  26. prevState: models.AlertStatePending,
  27. sendReminder: false,
  28. expect: false,
  29. },
  30. {
  31. name: "ok -> alerting should trigger an notification",
  32. newState: models.AlertStateAlerting,
  33. prevState: models.AlertStateOK,
  34. sendReminder: false,
  35. expect: true,
  36. },
  37. {
  38. name: "ok -> pending should not trigger an notification",
  39. newState: models.AlertStatePending,
  40. prevState: models.AlertStateOK,
  41. sendReminder: false,
  42. expect: false,
  43. },
  44. {
  45. name: "ok -> ok should not trigger an notification",
  46. newState: models.AlertStateOK,
  47. prevState: models.AlertStateOK,
  48. sendReminder: false,
  49. expect: false,
  50. },
  51. {
  52. name: "ok -> ok with reminder should not trigger an notification",
  53. newState: models.AlertStateOK,
  54. prevState: models.AlertStateOK,
  55. sendReminder: true,
  56. expect: false,
  57. },
  58. {
  59. name: "alerting -> ok should trigger an notification",
  60. newState: models.AlertStateOK,
  61. prevState: models.AlertStateAlerting,
  62. sendReminder: false,
  63. expect: true,
  64. },
  65. {
  66. name: "alerting -> ok should trigger an notification when reminders enabled",
  67. newState: models.AlertStateOK,
  68. prevState: models.AlertStateAlerting,
  69. frequency: time.Minute * 10,
  70. sendReminder: true,
  71. state: &models.AlertNotificationState{UpdatedAt: tnow.Add(-time.Minute).Unix()},
  72. expect: true,
  73. },
  74. {
  75. name: "alerting -> alerting with reminder and no state should trigger",
  76. newState: models.AlertStateAlerting,
  77. prevState: models.AlertStateAlerting,
  78. frequency: time.Minute * 10,
  79. sendReminder: true,
  80. expect: true,
  81. },
  82. {
  83. name: "alerting -> alerting with reminder and last notification sent 1 minute ago should not trigger",
  84. newState: models.AlertStateAlerting,
  85. prevState: models.AlertStateAlerting,
  86. frequency: time.Minute * 10,
  87. sendReminder: true,
  88. state: &models.AlertNotificationState{UpdatedAt: tnow.Add(-time.Minute).Unix()},
  89. expect: false,
  90. },
  91. {
  92. name: "alerting -> alerting with reminder and last notifciation sent 11 minutes ago should trigger",
  93. newState: models.AlertStateAlerting,
  94. prevState: models.AlertStateAlerting,
  95. frequency: time.Minute * 10,
  96. sendReminder: true,
  97. state: &models.AlertNotificationState{UpdatedAt: tnow.Add(-11 * time.Minute).Unix()},
  98. expect: true,
  99. },
  100. {
  101. name: "OK -> alerting with notifciation state pending and updated 30 seconds ago should not trigger",
  102. newState: models.AlertStateAlerting,
  103. prevState: models.AlertStateOK,
  104. state: &models.AlertNotificationState{State: models.AlertNotificationStatePending, UpdatedAt: tnow.Add(-30 * time.Second).Unix()},
  105. expect: false,
  106. },
  107. {
  108. name: "OK -> alerting with notifciation state pending and updated 2 minutes ago should trigger",
  109. newState: models.AlertStateAlerting,
  110. prevState: models.AlertStateOK,
  111. state: &models.AlertNotificationState{State: models.AlertNotificationStatePending, UpdatedAt: tnow.Add(-2 * time.Minute).Unix()},
  112. expect: true,
  113. },
  114. {
  115. name: "unknown -> ok",
  116. prevState: models.AlertStateUnknown,
  117. newState: models.AlertStateOK,
  118. expect: false,
  119. },
  120. {
  121. name: "unknown -> pending",
  122. prevState: models.AlertStateUnknown,
  123. newState: models.AlertStatePending,
  124. expect: false,
  125. },
  126. {
  127. name: "unknown -> alerting",
  128. prevState: models.AlertStateUnknown,
  129. newState: models.AlertStateAlerting,
  130. expect: true,
  131. },
  132. {
  133. name: "no_data -> pending",
  134. prevState: models.AlertStateNoData,
  135. newState: models.AlertStatePending,
  136. expect: false,
  137. },
  138. }
  139. for _, tc := range tcs {
  140. evalContext := alerting.NewEvalContext(context.Background(), &alerting.Rule{
  141. State: tc.prevState,
  142. })
  143. if tc.state == nil {
  144. tc.state = &models.AlertNotificationState{}
  145. }
  146. evalContext.Rule.State = tc.newState
  147. nb := &NotifierBase{SendReminder: tc.sendReminder, Frequency: tc.frequency}
  148. r := nb.ShouldNotify(evalContext.Ctx, evalContext, tc.state)
  149. assert.Equal(t, r, tc.expect, "failed test %s. expected %+v to return: %v", tc.name, tc, tc.expect)
  150. }
  151. }
  152. func TestBaseNotifier(t *testing.T) {
  153. Convey("default constructor for notifiers", t, func() {
  154. bJson := simplejson.New()
  155. model := &models.AlertNotification{
  156. Uid: "1",
  157. Name: "name",
  158. Type: "email",
  159. Settings: bJson,
  160. }
  161. Convey("can parse false value", func() {
  162. bJson.Set("uploadImage", false)
  163. base := NewNotifierBase(model)
  164. So(base.UploadImage, ShouldBeFalse)
  165. })
  166. Convey("can parse true value", func() {
  167. bJson.Set("uploadImage", true)
  168. base := NewNotifierBase(model)
  169. So(base.UploadImage, ShouldBeTrue)
  170. })
  171. Convey("default value should be true for backwards compatibility", func() {
  172. base := NewNotifierBase(model)
  173. So(base.UploadImage, ShouldBeTrue)
  174. })
  175. Convey("default value should be false for backwards compatibility", func() {
  176. base := NewNotifierBase(model)
  177. So(base.DisableResolveMessage, ShouldBeFalse)
  178. })
  179. })
  180. }