From 2d9a9cbc088f89848df84d6e5ea2db546b488c7a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gy=C3=B6rgy=20Krajcsovits?= Date: Tue, 24 Jan 2023 12:56:30 +0100 Subject: [PATCH] Fix storage/remote/codec ignoreing histogram reset hint MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: György Krajcsovits --- storage/remote/codec.go | 40 +++---- storage/remote/codec_test.go | 196 +++++++++++++++++++++++++++++++++++ 2 files changed, 218 insertions(+), 18 deletions(-) diff --git a/storage/remote/codec.go b/storage/remote/codec.go index 10f24efec..36bff2821 100644 --- a/storage/remote/codec.go +++ b/storage/remote/codec.go @@ -528,15 +528,16 @@ func exemplarProtoToExemplar(ep prompb.Exemplar) exemplar.Exemplar { // represents an integer histogram and not a float histogram. func HistogramProtoToHistogram(hp prompb.Histogram) *histogram.Histogram { return &histogram.Histogram{ - Schema: hp.Schema, - ZeroThreshold: hp.ZeroThreshold, - ZeroCount: hp.GetZeroCountInt(), - Count: hp.GetCountInt(), - Sum: hp.Sum, - PositiveSpans: spansProtoToSpans(hp.GetPositiveSpans()), - PositiveBuckets: hp.GetPositiveDeltas(), - NegativeSpans: spansProtoToSpans(hp.GetNegativeSpans()), - NegativeBuckets: hp.GetNegativeDeltas(), + CounterResetHint: histogram.CounterResetHint(hp.ResetHint), + Schema: hp.Schema, + ZeroThreshold: hp.ZeroThreshold, + ZeroCount: hp.GetZeroCountInt(), + Count: hp.GetCountInt(), + Sum: hp.Sum, + PositiveSpans: spansProtoToSpans(hp.GetPositiveSpans()), + PositiveBuckets: hp.GetPositiveDeltas(), + NegativeSpans: spansProtoToSpans(hp.GetNegativeSpans()), + NegativeBuckets: hp.GetNegativeDeltas(), } } @@ -545,15 +546,16 @@ func HistogramProtoToHistogram(hp prompb.Histogram) *histogram.Histogram { // the proto message represents an float histogram and not a integer histogram. func HistogramProtoToFloatHistogram(hp prompb.Histogram) *histogram.FloatHistogram { return &histogram.FloatHistogram{ - Schema: hp.Schema, - ZeroThreshold: hp.ZeroThreshold, - ZeroCount: hp.GetZeroCountFloat(), - Count: hp.GetCountFloat(), - Sum: hp.Sum, - PositiveSpans: spansProtoToSpans(hp.GetPositiveSpans()), - PositiveBuckets: hp.GetPositiveCounts(), - NegativeSpans: spansProtoToSpans(hp.GetNegativeSpans()), - NegativeBuckets: hp.GetNegativeCounts(), + CounterResetHint: histogram.CounterResetHint(hp.ResetHint), + Schema: hp.Schema, + ZeroThreshold: hp.ZeroThreshold, + ZeroCount: hp.GetZeroCountFloat(), + Count: hp.GetCountFloat(), + Sum: hp.Sum, + PositiveSpans: spansProtoToSpans(hp.GetPositiveSpans()), + PositiveBuckets: hp.GetPositiveCounts(), + NegativeSpans: spansProtoToSpans(hp.GetNegativeSpans()), + NegativeBuckets: hp.GetNegativeCounts(), } } @@ -577,6 +579,7 @@ func HistogramToHistogramProto(timestamp int64, h *histogram.Histogram) prompb.H NegativeDeltas: h.NegativeBuckets, PositiveSpans: spansToSpansProto(h.PositiveSpans), PositiveDeltas: h.PositiveBuckets, + ResetHint: prompb.Histogram_ResetHint(h.CounterResetHint), Timestamp: timestamp, } } @@ -592,6 +595,7 @@ func FloatHistogramToHistogramProto(timestamp int64, fh *histogram.FloatHistogra NegativeCounts: fh.NegativeBuckets, PositiveSpans: spansToSpansProto(fh.PositiveSpans), PositiveCounts: fh.PositiveBuckets, + ResetHint: prompb.Histogram_ResetHint(fh.CounterResetHint), Timestamp: timestamp, } } diff --git a/storage/remote/codec_test.go b/storage/remote/codec_test.go index bf3954c4d..f19259b9f 100644 --- a/storage/remote/codec_test.go +++ b/storage/remote/codec_test.go @@ -371,6 +371,202 @@ func TestNilHistogramProto(t *testing.T) { HistogramProtoToFloatHistogram(prompb.Histogram{}) } +func exampleHistogram() histogram.Histogram { + return histogram.Histogram{ + CounterResetHint: histogram.GaugeType, + Schema: 0, + Count: 19, + Sum: 2.7, + PositiveSpans: []histogram.Span{ + {Offset: 0, Length: 4}, + {Offset: 0, Length: 0}, + {Offset: 0, Length: 3}, + }, + PositiveBuckets: []int64{1, 2, -2, 1, -1, 0, 0}, + NegativeSpans: []histogram.Span{ + {Offset: 0, Length: 5}, + {Offset: 1, Length: 0}, + {Offset: 0, Length: 1}, + }, + NegativeBuckets: []int64{1, 2, -2, 1, -1, 0}, + } +} + +func exampleHistogramProto() prompb.Histogram { + return prompb.Histogram{ + Count: &prompb.Histogram_CountInt{CountInt: 19}, + Sum: 2.7, + Schema: 0, + ZeroThreshold: 0, + ZeroCount: &prompb.Histogram_ZeroCountInt{ZeroCountInt: 0}, + NegativeSpans: []*prompb.BucketSpan{ + { + Offset: 0, + Length: 5, + }, + { + Offset: 1, + Length: 0, + }, + { + Offset: 0, + Length: 1, + }, + }, + NegativeDeltas: []int64{1, 2, -2, 1, -1, 0}, + PositiveSpans: []*prompb.BucketSpan{ + { + Offset: 0, + Length: 4, + }, + { + Offset: 0, + Length: 0, + }, + { + Offset: 0, + Length: 3, + }, + }, + PositiveDeltas: []int64{1, 2, -2, 1, -1, 0, 0}, + ResetHint: prompb.Histogram_GAUGE, + Timestamp: 1337, + } +} + +func TestHistogramToProtoConvert(t *testing.T) { + tests := []struct { + input histogram.CounterResetHint + expected prompb.Histogram_ResetHint + }{ + { + input: histogram.UnknownCounterReset, + expected: prompb.Histogram_UNKNOWN, + }, + { + input: histogram.CounterReset, + expected: prompb.Histogram_YES, + }, + { + input: histogram.NotCounterReset, + expected: prompb.Histogram_NO, + }, + { + input: histogram.GaugeType, + expected: prompb.Histogram_GAUGE, + }, + } + + for _, test := range tests { + h := exampleHistogram() + h.CounterResetHint = test.input + p := exampleHistogramProto() + p.ResetHint = test.expected + + require.Equal(t, p, HistogramToHistogramProto(1337, &h)) + + require.Equal(t, h, *HistogramProtoToHistogram(p)) + } +} + +func exampleFloatHistogram() histogram.FloatHistogram { + return histogram.FloatHistogram{ + CounterResetHint: histogram.GaugeType, + Schema: 0, + Count: 19, + Sum: 2.7, + PositiveSpans: []histogram.Span{ + {Offset: 0, Length: 4}, + {Offset: 0, Length: 0}, + {Offset: 0, Length: 3}, + }, + PositiveBuckets: []float64{1, 2, -2, 1, -1, 0, 0}, + NegativeSpans: []histogram.Span{ + {Offset: 0, Length: 5}, + {Offset: 1, Length: 0}, + {Offset: 0, Length: 1}, + }, + NegativeBuckets: []float64{1, 2, -2, 1, -1, 0}, + } +} + +func exampleFloatHistogramProto() prompb.Histogram { + return prompb.Histogram{ + Count: &prompb.Histogram_CountFloat{CountFloat: 19}, + Sum: 2.7, + Schema: 0, + ZeroThreshold: 0, + ZeroCount: &prompb.Histogram_ZeroCountFloat{ZeroCountFloat: 0}, + NegativeSpans: []*prompb.BucketSpan{ + { + Offset: 0, + Length: 5, + }, + { + Offset: 1, + Length: 0, + }, + { + Offset: 0, + Length: 1, + }, + }, + NegativeCounts: []float64{1, 2, -2, 1, -1, 0}, + PositiveSpans: []*prompb.BucketSpan{ + { + Offset: 0, + Length: 4, + }, + { + Offset: 0, + Length: 0, + }, + { + Offset: 0, + Length: 3, + }, + }, + PositiveCounts: []float64{1, 2, -2, 1, -1, 0, 0}, + ResetHint: prompb.Histogram_GAUGE, + Timestamp: 1337, + } +} + +func TestFloatHistogramToProtoConvert(t *testing.T) { + tests := []struct { + input histogram.CounterResetHint + expected prompb.Histogram_ResetHint + }{ + { + input: histogram.UnknownCounterReset, + expected: prompb.Histogram_UNKNOWN, + }, + { + input: histogram.CounterReset, + expected: prompb.Histogram_YES, + }, + { + input: histogram.NotCounterReset, + expected: prompb.Histogram_NO, + }, + { + input: histogram.GaugeType, + expected: prompb.Histogram_GAUGE, + }, + } + + for _, test := range tests { + h := exampleFloatHistogram() + h.CounterResetHint = test.input + p := exampleFloatHistogramProto() + p.ResetHint = test.expected + + require.Equal(t, p, FloatHistogramToHistogramProto(1337, &h)) + + require.Equal(t, h, *HistogramProtoToFloatHistogram(p)) + } +} + func TestStreamResponse(t *testing.T) { lbs1 := labelsToLabelsProto(labels.FromStrings("instance", "localhost1", "job", "demo1"), nil) lbs2 := labelsToLabelsProto(labels.FromStrings("instance", "localhost2", "job", "demo2"), nil)