mirror of
https://github.com/prometheus/prometheus.git
synced 2024-11-09 23:24:05 -08:00
Merge pull request #12739 from prometheus/beorn7/histogram2
tsdb: Fix histogram validation
This commit is contained in:
commit
682ab7bc5e
|
@ -3182,7 +3182,7 @@ func TestNativeHistogramRate(t *testing.T) {
|
|||
Schema: 1,
|
||||
ZeroThreshold: 0.001,
|
||||
ZeroCount: 1. / 15.,
|
||||
Count: 8. / 15.,
|
||||
Count: 9. / 15.,
|
||||
Sum: 1.226666666666667,
|
||||
PositiveSpans: []histogram.Span{{Offset: 0, Length: 2}, {Offset: 1, Length: 2}},
|
||||
PositiveBuckets: []float64{1. / 15., 1. / 15., 1. / 15., 1. / 15.},
|
||||
|
@ -3223,7 +3223,7 @@ func TestNativeFloatHistogramRate(t *testing.T) {
|
|||
Schema: 1,
|
||||
ZeroThreshold: 0.001,
|
||||
ZeroCount: 1. / 15.,
|
||||
Count: 8. / 15.,
|
||||
Count: 9. / 15.,
|
||||
Sum: 1.226666666666667,
|
||||
PositiveSpans: []histogram.Span{{Offset: 0, Length: 2}, {Offset: 1, Length: 2}},
|
||||
PositiveBuckets: []float64{1. / 15., 1. / 15., 1. / 15., 1. / 15.},
|
||||
|
@ -3996,7 +3996,7 @@ func TestNativeHistogram_Sum_Count_Add_AvgOperator(t *testing.T) {
|
|||
{
|
||||
CounterResetHint: histogram.GaugeType,
|
||||
Schema: 0,
|
||||
Count: 21,
|
||||
Count: 25,
|
||||
Sum: 1234.5,
|
||||
ZeroThreshold: 0.001,
|
||||
ZeroCount: 4,
|
||||
|
@ -4014,7 +4014,7 @@ func TestNativeHistogram_Sum_Count_Add_AvgOperator(t *testing.T) {
|
|||
{
|
||||
CounterResetHint: histogram.GaugeType,
|
||||
Schema: 0,
|
||||
Count: 36,
|
||||
Count: 41,
|
||||
Sum: 2345.6,
|
||||
ZeroThreshold: 0.001,
|
||||
ZeroCount: 5,
|
||||
|
@ -4034,7 +4034,7 @@ func TestNativeHistogram_Sum_Count_Add_AvgOperator(t *testing.T) {
|
|||
{
|
||||
CounterResetHint: histogram.GaugeType,
|
||||
Schema: 0,
|
||||
Count: 36,
|
||||
Count: 41,
|
||||
Sum: 1111.1,
|
||||
ZeroThreshold: 0.001,
|
||||
ZeroCount: 5,
|
||||
|
@ -4061,7 +4061,7 @@ func TestNativeHistogram_Sum_Count_Add_AvgOperator(t *testing.T) {
|
|||
Schema: 0,
|
||||
ZeroThreshold: 0.001,
|
||||
ZeroCount: 14,
|
||||
Count: 93,
|
||||
Count: 107,
|
||||
Sum: 4691.2,
|
||||
PositiveSpans: []histogram.Span{
|
||||
{Offset: 0, Length: 7},
|
||||
|
@ -4078,7 +4078,7 @@ func TestNativeHistogram_Sum_Count_Add_AvgOperator(t *testing.T) {
|
|||
Schema: 0,
|
||||
ZeroThreshold: 0.001,
|
||||
ZeroCount: 3.5,
|
||||
Count: 23.25,
|
||||
Count: 26.75,
|
||||
Sum: 1172.8,
|
||||
PositiveSpans: []histogram.Span{
|
||||
{Offset: 0, Length: 7},
|
||||
|
@ -4189,7 +4189,7 @@ func TestNativeHistogram_SubOperator(t *testing.T) {
|
|||
histograms: []histogram.Histogram{
|
||||
{
|
||||
Schema: 0,
|
||||
Count: 36,
|
||||
Count: 41,
|
||||
Sum: 2345.6,
|
||||
ZeroThreshold: 0.001,
|
||||
ZeroCount: 5,
|
||||
|
@ -4224,7 +4224,7 @@ func TestNativeHistogram_SubOperator(t *testing.T) {
|
|||
},
|
||||
expected: histogram.FloatHistogram{
|
||||
Schema: 0,
|
||||
Count: 25,
|
||||
Count: 30,
|
||||
Sum: 1111.1,
|
||||
ZeroThreshold: 0.001,
|
||||
ZeroCount: 2,
|
||||
|
@ -4245,7 +4245,7 @@ func TestNativeHistogram_SubOperator(t *testing.T) {
|
|||
histograms: []histogram.Histogram{
|
||||
{
|
||||
Schema: 0,
|
||||
Count: 36,
|
||||
Count: 41,
|
||||
Sum: 2345.6,
|
||||
ZeroThreshold: 0.001,
|
||||
ZeroCount: 5,
|
||||
|
@ -4280,7 +4280,7 @@ func TestNativeHistogram_SubOperator(t *testing.T) {
|
|||
},
|
||||
expected: histogram.FloatHistogram{
|
||||
Schema: 0,
|
||||
Count: 25,
|
||||
Count: 30,
|
||||
Sum: 1111.1,
|
||||
ZeroThreshold: 0.001,
|
||||
ZeroCount: 2,
|
||||
|
@ -4315,7 +4315,7 @@ func TestNativeHistogram_SubOperator(t *testing.T) {
|
|||
},
|
||||
{
|
||||
Schema: 0,
|
||||
Count: 36,
|
||||
Count: 41,
|
||||
Sum: 2345.6,
|
||||
ZeroThreshold: 0.001,
|
||||
ZeroCount: 5,
|
||||
|
@ -4335,7 +4335,7 @@ func TestNativeHistogram_SubOperator(t *testing.T) {
|
|||
},
|
||||
expected: histogram.FloatHistogram{
|
||||
Schema: 0,
|
||||
Count: -25,
|
||||
Count: -30,
|
||||
Sum: -1111.1,
|
||||
ZeroThreshold: 0.001,
|
||||
ZeroCount: -2,
|
||||
|
|
File diff suppressed because one or more lines are too long
|
@ -621,7 +621,7 @@ func genSeries(totalSeries, labelCount int, mint, maxt int64) []storage.Series {
|
|||
func genHistogramSeries(totalSeries, labelCount int, mint, maxt, step int64, floatHistogram bool) []storage.Series {
|
||||
return genSeriesFromSampleGenerator(totalSeries, labelCount, mint, maxt, step, func(ts int64) tsdbutil.Sample {
|
||||
h := &histogram.Histogram{
|
||||
Count: 5 + uint64(ts*4),
|
||||
Count: 7 + uint64(ts*5),
|
||||
ZeroCount: 2 + uint64(ts),
|
||||
ZeroThreshold: 0.001,
|
||||
Sum: 18.4 * rand.Float64(),
|
||||
|
@ -660,7 +660,7 @@ func genHistogramAndFloatSeries(totalSeries, labelCount int, mint, maxt, step in
|
|||
s = sample{t: ts, f: rand.Float64()}
|
||||
} else {
|
||||
h := &histogram.Histogram{
|
||||
Count: 5 + uint64(ts*4),
|
||||
Count: 7 + uint64(ts*5),
|
||||
ZeroCount: 2 + uint64(ts),
|
||||
ZeroThreshold: 0.001,
|
||||
Sum: 18.4 * rand.Float64(),
|
||||
|
|
|
@ -1364,7 +1364,7 @@ func TestHeadCompactionWithHistograms(t *testing.T) {
|
|||
exp1, exp2, exp3, exp4 []tsdbutil.Sample
|
||||
)
|
||||
h := &histogram.Histogram{
|
||||
Count: 11,
|
||||
Count: 15,
|
||||
ZeroCount: 4,
|
||||
ZeroThreshold: 0.001,
|
||||
Sum: 35.5,
|
||||
|
|
|
@ -6133,7 +6133,7 @@ func testHistogramAppendAndQueryHelper(t *testing.T, floatHistogram bool) {
|
|||
}
|
||||
|
||||
baseH := &histogram.Histogram{
|
||||
Count: 11,
|
||||
Count: 15,
|
||||
ZeroCount: 4,
|
||||
ZeroThreshold: 0.001,
|
||||
Sum: 35.5,
|
||||
|
@ -6506,7 +6506,7 @@ func TestNativeHistogramFlag(t *testing.T) {
|
|||
require.NoError(t, db.Close())
|
||||
})
|
||||
h := &histogram.Histogram{
|
||||
Count: 6,
|
||||
Count: 10,
|
||||
ZeroCount: 4,
|
||||
ZeroThreshold: 0.001,
|
||||
Sum: 35.5,
|
||||
|
|
|
@ -659,7 +659,7 @@ func ValidateHistogram(h *histogram.Histogram) error {
|
|||
return errors.Wrap(err, "positive side")
|
||||
}
|
||||
|
||||
if c := nCount + pCount; c > h.Count {
|
||||
if c := nCount + pCount + h.ZeroCount; c > h.Count {
|
||||
return errors.Wrap(
|
||||
storage.ErrHistogramCountNotBigEnough,
|
||||
fmt.Sprintf("%d observations found in buckets, but the Count field is %d", c, h.Count),
|
||||
|
@ -686,12 +686,9 @@ func ValidateFloatHistogram(h *histogram.FloatHistogram) error {
|
|||
return errors.Wrap(err, "positive side")
|
||||
}
|
||||
|
||||
if c := nCount + pCount; c > h.Count {
|
||||
return errors.Wrap(
|
||||
storage.ErrHistogramCountNotBigEnough,
|
||||
fmt.Sprintf("%f observations found in buckets, but the Count field is %f", c, h.Count),
|
||||
)
|
||||
}
|
||||
// We do not check for h.Count being at least as large as the sum of the
|
||||
// counts in the buckets because floating point precision issues can
|
||||
// create false positives here.
|
||||
|
||||
return nil
|
||||
}
|
||||
|
|
|
@ -4710,42 +4710,42 @@ func TestReplayAfterMmapReplayError(t *testing.T) {
|
|||
|
||||
func TestHistogramValidation(t *testing.T) {
|
||||
tests := map[string]struct {
|
||||
h *histogram.Histogram
|
||||
errMsg string
|
||||
errMsgFloat string // To be considered for float histogram only if it is non-empty.
|
||||
h *histogram.Histogram
|
||||
errMsg string
|
||||
skipFloat bool
|
||||
}{
|
||||
"valid histogram": {
|
||||
h: tsdbutil.GenerateTestHistograms(1)[0],
|
||||
},
|
||||
"rejects histogram who has too few negative buckets": {
|
||||
"rejects histogram that has too few negative buckets": {
|
||||
h: &histogram.Histogram{
|
||||
NegativeSpans: []histogram.Span{{Offset: 0, Length: 1}},
|
||||
NegativeBuckets: []int64{},
|
||||
},
|
||||
errMsg: `negative side: spans need 1 buckets, have 0 buckets`,
|
||||
},
|
||||
"rejects histogram who has too few positive buckets": {
|
||||
"rejects histogram that has too few positive buckets": {
|
||||
h: &histogram.Histogram{
|
||||
PositiveSpans: []histogram.Span{{Offset: 0, Length: 1}},
|
||||
PositiveBuckets: []int64{},
|
||||
},
|
||||
errMsg: `positive side: spans need 1 buckets, have 0 buckets`,
|
||||
},
|
||||
"rejects histogram who has too many negative buckets": {
|
||||
"rejects histogram that has too many negative buckets": {
|
||||
h: &histogram.Histogram{
|
||||
NegativeSpans: []histogram.Span{{Offset: 0, Length: 1}},
|
||||
NegativeBuckets: []int64{1, 2},
|
||||
},
|
||||
errMsg: `negative side: spans need 1 buckets, have 2 buckets`,
|
||||
},
|
||||
"rejects histogram who has too many positive buckets": {
|
||||
"rejects histogram that has too many positive buckets": {
|
||||
h: &histogram.Histogram{
|
||||
PositiveSpans: []histogram.Span{{Offset: 0, Length: 1}},
|
||||
PositiveBuckets: []int64{1, 2},
|
||||
},
|
||||
errMsg: `positive side: spans need 1 buckets, have 2 buckets`,
|
||||
},
|
||||
"rejects a histogram which has a negative span with a negative offset": {
|
||||
"rejects a histogram that has a negative span with a negative offset": {
|
||||
h: &histogram.Histogram{
|
||||
NegativeSpans: []histogram.Span{{Offset: -1, Length: 1}, {Offset: -1, Length: 1}},
|
||||
NegativeBuckets: []int64{1, 2},
|
||||
|
@ -4759,21 +4759,21 @@ func TestHistogramValidation(t *testing.T) {
|
|||
},
|
||||
errMsg: `positive side: span number 2 with offset -1`,
|
||||
},
|
||||
"rejects a histogram which has a negative bucket with a negative count": {
|
||||
"rejects a histogram that has a negative bucket with a negative count": {
|
||||
h: &histogram.Histogram{
|
||||
NegativeSpans: []histogram.Span{{Offset: -1, Length: 1}},
|
||||
NegativeBuckets: []int64{-1},
|
||||
},
|
||||
errMsg: `negative side: bucket number 1 has observation count of -1`,
|
||||
},
|
||||
"rejects a histogram which has a positive bucket with a negative count": {
|
||||
"rejects a histogram that has a positive bucket with a negative count": {
|
||||
h: &histogram.Histogram{
|
||||
PositiveSpans: []histogram.Span{{Offset: -1, Length: 1}},
|
||||
PositiveBuckets: []int64{-1},
|
||||
},
|
||||
errMsg: `positive side: bucket number 1 has observation count of -1`,
|
||||
},
|
||||
"rejects a histogram which which has a lower count than count in buckets": {
|
||||
"rejects a histogram that has a lower count than count in buckets": {
|
||||
h: &histogram.Histogram{
|
||||
Count: 0,
|
||||
NegativeSpans: []histogram.Span{{Offset: -1, Length: 1}},
|
||||
|
@ -4781,25 +4781,36 @@ func TestHistogramValidation(t *testing.T) {
|
|||
NegativeBuckets: []int64{1},
|
||||
PositiveBuckets: []int64{1},
|
||||
},
|
||||
errMsg: `2 observations found in buckets, but the Count field is 0`,
|
||||
errMsgFloat: `2.000000 observations found in buckets, but the Count field is 0.000000`,
|
||||
errMsg: `2 observations found in buckets, but the Count field is 0`,
|
||||
skipFloat: true,
|
||||
},
|
||||
"rejects a histogram that doesn't count the zero bucket in its count": {
|
||||
h: &histogram.Histogram{
|
||||
Count: 2,
|
||||
ZeroCount: 1,
|
||||
NegativeSpans: []histogram.Span{{Offset: -1, Length: 1}},
|
||||
PositiveSpans: []histogram.Span{{Offset: -1, Length: 1}},
|
||||
NegativeBuckets: []int64{1},
|
||||
PositiveBuckets: []int64{1},
|
||||
},
|
||||
errMsg: `3 observations found in buckets, but the Count field is 2`,
|
||||
skipFloat: true,
|
||||
},
|
||||
}
|
||||
|
||||
for testName, tc := range tests {
|
||||
t.Run(testName, func(t *testing.T) {
|
||||
switch err := ValidateHistogram(tc.h); {
|
||||
case tc.errMsg != "":
|
||||
if err := ValidateHistogram(tc.h); tc.errMsg != "" {
|
||||
require.ErrorContains(t, err, tc.errMsg)
|
||||
default:
|
||||
} else {
|
||||
require.NoError(t, err)
|
||||
}
|
||||
switch err := ValidateFloatHistogram(tc.h.ToFloat()); {
|
||||
case tc.errMsgFloat != "":
|
||||
require.ErrorContains(t, err, tc.errMsgFloat)
|
||||
case tc.errMsg != "":
|
||||
if tc.skipFloat {
|
||||
return
|
||||
}
|
||||
if err := ValidateFloatHistogram(tc.h.ToFloat()); tc.errMsg != "" {
|
||||
require.ErrorContains(t, err, tc.errMsg)
|
||||
default:
|
||||
} else {
|
||||
require.NoError(t, err)
|
||||
}
|
||||
})
|
||||
|
|
|
@ -33,7 +33,7 @@ func GenerateTestHistograms(n int) (r []*histogram.Histogram) {
|
|||
// GenerateTestHistogram but it is up to the user to set any known counter reset hint.
|
||||
func GenerateTestHistogram(i int) *histogram.Histogram {
|
||||
return &histogram.Histogram{
|
||||
Count: 10 + uint64(i*8),
|
||||
Count: 12 + uint64(i*9),
|
||||
ZeroCount: 2 + uint64(i),
|
||||
ZeroThreshold: 0.001,
|
||||
Sum: 18.4 * float64(i+1),
|
||||
|
@ -78,7 +78,7 @@ func GenerateTestFloatHistograms(n int) (r []*histogram.FloatHistogram) {
|
|||
// GenerateTestFloatHistogram but it is up to the user to set any known counter reset hint.
|
||||
func GenerateTestFloatHistogram(i int) *histogram.FloatHistogram {
|
||||
return &histogram.FloatHistogram{
|
||||
Count: 10 + float64(i*8),
|
||||
Count: 12 + float64(i*9),
|
||||
ZeroCount: 2 + float64(i),
|
||||
ZeroThreshold: 0.001,
|
||||
Sum: 18.4 * float64(i+1),
|
||||
|
|
|
@ -306,7 +306,7 @@ func TestFederationWithNativeHistograms(t *testing.T) {
|
|||
|
||||
db := storage.DB
|
||||
hist := &histogram.Histogram{
|
||||
Count: 10,
|
||||
Count: 12,
|
||||
ZeroCount: 2,
|
||||
ZeroThreshold: 0.001,
|
||||
Sum: 39.4,
|
||||
|
@ -359,6 +359,7 @@ func TestFederationWithNativeHistograms(t *testing.T) {
|
|||
})
|
||||
default:
|
||||
hist.ZeroCount++
|
||||
hist.Count++
|
||||
_, err = app.AppendHistogram(0, l, 100*60*1000, hist.Copy(), nil)
|
||||
expVec = append(expVec, promql.Sample{
|
||||
T: 100 * 60 * 1000,
|
||||
|
|
Loading…
Reference in a new issue