@@ -129,11 +129,22 @@ func TestSYNDynamicTimeout(t *testing.T) {
129
129
require .Equal (t , minimumResendTimeout , newTimeout )
130
130
131
131
// Then we'll test that the resend timeout isn't dynamically set if
132
- // when simulating a that the SYN message has been resent.
132
+ // when simulating a that the SYN message has been resent, but that the
133
+ // handshake timeout is boosted.
134
+ tm .handshakeBooster .boostPercent = 0.2
135
+ originalHandshakeTimeout := tm .GetHandshakeTimeout ()
136
+
133
137
sendAndReceive (t , tm , synMsg , synMsg , true )
134
138
135
139
unchangedResendTimeout := tm .GetResendTimeout ()
136
140
require .Equal (t , newTimeout , unchangedResendTimeout )
141
+
142
+ newHandshakeTimeout := tm .GetHandshakeTimeout ()
143
+ require .Equal (
144
+ t ,
145
+ time .Duration (float32 (originalHandshakeTimeout )* 1.2 ),
146
+ newHandshakeTimeout ,
147
+ )
137
148
}
138
149
139
150
// TestDataPackageDynamicTimeout ensures that the resend timeout is dynamically
@@ -187,7 +198,9 @@ func TestDataPackageDynamicTimeout(t *testing.T) {
187
198
require .NotEqual (t , resendTimeout , newResendTimeout )
188
199
189
200
// Finally let's test that the resend timeout isn't dynamically set when
190
- // simulating that the data packet has been resent.
201
+ // simulating that the data packet has been resent. The resend timeout
202
+ // shouldn't be boosted either, as the resend timeout is only boosted
203
+ // if we resend a packet after the duration of the previous resend time.
191
204
tm .timeoutUpdateFrequency = 1
192
205
tm .resendMultiplier = 100
193
206
@@ -197,6 +210,124 @@ func TestDataPackageDynamicTimeout(t *testing.T) {
197
210
require .Equal (t , newResendTimeout , unchangedResendTimeout )
198
211
}
199
212
213
+ // TestResendBooster tests that the resend timeout booster works as expected,
214
+ // and that timeout manager's resendTimeout get's boosted when we need to resend
215
+ // a packet again due to not receiving a response within the resend timeout.
216
+ func TestResendBooster (t * testing.T ) {
217
+ t .Parallel ()
218
+
219
+ tm := NewTimeOutManager (nil )
220
+ setResendTimeout := time .Millisecond * 1000
221
+ tm .resendTimeout = setResendTimeout
222
+
223
+ initialResendTimeout := tm .GetResendTimeout ()
224
+ msg := & PacketData {Seq : 20 }
225
+ response := & PacketACK {Seq : 20 }
226
+
227
+ // As the resend timeout won't be dynamically set when we are resending
228
+ // packets, we'll first test that the resend timeout didn't get
229
+ // dynamically updated by a resent data packet. This will however
230
+ // boost the resend timeout, so let's initially set the boost percent
231
+ // to 0 so we can test that the resend timeout wasn't set.
232
+ tm .timeoutUpdateFrequency = 1
233
+ tm .resendMultiplier = 1
234
+
235
+ tm .resendBooster .boostPercent = 0
236
+
237
+ sendAndReceiveWithDuration (
238
+ t , tm , time .Millisecond , msg , response , true ,
239
+ )
240
+
241
+ unchangedResendTimeout := tm .GetResendTimeout ()
242
+ require .Equal (t , initialResendTimeout , unchangedResendTimeout )
243
+
244
+ // Now let's change the boost percent to a non-zero value and test that
245
+ // the resend timeout was boosted as expected.
246
+ tm .resendBooster .boostPercent = 0.1
247
+
248
+ changedResendTimeout := tm .GetResendTimeout ()
249
+
250
+ require .Equal (
251
+ t ,
252
+ time .Duration (float32 (initialResendTimeout )* 1.1 ),
253
+ changedResendTimeout ,
254
+ )
255
+
256
+ // Now let's resend another packet again, which shouldn't boost the
257
+ // resend timeout again, as the duration of the previous resend timeout
258
+ // hasn't passed.
259
+ sendAndReceiveWithDuration (
260
+ t , tm , time .Millisecond , msg , response , true ,
261
+ )
262
+
263
+ unchangedResendTimeout = tm .GetResendTimeout ()
264
+
265
+ require .Equal (
266
+ t ,
267
+ time .Duration (float32 (initialResendTimeout )* 1.1 ),
268
+ unchangedResendTimeout ,
269
+ )
270
+
271
+ // Now let's wait for the duration of the previous resend timeout and
272
+ // then resend another packet. This should boost the resend timeout
273
+ // once more, as the duration of the previous resend timeout has passed.
274
+ err := wait .Invariant (func () bool {
275
+ currentResendTimeout := tm .GetResendTimeout ()
276
+
277
+ return unchangedResendTimeout == currentResendTimeout
278
+ }, setResendTimeout )
279
+ require .NoError (t , err )
280
+
281
+ sendAndReceiveWithDuration (
282
+ t , tm , time .Millisecond , msg , response , true ,
283
+ )
284
+
285
+ changedResendTimeout = tm .GetResendTimeout ()
286
+
287
+ require .Equal (
288
+ t ,
289
+ time .Duration (float32 (initialResendTimeout )* 1.2 ),
290
+ changedResendTimeout ,
291
+ )
292
+
293
+ // Now let's verify that in case the resend timeout is dynamically set,
294
+ // the boost of the resend timeout is reset. Note that we're not
295
+ // simulating a resend here, as that will dynamically set the resend
296
+ // timeout as the timeout update frequency is set to 1.
297
+ sendAndReceiveWithDuration (
298
+ t , tm , time .Second , msg , response , false ,
299
+ )
300
+
301
+ newResendTimeout := tm .GetResendTimeout ()
302
+
303
+ require .NotEqual (t , changedResendTimeout , newResendTimeout )
304
+ require .Equal (t , 0 , tm .resendBooster .boostCount )
305
+
306
+ // Finally let's check that the resend timeout isn't boosted if we
307
+ // simulate a resend before the duration of the newly set resend
308
+ // timeout hasn't passed.
309
+ sendAndReceiveWithDuration (
310
+ t , tm , time .Millisecond , msg , response , true ,
311
+ )
312
+
313
+ require .Equal (t , 0 , tm .resendBooster .boostCount )
314
+
315
+ // But if we wait for the duration of the newly set resend timeout and
316
+ // then simulate a resend, then the resend timeout should be boosted.
317
+ err = wait .Invariant (func () bool {
318
+ currentResendTimeout := tm .GetResendTimeout ()
319
+
320
+ return newResendTimeout == currentResendTimeout
321
+ }, newResendTimeout )
322
+ require .NoError (t , err )
323
+
324
+ sendAndReceiveWithDuration (
325
+ t , tm , time .Millisecond , msg , response , true ,
326
+ )
327
+
328
+ require .Equal (t , 1 , tm .resendBooster .boostCount )
329
+ }
330
+
200
331
// TestStaticTimeout ensures that the resend timeout isn't dynamically set if a
201
332
// static timeout has been set.
202
333
func TestStaticTimeout (t * testing.T ) {
0 commit comments