Index: contrib/queries/src/test/org/apache/lucene/search/trie/TestTrieRangeQuery.java =================================================================== --- contrib/queries/src/test/org/apache/lucene/search/trie/TestTrieRangeQuery.java (revision 740444) +++ contrib/queries/src/test/org/apache/lucene/search/trie/TestTrieRangeQuery.java (working copy) @@ -36,11 +36,10 @@ { private static final long distance=66666; - private static Random rnd=new Random(); - private static RAMDirectory directory; - private static IndexSearcher searcher; + private static final RAMDirectory directory; + private static final IndexSearcher searcher; static { - try { + try { directory = new RAMDirectory(); IndexWriter writer = new IndexWriter(directory, new WhitespaceAnalyzer(), true, MaxFieldLength.UNLIMITED); @@ -136,6 +135,7 @@ } private void testRandomTrieAndClassicRangeQuery(final TrieUtils variant) throws Exception { + final Random rnd=newRandom(); String field="field"+variant.TRIE_BITS; // 50 random tests, the tests may also return 0 results, if min>max, but this is ok for (int i=0; i<50; i++) { @@ -185,6 +185,7 @@ } private void testRangeSplit(final TrieUtils variant) throws Exception { + final Random rnd=newRandom(); String field="ascfield"+variant.TRIE_BITS; // 50 random tests for (int i=0; i<50; i++) { @@ -225,6 +226,7 @@ } private void testSorting(final TrieUtils variant) throws Exception { + final Random rnd=newRandom(); String field="field"+variant.TRIE_BITS; // 10 random tests, the index order is ascending, // so using a reverse sort field should retun descending documents Index: src/test/org/apache/lucene/util/LuceneTestCase.java =================================================================== --- src/test/org/apache/lucene/util/LuceneTestCase.java (revision 740441) +++ src/test/org/apache/lucene/util/LuceneTestCase.java (working copy) @@ -20,6 +20,7 @@ import org.apache.lucene.analysis.TokenStream; import org.apache.lucene.index.ConcurrentMergeScheduler; import junit.framework.TestCase; +import java.util.Random; /** Base class for all Lucene unit tests. Currently the * only added functionality over JUnit's TestCase is @@ -54,4 +55,41 @@ fail("ConcurrentMergeScheduler hit unhandled exceptions"); } } + + /** + * 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 #getRandom(long)} with the recorded seed + *. + */ + public Random newRandom() { + 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) { + this.seed=new Long(seed); + return new Random(seed); + } + + protected void runTest() throws Throwable { + try { + super.runTest(); + } catch (Throwable e) { + if (seed!=null) { + System.out.println("Random seed of test '"+getName()+"' was: "+seed); + } + throw e; + } + } + + // recorded seed + protected Long seed=null; + + // static members + private static final Random seedRnd=new Random(); }