Skip to content

Commit 61b386b

Browse files
committed
Fix delimited proto not escaped correctly
Signed-off-by: Piotr <17101802+thampiotr@users.noreply.github.com>
1 parent c79a891 commit 61b386b

2 files changed

Lines changed: 53 additions & 60 deletions

File tree

expfmt/encode.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -153,7 +153,7 @@ func NewEncoder(w io.Writer, format Format, options ...EncoderOption) Encoder {
153153
case TypeProtoDelim:
154154
return encoderCloser{
155155
encode: func(v *dto.MetricFamily) error {
156-
_, err := protodelim.MarshalTo(w, v)
156+
_, err := protodelim.MarshalTo(w, model.EscapeMetricFamily(v, escapingScheme))
157157
return err
158158
},
159159
close: func() error { return nil },

expfmt/encode_test.go

Lines changed: 52 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ import (
1818
"net/http"
1919
"testing"
2020

21+
"github.com/stretchr/testify/require"
2122
"google.golang.org/protobuf/proto"
2223

2324
"github.com/prometheus/common/model"
@@ -309,86 +310,78 @@ foo_metric 1.234
309310
}
310311

311312
func TestEscapedEncode(t *testing.T) {
312-
var buff bytes.Buffer
313-
delimEncoder := NewEncoder(&buff, FmtProtoDelim+"; escaping=underscores")
314-
metric := &dto.MetricFamily{
315-
Name: proto.String("foo.metric"),
316-
Type: dto.MetricType_UNTYPED.Enum(),
317-
Metric: []*dto.Metric{
318-
{
319-
Untyped: &dto.Untyped{
320-
Value: proto.Float64(1.234),
321-
},
322-
},
323-
{
324-
Label: []*dto.LabelPair{
325-
{
326-
Name: proto.String("dotted.label.name"),
327-
Value: proto.String("my.label.value"),
313+
var (
314+
metric = &dto.MetricFamily{
315+
Name: proto.String("foo.metric"),
316+
Type: dto.MetricType_UNTYPED.Enum(),
317+
Metric: []*dto.Metric{
318+
{
319+
Untyped: &dto.Untyped{
320+
Value: proto.Float64(1.234),
328321
},
329322
},
330-
Untyped: &dto.Untyped{
331-
Value: proto.Float64(8),
323+
{
324+
Label: []*dto.LabelPair{
325+
{
326+
Name: proto.String("dotted.label.name"),
327+
Value: proto.String("my.label.value"),
328+
},
329+
},
330+
Untyped: &dto.Untyped{
331+
Value: proto.Float64(8),
332+
},
332333
},
333334
},
334-
},
335-
}
335+
}
336+
buff bytes.Buffer
337+
)
336338

337-
err := delimEncoder.Encode(metric)
338-
if err != nil {
339-
t.Errorf("unexpected error during encode: %s", err.Error())
339+
verifyCorrectlyEscaped := func(t *testing.T, out string, format Format) {
340+
require.NotContainsf(t, out, `"foo.metric"`, "format incorrectly escaped: %s", format)
341+
require.Containsf(t, out, `foo_metric`, "format incorrectly escaped: %s", format)
342+
require.NotContainsf(t, out, `"dotted.label.name"`, "format incorrectly escaped: %s", format)
343+
require.Containsf(t, out, `dotted_label_name`, "format incorrectly escaped: %s", format)
344+
require.Containsf(t, out, `my.label.value`, "format incorrectly escaped: %s", format)
340345
}
341346

347+
format := FmtProtoDelim + "; escaping=underscores"
348+
delimEncoder := NewEncoder(&buff, format)
349+
err := delimEncoder.Encode(metric)
350+
require.NoError(t, err)
342351
out := buff.Bytes()
343-
if len(out) == 0 {
344-
t.Errorf("expected the output bytes buffer to be non-empty")
345-
}
352+
require.NotEmptyf(t, out, "expected the output bytes buffer to be non-empty")
353+
verifyCorrectlyEscaped(t, string(out), format)
346354

347355
buff.Reset()
348-
349-
compactEncoder := NewEncoder(&buff, FmtProtoCompact)
356+
format = FmtProtoCompact
357+
compactEncoder := NewEncoder(&buff, format)
350358
err = compactEncoder.Encode(metric)
351-
if err != nil {
352-
t.Errorf("unexpected error during encode: %s", err.Error())
353-
}
354-
359+
require.NoError(t, err)
360+
verifyCorrectlyEscaped(t, string(out), format)
355361
out = buff.Bytes()
356-
if len(out) == 0 {
357-
t.Errorf("expected the output bytes buffer to be non-empty")
358-
}
362+
require.NotEmptyf(t, out, "expected the output bytes buffer to be non-empty")
363+
verifyCorrectlyEscaped(t, string(out), format)
359364

360365
buff.Reset()
361-
362-
protoTextEncoder := NewEncoder(&buff, FmtProtoText)
366+
format = FmtProtoText
367+
protoTextEncoder := NewEncoder(&buff, format)
363368
err = protoTextEncoder.Encode(metric)
364-
if err != nil {
365-
t.Errorf("unexpected error during encode: %s", err.Error())
366-
}
367-
369+
require.NoError(t, err)
368370
out = buff.Bytes()
369-
if len(out) == 0 {
370-
t.Errorf("expected the output bytes buffer to be non-empty")
371-
}
371+
require.NotEmptyf(t, out, "expected the output bytes buffer to be non-empty")
372+
verifyCorrectlyEscaped(t, string(out), format)
372373

373374
buff.Reset()
374-
375-
textEncoder := NewEncoder(&buff, FmtText)
375+
format = FmtText
376+
textEncoder := NewEncoder(&buff, format)
376377
err = textEncoder.Encode(metric)
377-
if err != nil {
378-
t.Errorf("unexpected error during encode: %s", err.Error())
379-
}
380-
378+
require.NoError(t, err)
381379
out = buff.Bytes()
382-
if len(out) == 0 {
383-
t.Errorf("expected the output bytes buffer to be non-empty")
384-
}
380+
require.NotEmptyf(t, out, "expected the output bytes buffer to be non-empty")
381+
verifyCorrectlyEscaped(t, string(out), format)
385382

386-
expected := `# TYPE foo_metric untyped
383+
require.Equal(t, `# TYPE foo_metric untyped
387384
foo_metric 1.234
388385
foo_metric{dotted_label_name="my.label.value"} 8
389-
`
390-
391-
if string(out) != expected {
392-
t.Errorf("expected TextEncoder to return %s, but got %s instead", expected, string(out))
393-
}
386+
`, string(out))
394387
}

0 commit comments

Comments
 (0)