@@ -41,7 +41,6 @@ namespace MongoDB.Driver.Core.Tests.Jira
4141{
4242 public class CSharp3173Tests
4343 {
44- #if WINDOWS
4544#pragma warning disable CS0618 // Type or member is obsolete
4645 private readonly static ClusterConnectionMode __clusterConnectionMode = ClusterConnectionMode . Sharded ;
4746 private readonly static ConnectionModeSwitch __connectionModeSwitch = ConnectionModeSwitch . UseConnectionMode ;
@@ -93,7 +92,7 @@ public void Ensure_command_network_error_before_hadnshake_is_correctly_handled([
9392 }
9493
9594 var e = exception . Should ( ) . BeOfType < MongoConnectionException > ( ) . Subject ;
96- e. Message . Should ( ) . Be ( "DnsException" ) ;
95+ e. Message . Should ( ) . Be ( "DnsException:pool " ) ;
9796
9897 // 2. Waiting for the hello or legacy hello check
9998 hasNetworkErrorBeenTriggered . SetResult ( true ) ; // unlock the in-progress hello or legacy hello response
@@ -129,22 +128,23 @@ public void Ensure_command_network_error_before_hadnshake_is_correctly_handled([
129128 AssertEvent ( initialHeartbeatEvents [ 1 ] , __endPoint2 , ServerType . ShardRouter , "Heartbeat" ) ; // the next 27018 events will be suppressed
130129
131130 AssertNextEvent ( eventCapturer , initialSelectedEndpoint , ServerType . Unknown , "InvalidatedBecause:ChannelException during handshake: MongoDB.Driver.MongoConnectionException: DnsException" ) ;
132- AssertNextEvent ( eventCapturer , initialSelectedEndpoint , ServerType . Unknown , "Heartbeat" , typeof ( MongoConnectionException ) ) ;
131+ AssertNextEvent ( eventCapturer , initialSelectedEndpoint , ServerType . Unknown , "Heartbeat" , ( typeof ( MongoConnectionException ) , "DnsException:sdam" ) ) ;
133132 eventCapturer . Any ( ) . Should ( ) . BeFalse ( ) ;
134133
135134 int GetPort ( EndPoint endpoint ) => ( ( DnsEndPoint ) endpoint ) . Port ;
136135 }
137136
138137 // private method
139- private void AssertEvent ( ServerDescriptionChangedEvent @event , EndPoint expectedEndPoint , ServerType expectedServerType , string expectedReasonStart , Type exceptionType = null )
138+ private void AssertEvent ( ServerDescriptionChangedEvent @event , EndPoint expectedEndPoint , ServerType expectedServerType , string expectedReasonStart , ( Type ExceptionType , string ExceptionMessage ) ? exceptionInfo = null )
140139 {
141140 @event . ServerId . ClusterId . Should ( ) . Be ( __clusterId ) ;
142141 @event . NewDescription . EndPoint . Should ( ) . Be ( expectedEndPoint ) ;
143142 @event . NewDescription . Type . Should ( ) . Be ( expectedServerType ) ;
144143 @event . NewDescription . State . Should ( ) . Be ( expectedServerType == ServerType . Unknown ? ServerState . Disconnected : ServerState . Connected ) ;
145- if ( exceptionType != null )
144+ if ( exceptionInfo . HasValue )
146145 {
147- @event . NewDescription . HeartbeatException . Should ( ) . BeOfType ( exceptionType ) ;
146+ @event . NewDescription . HeartbeatException . Should ( ) . BeOfType ( exceptionInfo . Value . ExceptionType ) ;
147+ @event . NewDescription . HeartbeatException . Message . Should ( ) . Be ( exceptionInfo . Value . ExceptionMessage ) ;
148148 }
149149 else
150150 {
@@ -153,10 +153,10 @@ private void AssertEvent(ServerDescriptionChangedEvent @event, EndPoint expected
153153 @event . NewDescription . ReasonChanged . Should ( ) . StartWith ( expectedReasonStart ) ;
154154 }
155155
156- private void AssertNextEvent ( EventCapturer eventCapturer , EndPoint expectedEndPoint , ServerType expectedServerType , string expectedReasonStart , Type exceptionType = null )
156+ private void AssertNextEvent ( EventCapturer eventCapturer , EndPoint expectedEndPoint , ServerType expectedServerType , string expectedReasonStart , ( Type ExceptionType , string ExceptionMessage ) ? exceptionInfo = null )
157157 {
158158 var @event = eventCapturer . Next ( ) . Should ( ) . BeOfType < ServerDescriptionChangedEvent > ( ) . Subject ;
159- AssertEvent ( @event , expectedEndPoint , expectedServerType , expectedReasonStart , exceptionType ) ;
159+ AssertEvent ( @event , expectedEndPoint , expectedServerType , expectedReasonStart , exceptionInfo ) ;
160160 }
161161
162162 private IConnectionPoolFactory CreateAndSetupConnectionPoolFactory ( Func < ServerId , IConnectionExceptionHandler > exceptionHandlerProvider , params ( ServerId ServerId , EndPoint Endpoint , bool IsHealthy ) [ ] serverInfoCollection )
@@ -183,7 +183,7 @@ void SetupConnection(Mock<IConnectionHandle> mockConnectionHandle, ServerId serv
183183
184184 void SetupConnectionPool ( Mock < IConnectionPool > mockConnectionPool , IConnectionHandle connection , Func < IConnectionExceptionHandler > exceptionHandlerProvider )
185185 {
186- var dnsException = CreateDnsException ( connection . ConnectionId ) ;
186+ var dnsException = CreateDnsException ( connection . ConnectionId , from : "pool" ) ;
187187 mockConnectionPool
188188 . Setup ( c => c . AcquireConnection ( It . IsAny < CancellationToken > ( ) ) )
189189 . Callback ( ( ) => exceptionHandlerProvider ( ) . HandleExceptionOnOpen ( dnsException ) )
@@ -210,17 +210,33 @@ private IConnectionFactory CreateAndSetupServerMonitorConnectionFactory(
210210
211211 foreach ( var serverInfo in serverInfoCollection )
212212 {
213+ // configure ServerMonitor connections
213214 var mockServerMonitorConnection = new Mock < IConnection > ( ) ;
214215 SetupServerMonitorConnection ( mockServerMonitorConnection , serverInfo . ServerId , serverInfo . IsHealthy , hasNetworkErrorBeenTriggered , hasClusterBeenDisposed , streamable ) ;
215216 mockConnectionFactory
217+ . When ( ( ) => ! Environment . StackTrace . Contains ( nameof ( RoundTripTimeMonitor ) ) )
216218 . Setup ( c => c . CreateConnection ( serverInfo . ServerId , serverInfo . Endpoint ) )
217219 . Returns ( mockServerMonitorConnection . Object ) ;
220+
221+ // configure healthy RTT connections
222+ var mockRttConnection = new Mock < IConnection > ( ) ;
223+ SetupServerMonitorConnection (
224+ mockRttConnection ,
225+ serverInfo . ServerId ,
226+ isHealthy : true ,
227+ hasNetworkErrorBeenTriggered : null , // has no role for RTT
228+ hasClusterBeenDisposed ,
229+ streamable ) ;
230+ mockConnectionFactory
231+ . When ( ( ) => Environment . StackTrace . Contains ( nameof ( RoundTripTimeMonitor ) ) )
232+ . Setup ( c => c . CreateConnection ( serverInfo . ServerId , serverInfo . Endpoint ) )
233+ . Returns ( mockRttConnection . Object ) ;
218234 }
219235
220236 return mockConnectionFactory . Object ;
221237 }
222238
223- private MultiServerCluster CreateAndSetupCluster ( TaskCompletionSource < bool > hasNetworkErrorBeenTriggered , TaskCompletionSource < bool > hasClusterBeenDisposed , EventCapturer eventCapturer , bool streamable )
239+ private MultiServerCluster CreateAndSetupCluster ( TaskCompletionSource < bool > hasNetworkErrorBeenTriggered , TaskCompletionSource < bool > hasClusterBeenDisposed , IEventSubscriber eventCapturer , bool streamable )
224240 {
225241 ( ServerId ServerId , EndPoint Endpoint , bool IsHealthy ) [ ] serverInfoCollection = new [ ]
226242 {
@@ -253,9 +269,9 @@ private MultiServerCluster CreateAndSetupCluster(TaskCompletionSource<bool> hasN
253269 return cluster = new MultiServerCluster ( clusterSettings , serverFactory , eventCapturer ) ;
254270 }
255271
256- private Exception CreateDnsException ( ConnectionId connectionId )
272+ private Exception CreateDnsException ( ConnectionId connectionId , string from )
257273 {
258- return new MongoConnectionException ( connectionId , "DnsException" ) ;
274+ return new MongoConnectionException ( connectionId , $ "DnsException: { from } ") ;
259275 }
260276
261277 private IServerSelector CreateWritableServerAndEndPointSelector ( EndPoint endPoint )
@@ -325,12 +341,13 @@ private void SetupServerMonitorConnection(
325341
326342 void SetupFailedConnection ( Mock < IConnection > mockFaultyConnection )
327343 {
344+ Ensure . IsNotNull ( hasNetworkErrorBeenTriggered , nameof ( hasNetworkErrorBeenTriggered ) ) ;
345+
328346 // async path is not used in serverMonitor
329347 var faultyConnectionResponses = new Queue < Action > ( new Action [ ]
330348 {
331- ( ) => { /* no action needed*/ } , // the first hello or legacy hello configuration passes
332- ( ) => { /* no action needed*/ } , // RTT
333- ( ) => throw CreateDnsException ( mockConnection . Object . ConnectionId ) , // the dns exception. Should be triggered after Invalidate
349+ ( ) => { } , // the first hello or legacy hello configuration passes
350+ ( ) => throw CreateDnsException ( mockConnection . Object . ConnectionId , from : "sdam" ) , // the dns exception. Should be triggered after Invalidate
334351 ( ) => WaitForTaskOrTimeout ( hasClusterBeenDisposed . Task , TimeSpan . FromMinutes ( 1 ) , "cluster dispose" )
335352 } ) ;
336353 mockFaultyConnection
@@ -345,8 +362,10 @@ void SetupFailedConnection(Mock<IConnection> mockFaultyConnection)
345362 . Setup ( c => c . ReceiveMessage ( It . IsAny < int > ( ) , It . IsAny < IMessageEncoderSelector > ( ) , It . IsAny < MessageEncoderSettings > ( ) , It . IsAny < CancellationToken > ( ) ) )
346363 . Returns ( ( ) =>
347364 {
348- // wait until the command network error has been triggered
349- WaitForTaskOrTimeout ( hasNetworkErrorBeenTriggered . Task , TimeSpan . FromMinutes ( 1 ) , "network error" ) ;
365+ WaitForTaskOrTimeout (
366+ hasNetworkErrorBeenTriggered . Task ,
367+ TimeSpan . FromMinutes ( 1 ) ,
368+ testTarget : "network error" ) ;
350369 return commandResponseAction ( ) ;
351370 } ) ;
352371 }
@@ -372,6 +391,5 @@ private void WaitForTaskOrTimeout(Task task, TimeSpan timeout, string testTarget
372391 throw new Exception ( $ "The waiting for { testTarget } is exceeded timeout { timeout } .") ;
373392 }
374393 }
375- #endif
376394 }
377395}
0 commit comments