@Test public void addingAnIndexingRuleShouldSucceed() { // WHEN IndexDefinition index = createIndex( db, label, propertyKey ); // THEN assertThat( getIndexes( db, label ), containsOnly( index ) ); }
@Test public void addingACompositeIndexingRuleShouldSucceed() { // WHEN IndexDefinition index = createIndex( db, label, propertyKey, secondPropertyKey ); // THEN assertThat( getIndexes( db, label ), containsOnly( index ) ); }
@Test public void droppingExistingIndexRuleShouldSucceed() { // GIVEN IndexDefinition index = createIndex( db, label, propertyKey ); // WHEN dropIndex( index ); // THEN assertThat( getIndexes( db, label ), isEmpty() ); }
@Test public void shouldKeepFailedIndexesAsFailedAfterRestart() throws Exception { // Given IndexPopulator indexPopulator = mock( IndexPopulator.class ); when( mockedIndexProvider.getPopulator( any( StoreIndexDescriptor.class ), any( IndexSamplingConfig.class ) ) ) .thenReturn( indexPopulator ); IndexAccessor indexAccessor = mock( IndexAccessor.class ); when( mockedIndexProvider.getOnlineAccessor( any( StoreIndexDescriptor.class ), any( IndexSamplingConfig.class ) ) ) .thenReturn( indexAccessor ); startDb(); createIndex( myLabel ); rotateLogsAndCheckPoint(); // And Given killDb(); when( mockedIndexProvider.getInitialState( any( StoreIndexDescriptor.class ) ) ) .thenReturn( InternalIndexState.FAILED ); // When startDb(); // Then assertThat( getIndexes( db, myLabel ), inTx( db, hasSize( 1 ) ) ); assertThat( getIndexes( db, myLabel ), inTx( db, haveState( db, Schema.IndexState.FAILED ) ) ); verify( mockedIndexProvider, times( 2 ) ) .getPopulator( any( StoreIndexDescriptor.class ), any( IndexSamplingConfig.class ) ); }
assertThat( getIndexes( db, myLabel ), inTx( db, hasSize( 1 ) ) ); assertThat( getIndexes( db, myLabel ), inTx( db, haveState( db, Schema.IndexState.POPULATING ) ) ); verify( mockedIndexProvider, times( 2 ) ) .getPopulator( any( StoreIndexDescriptor.class ), any( IndexSamplingConfig.class ) );
assertThat( getIndexes( db, myLabel ), inTx( db, hasSize( 1 ) ) ); assertThat( getIndexes( db, myLabel ), inTx( db, haveState( db, Schema.IndexState.POPULATING ) ) ); verify( mockedIndexProvider, times( 2 ) ) .getPopulator( any( StoreIndexDescriptor.class ), any( IndexSamplingConfig.class ) );
assertThat( getIndexes( db, myLabel ), inTx( db, hasSize( 1 ) ) ); assertThat( getIndexes( db, myLabel ), inTx( db, haveState( db, Schema.IndexState.ONLINE ) ) ); verify( mockedIndexProvider, times( 1 ) ) .getPopulator( any( StoreIndexDescriptor.class ), any( IndexSamplingConfig.class ) );
@Test public void droppingAnUnexistingIndexShouldGiveHelpfulExceptionInSeparateTransactions() { // GIVEN IndexDefinition index = createIndex( db, label, propertyKey ); dropIndex( index ); // WHEN try { dropIndex( index ); fail( "Should not be able to drop index twice" ); } catch ( ConstraintViolationException e ) { assertThat( e.getMessage(), containsString( "No such INDEX ON :MY_LABEL(my_property_key)." ) ); } // THEN assertThat( "Index should have been deleted", getIndexes( db, label ), not( contains( index ) ) ); }
@Test public void shouldHandleRestartIndexThatHasNotComeOnlineYet() { // Given startDb(); createIndex(); // And Given stopDb(); provider.setInitialIndexState( POPULATING ); // When startDb(); assertThat( getIndexes( db, myLabel ), inTx( db, not( haveState( db, Schema.IndexState.FAILED ) ) ) ); assertEquals( 2, provider.populatorCallCount.get() ); }
@Test public void droppingAnUnexistingIndexShouldGiveHelpfulExceptionInSameTransaction() { // GIVEN IndexDefinition index = createIndex( db, label, propertyKey ); // WHEN try ( Transaction tx = db.beginTx() ) { index.drop(); try { index.drop(); fail( "Should not be able to drop index twice" ); } catch ( ConstraintViolationException e ) { assertThat( e.getMessage(), containsString( "No such INDEX ON :MY_LABEL(my_property_key)." ) ); } tx.success(); } // THEN assertThat( "Index should have been deleted", getIndexes( db, label ), not( contains( index ) ) ); }
@Test public void shouldRecreateDroppedIndex() { // GIVEN Node node = createNode( db, propertyKey, "Neo", label ); // create an index IndexDefinition index = createIndex( db, label, propertyKey ); waitForIndex( db, index ); // delete the index right away dropIndex( index ); // WHEN recreating that index createIndex( db, label, propertyKey ); waitForIndex( db, index ); // THEN it should exist and be usable assertThat( getIndexes( db, label ), contains( index ) ); assertThat( findNodesByLabelAndProperty( label, propertyKey, "Neo", db ), containsOnly( node ) ); }
@Test public void shouldHandleRestartOfOnlineIndex() { // Given startDb(); createIndex(); provider.awaitFullyPopulated(); // And Given stopDb(); provider.setInitialIndexState( ONLINE ); // When startDb(); // Then assertThat( getIndexes( db, myLabel ), inTx( db, haveState( db, Schema.IndexState.ONLINE ) ) ); assertEquals( 1, provider.populatorCallCount.get() ); assertEquals( 2, provider.writerCallCount.get() ); }
@Test public void recoveryAfterCreateAndDropIndex() throws Exception { // GIVEN IndexDefinition indexDefinition = createIndex( db, label, propertyKey ); createSomeData( label, propertyKey ); doStuff( db, label, propertyKey ); dropIndex( indexDefinition ); doStuff( db, label, propertyKey ); // WHEN crashAndRestart(); // THEN assertThat( getIndexes( db, label ), isEmpty() ); }
@Test public void addingAnIndexingRuleInNestedTxShouldSucceed() { IndexDefinition index; // WHEN IndexDefinition indexDef; try ( Transaction tx = db.beginTx() ) { try ( Transaction nestedTransaction = db.beginTx() ) { indexDef = db.schema().indexFor( label ).on( propertyKey ).create(); nestedTransaction.success(); } index = indexDef; tx.success(); } waitForIndex( db, indexDef ); // THEN assertThat( getIndexes( db, label ), containsOnly( index ) ); }
@Documented( "Drop index" ) @Test @GraphDescription.Graph( nodes = {} ) public void drop_index() { data.get(); String labelName = labels.newInstance(); String propertyKey = properties.newInstance(); IndexDefinition schemaIndex = createIndex( labelName, propertyKey ); assertThat( Neo4jMatchers.getIndexes( graphdb(), label( labelName ) ), containsOnly( schemaIndex ) ); gen.get() .expectedStatus( 204 ) .delete( getSchemaIndexLabelPropertyUri( labelName, propertyKey ) ) .entity(); assertThat( Neo4jMatchers.getIndexes( graphdb(), label( labelName ) ), not( containsOnly( schemaIndex ) ) ); }
@Test public void shouldBeAbleToDropIndexWhileItIsPopulating() { // GIVEN startDb(); DoubleLatch populationCompletionLatch = provider.installPopulationJobCompletionLatch(); IndexDefinition index = createIndex(); populationCompletionLatch.waitForAllToStart(); // await population job to start // WHEN dropIndex( index, populationCompletionLatch ); // THEN assertThat( getIndexes( db, myLabel ), inTx( db, hasSize( 0 ) ) ); try { getIndexState( db, index ); fail( "This index should have been deleted" ); } catch ( NotFoundException e ) { assertThat( e.getMessage(), CoreMatchers.containsString( myLabel.name() ) ); } }
@Test public void shouldIndexArraysPostPopulation() { long[] arrayPropertyValue = {42, 23, 87}; Node node1; try ( Transaction tx = db.beginTx() ) { node1 = createNode( label, propertyKey, arrayPropertyValue ); tx.success(); } createIndex( db, label, propertyKey ); restart(); assertThat( getIndexes( db, label ), inTx( db, haveState( db, IndexState.ONLINE ) ) ); assertThat( findNodesByLabelAndProperty( label, propertyKey, arrayPropertyValue, db ), containsOnly( node1 ) ); assertThat( findNodesByLabelAndProperty( label, propertyKey, new long[]{42, 23}, db ), isEmpty() ); assertThat( findNodesByLabelAndProperty( label, propertyKey, Arrays.toString( arrayPropertyValue ), db ), isEmpty() ); }
@Test public void shouldIndexArrays() { long[] arrayPropertyValue = {42, 23, 87}; createIndex( db, label, propertyKey ); Node node1; try ( Transaction tx = db.beginTx() ) { node1 = createNode( label, propertyKey, arrayPropertyValue ); tx.success(); } restart(); assertThat( getIndexes( db, label ), inTx( db, haveState( db, IndexState.ONLINE ) )); assertThat( findNodesByLabelAndProperty( label, propertyKey, arrayPropertyValue, db ), containsOnly( node1 ) ); assertThat( findNodesByLabelAndProperty( label, propertyKey, new long[]{42, 23}, db ), isEmpty() ); assertThat( findNodesByLabelAndProperty( label, propertyKey, Arrays.toString( arrayPropertyValue ), db ), isEmpty() ); }
@Test public void shouldIndexStringArrays() { String[] arrayPropertyValue = {"A, B", "C"}; createIndex( db, label, propertyKey ); Node node1; try ( Transaction tx = db.beginTx() ) { node1 = createNode( label, propertyKey, arrayPropertyValue ); tx.success(); } restart(); assertThat( getIndexes( db, label ), inTx( db, haveState( db, IndexState.ONLINE ) ) ); assertThat( findNodesByLabelAndProperty( label, propertyKey, arrayPropertyValue, db ), containsOnly( node1 ) ); assertThat( findNodesByLabelAndProperty( label, propertyKey, new String[]{"A", "B, C"}, db ), isEmpty() ); assertThat( findNodesByLabelAndProperty( label, propertyKey, Arrays.toString( arrayPropertyValue ), db ), isEmpty() ); }