@@ -335,5 +335,101 @@ public void HostsReturnedBySniffAreVisited()
335335 seenNodes [ 6 ] . Port . Should ( ) . Be ( 9201 ) ;
336336 }
337337 }
338+
339+ [ Test ]
340+ public void ShouldRetryOnSniffConnectionException_Async ( )
341+ {
342+ using ( var fake = new AutoFake ( callsDoNothing : true ) )
343+ {
344+ var uris = new [ ]
345+ {
346+ new Uri ( "http://localhost:9200" ) ,
347+ new Uri ( "http://localhost:9201" ) ,
348+ new Uri ( "http://localhost:9202" )
349+ } ;
350+ var connectionPool = new SniffingConnectionPool ( uris , randomizeOnStartup : false ) ;
351+ var config = new ConnectionConfiguration ( connectionPool )
352+ . SniffOnConnectionFault ( ) ;
353+
354+ fake . Provide < IConnectionConfigurationValues > ( config ) ;
355+
356+ var pingAsyncCall = FakeCalls . PingAtConnectionLevelAsync ( fake ) ;
357+ pingAsyncCall . Returns ( FakeResponse . OkAsync ( config ) ) ;
358+
359+ //sniffing is always synchronous and in turn will issue synchronous pings
360+ var pingCall = FakeCalls . PingAtConnectionLevel ( fake ) ;
361+ pingCall . Returns ( FakeResponse . Ok ( config ) ) ;
362+
363+ var sniffCall = FakeCalls . Sniff ( fake ) ;
364+ var seenPorts = new List < int > ( ) ;
365+ sniffCall . ReturnsLazily ( ( Uri u , IRequestConfiguration c ) =>
366+ {
367+ seenPorts . Add ( u . Port ) ;
368+ throw new Exception ( "Something bad happened" ) ;
369+ } ) ;
370+
371+ var getCall = FakeCalls . GetCall ( fake ) ;
372+ getCall . Returns ( FakeResponse . BadAsync ( config ) ) ;
373+
374+ FakeCalls . ProvideDefaultTransport ( fake ) ;
375+
376+ var client = fake . Resolve < ElasticsearchClient > ( ) ;
377+
378+ var e = Assert . Throws < MaxRetryException > ( async ( ) => await client . NodesHotThreadsAsync ( "nodex" ) ) ;
379+
380+ //all nodes must be tried to sniff for more information
381+ sniffCall . MustHaveHappened ( Repeated . Exactly . Times ( uris . Count ( ) ) ) ;
382+ //make sure we only saw one call to hot threads (the one that failed initially)
383+ getCall . MustHaveHappened ( Repeated . Exactly . Once ) ;
384+
385+ //make sure the sniffs actually happened on all the individual nodes
386+ seenPorts . ShouldAllBeEquivalentTo ( uris . Select ( u=> u . Port ) ) ;
387+ e . InnerException . Message . Should ( ) . Be ( "Something bad happened" ) ;
388+ }
389+ }
390+
391+ [ Test ]
392+ public void ShouldRetryOnSniffConnectionException ( )
393+ {
394+ using ( var fake = new AutoFake ( callsDoNothing : true ) )
395+ {
396+ var uris = new [ ]
397+ {
398+ new Uri ( "http://localhost:9200" ) ,
399+ new Uri ( "http://localhost:9201" )
400+ } ;
401+ var connectionPool = new SniffingConnectionPool ( uris , randomizeOnStartup : false ) ;
402+ var config = new ConnectionConfiguration ( connectionPool )
403+ . SniffOnConnectionFault ( ) ;
404+
405+ fake . Provide < IConnectionConfigurationValues > ( config ) ;
406+ FakeCalls . ProvideDefaultTransport ( fake ) ;
407+
408+ var pingCall = FakeCalls . PingAtConnectionLevel ( fake ) ;
409+ pingCall . Returns ( FakeResponse . Ok ( config ) ) ;
410+
411+ var sniffCall = FakeCalls . Sniff ( fake ) ;
412+ var seenPorts = new List < int > ( ) ;
413+ sniffCall . ReturnsLazily ( ( Uri u , IRequestConfiguration c ) =>
414+ {
415+ seenPorts . Add ( u . Port ) ;
416+ throw new Exception ( "Something bad happened" ) ;
417+ } ) ;
418+
419+ var getCall = FakeCalls . GetSyncCall ( fake ) ;
420+ getCall . Returns ( FakeResponse . Bad ( config ) ) ;
421+
422+ var client = fake . Resolve < ElasticsearchClient > ( ) ;
423+
424+ var e = Assert . Throws < MaxRetryException > ( ( ) => client . Info ( ) ) ;
425+ sniffCall . MustHaveHappened ( Repeated . Exactly . Times ( uris . Count ( ) ) ) ;
426+ getCall . MustHaveHappened ( Repeated . Exactly . Once ) ;
427+
428+ //make sure that if a ping throws an exception it wont
429+ //keep retrying to ping the same node but failover to the next
430+ seenPorts . ShouldAllBeEquivalentTo ( uris . Select ( u=> u . Port ) ) ;
431+ e . InnerException . Message . Should ( ) . Be ( "Something bad happened" ) ;
432+ }
433+ }
338434 }
339435}
0 commit comments