From 8976cca20f47fbf4f2e569c543b623b26bb42fe3 Mon Sep 17 00:00:00 2001 From: Arve Knudsen Date: Mon, 25 Aug 2025 09:35:03 +0200 Subject: [PATCH] expfmt: Add NewTextParser function Add expfmt.NewTextParser function that allows providing name validation scheme. Signed-off-by: Arve Knudsen --- expfmt/decode.go | 2 +- expfmt/fuzz.go | 8 ++++++-- expfmt/text_parse.go | 5 +++++ expfmt/text_parse_test.go | 21 +++++++++++++++++++-- 4 files changed, 31 insertions(+), 5 deletions(-) diff --git a/expfmt/decode.go b/expfmt/decode.go index c4a701c50..98d278c13 100644 --- a/expfmt/decode.go +++ b/expfmt/decode.go @@ -151,7 +151,7 @@ type textDecoder struct { func (d *textDecoder) Decode(v *dto.MetricFamily) error { if d.err == nil { // Read all metrics in one shot. - p := TextParser{scheme: d.s} + p := NewTextParser(d.s) d.fams, d.err = p.TextToMetricFamilies(d.r) // If we don't get an error, store io.EOF for the end. if d.err == nil { diff --git a/expfmt/fuzz.go b/expfmt/fuzz.go index dfac962a4..ef9004640 100644 --- a/expfmt/fuzz.go +++ b/expfmt/fuzz.go @@ -17,7 +17,11 @@ package expfmt -import "bytes" +import ( + "bytes" + + "github.com/prometheus/common/model" +) // Fuzz text metric parser with with github.com/dvyukov/go-fuzz: // @@ -26,7 +30,7 @@ import "bytes" // // Further input samples should go in the folder fuzz/corpus. func Fuzz(in []byte) int { - parser := TextParser{} + parser := NewTextParser(model.UTF8Validation) _, err := parser.TextToMetricFamilies(bytes.NewReader(in)) if err != nil { diff --git a/expfmt/text_parse.go b/expfmt/text_parse.go index 4799f8358..26bd1c511 100644 --- a/expfmt/text_parse.go +++ b/expfmt/text_parse.go @@ -83,6 +83,11 @@ type TextParser struct { scheme model.ValidationScheme } +// NewTextParser returns a new TextParser with the provided nameValidationScheme. +func NewTextParser(nameValidationScheme model.ValidationScheme) TextParser { + return TextParser{scheme: nameValidationScheme} +} + // TextToMetricFamilies reads 'in' as the simple and flat text-based exchange // format and creates MetricFamily proto messages. It returns the MetricFamily // proto messages in a map where the metric names are the keys, along with any diff --git a/expfmt/text_parse_test.go b/expfmt/text_parse_test.go index 49fcfe778..5b848c4a1 100644 --- a/expfmt/text_parse_test.go +++ b/expfmt/text_parse_test.go @@ -25,6 +25,23 @@ import ( "github.com/prometheus/common/model" ) +func TestNewTextParser(t *testing.T) { + p := NewTextParser(model.UTF8Validation) + if p.scheme != model.UTF8Validation { + t.Errorf("expected NewTextParser to return a TextParser with scheme %s - got %s", model.UTF8Validation, p.scheme) + } + + p = NewTextParser(model.LegacyValidation) + if p.scheme != model.LegacyValidation { + t.Errorf("expected NewTextParser to return a TextParser with scheme %s - got %s", model.LegacyValidation, p.scheme) + } + + p = NewTextParser(model.UnsetValidation) + if p.scheme != model.UnsetValidation { + t.Errorf("expected NewTextParser to return a TextParser with scheme %s - got %s", model.UnsetValidation, p.scheme) + } +} + func testTextParse(t testing.TB) { scenarios := []struct { in string @@ -1001,7 +1018,7 @@ func BenchmarkParseError(b *testing.B) { func TestTextParserStartOfLine(t *testing.T) { t.Run("EOF", func(t *testing.T) { - p := TextParser{} + p := NewTextParser(model.UTF8Validation) in := strings.NewReader("") p.reset(in) fn := p.startOfLine() @@ -1014,7 +1031,7 @@ func TestTextParserStartOfLine(t *testing.T) { }) t.Run("OtherError", func(t *testing.T) { - p := TextParser{} + p := NewTextParser(model.UTF8Validation) in := &errReader{err: errors.New("unexpected error")} p.reset(in) fn := p.startOfLine()