Skip to content

Commit

Permalink
Some test code deduplication and comment fix
Browse files Browse the repository at this point in the history
  • Loading branch information
tinwelint committed May 16, 2018
1 parent c150611 commit c8f2e0e
Show file tree
Hide file tree
Showing 2 changed files with 39 additions and 103 deletions.
Expand Up @@ -109,6 +109,9 @@

/**
* Collects all Kernel API operations and guards them from being used outside of transaction.
*
* Many methods assume cursors to be initialized before use in private methods, even if they're not passed in explicitly.
* Keep that in mind: e.g. nodeCursor, propertyCursor and relationshipCursor
*/
public class Operations implements Write, ExplicitIndexWrite, SchemaWrite
{
Expand Down Expand Up @@ -295,7 +298,9 @@ private boolean nodeDelete( long node, boolean lock ) throws AutoIndexingKernelE
return false;
}

// Assuming that the nodeCursor have been initialized to the node that labels are retrieved from
/**
* Assuming that the nodeCursor have been initialized to the node that labels are retrieved from
*/
private void acquireSharedNodeLabelLocks()
{
ktx.statementLocks().optimistic().acquireShared( ktx.lockTracer(), ResourceTypes.LABEL, nodeCursor.labels().all() );
Expand Down
Expand Up @@ -23,6 +23,8 @@
import org.junit.Test;

import java.util.concurrent.TimeUnit;
import java.util.function.LongConsumer;
import java.util.function.LongFunction;

import org.neo4j.graphdb.Node;
import org.neo4j.graphdb.Transaction;
Expand All @@ -45,138 +47,62 @@ public class UpdateDeletedIndexIT
@Test
public void shouldHandleUpdateRemovalOfLabelConcurrentlyWithIndexDrop() throws Throwable
{
// given
long[] nodes = createNodes();
IndexDefinition indexDefinition = createIndex();

// when
Race race = new Race();
race.addContestant( indexDropper( indexDefinition ), 1 );
for ( int i = 0; i < NODES; i++ )
{
race.addContestant( nodeLabelRemover( nodes[i] ) );
}

// then
race.go();
shouldHandleIndexDropConcurrentlyWithOperation( nodeId -> db.getNodeById( nodeId ).removeLabel( LABEL ) );
}

@Test
public void shouldHandleDeleteNodeConcurrentlyWithIndexDrop() throws Throwable
{
// given
long[] nodes = createNodes();
IndexDefinition indexDefinition = createIndex();

// when
Race race = new Race();
race.addContestant( indexDropper( indexDefinition ), 1 );
for ( int i = 0; i < NODES; i++ )
{
race.addContestant( nodeDeleter( nodes[i] ) );
}

// then
race.go();
shouldHandleIndexDropConcurrentlyWithOperation( nodeId -> db.getNodeById( nodeId ).delete() );
}

@Test
public void shouldHandleRemovePropertyConcurrentlyWithIndexDrop() throws Throwable
{
// given
long[] nodes = createNodes();
IndexDefinition indexDefinition = createIndex();

// when
Race race = new Race();
race.addContestant( indexDropper( indexDefinition ), 1 );
for ( int i = 0; i < NODES; i++ )
{
race.addContestant( nodePropertyRemover( nodes[i] ) );
}

// then
race.go();
shouldHandleIndexDropConcurrentlyWithOperation( nodeId -> db.getNodeById( nodeId ).removeProperty( KEY ) );
}

@Test
public void shouldHandleNodeDetachDeleteConcurrentlyWithIndexDrop() throws Throwable
{
shouldHandleIndexDropConcurrentlyWithOperation( nodeId ->
{
ThreadToStatementContextBridge txBridge = db.getDependencyResolver().resolveDependency( ThreadToStatementContextBridge.class );
txBridge.getKernelTransactionBoundToThisThread( true ).dataWrite().nodeDetachDelete( nodeId );
} );
}

private void shouldHandleIndexDropConcurrentlyWithOperation( NodeOperation operation ) throws Throwable
{
// given
long[] nodes = createNodes();
IndexDefinition indexDefinition = createIndex();

// when
Race race = new Race();
race.addContestant( indexDropper( indexDefinition ), 1 );
for ( int i = 0; i < NODES; i++ )
{
race.addContestant( nodeDetachDeleter( nodes[i] ) );
}

// then
race.go();
}

private Runnable indexDropper( IndexDefinition indexDefinition )
{
return () ->
race.addContestant( () ->
{
try ( Transaction tx = db.beginTx() )
{
indexDefinition.drop();
tx.success();
}
};
}

private Runnable nodeLabelRemover( long nodeId )
{
return () ->
{
try ( Transaction tx = db.beginTx() )
{
db.getNodeById( nodeId ).removeLabel( LABEL );
tx.success();
}
};
}

private Runnable nodeDeleter( long nodeId )
{
return () ->
{
try ( Transaction tx = db.beginTx() )
{
db.getNodeById( nodeId ).delete();
tx.success();
}
};
}

private Runnable nodeDetachDeleter( long nodeId )
{
return throwing( () ->
}, 1 );
for ( int i = 0; i < NODES; i++ )
{
try ( Transaction tx = db.beginTx() )
final long nodeId = nodes[i];
race.addContestant( throwing( () ->
{
db.getDependencyResolver().resolveDependency( ThreadToStatementContextBridge.class ).getKernelTransactionBoundToThisThread(
true ).dataWrite().nodeDetachDelete( nodeId );
tx.success();
}
} );
}
try ( Transaction tx = db.beginTx() )
{
operation.run( nodeId );
tx.success();
}
} ) );
}

private Runnable nodePropertyRemover( long nodeId )
{
return () ->
{
try ( Transaction tx = db.beginTx() )
{
db.getNodeById( nodeId ).removeProperty( KEY );
tx.success();
}
};
// then
race.go();
}

private long[] createNodes()
Expand Down Expand Up @@ -218,4 +144,9 @@ private IndexDefinition createIndex()
}
return indexDefinition;
}

private interface NodeOperation
{
void run( long nodeId ) throws Exception;
}
}

0 comments on commit c8f2e0e

Please sign in to comment.