github.com/alibaba/sentinel-golang@v1.0.4/core/stat/base/sliding_window_metric_test.go (about) 1 // Copyright 1999-2020 Alibaba Group Holding Ltd. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package base 16 17 import ( 18 "testing" 19 20 "github.com/alibaba/sentinel-golang/core/base" 21 "github.com/alibaba/sentinel-golang/util" 22 "github.com/stretchr/testify/assert" 23 ) 24 25 func TestSlidingWindowMetric_getBucketStartRange(t *testing.T) { 26 type args struct { 27 sampleCount uint32 28 intervalInMs uint32 29 realSampleCount uint32 30 realIntervalInMs uint32 31 now uint64 32 } 33 tests := []struct { 34 name string 35 args args 36 wantStart uint64 37 wantEnd uint64 38 }{ 39 { 40 name: "TestSlidingWindowMetric_getBucketStartRange-1", 41 args: args{ 42 sampleCount: 4, 43 intervalInMs: 2000, 44 realSampleCount: 20, 45 realIntervalInMs: 10000, 46 // array start time:1578416550000 47 // bucket start time:1578416556500 48 now: 1578416556900, // 49 }, 50 wantStart: 1578416555000, 51 wantEnd: 1578416556500, 52 }, 53 { 54 name: "TestSlidingWindowMetric_getBucketStartRange-2", 55 args: args{ 56 sampleCount: 2, 57 intervalInMs: 1000, 58 realSampleCount: 20, 59 realIntervalInMs: 10000, 60 // array start time:1578416550000 61 // bucket start time:1578416556500 62 now: 1578416556900, // 63 }, 64 wantStart: 1578416556000, 65 wantEnd: 1578416556500, 66 }, 67 { 68 name: "TestSlidingWindowMetric_getBucketStartRange-3", 69 args: args{ 70 sampleCount: 1, 71 intervalInMs: 2000, 72 realSampleCount: 10, 73 realIntervalInMs: 10000, 74 // array start time:1578416550000 75 // bucket start time:1578416556500 76 now: 1578416556900, // 77 }, 78 wantStart: 1578416555000, 79 wantEnd: 1578416556000, 80 }, 81 { 82 name: "TestSlidingWindowMetric_getBucketStartRange-4", 83 args: args{ 84 sampleCount: 1, 85 intervalInMs: 10000, 86 realSampleCount: 10, 87 realIntervalInMs: 20000, 88 // array start time:1578416550000 89 // bucket start time:1578416556500 90 now: 1578416556900, // 91 }, 92 wantStart: 1578416548000, 93 wantEnd: 1578416556000, 94 }, 95 { 96 name: "TestSlidingWindowMetric_getBucketStartRange-5", 97 args: args{ 98 sampleCount: 2, 99 intervalInMs: 1000, 100 realSampleCount: 20, 101 realIntervalInMs: 10000, 102 // array start time:1578416550000 103 // bucket start time:1578416556500 104 now: 1578416556500, // 105 }, 106 wantStart: 1578416556000, 107 wantEnd: 1578416556500, 108 }, 109 } 110 for _, tt := range tests { 111 t.Run(tt.name, func(t *testing.T) { 112 m, err := NewSlidingWindowMetric(tt.args.sampleCount, tt.args.intervalInMs, NewBucketLeapArray(tt.args.realSampleCount, tt.args.realIntervalInMs)) 113 assert.True(t, err == nil) 114 115 gotStart, gotEnd := m.getBucketStartRange(tt.args.now) 116 if gotStart != tt.wantStart { 117 t.Errorf("SlidingWindowMetric.getBucketStartRange() gotStart = %v, want %v", gotStart, tt.wantStart) 118 } 119 if gotEnd != tt.wantEnd { 120 t.Errorf("SlidingWindowMetric.getBucketStartRange() gotEnd = %v, want %v", gotEnd, tt.wantEnd) 121 } 122 }) 123 } 124 } 125 126 func Test_NewSlidingWindowMetric(t *testing.T) { 127 got, err := NewSlidingWindowMetric(4, 2000, NewBucketLeapArray(SampleCount, IntervalInMs)) 128 assert.True(t, err == nil && got != nil) 129 got, err = NewSlidingWindowMetric(0, 0, NewBucketLeapArray(SampleCount, IntervalInMs)) 130 assert.True(t, got == nil && err != nil) 131 got, err = NewSlidingWindowMetric(4, 2001, NewBucketLeapArray(SampleCount, IntervalInMs)) 132 assert.True(t, got == nil && err != nil) 133 got, err = NewSlidingWindowMetric(2, 2002, NewBucketLeapArray(SampleCount, IntervalInMs)) 134 assert.True(t, got == nil && err != nil) 135 got, err = NewSlidingWindowMetric(4, 200000, NewBucketLeapArray(SampleCount, IntervalInMs)) 136 assert.True(t, got == nil && err != nil) 137 } 138 139 func TestSlidingWindowMetric_GetIntervalSumWithTime(t *testing.T) { 140 type fields struct { 141 sampleCount uint32 142 intervalInMs uint32 143 real *BucketLeapArray 144 } 145 type args struct { 146 event base.MetricEvent 147 now uint64 148 } 149 tests := []struct { 150 name string 151 fields fields 152 args args 153 want int64 154 }{ 155 { 156 name: "", 157 fields: fields{ 158 sampleCount: 2, 159 intervalInMs: 2000, 160 real: NewBucketLeapArray(SampleCount, IntervalInMs), 161 }, 162 args: args{ 163 event: base.MetricEventPass, 164 now: 1678416556599, 165 }, 166 want: 2000, 167 }, 168 } 169 for _, tt := range tests { 170 t.Run(tt.name, func(t *testing.T) { 171 for i := 0; i < 500; i++ { 172 tt.fields.real.addCountWithTime(tt.args.now, tt.args.event, 1) 173 } 174 for i := 0; i < int(tt.fields.intervalInMs); i++ { 175 tt.fields.real.addCountWithTime(tt.args.now-100-uint64(i), tt.args.event, 1) 176 } 177 m, _ := NewSlidingWindowMetric(tt.fields.sampleCount, tt.fields.intervalInMs, tt.fields.real) 178 if got := m.getSumWithTime(tt.args.now, tt.args.event); got != tt.want { 179 t.Errorf("SlidingWindowMetric.getSumWithTime() = %v, want %v", got, tt.want) 180 } 181 }) 182 } 183 } 184 185 func TestGetSum(t *testing.T) { 186 got, err := NewSlidingWindowMetric(4, 2000, NewBucketLeapArray(SampleCount, IntervalInMs)) 187 assert.True(t, err == nil && got != nil) 188 passSum := got.GetSum(base.MetricEventPass) 189 assert.True(t, passSum == 0) 190 } 191 192 func TestGetQPS(t *testing.T) { 193 got, err := NewSlidingWindowMetric(4, 2000, NewBucketLeapArray(SampleCount, IntervalInMs)) 194 assert.True(t, err == nil && got != nil) 195 qps := got.GetQPS(base.MetricEventPass) 196 assert.True(t, util.Float64Equals(qps, 0.0)) 197 } 198 199 func TestGetPreviousQPS(t *testing.T) { 200 got, err := NewSlidingWindowMetric(4, 2000, NewBucketLeapArray(SampleCount, IntervalInMs)) 201 assert.True(t, err == nil && got != nil) 202 previousQPS := got.GetPreviousQPS(base.MetricEventPass) 203 assert.True(t, util.Float64Equals(previousQPS, 0.0)) 204 } 205 206 func TestGetQPSWithTime(t *testing.T) { 207 got, err := NewSlidingWindowMetric(4, 2000, NewBucketLeapArray(SampleCount, IntervalInMs)) 208 assert.True(t, err == nil && got != nil) 209 qps := got.getQPSWithTime(util.CurrentTimeMillis(), base.MetricEventPass) 210 assert.True(t, util.Float64Equals(qps, 0.0)) 211 } 212 213 func TestGetMaxOfSingleBucket(t *testing.T) { 214 got, err := NewSlidingWindowMetric(4, 2000, NewBucketLeapArray(SampleCount, IntervalInMs)) 215 assert.True(t, err == nil && got != nil) 216 got.real.AddCount(base.MetricEventPass, 100) 217 max := got.GetMaxOfSingleBucket(base.MetricEventPass) 218 assert.True(t, max == 100) 219 } 220 221 func TestMinRT(t *testing.T) { 222 got, err := NewSlidingWindowMetric(4, 2000, NewBucketLeapArray(SampleCount, IntervalInMs)) 223 assert.True(t, err == nil && got != nil) 224 minRt := got.MinRT() 225 assert.True(t, util.Float64Equals(minRt, float64(base.DefaultStatisticMaxRt))) 226 } 227 228 func TestMaxConcurrency(t *testing.T) { 229 got, err := NewSlidingWindowMetric(4, 2000, NewBucketLeapArray(SampleCount, IntervalInMs)) 230 assert.True(t, err == nil && got != nil) 231 got.real.UpdateConcurrency(1) 232 got.real.UpdateConcurrency(3) 233 got.real.UpdateConcurrency(2) 234 mc := got.MaxConcurrency() 235 assert.True(t, mc == int32(3)) 236 } 237 238 func TestAvgRT(t *testing.T) { 239 got, err := NewSlidingWindowMetric(4, 2000, NewBucketLeapArray(SampleCount, IntervalInMs)) 240 assert.True(t, err == nil && got != nil) 241 got.real.AddCount(base.MetricEventRt, 100) 242 got.real.AddCount(base.MetricEventComplete, 100) 243 avgRT := got.AvgRT() 244 assert.True(t, util.Float64Equals(avgRT, 1.0)) 245 } 246 247 func TestMetricItemFromBuckets(t *testing.T) { 248 got, err := NewSlidingWindowMetric(4, 2000, NewBucketLeapArray(SampleCount, IntervalInMs)) 249 assert.True(t, err == nil && got != nil) 250 got.real.AddCount(base.MetricEventPass, 100) 251 item := got.metricItemFromBuckets(util.CurrentTimeMillis(), got.real.data.array.data) 252 assert.True(t, item.PassQps == 100) 253 } 254 255 func TestMetricItemFromBucket(t *testing.T) { 256 mb := NewMetricBucket() 257 mb.addCount(base.MetricEventPass, 100) 258 wrap := &BucketWrap{} 259 wrap.Value.Store(mb) 260 got := &SlidingWindowMetric{} 261 item := got.metricItemFromBucket(wrap) 262 assert.True(t, item.PassQps == 100) 263 } 264 265 func TestSecondMetricsOnCondition(t *testing.T) { 266 got, err := NewSlidingWindowMetric(4, 2000, NewBucketLeapArray(SampleCount, IntervalInMs)) 267 assert.True(t, err == nil && got != nil) 268 start, end := got.getBucketStartRange(util.CurrentTimeMillis()) 269 items := got.SecondMetricsOnCondition(func(ws uint64) bool { 270 return ws >= start && ws <= end 271 }) 272 assert.True(t, len(items) == 1) 273 }