github.com/jimmyx0x/go-ethereum@v1.10.28/metrics/runtimehistogram_test.go (about) 1 package metrics 2 3 import ( 4 "fmt" 5 "math" 6 "reflect" 7 "runtime/metrics" 8 "testing" 9 ) 10 11 var _ Histogram = (*runtimeHistogram)(nil) 12 13 type runtimeHistogramTest struct { 14 h metrics.Float64Histogram 15 16 Count int64 17 Min int64 18 Max int64 19 Sum int64 20 Mean float64 21 Variance float64 22 StdDev float64 23 Percentiles []float64 // .5 .8 .9 .99 .995 24 } 25 26 // This test checks the results of statistical functions implemented 27 // by runtimeHistogramSnapshot. 28 func TestRuntimeHistogramStats(t *testing.T) { 29 tests := []runtimeHistogramTest{ 30 0: { 31 h: metrics.Float64Histogram{ 32 Counts: []uint64{}, 33 Buckets: []float64{}, 34 }, 35 Count: 0, 36 Max: 0, 37 Min: 0, 38 Sum: 0, 39 Mean: 0, 40 Variance: 0, 41 StdDev: 0, 42 Percentiles: []float64{0, 0, 0, 0, 0}, 43 }, 44 1: { 45 // This checks the case where the highest bucket is +Inf. 46 h: metrics.Float64Histogram{ 47 Counts: []uint64{0, 1, 2}, 48 Buckets: []float64{0, 0.5, 1, math.Inf(1)}, 49 }, 50 Count: 3, 51 Max: 1, 52 Min: 0, 53 Sum: 3, 54 Mean: 0.9166666, 55 Percentiles: []float64{1, 1, 1, 1, 1}, 56 Variance: 0.020833, 57 StdDev: 0.144433, 58 }, 59 2: { 60 h: metrics.Float64Histogram{ 61 Counts: []uint64{8, 6, 3, 1}, 62 Buckets: []float64{12, 16, 18, 24, 25}, 63 }, 64 Count: 18, 65 Max: 25, 66 Min: 12, 67 Sum: 270, 68 Mean: 16.75, 69 Variance: 10.3015, 70 StdDev: 3.2096, 71 Percentiles: []float64{16, 18, 18, 24, 24}, 72 }, 73 } 74 75 for i, test := range tests { 76 t.Run(fmt.Sprint(i), func(t *testing.T) { 77 s := runtimeHistogramSnapshot(test.h) 78 79 if v := s.Count(); v != test.Count { 80 t.Errorf("Count() = %v, want %v", v, test.Count) 81 } 82 if v := s.Min(); v != test.Min { 83 t.Errorf("Min() = %v, want %v", v, test.Min) 84 } 85 if v := s.Max(); v != test.Max { 86 t.Errorf("Max() = %v, want %v", v, test.Max) 87 } 88 if v := s.Sum(); v != test.Sum { 89 t.Errorf("Sum() = %v, want %v", v, test.Sum) 90 } 91 if v := s.Mean(); !approxEqual(v, test.Mean, 0.0001) { 92 t.Errorf("Mean() = %v, want %v", v, test.Mean) 93 } 94 if v := s.Variance(); !approxEqual(v, test.Variance, 0.0001) { 95 t.Errorf("Variance() = %v, want %v", v, test.Variance) 96 } 97 if v := s.StdDev(); !approxEqual(v, test.StdDev, 0.0001) { 98 t.Errorf("StdDev() = %v, want %v", v, test.StdDev) 99 } 100 ps := []float64{.5, .8, .9, .99, .995} 101 if v := s.Percentiles(ps); !reflect.DeepEqual(v, test.Percentiles) { 102 t.Errorf("Percentiles(%v) = %v, want %v", ps, v, test.Percentiles) 103 } 104 }) 105 } 106 } 107 108 func approxEqual(x, y, ε float64) bool { 109 if math.IsInf(x, -1) && math.IsInf(y, -1) { 110 return true 111 } 112 if math.IsInf(x, 1) && math.IsInf(y, 1) { 113 return true 114 } 115 if math.IsNaN(x) && math.IsNaN(y) { 116 return true 117 } 118 return math.Abs(x-y) < ε 119 } 120 121 // This test verifies that requesting Percentiles in unsorted order 122 // returns them in the requested order. 123 func TestRuntimeHistogramStatsPercentileOrder(t *testing.T) { 124 p := runtimeHistogramSnapshot{ 125 Counts: []uint64{1, 1, 1, 1, 1, 1, 1, 1, 1, 1}, 126 Buckets: []float64{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10}, 127 } 128 result := p.Percentiles([]float64{1, 0.2, 0.5, 0.1, 0.2}) 129 expected := []float64{10, 2, 5, 1, 2} 130 if !reflect.DeepEqual(result, expected) { 131 t.Fatal("wrong result:", result) 132 } 133 }