func TestQueryCondition(t *testing.T) { Convey("when evaluating query condition", t, func() { queryConditionScenario("Given avg() and > 100", func(ctx *queryConditionTestContext) { ctx.reducer = `{"type": "avg"}` ctx.evaluator = `{"type": "gt", "params": [100]}` Convey("Can read query condition from json model", func() { ctx.exec() So(ctx.condition.Query.From, ShouldEqual, "5m") So(ctx.condition.Query.To, ShouldEqual, "now") So(ctx.condition.Query.DatasourceId, ShouldEqual, 1) Convey("Can read query reducer", func() { reducer, ok := ctx.condition.Reducer.(*SimpleReducer) So(ok, ShouldBeTrue) So(reducer.Type, ShouldEqual, "avg") }) Convey("Can read evaluator", func() { evaluator, ok := ctx.condition.Evaluator.(*ThresholdEvaluator) So(ok, ShouldBeTrue) So(evaluator.Type, ShouldEqual, "gt") }) }) Convey("should fire when avg is above 100", func() { points := tsdb.NewTimeSeriesPointsFromArgs(120, 0) ctx.series = tsdb.TimeSeriesSlice{tsdb.NewTimeSeries("test1", points)} cr, err := ctx.exec() So(err, ShouldBeNil) So(cr.Firing, ShouldBeTrue) }) Convey("Should not fire when avg is below 100", func() { points := tsdb.NewTimeSeriesPointsFromArgs(90, 0) ctx.series = tsdb.TimeSeriesSlice{tsdb.NewTimeSeries("test1", points)} cr, err := ctx.exec() So(err, ShouldBeNil) So(cr.Firing, ShouldBeFalse) }) Convey("Should fire if only first serie matches", func() { ctx.series = tsdb.TimeSeriesSlice{ tsdb.NewTimeSeries("test1", tsdb.NewTimeSeriesPointsFromArgs(120, 0)), tsdb.NewTimeSeries("test2", tsdb.NewTimeSeriesPointsFromArgs(0, 0)), } cr, err := ctx.exec() So(err, ShouldBeNil) So(cr.Firing, ShouldBeTrue) }) Convey("No series", func() { Convey("Should set NoDataFound when condition is gt", func() { ctx.series = tsdb.TimeSeriesSlice{} cr, err := ctx.exec() So(err, ShouldBeNil) So(cr.Firing, ShouldBeFalse) So(cr.NoDataFound, ShouldBeTrue) }) Convey("Should be firing when condition is no_value", func() { ctx.evaluator = `{"type": "no_value", "params": []}` ctx.series = tsdb.TimeSeriesSlice{} cr, err := ctx.exec() So(err, ShouldBeNil) So(cr.Firing, ShouldBeTrue) }) }) Convey("Empty series", func() { Convey("Should set Firing if eval match", func() { ctx.evaluator = `{"type": "no_value", "params": []}` ctx.series = tsdb.TimeSeriesSlice{ tsdb.NewTimeSeries("test1", tsdb.NewTimeSeriesPointsFromArgs()), } cr, err := ctx.exec() So(err, ShouldBeNil) So(cr.Firing, ShouldBeTrue) }) Convey("Should set NoDataFound both series are empty", func() { ctx.series = tsdb.TimeSeriesSlice{ tsdb.NewTimeSeries("test1", tsdb.NewTimeSeriesPointsFromArgs()), tsdb.NewTimeSeries("test2", tsdb.NewTimeSeriesPointsFromArgs()), } cr, err := ctx.exec() So(err, ShouldBeNil) So(cr.NoDataFound, ShouldBeTrue) }) Convey("Should set NoDataFound both series contains null", func() { ctx.series = tsdb.TimeSeriesSlice{ tsdb.NewTimeSeries("test1", tsdb.TimeSeriesPoints{tsdb.TimePoint{null.FloatFromPtr(nil), null.FloatFrom(0)}}), tsdb.NewTimeSeries("test2", tsdb.TimeSeriesPoints{tsdb.TimePoint{null.FloatFromPtr(nil), null.FloatFrom(0)}}), } cr, err := ctx.exec() So(err, ShouldBeNil) So(cr.NoDataFound, ShouldBeTrue) }) Convey("Should not set NoDataFound if one serie is empty", func() { ctx.series = tsdb.TimeSeriesSlice{ tsdb.NewTimeSeries("test1", tsdb.NewTimeSeriesPointsFromArgs()), tsdb.NewTimeSeries("test2", tsdb.NewTimeSeriesPointsFromArgs(120, 0)), } cr, err := ctx.exec() So(err, ShouldBeNil) So(cr.NoDataFound, ShouldBeFalse) }) }) }) }) }
func TestQueryCondition(t *testing.T) { Convey("when evaluating query condition", t, func() { queryConditionScenario("Given avg() and > 100", func(ctx *queryConditionTestContext) { ctx.reducer = `{"type": "avg"}` ctx.evaluator = `{"type": "gt", "params": [100]}` Convey("Can read query condition from json model", func() { ctx.exec() So(ctx.condition.Query.From, ShouldEqual, "5m") So(ctx.condition.Query.To, ShouldEqual, "now") So(ctx.condition.Query.DatasourceId, ShouldEqual, 1) Convey("Can read query reducer", func() { reducer, ok := ctx.condition.Reducer.(*SimpleReducer) So(ok, ShouldBeTrue) So(reducer.Type, ShouldEqual, "avg") }) Convey("Can read evaluator", func() { evaluator, ok := ctx.condition.Evaluator.(*ThresholdEvaluator) So(ok, ShouldBeTrue) So(evaluator.Type, ShouldEqual, "gt") }) }) Convey("should fire when avg is above 100", func() { one := float64(120) two := float64(0) ctx.series = tsdb.TimeSeriesSlice{tsdb.NewTimeSeries("test1", [][2]*float64{{&one, &two}})} ctx.exec() So(ctx.result.Error, ShouldBeNil) So(ctx.result.Firing, ShouldBeTrue) }) Convey("Should not fire when avg is below 100", func() { one := float64(90) two := float64(0) ctx.series = tsdb.TimeSeriesSlice{tsdb.NewTimeSeries("test1", [][2]*float64{{&one, &two}})} ctx.exec() So(ctx.result.Error, ShouldBeNil) So(ctx.result.Firing, ShouldBeFalse) }) Convey("Should fire if only first serie matches", func() { one := float64(120) two := float64(0) ctx.series = tsdb.TimeSeriesSlice{ tsdb.NewTimeSeries("test1", [][2]*float64{{&one, &two}}), tsdb.NewTimeSeries("test2", [][2]*float64{{&two, &two}}), } ctx.exec() So(ctx.result.Error, ShouldBeNil) So(ctx.result.Firing, ShouldBeTrue) }) Convey("Empty series", func() { Convey("Should set NoDataFound both series are empty", func() { ctx.series = tsdb.TimeSeriesSlice{ tsdb.NewTimeSeries("test1", [][2]*float64{}), tsdb.NewTimeSeries("test2", [][2]*float64{}), } ctx.exec() So(ctx.result.Error, ShouldBeNil) So(ctx.result.NoDataFound, ShouldBeTrue) }) Convey("Should set NoDataFound both series contains null", func() { one := float64(120) ctx.series = tsdb.TimeSeriesSlice{ tsdb.NewTimeSeries("test1", [][2]*float64{{nil, &one}}), tsdb.NewTimeSeries("test2", [][2]*float64{{nil, &one}}), } ctx.exec() So(ctx.result.Error, ShouldBeNil) So(ctx.result.NoDataFound, ShouldBeTrue) }) Convey("Should not set NoDataFound if one serie is empty", func() { one := float64(120) two := float64(0) ctx.series = tsdb.TimeSeriesSlice{ tsdb.NewTimeSeries("test1", [][2]*float64{}), tsdb.NewTimeSeries("test2", [][2]*float64{{&one, &two}}), } ctx.exec() So(ctx.result.Error, ShouldBeNil) So(ctx.result.NoDataFound, ShouldBeFalse) }) }) }) }) }