Attempt of generics.

Signed-off-by: bwplotka <bwplotka@gmail.com>
This commit is contained in:
bwplotka 2024-06-26 11:22:04 +01:00
parent c5faeb9511
commit 82518f669d
7 changed files with 192 additions and 92 deletions

View file

@ -73,6 +73,10 @@ func (h Histogram) IsFloatHistogram() bool {
return ok
}
func (h Histogram) T() int64 {
return h.Timestamp
}
// ToIntHistogram returns integer Prometheus histogram from the remote implementation
// of integer histogram. It's a caller responsibility to check if it's not a float histogram.
func (h Histogram) ToIntHistogram() *histogram.Histogram {

24
prompb/codec_test.go Normal file
View file

@ -0,0 +1,24 @@
// Copyright 2024 Prometheus Team
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package prompb
import (
"testing"
"github.com/prometheus/prometheus/prompb/rwcommon"
)
func TestHistogram(t *testing.T) {
rwcommon.TestHistogram(t, Histogram{}, FromIntHistogram, FromFloatHistogram)
}

View file

@ -59,6 +59,10 @@ func (h Histogram) IsFloatHistogram() bool {
return ok
}
func (h Histogram) T() int64 {
return h.Timestamp
}
// ToIntHistogram returns integer Prometheus histogram from the remote implementation
// of integer histogram. It's a caller responsibility to check if it's not a float histogram.
func (h Histogram) ToIntHistogram() *histogram.Histogram {

View file

@ -0,0 +1,24 @@
// Copyright 2024 Prometheus Team
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package writev2
import (
"testing"
"github.com/prometheus/prometheus/prompb/rwcommon"
)
func TestHistogram(t *testing.T) {
rwcommon.TestHistogram(t, Histogram{}, FromIntHistogram, FromFloatHistogram)
}

View file

@ -83,98 +83,6 @@ func TestFromMetadataType(t *testing.T) {
}
}
func TestToHistogram_Empty(t *testing.T) {
t.Run("v1", func(t *testing.T) {
require.NotNilf(t, prompb.Histogram{}.ToIntHistogram(), "")
require.NotNilf(t, prompb.Histogram{}.ToFloatHistogram(), "")
})
t.Run("v2", func(t *testing.T) {
require.NotNilf(t, writev2.Histogram{}.ToIntHistogram(), "")
require.NotNilf(t, writev2.Histogram{}.ToFloatHistogram(), "")
})
}
func testIntHistogram() histogram.Histogram {
return histogram.Histogram{
CounterResetHint: histogram.GaugeType,
Schema: 0,
Count: 19,
Sum: 2.7,
ZeroThreshold: 1e-128,
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 testFloatHistogram() histogram.FloatHistogram {
return histogram.FloatHistogram{
CounterResetHint: histogram.GaugeType,
Schema: 0,
Count: 19,
Sum: 2.7,
ZeroThreshold: 1e-128,
PositiveSpans: []histogram.Span{
{Offset: 0, Length: 4},
{Offset: 0, Length: 0},
{Offset: 0, Length: 3},
},
PositiveBuckets: []float64{1, 3, 1, 2, 1, 1, 1},
NegativeSpans: []histogram.Span{
{Offset: 0, Length: 5},
{Offset: 1, Length: 0},
{Offset: 0, Length: 1},
},
NegativeBuckets: []float64{1, 3, 1, 2, 1, 1},
}
}
func TestFromIntToFloatOrIntHistogram(t *testing.T) {
testIntHist := testIntHistogram()
testFloatHist := testFloatHistogram()
t.Run("v1", func(t *testing.T) {
h := prompb.FromIntHistogram(123, &testIntHist)
require.False(t, h.IsFloatHistogram())
require.Equal(t, int64(123), h.Timestamp)
require.Equal(t, &testIntHist, h.ToIntHistogram())
require.Equal(t, &testFloatHist, h.ToFloatHistogram())
})
t.Run("v2", func(t *testing.T) {
h := writev2.FromIntHistogram(123, &testIntHist)
require.False(t, h.IsFloatHistogram())
require.Equal(t, int64(123), h.Timestamp)
require.Equal(t, &testIntHist, h.ToIntHistogram())
require.Equal(t, &testFloatHist, h.ToFloatHistogram())
})
}
func TestFromFloatToFloatHistogram(t *testing.T) {
testFloatHist := testFloatHistogram()
t.Run("v1", func(t *testing.T) {
h := prompb.FromFloatHistogram(123, &testFloatHist)
require.True(t, h.IsFloatHistogram())
require.Equal(t, int64(123), h.Timestamp)
require.Equal(t, &testFloatHist, h.ToFloatHistogram())
})
t.Run("v2", func(t *testing.T) {
h := writev2.FromFloatHistogram(123, &testFloatHist)
require.True(t, h.IsFloatHistogram())
require.Equal(t, int64(123), h.Timestamp)
require.Equal(t, &testFloatHist, h.ToFloatHistogram())
})
}
func TestFromIntOrFloatHistogram_ResetHint(t *testing.T) {
for _, tc := range []struct {
input histogram.CounterResetHint

43
prompb/rwcommon/rw.go Normal file
View file

@ -0,0 +1,43 @@
// Copyright 2024 Prometheus Team
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package rwcommon
import (
"github.com/prometheus/prometheus/model/histogram"
)
// HistogramConvertable represent type that can be converted to model histogram.
type HistogramConvertable interface {
// ToIntHistogram returns integer Prometheus histogram from the remote implementation
// of integer histogram. It's a caller responsibility to check if it's not a float histogram.
ToIntHistogram() *histogram.Histogram
// ToFloatHistogram returns float Prometheus histogram from the remote implementation
// of float histogram. If the underlying implementation is an integer histogram, a
// conversion is performed.
ToFloatHistogram() *histogram.FloatHistogram
// IsFloatHistogram returns true if the histogram is float.
IsFloatHistogram() bool
// T returns timestamp.
// NOTE(bwplotka): Can't use GetTimestamp as we use gogo nullable and GetTimestamp is a pointer receiver.
T() int64
}
// FromIntHistogramFunc is a function that returns remote Histogram from the integer Histogram.
type FromIntHistogramFunc[T any] func(timestamp int64, h *histogram.Histogram) T
// FromFloatHistogramFunc is a function returns remote Histogram from the float Histogram.
type FromFloatHistogramFunc[T any] func(timestamp int64, h *histogram.FloatHistogram) T

View file

@ -0,0 +1,93 @@
// Copyright 2024 Prometheus Team
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package rwcommon
import (
"testing"
"github.com/stretchr/testify/require"
"github.com/prometheus/prometheus/model/histogram"
)
func testIntHistogram() histogram.Histogram {
return histogram.Histogram{
CounterResetHint: histogram.GaugeType,
Schema: 0,
Count: 19,
Sum: 2.7,
ZeroThreshold: 1e-128,
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 testFloatHistogram() histogram.FloatHistogram {
return histogram.FloatHistogram{
CounterResetHint: histogram.GaugeType,
Schema: 0,
Count: 19,
Sum: 2.7,
ZeroThreshold: 1e-128,
PositiveSpans: []histogram.Span{
{Offset: 0, Length: 4},
{Offset: 0, Length: 0},
{Offset: 0, Length: 3},
},
PositiveBuckets: []float64{1, 3, 1, 2, 1, 1, 1},
NegativeSpans: []histogram.Span{
{Offset: 0, Length: 5},
{Offset: 1, Length: 0},
{Offset: 0, Length: 1},
},
NegativeBuckets: []float64{1, 3, 1, 2, 1, 1},
}
}
func TestHistogram[T HistogramConvertable](t *testing.T, converter T, fromInt FromIntHistogramFunc[T], fromFloat FromFloatHistogramFunc[T]) {
t.Helper()
t.Run("ToHistogram_Empty", func(t *testing.T) {
require.NotNilf(t, converter.ToIntHistogram(), "")
require.NotNilf(t, converter.ToFloatHistogram(), "")
})
t.Run("FromIntToFloatOrIntHistogram", func(t *testing.T) {
h := testIntHistogram()
fh := testFloatHistogram()
got := fromInt(123, &h)
require.False(t, got.IsFloatHistogram())
require.Equal(t, int64(123), got.T())
require.Equal(t, &h, got.ToIntHistogram())
require.Equal(t, &fh, got.ToFloatHistogram())
})
t.Run("FromFloatToFloatHistogram(", func(t *testing.T) {
fh := testFloatHistogram()
got := fromFloat(123, &fh)
require.True(t, got.IsFloatHistogram())
require.Equal(t, int64(123), got.T())
require.Equal(t, &fh, got.ToFloatHistogram())
})
}