From 1ad1c64f251fec9ae97cd443d93d0cefbd3fec55 Mon Sep 17 00:00:00 2001 From: Mikhaylo Demianenko Date: Tue, 12 Jan 2016 11:20:28 +0100 Subject: [PATCH] Simple unit test for basic components of new indexing infrastructure Add base unit tests for indexing components which covers only most basic non-integration scenarios for simple cases only. --- .../test/java/org/neo4j/io/IOUtilsTest.java | 52 +++++++ .../neo4j/test/NestedThrowableMatcher.java | 38 +++++ .../impl/index/LuceneSchemaIndexProvider.java | 2 +- .../LuceneIndexSnapshotFileIterator.java | 8 +- .../impl/index/partition/IndexPartition.java | 15 +- .../index/partition/PartitionSearcher.java | 12 +- .../impl/index/storage/FailureStorage.java | 4 +- .../LuceneSchemaIndexCorruptionTest.java | 2 +- ... LuceneIndexSnapshotFileIteratorTest.java} | 3 +- .../index/reader/SimpleIndexReaderTest.java | 138 ++++++++++++++++++ .../NonUniqueLuceneIndexSamplerTest.java | 121 +++++++++++++++ .../sampler/UniqueLuceneIndexSamplerTest.java | 52 +++++++ .../storage/layout/IndexFolderLayoutTest.java | 43 ++++++ .../LegacyIndexesUpgradeTest.java | 37 +---- 14 files changed, 470 insertions(+), 57 deletions(-) create mode 100644 community/io/src/test/java/org/neo4j/io/IOUtilsTest.java create mode 100644 community/io/src/test/java/org/neo4j/test/NestedThrowableMatcher.java rename community/lucene-index/src/test/java/org/neo4j/kernel/api/impl/index/backup/{LuceneSnapshotterTest.java => LuceneIndexSnapshotFileIteratorTest.java} (97%) create mode 100644 community/lucene-index/src/test/java/org/neo4j/kernel/api/impl/index/reader/SimpleIndexReaderTest.java create mode 100644 community/lucene-index/src/test/java/org/neo4j/kernel/api/impl/index/sampler/NonUniqueLuceneIndexSamplerTest.java create mode 100644 community/lucene-index/src/test/java/org/neo4j/kernel/api/impl/index/sampler/UniqueLuceneIndexSamplerTest.java create mode 100644 community/lucene-index/src/test/java/org/neo4j/kernel/api/impl/index/storage/layout/IndexFolderLayoutTest.java diff --git a/community/io/src/test/java/org/neo4j/io/IOUtilsTest.java b/community/io/src/test/java/org/neo4j/io/IOUtilsTest.java new file mode 100644 index 0000000000000..3cda80ac5be92 --- /dev/null +++ b/community/io/src/test/java/org/neo4j/io/IOUtilsTest.java @@ -0,0 +1,52 @@ +package org.neo4j.io; + +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.ExpectedException; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.runners.MockitoJUnitRunner; + +import java.io.IOException; + +import org.neo4j.test.NestedThrowableMatcher; + +import static org.mockito.Mockito.doThrow; +import static org.mockito.Mockito.verify; + +@RunWith( MockitoJUnitRunner.class ) +public class IOUtilsTest +{ + @Rule + public ExpectedException expectedException = ExpectedException.none(); + + @Mock + private AutoCloseable faultyClosable; + @Mock + private AutoCloseable goodClosable1; + @Mock + private AutoCloseable goodClosable2; + + @Test + public void closeAllSilently() throws Exception + { + IOUtils.closeAllSilently( goodClosable1, faultyClosable, goodClosable2 ); + + verify( goodClosable1 ).close(); + verify( goodClosable2 ).close(); + verify( faultyClosable ).close(); + } + + @Test + public void closeAllAndRethrowException() throws Exception + { + doThrow( new IOException( "Faulty closable" ) ).when( faultyClosable ).close(); + + expectedException.expect( IOException.class ); + expectedException.expectMessage( "Exception closing multiple resources" ); + expectedException.expect( new NestedThrowableMatcher( IOException.class ) ); + + IOUtils.closeAll( goodClosable1, faultyClosable, goodClosable2 ); + } + +} \ No newline at end of file diff --git a/community/io/src/test/java/org/neo4j/test/NestedThrowableMatcher.java b/community/io/src/test/java/org/neo4j/test/NestedThrowableMatcher.java new file mode 100644 index 0000000000000..28eb7de006766 --- /dev/null +++ b/community/io/src/test/java/org/neo4j/test/NestedThrowableMatcher.java @@ -0,0 +1,38 @@ +package org.neo4j.test; + +import org.hamcrest.Description; +import org.hamcrest.TypeSafeMatcher; + +public class NestedThrowableMatcher extends TypeSafeMatcher +{ + private final Class expectedType; + + public NestedThrowableMatcher( Class expectedType ) + { + this.expectedType = expectedType; + } + + @Override + public void describeTo( Description description ) + { + description.appendText( "expect " ) + .appendValue( expectedType ) + .appendText( " to be exception cause." ); + } + + @Override + protected boolean matchesSafely( Throwable item ) + { + Throwable currentThrowable = item; + do + { + if ( expectedType.isInstance( currentThrowable ) ) + { + return true; + } + currentThrowable = currentThrowable.getCause(); + } + while ( currentThrowable != null ); + return false; + } +} diff --git a/community/lucene-index/src/main/java/org/neo4j/kernel/api/impl/index/LuceneSchemaIndexProvider.java b/community/lucene-index/src/main/java/org/neo4j/kernel/api/impl/index/LuceneSchemaIndexProvider.java index aae260742ea30..eeacf7b62144a 100644 --- a/community/lucene-index/src/main/java/org/neo4j/kernel/api/impl/index/LuceneSchemaIndexProvider.java +++ b/community/lucene-index/src/main/java/org/neo4j/kernel/api/impl/index/LuceneSchemaIndexProvider.java @@ -63,7 +63,7 @@ public LuceneSchemaIndexProvider( FileSystemAbstraction fileSystem, DirectoryFac /** * Visible only for testing. */ - LuceneSchemaIndexProvider( FileSystemAbstraction fileSystem, IndexStorageFactory indexStorageFactory ) + LuceneSchemaIndexProvider( IndexStorageFactory indexStorageFactory ) { super( LuceneSchemaIndexProviderFactory.PROVIDER_DESCRIPTOR, 1 ); this.indexStorageFactory = indexStorageFactory; diff --git a/community/lucene-index/src/main/java/org/neo4j/kernel/api/impl/index/backup/LuceneIndexSnapshotFileIterator.java b/community/lucene-index/src/main/java/org/neo4j/kernel/api/impl/index/backup/LuceneIndexSnapshotFileIterator.java index 57fcbd1233e7e..a074a7d323f57 100644 --- a/community/lucene-index/src/main/java/org/neo4j/kernel/api/impl/index/backup/LuceneIndexSnapshotFileIterator.java +++ b/community/lucene-index/src/main/java/org/neo4j/kernel/api/impl/index/backup/LuceneIndexSnapshotFileIterator.java @@ -43,14 +43,14 @@ public class LuceneIndexSnapshotFileIterator extends PrefetchingIterator i private final Iterator fileNames; private final IndexCommit snapshot; - public static ResourceIterator forIndex( File indexDirectory, IndexWriter indexWriter ) throws IOException + public static ResourceIterator forIndex( File indexFolder, IndexWriter indexWriter ) throws IOException { IndexDeletionPolicy deletionPolicy = indexWriter.getConfig().getIndexDeletionPolicy(); if ( deletionPolicy instanceof SnapshotDeletionPolicy ) { SnapshotDeletionPolicy policy = (SnapshotDeletionPolicy) deletionPolicy; return hasCommits( indexWriter ) - ? new LuceneIndexSnapshotFileIterator( indexDirectory, policy ) + ? new LuceneIndexSnapshotFileIterator( indexFolder, policy ) : emptyIterator(); } else @@ -98,9 +98,7 @@ public void close() private static boolean hasCommits( IndexWriter indexWriter ) throws IOException { Directory directory = indexWriter.getDirectory(); - return DirectoryReader.indexExists( directory ) && - SegmentInfos.readLatestCommit( directory ) != null; + return DirectoryReader.indexExists( directory ) && SegmentInfos.readLatestCommit( directory ) != null; } - } diff --git a/community/lucene-index/src/main/java/org/neo4j/kernel/api/impl/index/partition/IndexPartition.java b/community/lucene-index/src/main/java/org/neo4j/kernel/api/impl/index/partition/IndexPartition.java index f8721cd715a24..37cf84626be2e 100644 --- a/community/lucene-index/src/main/java/org/neo4j/kernel/api/impl/index/partition/IndexPartition.java +++ b/community/lucene-index/src/main/java/org/neo4j/kernel/api/impl/index/partition/IndexPartition.java @@ -38,11 +38,11 @@ public class IndexPartition implements Closeable private final IndexWriter indexWriter; private final Directory directory; private final SearcherManager searcherManager; - private final File indexDirectory; + private final File indexFolder; - public IndexPartition( File indexDirectory, Directory directory ) throws IOException + public IndexPartition( File partitionFolder, Directory directory ) throws IOException { - this.indexDirectory = indexDirectory; + this.indexFolder = partitionFolder; this.directory = directory; this.indexWriter = new IndexWriter( directory, IndexWriterConfigs.standardConfig() ); this.searcherManager = new SearcherManager( indexWriter, true, new SearcherFactory() ); @@ -58,6 +58,13 @@ public Directory getDirectory() return directory; } + /** + * Return searcher for requested partition. + * There is no tracking of acquired searchers, so the expectation is that callers will call close on acquired + * searchers to release resources. + * @return partition searcher + * @throws IOException if exception happened during searcher acquisition + */ public PartitionSearcher acquireSearcher() throws IOException { return new PartitionSearcher( searcherManager ); @@ -76,6 +83,6 @@ public void close() throws IOException public ResourceIterator snapshot() throws IOException { - return LuceneIndexSnapshotFileIterator.forIndex( indexDirectory, indexWriter ); + return LuceneIndexSnapshotFileIterator.forIndex( indexFolder, indexWriter ); } } diff --git a/community/lucene-index/src/main/java/org/neo4j/kernel/api/impl/index/partition/PartitionSearcher.java b/community/lucene-index/src/main/java/org/neo4j/kernel/api/impl/index/partition/PartitionSearcher.java index fdfeb3e5a0e13..fdbf8d58beccf 100644 --- a/community/lucene-index/src/main/java/org/neo4j/kernel/api/impl/index/partition/PartitionSearcher.java +++ b/community/lucene-index/src/main/java/org/neo4j/kernel/api/impl/index/partition/PartitionSearcher.java @@ -20,7 +20,7 @@ package org.neo4j.kernel.api.impl.index.partition; import org.apache.lucene.search.IndexSearcher; -import org.apache.lucene.search.SearcherManager; +import org.apache.lucene.search.ReferenceManager; import java.io.Closeable; import java.io.IOException; @@ -28,12 +28,12 @@ public class PartitionSearcher implements Closeable { private IndexSearcher indexSearcher; - private SearcherManager searcherManager; + private ReferenceManager referenceManager; - public PartitionSearcher( SearcherManager searcherManager ) throws IOException + public PartitionSearcher( ReferenceManager referenceManager ) throws IOException { - this.searcherManager = searcherManager; - this.indexSearcher = searcherManager.acquire(); + this.referenceManager = referenceManager; + this.indexSearcher = referenceManager.acquire(); } public IndexSearcher getIndexSearcher() @@ -44,6 +44,6 @@ public IndexSearcher getIndexSearcher() @Override public void close() throws IOException { - searcherManager.release( indexSearcher ); + referenceManager.release( indexSearcher ); } } diff --git a/community/lucene-index/src/main/java/org/neo4j/kernel/api/impl/index/storage/FailureStorage.java b/community/lucene-index/src/main/java/org/neo4j/kernel/api/impl/index/storage/FailureStorage.java index af9637314f9fa..598571d1eac8c 100644 --- a/community/lucene-index/src/main/java/org/neo4j/kernel/api/impl/index/storage/FailureStorage.java +++ b/community/lucene-index/src/main/java/org/neo4j/kernel/api/impl/index/storage/FailureStorage.java @@ -34,8 +34,8 @@ */ public class FailureStorage { - public static final int MAX_FAILURE_SIZE = 16384; - public static final String DEFAULT_FAILURE_FILE_NAME = "failure-message"; + private static final int MAX_FAILURE_SIZE = 16384; + private static final String DEFAULT_FAILURE_FILE_NAME = "failure-message"; private final FileSystemAbstraction fs; private final FolderLayout folderLayout; diff --git a/community/lucene-index/src/test/java/org/neo4j/kernel/api/impl/index/LuceneSchemaIndexCorruptionTest.java b/community/lucene-index/src/test/java/org/neo4j/kernel/api/impl/index/LuceneSchemaIndexCorruptionTest.java index 31c022f19ec01..172301a8416d1 100644 --- a/community/lucene-index/src/test/java/org/neo4j/kernel/api/impl/index/LuceneSchemaIndexCorruptionTest.java +++ b/community/lucene-index/src/test/java/org/neo4j/kernel/api/impl/index/LuceneSchemaIndexCorruptionTest.java @@ -130,7 +130,7 @@ public void shouldDenyFailureForNonFailedIndex() throws Exception private LuceneSchemaIndexProvider newFaultySchemaIndexProvider( long faultyIndexId, Exception error ) { FaultyIndexStorageFactory storageFactory = new FaultyIndexStorageFactory( faultyIndexId, error ); - return new LuceneSchemaIndexProvider( fs.get(), storageFactory ); + return new LuceneSchemaIndexProvider( storageFactory ); } private class FaultyIndexStorageFactory extends IndexStorageFactory diff --git a/community/lucene-index/src/test/java/org/neo4j/kernel/api/impl/index/backup/LuceneSnapshotterTest.java b/community/lucene-index/src/test/java/org/neo4j/kernel/api/impl/index/backup/LuceneIndexSnapshotFileIteratorTest.java similarity index 97% rename from community/lucene-index/src/test/java/org/neo4j/kernel/api/impl/index/backup/LuceneSnapshotterTest.java rename to community/lucene-index/src/test/java/org/neo4j/kernel/api/impl/index/backup/LuceneIndexSnapshotFileIteratorTest.java index 3b773fa3ae7d5..b9b265cea1422 100644 --- a/community/lucene-index/src/test/java/org/neo4j/kernel/api/impl/index/backup/LuceneSnapshotterTest.java +++ b/community/lucene-index/src/test/java/org/neo4j/kernel/api/impl/index/backup/LuceneIndexSnapshotFileIteratorTest.java @@ -45,7 +45,7 @@ import static junit.framework.TestCase.assertFalse; import static org.junit.Assert.assertEquals; -public class LuceneSnapshotterTest +public class LuceneIndexSnapshotFileIteratorTest { @Rule public final TargetDirectory.TestDirectory testDir = TargetDirectory.testDirForTest( getClass() ); @@ -86,7 +86,6 @@ public void shouldReturnRealSnapshotIfIndexAllowsIt() throws IOException @Test public void shouldReturnEmptyIteratorWhenNoCommitsHaveBeenMade() throws IOException { - String[] strings = dir.listAll(); try ( ResourceIterator snapshot = LuceneIndexSnapshotFileIterator.forIndex( indexDir, writer ) ) { assertFalse( snapshot.hasNext() ); diff --git a/community/lucene-index/src/test/java/org/neo4j/kernel/api/impl/index/reader/SimpleIndexReaderTest.java b/community/lucene-index/src/test/java/org/neo4j/kernel/api/impl/index/reader/SimpleIndexReaderTest.java new file mode 100644 index 0000000000000..29724c243b799 --- /dev/null +++ b/community/lucene-index/src/test/java/org/neo4j/kernel/api/impl/index/reader/SimpleIndexReaderTest.java @@ -0,0 +1,138 @@ +package org.neo4j.kernel.api.impl.index.reader; + +import org.apache.lucene.search.BooleanQuery; +import org.apache.lucene.search.IndexSearcher; +import org.apache.lucene.search.MatchAllDocsQuery; +import org.apache.lucene.search.NumericRangeQuery; +import org.apache.lucene.search.PrefixQuery; +import org.apache.lucene.search.TermQuery; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; + +import java.io.IOException; +import java.util.concurrent.TimeUnit; + +import org.neo4j.helpers.TaskCoordinator; +import org.neo4j.kernel.api.impl.index.DocValuesCollector; +import org.neo4j.kernel.api.impl.index.partition.PartitionSearcher; +import org.neo4j.kernel.api.impl.index.sampler.NonUniqueLuceneIndexSampler; +import org.neo4j.kernel.api.impl.index.sampler.UniqueLuceneIndexSampler; +import org.neo4j.kernel.api.index.IndexConfiguration; +import org.neo4j.kernel.configuration.Config; +import org.neo4j.kernel.impl.api.index.sampling.IndexSamplingConfig; +import org.neo4j.storageengine.api.schema.IndexReader; + +import static org.hamcrest.Matchers.instanceOf; +import static org.mockito.Matchers.any; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +public class SimpleIndexReaderTest +{ + private final PartitionSearcher partitionSearcher = mock( PartitionSearcher.class ); + private final IndexSearcher indexSearcher = mock( IndexSearcher.class ); + private final IndexSamplingConfig samplingConfig = new IndexSamplingConfig( new Config() ); + private final TaskCoordinator taskCoordinator = new TaskCoordinator( 0, TimeUnit.MILLISECONDS ); + + @Before + public void setUp() + { + when( partitionSearcher.getIndexSearcher() ).thenReturn( indexSearcher ); + } + + @Test + public void releaseSearcherOnClose() throws IOException + { + IndexReader simpleIndexReader = getUniqueSimpleReader(); + + simpleIndexReader.close(); + + verify( partitionSearcher ).close(); + } + + @Test + public void seekQueryReachSearcher() throws IOException + { + IndexReader simpleIndexReader = getUniqueSimpleReader(); + + simpleIndexReader.seek( "test" ); + + verify( indexSearcher ).search( any( TermQuery.class ), any( DocValuesCollector.class ) ); + } + + @Test + public void scanQueryReachSearcher() throws IOException + { + IndexReader simpleIndexReader = getUniqueSimpleReader(); + + simpleIndexReader.scan(); + + verify( indexSearcher ).search( any( MatchAllDocsQuery.class ), any( DocValuesCollector.class ) ); + } + + @Test + public void stringRangeSeekQueryReachSearcher() throws IOException + { + IndexReader simpleIndexReader = getUniqueSimpleReader(); + + simpleIndexReader.rangeSeekByString( "a", false, "b", true ); + + verify( indexSearcher ).search( any( TermQuery.class ), any( DocValuesCollector.class ) ); + } + + @Test + public void prefixRangeSeekQueryReachSearcher() throws IOException + { + IndexReader simpleIndexReader = getUniqueSimpleReader(); + + simpleIndexReader.rangeSeekByPrefix( "bb" ); + + verify( indexSearcher ).search( any( PrefixQuery.class ), any( DocValuesCollector.class ) ); + } + + @Test + public void numberRangeSeekQueryReachSearcher() throws IOException + { + IndexReader simpleIndexReader = getUniqueSimpleReader(); + + simpleIndexReader.rangeSeekByNumberInclusive( 7, 8 ); + + verify( indexSearcher ).search( any( NumericRangeQuery.class ), any( DocValuesCollector.class ) ); + } + + @Test + public void countIndexedNodesReachSearcher() throws IOException + { + IndexReader simpleIndexReader = getUniqueSimpleReader(); + + simpleIndexReader.countIndexedNodes( 2, "testValue" ); + + verify( indexSearcher ).search( any( BooleanQuery.class ), any( DocValuesCollector.class ) ); + } + + @Test + public void uniqueIndexSamplerForUniqueIndex() + { + SimpleIndexReader uniqueSimpleReader = getUniqueSimpleReader(); + Assert.assertThat( uniqueSimpleReader.createSampler(), instanceOf( UniqueLuceneIndexSampler.class ) ); + } + + @Test + public void nonUuniqueIndexSamplerForNonUniqueIndex() + { + SimpleIndexReader uniqueSimpleReader = getNonUniqueSimpleReader(); + Assert.assertThat( uniqueSimpleReader.createSampler(), instanceOf( NonUniqueLuceneIndexSampler.class) ); + } + + private SimpleIndexReader getNonUniqueSimpleReader() + { + return new SimpleIndexReader( partitionSearcher, IndexConfiguration.NON_UNIQUE, samplingConfig, taskCoordinator ); + } + + private SimpleIndexReader getUniqueSimpleReader() + { + return new SimpleIndexReader( partitionSearcher, IndexConfiguration.UNIQUE, samplingConfig, taskCoordinator ); + } +} \ No newline at end of file diff --git a/community/lucene-index/src/test/java/org/neo4j/kernel/api/impl/index/sampler/NonUniqueLuceneIndexSamplerTest.java b/community/lucene-index/src/test/java/org/neo4j/kernel/api/impl/index/sampler/NonUniqueLuceneIndexSamplerTest.java new file mode 100644 index 0000000000000..53dca7b5ffdab --- /dev/null +++ b/community/lucene-index/src/test/java/org/neo4j/kernel/api/impl/index/sampler/NonUniqueLuceneIndexSamplerTest.java @@ -0,0 +1,121 @@ +package org.neo4j.kernel.api.impl.index.sampler; + +import org.apache.lucene.index.Fields; +import org.apache.lucene.index.Terms; +import org.apache.lucene.index.TermsEnum; +import org.apache.lucene.search.IndexSearcher; +import org.apache.lucene.util.BytesRef; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.ExpectedException; +import org.mockito.Mockito; + +import java.io.IOException; +import java.util.Iterator; +import java.util.Map; +import java.util.concurrent.TimeUnit; + +import org.neo4j.helpers.TaskCoordinator; +import org.neo4j.helpers.collection.MapUtil; +import org.neo4j.kernel.api.exceptions.index.IndexNotFoundKernelException; +import org.neo4j.kernel.api.impl.index.IndexReaderStub; +import org.neo4j.kernel.configuration.Config; +import org.neo4j.kernel.impl.api.index.sampling.IndexSamplingConfig; +import org.neo4j.register.Register; +import org.neo4j.register.Registers; + +import static org.junit.Assert.assertEquals; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +public class NonUniqueLuceneIndexSamplerTest +{ + @Rule + public ExpectedException expectedException = ExpectedException.none(); + + private final IndexSearcher indexSearcher = mock( IndexSearcher.class, Mockito.RETURNS_DEEP_STUBS ); + private final TaskCoordinator taskControl = new TaskCoordinator( 0, TimeUnit.MILLISECONDS ); + private final IndexSamplingConfig indexSamplingConfig = new IndexSamplingConfig( new Config() ); + + @Test + public void nonUniqueSamplingCancel() throws IndexNotFoundKernelException, IOException + { + Terms terms = getTerms( "test", 1 ); + Map fieldTermsMap = MapUtil.genericMap( "a", terms, "id", terms, "b", terms ); + IndexReaderStub indexReader = new IndexReaderStub( new SamplingFields( fieldTermsMap ) ); + when( indexSearcher.getIndexReader() ).thenReturn( indexReader ); + + expectedException.expect( IndexNotFoundKernelException.class ); + expectedException.expectMessage( "Index dropped while sampling." ); + + NonUniqueLuceneIndexSampler luceneIndexSampler = createSampler(); + taskControl.cancel(); + luceneIndexSampler.sampleIndex( Registers.newDoubleLongRegister() ); + } + + @Test + public void nonUniqueIndexSampling() throws Exception + { + Terms aTerms = getTerms( "a", 1 ); + Terms idTerms = getTerms( "id", 2 ); + Terms bTerms = getTerms( "b", 3 ); + Map fieldTermsMap = MapUtil.genericMap( "a", aTerms, "id", idTerms, "b", bTerms ); + IndexReaderStub indexReader = new IndexReaderStub( new SamplingFields( fieldTermsMap ) ); + when( indexSearcher.getIndexReader() ).thenReturn( indexReader ); + + NonUniqueLuceneIndexSampler luceneIndexSampler = createSampler(); + Register.DoubleLongRegister register = Registers.newDoubleLongRegister(); + long sample = luceneIndexSampler.sampleIndex( register ); + + // unique values + assertEquals( 2, register.readFirst() ); + // total values + assertEquals( 4, register.readSecond() ); + assertEquals( 4, sample ); + } + + private NonUniqueLuceneIndexSampler createSampler() + { + return new NonUniqueLuceneIndexSampler( indexSearcher, taskControl.newInstance(), indexSamplingConfig ); + } + + private Terms getTerms( String value, int frequency ) throws IOException + { + TermsEnum termsEnum = mock( TermsEnum.class ); + Terms terms = mock( Terms.class ); + when( terms.iterator() ).thenReturn( termsEnum ); + when( termsEnum.next() ).thenReturn( new BytesRef( value.getBytes() ) ).thenReturn( null ); + when( termsEnum.docFreq() ).thenReturn( frequency ); + return terms; + } + + private class SamplingFields extends Fields + { + + private Map fieldTermsMap; + + public SamplingFields( Map fieldTermsMap ) + { + this.fieldTermsMap = fieldTermsMap; + } + + @Override + public Iterator iterator() + { + return fieldTermsMap.keySet().iterator(); + } + + @Override + public Terms terms( String field ) throws IOException + { + return fieldTermsMap.get( field ); + } + + @Override + public int size() + { + return fieldTermsMap.size(); + } + } + +} \ No newline at end of file diff --git a/community/lucene-index/src/test/java/org/neo4j/kernel/api/impl/index/sampler/UniqueLuceneIndexSamplerTest.java b/community/lucene-index/src/test/java/org/neo4j/kernel/api/impl/index/sampler/UniqueLuceneIndexSamplerTest.java new file mode 100644 index 0000000000000..33727e70ab48d --- /dev/null +++ b/community/lucene-index/src/test/java/org/neo4j/kernel/api/impl/index/sampler/UniqueLuceneIndexSamplerTest.java @@ -0,0 +1,52 @@ +package org.neo4j.kernel.api.impl.index.sampler; + +import org.apache.lucene.search.IndexSearcher; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.ExpectedException; +import org.mockito.Mockito; + +import java.util.concurrent.TimeUnit; + +import org.neo4j.helpers.TaskCoordinator; +import org.neo4j.kernel.api.exceptions.index.IndexNotFoundKernelException; +import org.neo4j.register.Registers; + +import static org.junit.Assert.assertEquals; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +public class UniqueLuceneIndexSamplerTest +{ + @Rule + public ExpectedException expectedException = ExpectedException.none(); + + private final IndexSearcher indexSearcher = mock( IndexSearcher.class, Mockito.RETURNS_DEEP_STUBS ); + private final TaskCoordinator taskControl = new TaskCoordinator(0, TimeUnit.MILLISECONDS); + + @Test + public void uniqueSamplingUseDocumentsNumber() throws IndexNotFoundKernelException + { + when( indexSearcher.getIndexReader().numDocs() ).thenReturn( 17 ); + + UniqueLuceneIndexSampler luceneIndexSampler = new UniqueLuceneIndexSampler( indexSearcher, taskControl.newInstance() ); + long sample = luceneIndexSampler.sampleIndex( Registers.newDoubleLongRegister() ); + assertEquals(17, sample); + } + + @Test + public void uniqueSamplingCancel() throws IndexNotFoundKernelException + { + when( indexSearcher.getIndexReader().numDocs() ).thenAnswer( invocation -> { + taskControl.cancel(); + return 17; + } ); + + expectedException.expect( IndexNotFoundKernelException.class ); + expectedException.expectMessage( "Index dropped while sampling." ); + + UniqueLuceneIndexSampler luceneIndexSampler = new UniqueLuceneIndexSampler( indexSearcher, taskControl.newInstance() ); + luceneIndexSampler.sampleIndex( Registers.newDoubleLongRegister() ); + } + +} \ No newline at end of file diff --git a/community/lucene-index/src/test/java/org/neo4j/kernel/api/impl/index/storage/layout/IndexFolderLayoutTest.java b/community/lucene-index/src/test/java/org/neo4j/kernel/api/impl/index/storage/layout/IndexFolderLayoutTest.java new file mode 100644 index 0000000000000..3364a31716699 --- /dev/null +++ b/community/lucene-index/src/test/java/org/neo4j/kernel/api/impl/index/storage/layout/IndexFolderLayoutTest.java @@ -0,0 +1,43 @@ +package org.neo4j.kernel.api.impl.index.storage.layout; + +import org.junit.Test; + +import java.io.File; + +import static org.junit.Assert.assertEquals; + +public class IndexFolderLayoutTest +{ + private final File indexRoot = new File( "indexRoot" ); + + @Test + public void testIndexFolder() + { + IndexFolderLayout indexLayout = createTestIndex(); + File indexFolder = indexLayout.getIndexFolder(); + + assertEquals( indexRoot, indexFolder.getParentFile() ); + assertEquals( "testIndex", indexFolder.getName() ); + } + + @Test + public void testIndexPartitionFolder() + { + IndexFolderLayout indexLayout = createTestIndex(); + + File indexFolder = indexLayout.getIndexFolder(); + File partitionFolder1 = indexLayout.getPartitionFolder( 1 ); + File partitionFolder3 = indexLayout.getPartitionFolder( 3 ); + + assertEquals( partitionFolder1.getParentFile(), partitionFolder3.getParentFile() ); + assertEquals( indexFolder, partitionFolder1.getParentFile() ); + assertEquals( "1", partitionFolder1.getName() ); + assertEquals( "3", partitionFolder3.getName() ); + } + + private IndexFolderLayout createTestIndex() + { + return new IndexFolderLayout( indexRoot, "testIndex" ); + } + +} \ No newline at end of file diff --git a/integrationtests/src/test/java/org/neo4j/storeupgrade/LegacyIndexesUpgradeTest.java b/integrationtests/src/test/java/org/neo4j/storeupgrade/LegacyIndexesUpgradeTest.java index f0910ed139967..a81eaad3360bd 100644 --- a/integrationtests/src/test/java/org/neo4j/storeupgrade/LegacyIndexesUpgradeTest.java +++ b/integrationtests/src/test/java/org/neo4j/storeupgrade/LegacyIndexesUpgradeTest.java @@ -19,8 +19,6 @@ */ package org.neo4j.storeupgrade; -import org.hamcrest.Description; -import org.hamcrest.TypeSafeMatcher; import org.junit.Rule; import org.junit.Test; import org.junit.rules.ExpectedException; @@ -44,6 +42,7 @@ import org.neo4j.index.lucene.ValueContext; import org.neo4j.io.fs.FileUtils; import org.neo4j.kernel.impl.storemigration.UpgradeNotAllowedByConfigurationException; +import org.neo4j.test.NestedThrowableMatcher; import org.neo4j.test.SuppressOutput; import org.neo4j.test.TargetDirectory; import org.neo4j.test.TestGraphDatabaseFactory; @@ -251,40 +250,6 @@ private IntFunction basicKeyFactory() return value -> "key-" + (value % 3); } - private class NestedThrowableMatcher extends TypeSafeMatcher - { - private final Class expectedType; - - public NestedThrowableMatcher( Class expectedType ) - { - this.expectedType = expectedType; - } - - @Override - public void describeTo( Description description ) - { - description.appendText( "expect " ) - .appendValue( expectedType ) - .appendText( " to be exception cause." ); - } - - @Override - protected boolean matchesSafely( Throwable item ) - { - Throwable currentThrowable = item; - do - { - if ( expectedType.isInstance( currentThrowable ) ) - { - return true; - } - currentThrowable = currentThrowable.getCause(); - } - while ( currentThrowable != null ); - return false; - } - } - private void checkMigrationProgressFeedback() { suppressOutput.getOutputVoice().containsMessage( "Starting upgrade of database" );