extractor_test.go 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219
  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. Convey("Parsing and validating alerts from dashboards", func() {
  12. json := `{
  13. "id": 57,
  14. "title": "Graphite 4",
  15. "originalTitle": "Graphite 4",
  16. "tags": [
  17. "graphite"
  18. ],
  19. "rows": [
  20. {
  21. "panels": [
  22. {
  23. "title": "Active desktop users",
  24. "editable": true,
  25. "type": "graph",
  26. "id": 3,
  27. "targets": [
  28. {
  29. "refId": "A",
  30. "target": "aliasByNode(statsd.fakesite.counters.session_start.desktop.count, 4)"
  31. }
  32. ],
  33. "datasource": null,
  34. "alert": {
  35. "name": "name1",
  36. "description": "desc1",
  37. "handler": 1,
  38. "enabled": true,
  39. "critical": {
  40. "level": 20,
  41. "op": ">"
  42. },
  43. "frequency": "60s",
  44. "query": {
  45. "from": "5m",
  46. "refId": "A",
  47. "to": "now"
  48. },
  49. "transform": {
  50. "method": "avg",
  51. "type": "aggregation"
  52. },
  53. "warn": {
  54. "level": 10,
  55. "op": ">"
  56. }
  57. }
  58. },
  59. {
  60. "title": "Active mobile users",
  61. "id": 4,
  62. "targets": [
  63. {
  64. "refId": "A",
  65. "target": "aliasByNode(statsd.fakesite.counters.session_start.mobile.count, 4)"
  66. }
  67. ],
  68. "datasource": "graphite2",
  69. "alert": {
  70. "name": "name2",
  71. "description": "desc2",
  72. "handler": 0,
  73. "enabled": true,
  74. "critical": {
  75. "level": 20,
  76. "op": ">"
  77. },
  78. "frequency": "60s",
  79. "query": {
  80. "from": "5m",
  81. "refId": "A",
  82. "to": "now"
  83. },
  84. "transform": {
  85. "method": "avg",
  86. "name": "aggregation"
  87. },
  88. "warn": {
  89. "level": 10,
  90. "op": ">"
  91. }
  92. }
  93. }
  94. ],
  95. "title": "Row"
  96. },
  97. {
  98. "collapse": false,
  99. "editable": true,
  100. "height": "250px",
  101. "panels": [
  102. {
  103. "datasource": "InfluxDB",
  104. "id": 2,
  105. "targets": [
  106. {
  107. "dsType": "influxdb",
  108. "groupBy": [
  109. {
  110. "params": [
  111. "$interval"
  112. ],
  113. "type": "time"
  114. },
  115. {
  116. "params": [
  117. "null"
  118. ],
  119. "type": "fill"
  120. }
  121. ],
  122. "measurement": "cpu",
  123. "policy": "default",
  124. "query": "SELECT mean(\"value\") FROM \"cpu\" WHERE $timeFilter GROUP BY time($interval) fill(null)",
  125. "refId": "A",
  126. "resultFormat": "table",
  127. "select": [
  128. [
  129. {
  130. "params": [
  131. "value"
  132. ],
  133. "type": "field"
  134. },
  135. {
  136. "params": [],
  137. "type": "mean"
  138. }
  139. ]
  140. ],
  141. "tags": [],
  142. "target": ""
  143. }
  144. ],
  145. "title": "Broken influxdb panel",
  146. "transform": "table",
  147. "type": "table"
  148. }
  149. ],
  150. "title": "New row"
  151. }
  152. ]
  153. }`
  154. dashJson, err := simplejson.NewJson([]byte(json))
  155. So(err, ShouldBeNil)
  156. dash := m.NewDashboardFromJson(dashJson)
  157. extractor := NewDashAlertExtractor(dash, 1)
  158. // mock data
  159. defaultDs := &m.DataSource{Id: 12, OrgId: 2, Name: "I am default", IsDefault: true}
  160. graphite2Ds := &m.DataSource{Id: 15, OrgId: 2, Name: "graphite2"}
  161. bus.AddHandler("test", func(query *m.GetDataSourcesQuery) error {
  162. query.Result = []*m.DataSource{defaultDs, graphite2Ds}
  163. return nil
  164. })
  165. bus.AddHandler("test", func(query *m.GetDataSourceByNameQuery) error {
  166. if query.Name == defaultDs.Name {
  167. query.Result = defaultDs
  168. }
  169. if query.Name == graphite2Ds.Name {
  170. query.Result = graphite2Ds
  171. }
  172. return nil
  173. })
  174. alerts, err := extractor.GetAlerts()
  175. Convey("Get rules without error", func() {
  176. So(err, ShouldBeNil)
  177. })
  178. Convey("all properties have been set", func() {
  179. So(len(alerts), ShouldEqual, 2)
  180. for _, v := range alerts {
  181. So(v.DashboardId, ShouldEqual, 57)
  182. So(v.Name, ShouldNotBeEmpty)
  183. So(v.Description, ShouldNotBeEmpty)
  184. }
  185. Convey("should extract handler property", func() {
  186. So(alerts[0].Handler, ShouldEqual, 1)
  187. So(alerts[1].Handler, ShouldEqual, 0)
  188. })
  189. Convey("should extract panel idc", func() {
  190. So(alerts[0].PanelId, ShouldEqual, 3)
  191. So(alerts[1].PanelId, ShouldEqual, 4)
  192. })
  193. Convey("should extract name and desc", func() {
  194. So(alerts[0].Name, ShouldEqual, "name1")
  195. So(alerts[0].Description, ShouldEqual, "desc1")
  196. So(alerts[1].Name, ShouldEqual, "name2")
  197. So(alerts[1].Description, ShouldEqual, "desc2")
  198. })
  199. })
  200. })
  201. })
  202. }