mirror of
				https://github.com/prometheus/prometheus.git
				synced 2025-11-04 02:11:01 +01:00 
			
		
		
		
	Merge pull request #17248 from prometheus/beorn7/histogram
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 {
 | 
			
		||||
			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 {
 | 
			
		||||
			return ErrHistogramExpSchemaCustomBounds
 | 
			
		||||
		}
 | 
			
		||||
	default:
 | 
			
		||||
		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)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		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) {
 | 
			
		||||
	rng := rand.New(rand.NewSource(0))
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -31,6 +31,7 @@ const (
 | 
			
		||||
var (
 | 
			
		||||
	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)")
 | 
			
		||||
	ErrHistogramNegativeCount           = errors.New("histogram's 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")
 | 
			
		||||
	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.
 | 
			
		||||
	return errors.Is(err, histogram.ErrHistogramCountMismatch) ||
 | 
			
		||||
		errors.Is(err, histogram.ErrHistogramCountNotBigEnough) ||
 | 
			
		||||
		errors.Is(err, histogram.ErrHistogramNegativeCount) ||
 | 
			
		||||
		errors.Is(err, histogram.ErrHistogramNegativeBucketCount) ||
 | 
			
		||||
		errors.Is(err, histogram.ErrHistogramSpanNegativeOffset) ||
 | 
			
		||||
		errors.Is(err, histogram.ErrHistogramSpansBucketsMismatch) ||
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user