@@ -46,19 +46,20 @@ public void Dispatch_MigrationDetected_should_push_ConnectionMigrationDetected()
4646
4747 [ Fact ( Timeout = 5000 ) ]
4848 [ Trait ( "RFC" , "RFC9000-9" ) ]
49- public void CheckForConnectionMigration_should_detect_endpoint_change ( )
49+ public void CheckForConnectionMigration_should_detect_remote_endpoint_change_on_timer ( )
5050 {
5151 var ops = new StubOps ( ) ;
5252 var sm = new QuicTransportStateMachine ( ops , ActorRefs . Nobody , ActorRefs . Nobody ) ;
5353
5454 var initialEp = new IPEndPoint ( IPAddress . Parse ( "10.0.0.1" ) , 12345 ) ;
5555 var changedEp = new IPEndPoint ( IPAddress . Parse ( "10.0.0.2" ) , 54321 ) ;
56- var currentEp = initialEp ;
56+ var currentRemoteEp = initialEp ;
5757
5858 var handle = new QuicConnectionHandle (
5959 openStream : ( _ , _ ) => Task . FromResult ( ( Stream : ( Stream ) new MemoryStream ( ) , StreamId : 0L ) ) ,
6060 acceptInboundStream : async ct => { await Task . Delay ( Timeout . Infinite , ct ) ; return null ; } ,
61- getLocalEndPoint : ( ) => currentEp ,
61+ getLocalEndPoint : ( ) => new IPEndPoint ( IPAddress . Loopback , 9999 ) ,
62+ getRemoteEndPoint : ( ) => currentRemoteEp ,
6263 dispose : ( ) => ValueTask . CompletedTask ) ;
6364
6465 var lease = new QuicConnectionLease ( handle , 100 ) ;
@@ -68,39 +69,54 @@ public void CheckForConnectionMigration_should_detect_endpoint_change()
6869
6970 ops . PushedInbound . Clear ( ) ;
7071
71- var buf1 = TransportBuffer . Rent ( 4 ) ;
72- buf1 . Length = 4 ;
73- sm . Dispatch ( new InboundData ( buf1 , 0 , 2 ) ) ;
72+ currentRemoteEp = changedEp ;
73+ sm . OnTimer ( "migration-check" ) ;
7474
75- var data1 = ops . PushedInbound . OfType < MultiplexedData > ( ) . FirstOrDefault ( ) ;
76- Assert . NotNull ( data1 ) ;
77- data1 . Buffer . Dispose ( ) ;
75+ Assert . Contains ( ops . PushedInbound , i => i is ConnectionMigrationDetected ) ;
76+ }
77+
78+ [ Fact ( Timeout = 5000 ) ]
79+ [ Trait ( "RFC" , "RFC9000-9" ) ]
80+ public void CheckForConnectionMigration_should_not_detect_when_remote_endpoint_unchanged ( )
81+ {
82+ var ops = new StubOps ( ) ;
83+ var sm = new QuicTransportStateMachine ( ops , ActorRefs . Nobody , ActorRefs . Nobody ) ;
84+
85+ var stableEp = new IPEndPoint ( IPAddress . Parse ( "10.0.0.1" ) , 12345 ) ;
86+
87+ var handle = new QuicConnectionHandle (
88+ openStream : ( _ , _ ) => Task . FromResult ( ( Stream : ( Stream ) new MemoryStream ( ) , StreamId : 0L ) ) ,
89+ acceptInboundStream : async ct => { await Task . Delay ( Timeout . Infinite , ct ) ; return null ; } ,
90+ getLocalEndPoint : ( ) => new IPEndPoint ( IPAddress . Loopback , 9999 ) ,
91+ getRemoteEndPoint : ( ) => stableEp ,
92+ dispose : ( ) => ValueTask . CompletedTask ) ;
93+
94+ var lease = new QuicConnectionLease ( handle , 100 ) ;
95+
96+ sm . HandlePush ( new ConnectTransport ( new QuicTransportOptions { Host = "example.com" , Port = 443 } ) ) ;
97+ sm . Dispatch ( new ConnectionLeaseAcquired ( lease ) ) ;
7898
7999 ops . PushedInbound . Clear ( ) ;
80- currentEp = changedEp ;
81100
82- var buf2 = TransportBuffer . Rent ( 4 ) ;
83- buf2 . Length = 4 ;
84- sm . Dispatch ( new InboundData ( buf2 , 0 , 2 ) ) ;
101+ sm . OnTimer ( "migration-check" ) ;
85102
86- var data2 = ops . PushedInbound . OfType < MultiplexedData > ( ) . FirstOrDefault ( ) ;
87- Assert . NotNull ( data2 ) ;
88- data2 . Buffer . Dispose ( ) ;
103+ Assert . DoesNotContain ( ops . PushedInbound , i => i is ConnectionMigrationDetected ) ;
89104 }
90105
91106 [ Fact ( Timeout = 5000 ) ]
92107 [ Trait ( "RFC" , "RFC9000-9" ) ]
93- public void CheckForConnectionMigration_should_not_detect_when_endpoint_unchanged ( )
108+ public void InboundData_should_not_trigger_migration_check ( )
94109 {
95110 var ops = new StubOps ( ) ;
96111 var sm = new QuicTransportStateMachine ( ops , ActorRefs . Nobody , ActorRefs . Nobody ) ;
97112
98- var stableEp = new IPEndPoint ( IPAddress . Parse ( "10.0.0.1 " ) , 12345 ) ;
113+ var changedEp = new IPEndPoint ( IPAddress . Parse ( "10.0.0.2 " ) , 54321 ) ;
99114
100115 var handle = new QuicConnectionHandle (
101116 openStream : ( _ , _ ) => Task . FromResult ( ( Stream : ( Stream ) new MemoryStream ( ) , StreamId : 0L ) ) ,
102117 acceptInboundStream : async ct => { await Task . Delay ( Timeout . Infinite , ct ) ; return null ; } ,
103- getLocalEndPoint : ( ) => stableEp ,
118+ getLocalEndPoint : ( ) => new IPEndPoint ( IPAddress . Loopback , 9999 ) ,
119+ getRemoteEndPoint : ( ) => changedEp ,
104120 dispose : ( ) => ValueTask . CompletedTask ) ;
105121
106122 var lease = new QuicConnectionLease ( handle , 100 ) ;
@@ -110,26 +126,41 @@ public void CheckForConnectionMigration_should_not_detect_when_endpoint_unchange
110126
111127 ops . PushedInbound . Clear ( ) ;
112128
113- var buf1 = TransportBuffer . Rent ( 4 ) ;
114- buf1 . Length = 4 ;
115- sm . Dispatch ( new InboundData ( buf1 , 0 , 2 ) ) ;
129+ var buf = TransportBuffer . Rent ( 4 ) ;
130+ buf . Length = 4 ;
131+ sm . Dispatch ( new InboundData ( buf , 0 , 2 ) ) ;
116132
117133 Assert . DoesNotContain ( ops . PushedInbound , i => i is ConnectionMigrationDetected ) ;
118134
119135 var data = ops . PushedInbound . OfType < MultiplexedData > ( ) . FirstOrDefault ( ) ;
120136 Assert . NotNull ( data ) ;
121137 data . Buffer . Dispose ( ) ;
138+ }
122139
123- ops . PushedInbound . Clear ( ) ;
140+ [ Fact ( Timeout = 5000 ) ]
141+ [ Trait ( "RFC" , "RFC9000-9" ) ]
142+ public void Timer_should_reschedule_after_migration_check ( )
143+ {
144+ var ops = new StubOps ( ) ;
145+ var sm = new QuicTransportStateMachine ( ops , ActorRefs . Nobody , ActorRefs . Nobody ) ;
124146
125- var buf2 = TransportBuffer . Rent ( 4 ) ;
126- buf2 . Length = 4 ;
127- sm . Dispatch ( new InboundData ( buf2 , 0 , 2 ) ) ;
147+ var stableEp = new IPEndPoint ( IPAddress . Parse ( "10.0.0.1" ) , 12345 ) ;
128148
129- Assert . DoesNotContain ( ops . PushedInbound , i => i is ConnectionMigrationDetected ) ;
149+ var handle = new QuicConnectionHandle (
150+ openStream : ( _ , _ ) => Task . FromResult ( ( Stream : ( Stream ) new MemoryStream ( ) , StreamId : 0L ) ) ,
151+ acceptInboundStream : async ct => { await Task . Delay ( Timeout . Infinite , ct ) ; return null ; } ,
152+ getLocalEndPoint : ( ) => new IPEndPoint ( IPAddress . Loopback , 9999 ) ,
153+ getRemoteEndPoint : ( ) => stableEp ,
154+ dispose : ( ) => ValueTask . CompletedTask ) ;
155+
156+ var lease = new QuicConnectionLease ( handle , 100 ) ;
157+
158+ sm . HandlePush ( new ConnectTransport ( new QuicTransportOptions { Host = "example.com" , Port = 443 } ) ) ;
159+ sm . Dispatch ( new ConnectionLeaseAcquired ( lease ) ) ;
160+
161+ ops . Timers . Clear ( ) ;
162+ sm . OnTimer ( "migration-check" ) ;
130163
131- var data2 = ops . PushedInbound . OfType < MultiplexedData > ( ) . FirstOrDefault ( ) ;
132- Assert . NotNull ( data2 ) ;
133- data2 . Buffer . Dispose ( ) ;
164+ Assert . True ( ops . Timers . ContainsKey ( "migration-check" ) ) ;
134165 }
135- }
166+ }
0 commit comments