Skip to content

Commit

Permalink
Improves on testing with more cases
Browse files Browse the repository at this point in the history
  • Loading branch information
tinwelint committed Sep 22, 2017
1 parent 65e8a97 commit ff7a680
Showing 1 changed file with 108 additions and 28 deletions.
Expand Up @@ -19,10 +19,14 @@
*/ */
package org.neo4j.graphdb.schema; package org.neo4j.graphdb.schema;


import org.junit.Before;
import org.junit.Rule; import org.junit.Rule;
import org.junit.Test; import org.junit.Test;


import java.util.ArrayList;
import java.util.HashSet;
import java.util.List; import java.util.List;
import java.util.Set;


import org.neo4j.graphdb.Label; import org.neo4j.graphdb.Label;
import org.neo4j.graphdb.Transaction; import org.neo4j.graphdb.Transaction;
Expand All @@ -31,7 +35,7 @@
import org.neo4j.test.rule.ImpermanentDatabaseRule; import org.neo4j.test.rule.ImpermanentDatabaseRule;


import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertEquals;

import static org.junit.Assert.assertTrue;
import static org.neo4j.helpers.collection.Iterables.asList; import static org.neo4j.helpers.collection.Iterables.asList;


public class ConcurrentCreateDropIndexIT public class ConcurrentCreateDropIndexIT
Expand All @@ -41,57 +45,65 @@ public class ConcurrentCreateDropIndexIT
@Rule @Rule
public final DatabaseRule db = new ImpermanentDatabaseRule(); public final DatabaseRule db = new ImpermanentDatabaseRule();


@Test private final int threads = Runtime.getRuntime().availableProcessors();
public void shouldTest() throws Throwable
@Before
public void createTokens()
{ {
// GIVEN all the required labels created, to not disturb timings in racing threads later
int threads = Runtime.getRuntime().availableProcessors();
try ( Transaction tx = db.beginTx() ) try ( Transaction tx = db.beginTx() )
{ {
for ( int i = 0; i < threads; i++ ) for ( int i = 0; i < threads; i++ )
{ {
db.createNode( label( i ) ); db.createNode( label( i ) ).setProperty( KEY, i );
} }
tx.success(); tx.success();
} }
}


@Test
public void concurrentCreatingOfIndexesShouldNotInterfere() throws Throwable
{
// WHEN concurrently creating indexes for different labels // WHEN concurrently creating indexes for different labels
Race race = new Race(); Race race = new Race();
for ( int i = 0; i < threads; i++ ) for ( int i = 0; i < threads; i++ )
{ {
int yo = i; race.addContestant( indexCreate( i ), 1 );
race.addContestant( () ->
{
try ( Transaction tx = db.beginTx() )
{
db.schema().indexFor( label( yo ) ).on( KEY ).create();
tx.success();
}
}, 1 );
} }
race.go(); race.go();


// THEN they should all be observed as existing in the end // THEN they should all be observed as existing in the end
List<IndexDefinition> indexes;
try ( Transaction tx = db.beginTx() ) try ( Transaction tx = db.beginTx() )
{ {
indexes = asList( db.schema().getIndexes() ); List<IndexDefinition> indexes = asList( db.schema().getIndexes() );
assertEquals( threads, indexes.size() );
Set<String> labels = new HashSet<>();
for ( IndexDefinition index : indexes )
{
assertTrue( labels.add( index.getLabel().name() ) );
}
tx.success(); tx.success();
} }
assertEquals( threads, indexes.size() ); }


// and WHEN dropping them @Test
race = new Race(); public void concurrentDroppingOfIndexesShouldNotInterfere() throws Throwable
for ( IndexDefinition index : indexes ) {
// GIVEN created indexes
List<IndexDefinition> indexes = new ArrayList<>();
try ( Transaction tx = db.beginTx() )
{ {
race.addContestant( () -> for ( int i = 0; i < threads; i++ )
{ {
try ( Transaction tx = db.beginTx() ) indexes.add( db.schema().indexFor( label( i ) ).on( KEY ).create() );
{ }
index.drop(); tx.success();
tx.success(); }
}
}, 1 ); // WHEN dropping them
Race race = new Race();
for ( IndexDefinition index : indexes )
{
race.addContestant( indexDrop( index ), 1 );
} }
race.go(); race.go();


Expand All @@ -103,6 +115,74 @@ public void shouldTest() throws Throwable
} }
} }


@Test
public void concurrentMixedCreatingAndDroppingOfIndexesShouldNotInterfere() throws Throwable
{
// GIVEN created indexes
List<IndexDefinition> indexesToDrop = new ArrayList<>();
int creates = threads / 2;
int drops = threads - creates;
try ( Transaction tx = db.beginTx() )
{
for ( int i = 0; i < drops; i++ )
{
indexesToDrop.add( db.schema().indexFor( label( i ) ).on( KEY ).create() );
}
tx.success();
}

// WHEN dropping them
Race race = new Race();
Set<String> expectedIndexedLabels = new HashSet<>();
for ( int i = 0; i < creates; i++ )
{
expectedIndexedLabels.add( label( drops + i ).name() );
race.addContestant( indexCreate( drops + i ), 1 );
}
for ( IndexDefinition index : indexesToDrop )
{
race.addContestant( indexDrop( index ), 1 );
}
race.go();

// THEN they should all be observed as dropped in the end
try ( Transaction tx = db.beginTx() )
{
List<IndexDefinition> indexes = asList( db.schema().getIndexes() );
assertEquals( creates, indexes.size() );
tx.success();

for ( IndexDefinition index : indexes )
{
assertTrue( expectedIndexedLabels.remove( index.getLabel().name() ) );
}
}
}

private Runnable indexCreate( int labelIndex )
{
return () ->
{
try ( Transaction tx = db.beginTx() )
{
db.schema().indexFor( label( labelIndex ) ).on( KEY ).create();
tx.success();
}
};
}

private Runnable indexDrop( IndexDefinition index )
{
return () ->
{
try ( Transaction tx = db.beginTx() )
{
index.drop();
tx.success();
}
};
}

private static Label label( int i ) private static Label label( int i )
{ {
return Label.label( "L" + i ); return Label.label( "L" + i );
Expand Down

0 comments on commit ff7a680

Please sign in to comment.