diff --git a/community/kernel/src/test/java/org/neo4j/kernel/impl/index/schema/fusion/FusionIndexAccessorTest.java b/community/kernel/src/test/java/org/neo4j/kernel/impl/index/schema/fusion/FusionIndexAccessorTest.java index 4cbd8d4e5967f..e3fe98b040678 100644 --- a/community/kernel/src/test/java/org/neo4j/kernel/impl/index/schema/fusion/FusionIndexAccessorTest.java +++ b/community/kernel/src/test/java/org/neo4j/kernel/impl/index/schema/fusion/FusionIndexAccessorTest.java @@ -23,6 +23,8 @@ import org.junit.Test; import java.io.IOException; +import java.util.Arrays; +import java.util.List; import java.util.Set; import org.neo4j.helpers.collection.BoundedIterable; @@ -58,6 +60,7 @@ public class FusionIndexAccessorTest private FusionIndexAccessor fusionIndexAccessor; private final long indexId = 10; private final DropAction dropAction = mock( DropAction.class ); + private List allAccessors; @Before public void setup() @@ -66,6 +69,7 @@ public void setup() spatialAccessor = mock( IndexAccessor.class ); temporalAccessor = mock( IndexAccessor.class ); luceneAccessor = mock( IndexAccessor.class ); + allAccessors = Arrays.asList(nativeAccessor, spatialAccessor, temporalAccessor, luceneAccessor); fusionIndexAccessor = new FusionIndexAccessor( nativeAccessor, spatialAccessor, temporalAccessor, luceneAccessor, new FusionSelector(), indexId, mock( IndexDescriptor.class ), dropAction ); } @@ -73,15 +77,16 @@ public void setup() /* drop */ @Test - public void dropMustDropNativeAndLucene() throws Exception + public void dropMustDropAll() throws Exception { // when - // ... both drop successful + // ... all drop successful fusionIndexAccessor.drop(); // then - verify( nativeAccessor, times( 1 ) ).drop(); - verify( spatialAccessor, times( 1 ) ).drop(); - verify( luceneAccessor, times( 1 ) ).drop(); + for ( IndexAccessor accessor : allAccessors ) + { + verify( accessor, times( 1 ) ).drop(); + } verify( dropAction ).drop( indexId ); } @@ -99,6 +104,20 @@ public void dropMustThrowIfDropSpatialFail() throws Exception verifyFailOnSingleDropFailure( spatialAccessor, fusionIndexAccessor ); } + @Test + public void dropMustThrowIfDropTemporalFail() throws Exception + { + // when + verifyFailOnSingleDropFailure( temporalAccessor, fusionIndexAccessor ); + } + + @Test + public void dropMustThrowIfDropLuceneFail() throws Exception + { + // when + verifyFailOnSingleDropFailure( luceneAccessor, fusionIndexAccessor ); + } + @Test public void fusionIndexIsDirtyWhenNativeIndexIsDirty() { @@ -109,10 +128,21 @@ public void fusionIndexIsDirtyWhenNativeIndexIsDirty() } @Test - public void dropMustThrowIfDropLuceneFail() throws Exception + public void fusionIndexIsDirtyWhenSpatialIndexIsDirty() { - // when - verifyFailOnSingleDropFailure( luceneAccessor, fusionIndexAccessor ); + when( spatialAccessor.isDirty() ).thenReturn( true ).thenReturn( false ); + + assertTrue( fusionIndexAccessor.isDirty() ); + assertFalse( fusionIndexAccessor.isDirty() ); + } + + @Test + public void fusionIndexIsDirtyWhenTemporalIndexIsDirty() + { + when( temporalAccessor.isDirty() ).thenReturn( true ).thenReturn( false ); + + assertTrue( fusionIndexAccessor.isDirty() ); + assertFalse( fusionIndexAccessor.isDirty() ); } private void verifyFailOnSingleDropFailure( IndexAccessor failingAccessor, FusionIndexAccessor fusionIndexAccessor ) @@ -132,14 +162,16 @@ private void verifyFailOnSingleDropFailure( IndexAccessor failingAccessor, Fusio } @Test - public void dropMustThrowIfBothFail() throws Exception + public void dropMustThrowIfAllFail() throws Exception { // given IOException nativeFailure = new IOException( "native" ); IOException spatialFailure = new IOException( "spatial" ); + IOException temporalFailure = new IOException( "temporal" ); IOException luceneFailure = new IOException( "lucene" ); doThrow( nativeFailure ).when( nativeAccessor ).drop(); doThrow( spatialFailure ).when( spatialAccessor ).drop(); + doThrow( temporalFailure ).when( temporalAccessor ).drop(); doThrow( luceneFailure ).when( luceneAccessor ).drop(); try @@ -151,23 +183,28 @@ public void dropMustThrowIfBothFail() throws Exception catch ( IOException e ) { // then - assertThat( e, anyOf( sameInstance( nativeFailure ), sameInstance( spatialFailure ), sameInstance( luceneFailure ) ) ); + assertThat( e, anyOf( + sameInstance( nativeFailure ), + sameInstance( spatialFailure ), + sameInstance( temporalFailure ), + sameInstance( luceneFailure ) ) ); } } /* close */ @Test - public void closeMustCloseNativeAndLucene() throws Exception + public void closeMustCloseAll() throws Exception { // when - // ... both drop successful + // ... all close successful fusionIndexAccessor.close(); // then - verify( nativeAccessor, times( 1 ) ).close(); - verify( spatialAccessor, times( 1 ) ).close(); - verify( luceneAccessor, times( 1 ) ).close(); + for ( IndexAccessor accessor : allAccessors ) + { + verify( accessor, times( 1 ) ).close(); + } } @Test @@ -182,6 +219,12 @@ public void closeMustThrowIfSpatialThrow() throws Exception verifyFusionCloseThrowOnSingleCloseThrow( spatialAccessor, fusionIndexAccessor ); } + @Test + public void closeMustThrowIfTemporalThrow() throws Exception + { + verifyFusionCloseThrowOnSingleCloseThrow( temporalAccessor, fusionIndexAccessor ); + } + @Test public void closeMustThrowIfNativeThrow() throws Exception { @@ -191,100 +234,162 @@ public void closeMustThrowIfNativeThrow() throws Exception @Test public void closeMustCloseOthersIfLuceneThrow() throws Exception { - verifyOtherIsClosedOnSingleThrow( luceneAccessor, fusionIndexAccessor, nativeAccessor, spatialAccessor ); + verifyOtherIsClosedOnSingleThrow( luceneAccessor, fusionIndexAccessor, nativeAccessor, spatialAccessor, temporalAccessor ); } @Test public void closeMustCloseOthersIfSpatialThrow() throws Exception { - verifyOtherIsClosedOnSingleThrow( spatialAccessor, fusionIndexAccessor, nativeAccessor, luceneAccessor ); + verifyOtherIsClosedOnSingleThrow( spatialAccessor, fusionIndexAccessor, nativeAccessor, temporalAccessor, luceneAccessor ); + } + + @Test + public void closeMustCloseOthersIfTemporalThrow() throws Exception + { + verifyOtherIsClosedOnSingleThrow( temporalAccessor, fusionIndexAccessor, nativeAccessor, spatialAccessor, luceneAccessor ); } @Test public void closeMustCloseOthersIfNativeThrow() throws Exception { - verifyOtherIsClosedOnSingleThrow( nativeAccessor, fusionIndexAccessor, luceneAccessor, spatialAccessor ); + verifyOtherIsClosedOnSingleThrow( nativeAccessor, fusionIndexAccessor, luceneAccessor, spatialAccessor, temporalAccessor ); } @Test public void closeMustThrowIfAllFail() throws Exception { - verifyFusionCloseThrowIfAllThrow( fusionIndexAccessor, nativeAccessor, spatialAccessor, luceneAccessor ); + verifyFusionCloseThrowIfAllThrow( fusionIndexAccessor, nativeAccessor, spatialAccessor, temporalAccessor, luceneAccessor ); } // newAllEntriesReader @Test - public void allEntriesReaderMustCombineResultFromNativeAndLucene() + public void allEntriesReaderMustCombineResultFromAll() { // given - long[] nativeEntries = {0, 1, 2, 5, 6}; - long[] luceneEntries = {3, 4, 7, 8}; - mockAllEntriesReaders( nativeEntries, luceneEntries ); + long[] nativeEntries = {0, 1, 6, 13, 14}; + long[] spatialEntries = {2, 5, 9}; + long[] temporalEntries = {4, 8, 11}; + long[] luceneEntries = {3, 7, 10, 12}; + mockAllEntriesReaders( nativeEntries, spatialEntries, temporalEntries, luceneEntries ); // when Set result = Iterables.asSet( fusionIndexAccessor.newAllEntriesReader() ); // then assertResultContainsAll( result, nativeEntries ); + assertResultContainsAll( result, spatialEntries ); + assertResultContainsAll( result, temporalEntries ); assertResultContainsAll( result, luceneEntries ); } @Test - public void allEntriesReaderMustCombineResultFromNativeAndLuceneWithEmptyNative() + public void allEntriesReaderMustCombineResultFromAllWithEmptyNative() { // given long[] nativeEntries = new long[0]; + long[] spatialEntries = {2, 5, 9}; + long[] temporalEntries = {4, 8, 11}; long[] luceneEntries = {3, 4, 7, 8}; - mockAllEntriesReaders( nativeEntries, luceneEntries ); + mockAllEntriesReaders( nativeEntries, spatialEntries, temporalEntries, luceneEntries ); + + // when + Set result = Iterables.asSet( fusionIndexAccessor.newAllEntriesReader() ); + + // then + assertResultContainsAll( result, nativeEntries ); + assertResultContainsAll( result, spatialEntries ); + assertResultContainsAll( result, temporalEntries ); + assertResultContainsAll( result, luceneEntries ); + } + @Test + public void allEntriesReaderMustCombineResultFromAllWithEmptySpatial() + { + // given + long[] nativeEntries = {0, 1, 6, 13, 14}; + long[] spatialEntries = new long[0]; + long[] temporalEntries = {4, 8, 11}; + long[] luceneEntries = {3, 7, 10, 12}; + mockAllEntriesReaders( nativeEntries, spatialEntries, temporalEntries, luceneEntries ); + + // when + Set result = Iterables.asSet( fusionIndexAccessor.newAllEntriesReader() ); + + // then + assertResultContainsAll( result, nativeEntries ); + assertResultContainsAll( result, spatialEntries ); + assertResultContainsAll( result, temporalEntries ); + assertResultContainsAll( result, luceneEntries ); + } + + @Test + public void allEntriesReaderMustCombineResultFromAllWithEmptyTemporal() + { + // given + long[] nativeEntries = {0, 1, 6, 13, 14}; + long[] spatialEntries = {2, 5, 9}; + long[] temporalEntries = new long[0]; + long[] luceneEntries = {3, 7, 10, 12}; + mockAllEntriesReaders( nativeEntries, spatialEntries, temporalEntries, luceneEntries ); // when Set result = Iterables.asSet( fusionIndexAccessor.newAllEntriesReader() ); // then assertResultContainsAll( result, nativeEntries ); + assertResultContainsAll( result, spatialEntries ); + assertResultContainsAll( result, temporalEntries ); assertResultContainsAll( result, luceneEntries ); } @Test - public void allEntriesReaderMustCombineResultFromNativeAndLuceneWithEmptyLucene() + public void allEntriesReaderMustCombineResultFromAllWithEmptyLucene() { // given long[] nativeEntries = {0, 1, 2, 5, 6}; + long[] spatialEntries = {2, 5, 9}; + long[] temporalEntries = {4, 8, 11}; long[] luceneEntries = new long[0]; - mockAllEntriesReaders( nativeEntries, luceneEntries ); + mockAllEntriesReaders( nativeEntries, spatialEntries, temporalEntries, luceneEntries ); // when Set result = Iterables.asSet( fusionIndexAccessor.newAllEntriesReader() ); // then assertResultContainsAll( result, nativeEntries ); + assertResultContainsAll( result, spatialEntries ); + assertResultContainsAll( result, temporalEntries ); assertResultContainsAll( result, luceneEntries ); } @Test - public void allEntriesReaderMustCombineResultFromNativeAndLuceneBothEmpty() + public void allEntriesReaderMustCombineResultFromAllEmpty() { // given long[] nativeEntries = new long[0]; + long[] spatialEntries = new long[0]; + long[] temporalEntries = new long[0]; long[] luceneEntries = new long[0]; - mockAllEntriesReaders( nativeEntries, luceneEntries ); + mockAllEntriesReaders( nativeEntries, spatialEntries, temporalEntries, luceneEntries ); // when Set result = Iterables.asSet( fusionIndexAccessor.newAllEntriesReader() ); // then assertResultContainsAll( result, nativeEntries ); + assertResultContainsAll( result, spatialEntries ); + assertResultContainsAll( result, temporalEntries ); assertResultContainsAll( result, luceneEntries ); assertTrue( result.isEmpty() ); } @Test - public void allEntriesReaderMustCloseBothNativeAndLucene() throws Exception + public void allEntriesReaderMustCloseAll() throws Exception { // given BoundedIterable nativeAllEntriesReader = mockSingleAllEntriesReader( nativeAccessor, new long[0] ); BoundedIterable spatialAllEntriesReader = mockSingleAllEntriesReader( spatialAccessor, new long[0] ); + BoundedIterable temporalAllEntriesReader = mockSingleAllEntriesReader( temporalAccessor, new long[0] ); BoundedIterable luceneAllEntriesReader = mockSingleAllEntriesReader( luceneAccessor, new long[0] ); // when @@ -293,6 +398,7 @@ public void allEntriesReaderMustCloseBothNativeAndLucene() throws Exception // then verify( nativeAllEntriesReader, times( 1 ) ).close(); verify( spatialAllEntriesReader, times( 1 ) ).close(); + verify( temporalAllEntriesReader, times( 1 ) ).close(); verify( luceneAllEntriesReader, times( 1 ) ).close(); } @@ -302,37 +408,58 @@ public void allEntriesReaderMustCloseNativeIfLuceneThrow() throws Exception // given BoundedIterable nativeAllEntriesReader = mockSingleAllEntriesReader( nativeAccessor, new long[0] ); BoundedIterable spatialAllEntriesReader = mockSingleAllEntriesReader( spatialAccessor, new long[0] ); + BoundedIterable temporalAllEntriesReader = mockSingleAllEntriesReader( temporalAccessor, new long[0] ); BoundedIterable luceneAllEntriesReader = mockSingleAllEntriesReader( luceneAccessor, new long[0] ); // then BoundedIterable fusionAllEntriesReader = fusionIndexAccessor.newAllEntriesReader(); - verifyOtherIsClosedOnSingleThrow( luceneAllEntriesReader, fusionAllEntriesReader, nativeAllEntriesReader, spatialAllEntriesReader ); + verifyOtherIsClosedOnSingleThrow( luceneAllEntriesReader, fusionAllEntriesReader, nativeAllEntriesReader, spatialAllEntriesReader, + temporalAllEntriesReader ); } @Test - public void allEntriesReaderMustCloseLuceneIfSpatialThrow() throws Exception + public void allEntriesReaderMustCloseAllIfSpatialThrow() throws Exception { // given BoundedIterable nativeAllEntriesReader = mockSingleAllEntriesReader( nativeAccessor, new long[0] ); BoundedIterable spatialAllEntriesReader = mockSingleAllEntriesReader( spatialAccessor, new long[0] ); + BoundedIterable temporalAllEntriesReader = mockSingleAllEntriesReader( temporalAccessor, new long[0] ); BoundedIterable luceneAllEntriesReader = mockSingleAllEntriesReader( luceneAccessor, new long[0] ); // then BoundedIterable fusionAllEntriesReader = fusionIndexAccessor.newAllEntriesReader(); - verifyOtherIsClosedOnSingleThrow( spatialAllEntriesReader, fusionAllEntriesReader, luceneAllEntriesReader, nativeAllEntriesReader ); + verifyOtherIsClosedOnSingleThrow( spatialAllEntriesReader, fusionAllEntriesReader, luceneAllEntriesReader, nativeAllEntriesReader, + temporalAllEntriesReader ); } @Test - public void allEntriesReaderMustCloseLuceneIfNativeThrow() throws Exception + public void allEntriesReaderMustCloseAllIfTemporalThrow() throws Exception { // given BoundedIterable nativeAllEntriesReader = mockSingleAllEntriesReader( nativeAccessor, new long[0] ); BoundedIterable spatialAllEntriesReader = mockSingleAllEntriesReader( spatialAccessor, new long[0] ); + BoundedIterable temporalAllEntriesReader = mockSingleAllEntriesReader( temporalAccessor, new long[0] ); BoundedIterable luceneAllEntriesReader = mockSingleAllEntriesReader( luceneAccessor, new long[0] ); // then BoundedIterable fusionAllEntriesReader = fusionIndexAccessor.newAllEntriesReader(); - verifyOtherIsClosedOnSingleThrow( nativeAllEntriesReader, fusionAllEntriesReader, luceneAllEntriesReader, spatialAllEntriesReader ); + verifyOtherIsClosedOnSingleThrow( temporalAllEntriesReader, fusionAllEntriesReader, luceneAllEntriesReader, spatialAllEntriesReader, + nativeAllEntriesReader ); + } + + @Test + public void allEntriesReaderMustCloseAllIfNativeThrow() throws Exception + { + // given + BoundedIterable nativeAllEntriesReader = mockSingleAllEntriesReader( nativeAccessor, new long[0] ); + BoundedIterable spatialAllEntriesReader = mockSingleAllEntriesReader( spatialAccessor, new long[0] ); + BoundedIterable temporalAllEntriesReader = mockSingleAllEntriesReader( temporalAccessor, new long[0] ); + BoundedIterable luceneAllEntriesReader = mockSingleAllEntriesReader( luceneAccessor, new long[0] ); + + // then + BoundedIterable fusionAllEntriesReader = fusionIndexAccessor.newAllEntriesReader(); + verifyOtherIsClosedOnSingleThrow( nativeAllEntriesReader, fusionAllEntriesReader, luceneAllEntriesReader, spatialAllEntriesReader, + temporalAllEntriesReader ); } @Test @@ -341,6 +468,7 @@ public void allEntriesReaderMustThrowIfLuceneThrow() throws Exception // given mockSingleAllEntriesReader( nativeAccessor, new long[0] ); mockSingleAllEntriesReader( spatialAccessor, new long[0] ); + mockSingleAllEntriesReader( temporalAccessor, new long[0] ); BoundedIterable luceneAllEntriesReader = mockSingleAllEntriesReader( luceneAccessor, new long[0] ); // then @@ -354,6 +482,7 @@ public void allEntriesReaderMustThrowIfNativeThrow() throws Exception // given BoundedIterable nativeAllEntriesReader = mockSingleAllEntriesReader( nativeAccessor, new long[0] ); mockSingleAllEntriesReader( spatialAccessor, new long[0] ); + mockSingleAllEntriesReader( temporalAccessor, new long[0] ); mockSingleAllEntriesReader( luceneAccessor, new long[0] ); // then @@ -368,6 +497,7 @@ public void allEntriesReaderMustThrowIfSpatialThrow() throws Exception // given mockSingleAllEntriesReader( nativeAccessor, new long[0] ); BoundedIterable spatialAllEntriesReader = mockSingleAllEntriesReader( spatialAccessor, new long[0] ); + mockSingleAllEntriesReader( temporalAccessor, new long[0] ); mockSingleAllEntriesReader( luceneAccessor, new long[0] ); // then @@ -376,12 +506,28 @@ public void allEntriesReaderMustThrowIfSpatialThrow() throws Exception } + @Test + public void allEntriesReaderMustThrowIfTemporalThrow() throws Exception + { + // given + mockSingleAllEntriesReader( nativeAccessor, new long[0] ); + mockSingleAllEntriesReader( spatialAccessor, new long[0] ); + BoundedIterable temporalAllEntriesReader = mockSingleAllEntriesReader( temporalAccessor, new long[0] ); + mockSingleAllEntriesReader( luceneAccessor, new long[0] ); + + // then + BoundedIterable fusionAllEntriesReader = fusionIndexAccessor.newAllEntriesReader(); + FusionIndexTestHelp.verifyFusionCloseThrowOnSingleCloseThrow( temporalAllEntriesReader, fusionAllEntriesReader ); + + } + @Test public void allEntriesReaderMustReportUnknownMaxCountIfNativeReportUnknownMaxCount() { // given mockSingleAllEntriesReaderWithUnknownMaxCount( nativeAccessor, new long[0] ); mockSingleAllEntriesReader( spatialAccessor, new long[0] ); + mockSingleAllEntriesReader( temporalAccessor, new long[0] ); mockSingleAllEntriesReader( luceneAccessor, new long[0] ); // then @@ -395,6 +541,21 @@ public void allEntriesReaderMustReportUnknownMaxCountIfSpatialReportUnknownMaxCo // given mockSingleAllEntriesReader( nativeAccessor, new long[0] ); mockSingleAllEntriesReaderWithUnknownMaxCount( spatialAccessor, new long[0] ); + mockSingleAllEntriesReader( temporalAccessor, new long[0] ); + mockSingleAllEntriesReader( luceneAccessor, new long[0] ); + + // then + BoundedIterable fusionAllEntriesReader = fusionIndexAccessor.newAllEntriesReader(); + assertThat( fusionAllEntriesReader.maxCount(), is( BoundedIterable.UNKNOWN_MAX_COUNT ) ); + } + + @Test + public void allEntriesReaderMustReportUnknownMaxCountIfTemporalReportUnknownMaxCount() throws Exception + { + // given + mockSingleAllEntriesReader( nativeAccessor, new long[0] ); + mockSingleAllEntriesReader( spatialAccessor, new long[0] ); + mockSingleAllEntriesReaderWithUnknownMaxCount( temporalAccessor, new long[0] ); mockSingleAllEntriesReader( luceneAccessor, new long[0] ); // then @@ -408,6 +569,7 @@ public void allEntriesReaderMustReportUnknownMaxCountIfLuceneReportUnknownMaxCou // given mockSingleAllEntriesReader( nativeAccessor, new long[0] ); mockSingleAllEntriesReader( spatialAccessor, new long[0] ); + mockSingleAllEntriesReader( temporalAccessor, new long[0] ); mockSingleAllEntriesReaderWithUnknownMaxCount( luceneAccessor, new long[0] ); // then @@ -420,11 +582,12 @@ public void allEntriesReaderMustReportFusionMaxCountOfNativeAndLucene() { mockSingleAllEntriesReader( nativeAccessor, new long[]{1, 2} ); mockSingleAllEntriesReader( spatialAccessor, new long[]{3, 4} ); - mockSingleAllEntriesReader( luceneAccessor, new long[]{5, 6} ); + mockSingleAllEntriesReader( temporalAccessor, new long[]{5, 6} ); + mockSingleAllEntriesReader( luceneAccessor, new long[]{7, 8} ); // then BoundedIterable fusionAllEntriesReader = fusionIndexAccessor.newAllEntriesReader(); - assertThat( fusionAllEntriesReader.maxCount(), is( 6L ) ); + assertThat( fusionAllEntriesReader.maxCount(), is( 8L ) ); } static void assertResultContainsAll( Set result, long[] nativeEntries ) @@ -435,7 +598,7 @@ static void assertResultContainsAll( Set result, long[] nativeEntries ) } } - static BoundedIterable mockSingleAllEntriesReader( IndexAccessor targetAccessor, long[] entries ) + private static BoundedIterable mockSingleAllEntriesReader( IndexAccessor targetAccessor, long[] entries ) { BoundedIterable allEntriesReader = mockedAllEntriesReader( entries ); when( targetAccessor.newAllEntriesReader() ).thenReturn( allEntriesReader ); @@ -447,11 +610,10 @@ static BoundedIterable mockedAllEntriesReader( long... entries ) return mockedAllEntriesReader( true, entries ); } - static BoundedIterable mockSingleAllEntriesReaderWithUnknownMaxCount( IndexAccessor targetAccessor, long[] entries ) + private static void mockSingleAllEntriesReaderWithUnknownMaxCount( IndexAccessor targetAccessor, long[] entries ) { BoundedIterable allEntriesReader = mockedAllEntriesReaderUnknownMaxCount( entries ); when( targetAccessor.newAllEntriesReader() ).thenReturn( allEntriesReader ); - return allEntriesReader; } static BoundedIterable mockedAllEntriesReaderUnknownMaxCount( long... entries ) @@ -467,10 +629,11 @@ static BoundedIterable mockedAllEntriesReader( boolean knownMaxCount, long return mockedAllEntriesReader; } - private void mockAllEntriesReaders( long[] nativeEntries, long[] luceneEntries ) + private void mockAllEntriesReaders( long[] numberEntries, long[] spatialEntries, long[] temporalEntries, long[] luceneEntries ) { - mockSingleAllEntriesReader( nativeAccessor, nativeEntries ); - mockSingleAllEntriesReader( spatialAccessor, nativeEntries ); + mockSingleAllEntriesReader( nativeAccessor, numberEntries ); + mockSingleAllEntriesReader( spatialAccessor, spatialEntries ); + mockSingleAllEntriesReader( temporalAccessor, temporalEntries ); mockSingleAllEntriesReader( luceneAccessor, luceneEntries ); } } diff --git a/community/kernel/src/test/java/org/neo4j/kernel/impl/index/schema/fusion/FusionIndexPopulatorTest.java b/community/kernel/src/test/java/org/neo4j/kernel/impl/index/schema/fusion/FusionIndexPopulatorTest.java index 2df9b1ed17292..0514889db21bf 100644 --- a/community/kernel/src/test/java/org/neo4j/kernel/impl/index/schema/fusion/FusionIndexPopulatorTest.java +++ b/community/kernel/src/test/java/org/neo4j/kernel/impl/index/schema/fusion/FusionIndexPopulatorTest.java @@ -80,9 +80,10 @@ public void createMustCreateBothNativeAndLucene() throws Exception fusionIndexPopulator.create(); // then - verify( numberPopulator, times( 1 ) ).create(); - verify( spatialPopulator, times( 1 ) ).create(); - verify( lucenePopulator, times( 1 ) ).create(); + for ( IndexPopulator populator : allPopulators ) + { + verify( populator, times( 1 ) ).create(); + } } @Test @@ -113,6 +114,20 @@ public void createMustThrowIfCreateSpatialThrow() throws Exception } ); } + @Test + public void createMustThrowIfCreateTemporalThrow() throws Exception + { + // given + IOException failure = new IOException( "fail" ); + doThrow( failure ).when( temporalPopulator ).create(); + + verifyCallFail( failure, () -> + { + fusionIndexPopulator.create(); + return null; + } ); + } + @Test public void createMustThrowIfCreateLuceneThrow() throws Exception { @@ -130,15 +145,16 @@ public void createMustThrowIfCreateLuceneThrow() throws Exception /* drop */ @Test - public void dropMustDropBothNativeAndLucene() throws Exception + public void dropMustDropAll() throws Exception { // when fusionIndexPopulator.drop(); // then - verify( numberPopulator, times( 1 ) ).drop(); - verify( spatialPopulator, times( 1 ) ).drop(); - verify( lucenePopulator, times( 1 ) ).drop(); + for ( IndexPopulator populator : allPopulators ) + { + verify( populator, times( 1 ) ).drop(); + } verify( dropAction ).drop( indexId ); } @@ -170,6 +186,20 @@ public void dropMustThrowIfDropSpatialThrow() throws Exception } ); } + @Test + public void dropMustThrowIfDropTemporalThrow() throws Exception + { + // given + IOException failure = new IOException( "fail" ); + doThrow( failure ).when( temporalPopulator ).drop(); + + verifyCallFail( failure, () -> + { + fusionIndexPopulator.drop(); + return null; + } ); + } + @Test public void dropMustThrowIfDropLuceneThrow() throws Exception { @@ -192,6 +222,7 @@ public void addMustSelectCorrectPopulator() throws Exception // given Value[] numberValues = FusionIndexTestHelp.valuesSupportedByNative(); Value[] spatialValues = FusionIndexTestHelp.valuesSupportedBySpatial(); + Value[] temporalValues = FusionIndexTestHelp.valuesSupportedByTemporal(); Value[] otherValues = FusionIndexTestHelp.valuesNotSupportedByNativeOrSpatial(); Value[] allValues = FusionIndexTestHelp.allValues(); @@ -207,6 +238,12 @@ public void addMustSelectCorrectPopulator() throws Exception verifyAddWithCorrectPopulator( spatialPopulator, spatialValue ); } + // Add with temporal for temporal values + for ( Value temporalValue : temporalValues ) + { + verifyAddWithCorrectPopulator( temporalPopulator, temporalValue ); + } + // Add with lucene for other values for ( Value otherValue : otherValues ) { @@ -268,6 +305,20 @@ public void verifyDeferredConstraintsMustThrowIfSpatialThrow() throws Exception } ); } + @Test + public void verifyDeferredConstraintsMustThrowIfTemporalThrow() throws Exception + { + // given + IndexEntryConflictException failure = mock( IndexEntryConflictException.class ); + doThrow( failure ).when( temporalPopulator ).verifyDeferredConstraints( any() ); + + verifyCallFail( failure, () -> + { + fusionIndexPopulator.verifyDeferredConstraints( null ); + return null; + } ); + } + @Test public void verifyDeferredConstraintsMustThrowIfLuceneThrow() throws Exception { @@ -285,14 +336,14 @@ public void verifyDeferredConstraintsMustThrowIfLuceneThrow() throws Exception /* close */ @Test - public void successfulCloseMustCloseBothNativeAndLucene() throws Exception + public void successfulCloseMustCloseAll() throws Exception { // when closeAndVerifyPropagation( true ); } @Test - public void unsuccessfulCloseMustCloseBothNativeAndLucene() throws Exception + public void unsuccessfulCloseMustCloseAll() throws Exception { // when closeAndVerifyPropagation( false ); @@ -303,9 +354,10 @@ private void closeAndVerifyPropagation( boolean populationCompletedSuccessfully fusionIndexPopulator.close( populationCompletedSuccessfully ); // then - verify( numberPopulator, times( 1 ) ).close( populationCompletedSuccessfully ); - verify( spatialPopulator, times( 1 ) ).close( populationCompletedSuccessfully ); - verify( lucenePopulator, times( 1 ) ).close( populationCompletedSuccessfully ); + for ( IndexPopulator populator : allPopulators ) + { + verify( populator, times( 1 ) ).close( populationCompletedSuccessfully ); + } } @Test @@ -337,11 +389,11 @@ public void closeMustThrowIfCloseSpatialThrow() throws Exception } @Test - public void closeMustThrowIfCloseLuceneThrow() throws Exception + public void closeMustThrowIfCloseTemporalThrow() throws Exception { // given IOException failure = new IOException( "fail" ); - doThrow( failure ).when( lucenePopulator ).close( anyBoolean() ); + doThrow( failure ).when( temporalPopulator ).close( anyBoolean() ); verifyCallFail( failure, () -> { @@ -351,38 +403,30 @@ public void closeMustThrowIfCloseLuceneThrow() throws Exception } @Test - public void closeMustCloseOthersIfLuceneThrow() throws Exception + public void closeMustThrowIfCloseLuceneThrow() throws Exception { // given IOException failure = new IOException( "fail" ); doThrow( failure ).when( lucenePopulator ).close( anyBoolean() ); - // when - try - { - fusionIndexPopulator.close( true ); - fail( "Should have failed" ); - } - catch ( IOException ignore ) + verifyCallFail( failure, () -> { - } - - // then - verify( numberPopulator, times( 1 ) ).close( true ); - verify( spatialPopulator, times( 1 ) ).close( true ); + fusionIndexPopulator.close( anyBoolean() ); + return null; + } ); } - @Test - public void closeMustCloseOthersIfSpatialThrow() throws Exception + private static void verifyOtherCloseOnThrow( IndexPopulator throwingPopulator, FusionIndexPopulator fusionPopulator, IndexPopulator... populators ) + throws Exception { // given IOException failure = new IOException( "fail" ); - doThrow( failure ).when( spatialPopulator ).close( anyBoolean() ); + doThrow( failure ).when( throwingPopulator ).close( anyBoolean() ); // when try { - fusionIndexPopulator.close( true ); + fusionPopulator.close( true ); fail( "Should have failed" ); } catch ( IOException ignore ) @@ -390,30 +434,34 @@ public void closeMustCloseOthersIfSpatialThrow() throws Exception } // then - verify( lucenePopulator, times( 1 ) ).close( true ); - verify( numberPopulator, times( 1 ) ).close( true ); + for ( IndexPopulator populator : populators ) + { + verify( populator, times( 1 ) ).close( true ); + } } @Test - public void closeMustCloseOthersIfNativeThrow() throws Exception + public void closeMustCloseOthersIfLuceneThrow() throws Exception { - // given - IOException failure = new IOException( "fail" ); - doThrow( failure ).when( numberPopulator ).close( anyBoolean() ); + verifyOtherCloseOnThrow( lucenePopulator, fusionIndexPopulator, numberPopulator, spatialPopulator, temporalPopulator ); + } - // when - try - { - fusionIndexPopulator.close( true ); - fail( "Should have failed" ); - } - catch ( IOException ignore ) - { - } + @Test + public void closeMustCloseOthersIfSpatialThrow() throws Exception + { + verifyOtherCloseOnThrow( spatialPopulator, fusionIndexPopulator, numberPopulator, temporalPopulator, lucenePopulator ); + } - // then - verify( lucenePopulator, times( 1 ) ).close( true ); - verify( spatialPopulator, times( 1 ) ).close( true ); + @Test + public void closeMustCloseOthersIfTemporalThrow() throws Exception + { + verifyOtherCloseOnThrow( temporalPopulator, fusionIndexPopulator, numberPopulator, spatialPopulator, lucenePopulator ); + } + + @Test + public void closeMustCloseOthersIfNumberThrow() throws Exception + { + verifyOtherCloseOnThrow( numberPopulator, fusionIndexPopulator, spatialPopulator, temporalPopulator, lucenePopulator ); } @Test @@ -422,9 +470,11 @@ public void closeMustThrowIfAllThrow() throws Exception // given IOException nativeFailure = new IOException( "native" ); IOException spatialFailure = new IOException( "spatial" ); + IOException temporalFailure = new IOException( "temporal" ); IOException luceneFailure = new IOException( "lucene" ); doThrow( nativeFailure ).when( numberPopulator ).close( anyBoolean() ); doThrow( spatialFailure ).when( spatialPopulator ).close( anyBoolean() ); + doThrow( temporalFailure ).when( temporalPopulator ).close( anyBoolean() ); doThrow( luceneFailure ).when( lucenePopulator).close( anyBoolean() ); try @@ -436,7 +486,11 @@ public void closeMustThrowIfAllThrow() throws Exception catch ( IOException e ) { // then - assertThat( e, anyOf( sameInstance( nativeFailure ), sameInstance( spatialFailure ), sameInstance( luceneFailure ) ) ); + assertThat( e, anyOf( + sameInstance( nativeFailure ), + sameInstance( spatialFailure ), + sameInstance( temporalFailure ), + sameInstance( luceneFailure ) ) ); } } @@ -450,9 +504,10 @@ public void markAsFailedMustMarkAll() throws Exception fusionIndexPopulator.markAsFailed( failureMessage ); // then - verify( numberPopulator, times( 1 ) ).markAsFailed( failureMessage ); - verify( spatialPopulator, times( 1 ) ).markAsFailed( failureMessage ); - verify( lucenePopulator, times( 1 ) ).markAsFailed( failureMessage ); + for ( IndexPopulator populator : allPopulators ) + { + verify( populator, times( 1 ) ).markAsFailed( failureMessage ); + } } @Test @@ -485,6 +540,21 @@ public void markAsFailedMustThrowIfSpatialThrow() throws Exception } ); } + @Test + public void markAsFailedMustThrowIfTemporalThrow() throws Exception + { + // given + IOException failure = new IOException( "fail" ); + doThrow( failure ).when( temporalPopulator ).markAsFailed( anyString() ); + + // then + verifyCallFail( failure, () -> + { + fusionIndexPopulator.markAsFailed( anyString() ); + return null; + } ); + } + @Test public void markAsFailedMustThrowIfLuceneThrow() throws Exception { @@ -506,10 +576,12 @@ public void shouldIncludeSampleOnCorrectPopulator() // given Value[] numberValues = FusionIndexTestHelp.valuesSupportedByNative(); Value[] spatialValues = FusionIndexTestHelp.valuesSupportedBySpatial(); + Value[] temporalValues = FusionIndexTestHelp.valuesSupportedByTemporal(); Value[] otherValues = FusionIndexTestHelp.valuesNotSupportedByNativeOrSpatial(); verifySampleToCorrectPopulator( numberValues, numberPopulator ); verifySampleToCorrectPopulator( spatialValues, spatialPopulator ); + verifySampleToCorrectPopulator( temporalValues, temporalPopulator ); verifySampleToCorrectPopulator( otherValues, lucenePopulator ); } diff --git a/community/kernel/src/test/java/org/neo4j/kernel/impl/index/schema/fusion/FusionIndexReaderTest.java b/community/kernel/src/test/java/org/neo4j/kernel/impl/index/schema/fusion/FusionIndexReaderTest.java index a8255989b2331..1559d006097e1 100644 --- a/community/kernel/src/test/java/org/neo4j/kernel/impl/index/schema/fusion/FusionIndexReaderTest.java +++ b/community/kernel/src/test/java/org/neo4j/kernel/impl/index/schema/fusion/FusionIndexReaderTest.java @@ -82,9 +82,10 @@ public void closeMustCloseBothNativeAndLucene() fusionIndexReader.close(); // then - verify( nativeReader, times( 1 ) ).close(); - verify( spatialReader, times( 1 ) ).close(); - verify( luceneReader, times( 1 ) ).close(); + for ( IndexReader reader : allReaders ) + { + verify( reader, times( 1 ) ).close(); + } } // close iterator @@ -95,9 +96,11 @@ public void closeIteratorMustCloseNativeAndLucene() throws Exception // given PrimitiveLongResourceIterator nativeIter = mock( PrimitiveLongResourceIterator.class ); PrimitiveLongResourceIterator spatialIter = mock( PrimitiveLongResourceIterator.class ); + PrimitiveLongResourceIterator temporalIter = mock( PrimitiveLongResourceIterator.class ); PrimitiveLongResourceIterator luceneIter = mock( PrimitiveLongResourceIterator.class ); when( nativeReader.query( any( IndexQuery.class ) ) ).thenReturn( nativeIter ); when( spatialReader.query( any( IndexQuery.class ) ) ).thenReturn( spatialIter ); + when( temporalReader.query( any( IndexQuery.class ) ) ).thenReturn( temporalIter ); when( luceneReader.query( any( IndexQuery.class ) ) ).thenReturn( luceneIter ); // when @@ -106,6 +109,7 @@ public void closeIteratorMustCloseNativeAndLucene() throws Exception // then verify( nativeIter, times( 1 ) ).close(); verify( spatialIter, times( 1 ) ).close(); + verify( temporalIter, times( 1 ) ).close(); verify( luceneIter, times( 1 ) ).close(); } @@ -117,6 +121,7 @@ public void countIndexedNodesMustSelectCorrectReader() // given Value[] nativeValues = FusionIndexTestHelp.valuesSupportedByNative(); Value[] spatialValues = FusionIndexTestHelp.valuesSupportedBySpatial(); + Value[] temporalValues = FusionIndexTestHelp.valuesSupportedByTemporal(); Value[] otherValues = FusionIndexTestHelp.valuesNotSupportedByNativeOrSpatial(); Value[] allValues = FusionIndexTestHelp.allValues(); @@ -132,7 +137,13 @@ public void countIndexedNodesMustSelectCorrectReader() verifyCountIndexedNodesWithCorrectReader( spatialReader, spatialValue ); } - // when passing values not handled by native or spatial + // when passing temporal values + for ( Value temporalValue : temporalValues ) + { + verifyCountIndexedNodesWithCorrectReader( temporalReader, temporalValue ); + } + + // when passing values not handled by others for ( Value otherValue : otherValues ) { verifyCountIndexedNodesWithCorrectReader( luceneReader, otherValue ); @@ -197,7 +208,20 @@ public void mustSelectSpatialForExactPredicateWithSpatialValue() throws Exceptio } @Test - public void mustSelectLuceneForExactPredicateWithNonNumberAndNonSpatialValue() throws Exception + public void mustSelectTemporalForExactPredicateWithTemporalValue() throws Exception + { + // given + for ( Object temporalValue : FusionIndexTestHelp.valuesSupportedByTemporal() ) + { + IndexQuery indexQuery = IndexQuery.exact( PROP_KEY, temporalValue ); + + // then + verifyQueryWithCorrectReader( temporalReader, indexQuery ); + } + } + + @Test + public void mustSelectLuceneForExactPredicateWithOtherValue() throws Exception { // given for ( Object nonNumberOrSpatialValue : FusionIndexTestHelp.valuesNotSupportedByNativeOrSpatial() ) @@ -277,7 +301,8 @@ public void mustCombineResultFromExistsPredicate() throws Exception // given IndexQuery.ExistsPredicate exists = IndexQuery.exists( PROP_KEY ); when( nativeReader.query( exists ) ).thenReturn( PrimitiveLongResourceCollections.iterator( null, 0L, 1L, 4L, 7L ) ); - when( spatialReader.query( exists ) ).thenReturn( PrimitiveLongResourceCollections.iterator( null, 3L, 8L, 9L ) ); + when( spatialReader.query( exists ) ).thenReturn( PrimitiveLongResourceCollections.iterator( null, 3L, 9L, 10L ) ); + when( temporalReader.query( exists ) ).thenReturn( PrimitiveLongResourceCollections.iterator( null, 8L, 11L, 12L ) ); when( luceneReader.query( exists ) ).thenReturn( PrimitiveLongResourceCollections.iterator( null, 2L, 5L, 6L ) ); // when diff --git a/community/kernel/src/test/java/org/neo4j/kernel/impl/index/schema/fusion/FusionIndexTestHelp.java b/community/kernel/src/test/java/org/neo4j/kernel/impl/index/schema/fusion/FusionIndexTestHelp.java index 58fa364fe1a62..ea78daeecfa29 100644 --- a/community/kernel/src/test/java/org/neo4j/kernel/impl/index/schema/fusion/FusionIndexTestHelp.java +++ b/community/kernel/src/test/java/org/neo4j/kernel/impl/index/schema/fusion/FusionIndexTestHelp.java @@ -32,6 +32,7 @@ import org.neo4j.kernel.api.index.IndexEntryUpdate; import org.neo4j.kernel.api.schema.SchemaDescriptorFactory; import org.neo4j.values.storable.CoordinateReferenceSystem; +import org.neo4j.values.storable.DateValue; import org.neo4j.values.storable.Value; import org.neo4j.values.storable.Values; @@ -63,6 +64,11 @@ class FusionIndexTestHelp Values.pointValue( CoordinateReferenceSystem.Cartesian, 123.0, 456.0, 789.0 ), Values.pointValue( CoordinateReferenceSystem.WGS84, 13.2, 56.8 ) }; + private static final Value[] temporalValues = new Value[] + { + DateValue.epochDate( 1 ), + DateValue.epochDate( 10000 ) + }; private static final Value[] otherValues = new Value[] { Values.booleanValue( true ), @@ -91,9 +97,14 @@ static Value[] valuesSupportedBySpatial() return pointValues; } + static Value[] valuesSupportedByTemporal() + { + return temporalValues; + } + private static Value[] valuesNotSupportedByNative() { - return ArrayUtils.addAll( pointValues, otherValues ); + return ArrayUtils.addAll( temporalValues, ArrayUtils.addAll( pointValues, otherValues ) ); } static Value[] valuesNotSupportedByNativeOrSpatial() diff --git a/community/kernel/src/test/java/org/neo4j/kernel/impl/index/schema/fusion/FusionIndexUpdaterTest.java b/community/kernel/src/test/java/org/neo4j/kernel/impl/index/schema/fusion/FusionIndexUpdaterTest.java index 846a15dd3ba5b..8faadc40bb028 100644 --- a/community/kernel/src/test/java/org/neo4j/kernel/impl/index/schema/fusion/FusionIndexUpdaterTest.java +++ b/community/kernel/src/test/java/org/neo4j/kernel/impl/index/schema/fusion/FusionIndexUpdaterTest.java @@ -66,6 +66,7 @@ public void processMustSelectCorrectForAdd() throws Exception // given Value[] supportedByNative = FusionIndexTestHelp.valuesSupportedByNative(); Value[] supportedBySpatial = FusionIndexTestHelp.valuesSupportedBySpatial(); + Value[] supportedByTemporal = FusionIndexTestHelp.valuesSupportedByTemporal(); Value[] notSupportedByNativeOrSpatial = FusionIndexTestHelp.valuesNotSupportedByNativeOrSpatial(); Value[] allValues = FusionIndexTestHelp.allValues(); @@ -85,6 +86,14 @@ public void processMustSelectCorrectForAdd() throws Exception verifyAddWithCorrectUpdater( spatialUpdater, value ); } + // when + // ... value supported by temporal + for ( Value value : supportedByTemporal ) + { + //then + verifyAddWithCorrectUpdater( temporalUpdater, value ); + } + // when // ... value not supported by native for ( Value value : notSupportedByNativeOrSpatial ) @@ -109,6 +118,7 @@ public void processMustSelectCorrectForRemove() throws Exception // given Value[] supportedByNative = FusionIndexTestHelp.valuesSupportedByNative(); Value[] supportedBySpatial = FusionIndexTestHelp.valuesSupportedBySpatial(); + Value[] supportedByTemporal = FusionIndexTestHelp.valuesSupportedByTemporal(); Value[] notSupportedByNativeOrSpatial = FusionIndexTestHelp.valuesNotSupportedByNativeOrSpatial(); Value[] allValues = FusionIndexTestHelp.allValues(); @@ -128,6 +138,14 @@ public void processMustSelectCorrectForRemove() throws Exception verifyRemoveWithCorrectUpdater( spatialUpdater, value ); } + // when + // ... value supported by temporal + for ( Value value : supportedByTemporal ) + { + //then + verifyRemoveWithCorrectUpdater( temporalUpdater, value ); + } + // when // ... value not supported by native for ( Value value : notSupportedByNativeOrSpatial ) @@ -182,6 +200,24 @@ public void processMustSelectCorrectForChangeSupportedBySpatial() throws Excepti } } + @Test + public void processMustSelectCorrectForChangeSupportedByTemporal() throws Exception + { + // given + Value[] supportedByTemporal = FusionIndexTestHelp.valuesSupportedByTemporal(); + + // when + // ... before - supported + // ... after - supported + for ( Value before : supportedByTemporal ) + { + for ( Value after : supportedByTemporal ) + { + verifyChangeWithCorrectUpdaterNotMixed( temporalUpdater, before, after ); + } + } + } + @Test public void processMustSelectCorrectForChangeNotSupportedByNative() throws Exception { @@ -240,6 +276,34 @@ public void processMustSelectCorrectForChangeFromNativeToSpatialOrBack() throws verifyChangeWithCorrectUpdaterMixed( spatialUpdater, nativeUpdater, supportedBySpatial, supportedByNative ); } + @Test + public void processMustSelectCorrectForChangeFromNativeToTemporalOrBack() throws Exception + { + // given + Value[] supportedByNative = FusionIndexTestHelp.valuesSupportedByNative(); + Value[] supportedByTemporal = FusionIndexTestHelp.valuesSupportedByTemporal(); + + // when + // ... before - supported + // ... after - not supported + verifyChangeWithCorrectUpdaterMixed( nativeUpdater, temporalUpdater, supportedByNative, supportedByTemporal ); + verifyChangeWithCorrectUpdaterMixed( temporalUpdater, nativeUpdater, supportedByTemporal, supportedByNative ); + } + + @Test + public void processMustSelectCorrectForChangeFromSpatialToTemporalOrBack() throws Exception + { + // given + Value[] supportedBySpatial = FusionIndexTestHelp.valuesSupportedBySpatial(); + Value[] supportedByTemporal = FusionIndexTestHelp.valuesSupportedByTemporal(); + + // when + // ... before - supported + // ... after - not supported + verifyChangeWithCorrectUpdaterMixed( spatialUpdater, temporalUpdater, supportedBySpatial, supportedByTemporal ); + verifyChangeWithCorrectUpdaterMixed( temporalUpdater, spatialUpdater, supportedByTemporal, supportedBySpatial ); + } + @Test public void processMustSelectCorrectForChangeFromLuceneToSpatialOrBack() throws Exception { @@ -255,6 +319,21 @@ public void processMustSelectCorrectForChangeFromLuceneToSpatialOrBack() throws verifyChangeWithCorrectUpdaterMixed( spatialUpdater, luceneUpdater, supportedBySpatial, supportedByLucene ); } + @Test + public void processMustSelectCorrectForChangeFromLuceneToTemporalOrBack() throws Exception + { + // given + Value[] supportedByLucene = FusionIndexTestHelp.valuesNotSupportedByNativeOrSpatial(); + Value[] supportedByTemporal = FusionIndexTestHelp.valuesSupportedByTemporal(); + + // when + // ... before - supported + // ... after - not supported + verifyChangeWithCorrectUpdaterMixed( luceneUpdater, temporalUpdater, supportedByLucene, supportedByTemporal ); + reset( luceneUpdater, temporalUpdater ); + verifyChangeWithCorrectUpdaterMixed( temporalUpdater, luceneUpdater, supportedByTemporal, supportedByLucene ); + } + private void verifyAddWithCorrectUpdater( IndexUpdater correctPopulator, Value... numberValues ) throws IndexEntryConflictException, IOException { @@ -323,15 +402,16 @@ private void verifyChangeWithCorrectUpdaterMixed( IndexUpdater expectRemoveFrom, /* close */ @Test - public void closeMustCloseBothNativeAndLucene() throws Exception + public void closeMustCloseAll() throws Exception { // when fusionIndexUpdater.close(); // then - verify( nativeUpdater, times( 1 ) ).close(); - verify( spatialUpdater, times( 1 ) ).close(); - verify( luceneUpdater, times( 1 ) ).close(); + for ( IndexUpdater updater : allUpdaters ) + { + verify( updater, times( 1 ) ).close(); + } } @Test @@ -353,26 +433,38 @@ public void closeMustThrowIfSpatialThrow() throws Exception } @Test - public void closeMustCloseNativeIfLuceneThrow() throws Exception + public void closeMustThrowIfTemporalThrow() throws Exception + { + FusionIndexTestHelp.verifyFusionCloseThrowOnSingleCloseThrow( temporalUpdater, fusionIndexUpdater ); + } + + @Test + public void closeMustCloseOthersIfLuceneThrow() throws Exception + { + FusionIndexTestHelp.verifyOtherIsClosedOnSingleThrow( luceneUpdater, fusionIndexUpdater, nativeUpdater, spatialUpdater, temporalUpdater ); + } + + @Test + public void closeMustCloseOthersIfSpatialThrow() throws Exception { - FusionIndexTestHelp.verifyOtherIsClosedOnSingleThrow( luceneUpdater, fusionIndexUpdater, nativeUpdater, spatialUpdater ); + FusionIndexTestHelp.verifyOtherIsClosedOnSingleThrow( spatialUpdater, fusionIndexUpdater, nativeUpdater, temporalUpdater, luceneUpdater ); } @Test - public void closeMustCloseLuceneIfSpatialThrow() throws Exception + public void closeMustCloseOthersIfTemporalThrow() throws Exception { - FusionIndexTestHelp.verifyOtherIsClosedOnSingleThrow( spatialUpdater, fusionIndexUpdater, luceneUpdater, nativeUpdater ); + FusionIndexTestHelp.verifyOtherIsClosedOnSingleThrow( temporalUpdater, fusionIndexUpdater, nativeUpdater, spatialUpdater, luceneUpdater ); } @Test - public void closeMustCloseLuceneIfNativeThrow() throws Exception + public void closeMustCloseOthersIfNativeThrow() throws Exception { - FusionIndexTestHelp.verifyOtherIsClosedOnSingleThrow( nativeUpdater, fusionIndexUpdater, luceneUpdater, spatialUpdater ); + FusionIndexTestHelp.verifyOtherIsClosedOnSingleThrow( nativeUpdater, fusionIndexUpdater, spatialUpdater, temporalUpdater, luceneUpdater ); } @Test - public void closeMustThrowIfBothThrow() throws Exception + public void closeMustThrowIfAllThrow() throws Exception { - FusionIndexTestHelp.verifyFusionCloseThrowIfAllThrow( fusionIndexUpdater, nativeUpdater, luceneUpdater ); + FusionIndexTestHelp.verifyFusionCloseThrowIfAllThrow( fusionIndexUpdater, nativeUpdater, spatialUpdater, temporalUpdater, luceneUpdater ); } } diff --git a/community/kernel/src/test/java/org/neo4j/kernel/impl/index/schema/fusion/FusionSchemaIndexProviderTest.java b/community/kernel/src/test/java/org/neo4j/kernel/impl/index/schema/fusion/FusionSchemaIndexProviderTest.java index 30e851dcfce9f..02a1e0992cd56 100644 --- a/community/kernel/src/test/java/org/neo4j/kernel/impl/index/schema/fusion/FusionSchemaIndexProviderTest.java +++ b/community/kernel/src/test/java/org/neo4j/kernel/impl/index/schema/fusion/FusionSchemaIndexProviderTest.java @@ -77,6 +77,7 @@ public void mustSelectCorrectTargetForAllGivenValueCombinations() // given Value[] numberValues = FusionIndexTestHelp.valuesSupportedByNative(); Value[] spatialValues = FusionIndexTestHelp.valuesSupportedBySpatial(); + Value[] temporalValues = FusionIndexTestHelp.valuesSupportedByTemporal(); Value[] otherValues = FusionIndexTestHelp.valuesNotSupportedByNativeOrSpatial(); Value[] allValues = FusionIndexTestHelp.allValues(); @@ -101,6 +102,16 @@ public void mustSelectCorrectTargetForAllGivenValueCombinations() assertSame( spatialProvider, selected ); } + // Temporal values should go to temporal provider + for ( Value temporalValue : temporalValues ) + { + // when + SchemaIndexProvider selected = selector.select( nativeProvider, spatialProvider, temporalProvider, luceneProvider, temporalValue ); + + // then + assertSame( temporalProvider, selected ); + } + // Other values should go to lucene provider for ( Value otherValue : otherValues ) { @@ -139,18 +150,23 @@ public void mustCombineSamples() int spatialSampleSize = random.nextInt( 0, 1_000_000 ); IndexSample spatialSample = new IndexSample( spatialIndexSize, spatialUniqueValues, spatialSampleSize ); + int temporalIndexSize = random.nextInt( 0, 1_000_000 ); + int temporalUniqueValues = random.nextInt( 0, 1_000_000 ); + int temporalSampleSize = random.nextInt( 0, 1_000_000 ); + IndexSample temporalSample = new IndexSample( temporalIndexSize, temporalUniqueValues, temporalSampleSize ); + int luceneIndexSize = random.nextInt( 0, 1_000_000 ); int luceneUniqueValues = random.nextInt( 0, 1_000_000 ); int luceneSampleSize = random.nextInt( 0, 1_000_000 ); IndexSample luceneSample = new IndexSample( luceneIndexSize, luceneUniqueValues, luceneSampleSize ); // when - IndexSample fusionSample = FusionSchemaIndexProvider.combineSamples( nativeSample, spatialSample, luceneSample ); + IndexSample fusionSample = FusionSchemaIndexProvider.combineSamples( nativeSample, spatialSample, temporalSample, luceneSample ); // then - assertEquals( nativeIndexSize + spatialIndexSize + luceneIndexSize, fusionSample.indexSize() ); - assertEquals( nativeUniqueValues + spatialUniqueValues + luceneUniqueValues, fusionSample.uniqueValues() ); - assertEquals( nativeSampleSize + spatialSampleSize + luceneSampleSize, fusionSample.sampleSize() ); + assertEquals( nativeIndexSize + spatialIndexSize + temporalIndexSize + luceneIndexSize, fusionSample.indexSize() ); + assertEquals( nativeUniqueValues + spatialUniqueValues + temporalUniqueValues + luceneUniqueValues, fusionSample.uniqueValues() ); + assertEquals( nativeSampleSize + spatialSampleSize + temporalSampleSize + luceneSampleSize, fusionSample.sampleSize() ); } @Test @@ -163,14 +179,16 @@ public void getPopulationFailureMustThrowIfNoFailure() // ... no failure IllegalStateException nativeThrow = new IllegalStateException( "no native failure" ); IllegalStateException spatialThrow = new IllegalStateException( "no spatial failure" ); + IllegalStateException temporalThrow = new IllegalStateException( "no temporal failure" ); IllegalStateException luceneThrow = new IllegalStateException( "no lucene failure" ); when( nativeProvider.getPopulationFailure( anyLong(), any( IndexDescriptor.class ) ) ).thenThrow( nativeThrow ); when( spatialProvider.getPopulationFailure( anyLong(), any( IndexDescriptor.class ) ) ).thenThrow( spatialThrow ); + when( temporalProvider.getPopulationFailure( anyLong(), any( IndexDescriptor.class ) ) ).thenThrow( temporalThrow ); when( luceneProvider.getPopulationFailure( anyLong(), any( IndexDescriptor.class ) ) ).thenThrow( luceneThrow ); // then try { - fusionSchemaIndexProvider.getPopulationFailure( 0, null ); + fusionSchemaIndexProvider.getPopulationFailure( 0, forLabel( 0, 0 ) ); fail( "Should have failed" ); } catch ( IllegalStateException e ) @@ -187,9 +205,11 @@ public void getPopulationFailureMustReportFailureWhenNativeFailure() // ... native failure String nativeFailure = "native failure"; IllegalStateException spatialThrow = new IllegalStateException( "no spatial failure" ); + IllegalStateException temporalThrow = new IllegalStateException( "no temporal failure" ); IllegalStateException luceneThrow = new IllegalStateException( "no lucene failure" ); when( nativeProvider.getPopulationFailure( anyLong(), any( IndexDescriptor.class ) ) ).thenReturn( nativeFailure ); when( spatialProvider.getPopulationFailure( anyLong(), any( IndexDescriptor.class ) ) ).thenThrow( spatialThrow ); + when( temporalProvider.getPopulationFailure( anyLong(), any( IndexDescriptor.class ) ) ).thenThrow( temporalThrow ); when( luceneProvider.getPopulationFailure( anyLong(), any( IndexDescriptor.class ) ) ).thenThrow( luceneThrow ); // then assertThat( fusionSchemaIndexProvider.getPopulationFailure( 0, forLabel( 0, 0 ) ), containsString( nativeFailure ) ); @@ -204,14 +224,35 @@ public void getPopulationFailureMustReportFailureWhenSpatialFailure() throws Exc // ... spatial failure IllegalStateException nativeThrow = new IllegalStateException( "no native failure" ); String spatialFailure = "spatial failure"; + IllegalStateException temporalThrow = new IllegalStateException( "no temporal failure" ); IllegalStateException luceneThrow = new IllegalStateException( "no lucene failure" ); when( nativeProvider.getPopulationFailure( anyLong(), any( IndexDescriptor.class ) ) ).thenThrow( nativeThrow ); when( spatialProvider.getPopulationFailure( anyLong(), any( IndexDescriptor.class ) ) ).thenReturn( spatialFailure ); + when( temporalProvider.getPopulationFailure( anyLong(), any( IndexDescriptor.class ) ) ).thenThrow( temporalThrow ); when( luceneProvider.getPopulationFailure( anyLong(), any( IndexDescriptor.class ) ) ).thenThrow( luceneThrow ); // then assertThat( fusionSchemaIndexProvider.getPopulationFailure( 0, forLabel( 0, 0 ) ), containsString( spatialFailure ) ); } + @Test + public void getPopulationFailureMustReportFailureWhenTemporalFailure() throws Exception + { + FusionSchemaIndexProvider fusionSchemaIndexProvider = fusionProvider(); + + // when + // ... spatial failure + IllegalStateException nativeThrow = new IllegalStateException( "no native failure" ); + IllegalStateException spatialThrow = new IllegalStateException( "no spatial failure" ); + String temporalFailure = "temporal failure"; + IllegalStateException luceneThrow = new IllegalStateException( "no lucene failure" ); + when( nativeProvider.getPopulationFailure( anyLong(), any( IndexDescriptor.class ) ) ).thenThrow( nativeThrow ); + when( spatialProvider.getPopulationFailure( anyLong(), any( IndexDescriptor.class ) ) ).thenThrow( spatialThrow ); + when( temporalProvider.getPopulationFailure( anyLong(), any( IndexDescriptor.class ) ) ).thenReturn( temporalFailure ); + when( luceneProvider.getPopulationFailure( anyLong(), any( IndexDescriptor.class ) ) ).thenThrow( luceneThrow ); + // then + assertThat( fusionSchemaIndexProvider.getPopulationFailure( 0, forLabel( 0, 0 ) ), containsString( temporalFailure ) ); + } + @Test public void getPopulationFailureMustReportFailureWhenLuceneFailure() { @@ -221,9 +262,11 @@ public void getPopulationFailureMustReportFailureWhenLuceneFailure() // ... lucene failure IllegalStateException nativeThrow = new IllegalStateException( "no native failure" ); IllegalStateException spatialThrow = new IllegalStateException( "no spatial failure" ); + IllegalStateException temporalThrow = new IllegalStateException( "no temporal failure" ); String luceneFailure = "lucene failure"; when( nativeProvider.getPopulationFailure( anyLong(), any( IndexDescriptor.class ) ) ).thenThrow( nativeThrow ); when( spatialProvider.getPopulationFailure( anyLong(), any( IndexDescriptor.class ) ) ).thenThrow( spatialThrow ); + when( temporalProvider.getPopulationFailure( anyLong(), any( IndexDescriptor.class ) ) ).thenThrow( temporalThrow ); when( luceneProvider.getPopulationFailure( anyLong(), any( IndexDescriptor.class ) ) ).thenReturn( luceneFailure ); // then assertThat( fusionSchemaIndexProvider.getPopulationFailure( 0, forLabel( 0, 0 ) ), containsString( luceneFailure ) ); @@ -238,9 +281,11 @@ public void getPopulationFailureMustReportFailureWhenBothNativeAndLuceneFail() // ... native and lucene failure String nativeFailure = "native failure"; IllegalStateException spatialThrow = new IllegalStateException( "no spatial failure" ); + IllegalStateException temporalThrow = new IllegalStateException( "no temporal failure" ); String luceneFailure = "lucene failure"; when( nativeProvider.getPopulationFailure( anyLong(), any( IndexDescriptor.class ) ) ).thenReturn( nativeFailure ); when( spatialProvider.getPopulationFailure( anyLong(), any( IndexDescriptor.class ) ) ).thenThrow( spatialThrow ); + when( temporalProvider.getPopulationFailure( anyLong(), any( IndexDescriptor.class ) ) ).thenThrow( temporalThrow ); when( luceneProvider.getPopulationFailure( anyLong(), any( IndexDescriptor.class ) ) ).thenReturn( luceneFailure ); // then String populationFailure = fusionSchemaIndexProvider.getPopulationFailure( 0, forLabel( 0, 0 ) ); @@ -256,15 +301,18 @@ public void getPopulationFailureMustReportFailureWhenAllFail() throws Exception // when // ... native and lucene failure String nativeFailure = "native failure"; - String spatialFailure = "native failure"; + String spatialFailure = "spatial failure"; + String temporalFailure = "temporal failure"; String luceneFailure = "lucene failure"; when( nativeProvider.getPopulationFailure( anyLong(), any( IndexDescriptor.class ) ) ).thenReturn( nativeFailure ); when( spatialProvider.getPopulationFailure( anyLong(), any( IndexDescriptor.class ) ) ).thenReturn( spatialFailure ); + when( temporalProvider.getPopulationFailure( anyLong(), any( IndexDescriptor.class ) ) ).thenReturn( temporalFailure ); when( luceneProvider.getPopulationFailure( anyLong(), any( IndexDescriptor.class ) ) ).thenReturn( luceneFailure ); // then String populationFailure = fusionSchemaIndexProvider.getPopulationFailure( 0, forLabel( 0, 0 ) ); assertThat( populationFailure, containsString( nativeFailure ) ); assertThat( populationFailure, containsString( spatialFailure ) ); + assertThat( populationFailure, containsString( temporalFailure ) ); assertThat( populationFailure, containsString( luceneFailure ) ); } @@ -280,23 +328,33 @@ public void shouldReportFailedIfAnyIsFailed() // when setInitialState( nativeProvider, InternalIndexState.FAILED ); setInitialState( spatialProvider, state ); + setInitialState( temporalProvider, state ); setInitialState( luceneProvider, state ); InternalIndexState failed1 = provider.getInitialState( 0, indexDescriptor ); setInitialState( nativeProvider, state ); setInitialState( spatialProvider, InternalIndexState.FAILED ); + setInitialState( temporalProvider, state ); setInitialState( luceneProvider, state ); InternalIndexState failed2 = provider.getInitialState( 0, indexDescriptor ); setInitialState( nativeProvider, state ); setInitialState( spatialProvider, state ); - setInitialState( luceneProvider, InternalIndexState.FAILED ); + setInitialState( temporalProvider, InternalIndexState.FAILED ); + setInitialState( luceneProvider, state ); InternalIndexState failed3 = provider.getInitialState( 0, indexDescriptor ); + setInitialState( nativeProvider, state ); + setInitialState( spatialProvider, state ); + setInitialState( temporalProvider, state ); + setInitialState( luceneProvider, InternalIndexState.FAILED ); + InternalIndexState failed4 = provider.getInitialState( 0, indexDescriptor ); + // then assertEquals( InternalIndexState.FAILED, failed1 ); assertEquals( InternalIndexState.FAILED, failed2 ); assertEquals( InternalIndexState.FAILED, failed3 ); + assertEquals( InternalIndexState.FAILED, failed4 ); } } @@ -312,23 +370,33 @@ public void shouldReportPopulatingIfAnyIsPopulating() // when setInitialState( nativeProvider, InternalIndexState.POPULATING ); setInitialState( spatialProvider, state ); + setInitialState( temporalProvider, state ); setInitialState( luceneProvider, state ); InternalIndexState failed1 = provider.getInitialState( 0, indexDescriptor ); setInitialState( nativeProvider, state ); setInitialState( spatialProvider, InternalIndexState.POPULATING ); + setInitialState( temporalProvider, state ); setInitialState( luceneProvider, state ); InternalIndexState failed2 = provider.getInitialState( 0, indexDescriptor ); setInitialState( nativeProvider, state ); setInitialState( spatialProvider, state ); - setInitialState( luceneProvider, InternalIndexState.POPULATING ); + setInitialState( temporalProvider, InternalIndexState.POPULATING ); + setInitialState( luceneProvider, state ); InternalIndexState failed3 = provider.getInitialState( 0, indexDescriptor ); + setInitialState( nativeProvider, state ); + setInitialState( spatialProvider, state ); + setInitialState( temporalProvider, state ); + setInitialState( luceneProvider, InternalIndexState.POPULATING ); + InternalIndexState failed4 = provider.getInitialState( 0, indexDescriptor ); + // then assertEquals( InternalIndexState.POPULATING, failed1 ); assertEquals( InternalIndexState.POPULATING, failed2 ); assertEquals( InternalIndexState.POPULATING, failed3 ); + assertEquals( InternalIndexState.POPULATING, failed4 ); } }