Skip to content

Commit

Permalink
Improve flaky AppsIT
Browse files Browse the repository at this point in the history
Test `canTerminateAnActiveCommand` tried to execute a really
heavyweight query with large collection. This made it flaky.
Now it executes query that blocks on a node lock.
  • Loading branch information
lutovich committed Sep 7, 2017
1 parent 618db39 commit c7dc29d
Show file tree
Hide file tree
Showing 2 changed files with 32 additions and 15 deletions.
Expand Up @@ -230,15 +230,14 @@ public void executeCommandExpectingException( String command, String errorMessag
try try
{ {
shellClient.evaluate( command, output ); shellClient.evaluate( command, output );
fail( "Was expecting an exception" ); fail( "Was expecting an exception but got output: '" + output.asString() + "'" );
} }
catch ( ShellException e ) catch ( ShellException e )
{ {
String errorMessage = e.getMessage(); String message = e.getMessage();
if ( !errorMessage.toLowerCase().contains( errorMessageShouldContain.toLowerCase() ) ) if ( !message.toLowerCase().contains( errorMessageShouldContain.toLowerCase() ) )
{ {
fail( "Error message '" + errorMessage + "' should have contained '" + errorMessageShouldContain + fail( "Error message '" + message + "' should have contained '" + errorMessageShouldContain + "'" );
"'" );
} }
} }
} }
Expand Down
38 changes: 28 additions & 10 deletions community/shell/src/test/java/org/neo4j/shell/AppsIT.java
Expand Up @@ -28,7 +28,6 @@
import java.io.Serializable; import java.io.Serializable;
import java.rmi.RemoteException; import java.rmi.RemoteException;
import java.util.Map; import java.util.Map;
import java.util.concurrent.ForkJoinPool;
import java.util.concurrent.Future; import java.util.concurrent.Future;
import java.util.regex.Pattern; import java.util.regex.Pattern;


Expand All @@ -49,14 +48,18 @@
import org.neo4j.shell.kernel.GraphDatabaseShellServer; import org.neo4j.shell.kernel.GraphDatabaseShellServer;
import org.neo4j.test.rule.SuppressOutput; import org.neo4j.test.rule.SuppressOutput;


import static java.util.concurrent.CompletableFuture.runAsync;
import static java.util.concurrent.TimeUnit.MINUTES;
import static org.hamcrest.core.IsNot.not; import static org.hamcrest.core.IsNot.not;
import static org.hamcrest.core.StringContains.containsString; import static org.hamcrest.core.StringContains.containsString;
import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull; import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertThat; import static org.junit.Assert.assertThat;
import static org.junit.Assert.fail; import static org.junit.Assert.fail;
import static org.mockito.Mockito.mock; import static org.mockito.Mockito.mock;
import static org.neo4j.function.Predicates.await;
import static org.neo4j.graphdb.Direction.OUTGOING; import static org.neo4j.graphdb.Direction.OUTGOING;
import static org.neo4j.graphdb.Label.label; import static org.neo4j.graphdb.Label.label;
import static org.neo4j.graphdb.RelationshipType.withName; import static org.neo4j.graphdb.RelationshipType.withName;
Expand Down Expand Up @@ -1170,17 +1173,15 @@ public void canTerminateAnActiveCommand() throws Exception
TransactionStats txStats = db.getDependencyResolver().resolveDependency( TransactionStats.class ); TransactionStats txStats = db.getDependencyResolver().resolveDependency( TransactionStats.class );
assertEquals( 0, txStats.getNumberOfActiveTransactions() ); assertEquals( 0, txStats.getNumberOfActiveTransactions() );


createNodeAndLockItInDifferentThread( "Person", "id", 42 );

Serializable clientId = shellClient.getId(); Serializable clientId = shellClient.getId();
Future<?> result = ForkJoinPool.commonPool().submit( () -> Future<?> result = runAsync( () ->
{ {
try try
{ {
while ( txStats.getNumberOfActiveTransactions() == 0 ) // await 2 active transactions: one that locked node and one that wants to update property via cypher
{ await( () -> txStats.getNumberOfActiveTransactions() == 2, 1, MINUTES );
Thread.sleep( 10 );
}
assertEquals( 1, txStats.getNumberOfActiveTransactions() );

shellServer.terminate( clientId ); shellServer.terminate( clientId );
} }
catch ( Exception e ) catch ( Exception e )
Expand All @@ -1189,8 +1190,7 @@ public void canTerminateAnActiveCommand() throws Exception
} }
} ); } );


executeCommandExpectingException( "FOREACH(i IN range(0, " + Integer.MAX_VALUE + ") | CREATE ());", executeCommandExpectingException( "MATCH (p:Person {id: 42}) SET p.id = 24 RETURN p;", "has been terminated" );
"has been terminated" );
assertNull( result.get() ); assertNull( result.get() );
} }


Expand Down Expand Up @@ -1310,4 +1310,22 @@ private String createCsvFile( long size ) throws IOException, InterruptedExcepti
} }
return tmpFile.toURI().toURL().toExternalForm(); return tmpFile.toURI().toURL().toExternalForm();
} }

private void createNodeAndLockItInDifferentThread( String label, String property, Object value ) throws Exception
{
try ( Transaction tx = db.beginTx() )
{
db.createNode( label( label ) ).setProperty( property, value );
tx.success();
}

runAsync( () ->
{
Transaction tx = db.beginTx();
Node node = db.findNode( label( "Person" ), "id", 42L );
assertNotNull( node );
tx.acquireWriteLock( node );
} ).get( 1, MINUTES );
}

} }

0 comments on commit c7dc29d

Please sign in to comment.