mirror of https://github.com/grafana/grafana.git
				
				
				
			
		
			
				
	
	
		
			377 lines
		
	
	
		
			10 KiB
		
	
	
	
		
			Go
		
	
	
	
			
		
		
	
	
			377 lines
		
	
	
		
			10 KiB
		
	
	
	
		
			Go
		
	
	
	
| //go:build integration
 | |
| // +build integration
 | |
| 
 | |
| package sqlstore
 | |
| 
 | |
| import (
 | |
| 	"testing"
 | |
| 	"time"
 | |
| 
 | |
| 	"github.com/grafana/grafana/pkg/components/simplejson"
 | |
| 	"github.com/grafana/grafana/pkg/models"
 | |
| 	. "github.com/smartystreets/goconvey/convey"
 | |
| )
 | |
| 
 | |
| func mockTimeNow() {
 | |
| 	var timeSeed int64
 | |
| 	timeNow = func() time.Time {
 | |
| 		loc := time.FixedZone("MockZoneUTC-5", -5*60*60)
 | |
| 		fakeNow := time.Unix(timeSeed, 0).In(loc)
 | |
| 		timeSeed++
 | |
| 		return fakeNow
 | |
| 	}
 | |
| }
 | |
| 
 | |
| func resetTimeNow() {
 | |
| 	timeNow = time.Now
 | |
| }
 | |
| 
 | |
| func TestAlertingDataAccess(t *testing.T) {
 | |
| 	mockTimeNow()
 | |
| 	defer resetTimeNow()
 | |
| 
 | |
| 	Convey("Testing Alerting data access", t, func() {
 | |
| 		sqlStore := InitTestDB(t)
 | |
| 
 | |
| 		testDash := insertTestDashboard(t, sqlStore, "dashboard with alerts", 1, 0, false, "alert")
 | |
| 		evalData, err := simplejson.NewJson([]byte(`{"test": "test"}`))
 | |
| 		So(err, ShouldBeNil)
 | |
| 		items := []*models.Alert{
 | |
| 			{
 | |
| 				PanelId:     1,
 | |
| 				DashboardId: testDash.Id,
 | |
| 				OrgId:       testDash.OrgId,
 | |
| 				Name:        "Alerting title",
 | |
| 				Message:     "Alerting message",
 | |
| 				Settings:    simplejson.New(),
 | |
| 				Frequency:   1,
 | |
| 				EvalData:    evalData,
 | |
| 			},
 | |
| 		}
 | |
| 
 | |
| 		cmd := models.SaveAlertsCommand{
 | |
| 			Alerts:      items,
 | |
| 			DashboardId: testDash.Id,
 | |
| 			OrgId:       1,
 | |
| 			UserId:      1,
 | |
| 		}
 | |
| 
 | |
| 		err = SaveAlerts(&cmd)
 | |
| 
 | |
| 		Convey("Can create one alert", func() {
 | |
| 			So(err, ShouldBeNil)
 | |
| 		})
 | |
| 
 | |
| 		Convey("Can set new states", func() {
 | |
| 
 | |
| 			// Get alert so we can use its ID in tests
 | |
| 			alertQuery := models.GetAlertsQuery{DashboardIDs: []int64{testDash.Id}, PanelId: 1, OrgId: 1, User: &models.SignedInUser{OrgRole: models.ROLE_ADMIN}}
 | |
| 			err2 := HandleAlertsQuery(&alertQuery)
 | |
| 			So(err2, ShouldBeNil)
 | |
| 
 | |
| 			insertedAlert := alertQuery.Result[0]
 | |
| 
 | |
| 			Convey("new state ok", func() {
 | |
| 				cmd := &models.SetAlertStateCommand{
 | |
| 					AlertId: insertedAlert.Id,
 | |
| 					State:   models.AlertStateOK,
 | |
| 				}
 | |
| 
 | |
| 				err = SetAlertState(cmd)
 | |
| 				So(err, ShouldBeNil)
 | |
| 			})
 | |
| 
 | |
| 			alert, _ := getAlertById(insertedAlert.Id)
 | |
| 			stateDateBeforePause := alert.NewStateDate
 | |
| 
 | |
| 			Convey("can pause all alerts", func() {
 | |
| 				err := pauseAllAlerts(true)
 | |
| 				So(err, ShouldBeNil)
 | |
| 
 | |
| 				Convey("cannot updated paused alert", func() {
 | |
| 					cmd := &models.SetAlertStateCommand{
 | |
| 						AlertId: insertedAlert.Id,
 | |
| 						State:   models.AlertStateOK,
 | |
| 					}
 | |
| 
 | |
| 					err = SetAlertState(cmd)
 | |
| 					So(err, ShouldNotBeNil)
 | |
| 				})
 | |
| 
 | |
| 				Convey("alert is paused", func() {
 | |
| 					alert, _ = getAlertById(insertedAlert.Id)
 | |
| 					currentState := alert.State
 | |
| 					So(currentState, ShouldEqual, "paused")
 | |
| 				})
 | |
| 
 | |
| 				Convey("pausing alerts should update their NewStateDate", func() {
 | |
| 					alert, _ = getAlertById(insertedAlert.Id)
 | |
| 					stateDateAfterPause := alert.NewStateDate
 | |
| 					So(stateDateBeforePause, ShouldHappenBefore, stateDateAfterPause)
 | |
| 				})
 | |
| 
 | |
| 				Convey("unpausing alerts should update their NewStateDate again", func() {
 | |
| 					err := pauseAllAlerts(false)
 | |
| 					So(err, ShouldBeNil)
 | |
| 					alert, _ = getAlertById(insertedAlert.Id)
 | |
| 					stateDateAfterUnpause := alert.NewStateDate
 | |
| 					So(stateDateBeforePause, ShouldHappenBefore, stateDateAfterUnpause)
 | |
| 				})
 | |
| 			})
 | |
| 		})
 | |
| 
 | |
| 		Convey("Can read properties", func() {
 | |
| 			alertQuery := models.GetAlertsQuery{DashboardIDs: []int64{testDash.Id}, PanelId: 1, OrgId: 1, User: &models.SignedInUser{OrgRole: models.ROLE_ADMIN}}
 | |
| 			err2 := HandleAlertsQuery(&alertQuery)
 | |
| 
 | |
| 			alert := alertQuery.Result[0]
 | |
| 			So(err2, ShouldBeNil)
 | |
| 			So(alert.Id, ShouldBeGreaterThan, 0)
 | |
| 			So(alert.DashboardId, ShouldEqual, testDash.Id)
 | |
| 			So(alert.PanelId, ShouldEqual, 1)
 | |
| 			So(alert.Name, ShouldEqual, "Alerting title")
 | |
| 			So(alert.State, ShouldEqual, models.AlertStateUnknown)
 | |
| 			So(alert.NewStateDate, ShouldNotBeNil)
 | |
| 			So(alert.EvalData, ShouldNotBeNil)
 | |
| 			So(alert.EvalData.Get("test").MustString(), ShouldEqual, "test")
 | |
| 			So(alert.EvalDate, ShouldNotBeNil)
 | |
| 			So(alert.ExecutionError, ShouldEqual, "")
 | |
| 			So(alert.DashboardUid, ShouldNotBeNil)
 | |
| 			So(alert.DashboardSlug, ShouldEqual, "dashboard-with-alerts")
 | |
| 		})
 | |
| 
 | |
| 		Convey("Viewer can read alerts", func() {
 | |
| 			viewerUser := &models.SignedInUser{OrgRole: models.ROLE_VIEWER, OrgId: 1}
 | |
| 			alertQuery := models.GetAlertsQuery{DashboardIDs: []int64{testDash.Id}, PanelId: 1, OrgId: 1, User: viewerUser}
 | |
| 			err2 := HandleAlertsQuery(&alertQuery)
 | |
| 
 | |
| 			So(err2, ShouldBeNil)
 | |
| 			So(alertQuery.Result, ShouldHaveLength, 1)
 | |
| 		})
 | |
| 
 | |
| 		Convey("Alerts with same dashboard id and panel id should update", func() {
 | |
| 			modifiedItems := items
 | |
| 			modifiedItems[0].Name = "Name"
 | |
| 
 | |
| 			modifiedCmd := models.SaveAlertsCommand{
 | |
| 				DashboardId: testDash.Id,
 | |
| 				OrgId:       1,
 | |
| 				UserId:      1,
 | |
| 				Alerts:      modifiedItems,
 | |
| 			}
 | |
| 
 | |
| 			err := SaveAlerts(&modifiedCmd)
 | |
| 
 | |
| 			Convey("Can save alerts with same dashboard and panel id", func() {
 | |
| 				So(err, ShouldBeNil)
 | |
| 			})
 | |
| 
 | |
| 			Convey("Alerts should be updated", func() {
 | |
| 				query := models.GetAlertsQuery{DashboardIDs: []int64{testDash.Id}, OrgId: 1, User: &models.SignedInUser{OrgRole: models.ROLE_ADMIN}}
 | |
| 				err2 := HandleAlertsQuery(&query)
 | |
| 
 | |
| 				So(err2, ShouldBeNil)
 | |
| 				So(len(query.Result), ShouldEqual, 1)
 | |
| 				So(query.Result[0].Name, ShouldEqual, "Name")
 | |
| 
 | |
| 				Convey("Alert state should not be updated", func() {
 | |
| 					So(query.Result[0].State, ShouldEqual, models.AlertStateUnknown)
 | |
| 				})
 | |
| 			})
 | |
| 
 | |
| 			Convey("Updates without changes should be ignored", func() {
 | |
| 				err3 := SaveAlerts(&modifiedCmd)
 | |
| 				So(err3, ShouldBeNil)
 | |
| 			})
 | |
| 		})
 | |
| 
 | |
| 		Convey("Multiple alerts per dashboard", func() {
 | |
| 			multipleItems := []*models.Alert{
 | |
| 				{
 | |
| 					DashboardId: testDash.Id,
 | |
| 					PanelId:     1,
 | |
| 					Name:        "1",
 | |
| 					OrgId:       1,
 | |
| 					Settings:    simplejson.New(),
 | |
| 				},
 | |
| 				{
 | |
| 					DashboardId: testDash.Id,
 | |
| 					PanelId:     2,
 | |
| 					Name:        "2",
 | |
| 					OrgId:       1,
 | |
| 					Settings:    simplejson.New(),
 | |
| 				},
 | |
| 				{
 | |
| 					DashboardId: testDash.Id,
 | |
| 					PanelId:     3,
 | |
| 					Name:        "3",
 | |
| 					OrgId:       1,
 | |
| 					Settings:    simplejson.New(),
 | |
| 				},
 | |
| 			}
 | |
| 
 | |
| 			cmd.Alerts = multipleItems
 | |
| 			err = SaveAlerts(&cmd)
 | |
| 
 | |
| 			Convey("Should save 3 dashboards", func() {
 | |
| 				So(err, ShouldBeNil)
 | |
| 
 | |
| 				queryForDashboard := models.GetAlertsQuery{DashboardIDs: []int64{testDash.Id}, OrgId: 1, User: &models.SignedInUser{OrgRole: models.ROLE_ADMIN}}
 | |
| 				err2 := HandleAlertsQuery(&queryForDashboard)
 | |
| 
 | |
| 				So(err2, ShouldBeNil)
 | |
| 				So(len(queryForDashboard.Result), ShouldEqual, 3)
 | |
| 			})
 | |
| 
 | |
| 			Convey("should updated two dashboards and delete one", func() {
 | |
| 				missingOneAlert := multipleItems[:2]
 | |
| 
 | |
| 				cmd.Alerts = missingOneAlert
 | |
| 				err = SaveAlerts(&cmd)
 | |
| 
 | |
| 				Convey("should delete the missing alert", func() {
 | |
| 					query := models.GetAlertsQuery{DashboardIDs: []int64{testDash.Id}, OrgId: 1, User: &models.SignedInUser{OrgRole: models.ROLE_ADMIN}}
 | |
| 					err2 := HandleAlertsQuery(&query)
 | |
| 					So(err2, ShouldBeNil)
 | |
| 					So(len(query.Result), ShouldEqual, 2)
 | |
| 				})
 | |
| 			})
 | |
| 		})
 | |
| 
 | |
| 		Convey("When dashboard is removed", func() {
 | |
| 			items := []*models.Alert{
 | |
| 				{
 | |
| 					PanelId:     1,
 | |
| 					DashboardId: testDash.Id,
 | |
| 					Name:        "Alerting title",
 | |
| 					Message:     "Alerting message",
 | |
| 				},
 | |
| 			}
 | |
| 
 | |
| 			cmd := models.SaveAlertsCommand{
 | |
| 				Alerts:      items,
 | |
| 				DashboardId: testDash.Id,
 | |
| 				OrgId:       1,
 | |
| 				UserId:      1,
 | |
| 			}
 | |
| 
 | |
| 			err = SaveAlerts(&cmd)
 | |
| 			So(err, ShouldBeNil)
 | |
| 
 | |
| 			err = DeleteDashboard(&models.DeleteDashboardCommand{
 | |
| 				OrgId: 1,
 | |
| 				Id:    testDash.Id,
 | |
| 			})
 | |
| 			So(err, ShouldBeNil)
 | |
| 
 | |
| 			Convey("Alerts should be removed", func() {
 | |
| 				query := models.GetAlertsQuery{DashboardIDs: []int64{testDash.Id}, OrgId: 1, User: &models.SignedInUser{OrgRole: models.ROLE_ADMIN}}
 | |
| 				err2 := HandleAlertsQuery(&query)
 | |
| 
 | |
| 				So(err2, ShouldBeNil)
 | |
| 				So(len(query.Result), ShouldEqual, 0)
 | |
| 			})
 | |
| 		})
 | |
| 	})
 | |
| }
 | |
| 
 | |
| func TestPausingAlerts(t *testing.T) {
 | |
| 	mockTimeNow()
 | |
| 	defer resetTimeNow()
 | |
| 
 | |
| 	Convey("Given an alert", t, func() {
 | |
| 		sqlStore := InitTestDB(t)
 | |
| 
 | |
| 		testDash := insertTestDashboard(t, sqlStore, "dashboard with alerts", 1, 0, false, "alert")
 | |
| 		alert, err := insertTestAlert("Alerting title", "Alerting message", testDash.OrgId, testDash.Id, simplejson.New())
 | |
| 		So(err, ShouldBeNil)
 | |
| 
 | |
| 		stateDateBeforePause := alert.NewStateDate
 | |
| 		stateDateAfterPause := stateDateBeforePause
 | |
| 
 | |
| 		// Get alert so we can use its ID in tests
 | |
| 		alertQuery := models.GetAlertsQuery{DashboardIDs: []int64{testDash.Id}, PanelId: 1, OrgId: 1, User: &models.SignedInUser{OrgRole: models.ROLE_ADMIN}}
 | |
| 		err2 := HandleAlertsQuery(&alertQuery)
 | |
| 		So(err2, ShouldBeNil)
 | |
| 
 | |
| 		insertedAlert := alertQuery.Result[0]
 | |
| 
 | |
| 		Convey("when paused", func() {
 | |
| 			_, err := pauseAlert(testDash.OrgId, insertedAlert.Id, true)
 | |
| 			So(err, ShouldBeNil)
 | |
| 
 | |
| 			Convey("the NewStateDate should be updated", func() {
 | |
| 				alert, err := getAlertById(insertedAlert.Id)
 | |
| 				So(err, ShouldBeNil)
 | |
| 
 | |
| 				stateDateAfterPause = alert.NewStateDate
 | |
| 				So(stateDateBeforePause, ShouldHappenBefore, stateDateAfterPause)
 | |
| 			})
 | |
| 		})
 | |
| 
 | |
| 		Convey("when unpaused", func() {
 | |
| 			_, err := pauseAlert(testDash.OrgId, insertedAlert.Id, false)
 | |
| 			So(err, ShouldBeNil)
 | |
| 
 | |
| 			Convey("the NewStateDate should be updated again", func() {
 | |
| 				alert, err := getAlertById(insertedAlert.Id)
 | |
| 				So(err, ShouldBeNil)
 | |
| 
 | |
| 				stateDateAfterUnpause := alert.NewStateDate
 | |
| 				So(stateDateAfterPause, ShouldHappenBefore, stateDateAfterUnpause)
 | |
| 			})
 | |
| 		})
 | |
| 	})
 | |
| }
 | |
| func pauseAlert(orgId int64, alertId int64, pauseState bool) (int64, error) {
 | |
| 	cmd := &models.PauseAlertCommand{
 | |
| 		OrgId:    orgId,
 | |
| 		AlertIds: []int64{alertId},
 | |
| 		Paused:   pauseState,
 | |
| 	}
 | |
| 	err := PauseAlert(cmd)
 | |
| 	So(err, ShouldBeNil)
 | |
| 	return cmd.ResultCount, err
 | |
| }
 | |
| func insertTestAlert(title string, message string, orgId int64, dashId int64, settings *simplejson.Json) (*models.Alert, error) {
 | |
| 	items := []*models.Alert{
 | |
| 		{
 | |
| 			PanelId:     1,
 | |
| 			DashboardId: dashId,
 | |
| 			OrgId:       orgId,
 | |
| 			Name:        title,
 | |
| 			Message:     message,
 | |
| 			Settings:    settings,
 | |
| 			Frequency:   1,
 | |
| 		},
 | |
| 	}
 | |
| 
 | |
| 	cmd := models.SaveAlertsCommand{
 | |
| 		Alerts:      items,
 | |
| 		DashboardId: dashId,
 | |
| 		OrgId:       orgId,
 | |
| 		UserId:      1,
 | |
| 	}
 | |
| 
 | |
| 	err := SaveAlerts(&cmd)
 | |
| 	return cmd.Alerts[0], err
 | |
| }
 | |
| 
 | |
| func getAlertById(id int64) (*models.Alert, error) {
 | |
| 	q := &models.GetAlertByIdQuery{
 | |
| 		Id: id,
 | |
| 	}
 | |
| 	err := GetAlertById(q)
 | |
| 	So(err, ShouldBeNil)
 | |
| 	return q.Result, err
 | |
| }
 | |
| 
 | |
| func pauseAllAlerts(pauseState bool) error {
 | |
| 	cmd := &models.PauseAllAlertCommand{
 | |
| 		Paused: pauseState,
 | |
| 	}
 | |
| 	err := PauseAllAlerts(cmd)
 | |
| 	So(err, ShouldBeNil)
 | |
| 	return err
 | |
| }
 |