rule_test.go 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185
  1. package alerting
  2. import (
  3. "testing"
  4. "github.com/grafana/grafana/pkg/components/simplejson"
  5. "github.com/grafana/grafana/pkg/models"
  6. "github.com/grafana/grafana/pkg/services/sqlstore"
  7. . "github.com/smartystreets/goconvey/convey"
  8. )
  9. type FakeCondition struct{}
  10. func (f *FakeCondition) Eval(context *EvalContext) (*ConditionResult, error) {
  11. return &ConditionResult{}, nil
  12. }
  13. func TestAlertRuleFrequencyParsing(t *testing.T) {
  14. tcs := []struct {
  15. input string
  16. err error
  17. result int64
  18. }{
  19. {input: "10s", result: 10},
  20. {input: "10m", result: 600},
  21. {input: "1h", result: 3600},
  22. {input: "1d", result: 86400},
  23. {input: "1o", result: 1},
  24. {input: "0s", err: ErrFrequencyCannotBeZeroOrLess},
  25. {input: "0m", err: ErrFrequencyCannotBeZeroOrLess},
  26. {input: "0h", err: ErrFrequencyCannotBeZeroOrLess},
  27. {input: "0", err: ErrFrequencyCannotBeZeroOrLess},
  28. {input: "-1s", err: ErrFrequencyCouldNotBeParsed},
  29. }
  30. for _, tc := range tcs {
  31. r, err := getTimeDurationStringToSeconds(tc.input)
  32. if err != tc.err {
  33. t.Errorf("expected error: '%v' got: '%v'", tc.err, err)
  34. return
  35. }
  36. if r != tc.result {
  37. t.Errorf("expected result: %d got %d", tc.result, r)
  38. }
  39. }
  40. }
  41. func TestAlertRuleModel(t *testing.T) {
  42. sqlstore.InitTestDB(t)
  43. Convey("Testing alert rule", t, func() {
  44. RegisterCondition("test", func(model *simplejson.Json, index int) (Condition, error) {
  45. return &FakeCondition{}, nil
  46. })
  47. Convey("should return err for empty string", func() {
  48. _, err := getTimeDurationStringToSeconds("")
  49. So(err, ShouldNotBeNil)
  50. })
  51. Convey("can construct alert rule model", func() {
  52. firstNotification := models.CreateAlertNotificationCommand{OrgId: 1, Name: "1"}
  53. err := sqlstore.CreateAlertNotificationCommand(&firstNotification)
  54. So(err, ShouldBeNil)
  55. secondNotification := models.CreateAlertNotificationCommand{Uid: "notifier2", OrgId: 1, Name: "2"}
  56. err = sqlstore.CreateAlertNotificationCommand(&secondNotification)
  57. So(err, ShouldBeNil)
  58. Convey("with notification id and uid", func() {
  59. json := `
  60. {
  61. "name": "name2",
  62. "description": "desc2",
  63. "handler": 0,
  64. "noDataMode": "critical",
  65. "enabled": true,
  66. "frequency": "60s",
  67. "conditions": [
  68. {
  69. "type": "test",
  70. "prop": 123
  71. }
  72. ],
  73. "notifications": [
  74. {"id": 1},
  75. {"uid": "notifier2"}
  76. ]
  77. }
  78. `
  79. alertJSON, jsonErr := simplejson.NewJson([]byte(json))
  80. So(jsonErr, ShouldBeNil)
  81. alert := &models.Alert{
  82. Id: 1,
  83. OrgId: 1,
  84. DashboardId: 1,
  85. PanelId: 1,
  86. Settings: alertJSON,
  87. }
  88. alertRule, err := NewRuleFromDBAlert(alert)
  89. So(err, ShouldBeNil)
  90. So(len(alertRule.Conditions), ShouldEqual, 1)
  91. Convey("Can read notifications", func() {
  92. So(len(alertRule.Notifications), ShouldEqual, 2)
  93. So(alertRule.Notifications, ShouldContain, "000000001")
  94. So(alertRule.Notifications, ShouldContain, "notifier2")
  95. })
  96. })
  97. })
  98. Convey("can construct alert rule model with invalid frequency", func() {
  99. json := `
  100. {
  101. "name": "name2",
  102. "description": "desc2",
  103. "noDataMode": "critical",
  104. "enabled": true,
  105. "frequency": "0s",
  106. "conditions": [ { "type": "test", "prop": 123 } ],
  107. "notifications": []
  108. }`
  109. alertJSON, jsonErr := simplejson.NewJson([]byte(json))
  110. So(jsonErr, ShouldBeNil)
  111. alert := &models.Alert{
  112. Id: 1,
  113. OrgId: 1,
  114. DashboardId: 1,
  115. PanelId: 1,
  116. Frequency: 0,
  117. Settings: alertJSON,
  118. }
  119. alertRule, err := NewRuleFromDBAlert(alert)
  120. So(err, ShouldBeNil)
  121. So(alertRule.Frequency, ShouldEqual, 60)
  122. })
  123. Convey("raise error in case of missing notification id and uid", func() {
  124. json := `
  125. {
  126. "name": "name2",
  127. "description": "desc2",
  128. "noDataMode": "critical",
  129. "enabled": true,
  130. "frequency": "60s",
  131. "conditions": [
  132. {
  133. "type": "test",
  134. "prop": 123
  135. }
  136. ],
  137. "notifications": [
  138. {"not_id_uid": "1134"}
  139. ]
  140. }
  141. `
  142. alertJSON, jsonErr := simplejson.NewJson([]byte(json))
  143. So(jsonErr, ShouldBeNil)
  144. alert := &models.Alert{
  145. Id: 1,
  146. OrgId: 1,
  147. DashboardId: 1,
  148. PanelId: 1,
  149. Frequency: 0,
  150. Settings: alertJSON,
  151. }
  152. _, err := NewRuleFromDBAlert(alert)
  153. So(err, ShouldNotBeNil)
  154. So(err.Error(), ShouldEqual, "Alert validation error: Neither id nor uid is specified in 'notifications' block, type assertion to string failed AlertId: 1 PanelId: 1 DashboardId: 1")
  155. })
  156. })
  157. }