Skip to content

Commit 39dbb24

Browse files
committed
Add helper functions for linting to testutil
Signed-off-by: beorn7 <[email protected]>
1 parent 6433bcf commit 39dbb24

File tree

3 files changed

+120
-0
lines changed

3 files changed

+120
-0
lines changed

prometheus/testutil/lint.go

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
// Copyright 2020 The Prometheus Authors
2+
// Licensed under the Apache License, Version 2.0 (the "License");
3+
// you may not use this file except in compliance with the License.
4+
// You may obtain a copy of the License at
5+
//
6+
// http://www.apache.org/licenses/LICENSE-2.0
7+
//
8+
// Unless required by applicable law or agreed to in writing, software
9+
// distributed under the License is distributed on an "AS IS" BASIS,
10+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11+
// See the License for the specific language governing permissions and
12+
// limitations under the License.
13+
14+
package testutil
15+
16+
import (
17+
"fmt"
18+
19+
"github.com/prometheus/client_golang/prometheus"
20+
"github.com/prometheus/client_golang/prometheus/testutil/promlint"
21+
)
22+
23+
// CollectAndLint registers the provided Collector with a newly created
24+
// pedantic Registry. It then does the same as GatherAndLint, gathering the
25+
// metrics from the pedantic Registry.
26+
func CollectAndLint(c prometheus.Collector, metricNames ...string) ([]promlint.Problem, error) {
27+
reg := prometheus.NewPedanticRegistry()
28+
if err := reg.Register(c); err != nil {
29+
return nil, fmt.Errorf("registering collector failed: %s", err)
30+
}
31+
return GatherAndLint(reg, metricNames...)
32+
}
33+
34+
// GatherAndLint gathers all metrics from the provided Gatherer and checks them
35+
// with the linter in the promlint package. If any metricNames are provided,
36+
// only metrics with those names are checked.
37+
func GatherAndLint(g prometheus.Gatherer, metricNames ...string) ([]promlint.Problem, error) {
38+
got, err := g.Gather()
39+
if err != nil {
40+
return nil, fmt.Errorf("gathering metrics failed: %s", err)
41+
}
42+
if metricNames != nil {
43+
got = filterMetrics(got, metricNames)
44+
}
45+
return promlint.NewWithMetricFamilies(got).Lint()
46+
}

prometheus/testutil/lint_test.go

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
// Copyright 2020 The Prometheus Authors
2+
// Licensed under the Apache License, Version 2.0 (the "License");
3+
// you may not use this file except in compliance with the License.
4+
// You may obtain a copy of the License at
5+
//
6+
// http://www.apache.org/licenses/LICENSE-2.0
7+
//
8+
// Unless required by applicable law or agreed to in writing, software
9+
// distributed under the License is distributed on an "AS IS" BASIS,
10+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11+
// See the License for the specific language governing permissions and
12+
// limitations under the License.
13+
14+
package testutil
15+
16+
import (
17+
"testing"
18+
19+
"github.com/prometheus/client_golang/prometheus"
20+
)
21+
22+
func TestCollectAndLintGood(t *testing.T) {
23+
cnt := prometheus.NewCounterVec(
24+
prometheus.CounterOpts{
25+
Name: "some_total",
26+
Help: "A value that represents a counter.",
27+
ConstLabels: prometheus.Labels{
28+
"label1": "value1",
29+
},
30+
},
31+
[]string{"foo"},
32+
)
33+
cnt.WithLabelValues("bar")
34+
cnt.WithLabelValues("baz")
35+
36+
problems, err := CollectAndLint(cnt)
37+
if err != nil {
38+
t.Error("Unexpected error:", err)
39+
}
40+
if len(problems) > 0 {
41+
t.Error("Unexpected lint problems:", problems)
42+
}
43+
}
44+
45+
func TestCollectAndLintBad(t *testing.T) {
46+
cnt := prometheus.NewCounterVec(
47+
prometheus.CounterOpts{
48+
Name: "someThing_ms",
49+
Help: "A value that represents a counter.",
50+
ConstLabels: prometheus.Labels{
51+
"label1": "value1",
52+
},
53+
},
54+
[]string{"fooBar"},
55+
)
56+
cnt.WithLabelValues("bar")
57+
cnt.WithLabelValues("baz")
58+
59+
problems, err := CollectAndLint(cnt)
60+
if err != nil {
61+
t.Error("Unexpected error:", err)
62+
}
63+
if len(problems) < 5 {
64+
// The exact nature of the lint problems found is tested within
65+
// the promlint package itself. Here we only want to make sure
66+
// that the collector successfully hit the linter and got enough
67+
// problems flagged.
68+
t.Error("Not enough lint problems found.")
69+
}
70+
}

prometheus/testutil/testutil.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,10 @@
3131
// testing custom prometheus.Collector implementations and in particular whole
3232
// exporters, i.e. programs that retrieve telemetry data from a 3rd party source
3333
// and convert it into Prometheus metrics.
34+
//
35+
// In a similar pattern, CollectAndLint and GatherAndLint can be used to detect
36+
// metrics that have issues with their name, type, or metadata without being
37+
// necessarily invalid, e.g. a counter with a name missing the “_total” suffix.
3438
package testutil
3539

3640
import (

0 commit comments

Comments
 (0)