summaryrefslogtreecommitdiffstats
path: root/src/go/collectors/go.d.plugin/pkg/prometheus/selector/parse_test.go
blob: ba764e0391e3aa28e3343a3487dc93b73f17ce12 (plain)
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/go.d.plugin/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))}
}