Merge pull request #497 from prometheus/beorn7/testing
Fix testutil metric comparison
This commit is contained in:
commit
ca9acd2391
|
@ -37,7 +37,6 @@ import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"reflect"
|
|
||||||
|
|
||||||
"github.com/prometheus/common/expfmt"
|
"github.com/prometheus/common/expfmt"
|
||||||
|
|
||||||
|
@ -125,39 +124,49 @@ func CollectAndCompare(c prometheus.Collector, expected io.Reader, metricNames .
|
||||||
// exposition format. If any metricNames are provided, only metrics with those
|
// exposition format. If any metricNames are provided, only metrics with those
|
||||||
// names are compared.
|
// names are compared.
|
||||||
func GatherAndCompare(g prometheus.Gatherer, expected io.Reader, metricNames ...string) error {
|
func GatherAndCompare(g prometheus.Gatherer, expected io.Reader, metricNames ...string) error {
|
||||||
metrics, err := g.Gather()
|
got, err := g.Gather()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("gathering metrics failed: %s", err)
|
return fmt.Errorf("gathering metrics failed: %s", err)
|
||||||
}
|
}
|
||||||
if metricNames != nil {
|
if metricNames != nil {
|
||||||
metrics = filterMetrics(metrics, metricNames)
|
got = filterMetrics(got, metricNames)
|
||||||
}
|
}
|
||||||
var tp expfmt.TextParser
|
var tp expfmt.TextParser
|
||||||
expectedMetrics, err := tp.TextToMetricFamilies(expected)
|
wantRaw, err := tp.TextToMetricFamilies(expected)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("parsing expected metrics failed: %s", err)
|
return fmt.Errorf("parsing expected metrics failed: %s", err)
|
||||||
}
|
}
|
||||||
|
want := internal.NormalizeMetricFamilies(wantRaw)
|
||||||
|
|
||||||
if !reflect.DeepEqual(metrics, internal.NormalizeMetricFamilies(expectedMetrics)) {
|
if len(got) != len(want) {
|
||||||
// Encode the gathered output to the readable text format for comparison.
|
return notMatchingError(got, want)
|
||||||
var buf1 bytes.Buffer
|
}
|
||||||
enc := expfmt.NewEncoder(&buf1, expfmt.FmtText)
|
for i := range got {
|
||||||
for _, mf := range metrics {
|
if got[i].String() != want[i].String() {
|
||||||
if err := enc.Encode(mf); err != nil {
|
return notMatchingError(got, want)
|
||||||
return fmt.Errorf("encoding result failed: %s", err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// Encode normalized expected metrics again to generate them in the same ordering
|
|
||||||
// the registry does to spot differences more easily.
|
|
||||||
var buf2 bytes.Buffer
|
|
||||||
enc = expfmt.NewEncoder(&buf2, expfmt.FmtText)
|
|
||||||
for _, mf := range internal.NormalizeMetricFamilies(expectedMetrics) {
|
|
||||||
if err := enc.Encode(mf); err != nil {
|
|
||||||
return fmt.Errorf("encoding result failed: %s", err)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
return fmt.Errorf(`
|
// notMatchingError encodes both provided slices of metric families into the
|
||||||
|
// text format and creates a readable error message from the result.
|
||||||
|
func notMatchingError(got, want []*dto.MetricFamily) error {
|
||||||
|
var gotBuf, wantBuf bytes.Buffer
|
||||||
|
enc := expfmt.NewEncoder(&gotBuf, expfmt.FmtText)
|
||||||
|
for _, mf := range got {
|
||||||
|
if err := enc.Encode(mf); err != nil {
|
||||||
|
return fmt.Errorf("encoding gathered metrics failed: %s", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
enc = expfmt.NewEncoder(&wantBuf, expfmt.FmtText)
|
||||||
|
for _, mf := range want {
|
||||||
|
if err := enc.Encode(mf); err != nil {
|
||||||
|
return fmt.Errorf("encoding expected metrics failed: %s", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return fmt.Errorf(`
|
||||||
metric output does not match expectation; want:
|
metric output does not match expectation; want:
|
||||||
|
|
||||||
%s
|
%s
|
||||||
|
@ -165,9 +174,7 @@ metric output does not match expectation; want:
|
||||||
got:
|
got:
|
||||||
|
|
||||||
%s
|
%s
|
||||||
`, buf2.String(), buf1.String())
|
`, wantBuf.String(), gotBuf.String())
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func filterMetrics(metrics []*dto.MetricFamily, names []string) []*dto.MetricFamily {
|
func filterMetrics(metrics []*dto.MetricFamily, names []string) []*dto.MetricFamily {
|
||||||
|
|
|
@ -143,6 +143,28 @@ func TestCollectAndCompare(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestCollectAndCompareNoLabel(t *testing.T) {
|
||||||
|
const metadata = `
|
||||||
|
# HELP some_total A value that represents a counter.
|
||||||
|
# TYPE some_total counter
|
||||||
|
`
|
||||||
|
|
||||||
|
c := prometheus.NewCounter(prometheus.CounterOpts{
|
||||||
|
Name: "some_total",
|
||||||
|
Help: "A value that represents a counter.",
|
||||||
|
})
|
||||||
|
c.Inc()
|
||||||
|
|
||||||
|
expected := `
|
||||||
|
|
||||||
|
some_total 1
|
||||||
|
`
|
||||||
|
|
||||||
|
if err := CollectAndCompare(c, strings.NewReader(metadata+expected), "some_total"); err != nil {
|
||||||
|
t.Errorf("unexpected collecting result:\n%s", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func TestNoMetricFilter(t *testing.T) {
|
func TestNoMetricFilter(t *testing.T) {
|
||||||
const metadata = `
|
const metadata = `
|
||||||
# HELP some_total A value that represents a counter.
|
# HELP some_total A value that represents a counter.
|
||||||
|
|
Loading…
Reference in New Issue