You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@lucene.apache.org by dw...@apache.org on 2013/05/15 12:08:41 UTC
svn commit: r1482746 - in /lucene/dev/trunk/lucene: CHANGES.txt
core/src/test/org/apache/lucene/index/TestIndexWriterOnJRECrash.java
Author: dweiss
Date: Wed May 15 10:08:41 2013
New Revision: 1482746
URL: http://svn.apache.org/r1482746
Log:
TestIndexWriterOnJRECrash should work on any JRE vendor via Runtime.halt().
Modified:
lucene/dev/trunk/lucene/CHANGES.txt
lucene/dev/trunk/lucene/core/src/test/org/apache/lucene/index/TestIndexWriterOnJRECrash.java
Modified: lucene/dev/trunk/lucene/CHANGES.txt
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/lucene/CHANGES.txt?rev=1482746&r1=1482745&r2=1482746&view=diff
==============================================================================
--- lucene/dev/trunk/lucene/CHANGES.txt (original)
+++ lucene/dev/trunk/lucene/CHANGES.txt Wed May 15 10:08:41 2013
@@ -190,6 +190,11 @@ Build
Test framework may fail internally due to overly aggresive J9 optimizations.
(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 =======================
Modified: lucene/dev/trunk/lucene/core/src/test/org/apache/lucene/index/TestIndexWriterOnJRECrash.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/lucene/core/src/test/org/apache/lucene/index/TestIndexWriterOnJRECrash.java?rev=1482746&r1=1482745&r2=1482746&view=diff
==============================================================================
--- lucene/dev/trunk/lucene/core/src/test/org/apache/lucene/index/TestIndexWriterOnJRECrash.java (original)
+++ lucene/dev/trunk/lucene/core/src/test/org/apache/lucene/index/TestIndexWriterOnJRECrash.java Wed May 15 10:08:41 2013
@@ -18,10 +18,11 @@ package org.apache.lucene.index;
*
*/
-import java.io.BufferedInputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
+import java.io.OutputStream;
+import java.io.PrintStream;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.ArrayList;
@@ -49,10 +50,6 @@ public class TestIndexWriterOnJRECrash e
@Override @Nightly
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 (System.getProperty("tests.crashmode") == null) {
// try up to 10 times to create an index
@@ -112,18 +109,40 @@ public class TestIndexWriterOnJRECrash e
pb.directory(tempDir);
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");
+
+ // We pump everything to stderr.
+ PrintStream childOut = System.err;
+ Thread stdoutPumper = ThreadPumper.start(p.getInputStream(), childOut);
+ Thread stderrPumper = ThreadPumper.start(p.getErrorStream(), childOut);
+ if (VERBOSE) childOut.println(">>> Begin subprocess output");
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 e
}
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();
+ final String vendor = Constants.JAVA_VENDOR;
+ final boolean supportsUnsafeNpeDereference =
+ vendor.startsWith("Oracle") ||
+ vendor.startsWith("Sun") ||
+ vendor.startsWith("Apple");
+
+ try {
+ if (supportsUnsafeNpeDereference) {
+ try {
+ 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();
}
}