mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
Chore: Test datasource to support template $seriesIndex in label values (#68497)
* update test datasource to support template $seriesIndex in label values * prettier --------- Co-authored-by: Marcus Efraimsson <marcus.efraimsson@gmail.com>
This commit is contained in:
parent
8ba1762618
commit
d3ae8df357
@ -652,7 +652,7 @@ func (s *Service) handleLogsScenario(ctx context.Context, req *backend.QueryData
|
|||||||
}
|
}
|
||||||
|
|
||||||
func RandomWalk(query backend.DataQuery, model *simplejson.Json, index int) *data.Frame {
|
func RandomWalk(query backend.DataQuery, model *simplejson.Json, index int) *data.Frame {
|
||||||
rand := rand.New(rand.NewSource(time.Now().UnixNano()))
|
rand := rand.New(rand.NewSource(time.Now().UnixNano() + int64(index)))
|
||||||
timeWalkerMs := query.TimeRange.From.UnixNano() / int64(time.Millisecond)
|
timeWalkerMs := query.TimeRange.From.UnixNano() / int64(time.Millisecond)
|
||||||
to := query.TimeRange.To.UnixNano() / int64(time.Millisecond)
|
to := query.TimeRange.To.UnixNano() / int64(time.Millisecond)
|
||||||
startValue := model.Get("startValue").MustFloat64(rand.Float64() * 100)
|
startValue := model.Get("startValue").MustFloat64(rand.Float64() * 100)
|
||||||
@ -700,7 +700,7 @@ func RandomWalk(query backend.DataQuery, model *simplejson.Json, index int) *dat
|
|||||||
SetConfig(&data.FieldConfig{
|
SetConfig(&data.FieldConfig{
|
||||||
Interval: float64(query.Interval.Milliseconds()),
|
Interval: float64(query.Interval.Milliseconds()),
|
||||||
}),
|
}),
|
||||||
data.NewField(frameNameForQuery(query, model, index), parseLabels(model), floatVec),
|
data.NewField(frameNameForQuery(query, model, index), parseLabels(model, index), floatVec),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -843,7 +843,7 @@ func predictableCSVWave(query backend.DataQuery, model *simplejson.Json) ([]*dat
|
|||||||
|
|
||||||
frame := newSeriesForQuery(query, model, 0)
|
frame := newSeriesForQuery(query, model, 0)
|
||||||
frame.Fields = fields
|
frame.Fields = fields
|
||||||
frame.Fields[1].Labels = parseLabelsString(subQ.Labels)
|
frame.Fields[1].Labels = parseLabelsString(subQ.Labels, 0)
|
||||||
if subQ.Name != "" {
|
if subQ.Name != "" {
|
||||||
frame.Name = subQ.Name
|
frame.Name = subQ.Name
|
||||||
}
|
}
|
||||||
@ -929,7 +929,7 @@ func predictablePulse(query backend.DataQuery, model *simplejson.Json) (*data.Fr
|
|||||||
|
|
||||||
frame := newSeriesForQuery(query, model, 0)
|
frame := newSeriesForQuery(query, model, 0)
|
||||||
frame.Fields = fields
|
frame.Fields = fields
|
||||||
frame.Fields[1].Labels = parseLabels(model)
|
frame.Fields[1].Labels = parseLabels(model, 0)
|
||||||
|
|
||||||
return frame, nil
|
return frame, nil
|
||||||
}
|
}
|
||||||
@ -998,12 +998,12 @@ func newSeriesForQuery(query backend.DataQuery, model *simplejson.Json, index in
|
|||||||
*
|
*
|
||||||
* '{job="foo", instance="bar"} => {job: "foo", instance: "bar"}`
|
* '{job="foo", instance="bar"} => {job: "foo", instance: "bar"}`
|
||||||
*/
|
*/
|
||||||
func parseLabels(model *simplejson.Json) data.Labels {
|
func parseLabels(model *simplejson.Json, seriesIndex int) data.Labels {
|
||||||
labelText := model.Get("labels").MustString("")
|
labelText := model.Get("labels").MustString("")
|
||||||
return parseLabelsString(labelText)
|
return parseLabelsString(labelText, seriesIndex)
|
||||||
}
|
}
|
||||||
|
|
||||||
func parseLabelsString(labelText string) data.Labels {
|
func parseLabelsString(labelText string, seriesIndex int) data.Labels {
|
||||||
if labelText == "" {
|
if labelText == "" {
|
||||||
return data.Labels{}
|
return data.Labels{}
|
||||||
}
|
}
|
||||||
@ -1020,6 +1020,7 @@ func parseLabelsString(labelText string) data.Labels {
|
|||||||
key := strings.TrimSpace(keyval[:idx])
|
key := strings.TrimSpace(keyval[:idx])
|
||||||
val := strings.TrimSpace(keyval[idx+1:])
|
val := strings.TrimSpace(keyval[idx+1:])
|
||||||
val = strings.Trim(val, "\"")
|
val = strings.Trim(val, "\"")
|
||||||
|
val = strings.ReplaceAll(val, "$seriesIndex", strconv.Itoa(seriesIndex))
|
||||||
tags[key] = val
|
tags[key] = val
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3,15 +3,17 @@ package testdatasource
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"math/rand"
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/grafana/grafana-plugin-sdk-go/backend"
|
"github.com/grafana/grafana-plugin-sdk-go/backend"
|
||||||
"github.com/grafana/grafana-plugin-sdk-go/data"
|
"github.com/grafana/grafana-plugin-sdk-go/data"
|
||||||
"github.com/grafana/grafana/pkg/components/simplejson"
|
|
||||||
"github.com/grafana/grafana/pkg/tsdb/legacydata"
|
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
|
|
||||||
|
"github.com/grafana/grafana/pkg/components/simplejson"
|
||||||
|
"github.com/grafana/grafana/pkg/tsdb/legacydata"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestTestdataScenarios(t *testing.T) {
|
func TestTestdataScenarios(t *testing.T) {
|
||||||
@ -193,23 +195,47 @@ func TestParseLabels(t *testing.T) {
|
|||||||
"job": "foo",
|
"job": "foo",
|
||||||
"instance": "bar",
|
"instance": "bar",
|
||||||
}
|
}
|
||||||
|
seriesIndex := rand.Int()
|
||||||
|
|
||||||
tcs := []struct {
|
tests := []struct {
|
||||||
model map[string]interface{}
|
name string
|
||||||
|
model map[string]interface{}
|
||||||
|
expected data.Labels
|
||||||
}{
|
}{
|
||||||
{model: map[string]interface{}{
|
{
|
||||||
"labels": `{job="foo", instance="bar"}`,
|
name: "wrapped in {} and quoted value ",
|
||||||
}},
|
model: map[string]interface{}{"labels": `{job="foo", instance="bar"}`},
|
||||||
{model: map[string]interface{}{
|
expected: expectedTags,
|
||||||
"labels": `job=foo, instance=bar`,
|
},
|
||||||
}},
|
{
|
||||||
{model: map[string]interface{}{
|
name: "comma-separated non-quoted",
|
||||||
"labels": `job = foo,instance = bar`,
|
model: map[string]interface{}{"labels": `job=foo, instance=bar`},
|
||||||
}},
|
expected: expectedTags,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "comma-separated quoted",
|
||||||
|
model: map[string]interface{}{"labels": `job="foo"", instance="bar"`},
|
||||||
|
expected: expectedTags,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "comma-separated with spaces, non quoted",
|
||||||
|
model: map[string]interface{}{"labels": `job = foo,instance = bar`},
|
||||||
|
expected: expectedTags,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "expands $seriesIndex",
|
||||||
|
model: map[string]interface{}{"labels": `job=series-$seriesIndex,instance=bar`},
|
||||||
|
expected: data.Labels{
|
||||||
|
"job": fmt.Sprintf("series-%d", seriesIndex),
|
||||||
|
"instance": "bar",
|
||||||
|
},
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
for i, tc := range tcs {
|
for i, tc := range tests {
|
||||||
model := simplejson.NewFromAny(tc.model)
|
t.Run(tc.name, func(t *testing.T) {
|
||||||
assert.Equal(t, expectedTags, parseLabels(model), fmt.Sprintf("Actual tags in test case %d doesn't match expected tags", i+1))
|
model := simplejson.NewFromAny(tc.model)
|
||||||
|
assert.Equal(t, tc.expected, parseLabels(model, seriesIndex), fmt.Sprintf("Actual tags in test case %d doesn't match expected tags", i+1))
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -231,6 +231,9 @@ export const QueryEditor = ({ query, datasource, onChange, onRunQuery }: Props)
|
|||||||
<br />
|
<br />
|
||||||
key=value, key2=value
|
key=value, key2=value
|
||||||
<br />
|
<br />
|
||||||
|
Value can contain templates:
|
||||||
|
<br />
|
||||||
|
$seriesIndex - replaced with index of the series
|
||||||
</>
|
</>
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
|
Loading…
Reference in New Issue
Block a user