@@ -125,6 +125,67 @@ func TestBackoffGC(t *testing.T) {
125
125
}
126
126
}
127
127
128
+ func TestAlternateBackoffGC (t * testing.T ) {
129
+ cases := []struct {
130
+ name string
131
+ hasExpiredFunc func (time.Time , time.Time , time.Duration ) bool
132
+ maxDuration time.Duration
133
+ nonExpiredTime time.Duration
134
+ expiredTime time.Duration
135
+ }{
136
+ {
137
+ name : "default GC" ,
138
+ maxDuration : time .Duration (50 * time .Second ),
139
+ nonExpiredTime : time .Duration (5 * time .Second ),
140
+ expiredTime : time .Duration (101 * time .Second ),
141
+ },
142
+ {
143
+ name : "GC later than 2*maxDuration" ,
144
+ hasExpiredFunc : func (eventTime time.Time , lastUpdate time.Time , maxDuration time.Duration ) bool {
145
+ return eventTime .Sub (lastUpdate ) >= 200 * time .Second
146
+ },
147
+ maxDuration : time .Duration (50 * time .Second ),
148
+ nonExpiredTime : time .Duration (101 * time .Second ),
149
+ expiredTime : time .Duration (501 * time .Second ),
150
+ },
151
+ }
152
+
153
+ for _ , tt := range cases {
154
+ clock := testingclock .NewFakeClock (time .Now ())
155
+ base := time .Second
156
+ maxDuration := tt .maxDuration
157
+ id := tt .name
158
+
159
+ b := NewFakeBackOff (base , maxDuration , clock )
160
+ if tt .hasExpiredFunc != nil {
161
+ b .HasExpiredFunc = tt .hasExpiredFunc
162
+ }
163
+
164
+ // initialize backoff
165
+ lastUpdate := clock .Now ()
166
+ b .Next (id , lastUpdate )
167
+
168
+ // increment to a time within GC expiration
169
+ clock .Step (tt .nonExpiredTime )
170
+ b .GC ()
171
+
172
+ // confirm we did not GC this entry
173
+ _ , found := b .perItemBackoff [id ]
174
+ if ! found {
175
+ t .Errorf ("[%s] expected GC to skip entry, elapsed time=%s" , tt .name , clock .Since (lastUpdate ))
176
+ }
177
+
178
+ // increment to a time beyond GC expiration
179
+ clock .Step (tt .expiredTime )
180
+ b .GC ()
181
+ r , found := b .perItemBackoff [id ]
182
+ if found {
183
+ t .Errorf ("[%s] expected GC of entry after %s got entry %v" , tt .name , clock .Since (lastUpdate ), r )
184
+ }
185
+
186
+ }
187
+ }
188
+
128
189
func TestIsInBackOffSinceUpdate (t * testing.T ) {
129
190
id := "_idIsInBackOffSinceUpdate"
130
191
tc := testingclock .NewFakeClock (time .Now ())
@@ -250,3 +311,67 @@ func TestBackoffWithJitter(t *testing.T) {
250
311
251
312
t .Logf ("exponentially backed off jittered delays: %v" , delays )
252
313
}
314
+
315
+ func TestAlternateHasExpiredFunc (t * testing.T ) {
316
+ cases := []struct {
317
+ name string
318
+ hasExpiredFunc func (time.Time , time.Time , time.Duration ) bool
319
+ maxDuration time.Duration
320
+ nonExpiredTime time.Duration
321
+ expiredTime time.Duration
322
+ }{
323
+ {
324
+ name : "default expiration" ,
325
+ maxDuration : time .Duration (50 * time .Second ),
326
+ nonExpiredTime : time .Duration (5 * time .Second ),
327
+ expiredTime : time .Duration (101 * time .Second ),
328
+ },
329
+ {
330
+ name : "expires faster than maxDuration" ,
331
+ hasExpiredFunc : func (eventTime time.Time , lastUpdate time.Time , maxDuration time.Duration ) bool {
332
+ return eventTime .Sub (lastUpdate ) >= 8 * time .Second
333
+ },
334
+ maxDuration : time .Duration (50 * time .Second ),
335
+ nonExpiredTime : time .Duration (5 * time .Second ),
336
+ expiredTime : time .Duration (9 * time .Second ),
337
+ },
338
+ }
339
+
340
+ for _ , tt := range cases {
341
+ clock := testingclock .NewFakeClock (time .Now ())
342
+ base := time .Second
343
+ maxDuration := tt .maxDuration
344
+ id := tt .name
345
+
346
+ b := NewFakeBackOff (base , maxDuration , clock )
347
+
348
+ if tt .hasExpiredFunc != nil {
349
+ b .HasExpiredFunc = tt .hasExpiredFunc
350
+ }
351
+ // initialize backoff
352
+ b .Next (id , clock .Now ())
353
+
354
+ // increment to a time within expiration
355
+ clock .Step (tt .nonExpiredTime )
356
+ b .Next (id , clock .Now ())
357
+
358
+ // confirm we did a backoff
359
+ w := b .Get (id )
360
+ if w < base * 2 {
361
+ t .Errorf ("case %v: backoff object has not incremented like expected: want %s, got %s" , tt .name , base * 2 , w )
362
+ }
363
+
364
+ // increment to a time beyond expiration
365
+ clock .Step (tt .expiredTime )
366
+ b .Next (id , clock .Now ())
367
+
368
+ // confirm we have reset the backoff to base
369
+ w = b .Get (id )
370
+ if w != base {
371
+ t .Errorf ("case %v: hasexpired value: expected %s (backoff to be reset to initial), got %s" , tt .name , base , w )
372
+ }
373
+
374
+ clock .SetTime (time .Now ())
375
+ b .Reset (id )
376
+ }
377
+ }
0 commit comments