Browse files

Adds two more tests considered to be edge-cases. Nice-to-haves

  • Loading branch information...
1 parent b0e39b4 commit fbf1d57c65cbd620f0568f8a8f9c773f3a605427 @tinwelint tinwelint committed Mar 22, 2013
View
53 community/kernel/src/test/java/org/neo4j/graphdb/IndexingAcceptanceTest.java
@@ -23,6 +23,7 @@
import static org.hamcrest.core.IsEqual.equalTo;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertThat;
+import static org.junit.Assert.fail;
import static org.neo4j.helpers.collection.Iterables.count;
import static org.neo4j.helpers.collection.Iterables.single;
import static org.neo4j.helpers.collection.IteratorUtil.asSet;
@@ -32,13 +33,65 @@
import java.util.Map;
import java.util.Set;
+import org.hamcrest.CoreMatchers;
import org.junit.Rule;
import org.junit.Test;
import org.neo4j.graphdb.schema.IndexDefinition;
import org.neo4j.test.ImpermanentDatabaseRule;
public class IndexingAcceptanceTest
{
+ @Test
+ public void shouldHandleAddingDataToAsWellAsDeletingIndexInTheSameTransaction() throws Exception
+ {
+ // GIVEN
+ GraphDatabaseService beansAPI = dbRule.getGraphDatabaseAPI();
+ IndexDefinition index = null;
+ Labels label = Labels.MY_LABEL;
+ String key = "key";
+ {
+ Transaction tx = beansAPI.beginTx();
+ try
+ {
+ Node node = beansAPI.createNode( label );
+ node.setProperty( key, "value" );
+ index = beansAPI.schema().indexCreator( label ).on( key ).create();
+ tx.success();
+ }
+ finally
+ {
+ tx.finish();
+ }
+ beansAPI.schema().awaitIndexOnline( index, 10, SECONDS );
+ }
+
+ // WHEN
+ Transaction tx = beansAPI.beginTx();
+ try
+ {
+ Node node = beansAPI.createNode( label );
+ node.setProperty( key, "other value" );
+ index.drop();
+ tx.success();
+ }
+ finally
+ {
+ tx.finish();
+ }
+
+ // THEN
+ assertEquals( asSet(), asSet( beansAPI.schema().getIndexes( label ) ) );
+ try
+ {
+ beansAPI.schema().getIndexState( index );
+ fail( "Should not succeed" );
+ }
+ catch ( NotFoundException e )
+ {
+ assertThat( e.getMessage(), CoreMatchers.containsString( label.name() ) );
+ }
+ }
+
/* This test is a bit interesting. It tests a case where we've got a property that sits in one
* property block and the value is of a long type. So given that plus that there's an index for that
* label/property, do an update that changes the long value into a value that requires two property blocks.
View
74 community/kernel/src/test/java/org/neo4j/kernel/impl/api/index/IndexRestartIt.java
@@ -23,25 +23,30 @@
import static org.hamcrest.core.IsEqual.equalTo;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertThat;
+import static org.junit.Assert.fail;
import static org.mockito.Mockito.mock;
import static org.neo4j.graphdb.DynamicLabel.label;
import static org.neo4j.helpers.collection.IteratorUtil.asCollection;
+import static org.neo4j.helpers.collection.IteratorUtil.asSet;
import static org.neo4j.helpers.collection.IteratorUtil.single;
import static org.neo4j.kernel.api.index.InternalIndexState.ONLINE;
import static org.neo4j.kernel.api.index.InternalIndexState.POPULATING;
import static org.neo4j.kernel.impl.api.index.SchemaIndexTestHelper.singleInstanceSchemaIndexProviderFactory;
import static org.neo4j.test.DoubleLatch.awaitLatch;
+import java.io.IOException;
import java.util.Arrays;
import java.util.Collection;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.atomic.AtomicInteger;
+import org.hamcrest.CoreMatchers;
import org.junit.After;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.neo4j.graphdb.Label;
+import org.neo4j.graphdb.NotFoundException;
import org.neo4j.graphdb.Transaction;
import org.neo4j.graphdb.schema.IndexDefinition;
import org.neo4j.graphdb.schema.Schema;
@@ -51,11 +56,41 @@
import org.neo4j.kernel.api.index.InternalIndexState;
import org.neo4j.kernel.api.index.SchemaIndexProvider;
import org.neo4j.kernel.extension.KernelExtensionFactory;
+import org.neo4j.test.DoubleLatch;
import org.neo4j.test.EphemeralFileSystemRule;
import org.neo4j.test.TestGraphDatabaseFactory;
public class IndexRestartIt
{
+ /* This is somewhat difficult to test since dropping an index while it's populating forces it to be cancelled
+ * first (and also awaiting cancellation to complete). So this is a best-effort to have the timing as close
+ * as possible. If this proves to be flaky, remove it right away.
+ */
+ @Test
+ public void shouldBeAbleToDropIndexWhileItIsPopulating() throws Exception
+ {
+ // GIVEN
+ startDb();
+ DoubleLatch populationCompletionLatch = provider.installPopulationJobCompletionLatch();
+ IndexDefinition index = createIndex();
+ populationCompletionLatch.awaitStart(); // await population job to start
+
+ // WHEN
+ dropIndex( index, populationCompletionLatch );
+
+ // THEN
+ assertEquals( asSet(), asSet( db.schema().getIndexes( myLabel ) ) );
+ try
+ {
+ db.schema().getIndexState( index );
+ fail( "This index should have been deleted" );
+ }
+ catch ( NotFoundException e )
+ {
+ assertThat( e.getMessage(), CoreMatchers.containsString( myLabel.name() ) );
+ }
+ }
+
@Test
public void shouldHandleRestartOfOnlineIndex() throws Exception
{
@@ -105,7 +140,7 @@ public void shouldHandleRestartIndexThatHasNotComeOnlineYet() throws Exception
private void startDb()
{
- if(db != null)
+ if ( db != null )
db.shutdown();
db = (GraphDatabaseAPI) factory.newImpermanentDatabase();
@@ -132,12 +167,13 @@ public void after() throws Exception
db.shutdown();
}
- private void createIndex()
+ private IndexDefinition createIndex()
{
Transaction tx = db.beginTx();
- db.schema().indexCreator( myLabel ).on( "number_of_bananas_owned" ).create();
+ IndexDefinition index = db.schema().indexCreator( myLabel ).on( "number_of_bananas_owned" ).create();
tx.success();
tx.finish();
+ return index;
}
private IndexDefinition getSingleIndex()
@@ -147,9 +183,24 @@ private IndexDefinition getSingleIndex()
return single( indexes );
}
+ private void dropIndex( IndexDefinition index, DoubleLatch populationCompletionLatch )
+ {
+ Transaction tx = db.beginTx();
+ try
+ {
+ index.drop();
+ populationCompletionLatch.finish();
+ tx.success();
+ }
+ finally
+ {
+ tx.finish();
+ }
+ }
+
private class ControlledSchemaIndexProvider extends SchemaIndexProvider
{
- private final IndexPopulator mockedPopulator = mock( IndexPopulator.class );
+ private IndexPopulator mockedPopulator = new IndexPopulator.Adapter();
private final IndexAccessor mockedWriter = mock( IndexAccessor.class );
private final CountDownLatch writerLatch = new CountDownLatch( 1 );
private InternalIndexState initialIndexState = POPULATING;
@@ -162,6 +213,21 @@ public ControlledSchemaIndexProvider()
setInitialIndexState( initialIndexState );
}
+ DoubleLatch installPopulationJobCompletionLatch()
+ {
+ final DoubleLatch populationCompletionLatch = new DoubleLatch();
+ mockedPopulator = new IndexPopulator.Adapter()
+ {
+ @Override
+ public void create() throws IOException
+ {
+ populationCompletionLatch.startAndAwaitFinish();
+ super.create();
+ }
+ };
+ return populationCompletionLatch;
+ }
+
public void awaitFullyPopulated()
{
awaitLatch( writerLatch );

0 comments on commit fbf1d57

Please sign in to comment.