extractor_test.go 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168
  1. package alerting
  2. import (
  3. "testing"
  4. "github.com/grafana/grafana/pkg/bus"
  5. "github.com/grafana/grafana/pkg/components/simplejson"
  6. m "github.com/grafana/grafana/pkg/models"
  7. . "github.com/smartystreets/goconvey/convey"
  8. )
  9. func TestAlertRuleExtraction(t *testing.T) {
  10. Convey("Parsing alert rules from dashboard json", t, func() {
  11. RegisterCondition("query", func(model *simplejson.Json, index int) (Condition, error) {
  12. return &FakeCondition{}, nil
  13. })
  14. Convey("Parsing and validating alerts from dashboards", func() {
  15. json := `{
  16. "id": 57,
  17. "title": "Graphite 4",
  18. "originalTitle": "Graphite 4",
  19. "tags": ["graphite"],
  20. "rows": [
  21. {
  22. "panels": [
  23. {
  24. "title": "Active desktop users",
  25. "editable": true,
  26. "type": "graph",
  27. "id": 3,
  28. "targets": [
  29. {
  30. "refId": "A",
  31. "target": "aliasByNode(statsd.fakesite.counters.session_start.desktop.count, 4)"
  32. }
  33. ],
  34. "datasource": null,
  35. "alert": {
  36. "name": "name1",
  37. "message": "desc1",
  38. "handler": 1,
  39. "enabled": true,
  40. "frequency": "60s",
  41. "severity": "critical",
  42. "conditions": [
  43. {
  44. "type": "query",
  45. "query": {"params": ["A", "5m", "now"]},
  46. "reducer": {"type": "avg", "params": []},
  47. "evaluator": {"type": ">", "params": [100]}
  48. }
  49. ]
  50. }
  51. },
  52. {
  53. "title": "Active mobile users",
  54. "id": 4,
  55. "targets": [
  56. {"refId": "A", "target": ""},
  57. {"refId": "B", "target": "aliasByNode(statsd.fakesite.counters.session_start.mobile.count, 4)"}
  58. ],
  59. "datasource": "graphite2",
  60. "alert": {
  61. "name": "name2",
  62. "message": "desc2",
  63. "handler": 0,
  64. "enabled": true,
  65. "frequency": "60s",
  66. "severity": "warning",
  67. "conditions": [
  68. {
  69. "type": "query",
  70. "query": {"params": ["B", "5m", "now"]},
  71. "reducer": {"type": "avg", "params": []},
  72. "evaluator": {"type": ">", "params": [100]}
  73. }
  74. ]
  75. }
  76. }
  77. ]
  78. }
  79. ]
  80. }`
  81. dashJson, err := simplejson.NewJson([]byte(json))
  82. So(err, ShouldBeNil)
  83. dash := m.NewDashboardFromJson(dashJson)
  84. extractor := NewDashAlertExtractor(dash, 1)
  85. // mock data
  86. defaultDs := &m.DataSource{Id: 12, OrgId: 2, Name: "I am default", IsDefault: true}
  87. graphite2Ds := &m.DataSource{Id: 15, OrgId: 2, Name: "graphite2"}
  88. bus.AddHandler("test", func(query *m.GetDataSourcesQuery) error {
  89. query.Result = []*m.DataSource{defaultDs, graphite2Ds}
  90. return nil
  91. })
  92. bus.AddHandler("test", func(query *m.GetDataSourceByNameQuery) error {
  93. if query.Name == defaultDs.Name {
  94. query.Result = defaultDs
  95. }
  96. if query.Name == graphite2Ds.Name {
  97. query.Result = graphite2Ds
  98. }
  99. return nil
  100. })
  101. alerts, err := extractor.GetAlerts()
  102. Convey("Get rules without error", func() {
  103. So(err, ShouldBeNil)
  104. })
  105. Convey("all properties have been set", func() {
  106. So(len(alerts), ShouldEqual, 2)
  107. for _, v := range alerts {
  108. So(v.DashboardId, ShouldEqual, 57)
  109. So(v.Name, ShouldNotBeEmpty)
  110. So(v.Message, ShouldNotBeEmpty)
  111. }
  112. Convey("should extract handler property", func() {
  113. So(alerts[0].Handler, ShouldEqual, 1)
  114. So(alerts[1].Handler, ShouldEqual, 0)
  115. })
  116. Convey("should extract Severity property", func() {
  117. So(alerts[0].Severity, ShouldEqual, "critical")
  118. So(alerts[1].Severity, ShouldEqual, "warning")
  119. })
  120. Convey("should extract frequency in seconds", func() {
  121. So(alerts[0].Frequency, ShouldEqual, 60)
  122. So(alerts[1].Frequency, ShouldEqual, 60)
  123. })
  124. Convey("should extract panel idc", func() {
  125. So(alerts[0].PanelId, ShouldEqual, 3)
  126. So(alerts[1].PanelId, ShouldEqual, 4)
  127. })
  128. Convey("should extract name and desc", func() {
  129. So(alerts[0].Name, ShouldEqual, "name1")
  130. So(alerts[0].Message, ShouldEqual, "desc1")
  131. So(alerts[1].Name, ShouldEqual, "name2")
  132. So(alerts[1].Message, ShouldEqual, "desc2")
  133. })
  134. Convey("should set datasourceId", func() {
  135. condition := simplejson.NewFromAny(alerts[0].Settings.Get("conditions").MustArray()[0])
  136. query := condition.Get("query")
  137. So(query.Get("datasourceId").MustInt64(), ShouldEqual, 12)
  138. })
  139. Convey("should copy query model to condition", func() {
  140. condition := simplejson.NewFromAny(alerts[0].Settings.Get("conditions").MustArray()[0])
  141. model := condition.Get("query").Get("model")
  142. So(model.Get("target").MustString(), ShouldEqual, "aliasByNode(statsd.fakesite.counters.session_start.desktop.count, 4)")
  143. })
  144. })
  145. })
  146. })
  147. }