@@ -61,18 +61,15 @@ type StateChangeListenerMock struct {
6161}
6262
6363func (s * StateChangeListenerMock ) OnTransformToClosed (prev State , rule Rule ) {
64- _ = s .Called (prev , rule )
6564 logging .Debug ("transform to closed" , "strategy" , rule .Strategy , "prevState" , prev .String ())
6665 return
6766}
6867
6968func (s * StateChangeListenerMock ) OnTransformToOpen (prev State , rule Rule , snapshot interface {}) {
70- _ = s .Called (prev , rule , snapshot )
7169 logging .Debug ("transform to open" , "strategy" , rule .Strategy , "prevState" , prev .String (), "snapshot" , snapshot )
7270}
7371
7472func (s * StateChangeListenerMock ) OnTransformToHalfOpen (prev State , rule Rule ) {
75- _ = s .Called (prev , rule )
7673 logging .Debug ("transform to Half-Open" , "strategy" , rule .Strategy , "prevState" , prev .String ())
7774}
7875
@@ -140,6 +137,35 @@ func TestSlowRtCircuitBreaker_TryPass(t *testing.T) {
140137 assert .True (t , pass )
141138 assert .True (t , b .state .get () == HalfOpen )
142139 })
140+
141+ t .Run ("TryPass_ProbeNum" , func (t * testing.T ) {
142+ r := & Rule {
143+ Resource : "abc" ,
144+ Strategy : SlowRequestRatio ,
145+ RetryTimeoutMs : 3000 ,
146+ MinRequestAmount : 10 ,
147+ StatIntervalMs : 10000 ,
148+ MaxAllowedRtMs : 50 ,
149+ Threshold : 0.5 ,
150+ ProbeNum : 10 ,
151+ }
152+ b , err := newSlowRtCircuitBreaker (r )
153+ assert .Nil (t , err )
154+
155+ b .state .set (Open )
156+ ctx := & base.EntryContext {
157+ Resource : base .NewResourceWrapper ("abc" , base .ResTypeCommon , base .Inbound ),
158+ }
159+ e := base .NewSentinelEntry (ctx , base .NewResourceWrapper ("abc" , base .ResTypeCommon , base .Inbound ), nil )
160+ ctx .SetEntry (e )
161+ for i := 0 ; i < 10 ; i ++ {
162+ pass := b .TryPass (ctx )
163+ assert .True (t , pass )
164+ assert .True (t , b .state .get () == HalfOpen )
165+ b .OnRequestComplete (1 , nil )
166+ }
167+ assert .True (t , b .state .get () == Closed )
168+ })
143169}
144170
145171func TestSlowRt_OnRequestComplete (t * testing.T ) {
@@ -169,6 +195,20 @@ func TestSlowRt_OnRequestComplete(t *testing.T) {
169195 b .OnRequestComplete (10 , nil )
170196 assert .True (t , b .CurrentState () == Closed )
171197 })
198+ t .Run ("OnRequestComplete_ProbeNum_Success" , func (t * testing.T ) {
199+ b .probeNumber = 2
200+ b .state .set (HalfOpen )
201+ b .OnRequestComplete (10 , nil )
202+ assert .True (t , b .CurrentState () == HalfOpen )
203+ assert .True (t , b .curProbeNumber == 1 )
204+ })
205+ t .Run ("OnRequestComplete_ProbeNum_Failed" , func (t * testing.T ) {
206+ b .probeNumber = 2
207+ b .state .set (HalfOpen )
208+ b .OnRequestComplete (base .NewEmptyEntryContext ().Rt (), nil )
209+ assert .True (t , b .CurrentState () == Open )
210+ assert .True (t , b .curProbeNumber == 0 )
211+ })
172212}
173213
174214func TestSlowRt_ResetBucketTo (t * testing.T ) {
@@ -227,6 +267,33 @@ func TestErrorRatioCircuitBreaker_TryPass(t *testing.T) {
227267 assert .True (t , pass )
228268 assert .True (t , b .state .get () == HalfOpen )
229269 })
270+ t .Run ("TryPass_ProbeNum" , func (t * testing.T ) {
271+ r := & Rule {
272+ Resource : "abc" ,
273+ Strategy : ErrorRatio ,
274+ RetryTimeoutMs : 3000 ,
275+ MinRequestAmount : 10 ,
276+ StatIntervalMs : 10000 ,
277+ Threshold : 0.5 ,
278+ ProbeNum : 10 ,
279+ }
280+ b , err := newErrorRatioCircuitBreaker (r )
281+ assert .Nil (t , err )
282+
283+ b .state .set (Open )
284+ ctx := & base.EntryContext {
285+ Resource : base .NewResourceWrapper ("abc" , base .ResTypeCommon , base .Inbound ),
286+ }
287+ e := base .NewSentinelEntry (ctx , base .NewResourceWrapper ("abc" , base .ResTypeCommon , base .Inbound ), nil )
288+ ctx .SetEntry (e )
289+ for i := 0 ; i < 10 ; i ++ {
290+ pass := b .TryPass (ctx )
291+ assert .True (t , pass )
292+ assert .True (t , b .state .get () == HalfOpen )
293+ b .OnRequestComplete (1 , nil )
294+ }
295+ assert .True (t , b .state .get () == Closed )
296+ })
230297}
231298
232299func TestErrorRatio_OnRequestComplete (t * testing.T ) {
@@ -254,6 +321,20 @@ func TestErrorRatio_OnRequestComplete(t *testing.T) {
254321 b .OnRequestComplete (0 , errors .New ("errorRatio" ))
255322 assert .True (t , b .CurrentState () == Open )
256323 })
324+ t .Run ("OnRequestComplete_ProbeNum_Success" , func (t * testing.T ) {
325+ b .probeNumber = 2
326+ b .state .set (HalfOpen )
327+ b .OnRequestComplete (base .NewEmptyEntryContext ().Rt (), nil )
328+ assert .True (t , b .CurrentState () == HalfOpen )
329+ assert .True (t , b .curProbeNumber == 1 )
330+ })
331+ t .Run ("OnRequestComplete_ProbeNum_Failed" , func (t * testing.T ) {
332+ b .probeNumber = 2
333+ b .state .set (HalfOpen )
334+ b .OnRequestComplete (0 , errors .New ("errorRatio" ))
335+ assert .True (t , b .CurrentState () == Open )
336+ assert .True (t , b .curProbeNumber == 0 )
337+ })
257338}
258339
259340func TestErrorRatio_ResetBucketTo (t * testing.T ) {
@@ -312,6 +393,34 @@ func TestErrorCountCircuitBreaker_TryPass(t *testing.T) {
312393 assert .True (t , pass )
313394 assert .True (t , b .state .get () == HalfOpen )
314395 })
396+
397+ t .Run ("TryPass_ProbeNum" , func (t * testing.T ) {
398+ r := & Rule {
399+ Resource : "abc" ,
400+ Strategy : ErrorCount ,
401+ RetryTimeoutMs : 3000 ,
402+ MinRequestAmount : 10 ,
403+ StatIntervalMs : 10000 ,
404+ Threshold : 1.0 ,
405+ ProbeNum : 10 ,
406+ }
407+ b , err := newErrorCountCircuitBreaker (r )
408+ assert .Nil (t , err )
409+
410+ b .state .set (Open )
411+ ctx := & base.EntryContext {
412+ Resource : base .NewResourceWrapper ("abc" , base .ResTypeCommon , base .Inbound ),
413+ }
414+ e := base .NewSentinelEntry (ctx , base .NewResourceWrapper ("abc" , base .ResTypeCommon , base .Inbound ), nil )
415+ ctx .SetEntry (e )
416+ for i := 0 ; i < 10 ; i ++ {
417+ pass := b .TryPass (ctx )
418+ assert .True (t , pass )
419+ assert .True (t , b .state .get () == HalfOpen )
420+ b .OnRequestComplete (1 , nil )
421+ }
422+ assert .True (t , b .state .get () == Closed )
423+ })
315424}
316425
317426func TestErrorCount_OnRequestComplete (t * testing.T ) {
@@ -339,6 +448,20 @@ func TestErrorCount_OnRequestComplete(t *testing.T) {
339448 b .OnRequestComplete (0 , errors .New ("errorCount" ))
340449 assert .True (t , b .CurrentState () == Open )
341450 })
451+ t .Run ("OnRequestComplete_ProbeNum_Success" , func (t * testing.T ) {
452+ b .probeNumber = 2
453+ b .state .set (HalfOpen )
454+ b .OnRequestComplete (base .NewEmptyEntryContext ().Rt (), nil )
455+ assert .True (t , b .CurrentState () == HalfOpen )
456+ assert .True (t , b .curProbeNumber == 1 )
457+ })
458+ t .Run ("OnRequestComplete_ProbeNum_Failed" , func (t * testing.T ) {
459+ b .probeNumber = 2
460+ b .state .set (HalfOpen )
461+ b .OnRequestComplete (0 , errors .New ("errorCount" ))
462+ assert .True (t , b .CurrentState () == Open )
463+ assert .True (t , b .curProbeNumber == 0 )
464+ })
342465}
343466
344467func TestFromClosedToOpen (t * testing.T ) {
0 commit comments