Modified: jackrabbit/oak/branches/1.2/oak-lucene/src/test/java/org/apache/jackrabbit/oak/plugins/index/lucene/IndexCopierTest.java URL: http://svn.apache.org/viewvc/jackrabbit/oak/branches/1.2/oak-lucene/src/test/java/org/apache/jackrabbit/oak/plugins/index/lucene/IndexCopierTest.java?rev=1681005&r1=1681004&r2=1681005&view=diff ============================================================================== --- jackrabbit/oak/branches/1.2/oak-lucene/src/test/java/org/apache/jackrabbit/oak/plugins/index/lucene/IndexCopierTest.java (original) +++ jackrabbit/oak/branches/1.2/oak-lucene/src/test/java/org/apache/jackrabbit/oak/plugins/index/lucene/IndexCopierTest.java Fri May 22 06:52:25 2015 @@ -20,25 +20,35 @@ package org.apache.jackrabbit.oak.plugins.index.lucene; import java.io.File; +import java.io.FileNotFoundException; import java.io.IOException; +import java.util.ArrayList; import java.util.Arrays; +import java.util.Collection; import java.util.HashSet; import java.util.List; import java.util.Random; import java.util.Set; +import java.util.concurrent.BlockingQueue; +import java.util.concurrent.Callable; import java.util.concurrent.CountDownLatch; import java.util.concurrent.Executor; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; +import java.util.concurrent.Future; +import java.util.concurrent.LinkedBlockingQueue; import javax.management.openmbean.TabularData; +import com.google.common.base.StandardSystemProperty; import com.google.common.collect.Lists; +import com.google.common.collect.Sets; import com.google.common.util.concurrent.ForwardingListeningExecutorService; import com.google.common.util.concurrent.Futures; import com.google.common.util.concurrent.ListenableFuture; import com.google.common.util.concurrent.ListeningExecutorService; import com.google.common.util.concurrent.MoreExecutors; +import org.apache.commons.io.FileUtils; import org.apache.jackrabbit.oak.commons.IOUtils; import org.apache.jackrabbit.oak.spi.state.NodeBuilder; import org.apache.jackrabbit.oak.spi.state.NodeState; @@ -47,19 +57,21 @@ import org.apache.lucene.store.IOContext import org.apache.lucene.store.IndexInput; import org.apache.lucene.store.IndexOutput; import org.apache.lucene.store.RAMDirectory; -import org.junit.Ignore; import org.junit.Rule; import org.junit.Test; import org.junit.rules.TemporaryFolder; import static com.google.common.collect.Lists.newArrayList; +import static com.google.common.collect.Sets.newHashSet; import static com.google.common.util.concurrent.MoreExecutors.sameThreadExecutor; import static org.apache.jackrabbit.oak.plugins.index.IndexConstants.REINDEX_COUNT; import static org.apache.jackrabbit.oak.plugins.nodetype.write.InitialContent.INITIAL_CONTENT; +import static org.junit.Assert.assertArrayEquals; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; +import static org.junit.Assume.assumeTrue; public class IndexCopierTest { private Random rnd = new Random(); @@ -79,7 +91,7 @@ public class IndexCopierTest { IndexCopier c1 = new RAMIndexCopier(baseDir, sameThreadExecutor(), getWorkDir()); Directory remote = new RAMDirectory(); - Directory wrapped = c1.wrap("/foo" , defn, remote); + Directory wrapped = c1.wrapForRead("/foo", defn, remote); byte[] t1 = writeFile(remote , "t1"); byte[] t2 = writeFile(remote , "t2"); @@ -104,7 +116,7 @@ public class IndexCopierTest { IndexCopier c1 = new IndexCopier(sameThreadExecutor(), getWorkDir()); Directory remote = new RAMDirectory(); - Directory wrapped = c1.wrap("/foo" , defn, remote); + Directory wrapped = c1.wrapForRead("/foo", defn, remote); byte[] t1 = writeFile(remote, "t1"); byte[] t2 = writeFile(remote , "t2"); @@ -128,16 +140,16 @@ public class IndexCopierTest { assertEquals(1, td.size()); } - @Ignore("OAK-2722") //FIXME test fails on windows @Test public void deleteOldPostReindex() throws Exception{ + assumeNotWindows(); IndexDefinition defn = new IndexDefinition(root, builder.getNodeState()); IndexCopier c1 = new IndexCopier(sameThreadExecutor(), getWorkDir()); Directory remote = new CloseSafeDir(); - Directory w1 = c1.wrap("/foo" , defn, remote); + Directory w1 = c1.wrapForRead("/foo", defn, remote); - byte[] t1 = writeFile(remote , "t1"); + byte[] t1 = writeFile(remote, "t1"); byte[] t2 = writeFile(remote , "t2"); readAndAssert(w1, "t1", t1); @@ -154,7 +166,7 @@ public class IndexCopierTest { //Close old version w1.close(); //Get a new one with updated reindexCount - Directory w2 = c1.wrap("/foo" , defn, remote); + Directory w2 = c1.wrapForRead("/foo", defn, remote); readAndAssert(w2, "t1", t1); @@ -174,7 +186,7 @@ public class IndexCopierTest { IndexCopier c1 = new RAMIndexCopier(baseDir, executor, getWorkDir()); TestRAMDirectory remote = new TestRAMDirectory(); - Directory wrapped = c1.wrap("/foo", defn, remote); + Directory wrapped = c1.wrapForRead("/foo", defn, remote); byte[] t1 = writeFile(remote , "t1"); @@ -237,7 +249,7 @@ public class IndexCopierTest { super.copy(to, src, dest, context); } }; - Directory wrapped = c1.wrap("/foo", defn, remote); + Directory wrapped = c1.wrapForRead("/foo", defn, remote); byte[] t1 = writeFile(remote , "t1"); @@ -281,7 +293,7 @@ public class IndexCopierTest { IndexCopier c1 = new RAMIndexCopier(baseDir, sameThreadExecutor(), getWorkDir()); TestRAMDirectory remote = new TestRAMDirectory(); - Directory wrapped = c1.wrap("/foo" , defn, remote); + Directory wrapped = c1.wrapForRead("/foo", defn, remote); byte[] t1 = writeFile(remote, "t1"); @@ -290,7 +302,7 @@ public class IndexCopierTest { assertEquals(1, remote.openedFiles.size()); //2. Reuse the testDir and read again - Directory wrapped2 = c1.wrap("/foo", defn, remote); + Directory wrapped2 = c1.wrapForRead("/foo", defn, remote); remote.reset(); //3. Now read should be served from local @@ -298,7 +310,7 @@ public class IndexCopierTest { assertEquals(0, remote.openedFiles.size()); //Now check if local file gets corrupted then read from remote - Directory wrapped3 = c1.wrap("/foo" , defn, remote); + Directory wrapped3 = c1.wrapForRead("/foo", defn, remote); remote.reset(); //4. Corrupt the local copy @@ -323,7 +335,7 @@ public class IndexCopierTest { }; String fileName = "failed.txt"; - Directory wrapped = c1.wrap("/foo" , defn, remote); + Directory wrapped = c1.wrapForRead("/foo", defn, remote); byte[] t1 = writeFile(remote , fileName); @@ -351,10 +363,10 @@ public class IndexCopierTest { Directory r1 = new RAMDirectory(); - byte[] t1 = writeFile(r1 , "t1"); + byte[] t1 = writeFile(r1, "t1"); byte[] t2 = writeFile(r1 , "t2"); - Directory w1 = c1.wrap("/foo" , defn, r1); + Directory w1 = c1.wrapForRead("/foo", defn, r1); readAndAssert(w1, "t1", t1); readAndAssert(w1, "t2", t2); @@ -366,7 +378,7 @@ public class IndexCopierTest { copy(r1, r2); r2.deleteFile("t1"); - Directory w2 = c1.wrap("/foo" , defn, r2); + Directory w2 = c1.wrapForRead("/foo", defn, r2); //Close would trigger removal of file which are not present in remote w2.close(); @@ -397,7 +409,7 @@ public class IndexCopierTest { byte[] t1 = writeFile(r1, "t1"); byte[] t2 = writeFile(r1 , "t2"); - Directory w1 = c1.wrap("/foo" , defn, r1); + Directory w1 = c1.wrapForRead("/foo", defn, r1); readAndAssert(w1, "t1", t1); readAndAssert(w1, "t2", t2); @@ -409,7 +421,7 @@ public class IndexCopierTest { copy(r1, r2); r2.deleteFile("t1"); - Directory w2 = c1.wrap("/foo" , defn, r2); + Directory w2 = c1.wrapForRead("/foo", defn, r2); //Close would trigger removal of file which are not present in remote testFiles.add("t1"); @@ -422,14 +434,14 @@ public class IndexCopierTest { assertEquals(IOUtils.humanReadableByteCount(t1.length), c1.getGarbageSize()); assertEquals(1, c1.getGarbageDetails().length); - Directory w3 = c1.wrap("/foo" , defn, r2); + Directory w3 = c1.wrapForRead("/foo", defn, r2); w3.close(); assertEquals(2, testFile.getDeleteAttemptCount()); //Now let the file to be deleted testFiles.clear(); - Directory w4 = c1.wrap("/foo" , defn, r2); + Directory w4 = c1.wrapForRead("/foo", defn, r2); w4.close(); //No pending deletes left @@ -447,14 +459,14 @@ public class IndexCopierTest { Directory remote1 = new RAMDirectory(); byte[] t1 = writeFile(remote1, "t1"); - Directory local1 = copier.wrap("/foo", defn, remote1); + Directory local1 = copier.wrapForRead("/foo", defn, remote1); readAndAssert(local1, "t1", t1); //While local1 is open , open another local2 and read t2 Directory remote2 = new RAMDirectory(); byte[] t2 = writeFile(remote2, "t2"); - Directory local2 = copier.wrap("/foo", defn, remote2); + Directory local2 = copier.wrapForRead("/foo", defn, remote2); readAndAssert(local2, "t2", t2); //Close local1 @@ -464,6 +476,345 @@ public class IndexCopierTest { readAndAssert(local2, "t2", t2); } + @Test + public void wrapForWriteWithoutIndexPath() throws Exception{ + assumeNotWindows(); + Directory remote = new CloseSafeDir(); + + IndexCopier copier = new IndexCopier(sameThreadExecutor(), getWorkDir()); + + IndexDefinition defn = new IndexDefinition(root, builder.getNodeState()); + Directory dir = copier.wrapForWrite(defn, remote, false); + + byte[] t1 = writeFile(dir, "t1"); + + dir.close(); + + readAndAssert(remote, "t1", t1); + //Work dir must be empty post close + assertArrayEquals(FileUtils.EMPTY_FILE_ARRAY, copier.getIndexWorkDir().listFiles()); + } + + @Test + public void wrapForWriteWithIndexPath() throws Exception{ + assumeNotWindows(); + Directory remote = new CloseSafeDir(); + + IndexCopier copier = new IndexCopier(sameThreadExecutor(), getWorkDir()); + + builder.setProperty(LuceneIndexConstants.INDEX_PATH, "foo"); + IndexDefinition defn = new IndexDefinition(root, builder.getNodeState()); + Directory dir = copier.wrapForWrite(defn, remote, false); + + byte[] t1 = writeFile(dir, "t1"); + + dir.close(); + + readAndAssert(remote, "t1", t1); + //Work dir must be empty post close + List<File> files = new ArrayList<File>(FileUtils.listFiles(copier.getIndexRootDir(), null, true)); + assertEquals(1, files.size()); + assertEquals("t1", files.get(0).getName()); + } + + @Test + public void copyOnWriteBasics() throws Exception{ + Directory baseDir = new CloseSafeDir(); + IndexDefinition defn = new IndexDefinition(root, builder.getNodeState()); + IndexCopier copier = new RAMIndexCopier(baseDir, sameThreadExecutor(), getWorkDir()); + + Directory remote = new RAMDirectory(); + byte[] t1 = writeFile(remote, "t1"); + + //State of remote directory should set before wrapping as later + //additions would not be picked up given COW assume remote directory + //to be read only + Directory local = copier.wrapForWrite(defn, remote, false); + + assertEquals(newHashSet("t1"), newHashSet(local.listAll())); + assertEquals(t1.length, local.fileLength("t1")); + + byte[] t2 = writeFile(local, "t2"); + assertEquals(newHashSet("t1", "t2"), newHashSet(local.listAll())); + assertEquals(t2.length, local.fileLength("t2")); + + assertTrue(local.fileExists("t1")); + assertTrue(local.fileExists("t2")); + + assertTrue("t2 should be copied to remote", remote.fileExists("t2")); + + readAndAssert(local, "t1", t1); + readAndAssert(local, "t2", t2); + + local.deleteFile("t1"); + assertEquals(newHashSet("t2"), newHashSet(local.listAll())); + + local.deleteFile("t2"); + assertEquals(newHashSet(), newHashSet(local.listAll())); + + + try { + local.fileLength("nonExistentFile"); + fail(); + } catch (FileNotFoundException ignore) { + + } + + try { + local.openInput("nonExistentFile", IOContext.DEFAULT); + fail(); + } catch (FileNotFoundException ignore) { + + } + + local.close(); + assertFalse(baseDir.fileExists("t2")); + } + + /** + * Checks for the case where if the file exist local before writer starts + * then those files do not get deleted even if deleted by writer via + * indexing process from 'baseDir' as they might be in use by existing open + * indexes + */ + @Test + public void cowExistingLocalFileNotDeleted() throws Exception{ + Directory baseDir = new CloseSafeDir(); + IndexDefinition defn = new IndexDefinition(root, builder.getNodeState()); + IndexCopier copier = new RAMIndexCopier(baseDir, sameThreadExecutor(), getWorkDir()); + + Directory remote = new CloseSafeDir(); + byte[] t1 = writeFile(remote, "t1"); + byte[] t2 = writeFile(remote, "t2"); + Directory local = copier.wrapForWrite(defn, remote, false); + assertEquals(newHashSet("t1", "t2"), newHashSet(local.listAll())); + + byte[] t3 = writeFile(local, "t3"); + + //Now pull in the file t1 via CopyOnRead in baseDir + Directory localForRead = copier.wrapForRead("/foo", defn, remote); + readAndAssert(localForRead, "t1", t1); + + //File which was copied from remote should not be deleted from baseDir + //upon delete from local + assertTrue(baseDir.fileExists("t1")); + local.deleteFile("t1"); + assertFalse("t1 should be deleted from remote", remote.fileExists("t1")); + assertFalse("t1 should be deleted from 'local' view also", local.fileExists("t1")); + assertTrue("t1 should not be deleted from baseDir", baseDir.fileExists("t1")); + + //File which was created only via local SHOULD get removed from + //baseDir only upon close + assertTrue(baseDir.fileExists("t3")); + local.deleteFile("t3"); + assertFalse("t1 should be deleted from remote", local.fileExists("t3")); + assertTrue("t1 should NOT be deleted from remote", baseDir.fileExists("t3")); + + local.close(); + assertFalse("t3 should also be deleted from local", baseDir.fileExists("t3")); + } + + @Test + public void cowReadDoneFromLocalIfFileExist() throws Exception{ + final Set<String> readLocal = newHashSet(); + Directory baseDir = new CloseSafeDir(){ + @Override + public IndexInput openInput(String name, IOContext context) throws IOException { + readLocal.add(name); + return super.openInput(name, context); + } + }; + IndexDefinition defn = new IndexDefinition(root, builder.getNodeState()); + IndexCopier copier = new RAMIndexCopier(baseDir, sameThreadExecutor(), getWorkDir()); + + final Set<String> readRemotes = newHashSet(); + Directory remote = new RAMDirectory() { + @Override + public IndexInput openInput(String name, IOContext context) throws IOException { + readRemotes.add(name); + return super.openInput(name, context); + } + }; + byte[] t1 = writeFile(remote, "t1"); + Directory local = copier.wrapForWrite(defn, remote, false); + + //Read should be served from remote + readRemotes.clear();readLocal.clear(); + readAndAssert(local, "t1", t1); + assertEquals(newHashSet("t1"), readRemotes); + assertEquals(newHashSet(), readLocal); + + //Now pull in the file t1 via CopyOnRead in baseDir + Directory localForRead = copier.wrapForRead("/foo", defn, remote); + readAndAssert(localForRead, "t1", t1); + + //Read should be served from local + readRemotes.clear();readLocal.clear(); + readAndAssert(local, "t1", t1); + assertEquals(newHashSet(), readRemotes); + assertEquals(newHashSet("t1"), readLocal); + + local.close(); + } + + @Test + public void cowCopyDoneOnClose() throws Exception{ + final CollectingExecutor executor = new CollectingExecutor(); + Directory baseDir = new CloseSafeDir(); + IndexDefinition defn = new IndexDefinition(root, builder.getNodeState()); + IndexCopier copier = new RAMIndexCopier(baseDir, executor, getWorkDir()); + + Directory remote = new CloseSafeDir(); + + final Directory local = copier.wrapForWrite(defn, remote, false); + byte[] t1 = writeFile(local, "t1"); + + assertTrue(local.fileExists("t1")); + assertFalse("t1 should NOT be copied to remote", remote.fileExists("t1")); + + //Execute all job + executor.executeAll(); + + assertTrue("t1 should now be copied to remote", remote.fileExists("t1")); + + byte[] t2 = writeFile(local, "t2"); + assertFalse("t2 should NOT be copied to remote", remote.fileExists("t2")); + + final ExecutorService executorService = Executors.newFixedThreadPool(4); + final CountDownLatch copyLatch = new CountDownLatch(1); + Future<?> copyTasks = executorService.submit(new Callable<Object>() { + @Override + public Object call() throws Exception { + copyLatch.await(); + //the executor to a proper one as it might happen that + //STOP task is added post CountingExecutor has executed. Then there + //would be none to process the STOP. Having a proper executor would + //handle that case + executor.setForwardingExecutor(executorService); + executor.executeAll(); + return null; + } + }); + + final CountDownLatch closeLatch = new CountDownLatch(1); + Future<?> closeTasks = executorService.submit(new Callable<Object>() { + @Override + public Object call() throws Exception { + closeLatch.await(); + local.close(); + return null; + } + }); + + closeLatch.countDown(); + assertFalse("t2 should NOT be copied to remote", remote.fileExists("t2")); + + //Let copy to proceed + copyLatch.countDown(); + + //Now wait for close to finish + closeTasks.get(); + assertTrue("t2 should now be copied to remote", remote.fileExists("t2")); + + executorService.shutdown(); + } + + @Test + public void cowCopyDoneOnCloseExceptionHandling() throws Exception{ + final CollectingExecutor executor = new CollectingExecutor(); + Directory baseDir = new CloseSafeDir(); + IndexDefinition defn = new IndexDefinition(root, builder.getNodeState()); + IndexCopier copier = new RAMIndexCopier(baseDir, executor, getWorkDir()); + + Directory remote = new CloseSafeDir(); + + final Directory local = copier.wrapForWrite(defn, remote, false); + byte[] t1 = writeFile(local, "t1"); + + assertTrue(local.fileExists("t1")); + assertFalse("t1 should NOT be copied to remote", remote.fileExists("t1")); + + //Execute all job + executor.executeAll(); + + assertTrue("t1 should now be copied to remote", remote.fileExists("t1")); + + byte[] t2 = writeFile(local, "t2"); + assertFalse("t2 should NOT be copied to remote", remote.fileExists("t2")); + + ExecutorService executorService = Executors.newFixedThreadPool(2); + final CountDownLatch copyLatch = new CountDownLatch(1); + Future<?> copyTasks = executorService.submit(new Callable<Object>() { + @Override + public Object call() throws Exception { + copyLatch.await(); + executor.executeAll(); + executor.enableImmediateExecution(); + return null; + } + }); + + final CountDownLatch closeLatch = new CountDownLatch(1); + Future<?> closeTasks = executorService.submit(new Callable<Object>() { + @Override + public Object call() throws Exception { + closeLatch.await(); + local.close(); + return null; + } + }); + + closeLatch.countDown(); + assertFalse("t2 should NOT be copied to remote", remote.fileExists("t2")); + + //Let copy to proceed + copyLatch.countDown(); + + //Now wait for close to finish + closeTasks.get(); + assertTrue("t2 should now be copied to remote", remote.fileExists("t2")); + + executorService.shutdown(); + } + + @Test + public void cowFailureInCopy() throws Exception{ + ExecutorService executorService = Executors.newFixedThreadPool(2); + Directory baseDir = new CloseSafeDir(); + IndexDefinition defn = new IndexDefinition(root, builder.getNodeState()); + IndexCopier copier = new RAMIndexCopier(baseDir, executorService, getWorkDir()); + + final Set<String> toFail = Sets.newHashSet(); + Directory remote = new CloseSafeDir() { + @Override + public IndexOutput createOutput(String name, IOContext context) throws IOException { + if (toFail.contains(name)){ + throw new RuntimeException("Failing copy for "+name); + } + return super.createOutput(name, context); + } + }; + + final Directory local = copier.wrapForWrite(defn, remote, false); + toFail.add("t2"); + byte[] t1 = writeFile(local, "t1"); + byte[] t2 = writeFile(local, "t2"); + + try { + local.close(); + fail(); + } catch (IOException ignore){ + + } + + executorService.shutdown(); + } + + @Test + public void cowIndexPathNotDefined() throws Exception{ + + } + private byte[] writeFile(Directory dir, String name) throws IOException { byte[] data = randomBytes(rnd.nextInt(maxFileSize) + 1); IndexOutput o = dir.createOutput(name, IOContext.DEFAULT); @@ -498,13 +849,18 @@ public class IndexCopierTest { private class RAMIndexCopier extends IndexCopier { final Directory baseDir; - public RAMIndexCopier(Directory baseDir, Executor executor, File indexRootDir) { + public RAMIndexCopier(Directory baseDir, Executor executor, File indexRootDir) throws IOException { super(executor, indexRootDir); this.baseDir = baseDir; } @Override - protected Directory createLocalDir(String indexPath, IndexDefinition definition) throws IOException { + protected Directory createLocalDirForIndexReader(String indexPath, IndexDefinition definition) throws IOException { + return baseDir; + } + + @Override + protected Directory createLocalDirForIndexWriter(IndexDefinition definition) throws IOException { return baseDir; } } @@ -531,18 +887,44 @@ public class IndexCopierTest { } private static class CollectingExecutor implements Executor { - final List<Runnable> commands = newArrayList(); + final BlockingQueue<Runnable> commands = new LinkedBlockingQueue<Runnable>(); + private boolean immediateExecution = false; + private volatile Executor forwardingExecutor; @Override public void execute(Runnable command) { - commands.add(command); + if (forwardingExecutor != null){ + forwardingExecutor.execute(command); + return; + } + if (immediateExecution){ + command.run(); + } else { + commands.add(command); + } } void executeAll(){ - for (Runnable c : commands) { + Runnable c; + while ((c = commands.poll()) != null){ c.run(); } } + + void enableImmediateExecution(){ + immediateExecution = true; + } + + void enableDelayedExecution(){ + immediateExecution = false; + } + + void setForwardingExecutor(Executor forwardingExecutor){ + this.forwardingExecutor = forwardingExecutor; + } } + private static void assumeNotWindows() { + assumeTrue(!StandardSystemProperty.OS_NAME.value().toLowerCase().contains("windows")); + } }
Modified: jackrabbit/oak/branches/1.2/oak-lucene/src/test/java/org/apache/jackrabbit/oak/plugins/index/lucene/LuceneIndexProviderServiceTest.java URL: http://svn.apache.org/viewvc/jackrabbit/oak/branches/1.2/oak-lucene/src/test/java/org/apache/jackrabbit/oak/plugins/index/lucene/LuceneIndexProviderServiceTest.java?rev=1681005&r1=1681004&r2=1681005&view=diff ============================================================================== --- jackrabbit/oak/branches/1.2/oak-lucene/src/test/java/org/apache/jackrabbit/oak/plugins/index/lucene/LuceneIndexProviderServiceTest.java (original) +++ jackrabbit/oak/branches/1.2/oak-lucene/src/test/java/org/apache/jackrabbit/oak/plugins/index/lucene/LuceneIndexProviderServiceTest.java Fri May 22 06:52:25 2015 @@ -22,16 +22,20 @@ package org.apache.jackrabbit.oak.plugin import java.util.HashMap; import java.util.Map; +import org.apache.jackrabbit.oak.plugins.index.IndexEditorProvider; import org.apache.jackrabbit.oak.spi.commit.BackgroundObserver; import org.apache.jackrabbit.oak.spi.commit.Observer; import org.apache.jackrabbit.oak.spi.query.QueryIndexProvider; +import org.apache.lucene.util.InfoStream; import org.apache.sling.testing.mock.osgi.MockOsgi; import org.apache.sling.testing.mock.osgi.junit.OsgiContext; import org.junit.Rule; import org.junit.Test; import org.junit.rules.TemporaryFolder; +import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; public class LuceneIndexProviderServiceTest { @@ -50,10 +54,16 @@ public class LuceneIndexProviderServiceT assertNotNull(context.getService(QueryIndexProvider.class)); assertNotNull(context.getService(Observer.class)); + assertNotNull(context.getService(IndexEditorProvider.class)); - assertNotNull("CopyOnRead should be enabled by default",context.getService(CopyOnReadStatsMBean.class)); + LuceneIndexEditorProvider editorProvider = + (LuceneIndexEditorProvider) context.getService(IndexEditorProvider.class); + assertNull(editorProvider.getIndexCopier()); + + assertNotNull("CopyOnRead should be enabled by default", context.getService(CopyOnReadStatsMBean.class)); assertTrue(context.getService(Observer.class) instanceof BackgroundObserver); + assertEquals(InfoStream.NO_OUTPUT, InfoStream.getDefault()); MockOsgi.deactivate(service); } @@ -69,6 +79,31 @@ public class LuceneIndexProviderServiceT MockOsgi.deactivate(service); } + @Test + public void enableCopyOnWrite() throws Exception{ + Map<String,Object> config = getDefaultConfig(); + config.put("enableCopyOnWriteSupport", true); + MockOsgi.activate(service, context.bundleContext(), config); + + LuceneIndexEditorProvider editorProvider = + (LuceneIndexEditorProvider) context.getService(IndexEditorProvider.class); + + assertNotNull(editorProvider); + assertNotNull(editorProvider.getIndexCopier()); + + MockOsgi.deactivate(service); + } + + @Test + public void debugLogging() throws Exception{ + Map<String,Object> config = getDefaultConfig(); + config.put("debug", true); + MockOsgi.activate(service, context.bundleContext(), config); + + assertEquals(LoggingInfoStream.INSTANCE, InfoStream.getDefault()); + MockOsgi.deactivate(service); + } + private Map<String,Object> getDefaultConfig(){ Map<String,Object> config = new HashMap<String, Object>(); config.put("localIndexDir", folder.getRoot().getAbsolutePath()); Modified: jackrabbit/oak/branches/1.2/oak-lucene/src/test/java/org/apache/jackrabbit/oak/plugins/index/lucene/LuceneIndexTest.java URL: http://svn.apache.org/viewvc/jackrabbit/oak/branches/1.2/oak-lucene/src/test/java/org/apache/jackrabbit/oak/plugins/index/lucene/LuceneIndexTest.java?rev=1681005&r1=1681004&r2=1681005&view=diff ============================================================================== --- jackrabbit/oak/branches/1.2/oak-lucene/src/test/java/org/apache/jackrabbit/oak/plugins/index/lucene/LuceneIndexTest.java (original) +++ jackrabbit/oak/branches/1.2/oak-lucene/src/test/java/org/apache/jackrabbit/oak/plugins/index/lucene/LuceneIndexTest.java Fri May 22 06:52:25 2015 @@ -108,6 +108,7 @@ import org.junit.Test; import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableSet; +@SuppressWarnings("ConstantConditions") public class LuceneIndexTest { private static final EditorHook HOOK = new EditorHook( @@ -341,7 +342,7 @@ public class LuceneIndexTest { } private void purgeDeletedDocs(NodeBuilder idx, IndexDefinition definition) throws IOException { - IndexWriter writer = new IndexWriter(newIndexDirectory(definition, idx), getIndexWriterConfig(definition)); + IndexWriter writer = new IndexWriter(newIndexDirectory(definition, idx), getIndexWriterConfig(definition, true)); writer.forceMergeDeletes(); writer.close(); } Modified: jackrabbit/oak/branches/1.2/oak-lucene/src/test/java/org/apache/jackrabbit/oak/plugins/index/lucene/LucenePropertyIndexTest.java URL: http://svn.apache.org/viewvc/jackrabbit/oak/branches/1.2/oak-lucene/src/test/java/org/apache/jackrabbit/oak/plugins/index/lucene/LucenePropertyIndexTest.java?rev=1681005&r1=1681004&r2=1681005&view=diff ============================================================================== --- jackrabbit/oak/branches/1.2/oak-lucene/src/test/java/org/apache/jackrabbit/oak/plugins/index/lucene/LucenePropertyIndexTest.java (original) +++ jackrabbit/oak/branches/1.2/oak-lucene/src/test/java/org/apache/jackrabbit/oak/plugins/index/lucene/LucenePropertyIndexTest.java Fri May 22 06:52:25 2015 @@ -20,12 +20,15 @@ package org.apache.jackrabbit.oak.plugins.index.lucene; import java.io.InputStream; +import java.io.IOException; import java.text.ParseException; import java.util.Calendar; import java.util.Collections; import java.util.List; import java.util.Random; import java.util.Set; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; import javax.annotation.Nonnull; import javax.jcr.PropertyType; @@ -59,7 +62,10 @@ import org.apache.jackrabbit.oak.spi.com import org.apache.jackrabbit.oak.spi.query.QueryIndexProvider; import org.apache.jackrabbit.oak.spi.security.OpenSecurityProvider; import org.apache.jackrabbit.util.ISO8601; +import org.junit.After; +import org.junit.Rule; import org.junit.Test; +import org.junit.rules.TemporaryFolder; import static com.google.common.collect.ImmutableSet.of; import static java.util.Arrays.asList; @@ -95,6 +101,11 @@ public class LucenePropertyIndexTest ext */ static final int NUMBER_OF_NODES = LucenePropertyIndex.LUCENE_QUERY_BATCH_SIZE * 2; + private ExecutorService executorService = Executors.newFixedThreadPool(2); + + @Rule + public TemporaryFolder temporaryFolder = new TemporaryFolder(); + @Override protected void createTestIndexNode() throws Exception { setTraversalEnabled(false); @@ -108,12 +119,25 @@ public class LucenePropertyIndexTest ext .with(new OpenSecurityProvider()) .with((QueryIndexProvider) provider) .with((Observer) provider) - .with(new LuceneIndexEditorProvider()) + .with(new LuceneIndexEditorProvider(createIndexCopier())) .with(new PropertyIndexEditorProvider()) .with(new NodeTypeIndexProvider()) .createContentRepository(); } + private IndexCopier createIndexCopier() { + try { + return new IndexCopier(executorService, temporaryFolder.getRoot()); + } catch (IOException e) { + throw new RuntimeException(e); + } + } + + @After + public void shutdownExecutor(){ + executorService.shutdown(); + } + @Test public void fulltextSearchWithCustomAnalyzer() throws Exception { Tree idx = createFulltextIndex(root.getTree("/"), "test");
