1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
|
// SPDX-License-Identifier: GPL-3.0-or-later
package selector
import (
"fmt"
"testing"
"github.com/netdata/netdata/go/plugins/plugin/go.d/pkg/matcher"
"github.com/prometheus/prometheus/model/labels"
"github.com/stretchr/testify/assert"
)
func TestParse(t *testing.T) {
tests := map[string]struct {
input string
expectedSr Selector
expectedErr bool
}{
"sp op: only metric name": {
input: "go_memstats_alloc_bytes !go_memstats_* *",
expectedSr: mustSPName("go_memstats_alloc_bytes !go_memstats_* *"),
},
"string op: metric name with labels": {
input: fmt.Sprintf(`go_memstats_*{label%s"value"}`, OpEqual),
expectedSr: andSelector{
lhs: mustSPName("go_memstats_*"),
rhs: mustString("label", "value"),
},
},
"neg string op: metric name with labels": {
input: fmt.Sprintf(`go_memstats_*{label%s"value"}`, OpNegEqual),
expectedSr: andSelector{
lhs: mustSPName("go_memstats_*"),
rhs: Not(mustString("label", "value")),
},
},
"regexp op: metric name with labels": {
input: fmt.Sprintf(`go_memstats_*{label%s"valu.+"}`, OpRegexp),
expectedSr: andSelector{
lhs: mustSPName("go_memstats_*"),
rhs: mustRegexp("label", "valu.+"),
},
},
"neg regexp op: metric name with labels": {
input: fmt.Sprintf(`go_memstats_*{label%s"valu.+"}`, OpNegRegexp),
expectedSr: andSelector{
lhs: mustSPName("go_memstats_*"),
rhs: Not(mustRegexp("label", "valu.+")),
},
},
"sp op: metric name with labels": {
input: fmt.Sprintf(`go_memstats_*{label%s"valu*"}`, OpSimplePatterns),
expectedSr: andSelector{
lhs: mustSPName("go_memstats_*"),
rhs: mustSP("label", "valu*"),
},
},
"neg sp op: metric name with labels": {
input: fmt.Sprintf(`go_memstats_*{label%s"valu*"}`, OpNegSimplePatterns),
expectedSr: andSelector{
lhs: mustSPName("go_memstats_*"),
rhs: Not(mustSP("label", "valu*")),
},
},
"metric name with several labels": {
input: fmt.Sprintf(`go_memstats_*{label1%s"value1",label2%s"value2"}`, OpEqual, OpEqual),
expectedSr: andSelector{
lhs: andSelector{
lhs: mustSPName("go_memstats_*"),
rhs: mustString("label1", "value1"),
},
rhs: mustString("label2", "value2"),
},
},
"only labels (unsugar)": {
input: fmt.Sprintf(`{__name__%s"go_memstats_*",label1%s"value1",label2%s"value2"}`,
OpSimplePatterns, OpEqual, OpEqual),
expectedSr: andSelector{
lhs: andSelector{
lhs: mustSPName("go_memstats_*"),
rhs: mustString("label1", "value1"),
},
rhs: mustString("label2", "value2"),
},
},
}
for name, test := range tests {
t.Run(name, func(t *testing.T) {
sr, err := Parse(test.input)
if test.expectedErr {
assert.Error(t, err)
} else {
assert.Equal(t, test.expectedSr, sr)
}
})
}
}
func mustSPName(pattern string) Selector {
return mustSP(labels.MetricName, pattern)
}
func mustString(name string, pattern string) Selector {
return labelSelector{name: name, m: matcher.Must(matcher.NewStringMatcher(pattern, true, true))}
}
func mustRegexp(name string, pattern string) Selector {
return labelSelector{name: name, m: matcher.Must(matcher.NewRegExpMatcher(pattern))}
}
func mustSP(name string, pattern string) Selector {
return labelSelector{name: name, m: matcher.Must(matcher.NewSimplePatternsMatcher(pattern))}
}
|