You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@lucene.apache.org by rm...@apache.org on 2010/12/10 13:31:16 UTC
svn commit: r1044328 -
/lucene/dev/trunk/lucene/src/test/org/apache/lucene/index/TestIndexWriterOnJRECrash.java
Author: rmuir
Date: Fri Dec 10 12:31:16 2010
New Revision: 1044328
URL: http://svn.apache.org/viewvc?rev=1044328&view=rev
Log:
add test for IW on jre crash
Added:
lucene/dev/trunk/lucene/src/test/org/apache/lucene/index/TestIndexWriterOnJRECrash.java (with props)
Added: lucene/dev/trunk/lucene/src/test/org/apache/lucene/index/TestIndexWriterOnJRECrash.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/lucene/src/test/org/apache/lucene/index/TestIndexWriterOnJRECrash.java?rev=1044328&view=auto
==============================================================================
--- lucene/dev/trunk/lucene/src/test/org/apache/lucene/index/TestIndexWriterOnJRECrash.java (added)
+++ lucene/dev/trunk/lucene/src/test/org/apache/lucene/index/TestIndexWriterOnJRECrash.java Fri Dec 10 12:31:16 2010
@@ -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();
+ }
+}