Skip to content

Commit 46862a5

Browse files
committed
Avoid nil pointer derefence panic edge case, add tests, add comments
Signed-off-by: Arianna Vespri <[email protected]>
1 parent 7c897f9 commit 46862a5

File tree

3 files changed

+60
-38
lines changed

3 files changed

+60
-38
lines changed

expfmt/encode_test.go

Lines changed: 43 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -120,47 +120,47 @@ func TestEncode(t *testing.T) {
120120
metric *dto.MetricFamily
121121
format Format
122122
withUnit bool
123-
out string
123+
expOut string
124124
}{
125-
// // 1: Untyped ProtoDelim
126-
// {
127-
// metric: metric1,
128-
// format: FmtProtoDelim,
129-
// out: ,
130-
// },
131-
// // 2: Untyped FmtProtoCompact
132-
// {
133-
// metric: metric1,
134-
// format: FmtProtoCompact,
135-
// out: ,
136-
// },
137-
// // 3: Untyped FmtProtoText
138-
// {
139-
// metric: metric1,
140-
// format: FmtProtoText,
141-
// out: ,
142-
// },
125+
// 1: Untyped ProtoDelim
126+
{
127+
metric: metric1,
128+
format: FmtProtoDelim,
129+
// expOut: `\x1b\n\nfoo_metric\x18\x03\"\v*\t\tX9\xb4\xc8v\xbe\xf3?`, // does this look like the desired output?
130+
},
131+
// 2: Untyped FmtProtoCompact
132+
{
133+
metric: metric1,
134+
format: FmtProtoCompact,
135+
// expOut: `name:\"foo_metric\" type:UNTYPED metric:{untyped:{value:1.234}}\n`, // does this look like the desired output?
136+
},
137+
// 3: Untyped FmtProtoText
138+
{
139+
metric: metric1,
140+
format: FmtProtoText,
141+
// expOut: `name: \"foo_metric\"\ntype: UNTYPED\nmetric: {\n untyped: {\n value: 1.234\n }\n}\n\n`, // does this look like the desired output?
142+
},
143143
// 4: Untyped FmtText
144144
{
145145
metric: metric1,
146146
format: FmtText,
147-
out: `# TYPE foo_metric untyped
147+
expOut: `# TYPE foo_metric untyped
148148
foo_metric 1.234
149149
`,
150150
},
151151
// 5: Untyped FmtOpenMetrics_0_0_1
152152
{
153153
metric: metric1,
154154
format: FmtOpenMetrics_0_0_1,
155-
out: `# TYPE foo_metric unknown
155+
expOut: `# TYPE foo_metric unknown
156156
foo_metric 1.234
157157
`,
158158
},
159159
// 6: Untyped FmtOpenMetrics_1_0_0
160160
{
161161
metric: metric1,
162162
format: FmtOpenMetrics_1_0_0,
163-
out: `# TYPE foo_metric unknown
163+
expOut: `# TYPE foo_metric unknown
164164
foo_metric 1.234
165165
`,
166166
},
@@ -181,7 +181,7 @@ foo_metric 1.234
181181
},
182182
format: FmtOpenMetrics_0_0_1,
183183
withUnit: true,
184-
out: `# HELP foos_duration_seconds Duration of foos in seconds.
184+
expOut: `# HELP foos_duration_seconds Duration of foos in seconds.
185185
# TYPE foos_duration_seconds counter
186186
# UNIT foos_duration_seconds seconds
187187
foos_duration_seconds_total 420.0
@@ -202,7 +202,7 @@ foos_duration_seconds_total 420.0
202202
},
203203
},
204204
format: FmtOpenMetrics_1_0_0,
205-
out: `# HELP foos_duration_seconds Duration of foos in seconds.
205+
expOut: `# HELP foos_duration_seconds Duration of foos in seconds.
206206
# TYPE foos_duration_seconds counter
207207
foos_duration_seconds_total 420.0
208208
`,
@@ -213,24 +213,33 @@ foos_duration_seconds_total 420.0
213213
if scenario.withUnit {
214214
opts = append(opts, ToOpenMetricsWithUnit())
215215
}
216-
out := bytes.NewBuffer(make([]byte, 0, len(scenario.out)))
216+
out := bytes.NewBuffer(make([]byte, 0, len(scenario.expOut)))
217217
enc := NewEncoder(out, scenario.format, opts...)
218218
err := enc.Encode(scenario.metric)
219219
if err != nil {
220220
t.Errorf("%d. error: %s", i, err)
221221
continue
222222
}
223-
224-
if expected, got := len(scenario.out), len(out.Bytes()); expected != got {
225-
t.Errorf(
226-
"%d. expected %d bytes written, got %d",
227-
i, expected, got,
228-
)
223+
// N.B. For the first three cases, I'm maintaining the same checks as they were before, i. e. the expected output is
224+
// not declared ergo no comparison with the actual output is ever performed, expect for its length being bigger than zero.
225+
if i > 2 {
226+
if expected, got := len(scenario.expOut), len(out.Bytes()); expected != got {
227+
t.Errorf(
228+
"%d. expected %d bytes written, got %d",
229+
i, expected, got,
230+
)
231+
}
232+
if expected, got := scenario.expOut, out.String(); expected != got {
233+
t.Errorf(
234+
"%d. expected out=%q, got %q",
235+
i, expected, got,
236+
)
237+
}
229238
}
230-
if expected, got := scenario.out, out.String(); expected != got {
239+
if len(out.Bytes()) == 0 {
231240
t.Errorf(
232-
"%d. expected out=%q, got %q",
233-
i, expected, got,
241+
"%d. expected output not to be empty",
242+
i,
234243
)
235244
}
236245
}

expfmt/openmetrics_create.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ import (
2727
dto "github.com/prometheus/client_model/go"
2828
)
2929

30-
type ToOpenMetrics struct { // TODO: reunite the comment above with its right function!!
30+
type ToOpenMetrics struct {
3131
withUnit bool
3232
// withCreated bool can be added in the future.
3333
}
@@ -121,7 +121,7 @@ func MetricFamilyToOpenMetrics(out io.Writer, in *dto.MetricFamily, options ...T
121121
if metricType == dto.MetricType_COUNTER && strings.HasSuffix(shortName, "_total") {
122122
shortName = name[:len(name)-6]
123123
}
124-
if toOM.withUnit && !strings.HasSuffix(shortName, fmt.Sprintf("_%s", *in.Unit)) {
124+
if toOM.withUnit && in.Unit != nil && !strings.HasSuffix(shortName, fmt.Sprintf("_%s", *in.Unit)) {
125125
shortName = shortName + fmt.Sprintf("_%s", *in.Unit)
126126
}
127127

expfmt/openmetrics_create_test.go

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -439,7 +439,7 @@ foos_total 42.0
439439
# UNIT name_seconds seconds
440440
`,
441441
},
442-
// 10: Histogram plus unit.
442+
// 10: Histogram plus unit, but unit not opted in.
443443
{
444444
in: &dto.MetricFamily{
445445
Name: proto.String("request_duration_microseconds"),
@@ -488,7 +488,7 @@ request_duration_microseconds_sum 1.7560473e+06
488488
request_duration_microseconds_count 2693
489489
`,
490490
},
491-
// 11: No metric unit opted in no unit in name
491+
// 11: No metric, unit opted in, no unit in name.
492492
{
493493
in: &dto.MetricFamily{
494494
Name: proto.String("name_total"),
@@ -501,6 +501,19 @@ request_duration_microseconds_count 2693
501501
out: `# HELP name_seconds doc string
502502
# TYPE name_seconds counter
503503
# UNIT name_seconds seconds
504+
`,
505+
},
506+
// 12: No metric, unit opted in, BUT unit == nil.
507+
{
508+
in: &dto.MetricFamily{
509+
Name: proto.String("name_total"),
510+
Help: proto.String("doc string"),
511+
Type: dto.MetricType_COUNTER.Enum(),
512+
Metric: []*dto.Metric{},
513+
},
514+
withUnit: true,
515+
out: `# HELP name doc string
516+
# TYPE name counter
504517
`,
505518
},
506519
}

0 commit comments

Comments
 (0)