From 5b1605053c454de239dc8723481763c81a1cf5d8 Mon Sep 17 00:00:00 2001 From: beorn7 Date: Tue, 13 Nov 2018 16:16:43 +0100 Subject: [PATCH] Fix metric comparison for empty labels reflect.DeepEqual is not suitable for zero occurrences of repeated proto messages. This changes the comparison to act on the string representation of proto messages. Signed-off-by: beorn7 --- prometheus/testutil/testutil.go | 54 ++++++++++++++++++--------------- 1 file changed, 30 insertions(+), 24 deletions(-) diff --git a/prometheus/testutil/testutil.go b/prometheus/testutil/testutil.go index d148af9b8..b1c382c98 100644 --- a/prometheus/testutil/testutil.go +++ b/prometheus/testutil/testutil.go @@ -37,7 +37,6 @@ import ( "bytes" "fmt" "io" - "reflect" "github.com/prometheus/common/expfmt" @@ -125,39 +124,48 @@ 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) { + } + 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 @@ -165,9 +173,7 @@ metric output does not match expectation; want: got: %s -`, buf2.String(), buf1.String()) - } - return nil +`, wantBuf.String(), gotBuf.String()) } func filterMetrics(metrics []*dto.MetricFamily, names []string) []*dto.MetricFamily {