github.com/lingyao2333/mo-zero@v1.4.1/core/breaker/breaker_test.go (about) 1 package breaker 2 3 import ( 4 "errors" 5 "fmt" 6 "strconv" 7 "strings" 8 "testing" 9 10 "github.com/lingyao2333/mo-zero/core/stat" 11 "github.com/stretchr/testify/assert" 12 ) 13 14 func init() { 15 stat.SetReporter(nil) 16 } 17 18 func TestCircuitBreaker_Allow(t *testing.T) { 19 b := NewBreaker() 20 assert.True(t, len(b.Name()) > 0) 21 _, err := b.Allow() 22 assert.Nil(t, err) 23 } 24 25 func TestLogReason(t *testing.T) { 26 b := NewBreaker() 27 assert.True(t, len(b.Name()) > 0) 28 29 for i := 0; i < 1000; i++ { 30 _ = b.Do(func() error { 31 return errors.New(strconv.Itoa(i)) 32 }) 33 } 34 errs := b.(*circuitBreaker).throttle.(loggedThrottle).errWin 35 assert.Equal(t, numHistoryReasons, errs.count) 36 } 37 38 func TestErrorWindow(t *testing.T) { 39 tests := []struct { 40 name string 41 reasons []string 42 }{ 43 { 44 name: "no error", 45 }, 46 { 47 name: "one error", 48 reasons: []string{"foo"}, 49 }, 50 { 51 name: "two errors", 52 reasons: []string{"foo", "bar"}, 53 }, 54 { 55 name: "five errors", 56 reasons: []string{"first", "second", "third", "fourth", "fifth"}, 57 }, 58 { 59 name: "six errors", 60 reasons: []string{"first", "second", "third", "fourth", "fifth", "sixth"}, 61 }, 62 } 63 64 for _, test := range tests { 65 t.Run(test.name, func(t *testing.T) { 66 var ew errorWindow 67 for _, reason := range test.reasons { 68 ew.add(reason) 69 } 70 var reasons []string 71 if len(test.reasons) > numHistoryReasons { 72 reasons = test.reasons[len(test.reasons)-numHistoryReasons:] 73 } else { 74 reasons = test.reasons 75 } 76 for _, reason := range reasons { 77 assert.True(t, strings.Contains(ew.String(), reason), fmt.Sprintf("actual: %s", ew.String())) 78 } 79 }) 80 } 81 } 82 83 func TestPromiseWithReason(t *testing.T) { 84 tests := []struct { 85 name string 86 reason string 87 expect string 88 }{ 89 { 90 name: "success", 91 }, 92 { 93 name: "success", 94 reason: "fail", 95 expect: "fail", 96 }, 97 } 98 99 for _, test := range tests { 100 t.Run(test.name, func(t *testing.T) { 101 promise := promiseWithReason{ 102 promise: new(mockedPromise), 103 errWin: new(errorWindow), 104 } 105 if len(test.reason) == 0 { 106 promise.Accept() 107 } else { 108 promise.Reject(test.reason) 109 } 110 111 assert.True(t, strings.Contains(promise.errWin.String(), test.expect)) 112 }) 113 } 114 } 115 116 func BenchmarkGoogleBreaker(b *testing.B) { 117 br := NewBreaker() 118 for i := 0; i < b.N; i++ { 119 _ = br.Do(func() error { 120 return nil 121 }) 122 } 123 } 124 125 type mockedPromise struct{} 126 127 func (m *mockedPromise) Accept() { 128 } 129 130 func (m *mockedPromise) Reject() { 131 }