mirror of
https://github.com/grafana/grafana.git
synced 2025-02-20 11:48:34 -06:00
* propagate notificationservice down to the notifiers * replace dispatch in result handler * remove dispatch from the rule reader * remove dispatch from eval context * remove dispatch from alerting usage * remove dispatch from alerting usage * remove dispatch from notifier * attempt to fix tests in alerting * hello linter, my old friend; also disable some tests for now * use mocks to fix the tests * resolving wire providers * make linter happy * remove yet another bus.dispatch * fix tests using store mock
183 lines
6.2 KiB
Go
183 lines
6.2 KiB
Go
package conditions
|
|
|
|
import (
|
|
"context"
|
|
"testing"
|
|
|
|
"github.com/grafana/grafana/pkg/components/simplejson"
|
|
"github.com/grafana/grafana/pkg/models"
|
|
"github.com/grafana/grafana/pkg/services/alerting"
|
|
"github.com/grafana/grafana/pkg/services/sqlstore/mockstore"
|
|
"github.com/grafana/grafana/pkg/services/validations"
|
|
"github.com/grafana/grafana/pkg/tsdb/intervalv2"
|
|
"github.com/grafana/grafana/pkg/tsdb/legacydata"
|
|
|
|
"github.com/stretchr/testify/require"
|
|
)
|
|
|
|
func TestQueryInterval(t *testing.T) {
|
|
t.Run("When evaluating query condition, regarding the interval value", func(t *testing.T) {
|
|
t.Run("Can handle interval-calculation with no panel-min-interval and no datasource-min-interval", func(t *testing.T) {
|
|
// no panel-min-interval in the queryModel
|
|
queryModel := `{"target": "aliasByNode(statsd.fakesite.counters.session_start.mobile.count, 4)"}`
|
|
|
|
// no datasource-min-interval
|
|
var dataSourceJson *simplejson.Json = nil
|
|
|
|
timeRange := "5m"
|
|
|
|
verifier := func(query legacydata.DataSubQuery) {
|
|
// 5minutes timerange = 300000milliseconds; default-resolution is 1500pixels,
|
|
// so we should have 300000/1500 = 200milliseconds here
|
|
require.Equal(t, int64(200), query.IntervalMS)
|
|
require.Equal(t, intervalv2.DefaultRes, query.MaxDataPoints)
|
|
}
|
|
|
|
applyScenario(t, timeRange, dataSourceJson, queryModel, verifier)
|
|
})
|
|
t.Run("Can handle interval-calculation with panel-min-interval and no datasource-min-interval", func(t *testing.T) {
|
|
// panel-min-interval in the queryModel
|
|
queryModel := `{"interval":"123s", "target": "aliasByNode(statsd.fakesite.counters.session_start.mobile.count, 4)"}`
|
|
|
|
// no datasource-min-interval
|
|
var dataSourceJson *simplejson.Json = nil
|
|
|
|
timeRange := "5m"
|
|
|
|
verifier := func(query legacydata.DataSubQuery) {
|
|
require.Equal(t, int64(123000), query.IntervalMS)
|
|
require.Equal(t, intervalv2.DefaultRes, query.MaxDataPoints)
|
|
}
|
|
|
|
applyScenario(t, timeRange, dataSourceJson, queryModel, verifier)
|
|
})
|
|
t.Run("Can handle interval-calculation with no panel-min-interval and datasource-min-interval", func(t *testing.T) {
|
|
// no panel-min-interval in the queryModel
|
|
queryModel := `{"target": "aliasByNode(statsd.fakesite.counters.session_start.mobile.count, 4)"}`
|
|
|
|
// min-interval in datasource-json
|
|
dataSourceJson, err := simplejson.NewJson([]byte(`{
|
|
"timeInterval": "71s"
|
|
}`))
|
|
require.Nil(t, err)
|
|
|
|
timeRange := "5m"
|
|
|
|
verifier := func(query legacydata.DataSubQuery) {
|
|
require.Equal(t, int64(71000), query.IntervalMS)
|
|
require.Equal(t, intervalv2.DefaultRes, query.MaxDataPoints)
|
|
}
|
|
|
|
applyScenario(t, timeRange, dataSourceJson, queryModel, verifier)
|
|
})
|
|
t.Run("Can handle interval-calculation with both panel-min-interval and datasource-min-interval", func(t *testing.T) {
|
|
// panel-min-interval in the queryModel
|
|
queryModel := `{"interval":"19s", "target": "aliasByNode(statsd.fakesite.counters.session_start.mobile.count, 4)"}`
|
|
|
|
// min-interval in datasource-json
|
|
dataSourceJson, err := simplejson.NewJson([]byte(`{
|
|
"timeInterval": "71s"
|
|
}`))
|
|
require.Nil(t, err)
|
|
|
|
timeRange := "5m"
|
|
|
|
verifier := func(query legacydata.DataSubQuery) {
|
|
// when both panel-min-interval and datasource-min-interval exists,
|
|
// panel-min-interval is used
|
|
require.Equal(t, int64(19000), query.IntervalMS)
|
|
require.Equal(t, intervalv2.DefaultRes, query.MaxDataPoints)
|
|
}
|
|
|
|
applyScenario(t, timeRange, dataSourceJson, queryModel, verifier)
|
|
})
|
|
|
|
t.Run("Can handle no min-interval, and very small time-ranges, where the default-min-interval=1ms applies", func(t *testing.T) {
|
|
// no panel-min-interval in the queryModel
|
|
queryModel := `{"target": "aliasByNode(statsd.fakesite.counters.session_start.mobile.count, 4)"}`
|
|
|
|
// no datasource-min-interval
|
|
var dataSourceJson *simplejson.Json = nil
|
|
|
|
timeRange := "1s"
|
|
|
|
verifier := func(query legacydata.DataSubQuery) {
|
|
// no min-interval exists, the default-min-interval will be used,
|
|
// and for such a short time-range this will cause the value to be 1millisecond.
|
|
require.Equal(t, int64(1), query.IntervalMS)
|
|
require.Equal(t, intervalv2.DefaultRes, query.MaxDataPoints)
|
|
}
|
|
|
|
applyScenario(t, timeRange, dataSourceJson, queryModel, verifier)
|
|
})
|
|
})
|
|
}
|
|
|
|
type queryIntervalTestContext struct {
|
|
result *alerting.EvalContext
|
|
condition *QueryCondition
|
|
}
|
|
|
|
type queryIntervalVerifier func(query legacydata.DataSubQuery)
|
|
|
|
type fakeIntervalTestReqHandler struct {
|
|
//nolint: staticcheck // legacydata.DataResponse deprecated
|
|
response legacydata.DataResponse
|
|
verifier queryIntervalVerifier
|
|
}
|
|
|
|
//nolint: staticcheck // legacydata.DataResponse deprecated
|
|
func (rh fakeIntervalTestReqHandler) HandleRequest(ctx context.Context, dsInfo *models.DataSource, query legacydata.DataQuery) (
|
|
legacydata.DataResponse, error) {
|
|
q := query.Queries[0]
|
|
rh.verifier(q)
|
|
return rh.response, nil
|
|
}
|
|
|
|
//nolint: staticcheck // legacydata.DataResponse deprecated
|
|
func applyScenario(t *testing.T, timeRange string, dataSourceJsonData *simplejson.Json, queryModel string, verifier func(query legacydata.DataSubQuery)) {
|
|
t.Run("desc", func(t *testing.T) {
|
|
store := mockstore.NewSQLStoreMock()
|
|
store.ExpectedDatasource = &models.DataSource{Id: 1, Type: "graphite", JsonData: dataSourceJsonData}
|
|
|
|
ctx := &queryIntervalTestContext{}
|
|
ctx.result = &alerting.EvalContext{
|
|
Ctx: context.Background(),
|
|
Rule: &alerting.Rule{},
|
|
RequestValidator: &validations.OSSPluginRequestValidator{},
|
|
Store: store,
|
|
}
|
|
|
|
jsonModel, err := simplejson.NewJson([]byte(`{
|
|
"type": "query",
|
|
"query": {
|
|
"params": ["A", "` + timeRange + `", "now"],
|
|
"datasourceId": 1,
|
|
"model": ` + queryModel + `
|
|
},
|
|
"reducer":{"type": "avg"},
|
|
"evaluator":{"type": "gt", "params": [100]}
|
|
}`))
|
|
require.Nil(t, err)
|
|
|
|
condition, err := newQueryCondition(jsonModel, 0)
|
|
require.Nil(t, err)
|
|
|
|
ctx.condition = condition
|
|
|
|
qr := legacydata.DataQueryResult{}
|
|
|
|
reqHandler := fakeIntervalTestReqHandler{
|
|
response: legacydata.DataResponse{
|
|
Results: map[string]legacydata.DataQueryResult{
|
|
"A": qr,
|
|
},
|
|
},
|
|
verifier: verifier,
|
|
}
|
|
_, err = condition.Eval(ctx.result, reqHandler)
|
|
|
|
require.Nil(t, err)
|
|
})
|
|
}
|