2023-02-16 10:16:36 -06:00
|
|
|
package template
|
2021-10-04 13:04:37 -05:00
|
|
|
|
|
|
|
import (
|
2021-12-28 03:26:18 -06:00
|
|
|
"context"
|
2021-10-04 13:04:37 -05:00
|
|
|
"errors"
|
|
|
|
"net/url"
|
|
|
|
"testing"
|
|
|
|
|
|
|
|
"github.com/grafana/grafana-plugin-sdk-go/data"
|
|
|
|
"github.com/stretchr/testify/assert"
|
|
|
|
"github.com/stretchr/testify/require"
|
2022-12-12 09:12:30 -06:00
|
|
|
|
|
|
|
"github.com/grafana/grafana/pkg/services/ngalert/eval"
|
2023-03-06 04:23:15 -06:00
|
|
|
"github.com/grafana/grafana/pkg/util"
|
2021-10-04 13:04:37 -05:00
|
|
|
)
|
|
|
|
|
2023-02-16 11:04:15 -06:00
|
|
|
func TestLabelsString(t *testing.T) {
|
|
|
|
tests := []struct {
|
|
|
|
name string
|
|
|
|
labels Labels
|
|
|
|
expected string
|
|
|
|
}{{
|
|
|
|
name: "single label has no commas",
|
|
|
|
labels: Labels{"foo": "bar"},
|
|
|
|
expected: "foo=bar",
|
|
|
|
}, {
|
|
|
|
name: "labels are sorted in increasing order",
|
|
|
|
labels: Labels{"foo": "bar", "bar": "baz"},
|
|
|
|
expected: "bar=baz, foo=bar",
|
|
|
|
}}
|
|
|
|
|
|
|
|
for _, test := range tests {
|
|
|
|
t.Run(test.name, func(t *testing.T) {
|
|
|
|
assert.Equal(t, test.expected, test.labels.String())
|
|
|
|
})
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-02-16 10:16:36 -06:00
|
|
|
func TestValueString(t *testing.T) {
|
|
|
|
tests := []struct {
|
2021-10-04 13:04:37 -05:00
|
|
|
name string
|
2023-02-16 10:16:36 -06:00
|
|
|
value Value
|
2021-10-04 13:04:37 -05:00
|
|
|
expected string
|
|
|
|
}{{
|
|
|
|
name: "0 is returned as integer value",
|
2023-02-16 10:16:36 -06:00
|
|
|
value: Value{Value: 0},
|
2021-10-04 13:04:37 -05:00
|
|
|
expected: "0",
|
|
|
|
}, {
|
|
|
|
name: "1.0 is returned as integer value",
|
2023-02-16 10:16:36 -06:00
|
|
|
value: Value{Value: 1.0},
|
2021-10-04 13:04:37 -05:00
|
|
|
expected: "1",
|
|
|
|
}, {
|
|
|
|
name: "1.1 is returned as decimal value",
|
2023-02-16 10:16:36 -06:00
|
|
|
value: Value{Value: 1.1},
|
|
|
|
expected: "1.1",
|
|
|
|
}, {
|
|
|
|
name: "1.1 is returned as decimal value, no labels",
|
|
|
|
value: Value{Labels: map[string]string{"foo": "bar"}, Value: 1.1},
|
2021-10-04 13:04:37 -05:00
|
|
|
expected: "1.1",
|
|
|
|
}}
|
|
|
|
|
2023-02-16 10:16:36 -06:00
|
|
|
for _, test := range tests {
|
|
|
|
t.Run(test.name, func(t *testing.T) {
|
|
|
|
assert.Equal(t, test.expected, test.value.String())
|
2021-10-04 13:04:37 -05:00
|
|
|
})
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-03-08 06:25:02 -06:00
|
|
|
func TestExpandError(t *testing.T) {
|
|
|
|
err := ExpandError{Tmpl: "{{", Err: errors.New("unexpected {{")}
|
|
|
|
assert.Equal(t, "failed to expand template '{{': unexpected {{", err.Error())
|
|
|
|
}
|
|
|
|
|
2021-10-04 13:04:37 -05:00
|
|
|
func TestExpandTemplate(t *testing.T) {
|
|
|
|
pathPrefix := "/path/prefix"
|
|
|
|
externalURL, err := url.Parse("http://localhost" + pathPrefix)
|
|
|
|
assert.NoError(t, err)
|
|
|
|
|
|
|
|
cases := []struct {
|
|
|
|
name string
|
|
|
|
text string
|
|
|
|
alertInstance eval.Result
|
|
|
|
labels data.Labels
|
|
|
|
expected string
|
|
|
|
expectedError error
|
|
|
|
}{{
|
|
|
|
name: "labels are expanded into $labels",
|
|
|
|
text: "{{ $labels.instance }} is down",
|
|
|
|
labels: data.Labels{"instance": "foo"},
|
|
|
|
expected: "foo is down",
|
|
|
|
}, {
|
2022-12-12 09:12:30 -06:00
|
|
|
name: "missing label in $labels returns [no value]",
|
2021-11-29 12:26:51 -06:00
|
|
|
text: "{{ $labels.instance }} is down",
|
|
|
|
labels: data.Labels{},
|
2022-12-12 09:12:30 -06:00
|
|
|
expected: "[no value] is down",
|
2021-10-04 13:04:37 -05:00
|
|
|
}, {
|
|
|
|
name: "values are expanded into $values",
|
|
|
|
text: "{{ $values.A.Labels.instance }} has value {{ $values.A }}",
|
|
|
|
alertInstance: eval.Result{
|
|
|
|
Values: map[string]eval.NumberValueCapture{
|
|
|
|
"A": {
|
|
|
|
Var: "A",
|
|
|
|
Labels: data.Labels{"instance": "foo"},
|
2023-03-06 04:23:15 -06:00
|
|
|
Value: util.Pointer(1.0),
|
2021-10-04 13:04:37 -05:00
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
expected: "foo has value 1",
|
|
|
|
}, {
|
|
|
|
name: "values can be passed to template functions such as printf",
|
|
|
|
text: "{{ $values.A.Labels.instance }} has value {{ $values.A.Value | printf \"%.1f\" }}",
|
|
|
|
alertInstance: eval.Result{
|
|
|
|
Values: map[string]eval.NumberValueCapture{
|
|
|
|
"A": {
|
|
|
|
Var: "A",
|
|
|
|
Labels: data.Labels{"instance": "foo"},
|
2023-03-06 04:23:15 -06:00
|
|
|
Value: util.Pointer(1.1),
|
2021-10-04 13:04:37 -05:00
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
expected: "foo has value 1.1",
|
|
|
|
}, {
|
2022-12-12 09:12:30 -06:00
|
|
|
name: "missing label in $values returns [no value]",
|
2021-10-04 13:04:37 -05:00
|
|
|
text: "{{ $values.A.Labels.instance }} has value {{ $values.A }}",
|
|
|
|
alertInstance: eval.Result{
|
|
|
|
Values: map[string]eval.NumberValueCapture{
|
|
|
|
"A": {
|
|
|
|
Var: "A",
|
|
|
|
Labels: data.Labels{},
|
2023-03-06 04:23:15 -06:00
|
|
|
Value: util.Pointer(1.0),
|
2021-10-04 13:04:37 -05:00
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
2022-12-12 09:12:30 -06:00
|
|
|
expected: "[no value] has value 1",
|
2021-10-04 13:04:37 -05:00
|
|
|
}, {
|
|
|
|
name: "missing value in $values is returned as NaN",
|
|
|
|
text: "{{ $values.A.Labels.instance }} has value {{ $values.A }}",
|
|
|
|
alertInstance: eval.Result{
|
|
|
|
Values: map[string]eval.NumberValueCapture{
|
|
|
|
"A": {
|
|
|
|
Var: "A",
|
|
|
|
Labels: data.Labels{"instance": "foo"},
|
|
|
|
Value: nil,
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
expected: "foo has value NaN",
|
|
|
|
}, {
|
|
|
|
name: "assert value string is expanded into $value",
|
|
|
|
text: "{{ $value }}",
|
|
|
|
alertInstance: eval.Result{
|
|
|
|
EvaluationString: "[ var='A' labels={instance=foo} value=10 ]",
|
|
|
|
},
|
|
|
|
expected: "[ var='A' labels={instance=foo} value=10 ]",
|
|
|
|
}, {
|
|
|
|
name: "float64 is humanized correctly",
|
|
|
|
text: "{{ humanize $value }}",
|
|
|
|
alertInstance: eval.Result{
|
|
|
|
EvaluationString: "1234567.0",
|
|
|
|
},
|
|
|
|
expected: "1.235M",
|
|
|
|
}, {
|
|
|
|
name: "int is humanized correctly",
|
|
|
|
text: "{{ humanize $value }}",
|
|
|
|
alertInstance: eval.Result{
|
|
|
|
EvaluationString: "1234567",
|
|
|
|
},
|
|
|
|
expected: "1.235M",
|
|
|
|
}, {
|
|
|
|
name: "humanize string with error",
|
|
|
|
text: `{{ humanize $value }}`,
|
|
|
|
alertInstance: eval.Result{
|
|
|
|
EvaluationString: "invalid",
|
|
|
|
},
|
2023-03-08 06:25:02 -06:00
|
|
|
expectedError: errors.New(`failed to expand template '{{- $labels := .Labels -}}{{- $values := .Values -}}{{- $value := .Value -}}{{ humanize $value }}': error executing template __alert_test: template: __alert_test:1:79: executing "__alert_test" at <humanize $value>: error calling humanize: strconv.ParseFloat: parsing "invalid": invalid syntax`),
|
2021-10-04 13:04:37 -05:00
|
|
|
}, {
|
|
|
|
name: "humanize1024 float64",
|
|
|
|
text: "{{ range $key, $val := $values }}{{ humanize1024 .Value }}:{{ end }}",
|
|
|
|
alertInstance: eval.Result{
|
|
|
|
Values: map[string]eval.NumberValueCapture{
|
|
|
|
"A": {
|
|
|
|
Var: "A",
|
|
|
|
Labels: data.Labels{},
|
2023-03-06 04:23:15 -06:00
|
|
|
Value: util.Pointer(0.0),
|
2021-10-04 13:04:37 -05:00
|
|
|
},
|
|
|
|
"B": {
|
|
|
|
Var: "B",
|
|
|
|
Labels: data.Labels{},
|
2023-03-06 04:23:15 -06:00
|
|
|
Value: util.Pointer(1.0),
|
2021-10-04 13:04:37 -05:00
|
|
|
},
|
|
|
|
"C": {
|
|
|
|
Var: "C",
|
|
|
|
Labels: data.Labels{},
|
2023-03-06 04:23:15 -06:00
|
|
|
Value: util.Pointer(1048576.0),
|
2021-10-04 13:04:37 -05:00
|
|
|
},
|
|
|
|
"D": {
|
|
|
|
Var: "D",
|
|
|
|
Labels: data.Labels{},
|
2023-03-06 04:23:15 -06:00
|
|
|
Value: util.Pointer(.12),
|
2021-10-04 13:04:37 -05:00
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
expected: "0:1:1Mi:0.12:",
|
|
|
|
}, {
|
|
|
|
name: "humanize1024 string with error",
|
|
|
|
text: "{{ humanize1024 $value }}",
|
|
|
|
alertInstance: eval.Result{
|
|
|
|
EvaluationString: "invalid",
|
|
|
|
},
|
2023-03-08 06:25:02 -06:00
|
|
|
expectedError: errors.New(`failed to expand template '{{- $labels := .Labels -}}{{- $values := .Values -}}{{- $value := .Value -}}{{ humanize1024 $value }}': error executing template __alert_test: template: __alert_test:1:79: executing "__alert_test" at <humanize1024 $value>: error calling humanize1024: strconv.ParseFloat: parsing "invalid": invalid syntax`),
|
2021-10-04 13:04:37 -05:00
|
|
|
}, {
|
|
|
|
name: "humanizeDuration - seconds - float64",
|
|
|
|
text: "{{ range $key, $val := $values }}{{ humanizeDuration .Value }}:{{ end }}",
|
|
|
|
alertInstance: eval.Result{
|
|
|
|
Values: map[string]eval.NumberValueCapture{
|
|
|
|
"A": {
|
|
|
|
Var: "A",
|
|
|
|
Labels: data.Labels{},
|
2023-03-06 04:23:15 -06:00
|
|
|
Value: util.Pointer(0.0),
|
2021-10-04 13:04:37 -05:00
|
|
|
},
|
|
|
|
"B": {
|
|
|
|
Var: "B",
|
|
|
|
Labels: data.Labels{},
|
2023-03-06 04:23:15 -06:00
|
|
|
Value: util.Pointer(1.0),
|
2021-10-04 13:04:37 -05:00
|
|
|
},
|
|
|
|
"C": {
|
|
|
|
Var: "C",
|
|
|
|
Labels: data.Labels{},
|
2023-03-06 04:23:15 -06:00
|
|
|
Value: util.Pointer(60.0),
|
2021-10-04 13:04:37 -05:00
|
|
|
},
|
|
|
|
"D": {
|
|
|
|
Var: "D",
|
|
|
|
Labels: data.Labels{},
|
2023-03-06 04:23:15 -06:00
|
|
|
Value: util.Pointer(3600.0),
|
2021-10-04 13:04:37 -05:00
|
|
|
},
|
|
|
|
"E": {
|
|
|
|
Var: "E",
|
|
|
|
Labels: data.Labels{},
|
2023-03-06 04:23:15 -06:00
|
|
|
Value: util.Pointer(86400.0),
|
2021-10-04 13:04:37 -05:00
|
|
|
},
|
|
|
|
"F": {
|
|
|
|
Var: "F",
|
|
|
|
Labels: data.Labels{},
|
2023-03-06 04:23:15 -06:00
|
|
|
Value: util.Pointer(86400.0 + 3600.0),
|
2021-10-04 13:04:37 -05:00
|
|
|
},
|
|
|
|
"G": {
|
|
|
|
Var: "G",
|
|
|
|
Labels: data.Labels{},
|
2023-03-06 04:23:15 -06:00
|
|
|
Value: util.Pointer(-(86400*2 + 3600*3 + 60*4 + 5.0)),
|
2021-10-04 13:04:37 -05:00
|
|
|
},
|
|
|
|
"H": {
|
|
|
|
Var: "H",
|
|
|
|
Labels: data.Labels{},
|
2023-03-06 04:23:15 -06:00
|
|
|
Value: util.Pointer(899.99),
|
2021-10-04 13:04:37 -05:00
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
expected: "0s:1s:1m 0s:1h 0m 0s:1d 0h 0m 0s:1d 1h 0m 0s:-2d 3h 4m 5s:14m 59s:",
|
|
|
|
}, {
|
|
|
|
name: "humanizeDuration - string",
|
|
|
|
text: "{{ humanizeDuration $value }}",
|
|
|
|
alertInstance: eval.Result{
|
|
|
|
EvaluationString: "86400",
|
|
|
|
},
|
|
|
|
expected: "1d 0h 0m 0s",
|
|
|
|
}, {
|
|
|
|
name: "humanizeDuration - subsecond and fractional seconds - float64",
|
|
|
|
text: "{{ range $key, $val := $values }}{{ humanizeDuration .Value }}:{{ end }}",
|
|
|
|
alertInstance: eval.Result{
|
|
|
|
Values: map[string]eval.NumberValueCapture{
|
|
|
|
"A": {
|
|
|
|
Var: "A",
|
|
|
|
Labels: data.Labels{},
|
2023-03-06 04:23:15 -06:00
|
|
|
Value: util.Pointer(.1),
|
2021-10-04 13:04:37 -05:00
|
|
|
},
|
|
|
|
"B": {
|
|
|
|
Var: "B",
|
|
|
|
Labels: data.Labels{},
|
2023-03-06 04:23:15 -06:00
|
|
|
Value: util.Pointer(.0001),
|
2021-10-04 13:04:37 -05:00
|
|
|
},
|
|
|
|
"C": {
|
|
|
|
Var: "C",
|
|
|
|
Labels: data.Labels{},
|
2023-03-06 04:23:15 -06:00
|
|
|
Value: util.Pointer(.12345),
|
2021-10-04 13:04:37 -05:00
|
|
|
},
|
|
|
|
"D": {
|
|
|
|
Var: "D",
|
|
|
|
Labels: data.Labels{},
|
2023-03-06 04:23:15 -06:00
|
|
|
Value: util.Pointer(60.1),
|
2021-10-04 13:04:37 -05:00
|
|
|
},
|
|
|
|
"E": {
|
|
|
|
Var: "E",
|
|
|
|
Labels: data.Labels{},
|
2023-03-06 04:23:15 -06:00
|
|
|
Value: util.Pointer(60.5),
|
2021-10-04 13:04:37 -05:00
|
|
|
},
|
|
|
|
"F": {
|
|
|
|
Var: "F",
|
|
|
|
Labels: data.Labels{},
|
2023-03-06 04:23:15 -06:00
|
|
|
Value: util.Pointer(1.2345),
|
2021-10-04 13:04:37 -05:00
|
|
|
},
|
|
|
|
"G": {
|
|
|
|
Var: "G",
|
|
|
|
Labels: data.Labels{},
|
2023-03-06 04:23:15 -06:00
|
|
|
Value: util.Pointer(12.345),
|
2021-10-04 13:04:37 -05:00
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
expected: "100ms:100us:123.5ms:1m 0s:1m 0s:1.234s:12.35s:",
|
|
|
|
}, {
|
|
|
|
name: "humanizeDuration - subsecond - string",
|
|
|
|
text: "{{ humanizeDuration $value }}",
|
|
|
|
alertInstance: eval.Result{
|
|
|
|
EvaluationString: ".0001",
|
|
|
|
},
|
|
|
|
expected: "100us",
|
|
|
|
}, {
|
|
|
|
name: "humanizeDuration - fractional seconds - string",
|
|
|
|
text: "{{ humanizeDuration $value }}",
|
|
|
|
alertInstance: eval.Result{
|
|
|
|
EvaluationString: "1.2345",
|
|
|
|
},
|
|
|
|
expected: "1.234s",
|
|
|
|
}, {
|
|
|
|
name: "humanizeDuration - string with error",
|
|
|
|
text: `{{ humanizeDuration $value }}`,
|
|
|
|
alertInstance: eval.Result{
|
|
|
|
EvaluationString: "invalid",
|
|
|
|
},
|
2023-03-08 06:25:02 -06:00
|
|
|
expectedError: errors.New(`failed to expand template '{{- $labels := .Labels -}}{{- $values := .Values -}}{{- $value := .Value -}}{{ humanizeDuration $value }}': error executing template __alert_test: template: __alert_test:1:79: executing "__alert_test" at <humanizeDuration $value>: error calling humanizeDuration: strconv.ParseFloat: parsing "invalid": invalid syntax`),
|
2021-10-04 13:04:37 -05:00
|
|
|
}, {
|
|
|
|
name: "humanizePercentage - float64",
|
|
|
|
text: "{{ -0.22222 | humanizePercentage }}:{{ 0.0 | humanizePercentage }}:{{ 0.1234567 | humanizePercentage }}:{{ 1.23456 | humanizePercentage }}",
|
|
|
|
expected: "-22.22%:0%:12.35%:123.5%",
|
|
|
|
}, {
|
|
|
|
name: "humanizePercentage - string",
|
|
|
|
text: `{{ "-0.22222" | humanizePercentage }}:{{ "0.0" | humanizePercentage }}:{{ "0.1234567" | humanizePercentage }}:{{ "1.23456" | humanizePercentage }}`,
|
|
|
|
expected: "-22.22%:0%:12.35%:123.5%",
|
|
|
|
}, {
|
|
|
|
name: "humanizePercentage - string with error",
|
|
|
|
text: `{{ "invalid" | humanizePercentage }}`,
|
2023-03-08 06:25:02 -06:00
|
|
|
expectedError: errors.New(`failed to expand template '{{- $labels := .Labels -}}{{- $values := .Values -}}{{- $value := .Value -}}{{ "invalid" | humanizePercentage }}': error executing template __alert_test: template: __alert_test:1:91: executing "__alert_test" at <humanizePercentage>: error calling humanizePercentage: strconv.ParseFloat: parsing "invalid": invalid syntax`),
|
2021-10-04 13:04:37 -05:00
|
|
|
}, {
|
|
|
|
name: "humanizeTimestamp - float64",
|
|
|
|
text: "{{ 1435065584.128 | humanizeTimestamp }}",
|
|
|
|
expected: "2015-06-23 13:19:44.128 +0000 UTC",
|
|
|
|
}, {
|
|
|
|
name: "humanizeTimestamp - string",
|
|
|
|
text: `{{ "1435065584.128" | humanizeTimestamp }}`,
|
|
|
|
expected: "2015-06-23 13:19:44.128 +0000 UTC",
|
|
|
|
}, {
|
|
|
|
name: "title",
|
|
|
|
text: `{{ "aa bb CC" | title }}`,
|
|
|
|
expected: "Aa Bb CC",
|
|
|
|
}, {
|
|
|
|
name: "toUpper",
|
|
|
|
text: `{{ "aa bb CC" | toUpper }}`,
|
|
|
|
expected: "AA BB CC",
|
|
|
|
}, {
|
|
|
|
name: "toLower",
|
|
|
|
text: `{{ "aA bB CC" | toLower }}`,
|
|
|
|
expected: "aa bb cc",
|
|
|
|
}, {
|
|
|
|
name: "match",
|
|
|
|
text: `{{ match "a+" "aa" }} {{ match "a+" "b" }}`,
|
|
|
|
expected: "true false",
|
|
|
|
}, {
|
|
|
|
name: "regex replacement",
|
|
|
|
text: "{{ reReplaceAll \"(a)b\" \"x$1\" \"ab\" }}",
|
|
|
|
expected: "xa",
|
|
|
|
}, {
|
|
|
|
name: "pass multiple arguments to templates",
|
|
|
|
text: `{{define "x"}}{{.arg0}} {{.arg1}}{{end}}{{template "x" (args 1 "2")}}`,
|
|
|
|
expected: "1 2",
|
|
|
|
}, {
|
|
|
|
name: "pathPrefix",
|
|
|
|
text: "{{ pathPrefix }}",
|
|
|
|
expected: pathPrefix,
|
|
|
|
}, {
|
|
|
|
name: "externalURL",
|
|
|
|
text: "{{ externalURL }}",
|
|
|
|
expected: externalURL.String(),
|
|
|
|
}, {
|
|
|
|
name: "check that query, first and value don't error or panic",
|
|
|
|
text: "{{ query \"1.5\" | first | value }}",
|
|
|
|
expected: "",
|
|
|
|
}, {
|
|
|
|
name: "check that label doesn't error or panic",
|
|
|
|
text: "{{ query \"metric{instance='a'}\" | first | label \"instance\" }}",
|
|
|
|
expected: "",
|
|
|
|
}, {
|
2021-11-10 07:36:03 -06:00
|
|
|
name: "graphLink",
|
|
|
|
text: `{{ graphLink "{\"expr\": \"up\", \"datasource\": \"gdev-prometheus\"}" }}`,
|
2022-12-14 12:57:53 -06:00
|
|
|
expected: `/explore?left={"datasource":"gdev-prometheus","queries":[{"datasource":"gdev-prometheus","expr":"up","instant":false,"range":true,"refId":"A"}],"range":{"from":"now-1h","to":"now"}}`,
|
2021-11-10 07:36:03 -06:00
|
|
|
}, {
|
|
|
|
name: "graphLink should escape both the expression and the datasource",
|
|
|
|
text: `{{ graphLink "{\"expr\": \"process_open_fds > 0\", \"datasource\": \"gdev prometheus\"}" }}`,
|
2022-12-14 12:57:53 -06:00
|
|
|
expected: `/explore?left={"datasource":"gdev+prometheus","queries":[{"datasource":"gdev+prometheus","expr":"process_open_fds+%3E+0","instant":false,"range":true,"refId":"A"}],"range":{"from":"now-1h","to":"now"}}`,
|
2021-11-10 07:36:03 -06:00
|
|
|
}, {
|
|
|
|
name: "check that graphLink returns an empty string when the query is not formatted correctly",
|
2021-10-04 13:04:37 -05:00
|
|
|
text: "{{ graphLink \"up\" }}",
|
|
|
|
expected: "",
|
|
|
|
}, {
|
2021-11-10 07:36:03 -06:00
|
|
|
name: "tableLink",
|
|
|
|
text: `{{ tableLink "{\"expr\": \"up\", \"datasource\": \"gdev-prometheus\"}" }}`,
|
2022-12-14 12:57:53 -06:00
|
|
|
expected: `/explore?left={"datasource":"gdev-prometheus","queries":[{"datasource":"gdev-prometheus","expr":"up","instant":true,"range":false,"refId":"A"}],"range":{"from":"now-1h","to":"now"}}`,
|
2021-11-10 07:36:03 -06:00
|
|
|
}, {
|
|
|
|
name: "tableLink should escape both the expression and the datasource",
|
|
|
|
text: `{{ tableLink "{\"expr\": \"process_open_fds > 0\", \"datasource\": \"gdev prometheus\"}" }}`,
|
2022-12-14 12:57:53 -06:00
|
|
|
expected: `/explore?left={"datasource":"gdev+prometheus","queries":[{"datasource":"gdev+prometheus","expr":"process_open_fds+%3E+0","instant":true,"range":false,"refId":"A"}],"range":{"from":"now-1h","to":"now"}}`,
|
2021-11-10 07:36:03 -06:00
|
|
|
}, {
|
|
|
|
name: "check that tableLink returns an empty string when the query is not formatted correctly",
|
2021-10-04 13:04:37 -05:00
|
|
|
text: "{{ tableLink \"up\" }}",
|
|
|
|
expected: "",
|
|
|
|
}, {
|
|
|
|
name: "check that sortByLabel doesn't error or panic",
|
|
|
|
text: "{{ query \"metric{__value__='a'}\" | sortByLabel }}",
|
|
|
|
expected: "",
|
|
|
|
}, {
|
|
|
|
name: "check that strvalue returns an empty string (for now)",
|
|
|
|
text: "{{ $values.A | strvalue }}",
|
|
|
|
alertInstance: eval.Result{
|
|
|
|
Values: map[string]eval.NumberValueCapture{
|
|
|
|
"A": {
|
|
|
|
Var: "A",
|
|
|
|
Labels: data.Labels{"__value__": "foo"},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
expected: "",
|
|
|
|
}, {
|
|
|
|
name: "check that safeHtml doesn't error or panic",
|
|
|
|
text: "{{ \"<b>\" | safeHtml }}",
|
|
|
|
expected: "<b>",
|
|
|
|
},
|
|
|
|
}
|
|
|
|
|
|
|
|
for _, c := range cases {
|
|
|
|
t.Run(c.name, func(t *testing.T) {
|
2023-02-20 03:24:11 -06:00
|
|
|
v, err := Expand(context.Background(), "test", c.text, NewData(c.labels, c.alertInstance), externalURL, c.alertInstance.EvaluatedAt)
|
2021-10-04 13:04:37 -05:00
|
|
|
if c.expectedError != nil {
|
|
|
|
require.NotNil(t, err)
|
|
|
|
require.EqualError(t, c.expectedError, err.Error())
|
|
|
|
} else {
|
|
|
|
require.Nil(t, c.expectedError)
|
|
|
|
}
|
|
|
|
require.Equal(t, c.expected, v)
|
|
|
|
})
|
|
|
|
}
|
|
|
|
}
|