Skip to content

Commit b1076c6

Browse files
authored
Merge pull request #466 from lutovich/1.4-fix-flaky-tests
Fix couple newly created flaky CC tests
2 parents 8c72e38 + 1b1b973 commit b1076c6

File tree

7 files changed

+126
-126
lines changed

7 files changed

+126
-126
lines changed

driver/src/test/java/org/neo4j/driver/internal/util/ConnectionTrackingConnector.java

Lines changed: 0 additions & 45 deletions
This file was deleted.

driver/src/test/java/org/neo4j/driver/internal/util/ConnectionTrackingDriverFactory.java

Lines changed: 0 additions & 57 deletions
This file was deleted.

driver/src/test/java/org/neo4j/driver/internal/util/ThrowingConnection.java

Lines changed: 23 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
package org.neo4j.driver.internal.util;
2020

2121
import java.util.Map;
22+
import java.util.concurrent.atomic.AtomicReference;
2223

2324
import org.neo4j.driver.internal.net.BoltServerAddress;
2425
import org.neo4j.driver.internal.spi.Collector;
@@ -29,11 +30,14 @@
2930
public class ThrowingConnection implements Connection
3031
{
3132
private final Connection realConnection;
32-
private RuntimeException nextRunFailure;
33+
private final AtomicReference<RuntimeException> nextRunError;
34+
private final AtomicReference<RuntimeException> nextResetError;
3335

3436
public ThrowingConnection( Connection realConnection )
3537
{
3638
this.realConnection = realConnection;
39+
this.nextRunError = new AtomicReference<>();
40+
this.nextResetError = new AtomicReference<>();
3741
}
3842

3943
@Override
@@ -45,12 +49,7 @@ public void init( String clientName, Map<String,Value> authToken )
4549
@Override
4650
public void run( String statement, Map<String,Value> parameters, Collector collector )
4751
{
48-
if ( nextRunFailure != null )
49-
{
50-
RuntimeException error = nextRunFailure;
51-
nextRunFailure = null;
52-
throw error;
53-
}
52+
throwErrorIfExists( nextRunError );
5453
realConnection.run( statement, parameters, collector );
5554
}
5655

@@ -69,6 +68,7 @@ public void pullAll( Collector collector )
6968
@Override
7069
public void reset()
7170
{
71+
throwErrorIfExists( nextResetError );
7272
realConnection.reset();
7373
}
7474

@@ -132,8 +132,22 @@ public BoltServerAddress boltServerAddress()
132132
return realConnection.boltServerAddress();
133133
}
134134

135-
public void setNextRunFailure( RuntimeException nextRunFailure )
135+
public void setNextRunError( RuntimeException error )
136+
{
137+
nextRunError.set( error );
138+
}
139+
140+
public void setNextResetError( RuntimeException error )
136141
{
137-
this.nextRunFailure = nextRunFailure;
142+
nextResetError.set( error );
143+
}
144+
145+
private static void throwErrorIfExists( AtomicReference<RuntimeException> errorReference )
146+
{
147+
RuntimeException error = errorReference.getAndSet( null );
148+
if ( error != null )
149+
{
150+
throw error;
151+
}
138152
}
139153
}

driver/src/test/java/org/neo4j/driver/internal/util/ThrowingConnectionDriverFactory.java

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,8 +30,25 @@
3030

3131
public class ThrowingConnectionDriverFactory extends DriverFactory
3232
{
33+
private final Clock clock;
3334
private final List<ThrowingConnection> connections = new CopyOnWriteArrayList<>();
3435

36+
public ThrowingConnectionDriverFactory()
37+
{
38+
this( Clock.SYSTEM );
39+
}
40+
41+
public ThrowingConnectionDriverFactory( Clock clock )
42+
{
43+
this.clock = clock;
44+
}
45+
46+
@Override
47+
protected Clock createClock()
48+
{
49+
return clock;
50+
}
51+
3552
@Override
3653
protected Connector createConnector( ConnectionSettings connectionSettings, SecurityPlan securityPlan,
3754
Logging logging )
@@ -44,4 +61,11 @@ public List<ThrowingConnection> getConnections()
4461
{
4562
return new ArrayList<>( connections );
4663
}
64+
65+
public List<ThrowingConnection> pollConnections()
66+
{
67+
List<ThrowingConnection> result = new ArrayList<>( connections );
68+
connections.clear();
69+
return result;
70+
}
4771
}

driver/src/test/java/org/neo4j/driver/v1/integration/CausalClusteringIT.java

Lines changed: 56 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
package org.neo4j.driver.v1.integration;
2020

2121
import org.junit.After;
22+
import org.junit.AfterClass;
2223
import org.junit.Rule;
2324
import org.junit.Test;
2425

@@ -35,8 +36,6 @@
3536

3637
import org.neo4j.driver.internal.cluster.RoutingSettings;
3738
import org.neo4j.driver.internal.retry.RetrySettings;
38-
import org.neo4j.driver.internal.util.Clock;
39-
import org.neo4j.driver.internal.util.ConnectionTrackingDriverFactory;
4039
import org.neo4j.driver.internal.util.FakeClock;
4140
import org.neo4j.driver.internal.util.ThrowingConnection;
4241
import org.neo4j.driver.internal.util.ThrowingConnectionDriverFactory;
@@ -70,6 +69,7 @@
7069
import static org.hamcrest.Matchers.instanceOf;
7170
import static org.hamcrest.Matchers.startsWith;
7271
import static org.junit.Assert.assertEquals;
72+
import static org.junit.Assert.assertFalse;
7373
import static org.junit.Assert.assertNotNull;
7474
import static org.junit.Assert.assertNull;
7575
import 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

Comments
 (0)