alert_test.go 8.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343
  1. package sqlstore
  2. import (
  3. "testing"
  4. "time"
  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 mockTimeNow() {
  10. var timeSeed int64
  11. timeNow = func() time.Time {
  12. fakeNow := time.Unix(timeSeed, 0)
  13. timeSeed++
  14. return fakeNow
  15. }
  16. }
  17. func resetTimeNow() {
  18. timeNow = time.Now
  19. }
  20. func TestAlertingDataAccess(t *testing.T) {
  21. mockTimeNow()
  22. defer resetTimeNow()
  23. Convey("Testing Alerting data access", t, func() {
  24. InitTestDB(t)
  25. testDash := insertTestDashboard("dashboard with alerts", 1, 0, false, "alert")
  26. evalData, _ := simplejson.NewJson([]byte(`{"test": "test"}`))
  27. items := []*m.Alert{
  28. {
  29. PanelId: 1,
  30. DashboardId: testDash.Id,
  31. OrgId: testDash.OrgId,
  32. Name: "Alerting title",
  33. Message: "Alerting message",
  34. Settings: simplejson.New(),
  35. Frequency: 1,
  36. EvalData: evalData,
  37. },
  38. }
  39. cmd := m.SaveAlertsCommand{
  40. Alerts: items,
  41. DashboardId: testDash.Id,
  42. OrgId: 1,
  43. UserId: 1,
  44. }
  45. err := SaveAlerts(&cmd)
  46. Convey("Can create one alert", func() {
  47. So(err, ShouldBeNil)
  48. })
  49. Convey("Can set new states", func() {
  50. Convey("new state ok", func() {
  51. cmd := &m.SetAlertStateCommand{
  52. AlertId: 1,
  53. State: m.AlertStateOK,
  54. }
  55. err = SetAlertState(cmd)
  56. So(err, ShouldBeNil)
  57. })
  58. alert, _ := getAlertById(1)
  59. stateDateBeforePause := alert.NewStateDate
  60. Convey("can pause all alerts", func() {
  61. pauseAllAlerts(true)
  62. Convey("cannot updated paused alert", func() {
  63. cmd := &m.SetAlertStateCommand{
  64. AlertId: 1,
  65. State: m.AlertStateOK,
  66. }
  67. err = SetAlertState(cmd)
  68. So(err, ShouldNotBeNil)
  69. })
  70. Convey("pausing alerts should update their NewStateDate", func() {
  71. alert, _ = getAlertById(1)
  72. stateDateAfterPause := alert.NewStateDate
  73. So(stateDateBeforePause, ShouldHappenBefore, stateDateAfterPause)
  74. })
  75. Convey("unpausing alerts should update their NewStateDate again", func() {
  76. pauseAllAlerts(false)
  77. alert, _ = getAlertById(1)
  78. stateDateAfterUnpause := alert.NewStateDate
  79. So(stateDateBeforePause, ShouldHappenBefore, stateDateAfterUnpause)
  80. })
  81. })
  82. })
  83. Convey("Can read properties", func() {
  84. alertQuery := m.GetAlertsQuery{DashboardIDs: []int64{testDash.Id}, PanelId: 1, OrgId: 1, User: &m.SignedInUser{OrgRole: m.ROLE_ADMIN}}
  85. err2 := HandleAlertsQuery(&alertQuery)
  86. alert := alertQuery.Result[0]
  87. So(err2, ShouldBeNil)
  88. So(alert.Id, ShouldBeGreaterThan, 0)
  89. So(alert.DashboardId, ShouldEqual, testDash.Id)
  90. So(alert.PanelId, ShouldEqual, 1)
  91. So(alert.Name, ShouldEqual, "Alerting title")
  92. So(alert.State, ShouldEqual, m.AlertStateUnknown)
  93. So(alert.NewStateDate, ShouldNotBeNil)
  94. So(alert.EvalData, ShouldNotBeNil)
  95. So(alert.EvalData.Get("test").MustString(), ShouldEqual, "test")
  96. So(alert.EvalDate, ShouldNotBeNil)
  97. So(alert.ExecutionError, ShouldEqual, "")
  98. So(alert.DashboardUid, ShouldNotBeNil)
  99. So(alert.DashboardSlug, ShouldEqual, "dashboard-with-alerts")
  100. })
  101. Convey("Viewer cannot read alerts", func() {
  102. viewerUser := &m.SignedInUser{OrgRole: m.ROLE_VIEWER, OrgId: 1}
  103. alertQuery := m.GetAlertsQuery{DashboardIDs: []int64{testDash.Id}, PanelId: 1, OrgId: 1, User: viewerUser}
  104. err2 := HandleAlertsQuery(&alertQuery)
  105. So(err2, ShouldBeNil)
  106. So(alertQuery.Result, ShouldHaveLength, 1)
  107. })
  108. Convey("Alerts with same dashboard id and panel id should update", func() {
  109. modifiedItems := items
  110. modifiedItems[0].Name = "Name"
  111. modifiedCmd := m.SaveAlertsCommand{
  112. DashboardId: testDash.Id,
  113. OrgId: 1,
  114. UserId: 1,
  115. Alerts: modifiedItems,
  116. }
  117. err := SaveAlerts(&modifiedCmd)
  118. Convey("Can save alerts with same dashboard and panel id", func() {
  119. So(err, ShouldBeNil)
  120. })
  121. Convey("Alerts should be updated", func() {
  122. query := m.GetAlertsQuery{DashboardIDs: []int64{testDash.Id}, OrgId: 1, User: &m.SignedInUser{OrgRole: m.ROLE_ADMIN}}
  123. err2 := HandleAlertsQuery(&query)
  124. So(err2, ShouldBeNil)
  125. So(len(query.Result), ShouldEqual, 1)
  126. So(query.Result[0].Name, ShouldEqual, "Name")
  127. Convey("Alert state should not be updated", func() {
  128. So(query.Result[0].State, ShouldEqual, m.AlertStateUnknown)
  129. })
  130. })
  131. Convey("Updates without changes should be ignored", func() {
  132. err3 := SaveAlerts(&modifiedCmd)
  133. So(err3, ShouldBeNil)
  134. })
  135. })
  136. Convey("Multiple alerts per dashboard", func() {
  137. multipleItems := []*m.Alert{
  138. {
  139. DashboardId: testDash.Id,
  140. PanelId: 1,
  141. Name: "1",
  142. OrgId: 1,
  143. Settings: simplejson.New(),
  144. },
  145. {
  146. DashboardId: testDash.Id,
  147. PanelId: 2,
  148. Name: "2",
  149. OrgId: 1,
  150. Settings: simplejson.New(),
  151. },
  152. {
  153. DashboardId: testDash.Id,
  154. PanelId: 3,
  155. Name: "3",
  156. OrgId: 1,
  157. Settings: simplejson.New(),
  158. },
  159. }
  160. cmd.Alerts = multipleItems
  161. err = SaveAlerts(&cmd)
  162. Convey("Should save 3 dashboards", func() {
  163. So(err, ShouldBeNil)
  164. queryForDashboard := m.GetAlertsQuery{DashboardIDs: []int64{testDash.Id}, OrgId: 1, User: &m.SignedInUser{OrgRole: m.ROLE_ADMIN}}
  165. err2 := HandleAlertsQuery(&queryForDashboard)
  166. So(err2, ShouldBeNil)
  167. So(len(queryForDashboard.Result), ShouldEqual, 3)
  168. })
  169. Convey("should updated two dashboards and delete one", func() {
  170. missingOneAlert := multipleItems[:2]
  171. cmd.Alerts = missingOneAlert
  172. err = SaveAlerts(&cmd)
  173. Convey("should delete the missing alert", func() {
  174. query := m.GetAlertsQuery{DashboardIDs: []int64{testDash.Id}, OrgId: 1, User: &m.SignedInUser{OrgRole: m.ROLE_ADMIN}}
  175. err2 := HandleAlertsQuery(&query)
  176. So(err2, ShouldBeNil)
  177. So(len(query.Result), ShouldEqual, 2)
  178. })
  179. })
  180. })
  181. Convey("When dashboard is removed", func() {
  182. items := []*m.Alert{
  183. {
  184. PanelId: 1,
  185. DashboardId: testDash.Id,
  186. Name: "Alerting title",
  187. Message: "Alerting message",
  188. },
  189. }
  190. cmd := m.SaveAlertsCommand{
  191. Alerts: items,
  192. DashboardId: testDash.Id,
  193. OrgId: 1,
  194. UserId: 1,
  195. }
  196. SaveAlerts(&cmd)
  197. err = DeleteDashboard(&m.DeleteDashboardCommand{
  198. OrgId: 1,
  199. Id: testDash.Id,
  200. })
  201. So(err, ShouldBeNil)
  202. Convey("Alerts should be removed", func() {
  203. query := m.GetAlertsQuery{DashboardIDs: []int64{testDash.Id}, OrgId: 1, User: &m.SignedInUser{OrgRole: m.ROLE_ADMIN}}
  204. err2 := HandleAlertsQuery(&query)
  205. So(testDash.Id, ShouldEqual, 1)
  206. So(err2, ShouldBeNil)
  207. So(len(query.Result), ShouldEqual, 0)
  208. })
  209. })
  210. })
  211. }
  212. func TestPausingAlerts(t *testing.T) {
  213. mockTimeNow()
  214. defer resetTimeNow()
  215. Convey("Given an alert", t, func() {
  216. InitTestDB(t)
  217. testDash := insertTestDashboard("dashboard with alerts", 1, 0, false, "alert")
  218. alert, _ := insertTestAlert("Alerting title", "Alerting message", testDash.OrgId, testDash.Id, simplejson.New())
  219. stateDateBeforePause := alert.NewStateDate
  220. stateDateAfterPause := stateDateBeforePause
  221. Convey("when paused", func() {
  222. pauseAlert(testDash.OrgId, 1, true)
  223. Convey("the NewStateDate should be updated", func() {
  224. alert, _ := getAlertById(1)
  225. stateDateAfterPause = alert.NewStateDate
  226. So(stateDateBeforePause, ShouldHappenBefore, stateDateAfterPause)
  227. })
  228. })
  229. Convey("when unpaused", func() {
  230. pauseAlert(testDash.OrgId, 1, false)
  231. Convey("the NewStateDate should be updated again", func() {
  232. alert, _ := getAlertById(1)
  233. stateDateAfterUnpause := alert.NewStateDate
  234. So(stateDateAfterPause, ShouldHappenBefore, stateDateAfterUnpause)
  235. })
  236. })
  237. })
  238. }
  239. func pauseAlert(orgId int64, alertId int64, pauseState bool) (int64, error) {
  240. cmd := &m.PauseAlertCommand{
  241. OrgId: orgId,
  242. AlertIds: []int64{alertId},
  243. Paused: pauseState,
  244. }
  245. err := PauseAlert(cmd)
  246. So(err, ShouldBeNil)
  247. return cmd.ResultCount, err
  248. }
  249. func insertTestAlert(title string, message string, orgId int64, dashId int64, settings *simplejson.Json) (*m.Alert, error) {
  250. items := []*m.Alert{
  251. {
  252. PanelId: 1,
  253. DashboardId: dashId,
  254. OrgId: orgId,
  255. Name: title,
  256. Message: message,
  257. Settings: settings,
  258. Frequency: 1,
  259. },
  260. }
  261. cmd := m.SaveAlertsCommand{
  262. Alerts: items,
  263. DashboardId: dashId,
  264. OrgId: orgId,
  265. UserId: 1,
  266. }
  267. err := SaveAlerts(&cmd)
  268. return cmd.Alerts[0], err
  269. }
  270. func getAlertById(id int64) (*m.Alert, error) {
  271. q := &m.GetAlertByIdQuery{
  272. Id: id,
  273. }
  274. err := GetAlertById(q)
  275. So(err, ShouldBeNil)
  276. return q.Result, err
  277. }
  278. func pauseAllAlerts(pauseState bool) error {
  279. cmd := &m.PauseAllAlertCommand{
  280. Paused: pauseState,
  281. }
  282. err := PauseAllAlerts(cmd)
  283. So(err, ShouldBeNil)
  284. return err
  285. }