mirror of
https://github.com/prometheus/prometheus.git
synced 2026-05-28 04:02:21 -04:00
368 lines
9.6 KiB
Go
368 lines
9.6 KiB
Go
// Copyright The Prometheus Authors
|
|
// 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 scrape
|
|
|
|
import (
|
|
"testing"
|
|
|
|
"github.com/stretchr/testify/require"
|
|
|
|
"github.com/prometheus/prometheus/model/histogram"
|
|
)
|
|
|
|
func TestSynthesizeFloat_ValidCounter(t *testing.T) {
|
|
st := &stCache{}
|
|
|
|
// Scrape loop anchors first sample.
|
|
v, ct, skip := st.synthesizeFloat(10.0, 1000)
|
|
require.Equal(t, 10.0, v)
|
|
require.Equal(t, int64(1000), ct)
|
|
require.True(t, skip)
|
|
require.Equal(t, 10.0, st.f.prev)
|
|
require.Equal(t, 10.0, st.f.starting)
|
|
|
|
// Second scrape, no reset.
|
|
v, ct, skip = st.synthesizeFloat(15.0, 2000)
|
|
require.Equal(t, 5.0, v)
|
|
require.Equal(t, 15.0, st.f.prev)
|
|
require.Equal(t, int64(1000), ct)
|
|
require.False(t, skip)
|
|
|
|
// Third scrape, no reset.
|
|
v, ct, skip = st.synthesizeFloat(20.0, 3000)
|
|
require.Equal(t, 10.0, v)
|
|
require.Equal(t, 20.0, st.f.prev)
|
|
require.Equal(t, int64(1000), ct)
|
|
require.False(t, skip)
|
|
}
|
|
|
|
func TestSynthesizeFloat_CounterReset(t *testing.T) {
|
|
st := &stCache{}
|
|
|
|
// Scrape loop anchors first sample.
|
|
v, ct, skip := st.synthesizeFloat(100.0, 1000)
|
|
require.Equal(t, 100.0, v)
|
|
require.Equal(t, int64(1000), ct)
|
|
require.True(t, skip)
|
|
require.Equal(t, 100.0, st.f.prev)
|
|
require.Equal(t, 100.0, st.f.starting)
|
|
|
|
// First reset (value goes down).
|
|
v, ct, skip = st.synthesizeFloat(5.0, 2000)
|
|
require.Equal(t, 5.0, v)
|
|
require.Equal(t, int64(1999), ct)
|
|
require.False(t, skip)
|
|
require.Equal(t, 5.0, st.f.prev)
|
|
require.Equal(t, 0.0, st.f.starting)
|
|
|
|
// Increment.
|
|
v, ct, skip = st.synthesizeFloat(15.0, 3000)
|
|
require.Equal(t, 15.0, v)
|
|
require.Equal(t, int64(1999), ct)
|
|
require.False(t, skip)
|
|
}
|
|
|
|
func TestSynthesizeFloatHistogram_ValidAndReset(t *testing.T) {
|
|
st := &stCache{}
|
|
|
|
fh1 := &histogram.FloatHistogram{
|
|
Count: 10,
|
|
Sum: 50.5,
|
|
ZeroCount: 2,
|
|
}
|
|
|
|
// Scrape loop anchors first sample.
|
|
v, ct, skip := st.synthesizeFloatHistogram(fh1, 1000)
|
|
require.Equal(t, fh1, v)
|
|
require.Equal(t, int64(1000), ct)
|
|
require.True(t, skip)
|
|
require.NotNil(t, st.h)
|
|
require.NotNil(t, st.h.prev)
|
|
require.NotNil(t, st.h.starting)
|
|
|
|
// Next scrape.
|
|
fh2 := &histogram.FloatHistogram{
|
|
Count: 25,
|
|
Sum: 120.0,
|
|
ZeroCount: 5,
|
|
}
|
|
v, ct, skip = st.synthesizeFloatHistogram(fh2, 2000)
|
|
require.Equal(t, 15.0, v.Count)
|
|
require.Equal(t, 69.5, v.Sum)
|
|
require.Equal(t, 3.0, v.ZeroCount)
|
|
require.Equal(t, int64(1000), ct)
|
|
require.False(t, skip)
|
|
|
|
// Reset scrape (values go down).
|
|
fh3 := &histogram.FloatHistogram{
|
|
Count: 5,
|
|
Sum: 12.0,
|
|
ZeroCount: 1,
|
|
}
|
|
v, ct, skip = st.synthesizeFloatHistogram(fh3, 3000)
|
|
require.Equal(t, 5.0, v.Count)
|
|
require.Equal(t, 12.0, v.Sum)
|
|
require.Equal(t, 1.0, v.ZeroCount)
|
|
require.Equal(t, int64(2999), ct)
|
|
require.False(t, skip)
|
|
require.Nil(t, st.h.starting)
|
|
|
|
// Next scrape.
|
|
fh4 := &histogram.FloatHistogram{
|
|
Count: 25,
|
|
Sum: 120.0,
|
|
ZeroCount: 5,
|
|
}
|
|
v, ct, skip = st.synthesizeFloatHistogram(fh4, 4000)
|
|
require.Equal(t, 25.0, v.Count)
|
|
require.Equal(t, 120.0, v.Sum)
|
|
require.Equal(t, 5.0, v.ZeroCount)
|
|
require.Equal(t, int64(2999), ct)
|
|
require.False(t, skip)
|
|
}
|
|
|
|
func TestSynthesizeHistogram_ValidAndReset(t *testing.T) {
|
|
st := &stCache{}
|
|
|
|
h1 := &histogram.Histogram{
|
|
Count: 10,
|
|
Sum: 50.5,
|
|
ZeroCount: 2,
|
|
}
|
|
|
|
// Scrape loop anchors first sample.
|
|
v, ct, skip := st.synthesizeHistogram(h1, 1000)
|
|
require.Equal(t, h1, v)
|
|
require.Equal(t, int64(1000), ct)
|
|
require.True(t, skip)
|
|
require.NotNil(t, st.h)
|
|
|
|
// Next scrape.
|
|
h2 := &histogram.Histogram{
|
|
Count: 25,
|
|
Sum: 120.0,
|
|
ZeroCount: 5,
|
|
}
|
|
v, ct, skip = st.synthesizeHistogram(h2, 2000)
|
|
require.Equal(t, uint64(15), v.Count)
|
|
require.Equal(t, 69.5, v.Sum)
|
|
require.Equal(t, uint64(3), v.ZeroCount)
|
|
require.Equal(t, int64(1000), ct)
|
|
require.False(t, skip)
|
|
|
|
// Reset scrape (values go down).
|
|
h3 := &histogram.Histogram{
|
|
Count: 5,
|
|
Sum: 12.0,
|
|
ZeroCount: 1,
|
|
}
|
|
v, ct, skip = st.synthesizeHistogram(h3, 3000)
|
|
require.Equal(t, uint64(5), v.Count)
|
|
require.Equal(t, 12.0, v.Sum)
|
|
require.Equal(t, uint64(1), v.ZeroCount)
|
|
require.Equal(t, int64(2999), ct)
|
|
require.False(t, skip)
|
|
require.Nil(t, st.h.starting)
|
|
|
|
// Next scrape.
|
|
h4 := &histogram.Histogram{
|
|
Count: 25,
|
|
Sum: 120.0,
|
|
ZeroCount: 5,
|
|
}
|
|
v, ct, skip = st.synthesizeHistogram(h4, 4000)
|
|
require.Equal(t, uint64(25), v.Count)
|
|
require.Equal(t, 120.0, v.Sum)
|
|
require.Equal(t, uint64(5), v.ZeroCount)
|
|
require.Equal(t, int64(2999), ct)
|
|
require.False(t, skip)
|
|
}
|
|
|
|
func TestSynthesizeFloatHistogram_SubtractionMapping(t *testing.T) {
|
|
st := &stCache{}
|
|
|
|
// Create an anchor.
|
|
fh1 := &histogram.FloatHistogram{
|
|
Count: 10,
|
|
Sum: 50.5,
|
|
ZeroCount: 2,
|
|
PositiveSpans: []histogram.Span{
|
|
{Offset: 0, Length: 2}, // Buckets at index 0, 1
|
|
},
|
|
PositiveBuckets: []float64{3.0, 5.0}, // total 8
|
|
}
|
|
|
|
// Scrape loop anchors first sample.
|
|
v, ct, skip := st.synthesizeFloatHistogram(fh1, 1000)
|
|
require.Equal(t, fh1, v)
|
|
require.Equal(t, int64(1000), ct)
|
|
require.True(t, skip)
|
|
|
|
// Next scrape has a NEW span layout because a previous 0 bucket got populated
|
|
// We expect NO reset, just proper subtraction.
|
|
fh2 := &histogram.FloatHistogram{
|
|
Count: 25,
|
|
Sum: 120.0,
|
|
ZeroCount: 3,
|
|
PositiveSpans: []histogram.Span{
|
|
{Offset: 0, Length: 3}, // Buckets at index 0, 1, 2
|
|
},
|
|
PositiveBuckets: []float64{4.0, 7.0, 6.0}, // The previous 0 bucket is now index 2 with 6.0 counts!
|
|
}
|
|
|
|
// Expect subtraction:
|
|
// fh1 buckets [0, 1]: 3.0, 5.0
|
|
// fh2 buckets [0, 1, 2]: 4.0, 7.0, 6.0
|
|
// Result: [4-3, 7-5, 6-0] -> [1.0, 2.0, 6.0]
|
|
// Count: 25 - 10 = 15
|
|
// Sum: 120 - 50.5 = 69.5
|
|
// ZeroCount: 3 - 2 = 1.0
|
|
v, ct, skip = st.synthesizeFloatHistogram(fh2, 2000)
|
|
|
|
require.False(t, skip)
|
|
require.Equal(t, int64(1000), ct)
|
|
require.Equal(t, 15.0, v.Count)
|
|
require.Equal(t, 69.5, v.Sum)
|
|
require.Equal(t, 1.0, v.ZeroCount)
|
|
require.Len(t, v.PositiveSpans, 1)
|
|
require.Equal(t, uint32(3), v.PositiveSpans[0].Length)
|
|
require.Equal(t, []float64{1.0, 2.0, 6.0}, v.PositiveBuckets)
|
|
}
|
|
|
|
func TestSynthesizeHistogram_SubtractionMapping(t *testing.T) {
|
|
st := &stCache{}
|
|
|
|
// Create an anchor
|
|
h1 := &histogram.Histogram{
|
|
Count: 10,
|
|
Sum: 50.5,
|
|
ZeroCount: 2,
|
|
PositiveSpans: []histogram.Span{
|
|
{Offset: 0, Length: 2}, // Buckets at index 0, 1
|
|
},
|
|
PositiveBuckets: []int64{3, 2}, // Absolute: 3, 5
|
|
}
|
|
|
|
// Scrape loop anchors first sample
|
|
v, ct, skip := st.synthesizeHistogram(h1, 1000)
|
|
require.Equal(t, h1, v)
|
|
require.Equal(t, int64(1000), ct)
|
|
require.True(t, skip)
|
|
|
|
// Next scrape has a NEW span layout because a previous 0 bucket got populated
|
|
h2 := &histogram.Histogram{
|
|
Count: 25,
|
|
Sum: 120.0,
|
|
ZeroCount: 3,
|
|
PositiveSpans: []histogram.Span{
|
|
{Offset: 0, Length: 3}, // Buckets at index 0, 1, 2
|
|
},
|
|
PositiveBuckets: []int64{4, 3, -1}, // Absolute: 4, 7, 6
|
|
}
|
|
|
|
// Expect absolute subtraction result:
|
|
// fh1 buckets absolute: 3, 5
|
|
// fh2 buckets absolute: 4, 7, 6
|
|
// Result absolute: 1, 2, 6
|
|
// Back to Delta -> [1, 1, 4]
|
|
v, ct, skip = st.synthesizeHistogram(h2, 2000)
|
|
|
|
require.False(t, skip)
|
|
require.Equal(t, int64(1000), ct)
|
|
require.Equal(t, uint64(15), v.Count)
|
|
require.Equal(t, 69.5, v.Sum)
|
|
require.Equal(t, uint64(1), v.ZeroCount)
|
|
require.Len(t, v.PositiveSpans, 1)
|
|
}
|
|
|
|
func TestSynthesizeFloatHistogram_BucketReset(t *testing.T) {
|
|
st := &stCache{}
|
|
|
|
fh1 := &histogram.FloatHistogram{
|
|
Count: 10,
|
|
Sum: 50.5,
|
|
ZeroCount: 2,
|
|
PositiveSpans: []histogram.Span{
|
|
{Offset: 0, Length: 2}, // Buckets at index 0, 1
|
|
},
|
|
PositiveBuckets: []float64{3.0, 5.0}, // total 8
|
|
}
|
|
|
|
v, ct, skip := st.synthesizeFloatHistogram(fh1, 1000)
|
|
_ = v
|
|
_ = ct
|
|
require.True(t, skip)
|
|
|
|
// Next scrape: total count up to 12. Sum up to 60.0. Zero count stable.
|
|
// BUT Bucket 0 goes from 3.0 down to 2.0. Bucket 1 goes from 5.0 to 8.0.
|
|
fh2 := &histogram.FloatHistogram{
|
|
Count: 12,
|
|
Sum: 60.0,
|
|
ZeroCount: 2,
|
|
PositiveSpans: []histogram.Span{
|
|
{Offset: 0, Length: 2},
|
|
},
|
|
PositiveBuckets: []float64{2.0, 8.0},
|
|
}
|
|
|
|
v, ct, skip = st.synthesizeFloatHistogram(fh2, 2000)
|
|
|
|
require.False(t, skip)
|
|
// Since it resets, ct should be 1999.
|
|
require.Equal(t, int64(1999), ct)
|
|
// v should equal fh2 exactly since it resets
|
|
require.Equal(t, 12.0, v.Count)
|
|
require.Equal(t, 60.0, v.Sum)
|
|
require.Equal(t, 2.0, v.ZeroCount)
|
|
require.Equal(t, []float64{2.0, 8.0}, v.PositiveBuckets)
|
|
require.Nil(t, st.h.starting)
|
|
}
|
|
|
|
func TestSynthesizeHistogram_BucketReset(t *testing.T) {
|
|
st := &stCache{}
|
|
|
|
h1 := &histogram.Histogram{
|
|
Count: 10,
|
|
Sum: 50.5,
|
|
ZeroCount: 2,
|
|
PositiveSpans: []histogram.Span{
|
|
{Offset: 0, Length: 2}, // Buckets at index 0, 1
|
|
},
|
|
PositiveBuckets: []int64{3, 2}, // Absolute: 3, 5
|
|
}
|
|
|
|
v, ct, skip := st.synthesizeHistogram(h1, 1000)
|
|
_ = v
|
|
_ = ct
|
|
require.True(t, skip)
|
|
|
|
h2 := &histogram.Histogram{
|
|
Count: 12,
|
|
Sum: 60.0,
|
|
ZeroCount: 2,
|
|
PositiveSpans: []histogram.Span{
|
|
{Offset: 0, Length: 2},
|
|
},
|
|
PositiveBuckets: []int64{2, 6}, // Absolute: 2, 8. Bucket 0 went from 3 to 2 -> Reset!
|
|
}
|
|
|
|
v, ct, skip = st.synthesizeHistogram(h2, 2000)
|
|
|
|
require.False(t, skip)
|
|
require.Equal(t, int64(1999), ct)
|
|
require.Equal(t, uint64(12), v.Count)
|
|
require.Equal(t, 60.0, v.Sum)
|
|
require.Equal(t, []int64{2, 6}, v.PositiveBuckets)
|
|
require.Nil(t, st.h.starting)
|
|
}
|