1919package org .neo4j .driver .v1 .integration ;
2020
2121import org .junit .After ;
22+ import org .junit .AfterClass ;
2223import org .junit .Rule ;
2324import org .junit .Test ;
2425
3536
3637import org .neo4j .driver .internal .cluster .RoutingSettings ;
3738import org .neo4j .driver .internal .retry .RetrySettings ;
38- import org .neo4j .driver .internal .util .Clock ;
39- import org .neo4j .driver .internal .util .ConnectionTrackingDriverFactory ;
4039import org .neo4j .driver .internal .util .FakeClock ;
4140import org .neo4j .driver .internal .util .ThrowingConnection ;
4241import org .neo4j .driver .internal .util .ThrowingConnectionDriverFactory ;
7069import static org .hamcrest .Matchers .instanceOf ;
7170import static org .hamcrest .Matchers .startsWith ;
7271import static org .junit .Assert .assertEquals ;
72+ import static org .junit .Assert .assertFalse ;
7373import static org .junit .Assert .assertNotNull ;
7474import static org .junit .Assert .assertNull ;
7575import static org .junit .Assert .assertThat ;
@@ -97,6 +97,12 @@ public void tearDown()
9797 }
9898 }
9999
100+ @ AfterClass
101+ public static void stopSharedCluster ()
102+ {
103+ ClusterRule .stopSharedCluster ();
104+ }
105+
100106 @ Test
101107 public void shouldExecuteReadAndWritesWhenDriverSuppliedWithAddressOfLeader () throws Exception
102108 {
@@ -236,7 +242,7 @@ public Void apply( Session session )
236242 }
237243
238244 @ Test
239- public void shouldDropBrokenOldSessions () throws Exception
245+ public void shouldDropBrokenOldConnections () throws Exception
240246 {
241247 Cluster cluster = clusterRule .getCluster ();
242248
@@ -249,19 +255,24 @@ public void shouldDropBrokenOldSessions() throws Exception
249255 .toConfig ();
250256
251257 FakeClock clock = new FakeClock ();
252- ConnectionTrackingDriverFactory driverFactory = new ConnectionTrackingDriverFactory ( clock );
258+ ThrowingConnectionDriverFactory driverFactory = new ThrowingConnectionDriverFactory ( clock );
253259
254260 URI routingUri = cluster .leader ().getRoutingUri ();
255261 AuthToken auth = clusterRule .getDefaultAuthToken ();
256262 RetrySettings retrySettings = RetrySettings .DEFAULT ;
257263
258264 try ( Driver driver = driverFactory .newInstance ( routingUri , auth , defaultRoutingSettings (), retrySettings , config ) )
259265 {
260- // create nodes in different threads using different sessions
266+ // create nodes in different threads using different sessions and connections
261267 createNodesInDifferentThreads ( concurrentSessionsCount , driver );
262268
263- // now pool contains many sessions, make them all invalid
264- driverFactory .closeConnections ();
269+ // now pool contains many connections, make them all invalid
270+ List <ThrowingConnection > oldConnections = driverFactory .pollConnections ();
271+ for ( ThrowingConnection oldConnection : oldConnections )
272+ {
273+ oldConnection .setNextResetError ( new ServiceUnavailableException ( "Unable to reset" ) );
274+ }
275+
265276 // move clock forward more than configured liveness check timeout
266277 clock .progress ( MINUTES .toMillis ( livenessCheckTimeoutMinutes + 1 ) );
267278
@@ -273,6 +284,12 @@ public void shouldDropBrokenOldSessions() throws Exception
273284 assertEquals ( 1 , records .size () );
274285 assertEquals ( concurrentSessionsCount , records .get ( 0 ).get ( 0 ).asInt () );
275286 }
287+
288+ // all old connections failed to reset and should be closed
289+ for ( ThrowingConnection connection : oldConnections )
290+ {
291+ assertFalse ( connection .isOpen () );
292+ }
276293 }
277294 }
278295
@@ -573,7 +590,7 @@ public void shouldRediscoverWhenConnectionsToAllCoresBreak()
573590 // make all those connections throw and seem broken
574591 for ( ThrowingConnection connection : driverFactory .getConnections () )
575592 {
576- connection .setNextRunFailure ( new ServiceUnavailableException ( "Disconnected" ) );
593+ connection .setNextRunError ( new ServiceUnavailableException ( "Disconnected" ) );
577594 }
578595
579596 // observe that connection towards writer is broken
@@ -620,7 +637,7 @@ public void shouldKeepOperatingWhenConnectionsBreak() throws Exception
620637 String value = "Tony Stark" ;
621638 Cluster cluster = clusterRule .getCluster ();
622639
623- ConnectionTrackingDriverFactory driverFactory = new ConnectionTrackingDriverFactory ( Clock . SYSTEM );
640+ ThrowingConnectionDriverFactory driverFactory = new ThrowingConnectionDriverFactory ( );
624641 AtomicBoolean stop = new AtomicBoolean ();
625642 executor = newExecutor ();
626643
@@ -632,18 +649,22 @@ public void shouldKeepOperatingWhenConnectionsBreak() throws Exception
632649 // launch writers and readers that use transaction functions and thus should never fail
633650 for ( int i = 0 ; i < 3 ; i ++ )
634651 {
635- results .add ( executor .submit ( countNodesCallable ( driver , label , property , value , stop ) ) );
652+ results .add ( executor .submit ( readNodesCallable ( driver , label , property , value , stop ) ) );
636653 }
637654 for ( int i = 0 ; i < 2 ; i ++ )
638655 {
639656 results .add ( executor .submit ( createNodesCallable ( driver , label , property , value , stop ) ) );
640657 }
641658
642- // terminate connections while reads and writes are in progress
659+ // make connections throw while reads and writes are in progress
643660 long deadline = System .currentTimeMillis () + MINUTES .toMillis ( 1 );
644661 while ( System .currentTimeMillis () < deadline && !stop .get () )
645662 {
646- driverFactory .closeConnections ();
663+ List <ThrowingConnection > connections = driverFactory .pollConnections ();
664+ for ( ThrowingConnection connection : connections )
665+ {
666+ connection .setNextRunError ( new ServiceUnavailableException ( "Unable to execute query" ) );
667+ }
647668 SECONDS .sleep ( 5 ); // sleep a bit to allow readers and writers to progress
648669 }
649670 stop .set ( true );
@@ -676,7 +697,7 @@ private static void setupLastConnectionToThrow( ThrowingConnectionDriverFactory
676697 {
677698 List <ThrowingConnection > connections = factory .getConnections ();
678699 ThrowingConnection lastConnection = connections .get ( connections .size () - 1 );
679- lastConnection .setNextRunFailure ( error );
700+ lastConnection .setNextRunError ( error );
680701 }
681702
682703 private int executeWriteAndReadThroughBolt ( ClusterMember member ) throws TimeoutException , InterruptedException
@@ -951,7 +972,7 @@ public Void call() throws Exception
951972 };
952973 }
953974
954- private static Callable <Void > countNodesCallable ( final Driver driver , final String label , final String property , final String value ,
975+ private static Callable <Void > readNodesCallable ( final Driver driver , final String label , final String property , final String value ,
955976 final AtomicBoolean stop )
956977 {
957978 return new Callable <Void >()
@@ -963,7 +984,7 @@ public Void call() throws Exception
963984 {
964985 try ( Session session = driver .session ( AccessMode .READ ) )
965986 {
966- countNodes ( session , label , property , value );
987+ readNodeIds ( session , label , property , value );
967988 }
968989 catch ( Throwable t )
969990 {
@@ -989,6 +1010,26 @@ public Void execute( Transaction tx )
9891010 } );
9901011 }
9911012
1013+ private static List <Long > readNodeIds ( final Session session , final String label , final String property , final String value )
1014+ {
1015+ return session .readTransaction ( new TransactionWork <List <Long >>()
1016+ {
1017+ @ Override
1018+ public List <Long > execute ( Transaction tx )
1019+ {
1020+ StatementResult result = tx .run ( "MATCH (n:" + label + " {" + property + ": $value}) RETURN n LIMIT 5" ,
1021+ parameters ( "value" , value ) );
1022+
1023+ List <Long > ids = new ArrayList <>();
1024+ while ( result .hasNext () )
1025+ {
1026+ ids .add ( result .next ().get ( 0 ).asNode ().id () );
1027+ }
1028+ return ids ;
1029+ }
1030+ } );
1031+ }
1032+
9921033 private static void updateNode ( final Session session , final String label , final String property , final String oldValue , final String newValue )
9931034 {
9941035 session .writeTransaction ( new TransactionWork <Void >()
0 commit comments