Skip to content

Commit 7310fdf

Browse files
committed
Unflake couple CC integration tests
New test 'shouldKeepOperatingWhenConnectionsBreak' was flaky because it's reads sometimes failed with `EntityNotFoundException`. Test itself does not remove any nodes. It stepped on transactions created by previous data cleanup that is executed between tests. That cleanup did not actually wait for all cluster members to observe removals. This commit makes cleanup procedure use bookmark and count nodes on all cluster members.
1 parent b8ff396 commit 7310fdf

File tree

4 files changed

+109
-22
lines changed

4 files changed

+109
-22
lines changed

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

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -632,6 +632,7 @@ public void shouldRediscoverWhenConnectionsToAllCoresBreak()
632632
@Test
633633
public void shouldKeepOperatingWhenConnectionsBreak() throws Exception
634634
{
635+
long testRunTimeMs = MINUTES.toMillis( 1 );
635636
String label = "Person";
636637
String property = "name";
637638
String value = "Tony Stark";
@@ -641,8 +642,13 @@ public void shouldKeepOperatingWhenConnectionsBreak() throws Exception
641642
AtomicBoolean stop = new AtomicBoolean();
642643
executor = newExecutor();
643644

645+
Config config = Config.build()
646+
.withLogging( DEV_NULL_LOGGING )
647+
.withMaxTransactionRetryTime( testRunTimeMs, MILLISECONDS )
648+
.toConfig();
649+
644650
try ( Driver driver = driverFactory.newInstance( cluster.leader().getRoutingUri(), clusterRule.getDefaultAuthToken(),
645-
defaultRoutingSettings(), RetrySettings.DEFAULT, configWithoutLogging() ) )
651+
defaultRoutingSettings(), RetrySettings.DEFAULT, config ) )
646652
{
647653
List<Future<?>> results = new ArrayList<>();
648654

@@ -665,7 +671,7 @@ public void shouldKeepOperatingWhenConnectionsBreak() throws Exception
665671
{
666672
connection.setNextRunError( new ServiceUnavailableException( "Unable to execute query" ) );
667673
}
668-
SECONDS.sleep( 5 ); // sleep a bit to allow readers and writers to progress
674+
SECONDS.sleep( 10 ); // sleep a bit to allow readers and writers to progress
669675
}
670676
stop.set( true );
671677

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
/*
2+
* Copyright (c) 2002-2018 "Neo Technology,"
3+
* Network Engine for Objects in Lund AB [http://neotechnology.com]
4+
*
5+
* This file is part of Neo4j.
6+
*
7+
* Licensed under the Apache License, Version 2.0 (the "License");
8+
* you may not use this file except in compliance with the License.
9+
* You may obtain a copy of the License at
10+
*
11+
* http://www.apache.org/licenses/LICENSE-2.0
12+
*
13+
* Unless required by applicable law or agreed to in writing, software
14+
* distributed under the License is distributed on an "AS IS" BASIS,
15+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16+
* See the License for the specific language governing permissions and
17+
* limitations under the License.
18+
*/
19+
package org.neo4j.driver.v1.util;
20+
21+
import org.neo4j.driver.v1.Driver;
22+
import org.neo4j.driver.v1.Session;
23+
import org.neo4j.driver.v1.StatementResult;
24+
import org.neo4j.driver.v1.Transaction;
25+
import org.neo4j.driver.v1.TransactionWork;
26+
27+
public final class TestUtil
28+
{
29+
private TestUtil()
30+
{
31+
}
32+
33+
public static long countNodes( Driver driver, String bookmark )
34+
{
35+
try ( Session session = driver.session( bookmark ) )
36+
{
37+
return session.readTransaction( new TransactionWork<Long>()
38+
{
39+
@Override
40+
public Long execute( Transaction tx )
41+
{
42+
return tx.run( "MATCH (n) RETURN count(n)" ).single().get( 0 ).asLong();
43+
}
44+
} );
45+
}
46+
}
47+
48+
public static String cleanDb( Driver driver )
49+
{
50+
try ( Session session = driver.session() )
51+
{
52+
cleanDb( session );
53+
return session.lastBookmark();
54+
}
55+
}
56+
57+
private static void cleanDb( Session session )
58+
{
59+
int nodesDeleted;
60+
do
61+
{
62+
nodesDeleted = deleteBatchOfNodes( session );
63+
}
64+
while ( nodesDeleted > 0 );
65+
}
66+
67+
private static int deleteBatchOfNodes( Session session )
68+
{
69+
return session.writeTransaction( new TransactionWork<Integer>()
70+
{
71+
@Override
72+
public Integer execute( Transaction tx )
73+
{
74+
StatementResult result = tx.run( "MATCH (n) WITH n LIMIT 10000 DETACH DELETE n RETURN count(n)" );
75+
return result.single().get( 0 ).asInt();
76+
}
77+
} );
78+
}
79+
}

driver/src/test/java/org/neo4j/driver/v1/util/cc/Cluster.java

Lines changed: 18 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,6 @@
2929
import java.util.concurrent.TimeUnit;
3030

3131
import org.neo4j.driver.internal.net.BoltServerAddress;
32-
import org.neo4j.driver.internal.util.Consumer;
3332
import org.neo4j.driver.v1.AccessMode;
3433
import org.neo4j.driver.v1.AuthTokens;
3534
import org.neo4j.driver.v1.Config;
@@ -38,8 +37,11 @@
3837
import org.neo4j.driver.v1.Record;
3938
import org.neo4j.driver.v1.Session;
4039
import org.neo4j.driver.v1.StatementResult;
40+
import org.neo4j.driver.v1.util.TestUtil;
4141

4242
import static java.util.Collections.unmodifiableSet;
43+
import static org.junit.Assert.assertEquals;
44+
import static org.junit.Assert.assertNotNull;
4345
import static org.neo4j.driver.internal.util.Iterables.single;
4446
import static org.neo4j.driver.v1.Config.TrustStrategy.trustAllCertificates;
4547

@@ -80,26 +82,23 @@ public Path getPath()
8082

8183
public void deleteData()
8284
{
83-
leaderTx( new Consumer<Session>()
85+
// execute write query to remove all nodes and retreive bookmark
86+
String bookmark;
87+
try ( Driver driver = createDriver( leader().getBoltUri(), password ) )
8488
{
85-
@Override
86-
public void accept( Session session )
87-
{
88-
session.run( "MATCH (n) DETACH DELETE n" ).consume();
89-
}
90-
} );
91-
}
89+
bookmark = TestUtil.cleanDb( driver );
90+
assertNotNull( "Cleanup of the database did not produce a bookmark", bookmark );
91+
}
9292

93-
public ClusterMember leaderTx( Consumer<Session> tx )
94-
{
95-
ClusterMember leader = leader();
96-
try ( Driver driver = createDriver( leader.getBoltUri(), password );
97-
Session session = driver.session() )
93+
// ensure that every cluster member is up-to-date and contains no nodes
94+
for ( ClusterMember member : members )
9895
{
99-
tx.accept( session );
96+
try ( Driver driver = createDriver( member.getBoltUri(), password ) )
97+
{
98+
long nodeCount = TestUtil.countNodes( driver, bookmark );
99+
assertEquals( "Not all nodes have been deleted. " + nodeCount + " still there somehow ", 0L, nodeCount );
100+
}
100101
}
101-
102-
return leader;
103102
}
104103

105104
public Set<ClusterMember> members()
@@ -314,13 +313,13 @@ private static Driver createDriver( Set<ClusterMember> members, String password
314313

315314
private static List<Record> findClusterOverview( Session session )
316315
{
317-
StatementResult result = session.run( "call dbms.cluster.overview" );
316+
StatementResult result = session.run( "CALL dbms.cluster.overview()" );
318317
return result.list();
319318
}
320319

321320
private static boolean isCoreMember( Session session )
322321
{
323-
Record record = single( session.run( "call dbms.cluster.role" ).list() );
322+
Record record = single( session.run( "CALL dbms.cluster.role()" ).list() );
324323
ClusterMemberRole role = extractRole( record );
325324
return role != ClusterMemberRole.READ_REPLICA;
326325
}

driver/src/test/java/org/neo4j/driver/v1/util/cc/ClusterRule.java

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -133,7 +133,10 @@ public void run()
133133
{
134134
try
135135
{
136-
SharedCluster.kill();
136+
if ( SharedCluster.exists() )
137+
{
138+
SharedCluster.kill();
139+
}
137140
}
138141
catch ( Throwable t )
139142
{

0 commit comments

Comments
 (0)