diff --git a/lucene/CHANGES.txt b/lucene/CHANGES.txt index e4b36f793f3..8b6a4fa2d8f 100644 --- a/lucene/CHANGES.txt +++ b/lucene/CHANGES.txt @@ -192,6 +192,11 @@ Bug Fixes behave properly when wrapping other ValueSources which do not exist for the specified document (hossman) +* LUCENE-6019: Detect when DocValuesType illegally changes for the + same field name. Also added -Dtests.asserts=true|false so we can + run tests with and without assertions. (Simon Willnauer, Robert + Muir, Mike McCandless). + Documentation * LUCENE-5392: Add/improve analysis package documentation to reflect diff --git a/lucene/common-build.xml b/lucene/common-build.xml index 7e5e74ac3c3..772fa65cc78 100644 --- a/lucene/common-build.xml +++ b/lucene/common-build.xml @@ -120,11 +120,15 @@ - + + + + + @@ -963,16 +967,11 @@ - - - - - - + @@ -1010,7 +1009,7 @@ - + diff --git a/lucene/core/src/java/org/apache/lucene/index/DocumentsWriterPerThread.java b/lucene/core/src/java/org/apache/lucene/index/DocumentsWriterPerThread.java index 781b44429ba..21a0840844d 100644 --- a/lucene/core/src/java/org/apache/lucene/index/DocumentsWriterPerThread.java +++ b/lucene/core/src/java/org/apache/lucene/index/DocumentsWriterPerThread.java @@ -78,9 +78,8 @@ class DocumentsWriterPerThread { this.infoStream = infoStream; } - // Only called by asserts - public boolean testPoint(String name) { - return docWriter.testPoint(name); + public void testPoint(String name) { + docWriter.testPoint(name); } public void clear() { @@ -203,11 +202,10 @@ class DocumentsWriterPerThread { return retval; } - final boolean testPoint(String message) { + final void testPoint(String message) { if (infoStream.isEnabled("TP")) { infoStream.message("TP", message); } - return true; } /** Anything that will add N docs to the index should reserve first to @@ -221,7 +219,7 @@ class DocumentsWriterPerThread { } public void updateDocument(IndexDocument doc, Analyzer analyzer, Term delTerm) throws IOException { - assert testPoint("DocumentsWriterPerThread addDocument start"); + testPoint("DocumentsWriterPerThread addDocument start"); assert deleteQueue != null; docState.doc = doc; docState.analyzer = analyzer; @@ -259,7 +257,7 @@ class DocumentsWriterPerThread { } public int updateDocuments(Iterable docs, Analyzer analyzer, Term delTerm) throws IOException { - assert testPoint("DocumentsWriterPerThread addDocuments start"); + testPoint("DocumentsWriterPerThread addDocuments start"); assert deleteQueue != null; docState.analyzer = analyzer; if (INFO_VERBOSE && infoStream.isEnabled("DWPT")) { diff --git a/lucene/core/src/java/org/apache/lucene/index/DocumentsWriterStallControl.java b/lucene/core/src/java/org/apache/lucene/index/DocumentsWriterStallControl.java index 9cfe6a533eb..a799fbf58ec 100644 --- a/lucene/core/src/java/org/apache/lucene/index/DocumentsWriterStallControl.java +++ b/lucene/core/src/java/org/apache/lucene/index/DocumentsWriterStallControl.java @@ -70,9 +70,9 @@ final class DocumentsWriterStallControl { if (stalled) { // react on the first wakeup call! // don't loop here, higher level logic will re-stall! try { - assert incWaiters(); + incWaiters(); wait(); - assert decrWaiters(); + decrWaiters(); } catch (InterruptedException e) { throw new ThreadInterruptedException(e); } @@ -86,17 +86,16 @@ final class DocumentsWriterStallControl { } - private boolean incWaiters() { + private void incWaiters() { numWaiting++; assert waiting.put(Thread.currentThread(), Boolean.TRUE) == null; - - return numWaiting > 0; + assert numWaiting > 0; } - private boolean decrWaiters() { + private void decrWaiters() { numWaiting--; assert waiting.remove(Thread.currentThread()) != null; - return numWaiting >= 0; + assert numWaiting >= 0; } synchronized boolean hasBlocked() { // for tests diff --git a/lucene/core/src/java/org/apache/lucene/index/FieldInfos.java b/lucene/core/src/java/org/apache/lucene/index/FieldInfos.java index a4507644bef..e7a0184dc80 100644 --- a/lucene/core/src/java/org/apache/lucene/index/FieldInfos.java +++ b/lucene/core/src/java/org/apache/lucene/index/FieldInfos.java @@ -220,11 +220,17 @@ public class FieldInfos implements Iterable { return fieldNumber.intValue(); } - // used by assert - synchronized boolean containsConsistent(Integer number, String name, DocValuesType dvType) { - return name.equals(numberToName.get(number)) - && number.equals(nameToNumber.get(name)) && - (dvType == null || docValuesType.get(name) == null || dvType == docValuesType.get(name)); + synchronized void verifyConsistent(Integer number, String name, DocValuesType dvType) { + if (name.equals(numberToName.get(number)) == false) { + throw new IllegalArgumentException("field number " + number + " is already mapped to field name \"" + numberToName.get(number) + "\", not \"" + name + "\""); + } + if (number.equals(nameToNumber.get(name)) == false) { + throw new IllegalArgumentException("field name \"" + name + "\" is already mapped to field number \"" + nameToNumber.get(name) + "\", not \"" + number + "\""); + } + DocValuesType currentDVType = docValuesType.get(name); + if (dvType != null && currentDVType != null && dvType != currentDVType) { + throw new IllegalArgumentException("cannot change DocValues type from " + currentDVType + " to " + dvType + " for field \"" + name + "\""); + } } /** @@ -248,7 +254,7 @@ public class FieldInfos implements Iterable { } synchronized void setDocValuesType(int number, String name, DocValuesType dvType) { - assert containsConsistent(number, name, dvType); + verifyConsistent(number, name, dvType); docValuesType.put(name, dvType); } } @@ -302,7 +308,7 @@ public class FieldInfos implements Iterable { final int fieldNumber = globalFieldNumbers.addOrGet(name, preferredFieldNumber, docValues); fi = new FieldInfo(name, fieldNumber, storeTermVector, omitNorms, storePayloads, indexOptions, docValues, -1, null); assert !byName.containsKey(fi.name); - assert globalFieldNumbers.containsConsistent(Integer.valueOf(fi.number), fi.name, fi.getDocValuesType()); + globalFieldNumbers.verifyConsistent(Integer.valueOf(fi.number), fi.name, fi.getDocValuesType()); byName.put(fi.name, fi); } else { fi.update(storeTermVector, omitNorms, storePayloads, indexOptions); diff --git a/lucene/core/src/java/org/apache/lucene/index/FreqProxTermsWriterPerField.java b/lucene/core/src/java/org/apache/lucene/index/FreqProxTermsWriterPerField.java index 8403e852eac..a45e62a05f7 100644 --- a/lucene/core/src/java/org/apache/lucene/index/FreqProxTermsWriterPerField.java +++ b/lucene/core/src/java/org/apache/lucene/index/FreqProxTermsWriterPerField.java @@ -110,8 +110,6 @@ final class FreqProxTermsWriterPerField extends TermsHashPerField { void newTerm(final int termID) { // First time we're seeing this term since the last // flush - assert docState.testPoint("FreqProxTermsWriterPerField.newTerm start"); - final FreqProxPostingsArray postings = freqProxPostingsArray; postings.lastDocIDs[termID] = docState.docID; @@ -136,9 +134,6 @@ final class FreqProxTermsWriterPerField extends TermsHashPerField { @Override void addTerm(final int termID) { - - assert docState.testPoint("FreqProxTermsWriterPerField.addTerm start"); - final FreqProxPostingsArray postings = freqProxPostingsArray; assert !hasFreq || postings.termFreqs[termID] > 0; diff --git a/lucene/core/src/java/org/apache/lucene/index/IndexWriter.java b/lucene/core/src/java/org/apache/lucene/index/IndexWriter.java index 93587f82d13..5b07ae9ff4f 100644 --- a/lucene/core/src/java/org/apache/lucene/index/IndexWriter.java +++ b/lucene/core/src/java/org/apache/lucene/index/IndexWriter.java @@ -2013,7 +2013,7 @@ public class IndexWriter implements Closeable, TwoPhaseCommit, Accountable { infoStream.message("IW", "rollback: infos=" + segString(segmentInfos)); } - assert testPoint("rollback before checkpoint"); + testPoint("rollback before checkpoint"); // Ask deleter to locate unreferenced files & remove // them: @@ -2711,7 +2711,7 @@ public class IndexWriter implements Closeable, TwoPhaseCommit, Accountable { } doBeforeFlush(); - assert testPoint("startDoFlush"); + testPoint("startDoFlush"); SegmentInfos toCommit = null; boolean anySegmentsFlushed = false; @@ -2997,7 +2997,7 @@ public class IndexWriter implements Closeable, TwoPhaseCommit, Accountable { } doBeforeFlush(); - assert testPoint("startDoFlush"); + testPoint("startDoFlush"); boolean success = false; try { @@ -3080,9 +3080,7 @@ public class IndexWriter implements Closeable, TwoPhaseCommit, Accountable { // for testing only DocumentsWriter getDocsWriter() { - boolean test = false; - assert test = true; - return test ? docWriter : null; + return docWriter; } /** Expert: Return the number of documents currently @@ -3167,7 +3165,7 @@ public class IndexWriter implements Closeable, TwoPhaseCommit, Accountable { */ synchronized private ReadersAndUpdates commitMergedDeletesAndUpdates(MergePolicy.OneMerge merge, MergeState mergeState) throws IOException { - assert testPoint("startCommitMergeDeletes"); + testPoint("startCommitMergeDeletes"); final List sourceSegments = merge.segments; @@ -3352,7 +3350,7 @@ public class IndexWriter implements Closeable, TwoPhaseCommit, Accountable { synchronized private boolean commitMerge(MergePolicy.OneMerge merge, MergeState mergeState) throws IOException { - assert testPoint("startCommitMerge"); + testPoint("startCommitMerge"); if (tragedy != null) { throw new IllegalStateException("this writer hit an unrecoverable error; cannot complete merge", tragedy); @@ -3696,7 +3694,7 @@ public class IndexWriter implements Closeable, TwoPhaseCommit, Accountable { synchronized private void _mergeInit(MergePolicy.OneMerge merge) throws IOException { - assert testPoint("startMergeInit"); + testPoint("startMergeInit"); assert merge.registerDone; assert merge.maxNumSegments == -1 || merge.maxNumSegments > 0; @@ -4234,7 +4232,7 @@ public class IndexWriter implements Closeable, TwoPhaseCommit, Accountable { * it. */ private void startCommit(final SegmentInfos toSync) throws IOException { - assert testPoint("startStartCommit"); + testPoint("startStartCommit"); assert pendingCommit == null; if (tragedy != null) { @@ -4270,13 +4268,13 @@ public class IndexWriter implements Closeable, TwoPhaseCommit, Accountable { assert filesExist(toSync); } - assert testPoint("midStartCommit"); + testPoint("midStartCommit"); boolean pendingCommitSet = false; try { - assert testPoint("midStartCommit2"); + testPoint("midStartCommit2"); synchronized(this) { @@ -4314,7 +4312,7 @@ public class IndexWriter implements Closeable, TwoPhaseCommit, Accountable { infoStream.message("IW", "done all syncs: " + filesToSync); } - assert testPoint("midStartCommitSuccess"); + testPoint("midStartCommitSuccess"); } finally { synchronized(this) { @@ -4338,7 +4336,7 @@ public class IndexWriter implements Closeable, TwoPhaseCommit, Accountable { } catch (OutOfMemoryError oom) { tragicEvent(oom, "startCommit"); } - assert testPoint("finishStartCommit"); + testPoint("finishStartCommit"); } /** @@ -4415,7 +4413,7 @@ public class IndexWriter implements Closeable, TwoPhaseCommit, Accountable { IOUtils.reThrowUnchecked(tragedy); } - // Used only by assert for testing. Current points: + // Used for testing. Current points: // startDoFlush // startCommitMerge // startStartCommit @@ -4426,11 +4424,10 @@ public class IndexWriter implements Closeable, TwoPhaseCommit, Accountable { // startCommitMergeDeletes // startMergeInit // DocumentsWriter.ThreadState.init start - private final boolean testPoint(String message) { + private final void testPoint(String message) { if (infoStream.isEnabled("TP")) { infoStream.message("TP", message); } - return true; } synchronized boolean nrtIsCurrent(SegmentInfos infos) { diff --git a/lucene/core/src/java/org/apache/lucene/index/TermVectorsConsumer.java b/lucene/core/src/java/org/apache/lucene/index/TermVectorsConsumer.java index d138ad51eeb..36e8e184b9e 100644 --- a/lucene/core/src/java/org/apache/lucene/index/TermVectorsConsumer.java +++ b/lucene/core/src/java/org/apache/lucene/index/TermVectorsConsumer.java @@ -93,8 +93,6 @@ final class TermVectorsConsumer extends TermsHash { @Override void finishDocument() throws IOException { - assert docWriter.testPoint("TermVectorsTermsWriter.finishDocument start"); - if (!hasVectors) { return; } @@ -119,7 +117,6 @@ final class TermVectorsConsumer extends TermsHash { super.reset(); resetFields(); - assert docWriter.testPoint("TermVectorsTermsWriter.finishDocument end"); } @Override diff --git a/lucene/core/src/java/org/apache/lucene/index/TermVectorsConsumerPerField.java b/lucene/core/src/java/org/apache/lucene/index/TermVectorsConsumerPerField.java index e34b41f1552..ccebf1b5259 100644 --- a/lucene/core/src/java/org/apache/lucene/index/TermVectorsConsumerPerField.java +++ b/lucene/core/src/java/org/apache/lucene/index/TermVectorsConsumerPerField.java @@ -63,8 +63,6 @@ final class TermVectorsConsumerPerField extends TermsHashPerField { doVectors = false; - assert docState.testPoint("TermVectorsTermsWriterPerField.finish start"); - final int numPostings = bytesHash.size(); final BytesRef flushTerm = termsWriter.flushTerm; @@ -226,7 +224,6 @@ final class TermVectorsConsumerPerField extends TermsHashPerField { @Override void newTerm(final int termID) { - assert docState.testPoint("TermVectorsTermsWriterPerField.newTerm start"); TermVectorsPostingsArray postings = termVectorsPostingsArray; postings.freqs[termID] = 1; @@ -238,7 +235,6 @@ final class TermVectorsConsumerPerField extends TermsHashPerField { @Override void addTerm(final int termID) { - assert docState.testPoint("TermVectorsTermsWriterPerField.addTerm start"); TermVectorsPostingsArray postings = termVectorsPostingsArray; postings.freqs[termID]++; diff --git a/lucene/core/src/test/org/apache/lucene/TestAssertions.java b/lucene/core/src/test/org/apache/lucene/TestAssertions.java index 5ad3a80878d..f4b9d51c878 100644 --- a/lucene/core/src/test/org/apache/lucene/TestAssertions.java +++ b/lucene/core/src/test/org/apache/lucene/TestAssertions.java @@ -17,8 +17,8 @@ package org.apache.lucene; * limitations under the License. */ -import org.apache.lucene.util.LuceneTestCase; import org.apache.lucene.analysis.TokenStream; +import org.apache.lucene.util.LuceneTestCase; /** * validate that assertions are enabled during tests @@ -43,13 +43,14 @@ public class TestAssertions extends LuceneTestCase { public void testTokenStreams() { new TestTokenStream1(); new TestTokenStream2(); - boolean doFail = false; try { new TestTokenStream3(); - doFail = true; + if (assertsAreEnabled) { + fail("TestTokenStream3 should fail assertion"); + } } catch (AssertionError e) { // expected + e.printStackTrace(System.out); } - assertFalse("TestTokenStream3 should fail assertion", doFail); } } diff --git a/lucene/core/src/test/org/apache/lucene/index/TestDocValuesIndexing.java b/lucene/core/src/test/org/apache/lucene/index/TestDocValuesIndexing.java index 9891d0c2eb7..06dfd27a76d 100644 --- a/lucene/core/src/test/org/apache/lucene/index/TestDocValuesIndexing.java +++ b/lucene/core/src/test/org/apache/lucene/index/TestDocValuesIndexing.java @@ -231,6 +231,7 @@ public class TestDocValuesIndexing extends LuceneTestCase { doc.add(new SortedDocValuesField("foo", new BytesRef("hello"))); try { w.addDocument(doc); + fail("didn't hit expected exception"); } catch (IllegalArgumentException iae) { // expected } @@ -253,6 +254,7 @@ public class TestDocValuesIndexing extends LuceneTestCase { doc.add(new SortedDocValuesField("foo", new BytesRef("hello"))); try { w.addDocument(doc); + fail("didn't hit expected exception"); } catch (IllegalArgumentException iae) { // expected } @@ -420,6 +422,7 @@ public class TestDocValuesIndexing extends LuceneTestCase { doc.add(new SortedDocValuesField("foo", new BytesRef("hello"))); try { w.addDocument(doc); + fail("did not get expected exception"); } catch (IllegalArgumentException iae) { // expected } @@ -456,12 +459,58 @@ public class TestDocValuesIndexing extends LuceneTestCase { iwc.setOpenMode(IndexWriterConfig.OpenMode.CREATE); w = new IndexWriter(dir, iwc); doc = new Document(); - doc.add(new SortedDocValuesField("foo", new BytesRef("hello"))); w.addDocument(doc); w.close(); dir.close(); } + public void testMixedTypesAfterReopenAppend1() throws Exception { + Directory dir = newDirectory(); + IndexWriter w = new IndexWriter(dir, newIndexWriterConfig(new MockAnalyzer(random()))); + Document doc = new Document(); + doc.add(new NumericDocValuesField("foo", 0)); + w.addDocument(doc); + w.close(); + + w = new IndexWriter(dir, newIndexWriterConfig(new MockAnalyzer(random()))); + doc = new Document(); + doc.add(new SortedDocValuesField("foo", new BytesRef("hello"))); + try { + w.addDocument(doc); + fail("did not get expected exception"); + } catch (IllegalArgumentException iae) { + // expected + } + w.close(); + dir.close(); + } + + public void testMixedTypesAfterReopenAppend2() throws IOException { + Directory dir = newDirectory(); + IndexWriter w = new IndexWriter(dir, newIndexWriterConfig(new MockAnalyzer(random()))) ; + Document doc = new Document(); + doc.add(new SortedSetDocValuesField("foo", new BytesRef("foo"))); + w.addDocument(doc); + w.close(); + + doc = new Document(); + w = new IndexWriter(dir, newIndexWriterConfig(new MockAnalyzer(random()))); + doc.add(new StringField("foo", "bar", Field.Store.NO)); + doc.add(new BinaryDocValuesField("foo", new BytesRef("foo"))); + try { + // NOTE: this case follows a different code path inside + // DefaultIndexingChain/FieldInfos, because the field (foo) + // is first added without DocValues: + w.addDocument(doc); + fail("did not get expected exception"); + } catch (IllegalArgumentException iae) { + // expected + } + w.forceMerge(1); + w.close(); + dir.close(); + } + // Two documents with same field as different types, added // from separate threads: public void testMixedTypesDifferentThreads() throws Exception { @@ -528,6 +577,7 @@ public class TestDocValuesIndexing extends LuceneTestCase { try { w.addIndexes(new Directory[] {dir2}); + fail("didn't hit expected exception"); } catch (IllegalArgumentException iae) { // expected } @@ -535,6 +585,7 @@ public class TestDocValuesIndexing extends LuceneTestCase { IndexReader r = DirectoryReader.open(dir2); try { w.addIndexes(new IndexReader[] {r}); + fail("didn't hit expected exception"); } catch (IllegalArgumentException iae) { // expected } @@ -819,5 +870,4 @@ public class TestDocValuesIndexing extends LuceneTestCase { dir.close(); } - } diff --git a/lucene/test-framework/src/java/org/apache/lucene/index/RandomIndexWriter.java b/lucene/test-framework/src/java/org/apache/lucene/index/RandomIndexWriter.java index 6aac9e34381..47b1b792478 100644 --- a/lucene/test-framework/src/java/org/apache/lucene/index/RandomIndexWriter.java +++ b/lucene/test-framework/src/java/org/apache/lucene/index/RandomIndexWriter.java @@ -54,7 +54,7 @@ public class RandomIndexWriter implements Closeable { public static IndexWriter mockIndexWriter(Directory dir, IndexWriterConfig conf, Random r) throws IOException { // Randomly calls Thread.yield so we mixup thread scheduling final Random random = new Random(r.nextLong()); - return mockIndexWriter(dir, conf, new TestPoint() { + return mockIndexWriter(dir, conf, new TestPoint() { @Override public void apply(String message) { if (random.nextInt(4) == 2) diff --git a/lucene/test-framework/src/java/org/apache/lucene/store/MockDirectoryWrapper.java b/lucene/test-framework/src/java/org/apache/lucene/store/MockDirectoryWrapper.java index 5d04281b5db..0100a15aece 100644 --- a/lucene/test-framework/src/java/org/apache/lucene/store/MockDirectoryWrapper.java +++ b/lucene/test-framework/src/java/org/apache/lucene/store/MockDirectoryWrapper.java @@ -859,7 +859,7 @@ public class MockDirectoryWrapper extends BaseDirectoryWrapper { extras += "\n\nThese files we had previously tried to delete, but couldn't: " + pendingDeletions; } - assert false : "unreferenced files: before delete:\n " + Arrays.toString(startFiles) + "\n after delete:\n " + Arrays.toString(endFiles) + extras; + throw new RuntimeException("unreferenced files: before delete:\n " + Arrays.toString(startFiles) + "\n after delete:\n " + Arrays.toString(endFiles) + extras); } DirectoryReader ir1 = DirectoryReader.open(this); 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 f6e6b60c10a..51e43c75842 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 @@ -78,7 +78,6 @@ import org.apache.lucene.index.IndexReader.ReaderClosedListener; import org.apache.lucene.index.IndexReader; import org.apache.lucene.index.IndexWriter; import org.apache.lucene.index.IndexWriterConfig; -import org.apache.lucene.index.IndexableField; import org.apache.lucene.index.LeafReader; import org.apache.lucene.index.LeafReaderContext; import org.apache.lucene.index.LiveIndexWriterConfig; @@ -387,6 +386,8 @@ public abstract class LuceneTestCase extends Assert { */ public static final int RANDOM_MULTIPLIER = systemPropertyAsInt("tests.multiplier", 1); + public static final boolean TEST_ASSERTS_ENABLED = systemPropertyAsBoolean("tests.asserts", true); + /** TODO: javadoc? */ public static final String DEFAULT_LINE_DOCS_FILE = "europarl.lines.txt.gz"; @@ -2461,4 +2462,13 @@ public abstract class LuceneTestCase extends Assert { public static Path createTempFile() throws IOException { return createTempFile("tempFile", ".tmp"); } + + /** True if assertions (-ea) are enabled (at least for this class). */ + public static final boolean assertsAreEnabled; + + static { + boolean enabled = false; + assert enabled = true; // Intentional side-effect!!! + assertsAreEnabled = enabled; + } } diff --git a/lucene/test-framework/src/java/org/apache/lucene/util/RunListenerPrintReproduceInfo.java b/lucene/test-framework/src/java/org/apache/lucene/util/RunListenerPrintReproduceInfo.java index 6041d22e96a..dc7d3bfdf69 100644 --- a/lucene/test-framework/src/java/org/apache/lucene/util/RunListenerPrintReproduceInfo.java +++ b/lucene/test-framework/src/java/org/apache/lucene/util/RunListenerPrintReproduceInfo.java @@ -177,6 +177,12 @@ public final class RunListenerPrintReproduceInfo extends RunListener { } } + if (LuceneTestCase.assertsAreEnabled) { + addVmOpt(b, "tests.asserts", "true"); + } else { + addVmOpt(b, "tests.asserts", "false"); + } + addVmOpt(b, "tests.file.encoding", System.getProperty("file.encoding")); System.err.println(b.toString()); diff --git a/lucene/test-framework/src/java/org/apache/lucene/util/TestRuleAssertionsRequired.java b/lucene/test-framework/src/java/org/apache/lucene/util/TestRuleAssertionsRequired.java index 86083287f4c..8ce1bf78c48 100644 --- a/lucene/test-framework/src/java/org/apache/lucene/util/TestRuleAssertionsRequired.java +++ b/lucene/test-framework/src/java/org/apache/lucene/util/TestRuleAssertionsRequired.java @@ -31,11 +31,22 @@ public class TestRuleAssertionsRequired implements TestRule { @Override public void evaluate() throws Throwable { try { - assert false; - String msg = "Test class requires enabled assertions, enable globally (-ea)" + - " or for Solr/Lucene subpackages only: " + description.getClassName(); - System.err.println(msg); - throw new Exception(msg); + // Make sure -ea matches -Dtests.asserts, to catch accidental mis-use: + if (LuceneTestCase.assertsAreEnabled != LuceneTestCase.TEST_ASSERTS_ENABLED) { + String msg = "Assertions mismatch: "; + if (LuceneTestCase.assertsAreEnabled) { + msg += "-ea was specified"; + } else { + msg += "-ea was not specified"; + } + if (LuceneTestCase.TEST_ASSERTS_ENABLED) { + msg += " but -Dtests.asserts=true"; + } else { + msg += " but -Dtests.asserts=false"; + } + System.err.println(msg); + throw new Exception(msg); + } } catch (AssertionError e) { // Ok, enabled. }