From b7ea66b00dea6a7fbb6409384b9621d57dab6f12 Mon Sep 17 00:00:00 2001 From: Ben Sully Date: Wed, 26 May 2021 10:45:11 +0100 Subject: [PATCH] Datasource: Use intervalMs field of query model in GetIntervalFrom if interval field is not set (#34270) The /api/ds/query and /api/tsdb/query endpoints extract the intervalMs field from each query in the request, but it currently seems to be ignored, at least for queries to a Prometheus datasource. This changes GetIntervalFrom function to check for the presence of intervalMs in the query model if interval is missing. --- pkg/tsdb/interval/interval.go | 9 +++++++++ pkg/tsdb/interval/interval_test.go | 10 ++++++++++ 2 files changed, 19 insertions(+) diff --git a/pkg/tsdb/interval/interval.go b/pkg/tsdb/interval/interval.go index 14e99d2f95a..5ce318e31ac 100644 --- a/pkg/tsdb/interval/interval.go +++ b/pkg/tsdb/interval/interval.go @@ -69,6 +69,15 @@ func (ic *intervalCalculator) Calculate(timerange plugins.DataTimeRange, minInte func GetIntervalFrom(dsInfo *models.DataSource, queryModel *simplejson.Json, defaultInterval time.Duration) (time.Duration, error) { interval := queryModel.Get("interval").MustString("") + // intervalMs field appears in the v2 plugins API and should be preferred + // if 'interval' isn't present. + if interval == "" { + intervalMS := queryModel.Get("intervalMs").MustInt(0) + if intervalMS != 0 { + return time.Duration(intervalMS) * time.Millisecond, nil + } + } + if interval == "" && dsInfo != nil && dsInfo.JsonData != nil { dsInterval := dsInfo.JsonData.Get("timeInterval").MustString("") if dsInterval != "" { diff --git a/pkg/tsdb/interval/interval_test.go b/pkg/tsdb/interval/interval_test.go index 88bba2a2d86..6a38b20c048 100644 --- a/pkg/tsdb/interval/interval_test.go +++ b/pkg/tsdb/interval/interval_test.go @@ -8,6 +8,7 @@ import ( "github.com/grafana/grafana/pkg/models" "github.com/grafana/grafana/pkg/plugins" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" ) func TestIntervalCalculator_Calculate(t *testing.T) { @@ -70,6 +71,8 @@ func TestFormatDuration(t *testing.T) { } func TestGetIntervalFrom(t *testing.T) { + dsJSON, err := simplejson.NewJson([]byte(`{"timeInterval": "60s"}`)) + require.NoError(t, err) testCases := []struct { name string dsInfo *models.DataSource @@ -80,6 +83,13 @@ func TestGetIntervalFrom(t *testing.T) { {"45s", nil, `{"interval": "45s"}`, time.Second * 15, time.Second * 45}, {"45", nil, `{"interval": "45"}`, time.Second * 15, time.Second * 45}, {"2m", nil, `{"interval": "2m"}`, time.Second * 15, time.Minute * 2}, + {"intervalMs", nil, `{"intervalMs": 45000}`, time.Second * 15, time.Second * 45}, + {"intervalMs sub-seconds", nil, `{"intervalMs": 45200}`, time.Second * 15, time.Millisecond * 45200}, + {"dsInfo timeInterval", &models.DataSource{ + JsonData: dsJSON, + }, `{}`, time.Second * 15, time.Second * 60}, + {"defaultInterval when interval empty", nil, `{"interval": ""}`, time.Second * 15, time.Second * 15}, + {"defaultInterval when intervalMs 0", nil, `{"intervalMs": 0}`, time.Second * 15, time.Second * 15}, } for _, tc := range testCases {