1 package org.apache.lucene.index;
4 * Licensed to the Apache Software Foundation (ASF) under one or more
5 * contributor license agreements. See the NOTICE file distributed with
6 * this work for additional information regarding copyright ownership.
7 * The ASF licenses this file to You under the Apache License, Version 2.0
8 * (the "License"); you may not use this file except in compliance with
9 * the License. You may obtain a copy of the License at
11 * http://www.apache.org/licenses/LICENSE-2.0
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
21 import java.io.BufferedInputStream;
23 import java.io.IOException;
24 import java.io.InputStream;
25 import java.lang.reflect.Field;
26 import java.lang.reflect.Method;
27 import java.util.ArrayList;
28 import java.util.List;
30 import org.apache.lucene.store.Directory;
31 import org.apache.lucene.store.MockDirectoryWrapper;
32 import org.apache.lucene.util.Constants;
33 import org.apache.lucene.util._TestUtil;
36 * Runs TestNRTThreads in a separate process, crashes the JRE in the middle
37 * of execution, then runs checkindex to make sure its not corrupt.
39 public class TestIndexWriterOnJRECrash extends TestNRTThreads {
43 public void setUp() throws Exception {
45 tempDir = _TestUtil.getTempDir("jrecrash");
51 public void testNRTThreads() throws Exception {
52 String vendor = Constants.JAVA_VENDOR;
53 assumeTrue(vendor + " JRE not supported.",
54 vendor.startsWith("Sun") || vendor.startsWith("Apple"));
56 // if we are not the fork
57 if (System.getProperty("tests.crashmode") == null) {
58 // try up to 10 times to create an index
59 for (int i = 0; i < 10; i++) {
61 // if we succeeded in finding an index, we are done.
62 if (checkIndexes(tempDir))
66 // we are the fork, setup a crashing thread
67 final int crashTime = _TestUtil.nextInt(random, 3000, 4000);
68 Thread t = new Thread() {
72 Thread.sleep(crashTime);
73 } catch (InterruptedException e) {}
77 t.setPriority(Thread.MAX_PRIORITY);
79 // run the test until we crash.
80 for (int i = 0; i < 1000; i++) {
81 super.testNRTThreads();
86 /** fork ourselves in a new jvm. sets -Dtests.crashmode=true */
87 public void forkTest() throws Exception {
88 List<String> cmd = new ArrayList<String>();
89 cmd.add(System.getProperty("java.home")
90 + System.getProperty("file.separator")
92 + System.getProperty("file.separator")
95 cmd.add("-Dtests.crashmode=true");
96 // passing NIGHTLY to this test makes it run for much longer, easier to catch it in the act...
97 cmd.add("-Dtests.nightly=true");
98 cmd.add("-DtempDir=" + tempDir.getPath());
99 cmd.add("-Dtests.seed=" + random.nextLong() + ":" + random.nextLong());
102 cmd.add(System.getProperty("java.class.path"));
103 cmd.add("org.junit.runner.JUnitCore");
104 cmd.add(getClass().getName());
105 ProcessBuilder pb = new ProcessBuilder(cmd);
106 pb.directory(tempDir);
107 pb.redirectErrorStream(true);
108 Process p = pb.start();
109 InputStream is = p.getInputStream();
110 BufferedInputStream isl = new BufferedInputStream(is);
111 byte buffer[] = new byte[1024];
113 if (VERBOSE) System.err.println(">>> Begin subprocess output");
114 while ((len = isl.read(buffer)) != -1) {
116 System.err.write(buffer, 0, len);
119 if (VERBOSE) System.err.println("<<< End subprocess output");
124 * Recursively looks for indexes underneath <code>file</code>,
125 * and runs checkindex on them. returns true if it found any indexes.
127 public boolean checkIndexes(File file) throws IOException {
128 if (file.isDirectory()) {
129 MockDirectoryWrapper dir = newFSDirectory(file);
130 dir.setCheckIndexOnClose(false); // don't double-checkindex
131 if (IndexReader.indexExists(dir)) {
133 System.err.println("Checking index: " + file);
135 _TestUtil.checkIndex(dir);
140 for (File f : file.listFiles())
148 * currently, this only works/tested on Sun and IBM.
150 public void crashJRE() {
152 Class<?> clazz = Class.forName("sun.misc.Unsafe");
153 // we should use getUnsafe instead, harmony implements it, etc.
154 Field field = clazz.getDeclaredField("theUnsafe");
155 field.setAccessible(true);
156 Object o = field.get(null);
157 Method m = clazz.getMethod("putAddress", long.class, long.class);
159 } catch (Exception e) { e.printStackTrace(); }