Skip to content

Commit 6c4e0ef

Browse files
committed
Add tests for sparse histogram
Signed-off-by: beorn7 <[email protected]>
1 parent 31318b7 commit 6c4e0ef

File tree

2 files changed

+93
-3
lines changed

2 files changed

+93
-3
lines changed

prometheus/histogram.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -238,11 +238,11 @@ var DefBuckets = []float64{.005, .01, .025, .05, .1, .25, .5, 1, 2.5, 5, 10}
238238

239239
// DefSparseBucketsZeroThreshold is the default value for
240240
// SparseBucketsZeroThreshold in the HistogramOpts.
241+
//
242+
// The value is 2^-128 (or 0.5*2^-127 in the actual IEEE 754 representation),
243+
// which is a bucket boundary at all possible resolutions.
241244
const DefSparseBucketsZeroThreshold = 2.938735877055719e-39
242245

243-
// This is 2^-128 (or 0.5*2^-127 in the actual IEEE 754 representation), which
244-
// is a bucket boundary at all possible resolutions.
245-
246246
var errBucketLabelNotAllowed = fmt.Errorf(
247247
"%q is not allowed as label name in histograms", bucketLabel,
248248
)

prometheus/histogram_test.go

Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -456,3 +456,93 @@ func TestHistogramExemplar(t *testing.T) {
456456
}
457457
}
458458
}
459+
460+
func TestSparseHistogram(t *testing.T) {
461+
462+
scenarios := []struct {
463+
name string
464+
observations []float64
465+
factor float64
466+
zeroThreshold float64
467+
want string // String representation of protobuf.
468+
}{
469+
{
470+
name: "no sparse buckets",
471+
observations: []float64{1, 2, 3},
472+
factor: 1,
473+
want: `sample_count:3 sample_sum:6 bucket:<cumulative_count:0 upper_bound:0.005 > bucket:<cumulative_count:0 upper_bound:0.01 > bucket:<cumulative_count:0 upper_bound:0.025 > bucket:<cumulative_count:0 upper_bound:0.05 > bucket:<cumulative_count:0 upper_bound:0.1 > bucket:<cumulative_count:0 upper_bound:0.25 > bucket:<cumulative_count:0 upper_bound:0.5 > bucket:<cumulative_count:1 upper_bound:1 > bucket:<cumulative_count:2 upper_bound:2.5 > bucket:<cumulative_count:3 upper_bound:5 > bucket:<cumulative_count:3 upper_bound:10 > sb_schema:0 sb_zero_threshold:0 `, // Has conventional buckets because there are no sparse buckets.
474+
},
475+
{
476+
name: "factor 1.1 results in schema 3",
477+
observations: []float64{0, 1, 2, 3},
478+
factor: 1.1,
479+
want: `sample_count:4 sample_sum:6 sb_schema:3 sb_zero_threshold:2.938735877055719e-39 sb_zero_count:1 sb_positive:<span:<offset:0 length:1 > span:<offset:7 length:1 > span:<offset:4 length:1 > delta:1 delta:0 delta:0 > `,
480+
},
481+
{
482+
name: "factor 1.2 results in schema 2",
483+
observations: []float64{0, 1, 1.2, 1.4, 1.8, 2},
484+
factor: 1.2,
485+
want: `sample_count:6 sample_sum:7.4 sb_schema:2 sb_zero_threshold:2.938735877055719e-39 sb_zero_count:1 sb_positive:<span:<offset:0 length:5 > delta:1 delta:-1 delta:2 delta:-2 delta:2 > `,
486+
},
487+
{
488+
name: "negative buckets",
489+
observations: []float64{0, -1, -1.2, -1.4, -1.8, -2},
490+
factor: 1.2,
491+
want: `sample_count:6 sample_sum:-7.4 sb_schema:2 sb_zero_threshold:2.938735877055719e-39 sb_zero_count:1 sb_negative:<span:<offset:0 length:5 > delta:1 delta:-1 delta:2 delta:-2 delta:2 > `,
492+
},
493+
{
494+
name: "negative and positive buckets",
495+
observations: []float64{0, -1, -1.2, -1.4, -1.8, -2, 1, 1.2, 1.4, 1.8, 2},
496+
factor: 1.2,
497+
want: `sample_count:11 sample_sum:0 sb_schema:2 sb_zero_threshold:2.938735877055719e-39 sb_zero_count:1 sb_negative:<span:<offset:0 length:5 > delta:1 delta:-1 delta:2 delta:-2 delta:2 > sb_positive:<span:<offset:0 length:5 > delta:1 delta:-1 delta:2 delta:-2 delta:2 > `,
498+
},
499+
{
500+
name: "wide zero bucket",
501+
observations: []float64{0, -1, -1.2, -1.4, -1.8, -2, 1, 1.2, 1.4, 1.8, 2},
502+
factor: 1.2,
503+
zeroThreshold: 1.4,
504+
want: `sample_count:11 sample_sum:0 sb_schema:2 sb_zero_threshold:1.4 sb_zero_count:7 sb_negative:<span:<offset:4 length:1 > delta:2 > sb_positive:<span:<offset:4 length:1 > delta:2 > `,
505+
},
506+
{
507+
name: "NaN observation",
508+
observations: []float64{0, 1, 1.2, 1.4, 1.8, 2, math.NaN()},
509+
factor: 1.2,
510+
want: `sample_count:7 sample_sum:nan sb_schema:2 sb_zero_threshold:2.938735877055719e-39 sb_zero_count:1 sb_positive:<span:<offset:0 length:5 > delta:1 delta:-1 delta:2 delta:-2 delta:2 > `,
511+
},
512+
{
513+
name: "+Inf observation",
514+
observations: []float64{0, 1, 1.2, 1.4, 1.8, 2, math.Inf(+1)},
515+
factor: 1.2,
516+
want: `sample_count:7 sample_sum:inf sb_schema:2 sb_zero_threshold:2.938735877055719e-39 sb_zero_count:1 sb_positive:<span:<offset:0 length:5 > span:<offset:2147483642 length:1 > delta:1 delta:-1 delta:2 delta:-2 delta:2 delta:-1 > `,
517+
},
518+
{
519+
name: "-Inf observation",
520+
observations: []float64{0, 1, 1.2, 1.4, 1.8, 2, math.Inf(-1)},
521+
factor: 1.2,
522+
want: `sample_count:7 sample_sum:-inf sb_schema:2 sb_zero_threshold:2.938735877055719e-39 sb_zero_count:1 sb_negative:<span:<offset:2147483647 length:1 > delta:1 > sb_positive:<span:<offset:0 length:5 > delta:1 delta:-1 delta:2 delta:-2 delta:2 > `,
523+
},
524+
}
525+
526+
for _, s := range scenarios {
527+
t.Run(s.name, func(t *testing.T) {
528+
his := NewHistogram(HistogramOpts{
529+
Name: "name",
530+
Help: "help",
531+
SparseBucketsFactor: s.factor,
532+
SparseBucketsZeroThreshold: s.zeroThreshold,
533+
})
534+
for _, o := range s.observations {
535+
his.Observe(o)
536+
}
537+
m := &dto.Metric{}
538+
if err := his.Write(m); err != nil {
539+
t.Fatal("unexpected error writing metric", err)
540+
}
541+
got := m.Histogram.String()
542+
if s.want != got {
543+
t.Errorf("want histogram %q, got %q", s.want, got)
544+
}
545+
})
546+
}
547+
548+
}

0 commit comments

Comments
 (0)