extractor_test.go 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162
  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. "conditions": [
  42. {
  43. "type": "query",
  44. "query": {"params": ["A", "5m", "now"]},
  45. "reducer": {"type": "avg", "params": []},
  46. "evaluator": {"type": ">", "params": [100]}
  47. }
  48. ]
  49. }
  50. },
  51. {
  52. "title": "Active mobile users",
  53. "id": 4,
  54. "targets": [
  55. {"refId": "A", "target": ""},
  56. {"refId": "B", "target": "aliasByNode(statsd.fakesite.counters.session_start.mobile.count, 4)"}
  57. ],
  58. "datasource": "graphite2",
  59. "alert": {
  60. "name": "name2",
  61. "message": "desc2",
  62. "handler": 0,
  63. "enabled": true,
  64. "frequency": "60s",
  65. "severity": "warning",
  66. "conditions": [
  67. {
  68. "type": "query",
  69. "query": {"params": ["B", "5m", "now"]},
  70. "reducer": {"type": "avg", "params": []},
  71. "evaluator": {"type": ">", "params": [100]}
  72. }
  73. ]
  74. }
  75. }
  76. ]
  77. }
  78. ]
  79. }`
  80. dashJson, err := simplejson.NewJson([]byte(json))
  81. So(err, ShouldBeNil)
  82. dash := m.NewDashboardFromJson(dashJson)
  83. extractor := NewDashAlertExtractor(dash, 1)
  84. // mock data
  85. defaultDs := &m.DataSource{Id: 12, OrgId: 2, Name: "I am default", IsDefault: true}
  86. graphite2Ds := &m.DataSource{Id: 15, OrgId: 2, Name: "graphite2"}
  87. bus.AddHandler("test", func(query *m.GetDataSourcesQuery) error {
  88. query.Result = []*m.DataSource{defaultDs, graphite2Ds}
  89. return nil
  90. })
  91. bus.AddHandler("test", func(query *m.GetDataSourceByNameQuery) error {
  92. if query.Name == defaultDs.Name {
  93. query.Result = defaultDs
  94. }
  95. if query.Name == graphite2Ds.Name {
  96. query.Result = graphite2Ds
  97. }
  98. return nil
  99. })
  100. alerts, err := extractor.GetAlerts()
  101. Convey("Get rules without error", func() {
  102. So(err, ShouldBeNil)
  103. })
  104. Convey("all properties have been set", func() {
  105. So(len(alerts), ShouldEqual, 2)
  106. for _, v := range alerts {
  107. So(v.DashboardId, ShouldEqual, 57)
  108. So(v.Name, ShouldNotBeEmpty)
  109. So(v.Message, ShouldNotBeEmpty)
  110. }
  111. Convey("should extract handler property", func() {
  112. So(alerts[0].Handler, ShouldEqual, 1)
  113. So(alerts[1].Handler, ShouldEqual, 0)
  114. })
  115. Convey("should extract frequency in seconds", func() {
  116. So(alerts[0].Frequency, ShouldEqual, 60)
  117. So(alerts[1].Frequency, ShouldEqual, 60)
  118. })
  119. Convey("should extract panel idc", func() {
  120. So(alerts[0].PanelId, ShouldEqual, 3)
  121. So(alerts[1].PanelId, ShouldEqual, 4)
  122. })
  123. Convey("should extract name and desc", func() {
  124. So(alerts[0].Name, ShouldEqual, "name1")
  125. So(alerts[0].Message, ShouldEqual, "desc1")
  126. So(alerts[1].Name, ShouldEqual, "name2")
  127. So(alerts[1].Message, ShouldEqual, "desc2")
  128. })
  129. Convey("should set datasourceId", func() {
  130. condition := simplejson.NewFromAny(alerts[0].Settings.Get("conditions").MustArray()[0])
  131. query := condition.Get("query")
  132. So(query.Get("datasourceId").MustInt64(), ShouldEqual, 12)
  133. })
  134. Convey("should copy query model to condition", func() {
  135. condition := simplejson.NewFromAny(alerts[0].Settings.Get("conditions").MustArray()[0])
  136. model := condition.Get("query").Get("model")
  137. So(model.Get("target").MustString(), ShouldEqual, "aliasByNode(statsd.fakesite.counters.session_start.desktop.count, 4)")
  138. })
  139. })
  140. })
  141. })
  142. }