2121import org .junit .Test ;
2222import org .mockito .InOrder ;
2323
24- import java .util .HashSet ;
24+ import java .util .Collections ;
25+ import java .util .Set ;
2526import java .util .concurrent .atomic .AtomicInteger ;
2627
28+ import org .neo4j .driver .internal .RoutingTransaction ;
2729import org .neo4j .driver .internal .net .BoltServerAddress ;
2830import org .neo4j .driver .internal .spi .Connection ;
2931import org .neo4j .driver .internal .spi .ConnectionPool ;
32+ import org .neo4j .driver .v1 .AccessMode ;
33+ import org .neo4j .driver .v1 .Transaction ;
34+ import org .neo4j .driver .v1 .exceptions .ServiceUnavailableException ;
35+ import org .neo4j .driver .v1 .exceptions .SessionExpiredException ;
3036
31- import static java .util .Arrays .asList ;
3237import static org .hamcrest .MatcherAssert .assertThat ;
38+ import static org .hamcrest .Matchers .instanceOf ;
3339import static org .hamcrest .core .IsEqual .equalTo ;
40+ import static org .junit .Assert .assertNotNull ;
41+ import static org .junit .Assert .fail ;
3442import static org .mockito .Matchers .any ;
43+ import static org .mockito .Mockito .doThrow ;
3544import static org .mockito .Mockito .inOrder ;
3645import static org .mockito .Mockito .mock ;
3746import static org .mockito .Mockito .spy ;
@@ -49,27 +58,28 @@ public void ensureRoutingShouldUpdateRoutingTableAndPurgeConnectionPoolWhenStale
4958 RoutingTable routingTable = mock ( RoutingTable .class );
5059 Rediscovery rediscovery = mock ( Rediscovery .class );
5160 when ( routingTable .isStale () ).thenReturn ( true );
52- HashSet <BoltServerAddress > set = new HashSet <>( asList ( new BoltServerAddress ( "abc" , 12 ) ) );
61+ Set <BoltServerAddress > set = Collections . singleton ( new BoltServerAddress ( "abc" , 12 ) );
5362 when ( routingTable .update ( any ( ClusterComposition .class ) ) ).thenReturn ( set );
5463
5564 // when
56- LoadBalancer balancer = new LoadBalancer ( DEV_NULL_LOGGER , conns , routingTable , rediscovery );
65+ LoadBalancer balancer = new LoadBalancer ( routingTable , conns , rediscovery , DEV_NULL_LOGGER );
5766
5867 // then
68+ assertNotNull ( balancer );
5969 InOrder inOrder = inOrder ( rediscovery , routingTable , conns );
6070 inOrder .verify ( rediscovery ).lookupRoutingTable ( conns , routingTable );
6171 inOrder .verify ( routingTable ).update ( any ( ClusterComposition .class ) );
6272 inOrder .verify ( conns ).purge ( new BoltServerAddress ( "abc" , 12 ) );
6373 }
6474
65-
6675 @ Test
6776 public void shouldEnsureRoutingOnInitialization () throws Exception
6877 {
6978 // given & when
7079 final AtomicInteger ensureRoutingCounter = new AtomicInteger ( 0 );
71- LoadBalancer balancer = new LoadBalancer ( DEV_NULL_LOGGER , mock ( ConnectionPool .class ),
72- mock ( RoutingTable .class ), mock ( Rediscovery .class ) ) {
80+ LoadBalancer balancer = new LoadBalancer ( mock ( RoutingTable .class ), mock ( ConnectionPool .class ),
81+ mock ( Rediscovery .class ), DEV_NULL_LOGGER )
82+ {
7383 @ Override
7484 public void ensureRouting ()
7585 {
@@ -78,6 +88,7 @@ public void ensureRouting()
7888 };
7989
8090 // then
91+ assertNotNull ( balancer );
8192 assertThat ( ensureRoutingCounter .get (), equalTo ( 1 ) );
8293 }
8394
@@ -129,9 +140,36 @@ private LoadBalancer setupLoadBalancer( Connection writerConn, Connection readCo
129140 when ( routingTable .readers () ).thenReturn ( readerAddrs );
130141 when ( routingTable .writers () ).thenReturn ( writerAddrs );
131142
132- LoadBalancer balancer = new LoadBalancer ( DEV_NULL_LOGGER , connPool ,
133- routingTable , mock ( Rediscovery . class ) ) ;
143+ return new LoadBalancer ( routingTable , connPool , mock ( Rediscovery . class ), DEV_NULL_LOGGER );
144+ }
134145
135- return balancer ;
146+ @ Test
147+ public void shouldForgetAddressAndItsConnectionsOnServiceUnavailable ()
148+ {
149+ Transaction tx = mock ( Transaction .class );
150+ RoutingTable routingTable = mock ( RoutingTable .class );
151+ ConnectionPool connectionPool = mock ( ConnectionPool .class );
152+ Rediscovery rediscovery = mock ( Rediscovery .class );
153+ LoadBalancer loadBalancer = new LoadBalancer ( routingTable , connectionPool , rediscovery , DEV_NULL_LOGGER );
154+ BoltServerAddress address = new BoltServerAddress ( "host" , 42 );
155+
156+ RoutingTransaction routingTx = new RoutingTransaction ( tx , AccessMode .WRITE , address , loadBalancer );
157+
158+ ServiceUnavailableException txCloseError = new ServiceUnavailableException ( "Oh!" );
159+ doThrow ( txCloseError ).when ( tx ).close ();
160+
161+ try
162+ {
163+ routingTx .close ();
164+ fail ( "Exception expected" );
165+ }
166+ catch ( Exception e )
167+ {
168+ assertThat ( e , instanceOf ( SessionExpiredException .class ) );
169+ assertThat ( e .getCause (), instanceOf ( ServiceUnavailableException .class ) );
170+ }
171+
172+ verify ( routingTable ).forget ( address );
173+ verify ( connectionPool ).purge ( address );
136174 }
137175}
0 commit comments