alert_test.go 8.1 KB

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