rule_test.go 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184
  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. firstNotification := m.CreateAlertNotificationCommand{OrgId: 1, Name: "1"}
  52. err := sqlstore.CreateAlertNotificationCommand(&firstNotification)
  53. So(err, ShouldBeNil)
  54. secondNotification := m.CreateAlertNotificationCommand{Uid: "notifier2", OrgId: 1, Name: "2"}
  55. err = sqlstore.CreateAlertNotificationCommand(&secondNotification)
  56. So(err, ShouldBeNil)
  57. Convey("with notification id and uid", func() {
  58. json := `
  59. {
  60. "name": "name2",
  61. "description": "desc2",
  62. "handler": 0,
  63. "noDataMode": "critical",
  64. "enabled": true,
  65. "frequency": "60s",
  66. "conditions": [
  67. {
  68. "type": "test",
  69. "prop": 123
  70. }
  71. ],
  72. "notifications": [
  73. {"id": 1},
  74. {"uid": "notifier2"}
  75. ]
  76. }
  77. `
  78. alertJSON, jsonErr := simplejson.NewJson([]byte(json))
  79. So(jsonErr, ShouldBeNil)
  80. alert := &m.Alert{
  81. Id: 1,
  82. OrgId: 1,
  83. DashboardId: 1,
  84. PanelId: 1,
  85. Settings: alertJSON,
  86. }
  87. alertRule, err := NewRuleFromDBAlert(alert)
  88. So(err, ShouldBeNil)
  89. So(len(alertRule.Conditions), ShouldEqual, 1)
  90. Convey("Can read notifications", func() {
  91. So(len(alertRule.Notifications), ShouldEqual, 2)
  92. So(alertRule.Notifications, ShouldContain, "000000001")
  93. So(alertRule.Notifications, ShouldContain, "notifier2")
  94. })
  95. })
  96. })
  97. Convey("can construct alert rule model with invalid frequency", func() {
  98. json := `
  99. {
  100. "name": "name2",
  101. "description": "desc2",
  102. "noDataMode": "critical",
  103. "enabled": true,
  104. "frequency": "0s",
  105. "conditions": [ { "type": "test", "prop": 123 } ],
  106. "notifications": []
  107. }`
  108. alertJSON, jsonErr := simplejson.NewJson([]byte(json))
  109. So(jsonErr, ShouldBeNil)
  110. alert := &m.Alert{
  111. Id: 1,
  112. OrgId: 1,
  113. DashboardId: 1,
  114. PanelId: 1,
  115. Frequency: 0,
  116. Settings: alertJSON,
  117. }
  118. alertRule, err := NewRuleFromDBAlert(alert)
  119. So(err, ShouldBeNil)
  120. So(alertRule.Frequency, ShouldEqual, 60)
  121. })
  122. Convey("raise error in case of missing notification id and uid", func() {
  123. json := `
  124. {
  125. "name": "name2",
  126. "description": "desc2",
  127. "noDataMode": "critical",
  128. "enabled": true,
  129. "frequency": "60s",
  130. "conditions": [
  131. {
  132. "type": "test",
  133. "prop": 123
  134. }
  135. ],
  136. "notifications": [
  137. {"not_id_uid": "1134"}
  138. ]
  139. }
  140. `
  141. alertJSON, jsonErr := simplejson.NewJson([]byte(json))
  142. So(jsonErr, ShouldBeNil)
  143. alert := &m.Alert{
  144. Id: 1,
  145. OrgId: 1,
  146. DashboardId: 1,
  147. PanelId: 1,
  148. Frequency: 0,
  149. Settings: alertJSON,
  150. }
  151. _, err := NewRuleFromDBAlert(alert)
  152. So(err, ShouldNotBeNil)
  153. So(err.Error(), ShouldEqual, "Alert validation error: Neither id nor uid is specified, type assertion to string failed AlertId: 1 PanelId: 1 DashboardId: 1")
  154. })
  155. })
  156. }