rule_test.go 4.4 KB

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