@@ -61,11 +61,22 @@ func TestSYNDynamicTimeout(t *testing.T) {
6161 require .Equal (t , minimumResendTimeout , newTimeout )
6262
6363 // Then we'll test that the resend timeout isn't dynamically set if
64- // when simulating a that the SYN message has been resent.
64+ // when simulating a that the SYN message has been resent, but that the
65+ // handshake timeout is boosted.
66+ tm .handshakeBooster .boostPercent = 0.2
67+ originalHandshakeTimeout := tm .GetHandshakeTimeout ()
68+
6569 sendAndReceive (t , tm , synMsg , synMsg , true )
6670
6771 unchangedResendTimeout := tm .GetResendTimeout ()
6872 require .Equal (t , newTimeout , unchangedResendTimeout )
73+
74+ newHandshakeTimeout := tm .GetHandshakeTimeout ()
75+ require .Equal (
76+ t ,
77+ time .Duration (float32 (originalHandshakeTimeout )* 1.2 ),
78+ newHandshakeTimeout ,
79+ )
6980}
7081
7182// TestDataPackageDynamicTimeout ensures that the resend timeout is dynamically
@@ -121,7 +132,9 @@ func TestDataPackageDynamicTimeout(t *testing.T) {
121132 require .NotEqual (t , resendTimeout , newResendTimeout )
122133
123134 // Finally let's test that the resend timeout isn't dynamically set when
124- // simulating that the data packet has been resent.
135+ // simulating that the data packet has been resent. The resend timeout
136+ // shouldn't be boosted either, as the resend timeout is only boosted
137+ // if we resend a packet after the duration of the previous resend time.
125138 tm .timeoutUpdateFrequency = 1
126139 tm .resendMultiplier = 100
127140
@@ -131,6 +144,124 @@ func TestDataPackageDynamicTimeout(t *testing.T) {
131144 require .Equal (t , newResendTimeout , unchangedResendTimeout )
132145}
133146
147+ // TestResendBooster tests that the resend timeout booster works as expected,
148+ // and that timeout manager's resendTimeout get's boosted when we need to resend
149+ // a packet again due to not receiving a response within the resend timeout.
150+ func TestResendBooster (t * testing.T ) {
151+ t .Parallel ()
152+
153+ tm := NewTimeOutManager (nil )
154+ setResendTimeout := time .Millisecond * 1000
155+ tm .resendTimeout = setResendTimeout
156+
157+ initialResendTimeout := tm .GetResendTimeout ()
158+ msg := & PacketData {Seq : 20 }
159+ response := & PacketACK {Seq : 20 }
160+
161+ // As the resend timeout won't be dynamically set when we are resending
162+ // packets, we'll first test that the resend timeout didn't get
163+ // dynamically updated by a resent data packet. This will however
164+ // boost the resend timeout, so let's initially set the boost percent
165+ // to 0 so we can test that the resend timeout wasn't set.
166+ tm .timeoutUpdateFrequency = 1
167+ tm .resendMultiplier = 1
168+
169+ tm .resendBooster .boostPercent = 0
170+
171+ sendAndReceiveWithDuration (
172+ t , tm , time .Millisecond , msg , response , true ,
173+ )
174+
175+ unchangedResendTimeout := tm .GetResendTimeout ()
176+ require .Equal (t , initialResendTimeout , unchangedResendTimeout )
177+
178+ // Now let's change the boost percent to a non-zero value and test that
179+ // the resend timeout was boosted as expected.
180+ tm .resendBooster .boostPercent = 0.1
181+
182+ changedResendTimeout := tm .GetResendTimeout ()
183+
184+ require .Equal (
185+ t ,
186+ time .Duration (float32 (initialResendTimeout )* 1.1 ),
187+ changedResendTimeout ,
188+ )
189+
190+ // Now let's resend another packet again, which shouldn't boost the
191+ // resend timeout again, as the duration of the previous resend timeout
192+ // hasn't passed.
193+ sendAndReceiveWithDuration (
194+ t , tm , time .Millisecond , msg , response , true ,
195+ )
196+
197+ unchangedResendTimeout = tm .GetResendTimeout ()
198+
199+ require .Equal (
200+ t ,
201+ time .Duration (float32 (initialResendTimeout )* 1.1 ),
202+ unchangedResendTimeout ,
203+ )
204+
205+ // Now let's wait for the duration of the previous resend timeout and
206+ // then resend another packet. This should boost the resend timeout
207+ // once more, as the duration of the previous resend timeout has passed.
208+ err := wait .Invariant (func () bool {
209+ currentResendTimeout := tm .GetResendTimeout ()
210+
211+ return unchangedResendTimeout == currentResendTimeout
212+ }, setResendTimeout )
213+ require .NoError (t , err )
214+
215+ sendAndReceiveWithDuration (
216+ t , tm , time .Millisecond , msg , response , true ,
217+ )
218+
219+ changedResendTimeout = tm .GetResendTimeout ()
220+
221+ require .Equal (
222+ t ,
223+ time .Duration (float32 (initialResendTimeout )* 1.2 ),
224+ changedResendTimeout ,
225+ )
226+
227+ // Now let's verify that in case the resend timeout is dynamically set,
228+ // the boost of the resend timeout is reset. Note that we're not
229+ // simulating a resend here, as that will dynamically set the resend
230+ // timeout as the timeout update frequency is set to 1.
231+ sendAndReceiveWithDuration (
232+ t , tm , time .Second , msg , response , false ,
233+ )
234+
235+ newResendTimeout := tm .GetResendTimeout ()
236+
237+ require .NotEqual (t , changedResendTimeout , newResendTimeout )
238+ require .Equal (t , 0 , tm .resendBooster .boostCount )
239+
240+ // Finally let's check that the resend timeout isn't boosted if we
241+ // simulate a resend before the duration of the newly set resend
242+ // timeout hasn't passed.
243+ sendAndReceiveWithDuration (
244+ t , tm , time .Millisecond , msg , response , true ,
245+ )
246+
247+ require .Equal (t , 0 , tm .resendBooster .boostCount )
248+
249+ // But if we wait for the duration of the newly set resend timeout and
250+ // then simulate a resend, then the resend timeout should be boosted.
251+ err = wait .Invariant (func () bool {
252+ currentResendTimeout := tm .GetResendTimeout ()
253+
254+ return newResendTimeout == currentResendTimeout
255+ }, newResendTimeout )
256+ require .NoError (t , err )
257+
258+ sendAndReceiveWithDuration (
259+ t , tm , time .Millisecond , msg , response , true ,
260+ )
261+
262+ require .Equal (t , 1 , tm .resendBooster .boostCount )
263+ }
264+
134265// TestStaticTimeout ensures that the resend timeout isn't dynamically set if a
135266// static timeout has been set.
136267func TestStaticTimeout (t * testing.T ) {
0 commit comments