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