larger values first
- : id2String(i+1); // reverse ==> smaller values first
- assertTrue("id of result "+i+" shuould be "+expectedId+" != "+score, expectedId.equals(id));
+ log("-------- " + i + ". Explain doc " + id);
+ log(s.explain(q, sd[i].doc));
+ float expectedScore = N_DOCS - i;
+ assertEquals("score of result " + i + " shuould be " + expectedScore + " != " + score, expectedScore, score, TEST_SCORE_TOLERANCE_DELTA);
+ String expectedId = inOrder
+ ? id2String(N_DOCS - i) // in-order ==> larger values first
+ : id2String(i + 1); // reverse ==> smaller values first
+ assertTrue("id of result " + i + " shuould be " + expectedId + " != " + score, expectedId.equals(id));
}
}
-
- /** Test caching OrdFieldSource */
- public void testCachingOrd () throws CorruptIndexException, Exception {
- doTestCaching(ID_FIELD,true);
+
+ /**
+ * Test caching OrdFieldSource
+ */
+ @Test
+ public void testCachingOrd() throws CorruptIndexException, Exception {
+ doTestCaching(ID_FIELD, true);
}
-
- /** Test caching for ReverseOrdFieldSource */
- public void tesCachingReverseOrd () throws CorruptIndexException, Exception {
- doTestCaching(ID_FIELD,false);
+
+ /**
+ * Test caching for ReverseOrdFieldSource
+ */
+ @Test
+ public void tesCachingReverseOrd() throws CorruptIndexException, Exception {
+ doTestCaching(ID_FIELD, false);
}
// Test that values loaded for FieldScoreQuery are cached properly and consumes the proper RAM resources.
- private void doTestCaching (String field, boolean inOrder) throws CorruptIndexException, Exception {
+ private void doTestCaching(String field, boolean inOrder) throws CorruptIndexException, Exception {
IndexSearcher s = new IndexSearcher(dir, true);
Object innerArray = null;
boolean warned = false; // print warning once
-
- for (int i=0; i<10; i++) {
+
+ for (int i = 0; i < 10; i++) {
ValueSource vs;
if (inOrder) {
vs = new OrdFieldSource(field);
@@ -150,30 +162,29 @@
ValueSourceQuery q = new ValueSourceQuery(vs);
ScoreDoc[] h = s.search(q, null, 1000).scoreDocs;
try {
- assertEquals("All docs should be matched!",N_DOCS,h.length);
+ assertEquals("All docs should be matched!", N_DOCS, h.length);
IndexReader[] readers = s.getIndexReader().getSequentialSubReaders();
- for(int j = 0; j < readers.length; j++) {
- IndexReader reader = readers[j];
- if (i==0) {
+ for (IndexReader reader : readers) {
+ if (i == 0) {
innerArray = q.valSrc.getValues(reader).getInnerArray();
} else {
- log(i+". compare: "+innerArray+" to "+q.valSrc.getValues(reader).getInnerArray());
+ log(i + ". compare: " + innerArray + " to " + q.valSrc.getValues(reader).getInnerArray());
assertSame("field values should be cached and reused!", innerArray, q.valSrc.getValues(reader).getInnerArray());
}
}
} catch (UnsupportedOperationException e) {
if (!warned) {
- System.err.println("WARNING: "+testName()+" cannot fully test values of "+q);
+ System.err.println("WARNING: " + testName() + " cannot fully test values of " + q);
warned = true;
}
}
}
-
+
ValueSource vs;
ValueSourceQuery q;
ScoreDoc[] h;
-
+
// verify that different values are loaded for a different field
String field2 = INT_FIELD;
assertFalse(field.equals(field2)); // otherwise this test is meaningless.
@@ -184,21 +195,20 @@
}
q = new ValueSourceQuery(vs);
h = s.search(q, null, 1000).scoreDocs;
- assertEquals("All docs should be matched!",N_DOCS,h.length);
+ assertEquals("All docs should be matched!", N_DOCS, h.length);
IndexReader[] readers = s.getIndexReader().getSequentialSubReaders();
- for (int j = 0; j < readers.length; j++) {
- IndexReader reader = readers[j];
+ for (IndexReader reader : readers) {
try {
log("compare (should differ): " + innerArray + " to "
- + q.valSrc.getValues(reader).getInnerArray());
+ + q.valSrc.getValues(reader).getInnerArray());
assertNotSame(
- "different values shuold be loaded for a different field!",
- innerArray, q.valSrc.getValues(reader).getInnerArray());
+ "different values shuold be loaded for a different field!",
+ innerArray, q.valSrc.getValues(reader).getInnerArray());
} catch (UnsupportedOperationException e) {
if (!warned) {
System.err.println("WARNING: " + testName()
- + " cannot fully test values of " + q);
+ + " cannot fully test values of " + q);
warned = true;
}
}
@@ -213,21 +223,20 @@
}
q = new ValueSourceQuery(vs);
h = s.search(q, null, 1000).scoreDocs;
- assertEquals("All docs should be matched!",N_DOCS,h.length);
+ assertEquals("All docs should be matched!", N_DOCS, h.length);
readers = s.getIndexReader().getSequentialSubReaders();
- for (int j = 0; j < readers.length; j++) {
- IndexReader reader = readers[j];
+ for (IndexReader reader : readers) {
try {
log("compare (should differ): " + innerArray + " to "
- + q.valSrc.getValues(reader).getInnerArray());
+ + q.valSrc.getValues(reader).getInnerArray());
assertNotSame(
- "cached field values should not be reused if reader as changed!",
- innerArray, q.valSrc.getValues(reader).getInnerArray());
+ "cached field values should not be reused if reader as changed!",
+ innerArray, q.valSrc.getValues(reader).getInnerArray());
} catch (UnsupportedOperationException e) {
if (!warned) {
System.err.println("WARNING: " + testName()
- + " cannot fully test values of " + q);
+ + " cannot fully test values of " + q);
warned = true;
}
}
@@ -235,7 +244,7 @@
}
private String testName() {
- return getClass().getName()+"."+getName();
+ return getClass().getName() + "." + getName();
}
}
Index: src/test/org/apache/lucene/search/function/TestDocValues.java
===================================================================
--- src/test/org/apache/lucene/search/function/TestDocValues.java (revision 836300)
+++ src/test/org/apache/lucene/search/function/TestDocValues.java (working copy)
@@ -18,18 +18,18 @@
*/
import org.apache.lucene.util.LuceneTestCase;
-import junit.framework.Assert;
+import org.apache.lucene.util.LuceneTestCaseJ4;
+import org.junit.Test;
+import org.junit.Before;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
/**
* DocValues TestCase
*/
-public class TestDocValues extends LuceneTestCase {
+public class TestDocValues extends LuceneTestCaseJ4 {
- /* @override constructor */
- public TestDocValues(String name) {
- super(name);
- }
-
+ @Test
public void testGetMinValue() {
float[] innerArray = new float[] { 1.0f, 2.0f, -1.0f, 100.0f };
DocValuesTestImpl docValues = new DocValuesTestImpl(innerArray);
@@ -42,7 +42,7 @@
assertTrue("max is NaN - no values in inner array", Float.isNaN(docValues
.getMinValue()));
}
-
+ @Test
public void testGetMaxValue() {
float[] innerArray = new float[] { 1.0f, 2.0f, -1.0f, 10.0f };
DocValuesTestImpl docValues = new DocValuesTestImpl(innerArray);
@@ -67,6 +67,7 @@
.getMaxValue()));
}
+ @Test
public void testGetAverageValue() {
float[] innerArray = new float[] { 1.0f, 1.0f, 1.0f, 1.0f };
DocValuesTestImpl docValues = new DocValuesTestImpl(innerArray);
@@ -98,7 +99,6 @@
/**
* @see org.apache.lucene.search.function.DocValues#floatVal(int)
*/
- /* @Override */
@Override
public float floatVal(int doc) {
return innerArray[doc];
@@ -107,7 +107,6 @@
/**
* @see org.apache.lucene.search.function.DocValues#toString(int)
*/
- /* @Override */
@Override
public String toString(int doc) {
return Integer.toString(doc);
Index: src/test/org/apache/lucene/search/function/TestFieldScoreQuery.java
===================================================================
--- src/test/org/apache/lucene/search/function/TestFieldScoreQuery.java (revision 836300)
+++ src/test/org/apache/lucene/search/function/TestFieldScoreQuery.java (working copy)
@@ -18,14 +18,16 @@
*/
import java.util.HashMap;
+import java.util.Map;
-import org.apache.lucene.index.CorruptIndexException;
import org.apache.lucene.index.IndexReader;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.Query;
import org.apache.lucene.search.QueryUtils;
import org.apache.lucene.search.ScoreDoc;
import org.apache.lucene.search.TopDocs;
+import org.junit.Test;
+import static org.junit.Assert.*;
/**
* Test FieldScoreQuery search.
@@ -38,32 +40,32 @@
*
* The exact score tests use TopDocs top to verify the exact score.
*/
+@SuppressWarnings({"UseOfSystemOutOrSystemErr"})
public class TestFieldScoreQuery extends FunctionTestSetup {
- /* @override constructor */
- public TestFieldScoreQuery(String name) {
- super(name);
- }
-
/** Test that FieldScoreQuery of Type.BYTE returns docs in expected order. */
- public void testRankByte () throws CorruptIndexException, Exception {
+ @Test
+ public void testRankByte () throws Exception {
// INT field values are small enough to be parsed as byte
doTestRank(INT_FIELD,FieldScoreQuery.Type.BYTE);
}
/** Test that FieldScoreQuery of Type.SHORT returns docs in expected order. */
- public void testRankShort () throws CorruptIndexException, Exception {
+ @Test
+ public void testRankShort () throws Exception {
// INT field values are small enough to be parsed as short
doTestRank(INT_FIELD,FieldScoreQuery.Type.SHORT);
}
/** Test that FieldScoreQuery of Type.INT returns docs in expected order. */
- public void testRankInt () throws CorruptIndexException, Exception {
+ @Test
+ public void testRankInt () throws Exception {
doTestRank(INT_FIELD,FieldScoreQuery.Type.INT);
}
/** Test that FieldScoreQuery of Type.FLOAT returns docs in expected order. */
- public void testRankFloat () throws CorruptIndexException, Exception {
+ @Test
+ public void testRankFloat () throws Exception {
// INT field can be parsed as float
doTestRank(INT_FIELD,FieldScoreQuery.Type.FLOAT);
// same values, but in flot format
@@ -71,7 +73,7 @@
}
// Test that FieldScoreQuery returns docs in expected order.
- private void doTestRank (String field, FieldScoreQuery.Type tp) throws CorruptIndexException, Exception {
+ private void doTestRank (String field, FieldScoreQuery.Type tp) throws Exception {
IndexSearcher s = new IndexSearcher(dir, true);
Query q = new FieldScoreQuery(field,tp);
log("test: "+q);
@@ -89,24 +91,28 @@
}
/** Test that FieldScoreQuery of Type.BYTE returns the expected scores. */
- public void testExactScoreByte () throws CorruptIndexException, Exception {
+ @Test
+ public void testExactScoreByte () throws Exception {
// INT field values are small enough to be parsed as byte
doTestExactScore(INT_FIELD,FieldScoreQuery.Type.BYTE);
}
/** Test that FieldScoreQuery of Type.SHORT returns the expected scores. */
- public void testExactScoreShort () throws CorruptIndexException, Exception {
+ @Test
+ public void testExactScoreShort () throws Exception {
// INT field values are small enough to be parsed as short
doTestExactScore(INT_FIELD,FieldScoreQuery.Type.SHORT);
}
/** Test that FieldScoreQuery of Type.INT returns the expected scores. */
- public void testExactScoreInt () throws CorruptIndexException, Exception {
+ @Test
+ public void testExactScoreInt () throws Exception {
doTestExactScore(INT_FIELD,FieldScoreQuery.Type.INT);
}
/** Test that FieldScoreQuery of Type.FLOAT returns the expected scores. */
- public void testExactScoreFloat () throws CorruptIndexException, Exception {
+ @Test
+ public void testExactScoreFloat () throws Exception {
// INT field can be parsed as float
doTestExactScore(INT_FIELD,FieldScoreQuery.Type.FLOAT);
// same values, but in flot format
@@ -114,40 +120,44 @@
}
// Test that FieldScoreQuery returns docs with expected score.
- private void doTestExactScore (String field, FieldScoreQuery.Type tp) throws CorruptIndexException, Exception {
+ private void doTestExactScore (String field, FieldScoreQuery.Type tp) throws Exception {
IndexSearcher s = new IndexSearcher(dir, true);
Query q = new FieldScoreQuery(field,tp);
TopDocs td = s.search(q,null,1000);
assertEquals("All docs should be matched!",N_DOCS,td.totalHits);
ScoreDoc sd[] = td.scoreDocs;
- for (int i=0; i 7.0
- assertEquals("score of "+id+" shuould be "+expectedScore+" != "+score, expectedScore, score, TEST_SCORE_TOLERANCE_DELTA);
+ assertEquals("score of " + id + " shuould be " + expectedScore + " != " + score, expectedScore, score, TEST_SCORE_TOLERANCE_DELTA);
}
}
/** Test that FieldScoreQuery of Type.BYTE caches/reuses loaded values and consumes the proper RAM resources. */
- public void testCachingByte () throws CorruptIndexException, Exception {
+ @Test
+ public void testCachingByte () throws Exception {
// INT field values are small enough to be parsed as byte
doTestCaching(INT_FIELD,FieldScoreQuery.Type.BYTE);
}
/** Test that FieldScoreQuery of Type.SHORT caches/reuses loaded values and consumes the proper RAM resources. */
- public void testCachingShort () throws CorruptIndexException, Exception {
+ @Test
+ public void testCachingShort () throws Exception {
// INT field values are small enough to be parsed as short
doTestCaching(INT_FIELD,FieldScoreQuery.Type.SHORT);
}
/** Test that FieldScoreQuery of Type.INT caches/reuses loaded values and consumes the proper RAM resources. */
- public void testCachingInt () throws CorruptIndexException, Exception {
+ @Test
+ public void testCachingInt () throws Exception {
doTestCaching(INT_FIELD,FieldScoreQuery.Type.INT);
}
/** Test that FieldScoreQuery of Type.FLOAT caches/reuses loaded values and consumes the proper RAM resources. */
- public void testCachingFloat () throws CorruptIndexException, Exception {
+ @Test
+ public void testCachingFloat () throws Exception {
// INT field values can be parsed as float
doTestCaching(INT_FIELD,FieldScoreQuery.Type.FLOAT);
// same values, but in flot format
@@ -155,9 +165,9 @@
}
// Test that values loaded for FieldScoreQuery are cached properly and consumes the proper RAM resources.
- private void doTestCaching (String field, FieldScoreQuery.Type tp) throws CorruptIndexException, Exception {
+ private void doTestCaching (String field, FieldScoreQuery.Type tp) throws Exception {
// prepare expected array types for comparison
- HashMap expectedArrayTypes = new HashMap();
+ Map expectedArrayTypes = new HashMap();
expectedArrayTypes.put(FieldScoreQuery.Type.BYTE, new byte[0]);
expectedArrayTypes.put(FieldScoreQuery.Type.SHORT, new short[0]);
expectedArrayTypes.put(FieldScoreQuery.Type.INT, new int[0]);
@@ -223,7 +233,7 @@
}
private String testName() {
- return getClass().getName()+"."+getName();
+ return getClass().getName()+"."+ getName();
}
}
Index: src/test/org/apache/lucene/search/function/FunctionTestSetup.java
===================================================================
--- src/test/org/apache/lucene/search/function/FunctionTestSetup.java (revision 836300)
+++ src/test/org/apache/lucene/search/function/FunctionTestSetup.java (working copy)
@@ -25,20 +25,23 @@
import org.apache.lucene.index.IndexWriter;
import org.apache.lucene.store.Directory;
import org.apache.lucene.store.RAMDirectory;
+import org.apache.lucene.util.LuceneTestCaseJ4;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Ignore;
-import org.apache.lucene.util.LuceneTestCase;
-
/**
* Setup for function tests
*/
-public abstract class FunctionTestSetup extends LuceneTestCase {
+@Ignore
+public class FunctionTestSetup extends LuceneTestCaseJ4 {
/**
* Actual score computation order is slightly different than assumptios
* this allows for a small amount of variation
*/
- public static float TEST_SCORE_TOLERANCE_DELTA = 0.001f;
-
+ protected static float TEST_SCORE_TOLERANCE_DELTA = 0.001f;
+
protected static final boolean DBG = false; // change to true for logging to print
protected static final int N_DOCS = 17; // select a primary number > 2
@@ -47,62 +50,57 @@
protected static final String TEXT_FIELD = "text";
protected static final String INT_FIELD = "iii";
protected static final String FLOAT_FIELD = "fff";
-
+
private static final String DOC_TEXT_LINES[] = {
- "Well, this is just some plain text we use for creating the ",
- "test documents. It used to be a text from an online collection ",
- "devoted to first aid, but if there was there an (online) lawyers ",
- "first aid collection with legal advices, \"it\" might have quite ",
- "probably advised one not to include \"it\"'s text or the text of ",
- "any other online collection in one's code, unless one has money ",
- "that one don't need and one is happy to donate for lawyers ",
- "charity. Anyhow at some point, rechecking the usage of this text, ",
- "it became uncertain that this text is free to use, because ",
- "the web site in the disclaimer of he eBook containing that text ",
- "was not responding anymore, and at the same time, in projGut, ",
- "searching for first aid no longer found that eBook as well. ",
- "So here we are, with a perhaps much less interesting ",
- "text for the test, but oh much much safer. ",
+ "Well, this is just some plain text we use for creating the ",
+ "test documents. It used to be a text from an online collection ",
+ "devoted to first aid, but if there was there an (online) lawyers ",
+ "first aid collection with legal advices, \"it\" might have quite ",
+ "probably advised one not to include \"it\"'s text or the text of ",
+ "any other online collection in one's code, unless one has money ",
+ "that one don't need and one is happy to donate for lawyers ",
+ "charity. Anyhow at some point, rechecking the usage of this text, ",
+ "it became uncertain that this text is free to use, because ",
+ "the web site in the disclaimer of he eBook containing that text ",
+ "was not responding anymore, and at the same time, in projGut, ",
+ "searching for first aid no longer found that eBook as well. ",
+ "So here we are, with a perhaps much less interesting ",
+ "text for the test, but oh much much safer. ",
};
-
- protected Directory dir;
- protected Analyzer anlzr;
-
- /* @override constructor */
- public FunctionTestSetup(String name) {
- super(name);
- }
- /* @override */
+ protected Directory dir = null;
+ protected Analyzer anlzr = null;
+
@Override
- protected void tearDown() throws Exception {
+ @After
+ public void tearDown() throws Exception {
super.tearDown();
dir = null;
anlzr = null;
}
- /* @override */
@Override
- protected void setUp() throws Exception {
+ @Before
+ public void setUp() throws Exception {
super.setUp();
// prepare a small index with just a few documents.
super.setUp();
dir = new RAMDirectory();
anlzr = new StandardAnalyzer(org.apache.lucene.util.Version.LUCENE_CURRENT);
IndexWriter iw = new IndexWriter(dir, anlzr,
- IndexWriter.MaxFieldLength.LIMITED);
+ IndexWriter.MaxFieldLength.LIMITED);
// add docs not exactly in natural ID order, to verify we do check the order of docs by scores
int remaining = N_DOCS;
boolean done[] = new boolean[N_DOCS];
int i = 0;
- while (remaining>0) {
+ while (remaining > 0) {
if (done[i]) {
- throw new Exception("to set this test correctly N_DOCS="+N_DOCS+" must be primary and greater than 2!");
+ throw new Exception("to set this test correctly N_DOCS=" + N_DOCS + " must be primary and greater than 2!");
}
- addDoc(iw,i);
+ addDoc(iw, i);
done[i] = true;
- i = (i+4)%N_DOCS;
- remaining --;
+ i = (i + 4) % N_DOCS;
+ remaining--;
}
iw.close();
}
@@ -110,36 +108,36 @@
private void addDoc(IndexWriter iw, int i) throws Exception {
Document d = new Document();
Fieldable f;
- int scoreAndID = i+1;
-
- f = new Field(ID_FIELD,id2String(scoreAndID),Field.Store.YES,Field.Index.NOT_ANALYZED); // for debug purposes
+ int scoreAndID = i + 1;
+
+ f = new Field(ID_FIELD, id2String(scoreAndID), Field.Store.YES, Field.Index.NOT_ANALYZED); // for debug purposes
f.setOmitNorms(true);
d.add(f);
-
- f = new Field(TEXT_FIELD,"text of doc"+scoreAndID+textLine(i),Field.Store.NO,Field.Index.ANALYZED); // for regular search
+
+ f = new Field(TEXT_FIELD, "text of doc" + scoreAndID + textLine(i), Field.Store.NO, Field.Index.ANALYZED); // for regular search
f.setOmitNorms(true);
d.add(f);
-
- f = new Field(INT_FIELD,""+scoreAndID,Field.Store.NO,Field.Index.NOT_ANALYZED); // for function scoring
+
+ f = new Field(INT_FIELD, "" + scoreAndID, Field.Store.NO, Field.Index.NOT_ANALYZED); // for function scoring
f.setOmitNorms(true);
d.add(f);
-
- f = new Field(FLOAT_FIELD,scoreAndID+".000",Field.Store.NO,Field.Index.NOT_ANALYZED); // for function scoring
+
+ f = new Field(FLOAT_FIELD, scoreAndID + ".000", Field.Store.NO, Field.Index.NOT_ANALYZED); // for function scoring
f.setOmitNorms(true);
d.add(f);
iw.addDocument(d);
- log("added: "+d);
+ log("added: " + d);
}
// 17 --> ID00017
protected String id2String(int scoreAndID) {
- String s = "000000000"+scoreAndID;
- int n = (""+N_DOCS).length() + 3;
- int k = s.length() - n;
- return "ID"+s.substring(k);
+ String s = "000000000" + scoreAndID;
+ int n = ("" + N_DOCS).length() + 3;
+ int k = s.length() - n;
+ return "ID" + s.substring(k);
}
-
+
// some text line for regular search
private String textLine(int docNum) {
return DOC_TEXT_LINES[docNum % DOC_TEXT_LINES.length];
@@ -147,11 +145,11 @@
// extract expected doc score from its ID Field: "ID7" --> 7.0
protected float expectedFieldScore(String docIDFieldVal) {
- return Float.parseFloat(docIDFieldVal.substring(2));
+ return Float.parseFloat(docIDFieldVal.substring(2));
}
-
+
// debug messages (change DBG to true for anything to print)
- protected void log (Object o) {
+ protected void log(Object o) {
if (DBG) {
System.out.println(o.toString());
}
Index: src/test/org/apache/lucene/search/function/JustCompileSearchSpans.java
===================================================================
--- src/test/org/apache/lucene/search/function/JustCompileSearchSpans.java (revision 836300)
+++ src/test/org/apache/lucene/search/function/JustCompileSearchSpans.java (working copy)
@@ -17,11 +17,11 @@
* limitations under the License.
*/
-import java.io.IOException;
-
import org.apache.lucene.index.IndexReader;
import org.apache.lucene.search.FieldCache;
+import java.io.IOException;
+
/**
* Holds all implementations of classes in the o.a.l.s.function package as a
* back-compatibility test. It does not run any tests per-se, however if
@@ -34,7 +34,6 @@
private static final String UNSUPPORTED_MSG = "unsupported: used for back-compat testing only !";
static final class JustCompileDocValues extends DocValues {
-
@Override
public float floatVal(int doc) {
throw new UnsupportedOperationException(UNSUPPORTED_MSG);
@@ -44,7 +43,7 @@
public String toString(int doc) {
throw new UnsupportedOperationException(UNSUPPORTED_MSG);
}
-
+
}
static final class JustCompileFieldCacheSource extends FieldCacheSource {
@@ -65,14 +64,13 @@
@Override
public DocValues getCachedFieldValues(FieldCache cache, String field,
- IndexReader reader) throws IOException {
+ IndexReader reader) throws IOException {
throw new UnsupportedOperationException(UNSUPPORTED_MSG);
}
-
+
}
static final class JustCompileValueSource extends ValueSource {
-
@Override
public String description() {
throw new UnsupportedOperationException(UNSUPPORTED_MSG);
@@ -92,7 +90,7 @@
public int hashCode() {
throw new UnsupportedOperationException(UNSUPPORTED_MSG);
}
-
+
}
-
+
}
Index: src/test/org/apache/lucene/search/function/TestCustomScoreQuery.java
===================================================================
--- src/test/org/apache/lucene/search/function/TestCustomScoreQuery.java (revision 836300)
+++ src/test/org/apache/lucene/search/function/TestCustomScoreQuery.java (working copy)
@@ -17,99 +17,113 @@
* limitations under the License.
*/
+import org.apache.lucene.queryParser.QueryParser;
+import org.apache.lucene.queryParser.ParseException;
+import org.apache.lucene.search.*;
+import org.apache.lucene.util.Version;
+import org.junit.Test;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
import java.io.IOException;
import java.util.HashMap;
-import java.util.Iterator;
-import org.apache.lucene.index.CorruptIndexException;
-import org.apache.lucene.queryParser.QueryParser;
-import org.apache.lucene.search.Explanation;
-import org.apache.lucene.search.IndexSearcher;
-import org.apache.lucene.search.Query;
-import org.apache.lucene.search.QueryUtils;
-import org.apache.lucene.search.TopDocs;
-import org.apache.lucene.util.Version;
-
/**
* Test CustomScoreQuery search.
*/
+@SuppressWarnings({"MagicNumber"})
public class TestCustomScoreQuery extends FunctionTestSetup {
- /* @override constructor */
- public TestCustomScoreQuery(String name) {
- super(name);
- }
- /** Test that CustomScoreQuery of Type.BYTE returns the expected scores. */
- public void testCustomScoreByte () throws CorruptIndexException, Exception {
+ /**
+ * Test that CustomScoreQuery of Type.BYTE returns the expected scores.
+ */
+ @Test
+ public void testCustomScoreByte() throws IOException, ParseException {
// INT field values are small enough to be parsed as byte
- doTestCustomScore(INT_FIELD,FieldScoreQuery.Type.BYTE,1.0);
- doTestCustomScore(INT_FIELD,FieldScoreQuery.Type.BYTE,2.0);
+ doTestCustomScore(INT_FIELD, FieldScoreQuery.Type.BYTE, 1.0);
+ doTestCustomScore(INT_FIELD, FieldScoreQuery.Type.BYTE, 2.0);
}
- /** Test that CustomScoreQuery of Type.SHORT returns the expected scores. */
- public void testCustomScoreShort () throws CorruptIndexException, Exception {
+ /**
+ * Test that CustomScoreQuery of Type.SHORT returns the expected scores.
+ */
+ @Test
+ public void testCustomScoreShort() throws IOException, ParseException {
// INT field values are small enough to be parsed as short
- doTestCustomScore(INT_FIELD,FieldScoreQuery.Type.SHORT,1.0);
- doTestCustomScore(INT_FIELD,FieldScoreQuery.Type.SHORT,3.0);
+ doTestCustomScore(INT_FIELD, FieldScoreQuery.Type.SHORT, 1.0);
+ doTestCustomScore(INT_FIELD, FieldScoreQuery.Type.SHORT, 3.0);
}
- /** Test that CustomScoreQuery of Type.INT returns the expected scores. */
- public void testCustomScoreInt () throws CorruptIndexException, Exception {
- doTestCustomScore(INT_FIELD,FieldScoreQuery.Type.INT,1.0);
- doTestCustomScore(INT_FIELD,FieldScoreQuery.Type.INT,4.0);
+ /**
+ * Test that CustomScoreQuery of Type.INT returns the expected scores.
+ */
+ @Test
+ public void testCustomScoreInt() throws IOException, ParseException {
+ doTestCustomScore(INT_FIELD, FieldScoreQuery.Type.INT, 1.0);
+ doTestCustomScore(INT_FIELD, FieldScoreQuery.Type.INT, 4.0);
}
- /** Test that CustomScoreQuery of Type.FLOAT returns the expected scores. */
- public void testCustomScoreFloat () throws CorruptIndexException, Exception {
+ /**
+ * Test that CustomScoreQuery of Type.FLOAT returns the expected scores.
+ */
+ @Test
+ public void testCustomScoreFloat() throws IOException, ParseException {
// INT field can be parsed as float
- doTestCustomScore(INT_FIELD,FieldScoreQuery.Type.FLOAT,1.0);
- doTestCustomScore(INT_FIELD,FieldScoreQuery.Type.FLOAT,5.0);
+ doTestCustomScore(INT_FIELD, FieldScoreQuery.Type.FLOAT, 1.0);
+ doTestCustomScore(INT_FIELD, FieldScoreQuery.Type.FLOAT, 5.0);
// same values, but in flot format
- doTestCustomScore(FLOAT_FIELD,FieldScoreQuery.Type.FLOAT,1.0);
- doTestCustomScore(FLOAT_FIELD,FieldScoreQuery.Type.FLOAT,6.0);
+ doTestCustomScore(FLOAT_FIELD, FieldScoreQuery.Type.FLOAT, 1.0);
+ doTestCustomScore(FLOAT_FIELD, FieldScoreQuery.Type.FLOAT, 6.0);
}
// must have static class otherwise serialization tests fail
+ @SuppressWarnings({"SerializableHasSerializationMethods", "serial"})
private static class CustomAddQuery extends CustomScoreQuery {
// constructor
- CustomAddQuery (Query q, ValueSourceQuery qValSrc) {
- super(q,qValSrc);
+ CustomAddQuery(Query q, ValueSourceQuery qValSrc) {
+ super(q, qValSrc);
}
+
/*(non-Javadoc) @see org.apache.lucene.search.function.CustomScoreQuery#name() */
@Override
public String name() {
return "customAdd";
}
+
/*(non-Javadoc) @see org.apache.lucene.search.function.CustomScoreQuery#customScore(int, float, float) */
@Override
public float customScore(int doc, float subQueryScore, float valSrcScore) {
return subQueryScore + valSrcScore;
}
+
/* (non-Javadoc)@see org.apache.lucene.search.function.CustomScoreQuery#customExplain(int, org.apache.lucene.search.Explanation, org.apache.lucene.search.Explanation)*/
@Override
public Explanation customExplain(int doc, Explanation subQueryExpl, Explanation valSrcExpl) {
- float valSrcScore = valSrcExpl==null ? 0 : valSrcExpl.getValue();
- Explanation exp = new Explanation( valSrcScore + subQueryExpl.getValue(), "custom score: sum of:");
+ float valSrcScore = valSrcExpl == null ? 0 : valSrcExpl.getValue();
+ Explanation exp = new Explanation(valSrcScore + subQueryExpl.getValue(), "custom score: sum of:");
exp.addDetail(subQueryExpl);
if (valSrcExpl != null) {
exp.addDetail(valSrcExpl);
}
- return exp;
- }
+ return exp;
+ }
}
-
+
// must have static class otherwise serialization tests fail
+ @SuppressWarnings({"SerializableHasSerializationMethods", "serial"})
private static class CustomMulAddQuery extends CustomScoreQuery {
// constructor
CustomMulAddQuery(Query q, ValueSourceQuery qValSrc1, ValueSourceQuery qValSrc2) {
- super(q,new ValueSourceQuery[]{qValSrc1,qValSrc2});
+ super(q, new ValueSourceQuery[]{qValSrc1, qValSrc2});
}
+
/*(non-Javadoc) @see org.apache.lucene.search.function.CustomScoreQuery#name() */
@Override
public String name() {
return "customMulAdd";
}
+
/*(non-Javadoc) @see org.apache.lucene.search.function.CustomScoreQuery#customScore(int, float, float) */
@Override
public float customScore(int doc, float subQueryScore, float valSrcScores[]) {
@@ -120,7 +134,8 @@
return subQueryScore + valSrcScores[0];
}
return (subQueryScore + valSrcScores[0]) * valSrcScores[1]; // we know there are two
- }
+ }
+
/* (non-Javadoc)@see org.apache.lucene.search.function.CustomScoreQuery#customExplain(int, org.apache.lucene.search.Explanation, org.apache.lucene.search.Explanation)*/
@Override
public Explanation customExplain(int doc, Explanation subQueryExpl, Explanation valSrcExpls[]) {
@@ -137,121 +152,123 @@
Explanation exp2 = new Explanation(valSrcExpls[1].getValue() * exp.getValue(), "custom score: product of:");
exp2.addDetail(valSrcExpls[1]);
exp2.addDetail(exp);
- return exp2;
- }
+ return exp2;
+ }
}
-
+
// Test that FieldScoreQuery returns docs with expected score.
- private void doTestCustomScore (String field, FieldScoreQuery.Type tp, double dboost) throws CorruptIndexException, Exception {
+ private void doTestCustomScore(String field, FieldScoreQuery.Type tp, double dboost) throws IOException, ParseException {
float boost = (float) dboost;
IndexSearcher s = new IndexSearcher(dir, true);
- FieldScoreQuery qValSrc = new FieldScoreQuery(field,tp); // a query that would score by the field
- QueryParser qp = new QueryParser(Version.LUCENE_CURRENT, TEXT_FIELD,anlzr);
+ FieldScoreQuery qValSrc = new FieldScoreQuery(field, tp); // a query that would score by the field
+ QueryParser qp = new QueryParser(Version.LUCENE_CURRENT, TEXT_FIELD, anlzr);
String qtxt = "first aid text"; // from the doc texts in FunctionQuerySetup.
-
+
// regular (boolean) query.
- Query q1 = qp.parse(qtxt);
+ Query q1 = qp.parse(qtxt);
log(q1);
-
+
// custom query, that should score the same as q1.
- CustomScoreQuery q2CustomNeutral = new CustomScoreQuery(q1);
+ Query q2CustomNeutral = new CustomScoreQuery(q1);
q2CustomNeutral.setBoost(boost);
log(q2CustomNeutral);
-
+
// custom query, that should (by default) multiply the scores of q1 by that of the field
- CustomScoreQuery q3CustomMul = new CustomScoreQuery(q1,qValSrc);
+ CustomScoreQuery q3CustomMul = new CustomScoreQuery(q1, qValSrc);
q3CustomMul.setStrict(true);
q3CustomMul.setBoost(boost);
log(q3CustomMul);
-
+
// custom query, that should add the scores of q1 to that of the field
- CustomScoreQuery q4CustomAdd = new CustomAddQuery(q1,qValSrc);
+ CustomScoreQuery q4CustomAdd = new CustomAddQuery(q1, qValSrc);
q4CustomAdd.setStrict(true);
q4CustomAdd.setBoost(boost);
log(q4CustomAdd);
// custom query, that multiplies and adds the field score to that of q1
- CustomScoreQuery q5CustomMulAdd = new CustomMulAddQuery(q1,qValSrc,qValSrc);
+ CustomScoreQuery q5CustomMulAdd = new CustomMulAddQuery(q1, qValSrc, qValSrc);
q5CustomMulAdd.setStrict(true);
q5CustomMulAdd.setBoost(boost);
log(q5CustomMulAdd);
// do al the searches
- TopDocs td1 = s.search(q1,null,1000);
- TopDocs td2CustomNeutral = s.search(q2CustomNeutral,null,1000);
- TopDocs td3CustomMul = s.search(q3CustomMul,null,1000);
- TopDocs td4CustomAdd = s.search(q4CustomAdd,null,1000);
- TopDocs td5CustomMulAdd = s.search(q5CustomMulAdd,null,1000);
-
+ TopDocs td1 = s.search(q1, null, 1000);
+ TopDocs td2CustomNeutral = s.search(q2CustomNeutral, null, 1000);
+ TopDocs td3CustomMul = s.search(q3CustomMul, null, 1000);
+ TopDocs td4CustomAdd = s.search(q4CustomAdd, null, 1000);
+ TopDocs td5CustomMulAdd = s.search(q5CustomMulAdd, null, 1000);
+
// put results in map so we can verify the scores although they have changed
- HashMap h1 = topDocsToMap(td1);
- HashMap h2CustomNeutral = topDocsToMap(td2CustomNeutral);
- HashMap h3CustomMul = topDocsToMap(td3CustomMul);
- HashMap h4CustomAdd = topDocsToMap(td4CustomAdd);
- HashMap h5CustomMulAdd = topDocsToMap(td5CustomMulAdd);
-
- verifyResults(boost, s,
- h1, h2CustomNeutral, h3CustomMul, h4CustomAdd, h5CustomMulAdd,
- q1, q2CustomNeutral, q3CustomMul, q4CustomAdd, q5CustomMulAdd);
+ HashMap h1 = topDocsToMap(td1);
+ HashMap h2CustomNeutral = topDocsToMap(td2CustomNeutral);
+ HashMap h3CustomMul = topDocsToMap(td3CustomMul);
+ HashMap h4CustomAdd = topDocsToMap(td4CustomAdd);
+ HashMap h5CustomMulAdd = topDocsToMap(td5CustomMulAdd);
+
+ verifyResults(boost, s,
+ h1, h2CustomNeutral, h3CustomMul, h4CustomAdd, h5CustomMulAdd,
+ q1, q2CustomNeutral, q3CustomMul, q4CustomAdd, q5CustomMulAdd);
}
-
+
// verify results are as expected.
- private void verifyResults(float boost, IndexSearcher s,
- HashMap h1, HashMap h2customNeutral, HashMap h3CustomMul, HashMap h4CustomAdd, HashMap h5CustomMulAdd,
- Query q1, Query q2, Query q3, Query q4, Query q5) throws Exception {
-
+ private void verifyResults(float boost, IndexSearcher s,
+ HashMap h1, HashMap h2customNeutral,
+ HashMap h3CustomMul, HashMap h4CustomAdd,
+ HashMap h5CustomMulAdd,
+ Query q1, Query q2, Query q3, Query q4, Query q5) throws IOException {
+
// verify numbers of matches
- log("#hits = "+h1.size());
- assertEquals("queries should have same #hits",h1.size(),h2customNeutral.size());
- assertEquals("queries should have same #hits",h1.size(),h3CustomMul.size());
- assertEquals("queries should have same #hits",h1.size(),h4CustomAdd.size());
- assertEquals("queries should have same #hits",h1.size(),h5CustomMulAdd.size());
-
+ log("#hits = " + h1.size());
+ assertEquals("queries should have same #hits", h1.size(), h2customNeutral.size());
+ assertEquals("queries should have same #hits", h1.size(), h3CustomMul.size());
+ assertEquals("queries should have same #hits", h1.size(), h4CustomAdd.size());
+ assertEquals("queries should have same #hits", h1.size(), h5CustomMulAdd.size());
+
+
// verify scores ratios
- for (Iterator it = h1.keySet().iterator(); it.hasNext();) {
- Integer x = (Integer) it.next();
+ for (int x : h1.keySet()) {
- int doc = x.intValue();
- log("doc = "+doc);
+ log("doc = " + x);
- float fieldScore = expectedFieldScore(s.getIndexReader().document(doc).get(ID_FIELD));
- log("fieldScore = "+fieldScore);
- assertTrue("fieldScore should not be 0",fieldScore>0);
+ float fieldScore = expectedFieldScore(s.getIndexReader().document(x).get(ID_FIELD));
+ log("fieldScore = " + fieldScore);
+ assertTrue("fieldScore should not be 0", fieldScore > 0);
- float score1 = ((Float)h1.get(x)).floatValue();
- logResult("score1=", s, q1, doc, score1);
-
- float score2 = ((Float)h2customNeutral.get(x)).floatValue();
- logResult("score2=", s, q2, doc, score2);
+ float score1 = h1.get(x);
+ logResult("score1=", s, q1, x, score1);
+
+ float score2 = h2customNeutral.get(x);
+ logResult("score2=", s, q2, x, score2);
assertEquals("same score (just boosted) for neutral", boost * score1, score2, TEST_SCORE_TOLERANCE_DELTA);
- float score3 = ((Float)h3CustomMul.get(x)).floatValue();
- logResult("score3=", s, q3, doc, score3);
+ float score3 = h3CustomMul.get(x);
+ logResult("score3=", s, q3, x, score3);
assertEquals("new score for custom mul", boost * fieldScore * score1, score3, TEST_SCORE_TOLERANCE_DELTA);
-
- float score4 = ((Float)h4CustomAdd.get(x)).floatValue();
- logResult("score4=", s, q4, doc, score4);
+
+ float score4 = h4CustomAdd.get(x);
+ logResult("score4=", s, q4, x, score4);
assertEquals("new score for custom add", boost * (fieldScore + score1), score4, TEST_SCORE_TOLERANCE_DELTA);
-
- float score5 = ((Float)h5CustomMulAdd.get(x)).floatValue();
- logResult("score5=", s, q5, doc, score5);
+
+ float score5 = h5CustomMulAdd.get(x);
+ logResult("score5=", s, q5, x, score5);
assertEquals("new score for custom mul add", boost * fieldScore * (score1 + fieldScore), score5, TEST_SCORE_TOLERANCE_DELTA);
}
}
- private void logResult(String msg, IndexSearcher s, Query q, int doc, float score1) throws IOException {
- QueryUtils.check(q,s);
- log(msg+" "+score1);
- log("Explain by: "+q);
- log(s.explain(q,doc));
+
+ private void logResult(String msg, Searcher s, Query q, int doc, float score1) throws IOException {
+ QueryUtils.check(q, s);
+ log(msg + " " + score1);
+ log("Explain by: " + q);
+ log(s.explain(q, doc));
}
// since custom scoring modifies the order of docs, map results
// by doc ids so that we can later compare/verify them
- private HashMap topDocsToMap(TopDocs td) {
- HashMap h = new HashMap();
- for (int i=0; i topDocsToMap(TopDocs td) {
+ HashMap h = new HashMap();
+ for (int i = 0; i < td.totalHits; i++) {
+ h.put(td.scoreDocs[i].doc, td.scoreDocs[i].score);
}
return h;
}
Index: src/test/org/apache/lucene/util/LuceneTestCaseJ4.java
===================================================================
--- src/test/org/apache/lucene/util/LuceneTestCaseJ4.java (revision 0)
+++ src/test/org/apache/lucene/util/LuceneTestCaseJ4.java (revision 0)
@@ -0,0 +1,254 @@
+package org.apache.lucene.util;
+
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import org.apache.lucene.index.ConcurrentMergeScheduler;
+import org.apache.lucene.search.FieldCache;
+import org.apache.lucene.search.FieldCache.CacheEntry;
+import org.apache.lucene.util.FieldCacheSanityChecker.Insanity;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.rules.TestWatchman;
+
+import java.io.PrintStream;
+import java.util.Arrays;
+import java.util.Iterator;
+import java.util.Random;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.fail;
+
+/**
+ * Base class for all Lucene unit tests, Junit4 variant.
+ * Replaces LuceneTestCase.
+ *
+ *
+ *
+ * If you
+ * override either setUp() or
+ * tearDown() in your unit test, make sure you
+ * call super.setUp() and
+ * super.tearDown()
+ *
+ *
+ * @After - replaces setup
+ * @Before - replaces teardown
+ * @Test - any public method with this annotation is a test case, regardless
+ * of its name
+ *
+ *
+ * See Junit4 documentation for a complete list of features at
+ * http://junit.org/junit/javadoc/4.7/
+ *
+ * Import from org.junit rather than junit.framework.
+ *
+ * You should be able to use this class anywhere you used LuceneTestCase
+ * if you annotate your derived class correctly with the annotations above
+ * @see assertSaneFieldCaches
+ *
+ */
+
+
+// If we really need functionality in runBare override from LuceneTestCase,
+// we can introduce RunBareWrapper and override runChild, and add the
+// @RunWith annotation as below. runChild will be called for
+// every test. But the functionality we used to
+// get from that override is provided by InterceptTestCaseEvents
+//@RunWith(RunBareWrapper.class)
+public class LuceneTestCaseJ4 extends TestWatchman {
+
+ // This is how we get control when errors occur.
+ // Think of this as start/end/success/failed
+ // events.
+ @Rule
+ public InterceptTestCaseEvents intercept = new InterceptTestCaseEvents(this);
+
+ public LuceneTestCaseJ4() {
+ }
+
+ public LuceneTestCaseJ4(String name) {
+ this.name = name;
+ }
+
+ @Before
+ public void setUp() throws Exception {
+ ConcurrentMergeScheduler.setTestMode();
+ seed = null;
+ }
+
+
+ /**
+ * Forcible purges all cache entries from the FieldCache.
+ *
+ * This method will be called by tearDown to clean up FieldCache.DEFAULT.
+ * If a (poorly written) test has some expectation that the FieldCache
+ * will persist across test methods (ie: a static IndexReader) this
+ * method can be overridden to do nothing.
+ *
+ *
+ * @see FieldCache#purgeAllCaches()
+ */
+ protected void purgeFieldCache(final FieldCache fc) {
+ fc.purgeAllCaches();
+ }
+
+ protected String getTestLabel() {
+ return getClass().getName() + "." + getName();
+ }
+
+ @After
+ public void tearDown() throws Exception {
+ try {
+ // this isn't as useful as calling directly from the scope where the
+ // index readers are used, because they could be gc'ed just before
+ // tearDown is called.
+ // But it's better then nothing.
+ assertSaneFieldCaches(getTestLabel());
+
+ if (ConcurrentMergeScheduler.anyUnhandledExceptions()) {
+ // Clear the failure so that we don't just keep
+ // failing subsequent test cases
+ ConcurrentMergeScheduler.clearUnhandledExceptions();
+ fail("ConcurrentMergeScheduler hit unhandled exceptions");
+ }
+ } finally {
+ purgeFieldCache(FieldCache.DEFAULT);
+ }
+ }
+
+ /**
+ * Asserts that FieldCacheSanityChecker does not detect any
+ * problems with FieldCache.DEFAULT.
+ *
+ * If any problems are found, they are logged to System.err
+ * (allong with the msg) when the Assertion is thrown.
+ *
+ *
+ * This method is called by tearDown after every test method,
+ * however IndexReaders scoped inside test methods may be garbage
+ * collected prior to this method being called, causing errors to
+ * be overlooked. Tests are encouraged to keep their IndexReaders
+ * scoped at the class level, or to explicitly call this method
+ * directly in the same scope as the IndexReader.
+ *
+ *
+ * @see FieldCacheSanityChecker
+ */
+ protected void assertSaneFieldCaches(final String msg) {
+ final CacheEntry[] entries = FieldCache.DEFAULT.getCacheEntries();
+ Insanity[] insanity = null;
+ try {
+ try {
+ insanity = FieldCacheSanityChecker.checkSanity(entries);
+ } catch (RuntimeException e) {
+ dumpArray(msg + ": FieldCache", entries, System.err);
+ throw e;
+ }
+
+ assertEquals(msg + ": Insane FieldCache usage(s) found",
+ 0, insanity.length);
+ insanity = null;
+ } finally {
+
+ // report this in the event of any exception/failure
+ // if no failure, then insanity will be null anyway
+ if (null != insanity) {
+ dumpArray(msg + ": Insane FieldCache usage(s)", insanity, System.err);
+ }
+
+ }
+ }
+
+ /**
+ * Convinience method for logging an iterator.
+ *
+ * @param label String logged before/after the items in the iterator
+ * @param iter Each next() is toString()ed and logged on it's own line. If iter is null this is logged differnetly then an empty iterator.
+ * @param stream Stream to log messages to.
+ */
+ public static void dumpIterator(String label, Iterator iter,
+ PrintStream stream) {
+ stream.println("*** BEGIN " + label + " ***");
+ if (null == iter) {
+ stream.println(" ... NULL ...");
+ } else {
+ while (iter.hasNext()) {
+ stream.println(iter.next().toString());
+ }
+ }
+ stream.println("*** END " + label + " ***");
+ }
+
+ /**
+ * Convinience method for logging an array. Wraps the array in an iterator and delegates
+ *
+ * @see dumpIterator(String,Iterator,PrintStream)
+ */
+ public static void dumpArray(String label, Object[] objs,
+ PrintStream stream) {
+ Iterator iter = (null == objs) ? null : Arrays.asList(objs).iterator();
+ dumpIterator(label, iter, stream);
+ }
+
+ /**
+ * Returns a {@link Random} instance for generating random numbers during the test.
+ * The random seed is logged during test execution and printed to System.out on any failure
+ * for reproducing the test using {@link #newRandom(long)} with the recorded seed
+ * .
+ */
+ public Random newRandom() {
+ if (seed != null) {
+ throw new IllegalStateException("please call LuceneTestCase.newRandom only once per test");
+ }
+ return newRandom(seedRnd.nextLong());
+ }
+
+ /**
+ * Returns a {@link Random} instance for generating random numbers during the test.
+ * If an error occurs in the test that is not reproducible, you can use this method to
+ * initialize the number generator with the seed that was printed out during the failing test.
+ */
+ public Random newRandom(long seed) {
+ if (this.seed != null) {
+ throw new IllegalStateException("please call LuceneTestCase.newRandom only once per test");
+ }
+ this.seed = Long.valueOf(seed);
+ return new Random(seed);
+ }
+
+ public String getName() {
+ return this.name;
+ }
+
+ // We get here fro InterceptTestCaseEvents on the 'failed' event....
+ public void reportAdditionalFailureInfo() {
+ if (seed != null) {
+ System.out.println("NOTE: random seed of testcase '" + getName() + "' was: " + seed);
+ }
+ }
+
+ // recorded seed
+ protected Long seed = null;
+
+ // static members
+ private static final Random seedRnd = new Random();
+
+ private String name = "";
+
+}
Index: src/test/org/apache/lucene/util/LuceneTestCase.java
===================================================================
--- src/test/org/apache/lucene/util/LuceneTestCase.java (revision 836280)
+++ src/test/org/apache/lucene/util/LuceneTestCase.java (working copy)
@@ -47,7 +47,11 @@
* super.tearDown()
*
* @see #assertSaneFieldCaches
+ *
+ * @deprecated Replaced by {@link #LuceneTestCaseJ4}
+ *
*/
+@Deprecated
public abstract class LuceneTestCase extends TestCase {
public LuceneTestCase() {
Index: src/test/org/apache/lucene/util/InterceptTestCaseEvents.java
===================================================================
--- src/test/org/apache/lucene/util/InterceptTestCaseEvents.java (revision 0)
+++ src/test/org/apache/lucene/util/InterceptTestCaseEvents.java (revision 0)
@@ -0,0 +1,60 @@
+package org.apache.lucene.util;
+
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+import org.junit.rules.TestWatchman;
+import org.junit.runners.model.FrameworkMethod;
+
+import java.lang.reflect.Method;
+
+
+public final class InterceptTestCaseEvents extends TestWatchman {
+ private Object obj;
+
+ public InterceptTestCaseEvents(Object obj) {
+ this.obj = obj;
+ }
+
+ @Override
+ public void failed(Throwable e, FrameworkMethod method) {
+ try {
+ Method reporter = method.getMethod().getDeclaringClass().getMethod("reportAdditionalFailureInfo",(Class>[]) null);
+ reporter.invoke(obj, (Object[])null);
+ } catch (Exception e1) {
+ System.err.println("InterceptTestCaseEvents.failed(). Cannot invoke reportAdditionalFailureInfo() method in" +
+ " consuming class, is it declared and public?");
+ }
+ super.failed(e, method);
+ }
+
+ @Override
+ public void finished(FrameworkMethod method) {
+ super.finished(method);
+ }
+
+ @Override
+ public void starting(FrameworkMethod method) {
+ super.starting(method);
+ }
+
+ @Override
+ public void succeeded(FrameworkMethod method) {
+ super.succeeded(method);
+ }
+}