package org.infinispan.lucene.readlocks; import java.io.IOException; import java.util.Set; import org.apache.lucene.store.Directory; import org.apache.lucene.store.IOContext; import org.apache.lucene.store.IndexInput; import org.apache.lucene.store.IndexOutput; import org.infinispan.Cache; import org.infinispan.commons.util.Util; import org.infinispan.lucene.ChunkCacheKey; import org.infinispan.lucene.DirectoryIntegrityCheck; import org.infinispan.lucene.FileCacheKey; import org.infinispan.lucene.FileListCacheKey; import org.infinispan.lucene.FileMetadata; import org.infinispan.lucene.directory.DirectoryBuilder; import org.infinispan.lucene.impl.FileListCacheValue; import org.testng.AssertJUnit; import org.testng.annotations.Test; /** * Tests covering the functionality of NoopSegmentreadLocker. * * @author Anna Manukyan */ @Test(groups = "functional", testName = "lucene.readlocks.NoopSegmentReadLockerTest") public class NoopSegmentReadLockerTest extends DistributedSegmentReadLockerTest { @Override Directory createDirectory(Cache cache) { return DirectoryBuilder.newDirectoryInstance(cache, cache, cache, INDEX_NAME) .chunkSize(CHUNK_SIZE) .overrideSegmentReadLocker(new NoopSegmentReadLocker()).create(); } @Test @Override public void testIndexWritingAndFinding() throws IOException, InterruptedException { verifyIgnoringFiles(cache0, cache1, Util.asSet("pending_segments_1")); IndexOutput indexOutput = dirA.createOutput(filename, IOContext.DEFAULT); indexOutput.writeString("no need to write, nobody ever will read this"); indexOutput.close(); assertFileExistsHavingRLCount(filename, 0, true); IndexInput firstOpenOnB = dirB.openInput(filename, IOContext.DEFAULT); assertFileExistsHavingRLCount(filename, 0, true); dirA.deleteFile(filename); assertFileExistsHavingRLCount(filename, 0, false); //Lucene does use clone() - lock implementation ignores it as a clone is //cast on locked segments and released before the close on the parent object IndexInput cloneOfFirstOpenOnB = (IndexInput) firstOpenOnB.clone(); assertFileExistsHavingRLCount(filename, 0, false); cloneOfFirstOpenOnB.close(); assertFileExistsHavingRLCount(filename, 0, false); IndexInput firstOpenOnA = dirA.openInput(filename, IOContext.DEFAULT); assertFileExistsHavingRLCount(filename, 0, false); IndexInput secondOpenOnA = dirA.openInput(filename, IOContext.DEFAULT); assertFileExistsHavingRLCount(filename, 0, false); firstOpenOnA.close(); assertFileExistsHavingRLCount(filename, 0, false); secondOpenOnA.close(); assertFileExistsHavingRLCount(filename, 0, false); firstOpenOnB.close(); //As the NoopSegmentReadLocker ignores also file deletions, then verifying. assertFileAfterDeletion(cache0); assertFileAfterDeletion(cache1); dirA.close(); dirB.close(); Set<String> left_behind = Util.asSet("pending_segments_1", "readme.txt"); verifyIgnoringFiles(cache0, left_behind); verifyIgnoringFiles(cache1, left_behind); } void verifyIgnoringFiles(Cache cache0, Cache cache1, Set<String> files) { verifyIgnoringFiles(cache0, files); verifyIgnoringFiles(cache1, files); } /** * Lucene 5 creates temporary "pending_segments_n" files during commit that get renamed to "segment_n", and since the * NoopSegmentReadLocker never deletes files, some garbage are left behind */ void verifyIgnoringFiles(Cache cache,Set<String> ignoring) { DirectoryIntegrityCheck.verifyDirectoryStructure(cache, INDEX_NAME, ignoring); } private void assertFileAfterDeletion(Cache cache) { FileListCacheValue fileList = (FileListCacheValue) cache.get(new FileListCacheKey(INDEX_NAME, -1)); AssertJUnit.assertNotNull(fileList); AssertJUnit.assertFalse(fileList.contains(filename)); FileMetadata metadata = (FileMetadata) cache.get(new FileCacheKey(INDEX_NAME, filename, -1)); AssertJUnit.assertNotNull(metadata); long totalFileSize = metadata.getSize(); int chunkNumbers = (int)(totalFileSize / CHUNK_SIZE); for(int i = 0; i < chunkNumbers; i++) { AssertJUnit.assertNotNull(cache.get(new ChunkCacheKey(INDEX_NAME, filename, i, CHUNK_SIZE, -1))); } boolean fileNameExistsInCache = false; for(Object key : cache.keySet()) { if(key instanceof FileCacheKey) { FileCacheKey keyObj = (FileCacheKey) key; if(keyObj.getFileName().contains(filename)) { fileNameExistsInCache = true; } } } AssertJUnit.assertTrue(fileNameExistsInCache); } }