Merge pull request #17248 from prometheus/beorn7/histogram
buf.build / lint and publish (push) Waiting to run
Details
CI / Go tests (push) Waiting to run
Details
CI / More Go tests (push) Waiting to run
Details
CI / Go tests with previous Go version (push) Waiting to run
Details
CI / UI tests (push) Waiting to run
Details
CI / Go tests on Windows (push) Waiting to run
Details
CI / Mixins tests (push) Waiting to run
Details
CI / Build Prometheus for common architectures (0) (push) Waiting to run
Details
CI / Build Prometheus for common architectures (1) (push) Waiting to run
Details
CI / Build Prometheus for common architectures (2) (push) Waiting to run
Details
CI / Build Prometheus for all architectures (0) (push) Waiting to run
Details
CI / Build Prometheus for all architectures (1) (push) Waiting to run
Details
CI / Build Prometheus for all architectures (10) (push) Waiting to run
Details
CI / Build Prometheus for all architectures (11) (push) Waiting to run
Details
CI / Build Prometheus for all architectures (2) (push) Waiting to run
Details
CI / Build Prometheus for all architectures (3) (push) Waiting to run
Details
CI / Build Prometheus for all architectures (4) (push) Waiting to run
Details
CI / Build Prometheus for all architectures (5) (push) Waiting to run
Details
CI / Build Prometheus for all architectures (6) (push) Waiting to run
Details
CI / Build Prometheus for all architectures (7) (push) Waiting to run
Details
CI / Build Prometheus for all architectures (8) (push) Waiting to run
Details
CI / Build Prometheus for all architectures (9) (push) Waiting to run
Details
CI / Report status of build Prometheus for all architectures (push) Blocked by required conditions
Details
CI / Check generated parser (push) Waiting to run
Details
CI / golangci-lint (push) Waiting to run
Details
CI / fuzzing (push) Waiting to run
Details
CI / codeql (push) Waiting to run
Details
CI / Publish main branch artifacts (push) Blocked by required conditions
Details
CI / Publish release artefacts (push) Blocked by required conditions
Details
CI / Publish UI on npm Registry (push) Blocked by required conditions
Details
Scorecards supply-chain security / Scorecards analysis (push) Waiting to run
Details
buf.build / lint and publish (push) Waiting to run
Details
CI / Go tests (push) Waiting to run
Details
CI / More Go tests (push) Waiting to run
Details
CI / Go tests with previous Go version (push) Waiting to run
Details
CI / UI tests (push) Waiting to run
Details
CI / Go tests on Windows (push) Waiting to run
Details
CI / Mixins tests (push) Waiting to run
Details
CI / Build Prometheus for common architectures (0) (push) Waiting to run
Details
CI / Build Prometheus for common architectures (1) (push) Waiting to run
Details
CI / Build Prometheus for common architectures (2) (push) Waiting to run
Details
CI / Build Prometheus for all architectures (0) (push) Waiting to run
Details
CI / Build Prometheus for all architectures (1) (push) Waiting to run
Details
CI / Build Prometheus for all architectures (10) (push) Waiting to run
Details
CI / Build Prometheus for all architectures (11) (push) Waiting to run
Details
CI / Build Prometheus for all architectures (2) (push) Waiting to run
Details
CI / Build Prometheus for all architectures (3) (push) Waiting to run
Details
CI / Build Prometheus for all architectures (4) (push) Waiting to run
Details
CI / Build Prometheus for all architectures (5) (push) Waiting to run
Details
CI / Build Prometheus for all architectures (6) (push) Waiting to run
Details
CI / Build Prometheus for all architectures (7) (push) Waiting to run
Details
CI / Build Prometheus for all architectures (8) (push) Waiting to run
Details
CI / Build Prometheus for all architectures (9) (push) Waiting to run
Details
CI / Report status of build Prometheus for all architectures (push) Blocked by required conditions
Details
CI / Check generated parser (push) Waiting to run
Details
CI / golangci-lint (push) Waiting to run
Details
CI / fuzzing (push) Waiting to run
Details
CI / codeql (push) Waiting to run
Details
CI / Publish main branch artifacts (push) Blocked by required conditions
Details
CI / Publish release artefacts (push) Blocked by required conditions
Details
CI / Publish UI on npm Registry (push) Blocked by required conditions
Details
Scorecards supply-chain security / Scorecards analysis (push) Waiting to run
Details
model/histogram: Validate non-negative count and zero bucket
This commit is contained in:
commit
12c0961fd4
|
@ -826,12 +826,18 @@ func (h *FloatHistogram) Validate() error {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("negative side: %w", err)
|
return fmt.Errorf("negative side: %w", err)
|
||||||
}
|
}
|
||||||
|
if h.ZeroCount < 0 {
|
||||||
|
return fmt.Errorf("zero bucket has observation count of %v: %w", h.ZeroCount, ErrHistogramNegativeBucketCount)
|
||||||
|
}
|
||||||
if h.CustomValues != nil {
|
if h.CustomValues != nil {
|
||||||
return ErrHistogramExpSchemaCustomBounds
|
return ErrHistogramExpSchemaCustomBounds
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
return InvalidSchemaError(h.Schema)
|
return InvalidSchemaError(h.Schema)
|
||||||
}
|
}
|
||||||
|
if h.Count < 0 {
|
||||||
|
return fmt.Errorf("observation count is %v: %w", h.Count, ErrHistogramNegativeCount)
|
||||||
|
}
|
||||||
err := checkHistogramBuckets(h.PositiveBuckets, &pCount, false)
|
err := checkHistogramBuckets(h.PositiveBuckets, &pCount, false)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("positive side: %w", err)
|
return fmt.Errorf("positive side: %w", err)
|
||||||
|
|
|
@ -3527,6 +3527,100 @@ func TestFloatHistogramString(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestFloatHistogramValidateNegativeHistogram(t *testing.T) {
|
||||||
|
cases := []struct {
|
||||||
|
name string
|
||||||
|
fh *FloatHistogram
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
"positive bucket with negative population",
|
||||||
|
&FloatHistogram{
|
||||||
|
Schema: 1,
|
||||||
|
ZeroThreshold: 0.01,
|
||||||
|
ZeroCount: 5.5,
|
||||||
|
Count: 3493.3,
|
||||||
|
Sum: 2349209.324,
|
||||||
|
PositiveSpans: []Span{
|
||||||
|
{-2, 1},
|
||||||
|
{2, 3},
|
||||||
|
},
|
||||||
|
PositiveBuckets: []float64{1, 3.3, -4.2, 0.1},
|
||||||
|
NegativeSpans: []Span{
|
||||||
|
{3, 2},
|
||||||
|
{3, 2},
|
||||||
|
},
|
||||||
|
NegativeBuckets: []float64{3.1, 3, 1.234e5, 1000},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"negative bucket with negative population",
|
||||||
|
&FloatHistogram{
|
||||||
|
Schema: 1,
|
||||||
|
ZeroThreshold: 0.01,
|
||||||
|
ZeroCount: 5.5,
|
||||||
|
Count: 3493.3,
|
||||||
|
Sum: 2349209.324,
|
||||||
|
PositiveSpans: []Span{
|
||||||
|
{-2, 1},
|
||||||
|
{2, 3},
|
||||||
|
},
|
||||||
|
PositiveBuckets: []float64{1, 3.3, 4.2, 0.1},
|
||||||
|
NegativeSpans: []Span{
|
||||||
|
{3, 2},
|
||||||
|
{3, 2},
|
||||||
|
},
|
||||||
|
NegativeBuckets: []float64{3.1, -3, 1.234e5, 1000},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"negative count",
|
||||||
|
&FloatHistogram{
|
||||||
|
Schema: 1,
|
||||||
|
ZeroThreshold: 0.01,
|
||||||
|
ZeroCount: 5.5,
|
||||||
|
Count: -3493.3,
|
||||||
|
Sum: 2349209.324,
|
||||||
|
PositiveSpans: []Span{
|
||||||
|
{-2, 1},
|
||||||
|
{2, 3},
|
||||||
|
},
|
||||||
|
PositiveBuckets: []float64{1, 3.3, 4.2, 0.1},
|
||||||
|
NegativeSpans: []Span{
|
||||||
|
{3, 2},
|
||||||
|
{3, 2},
|
||||||
|
},
|
||||||
|
NegativeBuckets: []float64{3.1, 3, 1.234e5, 1000},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"zero bucket with negative population",
|
||||||
|
&FloatHistogram{
|
||||||
|
Schema: 1,
|
||||||
|
ZeroThreshold: 0.01,
|
||||||
|
ZeroCount: -5.5,
|
||||||
|
Count: 3493.3,
|
||||||
|
Sum: 2349209.324,
|
||||||
|
PositiveSpans: []Span{
|
||||||
|
{-2, 1},
|
||||||
|
{2, 3},
|
||||||
|
},
|
||||||
|
PositiveBuckets: []float64{1, 3.3, 4.2, 0.1},
|
||||||
|
NegativeSpans: []Span{
|
||||||
|
{3, 2},
|
||||||
|
{3, 2},
|
||||||
|
},
|
||||||
|
NegativeBuckets: []float64{3.1, 3, 1.234e5, 1000},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, c := range cases {
|
||||||
|
t.Run(c.name, func(t *testing.T) {
|
||||||
|
require.Error(t, c.fh.Validate())
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func BenchmarkFloatHistogramAllBucketIterator(b *testing.B) {
|
func BenchmarkFloatHistogramAllBucketIterator(b *testing.B) {
|
||||||
rng := rand.New(rand.NewSource(0))
|
rng := rand.New(rand.NewSource(0))
|
||||||
|
|
||||||
|
|
|
@ -31,6 +31,7 @@ const (
|
||||||
var (
|
var (
|
||||||
ErrHistogramCountNotBigEnough = errors.New("histogram's observation count should be at least the number of observations found in the buckets")
|
ErrHistogramCountNotBigEnough = errors.New("histogram's observation count should be at least the number of observations found in the buckets")
|
||||||
ErrHistogramCountMismatch = errors.New("histogram's observation count should equal the number of observations found in the buckets (in absence of NaN)")
|
ErrHistogramCountMismatch = errors.New("histogram's observation count should equal the number of observations found in the buckets (in absence of NaN)")
|
||||||
|
ErrHistogramNegativeCount = errors.New("histogram's observation count is negative")
|
||||||
ErrHistogramNegativeBucketCount = errors.New("histogram has a bucket whose observation count is negative")
|
ErrHistogramNegativeBucketCount = errors.New("histogram has a bucket whose observation count is negative")
|
||||||
ErrHistogramSpanNegativeOffset = errors.New("histogram has a span whose offset is negative")
|
ErrHistogramSpanNegativeOffset = errors.New("histogram has a span whose offset is negative")
|
||||||
ErrHistogramSpansBucketsMismatch = errors.New("histogram spans specify different number of buckets than provided")
|
ErrHistogramSpansBucketsMismatch = errors.New("histogram spans specify different number of buckets than provided")
|
||||||
|
|
|
@ -122,6 +122,7 @@ func isHistogramValidationError(err error) bool {
|
||||||
// TODO: Consider adding single histogram error type instead of individual sentinel errors.
|
// TODO: Consider adding single histogram error type instead of individual sentinel errors.
|
||||||
return errors.Is(err, histogram.ErrHistogramCountMismatch) ||
|
return errors.Is(err, histogram.ErrHistogramCountMismatch) ||
|
||||||
errors.Is(err, histogram.ErrHistogramCountNotBigEnough) ||
|
errors.Is(err, histogram.ErrHistogramCountNotBigEnough) ||
|
||||||
|
errors.Is(err, histogram.ErrHistogramNegativeCount) ||
|
||||||
errors.Is(err, histogram.ErrHistogramNegativeBucketCount) ||
|
errors.Is(err, histogram.ErrHistogramNegativeBucketCount) ||
|
||||||
errors.Is(err, histogram.ErrHistogramSpanNegativeOffset) ||
|
errors.Is(err, histogram.ErrHistogramSpanNegativeOffset) ||
|
||||||
errors.Is(err, histogram.ErrHistogramSpansBucketsMismatch) ||
|
errors.Is(err, histogram.ErrHistogramSpansBucketsMismatch) ||
|
||||||
|
|
Loading…
Reference in New Issue