mirror of https://github.com/apache/lucene.git
add test for IW on jre crash
git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1044328 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
790a492be3
commit
ab3b6ced80
|
@ -0,0 +1,158 @@
|
||||||
|
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.BufferedInputStream;
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.lang.reflect.Field;
|
||||||
|
import java.lang.reflect.Method;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.apache.lucene.store.Directory;
|
||||||
|
import org.apache.lucene.util.Constants;
|
||||||
|
import org.apache.lucene.util._TestUtil;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Runs TestNRTThreads in a separate process, crashes the JRE in the middle
|
||||||
|
* of execution, then runs checkindex to make sure its not corrupt.
|
||||||
|
*/
|
||||||
|
public class TestIndexWriterOnJRECrash extends TestNRTThreads {
|
||||||
|
private File tempDir;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setUp() throws Exception {
|
||||||
|
super.setUp();
|
||||||
|
tempDir = File.createTempFile("jrecrash", "tmp", TEMP_DIR);
|
||||||
|
tempDir.delete();
|
||||||
|
tempDir.mkdir();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void testNRTThreads() throws Exception {
|
||||||
|
String vendor = Constants.JAVA_VENDOR;
|
||||||
|
assumeTrue(vendor + " JRE not supported.",
|
||||||
|
vendor.startsWith("Sun") || vendor.startsWith("IBM"));
|
||||||
|
|
||||||
|
// if we are not the fork
|
||||||
|
if (System.getProperty("tests.crashmode") == null) {
|
||||||
|
// try up to 10 times to create an index
|
||||||
|
for (int i = 0; i < 10; i++) {
|
||||||
|
forkTest();
|
||||||
|
// if we succeeded in finding an index, we are done.
|
||||||
|
if (checkIndexes(tempDir))
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// we are the fork, setup a crashing thread
|
||||||
|
final int crashTime = _TestUtil.nextInt(random, 500, 4000);
|
||||||
|
Thread t = new Thread() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
try {
|
||||||
|
Thread.sleep(crashTime);
|
||||||
|
} catch (InterruptedException e) {}
|
||||||
|
crashJRE();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
t.setPriority(Thread.MAX_PRIORITY);
|
||||||
|
t.start();
|
||||||
|
// run the test until we crash.
|
||||||
|
for (int i = 0; i < 1000; i++) {
|
||||||
|
super.testNRTThreads();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** fork ourselves in a new jvm. sets -Dtests.crashmode=true */
|
||||||
|
public void forkTest() throws Exception {
|
||||||
|
List<String> cmd = new ArrayList<String>();
|
||||||
|
cmd.add(System.getProperty("java.home")
|
||||||
|
+ System.getProperty("file.separator")
|
||||||
|
+ "bin"
|
||||||
|
+ System.getProperty("file.separator")
|
||||||
|
+ "java");
|
||||||
|
cmd.add("-Xmx512m");
|
||||||
|
cmd.add("-Dtests.crashmode=true");
|
||||||
|
cmd.add("-DtempDir=" + tempDir.getPath());
|
||||||
|
cmd.add("-Dtests.seed=" + random.nextLong() + ":" + random.nextLong());
|
||||||
|
cmd.add("-ea");
|
||||||
|
cmd.add("-cp");
|
||||||
|
cmd.add(System.getProperty("java.class.path"));
|
||||||
|
cmd.add("org.junit.runner.JUnitCore");
|
||||||
|
cmd.add(getClass().getName());
|
||||||
|
ProcessBuilder pb = new ProcessBuilder(cmd);
|
||||||
|
pb.directory(TEMP_DIR);
|
||||||
|
pb.redirectErrorStream(true);
|
||||||
|
Process p = pb.start();
|
||||||
|
InputStream is = p.getInputStream();
|
||||||
|
BufferedInputStream isl = new BufferedInputStream(is);
|
||||||
|
byte buffer[] = new byte[1024];
|
||||||
|
int len = 0;
|
||||||
|
if (VERBOSE) System.err.println(">>> Begin subprocess output");
|
||||||
|
while ((len = isl.read(buffer)) != -1) {
|
||||||
|
if (VERBOSE) {
|
||||||
|
System.err.write(buffer, 0, len);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (VERBOSE) System.err.println("<<< End subprocess output");
|
||||||
|
p.waitFor();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Recursively looks for indexes underneath <code>file</code>,
|
||||||
|
* and runs checkindex on them. returns true if it found any indexes.
|
||||||
|
*/
|
||||||
|
public boolean checkIndexes(File file) throws IOException {
|
||||||
|
if (file.isDirectory()) {
|
||||||
|
Directory dir = newFSDirectory(file);
|
||||||
|
if (IndexReader.indexExists(dir)) {
|
||||||
|
if (VERBOSE) {
|
||||||
|
System.err.println("Checking index: " + file);
|
||||||
|
}
|
||||||
|
_TestUtil.checkIndex(dir);
|
||||||
|
dir.close();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
dir.close();
|
||||||
|
for (File f : file.listFiles())
|
||||||
|
if (checkIndexes(f))
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* currently, this only works/tested on Sun and IBM.
|
||||||
|
*/
|
||||||
|
public void crashJRE() {
|
||||||
|
try {
|
||||||
|
Class<?> clazz = Class.forName("sun.misc.Unsafe");
|
||||||
|
// we should use getUnsafe instead, harmony implements it, etc.
|
||||||
|
Field field = clazz.getDeclaredField("theUnsafe");
|
||||||
|
field.setAccessible(true);
|
||||||
|
Object o = field.get(null);
|
||||||
|
Method m = clazz.getMethod("putAddress", long.class, long.class);
|
||||||
|
m.invoke(o, 0L, 0L);
|
||||||
|
} catch (Exception e) { e.printStackTrace(); }
|
||||||
|
fail();
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue