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 extends IndexDocument> 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.
}