github.com/bytedance/gopkg@v0.0.0-20240514070511-01b2cbcf35e1/cloud/circuitbreaker/metricer_test.go (about) 1 // Copyright 2021 ByteDance Inc. 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 circuitbreaker 16 17 import ( 18 "math/rand" 19 "testing" 20 "time" 21 ) 22 23 func BenchmarkBuckets(b *testing.B) { 24 bk := bucket{} 25 bk.Reset() 26 b.ResetTimer() 27 for i := 0; i < b.N; i++ { 28 bk.Fail() 29 bk.Timeout() 30 bk.Succeed() 31 } 32 } 33 34 // TestMetricser1 tests basic functions 35 func TestMetricser1(t *testing.T) { 36 m := newWindow() 37 38 // no data 39 deepEqual(t, m.ErrorRate(), float64(0)) 40 deepEqual(t, m.ConseErrors(), int64(0)) 41 deepEqual(t, m.Successes(), int64(0)) 42 deepEqual(t, m.Failures(), int64(0)) 43 deepEqual(t, m.Timeouts(), int64(0)) 44 45 m.Fail() 46 m.Timeout() 47 m.Fail() 48 m.Timeout() 49 deepEqual(t, m.Failures(), int64(2)) 50 deepEqual(t, m.Timeouts(), int64(2)) 51 deepEqual(t, m.ErrorRate(), float64(1)) 52 deepEqual(t, m.ConseErrors(), int64(4)) 53 deepEqual(t, m.Successes(), int64(0)) 54 55 m.Succeed() 56 deepEqual(t, m.ErrorRate(), float64(.8)) 57 deepEqual(t, m.ConseErrors(), int64(0)) 58 deepEqual(t, m.Successes(), int64(1)) 59 deepEqual(t, m.Failures(), int64(2)) 60 deepEqual(t, m.Timeouts(), int64(2)) 61 62 s, f, tm := m.Counts() 63 deepEqual(t, s, int64(1)) 64 deepEqual(t, f, int64(2)) 65 deepEqual(t, tm, int64(2)) 66 67 tot := 1000000 68 for i := 0; i < tot; i++ { 69 t := rand.Intn(3) 70 if t == 0 { // fail 71 m.Fail() 72 } else if t == 1 { // timeout 73 m.Timeout() 74 } else { // succeed 75 m.Succeed() 76 } 77 } 78 79 rate := m.ErrorRate() 80 assert(t, (rate > .6 && rate < .7)) 81 s = m.Successes() 82 assert(t, (s > int64(tot/3-1000) && s < int64(tot/3+1000))) 83 f = m.Failures() 84 assert(t, (f > int64(tot/3-1000) && f < int64(tot/3+1000))) 85 ts := m.Timeouts() 86 assert(t, (ts > int64(tot/3-1000) && ts < int64(tot/3+1000))) 87 } 88 89 // TestMetricser2 tests functions about time 90 func TestMetricser2(t *testing.T) { 91 p, _ := NewPanel(nil, Options{BucketTime: time.Millisecond * 10, BucketNums: 100}) 92 b := p.(*panel).getBreaker("test") 93 m := b.metricer 94 expire := time.Millisecond * 10 * 100 95 96 m.Succeed() 97 deepEqual(t, m.Successes(), int64(1)) 98 deepEqual(t, m.Failures(), int64(0)) 99 deepEqual(t, m.Timeouts(), int64(0)) 100 101 time.Sleep(expire + time.Millisecond*10) 102 deepEqual(t, m.Successes(), int64(0)) 103 deepEqual(t, m.Failures(), int64(0)) 104 deepEqual(t, m.Timeouts(), int64(0)) 105 106 for i := 0; i < 10; i++ { 107 m.Fail() 108 } 109 deepEqual(t, m.Successes(), int64(0)) 110 deepEqual(t, m.Failures(), int64(10)) 111 deepEqual(t, m.Timeouts(), int64(0)) 112 deepEqual(t, m.ConseErrors(), int64(10)) 113 114 time.Sleep(expire / 2) 115 for i := 0; i < 100; i++ { 116 m.Fail() 117 } 118 deepEqual(t, m.Successes(), int64(0)) 119 deepEqual(t, m.Failures(), int64(110)) 120 deepEqual(t, m.Timeouts(), int64(0)) 121 deepEqual(t, m.ConseErrors(), int64(110)) 122 123 time.Sleep(expire / 2) 124 deepEqual(t, m.Successes(), int64(0)) 125 deepEqual(t, m.Failures(), int64(100)) 126 deepEqual(t, m.Timeouts(), int64(0)) 127 deepEqual(t, m.ConseErrors(), int64(110)) 128 129 time.Sleep(expire / 2) 130 deepEqual(t, m.Successes(), int64(0)) 131 deepEqual(t, m.Failures(), int64(0)) 132 deepEqual(t, m.Timeouts(), int64(0)) 133 deepEqual(t, m.ConseErrors(), int64(110)) 134 135 m.Succeed() 136 deepEqual(t, m.Successes(), int64(1)) 137 deepEqual(t, m.Failures(), int64(0)) 138 deepEqual(t, m.Timeouts(), int64(0)) 139 deepEqual(t, m.ConseErrors(), int64(0)) 140 } 141 142 func BenchmarkWindow(b *testing.B) { 143 m := newWindow() 144 b.ResetTimer() 145 for i := 0; i < b.N; i++ { 146 m.Succeed() 147 } 148 } 149 150 func BenchmarkWindowParallel(b *testing.B) { 151 m := newWindow() 152 b.ResetTimer() 153 b.RunParallel(func(pb *testing.PB) { 154 for pb.Next() { 155 m.Succeed() 156 } 157 }) 158 } 159 160 func BenchmarkWindowParallel2Cores(b *testing.B) { 161 b.SetParallelism(2) 162 m := newWindow() 163 b.ResetTimer() 164 b.RunParallel(func(pb *testing.PB) { 165 for pb.Next() { 166 m.Succeed() 167 } 168 }) 169 }