query_test.go 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116
  1. package conditions
  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/grafana/grafana/pkg/services/alerting"
  8. "github.com/grafana/grafana/pkg/tsdb"
  9. . "github.com/smartystreets/goconvey/convey"
  10. )
  11. func TestQueryCondition(t *testing.T) {
  12. Convey("when evaluating query condition", t, func() {
  13. queryConditionScenario("Given avg() and > 100", func(ctx *queryConditionTestContext) {
  14. ctx.reducer = `{"type": "avg"}`
  15. ctx.evaluator = `{"type": ">", "params": [100]}`
  16. Convey("Can read query condition from json model", func() {
  17. ctx.exec()
  18. So(ctx.condition.Query.From, ShouldEqual, "5m")
  19. So(ctx.condition.Query.To, ShouldEqual, "now")
  20. So(ctx.condition.Query.DatasourceId, ShouldEqual, 1)
  21. Convey("Can read query reducer", func() {
  22. reducer, ok := ctx.condition.Reducer.(*SimpleReducer)
  23. So(ok, ShouldBeTrue)
  24. So(reducer.Type, ShouldEqual, "avg")
  25. })
  26. Convey("Can read evaluator", func() {
  27. evaluator, ok := ctx.condition.Evaluator.(*DefaultAlertEvaluator)
  28. So(ok, ShouldBeTrue)
  29. So(evaluator.Type, ShouldEqual, ">")
  30. })
  31. })
  32. Convey("should fire when avg is above 100", func() {
  33. ctx.series = tsdb.TimeSeriesSlice{tsdb.NewTimeSeries("test1", [][2]float64{{120, 0}})}
  34. ctx.exec()
  35. So(ctx.result.Error, ShouldBeNil)
  36. So(ctx.result.Firing, ShouldBeTrue)
  37. })
  38. Convey("Should not fire when avg is below 100", func() {
  39. ctx.series = tsdb.TimeSeriesSlice{tsdb.NewTimeSeries("test1", [][2]float64{{90, 0}})}
  40. ctx.exec()
  41. So(ctx.result.Error, ShouldBeNil)
  42. So(ctx.result.Firing, ShouldBeFalse)
  43. })
  44. })
  45. })
  46. }
  47. type queryConditionTestContext struct {
  48. reducer string
  49. evaluator string
  50. series tsdb.TimeSeriesSlice
  51. result *alerting.AlertResultContext
  52. condition *QueryCondition
  53. }
  54. type queryConditionScenarioFunc func(c *queryConditionTestContext)
  55. func (ctx *queryConditionTestContext) exec() {
  56. jsonModel, err := simplejson.NewJson([]byte(`{
  57. "type": "query",
  58. "query": {
  59. "params": ["A", "5m", "now"],
  60. "datasourceId": 1,
  61. "model": {"target": "aliasByNode(statsd.fakesite.counters.session_start.mobile.count, 4)"}
  62. },
  63. "reducer":` + ctx.reducer + `,
  64. "evaluator":` + ctx.evaluator + `
  65. }`))
  66. So(err, ShouldBeNil)
  67. condition, err := NewQueryCondition(jsonModel, 0)
  68. So(err, ShouldBeNil)
  69. ctx.condition = condition
  70. condition.HandleRequest = func(req *tsdb.Request) (*tsdb.Response, error) {
  71. return &tsdb.Response{
  72. Results: map[string]*tsdb.QueryResult{
  73. "A": {Series: ctx.series},
  74. },
  75. }, nil
  76. }
  77. condition.Eval(ctx.result)
  78. }
  79. func queryConditionScenario(desc string, fn queryConditionScenarioFunc) {
  80. Convey(desc, func() {
  81. bus.AddHandler("test", func(query *m.GetDataSourceByIdQuery) error {
  82. query.Result = &m.DataSource{Id: 1, Type: "graphite"}
  83. return nil
  84. })
  85. ctx := &queryConditionTestContext{}
  86. ctx.result = &alerting.AlertResultContext{
  87. Rule: &alerting.AlertRule{},
  88. }
  89. fn(ctx)
  90. })
  91. }