diff --git a/driver/src/test/java/org/neo4j/driver/stress/CausalClusteringIT.java b/driver/src/test/java/org/neo4j/driver/stress/CausalClusteringIT.java index e274c0b062..022e3858a0 100644 --- a/driver/src/test/java/org/neo4j/driver/stress/CausalClusteringIT.java +++ b/driver/src/test/java/org/neo4j/driver/stress/CausalClusteringIT.java @@ -26,7 +26,6 @@ import java.net.URI; import java.util.ArrayList; import java.util.Arrays; -import java.util.Collections; import java.util.List; import java.util.Map; import java.util.Set; @@ -40,7 +39,6 @@ import java.util.concurrent.TimeoutException; import java.util.concurrent.atomic.AtomicBoolean; import java.util.function.Function; -import java.util.stream.Collectors; import org.neo4j.driver.AccessMode; import org.neo4j.driver.AuthToken; @@ -70,7 +68,6 @@ import org.neo4j.driver.internal.util.ServerVersion; import org.neo4j.driver.internal.util.ThrowingMessageEncoder; import org.neo4j.driver.internal.util.io.ChannelTrackingDriverFactory; -import org.neo4j.driver.net.ServerAddress; import org.neo4j.driver.summary.ResultSummary; import org.neo4j.driver.util.cc.Cluster; import org.neo4j.driver.util.cc.ClusterExtension; @@ -329,140 +326,6 @@ void beginTransactionThrowsForInvalidBookmark() } } - @Test - void shouldHandleGracefulLeaderSwitch() throws Exception - { - Cluster cluster = clusterRule.getCluster(); - ClusterMember leader = cluster.leader(); - ServerAddress clusterAddress = ServerAddress.of( "cluster", 7687 ); - URI clusterUri = URI.create( String.format( "neo4j://%s:%d", clusterAddress.host(), clusterAddress.port() ) ); - Set coreAddresses = cluster.cores().stream() - .map( ClusterMember::getBoltAddress ) - .collect( Collectors.toSet() ); - - Config config = Config.builder() - .withLogging( none() ) - .withResolver( address -> address.equals( clusterAddress ) ? coreAddresses : Collections.singleton( address ) ) - .build(); - - try ( Driver driver = GraphDatabase.driver( clusterUri, clusterRule.getDefaultAuthToken(), config ) ) - { - Session session1 = driver.session(); - Transaction tx1 = session1.beginTransaction(); - - // gracefully stop current leader to force re-election - cluster.stop( leader ); - - assertThrows( (Class) SessionExpiredException.class, - () -> tx1.run( "CREATE (person:Person {name: $name, title: $title})", - parameters( "name", "Webber", "title", "Mr" ) ) ); - - session1.close(); - - Bookmark bookmark = inExpirableSession( driver, Driver::session, session -> - { - try ( Transaction tx = session.beginTransaction() ) - { - tx.run( "CREATE (person:Person {name: $name, title: $title})", - parameters( "name", "Webber", "title", "Mr" ) ); - tx.commit(); - } - return session.lastBookmark(); - } ); - - try ( Session session2 = driver.session( - builder().withDefaultAccessMode( AccessMode.READ ).withBookmarks( bookmark ).build() ); - Transaction tx2 = session2.beginTransaction() ) - { - Record record = tx2.run( "MATCH (n:Person) RETURN COUNT(*) AS count" ).next(); - tx2.commit(); - assertEquals( 1, record.get( "count" ).asInt() ); - } - } - } - - @Test - void shouldNotServeWritesWhenMajorityOfCoresAreDead() - { - Cluster cluster = clusterRule.getCluster(); - ClusterMember leader = cluster.leader(); - - try ( Driver driver = createDriver( leader.getRoutingUri() ) ) - { - Set cores = cluster.cores(); - for ( ClusterMember follower : cluster.followers() ) - { - cluster.stop( follower ); - } - awaitLeaderToStepDown( cores ); - - // now we should be unable to write because majority of cores is down - for ( int i = 0; i < 10; i++ ) - { - assertThrows( SessionExpiredException.class, () -> - { - try ( Session session = driver.session( builder().withDefaultAccessMode( AccessMode.WRITE ).build() ) ) - { - session.run( "CREATE (p:Person {name: 'Gamora'})" ).consume(); - } - } ); - } - } - } - - @Test - void shouldServeReadsWhenMajorityOfCoresAreDead() - { - Cluster cluster = clusterRule.getCluster(); - ClusterMember leader = cluster.leader(); - - try ( Driver driver = createDriver( leader.getRoutingUri() ) ) - { - Bookmark bookmark; - try ( Session session = driver.session() ) - { - int writeResult = session.writeTransaction( tx -> - { - Result result = tx.run( "CREATE (:Person {name: 'Star Lord'}) RETURN 42" ); - return result.single().get( 0 ).asInt(); - } ); - - assertEquals( 42, writeResult ); - bookmark = session.lastBookmark(); - } - - ensureNodeVisible( cluster, "Star Lord", bookmark ); - - Set cores = cluster.cores(); - for ( ClusterMember follower : cluster.followers() ) - { - cluster.stop( follower ); - } - awaitLeaderToStepDown( cores ); - - // now we should be unable to write because majority of cores is down - assertThrows( SessionExpiredException.class, () -> - { - try ( Session session = driver.session( builder().withDefaultAccessMode( AccessMode.WRITE ).build() ) ) - { - session.run( "CREATE (p:Person {name: 'Gamora'})" ).consume(); - } - } ); - - // but we should be able to read from the remaining core or read replicas - try ( Session session = driver.session() ) - { - int count = session.readTransaction( tx -> - { - Result result = tx.run( "MATCH (:Person {name: 'Star Lord'}) RETURN COUNT(*)" ); - return result.single().get( 0 ).asInt(); - } ); - - assertEquals( 1, count ); - } - } - } - @Test void shouldAcceptMultipleBookmarks() throws Exception { diff --git a/driver/src/test/java/org/neo4j/driver/util/cc/Cluster.java b/driver/src/test/java/org/neo4j/driver/util/cc/Cluster.java index 9fdd6cdbb6..b7f5d9709e 100644 --- a/driver/src/test/java/org/neo4j/driver/util/cc/Cluster.java +++ b/driver/src/test/java/org/neo4j/driver/util/cc/Cluster.java @@ -19,12 +19,8 @@ package org.neo4j.driver.util.cc; import java.io.FileNotFoundException; -import java.net.InetAddress; -import java.net.URI; -import java.net.UnknownHostException; import java.nio.file.Path; import java.util.HashSet; -import java.util.List; import java.util.Map; import java.util.Set; import java.util.concurrent.ThreadLocalRandom; @@ -32,7 +28,6 @@ import org.neo4j.driver.Bookmark; import org.neo4j.driver.Driver; -import org.neo4j.driver.Record; import org.neo4j.driver.internal.BoltServerAddress; import org.neo4j.driver.util.TestUtil; import org.neo4j.driver.util.cc.ClusterMemberRoleDiscoveryFactory.ClusterMemberRoleDiscovery; @@ -147,31 +142,6 @@ public void start( ClusterMember member ) waitForMembersToBeOnline(); } - public void startOfflineMembers() - { - // copy offline members to avoid ConcurrentModificationException - Set currentlyOfflineMembers = new HashSet<>( offlineMembers ); - for ( ClusterMember member : currentlyOfflineMembers ) - { - startNoWait( member ); - } - waitForMembersToBeOnline(); - } - - public void stop( ClusterMember member ) - { - removeOfflineMember( member ); - SharedCluster.stop( member ); - waitForMembersToBeOnline(); - } - - public void kill( ClusterMember member ) - { - removeOfflineMember( member ); - SharedCluster.kill( member ); - waitForMembersToBeOnline(); - } - public Driver getDirectDriver( ClusterMember member ) { return clusterDrivers.getDriver( member ); @@ -219,15 +189,6 @@ private void addOfflineMember( ClusterMember member ) members.add( member ); } - private void removeOfflineMember( ClusterMember member ) - { - if ( !members.remove( member ) ) - { - throw new IllegalArgumentException( "Unknown cluster member " + member ); - } - offlineMembers.add( member ); - } - private void startNoWait( ClusterMember member ) { addOfflineMember( member ); @@ -389,32 +350,6 @@ private static Set extractBoltAddresses( Set m return addresses; } - private static BoltServerAddress extractBoltAddress( Record record ) - { - List addresses = record.get( "addresses" ).asList(); - String boltUriString = (String) addresses.get( 0 ); - URI boltUri = URI.create( boltUriString ); - return newBoltServerAddress( boltUri ); - } - - private static BoltServerAddress newBoltServerAddress( URI uri ) - { - try - { - return new BoltServerAddress( InetAddress.getByName( uri.getHost() ).getHostAddress(), uri.getPort() ); - } - catch ( UnknownHostException e ) - { - throw new RuntimeException( "Unable to resolve host to IP in URI: '" + uri + "'" ); - } - } - - private static ClusterMemberRole extractRole( Record record ) - { - String roleString = record.get( "role" ).asString(); - return ClusterMemberRole.valueOf( roleString.toUpperCase() ); - } - private static ClusterMember findByBoltAddress( BoltServerAddress boltAddress, Set members ) { for ( ClusterMember member : members ) diff --git a/driver/src/test/java/org/neo4j/driver/util/cc/ClusterExtension.java b/driver/src/test/java/org/neo4j/driver/util/cc/ClusterExtension.java index ea50cb65a3..add7438fc0 100644 --- a/driver/src/test/java/org/neo4j/driver/util/cc/ClusterExtension.java +++ b/driver/src/test/java/org/neo4j/driver/util/cc/ClusterExtension.java @@ -100,7 +100,6 @@ public void beforeAll( ExtensionContext context ) throws Exception public void afterEach( ExtensionContext context ) { Cluster cluster = getCluster(); - cluster.startOfflineMembers(); cluster.deleteData(); }