mirror of https://github.com/apache/lucene.git
TestIndexWriterOnJRECrash should work on any JRE vendor via Runtime.halt().
git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1482746 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
b5d4f778d2
commit
81ad6c6c6a
|
@ -190,6 +190,11 @@ Build
|
||||||
Test framework may fail internally due to overly aggresive J9 optimizations.
|
Test framework may fail internally due to overly aggresive J9 optimizations.
|
||||||
(Dawid Weiss, Shai Erera)
|
(Dawid Weiss, Shai Erera)
|
||||||
|
|
||||||
|
Tests
|
||||||
|
|
||||||
|
* LUCENE-4901: TestIndexWriterOnJRECrash should work on any
|
||||||
|
JRE vendor via Runtime.halt().
|
||||||
|
(Mike McCandless, Robert Muir, Uwe Schindler, Rodrigo Trujillo, Dawid Weiss)
|
||||||
|
|
||||||
======================= Lucene 4.3.1 =======================
|
======================= Lucene 4.3.1 =======================
|
||||||
|
|
||||||
|
|
|
@ -18,10 +18,11 @@ package org.apache.lucene.index;
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import java.io.BufferedInputStream;
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
|
import java.io.OutputStream;
|
||||||
|
import java.io.PrintStream;
|
||||||
import java.lang.reflect.Field;
|
import java.lang.reflect.Field;
|
||||||
import java.lang.reflect.Method;
|
import java.lang.reflect.Method;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
@ -49,10 +50,6 @@ public class TestIndexWriterOnJRECrash extends TestNRTThreads {
|
||||||
|
|
||||||
@Override @Nightly
|
@Override @Nightly
|
||||||
public void testNRTThreads() throws Exception {
|
public void testNRTThreads() throws Exception {
|
||||||
String vendor = Constants.JAVA_VENDOR;
|
|
||||||
assumeTrue(vendor + " JRE not supported.",
|
|
||||||
vendor.startsWith("Oracle") || vendor.startsWith("Sun") || vendor.startsWith("Apple"));
|
|
||||||
|
|
||||||
// if we are not the fork
|
// if we are not the fork
|
||||||
if (System.getProperty("tests.crashmode") == null) {
|
if (System.getProperty("tests.crashmode") == null) {
|
||||||
// try up to 10 times to create an index
|
// try up to 10 times to create an index
|
||||||
|
@ -112,18 +109,40 @@ public class TestIndexWriterOnJRECrash extends TestNRTThreads {
|
||||||
pb.directory(tempDir);
|
pb.directory(tempDir);
|
||||||
pb.redirectErrorStream(true);
|
pb.redirectErrorStream(true);
|
||||||
Process p = pb.start();
|
Process p = pb.start();
|
||||||
InputStream is = p.getInputStream();
|
|
||||||
BufferedInputStream isl = new BufferedInputStream(is);
|
// We pump everything to stderr.
|
||||||
byte buffer[] = new byte[1024];
|
PrintStream childOut = System.err;
|
||||||
int len = 0;
|
Thread stdoutPumper = ThreadPumper.start(p.getInputStream(), childOut);
|
||||||
if (VERBOSE) System.err.println(">>> Begin subprocess output");
|
Thread stderrPumper = ThreadPumper.start(p.getErrorStream(), childOut);
|
||||||
while ((len = isl.read(buffer)) != -1) {
|
if (VERBOSE) childOut.println(">>> Begin subprocess output");
|
||||||
if (VERBOSE) {
|
|
||||||
System.err.write(buffer, 0, len);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (VERBOSE) System.err.println("<<< End subprocess output");
|
|
||||||
p.waitFor();
|
p.waitFor();
|
||||||
|
stdoutPumper.join();
|
||||||
|
stderrPumper.join();
|
||||||
|
if (VERBOSE) childOut.println("<<< End subprocess output");
|
||||||
|
}
|
||||||
|
|
||||||
|
/** A pipe thread. It'd be nice to reuse guava's implementation for this... */
|
||||||
|
static class ThreadPumper {
|
||||||
|
public static Thread start(final InputStream from, final OutputStream to) {
|
||||||
|
Thread t = new Thread() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
try {
|
||||||
|
byte [] buffer = new byte [1024];
|
||||||
|
int len;
|
||||||
|
while ((len = from.read(buffer)) != -1) {
|
||||||
|
if (VERBOSE) {
|
||||||
|
to.write(buffer, 0, len);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (IOException e) {
|
||||||
|
System.err.println("Couldn't pipe from the forked process: " + e.toString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
t.start();
|
||||||
|
return t;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -155,20 +174,40 @@ public class TestIndexWriterOnJRECrash extends TestNRTThreads {
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* currently, this only works/tested on Sun and IBM.
|
* currently, this only works/tested on Sun and IBM.
|
||||||
*/
|
*/
|
||||||
public void crashJRE() {
|
public void crashJRE() {
|
||||||
try {
|
final String vendor = Constants.JAVA_VENDOR;
|
||||||
Class<?> clazz = Class.forName("sun.misc.Unsafe");
|
final boolean supportsUnsafeNpeDereference =
|
||||||
// we should use getUnsafe instead, harmony implements it, etc.
|
vendor.startsWith("Oracle") ||
|
||||||
Field field = clazz.getDeclaredField("theUnsafe");
|
vendor.startsWith("Sun") ||
|
||||||
field.setAccessible(true);
|
vendor.startsWith("Apple");
|
||||||
Object o = field.get(null);
|
|
||||||
Method m = clazz.getMethod("putAddress", long.class, long.class);
|
try {
|
||||||
m.invoke(o, 0L, 0L);
|
if (supportsUnsafeNpeDereference) {
|
||||||
} catch (Exception e) { e.printStackTrace(); }
|
try {
|
||||||
fail();
|
Class<?> clazz = Class.forName("sun.misc.Unsafe");
|
||||||
|
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 (Throwable e) {
|
||||||
|
System.out.println("Couldn't kill the JVM via Unsafe.");
|
||||||
|
e.printStackTrace(System.out);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fallback attempt to Runtime.halt();
|
||||||
|
Runtime.getRuntime().halt(-1);
|
||||||
|
} catch (Exception e) {
|
||||||
|
System.out.println("Couldn't kill the JVM.");
|
||||||
|
e.printStackTrace(System.out);
|
||||||
|
}
|
||||||
|
|
||||||
|
// We couldn't get the JVM to crash for some reason.
|
||||||
|
fail();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue