|
|
|
@ -29,6 +29,7 @@ import (
|
|
|
|
|
"github.com/prometheus/prometheus/storage"
|
|
|
|
|
"github.com/prometheus/prometheus/tsdb/chunkenc"
|
|
|
|
|
"github.com/prometheus/prometheus/tsdb/chunks"
|
|
|
|
|
"github.com/prometheus/prometheus/tsdb/tsdbutil"
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
var testHistogram = histogram.Histogram{
|
|
|
|
@ -174,12 +175,12 @@ func TestValidateLabelsAndMetricName(t *testing.T) {
|
|
|
|
|
|
|
|
|
|
func TestConcreteSeriesSet(t *testing.T) {
|
|
|
|
|
series1 := &concreteSeries{
|
|
|
|
|
labels: labels.FromStrings("foo", "bar"),
|
|
|
|
|
samples: []prompb.Sample{{Value: 1, Timestamp: 2}},
|
|
|
|
|
labels: labels.FromStrings("foo", "bar"),
|
|
|
|
|
floats: []prompb.Sample{{Value: 1, Timestamp: 2}},
|
|
|
|
|
}
|
|
|
|
|
series2 := &concreteSeries{
|
|
|
|
|
labels: labels.FromStrings("foo", "baz"),
|
|
|
|
|
samples: []prompb.Sample{{Value: 3, Timestamp: 4}},
|
|
|
|
|
labels: labels.FromStrings("foo", "baz"),
|
|
|
|
|
floats: []prompb.Sample{{Value: 3, Timestamp: 4}},
|
|
|
|
|
}
|
|
|
|
|
c := &concreteSeriesSet{
|
|
|
|
|
series: []storage.Series{series1, series2},
|
|
|
|
@ -206,10 +207,10 @@ func TestConcreteSeriesClonesLabels(t *testing.T) {
|
|
|
|
|
require.Equal(t, lbls, gotLabels)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func TestConcreteSeriesIterator(t *testing.T) {
|
|
|
|
|
func TestConcreteSeriesIterator_FloatSamples(t *testing.T) {
|
|
|
|
|
series := &concreteSeries{
|
|
|
|
|
labels: labels.FromStrings("foo", "bar"),
|
|
|
|
|
samples: []prompb.Sample{
|
|
|
|
|
floats: []prompb.Sample{
|
|
|
|
|
{Value: 1, Timestamp: 1},
|
|
|
|
|
{Value: 1.5, Timestamp: 1},
|
|
|
|
|
{Value: 2, Timestamp: 2},
|
|
|
|
@ -255,6 +256,165 @@ func TestConcreteSeriesIterator(t *testing.T) {
|
|
|
|
|
require.Equal(t, chunkenc.ValNone, it.Seek(2))
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func TestConcreteSeriesIterator_HistogramSamples(t *testing.T) {
|
|
|
|
|
histograms := tsdbutil.GenerateTestHistograms(5)
|
|
|
|
|
histProtos := make([]prompb.Histogram, len(histograms))
|
|
|
|
|
for i, h := range histograms {
|
|
|
|
|
// Results in ts sequence of 1, 1, 2, 3, 4.
|
|
|
|
|
var ts int64
|
|
|
|
|
if i == 0 {
|
|
|
|
|
ts = 1
|
|
|
|
|
} else {
|
|
|
|
|
ts = int64(i)
|
|
|
|
|
}
|
|
|
|
|
histProtos[i] = HistogramToHistogramProto(ts, h)
|
|
|
|
|
}
|
|
|
|
|
series := &concreteSeries{
|
|
|
|
|
labels: labels.FromStrings("foo", "bar"),
|
|
|
|
|
histograms: histProtos,
|
|
|
|
|
}
|
|
|
|
|
it := series.Iterator(nil)
|
|
|
|
|
|
|
|
|
|
// Seek to the first sample with ts=1.
|
|
|
|
|
require.Equal(t, chunkenc.ValHistogram, it.Seek(1))
|
|
|
|
|
ts, v := it.AtHistogram()
|
|
|
|
|
require.Equal(t, int64(1), ts)
|
|
|
|
|
require.Equal(t, histograms[0], v)
|
|
|
|
|
|
|
|
|
|
// Seek one further, next sample still has ts=1.
|
|
|
|
|
require.Equal(t, chunkenc.ValHistogram, it.Next())
|
|
|
|
|
ts, v = it.AtHistogram()
|
|
|
|
|
require.Equal(t, int64(1), ts)
|
|
|
|
|
require.Equal(t, histograms[1], v)
|
|
|
|
|
|
|
|
|
|
// Seek again to 1 and make sure we stay where we are.
|
|
|
|
|
require.Equal(t, chunkenc.ValHistogram, it.Seek(1))
|
|
|
|
|
ts, v = it.AtHistogram()
|
|
|
|
|
require.Equal(t, int64(1), ts)
|
|
|
|
|
require.Equal(t, histograms[1], v)
|
|
|
|
|
|
|
|
|
|
// Another seek.
|
|
|
|
|
require.Equal(t, chunkenc.ValHistogram, it.Seek(3))
|
|
|
|
|
ts, v = it.AtHistogram()
|
|
|
|
|
require.Equal(t, int64(3), ts)
|
|
|
|
|
require.Equal(t, histograms[3], v)
|
|
|
|
|
|
|
|
|
|
// And we don't go back.
|
|
|
|
|
require.Equal(t, chunkenc.ValHistogram, it.Seek(2))
|
|
|
|
|
ts, v = it.AtHistogram()
|
|
|
|
|
require.Equal(t, int64(3), ts)
|
|
|
|
|
require.Equal(t, histograms[3], v)
|
|
|
|
|
|
|
|
|
|
// Seek beyond the end.
|
|
|
|
|
require.Equal(t, chunkenc.ValNone, it.Seek(5))
|
|
|
|
|
// And we don't go back. (This exposes issue #10027.)
|
|
|
|
|
require.Equal(t, chunkenc.ValNone, it.Seek(2))
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func TestConcreteSeriesIterator_FloatAndHistogramSamples(t *testing.T) {
|
|
|
|
|
// Series starts as histograms, then transitions to floats at ts=8 (with an overlap from ts=8 to ts=10), then
|
|
|
|
|
// transitions back to histograms at ts=16.
|
|
|
|
|
histograms := tsdbutil.GenerateTestHistograms(15)
|
|
|
|
|
histProtos := make([]prompb.Histogram, len(histograms))
|
|
|
|
|
for i, h := range histograms {
|
|
|
|
|
if i < 10 {
|
|
|
|
|
histProtos[i] = HistogramToHistogramProto(int64(i+1), h)
|
|
|
|
|
} else {
|
|
|
|
|
histProtos[i] = HistogramToHistogramProto(int64(i+6), h)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
series := &concreteSeries{
|
|
|
|
|
labels: labels.FromStrings("foo", "bar"),
|
|
|
|
|
floats: []prompb.Sample{
|
|
|
|
|
{Value: 1, Timestamp: 8},
|
|
|
|
|
{Value: 2, Timestamp: 9},
|
|
|
|
|
{Value: 3, Timestamp: 10},
|
|
|
|
|
{Value: 4, Timestamp: 11},
|
|
|
|
|
{Value: 5, Timestamp: 12},
|
|
|
|
|
{Value: 6, Timestamp: 13},
|
|
|
|
|
{Value: 7, Timestamp: 14},
|
|
|
|
|
{Value: 8, Timestamp: 15},
|
|
|
|
|
},
|
|
|
|
|
histograms: histProtos,
|
|
|
|
|
}
|
|
|
|
|
it := series.Iterator(nil)
|
|
|
|
|
|
|
|
|
|
var (
|
|
|
|
|
ts int64
|
|
|
|
|
v float64
|
|
|
|
|
h *histogram.Histogram
|
|
|
|
|
fh *histogram.FloatHistogram
|
|
|
|
|
)
|
|
|
|
|
require.Equal(t, chunkenc.ValHistogram, it.Next())
|
|
|
|
|
ts, h = it.AtHistogram()
|
|
|
|
|
require.Equal(t, int64(1), ts)
|
|
|
|
|
require.Equal(t, histograms[0], h)
|
|
|
|
|
|
|
|
|
|
require.Equal(t, chunkenc.ValHistogram, it.Next())
|
|
|
|
|
ts, h = it.AtHistogram()
|
|
|
|
|
require.Equal(t, int64(2), ts)
|
|
|
|
|
require.Equal(t, histograms[1], h)
|
|
|
|
|
|
|
|
|
|
// Seek to the first float/histogram sample overlap at ts=8 (should prefer the float sample).
|
|
|
|
|
require.Equal(t, chunkenc.ValFloat, it.Seek(8))
|
|
|
|
|
ts, v = it.At()
|
|
|
|
|
require.Equal(t, int64(8), ts)
|
|
|
|
|
require.Equal(t, 1., v)
|
|
|
|
|
|
|
|
|
|
// Attempting to seek backwards should do nothing.
|
|
|
|
|
require.Equal(t, chunkenc.ValFloat, it.Seek(1))
|
|
|
|
|
ts, v = it.At()
|
|
|
|
|
require.Equal(t, int64(8), ts)
|
|
|
|
|
require.Equal(t, 1., v)
|
|
|
|
|
|
|
|
|
|
// Seeking to 8 again should also do nothing.
|
|
|
|
|
require.Equal(t, chunkenc.ValFloat, it.Seek(8))
|
|
|
|
|
ts, v = it.At()
|
|
|
|
|
require.Equal(t, int64(8), ts)
|
|
|
|
|
require.Equal(t, 1., v)
|
|
|
|
|
|
|
|
|
|
// Again, should prefer the float sample.
|
|
|
|
|
require.Equal(t, chunkenc.ValFloat, it.Next())
|
|
|
|
|
ts, v = it.At()
|
|
|
|
|
require.Equal(t, int64(9), ts)
|
|
|
|
|
require.Equal(t, 2., v)
|
|
|
|
|
|
|
|
|
|
// Seek to ts=11 where there are only float samples.
|
|
|
|
|
require.Equal(t, chunkenc.ValFloat, it.Seek(11))
|
|
|
|
|
ts, v = it.At()
|
|
|
|
|
require.Equal(t, int64(11), ts)
|
|
|
|
|
require.Equal(t, 4., v)
|
|
|
|
|
|
|
|
|
|
// Seek to ts=15 right before the transition back to histogram samples.
|
|
|
|
|
require.Equal(t, chunkenc.ValFloat, it.Seek(15))
|
|
|
|
|
ts, v = it.At()
|
|
|
|
|
require.Equal(t, int64(15), ts)
|
|
|
|
|
require.Equal(t, 8., v)
|
|
|
|
|
|
|
|
|
|
require.Equal(t, chunkenc.ValHistogram, it.Next())
|
|
|
|
|
ts, h = it.AtHistogram()
|
|
|
|
|
require.Equal(t, int64(16), ts)
|
|
|
|
|
require.Equal(t, histograms[10], h)
|
|
|
|
|
|
|
|
|
|
// Getting a float histogram from an int histogram works.
|
|
|
|
|
require.Equal(t, chunkenc.ValHistogram, it.Next())
|
|
|
|
|
ts, fh = it.AtFloatHistogram()
|
|
|
|
|
require.Equal(t, int64(17), ts)
|
|
|
|
|
expected := HistogramProtoToFloatHistogram(HistogramToHistogramProto(int64(17), histograms[11]))
|
|
|
|
|
require.Equal(t, expected, fh)
|
|
|
|
|
|
|
|
|
|
// Keep calling Next() until the end.
|
|
|
|
|
for i := 0; i < 3; i++ {
|
|
|
|
|
require.Equal(t, chunkenc.ValHistogram, it.Next())
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// The iterator is exhausted.
|
|
|
|
|
require.Equal(t, chunkenc.ValNone, it.Next())
|
|
|
|
|
require.Equal(t, chunkenc.ValNone, it.Next())
|
|
|
|
|
// Should also not be able to seek backwards again.
|
|
|
|
|
require.Equal(t, chunkenc.ValNone, it.Seek(1))
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func TestFromQueryResultWithDuplicates(t *testing.T) {
|
|
|
|
|
ts1 := prompb.TimeSeries{
|
|
|
|
|
Labels: []prompb.Label{
|
|
|
|
@ -368,7 +528,7 @@ func TestNilHistogramProto(t *testing.T) {
|
|
|
|
|
// This function will panic if it impromperly handles nil
|
|
|
|
|
// values, causing the test to fail.
|
|
|
|
|
HistogramProtoToHistogram(prompb.Histogram{})
|
|
|
|
|
HistogramProtoToFloatHistogram(prompb.Histogram{})
|
|
|
|
|
FloatHistogramProtoToFloatHistogram(prompb.Histogram{})
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func exampleHistogram() histogram.Histogram {
|
|
|
|
@ -563,7 +723,7 @@ func TestFloatHistogramToProtoConvert(t *testing.T) {
|
|
|
|
|
|
|
|
|
|
require.Equal(t, p, FloatHistogramToHistogramProto(1337, &h))
|
|
|
|
|
|
|
|
|
|
require.Equal(t, h, *HistogramProtoToFloatHistogram(p))
|
|
|
|
|
require.Equal(t, h, *FloatHistogramProtoToFloatHistogram(p))
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|