@@ -61,18 +61,15 @@ type StateChangeListenerMock struct {
61
61
}
62
62
63
63
func (s * StateChangeListenerMock ) OnTransformToClosed (prev State , rule Rule ) {
64
- _ = s .Called (prev , rule )
65
64
logging .Debug ("transform to closed" , "strategy" , rule .Strategy , "prevState" , prev .String ())
66
65
return
67
66
}
68
67
69
68
func (s * StateChangeListenerMock ) OnTransformToOpen (prev State , rule Rule , snapshot interface {}) {
70
- _ = s .Called (prev , rule , snapshot )
71
69
logging .Debug ("transform to open" , "strategy" , rule .Strategy , "prevState" , prev .String (), "snapshot" , snapshot )
72
70
}
73
71
74
72
func (s * StateChangeListenerMock ) OnTransformToHalfOpen (prev State , rule Rule ) {
75
- _ = s .Called (prev , rule )
76
73
logging .Debug ("transform to Half-Open" , "strategy" , rule .Strategy , "prevState" , prev .String ())
77
74
}
78
75
@@ -140,6 +137,35 @@ func TestSlowRtCircuitBreaker_TryPass(t *testing.T) {
140
137
assert .True (t , pass )
141
138
assert .True (t , b .state .get () == HalfOpen )
142
139
})
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
+ })
143
169
}
144
170
145
171
func TestSlowRt_OnRequestComplete (t * testing.T ) {
@@ -169,6 +195,20 @@ func TestSlowRt_OnRequestComplete(t *testing.T) {
169
195
b .OnRequestComplete (10 , nil )
170
196
assert .True (t , b .CurrentState () == Closed )
171
197
})
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
+ })
172
212
}
173
213
174
214
func TestSlowRt_ResetBucketTo (t * testing.T ) {
@@ -227,6 +267,33 @@ func TestErrorRatioCircuitBreaker_TryPass(t *testing.T) {
227
267
assert .True (t , pass )
228
268
assert .True (t , b .state .get () == HalfOpen )
229
269
})
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
+ })
230
297
}
231
298
232
299
func TestErrorRatio_OnRequestComplete (t * testing.T ) {
@@ -254,6 +321,20 @@ func TestErrorRatio_OnRequestComplete(t *testing.T) {
254
321
b .OnRequestComplete (0 , errors .New ("errorRatio" ))
255
322
assert .True (t , b .CurrentState () == Open )
256
323
})
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
+ })
257
338
}
258
339
259
340
func TestErrorRatio_ResetBucketTo (t * testing.T ) {
@@ -312,6 +393,34 @@ func TestErrorCountCircuitBreaker_TryPass(t *testing.T) {
312
393
assert .True (t , pass )
313
394
assert .True (t , b .state .get () == HalfOpen )
314
395
})
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
+ })
315
424
}
316
425
317
426
func TestErrorCount_OnRequestComplete (t * testing.T ) {
@@ -339,6 +448,20 @@ func TestErrorCount_OnRequestComplete(t *testing.T) {
339
448
b .OnRequestComplete (0 , errors .New ("errorCount" ))
340
449
assert .True (t , b .CurrentState () == Open )
341
450
})
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
+ })
342
465
}
343
466
344
467
func TestFromClosedToOpen (t * testing.T ) {
0 commit comments