Skip to content

Commit

Permalink
Merge pull request prometheus#497 from prometheus/beorn7/testing
Browse files Browse the repository at this point in the history
Fix testutil metric comparison
  • Loading branch information
beorn7 committed Nov 13, 2018
2 parents abad2d1 + 86702ea commit ca9acd2
Show file tree
Hide file tree
Showing 2 changed files with 53 additions and 24 deletions.
55 changes: 31 additions & 24 deletions prometheus/testutil/testutil.go
Expand Up @@ -37,7 +37,6 @@ import (
"bytes"
"fmt"
"io"
"reflect"

"github.com/prometheus/common/expfmt"

Expand Down Expand Up @@ -125,49 +124,57 @@ func CollectAndCompare(c prometheus.Collector, expected io.Reader, metricNames .
// exposition format. If any metricNames are provided, only metrics with those
// names are compared.
func GatherAndCompare(g prometheus.Gatherer, expected io.Reader, metricNames ...string) error {
metrics, err := g.Gather()
got, err := g.Gather()
if err != nil {
return fmt.Errorf("gathering metrics failed: %s", err)
}
if metricNames != nil {
metrics = filterMetrics(metrics, metricNames)
got = filterMetrics(got, metricNames)
}
var tp expfmt.TextParser
expectedMetrics, err := tp.TextToMetricFamilies(expected)
wantRaw, err := tp.TextToMetricFamilies(expected)
if err != nil {
return fmt.Errorf("parsing expected metrics failed: %s", err)
}
want := internal.NormalizeMetricFamilies(wantRaw)

if !reflect.DeepEqual(metrics, internal.NormalizeMetricFamilies(expectedMetrics)) {
// Encode the gathered output to the readable text format for comparison.
var buf1 bytes.Buffer
enc := expfmt.NewEncoder(&buf1, expfmt.FmtText)
for _, mf := range metrics {
if err := enc.Encode(mf); err != nil {
return fmt.Errorf("encoding result failed: %s", err)
}
if len(got) != len(want) {
return notMatchingError(got, want)
}
for i := range got {
if got[i].String() != want[i].String() {
return notMatchingError(got, want)
}
// 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
}

// 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(`
return fmt.Errorf(`
metric output does not match expectation; want:
%s
got:
%s
`, buf2.String(), buf1.String())
}
return nil
`, wantBuf.String(), gotBuf.String())
}

func filterMetrics(metrics []*dto.MetricFamily, names []string) []*dto.MetricFamily {
Expand Down
22 changes: 22 additions & 0 deletions prometheus/testutil/testutil_test.go
Expand Up @@ -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) {
const metadata = `
# HELP some_total A value that represents a counter.
Expand Down

0 comments on commit ca9acd2

Please sign in to comment.