mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
* Expand the value of math and reduce expressions in annotations and labels
This commit makes it possible to use the values of reduce and math
expressions in annotations and labels via their RefIDs. It uses the
Stringer interface to ensure that "{{ $values.A }}" still prints the
value in decimal format while also making the labels for each RefID
available with "{{ $values.A.Labels }}" and the float64 value with
"{{ $values.A.Value }}"
106 lines
3.3 KiB
Go
106 lines
3.3 KiB
Go
package eval
|
|
|
|
import (
|
|
"testing"
|
|
|
|
"github.com/grafana/grafana-plugin-sdk-go/data"
|
|
"github.com/grafana/grafana/pkg/expr/classic"
|
|
"github.com/stretchr/testify/require"
|
|
ptr "github.com/xorcare/pointer"
|
|
)
|
|
|
|
func TestExtractEvalString(t *testing.T) {
|
|
cases := []struct {
|
|
desc string
|
|
inFrame *data.Frame
|
|
outString string
|
|
}{
|
|
{
|
|
desc: "1 EvalMatch",
|
|
inFrame: newMetaFrame([]classic.EvalMatch{
|
|
{Metric: "Test", Labels: data.Labels{"host": "foo"}, Value: ptr.Float64(32.3)},
|
|
}, ptr.Float64(1)),
|
|
outString: `[ metric='Test' labels={host=foo} value=32.3 ]`,
|
|
},
|
|
{
|
|
desc: "2 EvalMatches",
|
|
inFrame: newMetaFrame([]classic.EvalMatch{
|
|
{Metric: "Test", Labels: data.Labels{"host": "foo"}, Value: ptr.Float64(32.3)},
|
|
{Metric: "Test", Labels: data.Labels{"host": "baz"}, Value: ptr.Float64(10)},
|
|
}, ptr.Float64(1)),
|
|
outString: `[ metric='Test' labels={host=foo} value=32.3 ], [ metric='Test' labels={host=baz} value=10 ]`,
|
|
},
|
|
{
|
|
desc: "3 EvalMatches",
|
|
inFrame: newMetaFrame([]classic.EvalMatch{
|
|
{Metric: "Test", Labels: data.Labels{"host": "foo"}, Value: ptr.Float64(32.3)},
|
|
{Metric: "Test", Labels: data.Labels{"host": "baz"}, Value: ptr.Float64(10)},
|
|
{Metric: "TestA", Labels: data.Labels{"host": "zip"}, Value: ptr.Float64(11)},
|
|
}, ptr.Float64(1)),
|
|
outString: `[ metric='Test' labels={host=foo} value=32.3 ], [ metric='Test' labels={host=baz} value=10 ], [ metric='TestA' labels={host=zip} value=11 ]`,
|
|
},
|
|
}
|
|
for _, tc := range cases {
|
|
t.Run(tc.desc, func(t *testing.T) {
|
|
require.Equal(t, tc.outString, extractEvalString(tc.inFrame))
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestExtractValues(t *testing.T) {
|
|
cases := []struct {
|
|
desc string
|
|
inFrame *data.Frame
|
|
values map[string]NumberValueCapture
|
|
}{{
|
|
desc: "No values in frame returns nil",
|
|
inFrame: newMetaFrame(nil, ptr.Float64(1)),
|
|
values: nil,
|
|
}, {
|
|
desc: "Classic condition frame returns nil",
|
|
inFrame: newMetaFrame([]classic.EvalMatch{
|
|
{Metric: "A", Labels: data.Labels{"host": "foo"}, Value: ptr.Float64(1)},
|
|
}, ptr.Float64(1)),
|
|
values: nil,
|
|
}, {
|
|
desc: "Nil value",
|
|
inFrame: newMetaFrame([]NumberValueCapture{
|
|
{Var: "A", Labels: data.Labels{"host": "foo"}, Value: nil},
|
|
}, ptr.Float64(1)),
|
|
values: map[string]NumberValueCapture{
|
|
"A": {Var: "A", Labels: data.Labels{"host": "foo"}, Value: nil},
|
|
},
|
|
}, {
|
|
desc: "1 value",
|
|
inFrame: newMetaFrame([]NumberValueCapture{
|
|
{Var: "A", Labels: data.Labels{"host": "foo"}, Value: ptr.Float64(1)},
|
|
}, ptr.Float64(1)),
|
|
values: map[string]NumberValueCapture{
|
|
"A": {Var: "A", Labels: data.Labels{"host": "foo"}, Value: ptr.Float64(1)},
|
|
},
|
|
}, {
|
|
desc: "2 values",
|
|
inFrame: newMetaFrame([]NumberValueCapture{
|
|
{Var: "A", Labels: data.Labels{"host": "foo"}, Value: ptr.Float64(1)},
|
|
{Var: "B", Labels: nil, Value: ptr.Float64(2)},
|
|
}, ptr.Float64(1)),
|
|
values: map[string]NumberValueCapture{
|
|
"A": {Var: "A", Labels: data.Labels{"host": "foo"}, Value: ptr.Float64(1)},
|
|
"B": {Var: "B", Value: ptr.Float64(2)},
|
|
},
|
|
}}
|
|
for _, tc := range cases {
|
|
t.Run(tc.desc, func(t *testing.T) {
|
|
require.Equal(t, tc.values, extractValues(tc.inFrame))
|
|
})
|
|
}
|
|
}
|
|
|
|
func newMetaFrame(custom interface{}, val *float64) *data.Frame {
|
|
return data.NewFrame("",
|
|
data.NewField("", nil, []*float64{val})).
|
|
SetMeta(&data.FrameMeta{
|
|
Custom: custom,
|
|
})
|
|
}
|