From a6a220c89ae9dbbebf23cca1eb923ddb45d9b433 Mon Sep 17 00:00:00 2001 From: Uwe Schindler Date: Fri, 27 Dec 2019 11:54:00 +0100 Subject: [PATCH] LUCENE-9110: Backport refactored stack analysis in tests to use generalized LuceneTestCase methods --- lucene/CHANGES.txt | 3 + .../lucene/TestMergeSchedulerExternal.java | 19 ++-- .../index/TestConcurrentMergeScheduler.java | 16 +-- .../index/TestDirectoryReaderReopen.java | 15 +-- .../lucene/index/TestIndexFileDeleter.java | 16 +-- .../apache/lucene/index/TestIndexWriter.java | 24 ++-- .../lucene/index/TestIndexWriterDelete.java | 24 +--- .../index/TestIndexWriterExceptions.java | 104 ++++-------------- .../index/TestIndexWriterOnDiskFull.java | 18 ++- .../index/TestIndexWriterOnVMError.java | 29 +---- .../lucene/index/TestIndexWriterReader.java | 15 +-- .../index/TestIndexWriterWithThreads.java | 36 ++---- .../TestPersistentSnapshotDeletionPolicy.java | 7 +- .../TestUnifiedHighlighterTermVec.java | 12 +- .../index/BaseFieldInfoFormatTestCase.java | 24 ++-- .../index/BaseSegmentInfoFormatTestCase.java | 24 ++-- .../apache/lucene/util/LuceneTestCase.java | 22 ++++ 17 files changed, 126 insertions(+), 282 deletions(-) diff --git a/lucene/CHANGES.txt b/lucene/CHANGES.txt index 5d82f80a04c..ad4a2d8f9b9 100644 --- a/lucene/CHANGES.txt +++ b/lucene/CHANGES.txt @@ -23,6 +23,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) diff --git a/lucene/core/src/test/org/apache/lucene/TestMergeSchedulerExternal.java b/lucene/core/src/test/org/apache/lucene/TestMergeSchedulerExternal.java index 307a1a71d41..7498f1c15f5 100644 --- a/lucene/core/src/test/org/apache/lucene/TestMergeSchedulerExternal.java +++ b/lucene/core/src/test/org/apache/lucene/TestMergeSchedulerExternal.java @@ -89,18 +89,15 @@ 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())) { - IOException ioe = new IOException("now failing during merge"); - StringWriter sw = new StringWriter(); - PrintWriter pw = new PrintWriter(sw); - ioe.printStackTrace(pw); - if (infoStream.isEnabled("IW")) { - infoStream.message("IW", "TEST: now throw exc:\n" + sw.toString()); - } - throw ioe; + if (callStackContainsAnyOf("doMerge")) { + IOException ioe = new IOException("now failing during merge"); + StringWriter sw = new StringWriter(); + PrintWriter pw = new PrintWriter(sw); + ioe.printStackTrace(pw); + if (infoStream.isEnabled("IW")) { + infoStream.message("IW", "TEST: now throw exc:\n" + sw.toString()); } + throw ioe; } } } diff --git a/lucene/core/src/test/org/apache/lucene/index/TestConcurrentMergeScheduler.java b/lucene/core/src/test/org/apache/lucene/index/TestConcurrentMergeScheduler.java index fad831fb74b..4683a512be8 100644 --- a/lucene/core/src/test/org/apache/lucene/index/TestConcurrentMergeScheduler.java +++ b/lucene/core/src/test/org/apache/lucene/index/TestConcurrentMergeScheduler.java @@ -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"); } diff --git a/lucene/core/src/test/org/apache/lucene/index/TestDirectoryReaderReopen.java b/lucene/core/src/test/org/apache/lucene/index/TestDirectoryReaderReopen.java index 111c6832e63..ca37892e231 100644 --- a/lucene/core/src/test/org/apache/lucene/index/TestDirectoryReaderReopen.java +++ b/lucene/core/src/test/org/apache/lucene/index/TestDirectoryReaderReopen.java @@ -659,16 +659,13 @@ 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 (VERBOSE) { - System.out.println("TEST: now fail; exc:"); - new Throwable().printStackTrace(System.out); - } - failed = true; - throw new FakeIOException(); + if (callStackContainsAnyOf("readLiveDocs")) { + if (VERBOSE) { + System.out.println("TEST: now fail; exc:"); + new Throwable().printStackTrace(System.out); } + failed = true; + throw new FakeIOException(); } } }); diff --git a/lucene/core/src/test/org/apache/lucene/index/TestIndexFileDeleter.java b/lucene/core/src/test/org/apache/lucene/index/TestIndexFileDeleter.java index eedcfdb8344..d560298ec10 100644 --- a/lucene/core/src/test/org/apache/lucene/index/TestIndexFileDeleter.java +++ b/lucene/core/src/test/org/apache/lucene/index/TestIndexFileDeleter.java @@ -414,12 +414,8 @@ 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")) { - throw new RuntimeException("fake fail"); - } + if (callStackContains(IndexFileDeleter.class, "decRef")) { + throw new RuntimeException("fake fail"); } } } @@ -497,12 +493,8 @@ 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")) { - throw new MockDirectoryWrapper.FakeIOException(); - } + if (callStackContains(MockDirectoryWrapper.class, "deleteFile")) { + throw new MockDirectoryWrapper.FakeIOException(); } } } diff --git a/lucene/core/src/test/org/apache/lucene/index/TestIndexWriter.java b/lucene/core/src/test/org/apache/lucene/index/TestIndexWriter.java index 52bfd2ecd73..32a15994ced 100644 --- a/lucene/core/src/test/org/apache/lucene/index/TestIndexWriter.java +++ b/lucene/core/src/test/org/apache/lucene/index/TestIndexWriter.java @@ -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())) { - flushingThreads.add(Thread.currentThread().getName()); - break; - } + if (callStackContains(DocumentsWriterPerThread.class, "flush")) { + flushingThreads.add(Thread.currentThread().getName()); } } }); @@ -3384,15 +3379,12 @@ 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())) { - try { - inFlush.countDown(); - latch.await(); - } catch (InterruptedException e) { - throw new AssertionError(e); - } + if (callStackContains(DefaultIndexingChain.class, "flush")) { + try { + inFlush.countDown(); + latch.await(); + } catch (InterruptedException e) { + throw new AssertionError(e); } } return super.createOutput(name, context); diff --git a/lucene/core/src/test/org/apache/lucene/index/TestIndexWriterDelete.java b/lucene/core/src/test/org/apache/lucene/index/TestIndexWriterDelete.java index 4c9a4e01a22..80be5b2014e 100644 --- a/lucene/core/src/test/org/apache/lucene/index/TestIndexWriterDelete.java +++ b/lucene/core/src/test/org/apache/lucene/index/TestIndexWriterDelete.java @@ -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 (VERBOSE) { - System.out.println("TEST: mock failure: saw applyDeletes"); - new Throwable().printStackTrace(System.out); - } - sawMaybe = true; - break; + if (callStackContainsAnyOf("applyDeletesAndUpdates")) { + if (VERBOSE) { + System.out.println("TEST: mock failure: saw applyDeletes"); + new Throwable().printStackTrace(System.out); } + sawMaybe = true; } } } diff --git a/lucene/core/src/test/org/apache/lucene/index/TestIndexWriterExceptions.java b/lucene/core/src/test/org/apache/lucene/index/TestIndexWriterExceptions.java index bafe4873758..f221bd652d4 100644 --- a/lucene/core/src/test/org/apache/lucene/index/TestIndexWriterExceptions.java +++ b/lucene/core/src/test/org/apache/lucene/index/TestIndexWriterExceptions.java @@ -566,19 +566,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"); } @@ -871,16 +859,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())) { - 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"); + 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"); + } } } @@ -948,28 +934,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; } @@ -1383,17 +1351,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); } } @@ -1719,11 +1677,8 @@ 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())) { - throw new UnsupportedOperationException("expected UOE"); - } + if (callStackContainsAnyOf("readCommit", "readLatestCommit")) { + throw new UnsupportedOperationException("expected UOE"); } } return super.openInput(name, context); @@ -1939,17 +1894,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); @@ -2012,17 +1957,14 @@ 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 (VERBOSE) { - System.out.println("TEST: now fail; thread=" + Thread.currentThread().getName() + " exc:"); - new Throwable().printStackTrace(System.out); - } - didFail.set(true); - throw new FakeIOException(); + + if (callStackContainsAnyOf("merge")) { + if (VERBOSE) { + System.out.println("TEST: now fail; thread=" + Thread.currentThread().getName() + " exc:"); + new Throwable().printStackTrace(System.out); } + didFail.set(true); + throw new FakeIOException(); } } }); diff --git a/lucene/core/src/test/org/apache/lucene/index/TestIndexWriterOnDiskFull.java b/lucene/core/src/test/org/apache/lucene/index/TestIndexWriterOnDiskFull.java index 3629721f484..9799e65abcc 100644 --- a/lucene/core/src/test/org/apache/lucene/index/TestIndexWriterOnDiskFull.java +++ b/lucene/core/src/test/org/apache/lucene/index/TestIndexWriterOnDiskFull.java @@ -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,16 +477,13 @@ 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) { - didFail1 = true; - throw new IOException("fake disk full during mergeTerms"); - } - if (LiveDocsFormat.class.getName().equals(trace[i].getClassName()) && "writeLiveDocs".equals(trace[i].getMethodName()) && !didFail2) { - didFail2 = true; - throw new IOException("fake disk full while writing LiveDocs"); - } + if (callStackContains(SegmentMerger.class, "mergeTerms") && !didFail1) { + didFail1 = true; + throw new IOException("fake disk full during mergeTerms"); + } + if (callStackContains(LiveDocsFormat.class, "writeLiveDocs") && !didFail2) { + didFail2 = true; + throw new IOException("fake disk full while writing LiveDocs"); } } } diff --git a/lucene/core/src/test/org/apache/lucene/index/TestIndexWriterOnVMError.java b/lucene/core/src/test/org/apache/lucene/index/TestIndexWriterOnVMError.java index 99f7d539bf0..73704dd6a17 100644 --- a/lucene/core/src/test/org/apache/lucene/index/TestIndexWriterOnVMError.java +++ b/lucene/core/src/test/org/apache/lucene/index/TestIndexWriterOnVMError.java @@ -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,16 +267,11 @@ 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 (r.nextInt(4) == 0) { + if (callStackContains(IndexFileDeleter.class, "checkpoint")) { + throw new OutOfMemoryError("Fake OutOfMemoryError"); } } - if (ok && r.nextInt(4) == 0) { - throw new OutOfMemoryError("Fake OutOfMemoryError"); - } } }); } diff --git a/lucene/core/src/test/org/apache/lucene/index/TestIndexWriterReader.java b/lucene/core/src/test/org/apache/lucene/index/TestIndexWriterReader.java index 1e01712dcf1..c584b16900c 100644 --- a/lucene/core/src/test/org/apache/lucene/index/TestIndexWriterReader.java +++ b/lucene/core/src/test/org/apache/lucene/index/TestIndexWriterReader.java @@ -1067,17 +1067,14 @@ 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 (VERBOSE) { - System.out.println("TEST: now fail; exc:"); - new Throwable().printStackTrace(System.out); - } - shouldFail.set(false); - throw new FakeIOException(); + if (callStackContainsAnyOf("getReadOnlyClone")) { + if (VERBOSE) { + System.out.println("TEST: now fail; exc:"); + new Throwable().printStackTrace(System.out); } + shouldFail.set(false); + throw new FakeIOException(); } } } diff --git a/lucene/core/src/test/org/apache/lucene/index/TestIndexWriterWithThreads.java b/lucene/core/src/test/org/apache/lucene/index/TestIndexWriterWithThreads.java index 48e42bd3075..cfbf3f79513 100644 --- a/lucene/core/src/test/org/apache/lucene/index/TestIndexWriterWithThreads.java +++ b/lucene/core/src/test/org/apache/lucene/index/TestIndexWriterWithThreads.java @@ -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,15 +454,12 @@ 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 (onlyOnce) - doFail = false; - //System.out.println(Thread.currentThread().getName() + ": NOW FAIL: onlyOnce=" + onlyOnce); - //new Throwable().printStackTrace(System.out); - throw new IOException("now failing on purpose"); - } + if (callStackContains(DefaultIndexingChain.class, "flush")) { + if (onlyOnce) + doFail = false; + //System.out.println(Thread.currentThread().getName() + ": NOW FAIL: onlyOnce=" + onlyOnce); + //new Throwable().printStackTrace(System.out); + throw new IOException("now failing on purpose"); } } } diff --git a/lucene/core/src/test/org/apache/lucene/index/TestPersistentSnapshotDeletionPolicy.java b/lucene/core/src/test/org/apache/lucene/index/TestPersistentSnapshotDeletionPolicy.java index 21424cc1793..e244cd01c16 100644 --- a/lucene/core/src/test/org/apache/lucene/index/TestPersistentSnapshotDeletionPolicy.java +++ b/lucene/core/src/test/org/apache/lucene/index/TestPersistentSnapshotDeletionPolicy.java @@ -116,11 +116,8 @@ 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())) { - throw new IOException("now fail on purpose"); - } + if (callStackContains(PersistentSnapshotDeletionPolicy.class, "persist")) { + throw new IOException("now fail on purpose"); } } }); diff --git a/lucene/highlighter/src/test/org/apache/lucene/search/uhighlight/TestUnifiedHighlighterTermVec.java b/lucene/highlighter/src/test/org/apache/lucene/search/uhighlight/TestUnifiedHighlighterTermVec.java index 6a92546d8f0..b2319d1a1cd 100644 --- a/lucene/highlighter/src/test/org/apache/lucene/search/uhighlight/TestUnifiedHighlighterTermVec.java +++ b/lucene/highlighter/src/test/org/apache/lucene/search/uhighlight/TestUnifiedHighlighterTermVec.java @@ -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 diff --git a/lucene/test-framework/src/java/org/apache/lucene/index/BaseFieldInfoFormatTestCase.java b/lucene/test-framework/src/java/org/apache/lucene/index/BaseFieldInfoFormatTestCase.java index 3cd7fcdc3eb..ed211266bbd 100644 --- a/lucene/test-framework/src/java/org/apache/lucene/index/BaseFieldInfoFormatTestCase.java +++ b/lucene/test-framework/src/java/org/apache/lucene/index/BaseFieldInfoFormatTestCase.java @@ -102,10 +102,8 @@ 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())) { - throw new FakeIOException(); - } + if (doFail && callStackContainsAnyOf("createOutput")) { + throw new FakeIOException(); } } }; @@ -137,10 +135,8 @@ 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())) { - throw new FakeIOException(); - } + if (doFail && callStackContainsAnyOf("close")) { + throw new FakeIOException(); } } }; @@ -172,10 +168,8 @@ 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())) { - throw new FakeIOException(); - } + if (doFail && callStackContainsAnyOf("openInput")) { + throw new FakeIOException(); } } }; @@ -208,10 +202,8 @@ 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())) { - throw new FakeIOException(); - } + if (doFail && callStackContainsAnyOf("close")) { + throw new FakeIOException(); } } }; diff --git a/lucene/test-framework/src/java/org/apache/lucene/index/BaseSegmentInfoFormatTestCase.java b/lucene/test-framework/src/java/org/apache/lucene/index/BaseSegmentInfoFormatTestCase.java index 91eb971b0d7..a3a5391055d 100644 --- a/lucene/test-framework/src/java/org/apache/lucene/index/BaseSegmentInfoFormatTestCase.java +++ b/lucene/test-framework/src/java/org/apache/lucene/index/BaseSegmentInfoFormatTestCase.java @@ -292,10 +292,8 @@ 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())) { - throw new FakeIOException(); - } + if (doFail && callStackContainsAnyOf("createOutput")) { + throw new FakeIOException(); } } }; @@ -325,10 +323,8 @@ 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())) { - throw new FakeIOException(); - } + if (doFail && callStackContainsAnyOf("close")) { + throw new FakeIOException(); } } }; @@ -358,10 +354,8 @@ 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())) { - throw new FakeIOException(); - } + if (doFail && callStackContainsAnyOf("openInput")) { + throw new FakeIOException(); } } }; @@ -392,10 +386,8 @@ 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())) { - throw new FakeIOException(); - } + if (doFail && callStackContainsAnyOf("close")) { + throw new FakeIOException(); } } }; diff --git a/lucene/test-framework/src/java/org/apache/lucene/util/LuceneTestCase.java b/lucene/test-framework/src/java/org/apache/lucene/util/LuceneTestCase.java index 0cd9e84de0f..5ff376dad3a 100644 --- a/lucene/test-framework/src/java/org/apache/lucene/util/LuceneTestCase.java +++ b/lucene/test-framework/src/java/org/apache/lucene/util/LuceneTestCase.java @@ -66,6 +66,7 @@ import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicReference; import java.util.logging.Logger; import java.util.stream.Collectors; +import java.util.stream.Stream; import org.apache.lucene.analysis.Analyzer; import org.apache.lucene.analysis.MockAnalyzer; @@ -2700,6 +2701,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 Stream.of(new Exception().getStackTrace()).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 Stream.of(new Exception().getStackTrace()).skip(1) // exclude this utility method + .map(StackTraceElement::getMethodName) + .anyMatch(Arrays.asList(methodNames)::contains); + } + + /** Inspects stack trace if the given class called us. */ + public static boolean callStackContains(Class clazz) { + return Stream.of(new Exception().getStackTrace()).skip(1) // exclude this utility method + .map(StackTraceElement::getClassName) + .anyMatch(clazz.getName()::equals); + } /** A runnable that can throw any checked exception. */ @FunctionalInterface