From 80d3f0b5b36c891016370423516e353b1a5f0a55 Mon Sep 17 00:00:00 2001 From: Billy Keyes Date: Mon, 20 Nov 2023 04:57:30 -0500 Subject: [PATCH] Normalize empty help values in CollectAndCompare (#1378) Due to an inconsistency in the text protocol between encoding and decoding, it was not possible to use the testutil.CollectAndCompare function to test metrics with empty help values. To fix this, normalize empty help values from the expected/want side of the test so that they compare correctly with empty values on the actual/got side of the test. Signed-off-by: Billy Keyes --- prometheus/testutil/testutil.go | 15 +++++++++++++++ prometheus/testutil/testutil_test.go | 20 ++++++++++++++++++++ 2 files changed, 35 insertions(+) diff --git a/prometheus/testutil/testutil.go b/prometheus/testutil/testutil.go index 82d4a54..269f564 100644 --- a/prometheus/testutil/testutil.go +++ b/prometheus/testutil/testutil.go @@ -47,6 +47,7 @@ import ( "github.com/davecgh/go-spew/spew" dto "github.com/prometheus/client_model/go" "github.com/prometheus/common/expfmt" + "google.golang.org/protobuf/proto" "github.com/prometheus/client_golang/prometheus" "github.com/prometheus/client_golang/prometheus/internal" @@ -230,6 +231,20 @@ func convertReaderToMetricFamily(reader io.Reader) ([]*dto.MetricFamily, error) return nil, fmt.Errorf("converting reader to metric families failed: %w", err) } + // The text protocol handles empty help fields inconsistently. When + // encoding, any non-nil value, include the empty string, produces a + // "# HELP" line. But when decoding, the help field is only set to a + // non-nil value if the "# HELP" line contains a non-empty value. + // + // Because metrics in a registry always have non-nil help fields, populate + // any nil help fields in the parsed metrics with the empty string so that + // when we compare text encodings, the results are consistent. + for _, metric := range notNormalized { + if metric.Help == nil { + metric.Help = proto.String("") + } + } + return internal.NormalizeMetricFamilies(notNormalized), nil } diff --git a/prometheus/testutil/testutil_test.go b/prometheus/testutil/testutil_test.go index ab2fdb0..f2e1cba 100644 --- a/prometheus/testutil/testutil_test.go +++ b/prometheus/testutil/testutil_test.go @@ -168,6 +168,26 @@ func TestCollectAndCompareNoLabel(t *testing.T) { } } +func TestCollectAndCompareNoHelp(t *testing.T) { + const metadata = ` + # TYPE some_total counter + ` + + c := prometheus.NewCounter(prometheus.CounterOpts{ + Name: "some_total", + }) + 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 TestCollectAndCompareHistogram(t *testing.T) { inputs := []struct { name string