Merge remote-tracking branch 'origin/master' into gradle-master

This commit is contained in:
Dawid Weiss 2019-12-27 15:17:24 +01:00
commit 11a946d145
17 changed files with 129 additions and 282 deletions

View File

@ -65,6 +65,9 @@ Improvements
* LUCENE-9109: Use StackWalker to implement TestSecurityManager's detection
of JVM exit (Uwe Schindler)
* LUCENE-9110: Refactor stack analysis in tests to use generalized LuceneTestCase
methods that use StackWalker (Uwe Schindler)
Bug fixes
* LUCENE-8663: NRTCachingDirectory.slowFileExists may open a file while
@ -96,6 +99,9 @@ Improvements
* LUCENE-9109: Backport some changes from master (except StackWalker) to improve
TestSecurityManager (Uwe Schindler)
* LUCENE-9110: Backport refactored stack analysis in tests to use generalized
LuceneTestCase methods (Uwe Schindler)
Optimizations
---------------------
(No changes)

View File

@ -89,9 +89,7 @@ public class TestMergeSchedulerExternal extends LuceneTestCase {
private static class FailOnlyOnMerge extends MockDirectoryWrapper.Failure {
@Override
public void eval(MockDirectoryWrapper dir) throws IOException {
StackTraceElement[] trace = new Exception().getStackTrace();
for (int i = 0; i < trace.length; i++) {
if ("doMerge".equals(trace[i].getMethodName())) {
if (callStackContainsAnyOf("doMerge")) {
IOException ioe = new IOException("now failing during merge");
StringWriter sw = new StringWriter();
PrintWriter pw = new PrintWriter(sw);
@ -103,7 +101,6 @@ public class TestMergeSchedulerExternal extends LuceneTestCase {
}
}
}
}
@AfterClass
public static void afterClass() {

View File

@ -54,21 +54,7 @@ public class TestConcurrentMergeScheduler extends LuceneTestCase {
@Override
public void eval(MockDirectoryWrapper dir) throws IOException {
if (doFail && isTestThread()) {
boolean isDoFlush = false;
boolean isClose = false;
StackTraceElement[] trace = new Exception().getStackTrace();
for (int i = 0; i < trace.length; i++) {
if (isDoFlush && isClose) {
break;
}
if ("flush".equals(trace[i].getMethodName())) {
isDoFlush = true;
}
if ("close".equals(trace[i].getMethodName())) {
isClose = true;
}
}
if (isDoFlush && !isClose && random().nextBoolean()) {
if (callStackContainsAnyOf("flush") && false == callStackContainsAnyOf("close") && random().nextBoolean()) {
hitExc = true;
throw new IOException(Thread.currentThread().getName() + ": now failing during flush");
}

View File

@ -659,9 +659,7 @@ public class TestDirectoryReaderReopen extends LuceneTestCase {
}
//System.out.println("failOn: ");
//new Throwable().printStackTrace(System.out);
StackTraceElement[] trace = new Exception().getStackTrace();
for (int i = 0; i < trace.length; i++) {
if ("readLiveDocs".equals(trace[i].getMethodName())) {
if (callStackContainsAnyOf("readLiveDocs")) {
if (VERBOSE) {
System.out.println("TEST: now fail; exc:");
new Throwable().printStackTrace(System.out);
@ -670,7 +668,6 @@ public class TestDirectoryReaderReopen extends LuceneTestCase {
throw new FakeIOException();
}
}
}
});
// Now reopen:

View File

@ -414,15 +414,11 @@ public class TestIndexFileDeleter extends LuceneTestCase {
@Override
public void eval(MockDirectoryWrapper dir) throws IOException {
if (doFailExc.get() && random().nextInt(4) == 1) {
Exception e = new Exception();
StackTraceElement stack[] = e.getStackTrace();
for (int i = 0; i < stack.length; i++) {
if (stack[i].getClassName().equals(IndexFileDeleter.class.getName()) && stack[i].getMethodName().equals("decRef")) {
if (callStackContains(IndexFileDeleter.class, "decRef")) {
throw new RuntimeException("fake fail");
}
}
}
}
});
IndexWriterConfig iwc = newIndexWriterConfig(new MockAnalyzer(random()));
@ -497,15 +493,11 @@ public class TestIndexFileDeleter extends LuceneTestCase {
@Override
public void eval(MockDirectoryWrapper dir) throws IOException {
if (doFailExc.get() && random().nextInt(4) == 1) {
Exception e = new Exception();
StackTraceElement stack[] = e.getStackTrace();
for (int i = 0; i < stack.length; i++) {
if (stack[i].getClassName().equals(MockDirectoryWrapper.class.getName()) && stack[i].getMethodName().equals("deleteFile")) {
if (callStackContains(MockDirectoryWrapper.class, "deleteFile")) {
throw new MockDirectoryWrapper.FakeIOException();
}
}
}
}
});
IndexWriterConfig iwc = newIndexWriterConfig();

View File

@ -3048,13 +3048,8 @@ public class TestIndexWriter extends LuceneTestCase {
dir.failOn(new MockDirectoryWrapper.Failure() {
@Override
public void eval(MockDirectoryWrapper dir) throws IOException {
StackTraceElement[] trace = new Exception().getStackTrace();
for (int i = 0; i < trace.length; i++) {
if ("flush".equals(trace[i].getMethodName())
&& "org.apache.lucene.index.DocumentsWriterPerThread".equals(trace[i].getClassName())) {
if (callStackContains(DocumentsWriterPerThread.class, "flush")) {
flushingThreads.add(Thread.currentThread().getName());
break;
}
}
}
});
@ -3384,9 +3379,7 @@ public class TestIndexWriter extends LuceneTestCase {
try (Directory dir = new FilterDirectory(newDirectory()) {
@Override
public IndexOutput createOutput(String name, IOContext context) throws IOException {
StackTraceElement[] trace = new Exception().getStackTrace();
for (int i = 0; i < trace.length; i++) {
if ("flush".equals(trace[i].getMethodName()) && DefaultIndexingChain.class.getName().equals(trace[i].getClassName())) {
if (callStackContains(DefaultIndexingChain.class, "flush")) {
try {
inFlush.countDown();
latch.await();
@ -3394,7 +3387,6 @@ public class TestIndexWriter extends LuceneTestCase {
throw new AssertionError(e);
}
}
}
return super.createOutput(name, context);
}
}; IndexWriter writer = new IndexWriter(dir, newIndexWriterConfig())) {

View File

@ -731,15 +731,7 @@ public class TestIndexWriterDelete extends LuceneTestCase {
}
new Throwable().printStackTrace(System.out);
if (sawMaybe && !failed) {
boolean seen = false;
StackTraceElement[] trace = new Exception().getStackTrace();
for (int i = 0; i < trace.length; i++) {
if ("applyDeletesAndUpdates".equals(trace[i].getMethodName()) ||
"slowFileExists".equals(trace[i].getMethodName())) {
seen = true;
break;
}
}
boolean seen = callStackContainsAnyOf("applyDeletesAndUpdates", "slowFileExists");
if (!seen) {
// Only fail once we are no longer in applyDeletes
failed = true;
@ -751,16 +743,12 @@ public class TestIndexWriterDelete extends LuceneTestCase {
}
}
if (!failed) {
StackTraceElement[] trace = new Exception().getStackTrace();
for (int i = 0; i < trace.length; i++) {
if ("applyDeletesAndUpdates".equals(trace[i].getMethodName())) {
if (callStackContainsAnyOf("applyDeletesAndUpdates")) {
if (VERBOSE) {
System.out.println("TEST: mock failure: saw applyDeletes");
new Throwable().printStackTrace(System.out);
}
sawMaybe = true;
break;
}
}
}
}

View File

@ -567,19 +567,7 @@ public class TestIndexWriterExceptions extends LuceneTestCase {
@Override
public void eval(MockDirectoryWrapper dir) throws IOException {
if (doFail) {
StackTraceElement[] trace = new Exception().getStackTrace();
boolean sawFlush = false;
boolean sawFinishDocument = false;
for (int i = 0; i < trace.length; i++) {
if ("flush".equals(trace[i].getMethodName())) {
sawFlush = true;
}
if ("finishDocument".equals(trace[i].getMethodName())) {
sawFinishDocument = true;
}
}
if (sawFlush && sawFinishDocument == false && count++ >= 30) {
if (callStackContainsAnyOf("flush") && false == callStackContainsAnyOf("finishDocument") && count++ >= 30) {
doFail = false;
throw new IOException("now failing during flush");
}
@ -872,16 +860,14 @@ public class TestIndexWriterExceptions extends LuceneTestCase {
@Override
public void eval(MockDirectoryWrapper dir) throws IOException {
if (doFail) {
StackTraceElement[] trace = new Exception().getStackTrace();
for (int i = 0; i < trace.length; i++) {
if (doFail && MockDirectoryWrapper.class.getName().equals(trace[i].getClassName()) && "sync".equals(trace[i].getMethodName())) {
if (callStackContains(MockDirectoryWrapper.class, "sync")) {
didFail = true;
if (VERBOSE) {
System.out.println("TEST: now throw exc:");
new Throwable().printStackTrace(System.out);
}
throw new IOException("now failing on purpose during sync");
}
}
}
}
@ -949,28 +935,10 @@ public class TestIndexWriterExceptions extends LuceneTestCase {
@Override
public void eval(MockDirectoryWrapper dir) throws IOException {
StackTraceElement[] trace = new Exception().getStackTrace();
boolean isCommit = false;
boolean isDelete = false;
boolean isSyncMetadata = false;
boolean isInGlobalFieldMap = false;
for (int i = 0; i < trace.length; i++) {
if (isCommit && isDelete && isInGlobalFieldMap && isSyncMetadata) {
break;
}
if (SegmentInfos.class.getName().equals(trace[i].getClassName()) && stage.equals(trace[i].getMethodName())) {
isCommit = true;
}
if (MockDirectoryWrapper.class.getName().equals(trace[i].getClassName()) && "deleteFile".equals(trace[i].getMethodName())) {
isDelete = true;
}
if (SegmentInfos.class.getName().equals(trace[i].getClassName()) && "writeGlobalFieldMap".equals(trace[i].getMethodName())) {
isInGlobalFieldMap = true;
}
if (MockDirectoryWrapper.class.getName().equals(trace[i].getClassName()) && "syncMetaData".equals(trace[i].getMethodName())) {
isSyncMetadata = true;
}
}
boolean isCommit = callStackContains(SegmentInfos.class, stage);
boolean isDelete = callStackContains(MockDirectoryWrapper.class, "deleteFile");
boolean isSyncMetadata = callStackContains(MockDirectoryWrapper.class, "syncMetaData");
boolean isInGlobalFieldMap = callStackContains(SegmentInfos.class, "writeGlobalFieldMap");
if (isInGlobalFieldMap && dontFailDuringGlobalFieldMap) {
isCommit = false;
}
@ -1384,17 +1352,7 @@ public class TestIndexWriterExceptions extends LuceneTestCase {
@Override
public void eval(MockDirectoryWrapper dir) throws IOException {
StackTraceElement[] trace = new Exception().getStackTrace();
boolean fail = false;
for (int i = 0; i < trace.length; i++) {
if (TermVectorsConsumer.class.getName().equals(trace[i].getClassName()) && stage.equals(trace[i].getMethodName())) {
fail = true;
break;
}
}
if (fail) {
if (callStackContains(TermVectorsConsumer.class, stage)) {
throw new RuntimeException(EXC_MSG);
}
}
@ -1726,13 +1684,10 @@ public class TestIndexWriterExceptions extends LuceneTestCase {
@Override
public IndexInput openInput(String name, IOContext context) throws IOException {
if (doFail && name.startsWith("segments_")) {
StackTraceElement[] trace = new Exception().getStackTrace();
for (int i = 0; i < trace.length; i++) {
if ("readCommit".equals(trace[i].getMethodName()) || "readLatestCommit".equals(trace[i].getMethodName())) {
if (callStackContainsAnyOf("readCommit", "readLatestCommit")) {
throw new UnsupportedOperationException("expected UOE");
}
}
}
return super.openInput(name, context);
}
}
@ -1946,17 +1901,7 @@ public class TestIndexWriterExceptions extends LuceneTestCase {
if (random().nextInt(10) != 0) {
return;
}
boolean maybeFail = false;
StackTraceElement[] trace = Thread.currentThread().getStackTrace();
for (int i = 0; i < trace.length; i++) {
if ("rollbackInternal".equals(trace[i].getMethodName())) {
maybeFail = true;
break;
}
}
if (maybeFail) {
if (callStackContainsAnyOf("rollbackInternal")) {
if (VERBOSE) {
System.out.println("TEST: now fail; thread=" + Thread.currentThread().getName() + " exc:");
new Throwable().printStackTrace(System.out);
@ -2019,10 +1964,8 @@ public class TestIndexWriterExceptions extends LuceneTestCase {
// Already failed
return;
}
StackTraceElement[] trace = Thread.currentThread().getStackTrace();
for (int i = 0; i < trace.length; i++) {
if ("merge".equals(trace[i].getMethodName())) {
if (callStackContainsAnyOf("merge")) {
if (VERBOSE) {
System.out.println("TEST: now fail; thread=" + Thread.currentThread().getName() + " exc:");
new Throwable().printStackTrace(System.out);
@ -2031,7 +1974,6 @@ public class TestIndexWriterExceptions extends LuceneTestCase {
throw new FakeIOException();
}
}
}
});
IndexWriterConfig iwc = newIndexWriterConfig();

View File

@ -18,7 +18,6 @@ package org.apache.lucene.index;
import java.io.IOException;
import org.apache.lucene.analysis.MockAnalyzer;
import org.apache.lucene.codecs.LiveDocsFormat;
import org.apache.lucene.document.Document;
@ -478,19 +477,16 @@ public class TestIndexWriterOnDiskFull extends LuceneTestCase {
if (!doFail) {
return;
}
StackTraceElement[] trace = new Exception().getStackTrace();
for (int i = 0; i < trace.length; i++) {
if (SegmentMerger.class.getName().equals(trace[i].getClassName()) && "mergeTerms".equals(trace[i].getMethodName()) && !didFail1) {
if (callStackContains(SegmentMerger.class, "mergeTerms") && !didFail1) {
didFail1 = true;
throw new IOException("fake disk full during mergeTerms");
}
if (LiveDocsFormat.class.getName().equals(trace[i].getClassName()) && "writeLiveDocs".equals(trace[i].getMethodName()) && !didFail2) {
if (callStackContains(LiveDocsFormat.class, "writeLiveDocs") && !didFail2) {
didFail2 = true;
throw new IOException("fake disk full while writing LiveDocs");
}
}
}
}
// LUCENE-2593
public void testCorruptionAfterDiskFullDuringMerge() throws IOException {

View File

@ -238,14 +238,7 @@ public class TestIndexWriterOnVMError extends LuceneTestCase {
@Override
public void eval(MockDirectoryWrapper dir) throws IOException {
if (r.nextInt(3000) == 0) {
StackTraceElement stack[] = Thread.currentThread().getStackTrace();
boolean ok = false;
for (int i = 0; i < stack.length; i++) {
if (stack[i].getClassName().equals(IndexWriter.class.getName())) {
ok = true;
}
}
if (ok) {
if (callStackContains(IndexWriter.class)) {
throw new OutOfMemoryError("Fake OutOfMemoryError");
}
}
@ -259,14 +252,7 @@ public class TestIndexWriterOnVMError extends LuceneTestCase {
@Override
public void eval(MockDirectoryWrapper dir) throws IOException {
if (r.nextInt(3000) == 0) {
StackTraceElement stack[] = Thread.currentThread().getStackTrace();
boolean ok = false;
for (int i = 0; i < stack.length; i++) {
if (stack[i].getClassName().equals(IndexWriter.class.getName())) {
ok = true;
}
}
if (ok) {
if (callStackContains(IndexWriter.class)) {
throw new UnknownError("Fake UnknownError");
}
}
@ -281,17 +267,12 @@ public class TestIndexWriterOnVMError extends LuceneTestCase {
doTest(new Failure() {
@Override
public void eval(MockDirectoryWrapper dir) throws IOException {
StackTraceElement stack[] = Thread.currentThread().getStackTrace();
boolean ok = false;
for (int i = 0; i < stack.length; i++) {
if (stack[i].getClassName().equals(IndexFileDeleter.class.getName()) && stack[i].getMethodName().equals("checkpoint")) {
ok = true;
}
}
if (ok && r.nextInt(4) == 0) {
if (r.nextInt(4) == 0) {
if (callStackContains(IndexFileDeleter.class, "checkpoint")) {
throw new OutOfMemoryError("Fake OutOfMemoryError");
}
}
}
});
}
}

View File

@ -1067,10 +1067,8 @@ public class TestIndexWriterReader extends LuceneTestCase {
dir.failOn(new MockDirectoryWrapper.Failure() {
@Override
public void eval(MockDirectoryWrapper dir) throws IOException {
StackTraceElement[] trace = new Exception().getStackTrace();
if (shouldFail.get()) {
for (int i = 0; i < trace.length; i++) {
if ("getReadOnlyClone".equals(trace[i].getMethodName())) {
if (callStackContainsAnyOf("getReadOnlyClone")) {
if (VERBOSE) {
System.out.println("TEST: now fail; exc:");
new Throwable().printStackTrace(System.out);
@ -1080,7 +1078,6 @@ public class TestIndexWriterReader extends LuceneTestCase {
}
}
}
}
});
IndexWriterConfig conf = newIndexWriterConfig(new MockAnalyzer(random()));

View File

@ -407,26 +407,7 @@ public class TestIndexWriterWithThreads extends LuceneTestCase {
dir.setAssertNoUnrefencedFilesOnClose(false);
if (doFail) {
StackTraceElement[] trace = new Exception().getStackTrace();
boolean sawAbortOrFlushDoc = false;
boolean sawClose = false;
boolean sawMerge = false;
for (int i = 0; i < trace.length; i++) {
if (sawAbortOrFlushDoc && sawMerge && sawClose) {
break;
}
if ("abort".equals(trace[i].getMethodName()) ||
"finishDocument".equals(trace[i].getMethodName())) {
sawAbortOrFlushDoc = true;
}
if ("merge".equals(trace[i].getMethodName())) {
sawMerge = true;
}
if ("close".equals(trace[i].getMethodName())) {
sawClose = true;
}
}
if (sawAbortOrFlushDoc && !sawClose && !sawMerge) {
if (callStackContainsAnyOf("abort", "finishDocument") && false == callStackContainsAnyOf("merge", "close")) {
if (onlyOnce) {
doFail = false;
}
@ -473,9 +454,7 @@ public class TestIndexWriterWithThreads extends LuceneTestCase {
@Override
public void eval(MockDirectoryWrapper dir) throws IOException {
if (doFail) {
StackTraceElement[] trace = new Exception().getStackTrace();
for (int i = 0; i < trace.length; i++) {
if ("flush".equals(trace[i].getMethodName()) && DefaultIndexingChain.class.getName().equals(trace[i].getClassName())) {
if (callStackContains(DefaultIndexingChain.class, "flush")) {
if (onlyOnce)
doFail = false;
//System.out.println(Thread.currentThread().getName() + ": NOW FAIL: onlyOnce=" + onlyOnce);
@ -485,7 +464,6 @@ public class TestIndexWriterWithThreads extends LuceneTestCase {
}
}
}
}
// LUCENE-1130: test IOException in writeSegment
public void testIOExceptionDuringWriteSegment() throws IOException {

View File

@ -116,13 +116,10 @@ public class TestPersistentSnapshotDeletionPolicy extends TestSnapshotDeletionPo
dir.failOn(new MockDirectoryWrapper.Failure() {
@Override
public void eval(MockDirectoryWrapper dir) throws IOException {
StackTraceElement[] trace = Thread.currentThread().getStackTrace();
for (int i = 0; i < trace.length; i++) {
if (PersistentSnapshotDeletionPolicy.class.getName().equals(trace[i].getClassName()) && "persist".equals(trace[i].getMethodName())) {
if (callStackContains(PersistentSnapshotDeletionPolicy.class, "persist")) {
throw new IOException("now fail on purpose");
}
}
}
});
IndexWriter writer = new IndexWriter(dir, getConfig(random(), new PersistentSnapshotDeletionPolicy(
new KeepOnlyLastCommitDeletionPolicy(), dir, OpenMode.CREATE_OR_APPEND)));

View File

@ -133,8 +133,8 @@ public class TestUnifiedHighlighterTermVec extends LuceneTestCase {
@Override
public Fields getTermVectors(int docID) throws IOException {
// if we're invoked by ParallelLeafReader then we can't do our assertion. TODO see LUCENE-6868
if (calledBy(ParallelLeafReader.class) == false
&& calledBy(CheckIndex.class) == false) {
if (callStackContains(ParallelLeafReader.class) == false
&& callStackContains(CheckIndex.class) == false) {
assertFalse("Should not request TVs for doc more than once.", seenDocIDs.get(docID));
seenDocIDs.set(docID);
}
@ -170,14 +170,6 @@ public class TestUnifiedHighlighterTermVec extends LuceneTestCase {
}
}
private static boolean calledBy(Class<?> clazz) {
for (StackTraceElement stackTraceElement : Thread.currentThread().getStackTrace()) {
if (stackTraceElement.getClassName().equals(clazz.getName()))
return true;
}
return false;
}
@Test(expected = IllegalArgumentException.class)
public void testUserFailedToIndexOffsets() throws IOException {
FieldType fieldType = new FieldType(UHTestHelper.tvType); // note: it's indexed too

View File

@ -102,12 +102,10 @@ public abstract class BaseFieldInfoFormatTestCase extends BaseIndexFileFormatTes
Failure fail = new Failure() {
@Override
public void eval(MockDirectoryWrapper dir) throws IOException {
for (StackTraceElement e : Thread.currentThread().getStackTrace()) {
if (doFail && "createOutput".equals(e.getMethodName())) {
if (doFail && callStackContainsAnyOf("createOutput")) {
throw new FakeIOException();
}
}
}
};
MockDirectoryWrapper dir = newMockDirectory();
@ -137,12 +135,10 @@ public abstract class BaseFieldInfoFormatTestCase extends BaseIndexFileFormatTes
Failure fail = new Failure() {
@Override
public void eval(MockDirectoryWrapper dir) throws IOException {
for (StackTraceElement e : Thread.currentThread().getStackTrace()) {
if (doFail && "close".equals(e.getMethodName())) {
if (doFail && callStackContainsAnyOf("close")) {
throw new FakeIOException();
}
}
}
};
MockDirectoryWrapper dir = newMockDirectory();
@ -172,12 +168,10 @@ public abstract class BaseFieldInfoFormatTestCase extends BaseIndexFileFormatTes
Failure fail = new Failure() {
@Override
public void eval(MockDirectoryWrapper dir) throws IOException {
for (StackTraceElement e : Thread.currentThread().getStackTrace()) {
if (doFail && "openInput".equals(e.getMethodName())) {
if (doFail && callStackContainsAnyOf("openInput")) {
throw new FakeIOException();
}
}
}
};
MockDirectoryWrapper dir = newMockDirectory();
@ -208,12 +202,10 @@ public abstract class BaseFieldInfoFormatTestCase extends BaseIndexFileFormatTes
Failure fail = new Failure() {
@Override
public void eval(MockDirectoryWrapper dir) throws IOException {
for (StackTraceElement e : Thread.currentThread().getStackTrace()) {
if (doFail && "close".equals(e.getMethodName())) {
if (doFail && callStackContainsAnyOf("close")) {
throw new FakeIOException();
}
}
}
};
MockDirectoryWrapper dir = newMockDirectory();

View File

@ -292,12 +292,10 @@ public abstract class BaseSegmentInfoFormatTestCase extends BaseIndexFileFormatT
Failure fail = new Failure() {
@Override
public void eval(MockDirectoryWrapper dir) throws IOException {
for (StackTraceElement e : Thread.currentThread().getStackTrace()) {
if (doFail && "createOutput".equals(e.getMethodName())) {
if (doFail && callStackContainsAnyOf("createOutput")) {
throw new FakeIOException();
}
}
}
};
MockDirectoryWrapper dir = newMockDirectory();
@ -325,12 +323,10 @@ public abstract class BaseSegmentInfoFormatTestCase extends BaseIndexFileFormatT
Failure fail = new Failure() {
@Override
public void eval(MockDirectoryWrapper dir) throws IOException {
for (StackTraceElement e : Thread.currentThread().getStackTrace()) {
if (doFail && "close".equals(e.getMethodName())) {
if (doFail && callStackContainsAnyOf("close")) {
throw new FakeIOException();
}
}
}
};
MockDirectoryWrapper dir = newMockDirectory();
@ -358,12 +354,10 @@ public abstract class BaseSegmentInfoFormatTestCase extends BaseIndexFileFormatT
Failure fail = new Failure() {
@Override
public void eval(MockDirectoryWrapper dir) throws IOException {
for (StackTraceElement e : Thread.currentThread().getStackTrace()) {
if (doFail && "openInput".equals(e.getMethodName())) {
if (doFail && callStackContainsAnyOf("openInput")) {
throw new FakeIOException();
}
}
}
};
MockDirectoryWrapper dir = newMockDirectory();
@ -392,12 +386,10 @@ public abstract class BaseSegmentInfoFormatTestCase extends BaseIndexFileFormatT
Failure fail = new Failure() {
@Override
public void eval(MockDirectoryWrapper dir) throws IOException {
for (StackTraceElement e : Thread.currentThread().getStackTrace()) {
if (doFail && "close".equals(e.getMethodName())) {
if (doFail && callStackContainsAnyOf("close")) {
throw new FakeIOException();
}
}
}
};
MockDirectoryWrapper dir = newMockDirectory();

View File

@ -21,6 +21,7 @@ import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintStream;
import java.lang.StackWalker.StackFrame;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Inherited;
@ -2708,6 +2709,27 @@ public abstract class LuceneTestCase extends Assert {
}
}
/** Inspects stack trace to figure out if a method of a specific class called us. */
public static boolean callStackContains(Class<?> clazz, String methodName) {
final String className = clazz.getName();
return StackWalker.getInstance().walk(s -> s.skip(1) // exclude this utility method
.anyMatch(f -> className.equals(f.getClassName()) && methodName.equals(f.getMethodName())));
}
/** Inspects stack trace to figure out if one of the given method names (no class restriction) called us. */
public static boolean callStackContainsAnyOf(String... methodNames) {
return StackWalker.getInstance().walk(s -> s.skip(1) // exclude this utility method
.map(StackFrame::getMethodName)
.anyMatch(Set.of(methodNames)::contains));
}
/** Inspects stack trace if the given class called us. */
public static boolean callStackContains(Class<?> clazz) {
return StackWalker.getInstance().walk(s -> s.skip(1) // exclude this utility method
.map(StackFrame::getClassName)
.anyMatch(clazz.getName()::equals));
}
/** A runnable that can throw any checked exception. */
@FunctionalInterface
public interface ThrowingRunnable {