LUCENE-6264: Add SuppressFileSystems annotation

git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1661124 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Robert Muir 2015-02-20 14:00:30 +00:00
parent d3e7357d28
commit 8706a76fe0
5 changed files with 125 additions and 89 deletions

View File

@ -2589,56 +2589,6 @@ public class TestIndexWriter extends LuceneTestCase {
dir.close();
}
// LUCENE-5574
public void testClosingNRTReaderDoesNotCorruptYourIndex() throws IOException {
// Windows disallows deleting & overwriting files still
// open for reading:
assumeFalse("this test can't run on Windows", Constants.WINDOWS);
MockDirectoryWrapper dir = newMockDirectory();
if (TestUtil.isWindowsFS(dir)) {
dir.close();
assumeFalse("this test can't run on simulated windows (WindowsFS)", true);
}
// don't act like windows either, or the test won't simulate the condition
dir.setEnableVirusScanner(false);
// Allow deletion of still open files:
dir.setNoDeleteOpenFile(false);
// Allow writing to same file more than once:
dir.setPreventDoubleWrite(false);
IndexWriterConfig iwc = newIndexWriterConfig(new MockAnalyzer(random()));
LogMergePolicy lmp = new LogDocMergePolicy();
lmp.setMergeFactor(2);
iwc.setMergePolicy(lmp);
RandomIndexWriter w = new RandomIndexWriter(random(), dir, iwc);
Document doc = new Document();
doc.add(new TextField("a", "foo", Field.Store.NO));
w.addDocument(doc);
w.commit();
w.addDocument(doc);
// Get a new reader, but this also sets off a merge:
IndexReader r = w.getReader();
w.close();
// Blow away index and make a new writer:
for(String fileName : dir.listAll()) {
dir.deleteFile(fileName);
}
w = new RandomIndexWriter(random(), dir);
w.addDocument(doc);
w.close();
r.close();
dir.close();
}
/** Make sure that close waits for any still-running commits. */
public void testCloseDuringCommit() throws Exception {

View File

@ -0,0 +1,79 @@
package org.apache.lucene.index;
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import java.io.IOException;
import org.apache.lucene.analysis.MockAnalyzer;
import org.apache.lucene.document.Document;
import org.apache.lucene.document.Field;
import org.apache.lucene.document.TextField;
import org.apache.lucene.store.MockDirectoryWrapper;
import org.apache.lucene.util.Constants;
import org.apache.lucene.util.LuceneTestCase;
import org.apache.lucene.util.LuceneTestCase.SuppressFileSystems;
/** LUCENE-5574 */
@SuppressFileSystems("WindowsFS") // the bug doesn't happen on windows.
public class TestNRTReaderCleanup extends LuceneTestCase {
public void testClosingNRTReaderDoesNotCorruptYourIndex() throws IOException {
// Windows disallows deleting & overwriting files still
// open for reading:
assumeFalse("this test can't run on Windows", Constants.WINDOWS);
MockDirectoryWrapper dir = newMockDirectory();
// don't act like windows either, or the test won't simulate the condition
dir.setEnableVirusScanner(false);
// Allow deletion of still open files:
dir.setNoDeleteOpenFile(false);
// Allow writing to same file more than once:
dir.setPreventDoubleWrite(false);
IndexWriterConfig iwc = newIndexWriterConfig(new MockAnalyzer(random()));
LogMergePolicy lmp = new LogDocMergePolicy();
lmp.setMergeFactor(2);
iwc.setMergePolicy(lmp);
RandomIndexWriter w = new RandomIndexWriter(random(), dir, iwc);
Document doc = new Document();
doc.add(new TextField("a", "foo", Field.Store.NO));
w.addDocument(doc);
w.commit();
w.addDocument(doc);
// Get a new reader, but this also sets off a merge:
IndexReader r = w.getReader();
w.close();
// Blow away index and make a new writer:
for(String fileName : dir.listAll()) {
dir.deleteFile(fileName);
}
w = new RandomIndexWriter(random(), dir);
w.addDocument(doc);
w.close();
r.close();
dir.close();
}
}

View File

@ -295,6 +295,21 @@ public abstract class LuceneTestCase extends Assert {
String[] value();
}
/**
* Annotation for test classes that should avoid mock filesystem types
* (because they test a bug that only happens on linux, for example).
* <p>
* You can avoid specific names {@link Class#getSimpleName()} or use
* the special value {@code *} to disable all mock filesystems.
*/
@Documented
@Inherited
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface SuppressFileSystems {
String[] value();
}
/**
* Marks any suites which are known not to close all the temporary
* files. This may prevent temp. files and folders from being cleaned

View File

@ -6,17 +6,22 @@ import java.nio.file.FileSystem;
import java.nio.file.FileSystems;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.spi.FileSystemProvider;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Locale;
import java.util.Random;
import java.util.Set;
import org.apache.lucene.mockfile.DisableFsyncFS;
import org.apache.lucene.mockfile.HandleLimitFS;
import org.apache.lucene.mockfile.LeakFS;
import org.apache.lucene.mockfile.VerboseFS;
import org.apache.lucene.mockfile.WindowsFS;
import org.apache.lucene.util.LuceneTestCase.SuppressFileSystems;
import org.apache.lucene.util.LuceneTestCase.SuppressTempFileChecks;
import com.carrotsearch.randomizedtesting.RandomizedContext;
@ -111,21 +116,42 @@ final class TestRuleTemporaryFilesCleanup extends TestRuleAdapter {
// TODO: can we make this lower?
private static final int MAX_OPEN_FILES = 2048;
private boolean allowed(Set<String> avoid, Class<? extends FileSystemProvider> clazz) {
if (avoid.contains("*") || avoid.contains(clazz.getSimpleName())) {
return false;
} else {
return true;
}
}
private FileSystem initializeFileSystem() {
Class<?> targetClass = RandomizedContext.current().getTargetClass();
Set<String> avoid = new HashSet<>();
if (targetClass.isAnnotationPresent(SuppressFileSystems.class)) {
SuppressFileSystems a = targetClass.getAnnotation(SuppressFileSystems.class);
avoid.addAll(Arrays.asList(a.value()));
}
FileSystem fs = FileSystems.getDefault();
if (LuceneTestCase.VERBOSE) {
if (LuceneTestCase.VERBOSE && allowed(avoid, VerboseFS.class)) {
fs = new VerboseFS(fs, new TestRuleSetupAndRestoreClassEnv.ThreadNameFixingPrintStreamInfoStream(System.out)).getFileSystem(null);
}
Random random = RandomizedContext.current().getRandom();
// sometimes just use a bare filesystem
if (random.nextInt(10) > 0) {
fs = new DisableFsyncFS(fs).getFileSystem(null);
fs = new LeakFS(fs).getFileSystem(null);
fs = new HandleLimitFS(fs, MAX_OPEN_FILES).getFileSystem(null);
if (allowed(avoid, DisableFsyncFS.class)) {
fs = new DisableFsyncFS(fs).getFileSystem(null);
}
if (allowed(avoid, LeakFS.class)) {
fs = new LeakFS(fs).getFileSystem(null);
}
if (allowed(avoid, HandleLimitFS.class)) {
fs = new HandleLimitFS(fs, MAX_OPEN_FILES).getFileSystem(null);
}
// windows is currently slow
if (random.nextInt(10) == 0) {
// don't try to emulate windows on windows: they don't get along
if (!Constants.WINDOWS) {
if (!Constants.WINDOWS && allowed(avoid, WindowsFS.class)) {
fs = new WindowsFS(fs).getFileSystem(null);
}
}

View File

@ -26,7 +26,6 @@ import java.io.PrintStream;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.nio.CharBuffer;
import java.nio.file.FileSystem;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.ArrayList;
@ -91,16 +90,12 @@ import org.apache.lucene.index.SlowCodecReaderWrapper;
import org.apache.lucene.index.Terms;
import org.apache.lucene.index.TermsEnum;
import org.apache.lucene.index.TieredMergePolicy;
import org.apache.lucene.mockfile.FilterFileSystem;
import org.apache.lucene.mockfile.WindowsFS;
import org.apache.lucene.search.FieldDoc;
import org.apache.lucene.search.FilteredQuery;
import org.apache.lucene.search.FilteredQuery.FilterStrategy;
import org.apache.lucene.search.ScoreDoc;
import org.apache.lucene.search.TopDocs;
import org.apache.lucene.store.Directory;
import org.apache.lucene.store.FSDirectory;
import org.apache.lucene.store.FilterDirectory;
import org.apache.lucene.store.IOContext;
import org.apache.lucene.store.NoLockFactory;
import org.apache.lucene.store.RAMDirectory;
@ -1209,35 +1204,6 @@ public final class TestUtil {
}
}
/** Returns true if this is an FSDirectory backed by {@link WindowsFS}. */
public static boolean isWindowsFS(Directory dir) {
// First unwrap directory to see if there is an FSDir:
while (true) {
if (dir instanceof FSDirectory) {
return isWindowsFS(((FSDirectory) dir).getDirectory());
} else if (dir instanceof FilterDirectory) {
dir = ((FilterDirectory) dir).getDelegate();
} else {
return false;
}
}
}
/** Returns true if this Path is backed by {@link WindowsFS}. */
public static boolean isWindowsFS(Path path) {
FileSystem fs = path.getFileSystem();
while (true) {
if (fs instanceof FilterFileSystem) {
if (((FilterFileSystem) fs).getParent() instanceof WindowsFS) {
return true;
}
fs = ((FilterFileSystem) fs).getDelegate();
} else {
return false;
}
}
}
/** Returns a copy of directory, entirely in RAM */
public static RAMDirectory ramCopyOf(Directory dir) throws IOException {
RAMDirectory ram = new RAMDirectory();