You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@lucene.apache.org by rm...@apache.org on 2020/01/29 19:44:49 UTC

[lucene-solr] branch branch_8x updated: LUCENE-9192: speed up more slow tests

This is an automated email from the ASF dual-hosted git repository.

rmuir pushed a commit to branch branch_8x
in repository https://gitbox.apache.org/repos/asf/lucene-solr.git


The following commit(s) were added to refs/heads/branch_8x by this push:
     new e258ab3  LUCENE-9192: speed up more slow tests
e258ab3 is described below

commit e258ab32f0dffeaaf1c27b4ea824028864e83674
Author: Robert Muir <rm...@apache.org>
AuthorDate: Wed Jan 29 14:30:31 2020 -0500

    LUCENE-9192: speed up more slow tests
---
 .../lucene/analysis/core/TestDuelingAnalyzers.java | 26 ++++---
 .../src/java/org/apache/lucene/util/BitUtil.java   | 60 ++++++++-------
 .../lucene/util/packed/DirectMonotonicWriter.java  |  2 +-
 .../compressing/AbstractTestCompressionMode.java   | 40 +++++-----
 .../lucene/codecs/lucene80/TestIndexedDISI.java    | 15 ++--
 .../lucene/document/BaseXYShapeTestCase.java       | 10 ++-
 .../lucene/document/TestXYLineShapeQueries.java    | 16 ++--
 .../document/TestXYMultiPolygonShapeQueries.java   |  2 +-
 .../lucene/document/TestXYPointShapeQueries.java   | 14 ++--
 .../org/apache/lucene/document/TestXYShape.java    | 13 ++--
 .../lucene/document/TestXYShapeEncoding.java       |  4 +-
 .../test/org/apache/lucene/geo/ShapeTestUtil.java  | 55 +++++++-------
 .../test/org/apache/lucene/geo/TestGeoUtils.java   | 42 ++++++-----
 .../test/org/apache/lucene/geo/TestPolygon2D.java  |  3 +-
 .../org/apache/lucene/geo/TestXYRectangle2D.java   | 17 +++--
 .../org/apache/lucene/index/TestByteSlices.java    | 25 ++++---
 .../org/apache/lucene/index/TestTermsEnum.java     |  3 +-
 .../lucene/store/TestByteBuffersDataInput.java     |  2 +-
 .../org/apache/lucene/util/TestPagedBytes.java     | 12 +--
 .../test/org/apache/lucene/util/bkd/TestBKD.java   | 12 +--
 .../lucene/util/packed/TestDirectMonotonic.java    | 18 +++--
 .../lucene/util/packed/TestDirectPacked.java       |  2 +-
 .../apache/lucene/util/packed/TestPackedInts.java  | 87 ++++++++++++----------
 .../org/apache/lucene/analysis/MockTokenizer.java  |  6 +-
 .../org/apache/lucene/util/BaseBitSetTestCase.java | 27 ++++---
 .../apache/lucene/util/BaseDocIdSetTestCase.java   | 24 +++---
 26 files changed, 301 insertions(+), 236 deletions(-)

diff --git a/lucene/analysis/common/src/test/org/apache/lucene/analysis/core/TestDuelingAnalyzers.java b/lucene/analysis/common/src/test/org/apache/lucene/analysis/core/TestDuelingAnalyzers.java
index 689d683..47da6e6 100644
--- a/lucene/analysis/common/src/test/org/apache/lucene/analysis/core/TestDuelingAnalyzers.java
+++ b/lucene/analysis/common/src/test/org/apache/lucene/analysis/core/TestDuelingAnalyzers.java
@@ -33,6 +33,8 @@ import org.apache.lucene.analysis.tokenattributes.PositionIncrementAttribute;
 import org.apache.lucene.util.IOUtils;
 import org.apache.lucene.util.TestUtil;
 import org.apache.lucene.util.automaton.Operations;
+import org.junit.AfterClass;
+import org.junit.BeforeClass;
 import org.apache.lucene.util.automaton.CharacterRunAutomaton;
 import org.apache.lucene.util.automaton.Automaton;
 
@@ -44,11 +46,10 @@ import org.apache.lucene.util.automaton.Automaton;
  * cause false fails).
  */
 public class TestDuelingAnalyzers extends BaseTokenStreamTestCase {
-  private CharacterRunAutomaton jvmLetter;
+  private static CharacterRunAutomaton jvmLetter;
   
-  @Override
-  public void setUp() throws Exception {
-    super.setUp();
+  @BeforeClass
+  public static void beforeClass() throws Exception {
     Automaton single = new Automaton();
     int initial = single.createState();
     int accept = single.createState();
@@ -64,6 +65,11 @@ public class TestDuelingAnalyzers extends BaseTokenStreamTestCase {
     jvmLetter = new CharacterRunAutomaton(repeat);
   }
   
+  @AfterClass
+  public static void afterClass() throws Exception {
+    jvmLetter = null;
+  }
+
   public void testLetterAscii() throws Exception {
     Random random = random();
     Analyzer left = new MockAnalyzer(random, jvmLetter, false);
@@ -74,7 +80,7 @@ public class TestDuelingAnalyzers extends BaseTokenStreamTestCase {
         return new TokenStreamComponents(tokenizer, tokenizer);
       }
     };
-    for (int i = 0; i < 1000; i++) {
+    for (int i = 0; i < 200; i++) {
       String s = TestUtil.randomSimpleString(random);
       assertEquals(s, left.tokenStream("foo", newStringReader(s)), 
                    right.tokenStream("foo", newStringReader(s)));
@@ -95,7 +101,7 @@ public class TestDuelingAnalyzers extends BaseTokenStreamTestCase {
         return new TokenStreamComponents(tokenizer, tokenizer);
       }
     };
-    int numIterations = atLeast(50);
+    int numIterations = atLeast(10);
     for (int i = 0; i < numIterations; i++) {
       String s = TestUtil.randomSimpleString(random, maxLength);
       assertEquals(s, left.tokenStream("foo", newStringReader(s)), 
@@ -114,7 +120,7 @@ public class TestDuelingAnalyzers extends BaseTokenStreamTestCase {
         return new TokenStreamComponents(tokenizer, tokenizer);
       }
     };
-    for (int i = 0; i < 1000; i++) {
+    for (int i = 0; i < 200; i++) {
       String s = TestUtil.randomHtmlishString(random, 20);
       assertEquals(s, left.tokenStream("foo", newStringReader(s)), 
                    right.tokenStream("foo", newStringReader(s)));
@@ -134,7 +140,7 @@ public class TestDuelingAnalyzers extends BaseTokenStreamTestCase {
         return new TokenStreamComponents(tokenizer, tokenizer);
       }
     };
-    int numIterations = atLeast(50);
+    int numIterations = atLeast(10);
     for (int i = 0; i < numIterations; i++) {
       String s = TestUtil.randomHtmlishString(random, maxLength);
       assertEquals(s, left.tokenStream("foo", newStringReader(s)), 
@@ -153,7 +159,7 @@ public class TestDuelingAnalyzers extends BaseTokenStreamTestCase {
         return new TokenStreamComponents(tokenizer, tokenizer);
       }
     };
-    for (int i = 0; i < 1000; i++) {
+    for (int i = 0; i < 200; i++) {
       String s = TestUtil.randomUnicodeString(random);
       assertEquals(s, left.tokenStream("foo", newStringReader(s)), 
                    right.tokenStream("foo", newStringReader(s)));
@@ -173,7 +179,7 @@ public class TestDuelingAnalyzers extends BaseTokenStreamTestCase {
         return new TokenStreamComponents(tokenizer, tokenizer);
       }
     };
-    int numIterations = atLeast(50);
+    int numIterations = atLeast(10);
     for (int i = 0; i < numIterations; i++) {
       String s = TestUtil.randomUnicodeString(random, maxLength);
       assertEquals(s, left.tokenStream("foo", newStringReader(s)), 
diff --git a/lucene/core/src/java/org/apache/lucene/util/BitUtil.java b/lucene/core/src/java/org/apache/lucene/util/BitUtil.java
index f9557bc..a475fe2 100644
--- a/lucene/core/src/java/org/apache/lucene/util/BitUtil.java
+++ b/lucene/core/src/java/org/apache/lucene/util/BitUtil.java
@@ -21,16 +21,6 @@ package org.apache.lucene.util; // from org.apache.solr.util rev 555343
  */
 public final class BitUtil {
 
-  // magic numbers for bit interleaving
-  private static final long MAGIC[] = {
-      0x5555555555555555L, 0x3333333333333333L,
-      0x0F0F0F0F0F0F0F0FL, 0x00FF00FF00FF00FFL,
-      0x0000FFFF0000FFFFL, 0x00000000FFFFFFFFL,
-      0xAAAAAAAAAAAAAAAAL
-  };
-  // shift values for bit interleaving
-  private static final short SHIFT[] = {1, 2, 4, 8, 16};
-
   private BitUtil() {} // no instance
 
   // The pop methods used to rely on bit-manipulation tricks for speed but it
@@ -111,6 +101,22 @@ public final class BitUtil {
     return v;
   }
 
+  // magic numbers for bit interleaving
+  private static final long MAGIC0 = 0x5555555555555555L;
+  private static final long MAGIC1 = 0x3333333333333333L;
+  private static final long MAGIC2 = 0x0F0F0F0F0F0F0F0FL;
+  private static final long MAGIC3 = 0x00FF00FF00FF00FFL;
+  private static final long MAGIC4 = 0x0000FFFF0000FFFFL;
+  private static final long MAGIC5 = 0x00000000FFFFFFFFL;
+  private static final long MAGIC6 = 0xAAAAAAAAAAAAAAAAL;
+
+  // shift values for bit interleaving
+  private static final long SHIFT0 = 1;
+  private static final long SHIFT1 = 2;
+  private static final long SHIFT2 = 4;
+  private static final long SHIFT3 = 8;
+  private static final long SHIFT4 = 16;
+
   /**
    * Interleaves the first 32 bits of each long value
    *
@@ -119,16 +125,16 @@ public final class BitUtil {
   public static long interleave(int even, int odd) {
     long v1 = 0x00000000FFFFFFFFL & even;
     long v2 = 0x00000000FFFFFFFFL & odd;
-    v1 = (v1 | (v1 << SHIFT[4])) & MAGIC[4];
-    v1 = (v1 | (v1 << SHIFT[3])) & MAGIC[3];
-    v1 = (v1 | (v1 << SHIFT[2])) & MAGIC[2];
-    v1 = (v1 | (v1 << SHIFT[1])) & MAGIC[1];
-    v1 = (v1 | (v1 << SHIFT[0])) & MAGIC[0];
-    v2 = (v2 | (v2 << SHIFT[4])) & MAGIC[4];
-    v2 = (v2 | (v2 << SHIFT[3])) & MAGIC[3];
-    v2 = (v2 | (v2 << SHIFT[2])) & MAGIC[2];
-    v2 = (v2 | (v2 << SHIFT[1])) & MAGIC[1];
-    v2 = (v2 | (v2 << SHIFT[0])) & MAGIC[0];
+    v1 = (v1 | (v1 << SHIFT4)) & MAGIC4;
+    v1 = (v1 | (v1 << SHIFT3)) & MAGIC3;
+    v1 = (v1 | (v1 << SHIFT2)) & MAGIC2;
+    v1 = (v1 | (v1 << SHIFT1)) & MAGIC1;
+    v1 = (v1 | (v1 << SHIFT0)) & MAGIC0;
+    v2 = (v2 | (v2 << SHIFT4)) & MAGIC4;
+    v2 = (v2 | (v2 << SHIFT3)) & MAGIC3;
+    v2 = (v2 | (v2 << SHIFT2)) & MAGIC2;
+    v2 = (v2 | (v2 << SHIFT1)) & MAGIC1;
+    v2 = (v2 | (v2 << SHIFT0)) & MAGIC0;
 
     return (v2<<1) | v1;
   }
@@ -137,12 +143,12 @@ public final class BitUtil {
    * Extract just the even-bits value as a long from the bit-interleaved value
    */
   public static long deinterleave(long b) {
-    b &= MAGIC[0];
-    b = (b ^ (b >>> SHIFT[0])) & MAGIC[1];
-    b = (b ^ (b >>> SHIFT[1])) & MAGIC[2];
-    b = (b ^ (b >>> SHIFT[2])) & MAGIC[3];
-    b = (b ^ (b >>> SHIFT[3])) & MAGIC[4];
-    b = (b ^ (b >>> SHIFT[4])) & MAGIC[5];
+    b &= MAGIC0;
+    b = (b ^ (b >>> SHIFT0)) & MAGIC1;
+    b = (b ^ (b >>> SHIFT1)) & MAGIC2;
+    b = (b ^ (b >>> SHIFT2)) & MAGIC3;
+    b = (b ^ (b >>> SHIFT3)) & MAGIC4;
+    b = (b ^ (b >>> SHIFT4)) & MAGIC5;
     return b;
   }
 
@@ -150,7 +156,7 @@ public final class BitUtil {
    * flip flops odd with even bits
    */
   public static final long flipFlop(final long b) {
-    return ((b & MAGIC[6]) >>> 1) | ((b & MAGIC[0]) << 1 );
+    return ((b & MAGIC6) >>> 1) | ((b & MAGIC0) << 1 );
   }
 
    /** Same as {@link #zigZagEncode(long)} but on integers. */
diff --git a/lucene/core/src/java/org/apache/lucene/util/packed/DirectMonotonicWriter.java b/lucene/core/src/java/org/apache/lucene/util/packed/DirectMonotonicWriter.java
index 2e8fc08..04dfdb9 100644
--- a/lucene/core/src/java/org/apache/lucene/util/packed/DirectMonotonicWriter.java
+++ b/lucene/core/src/java/org/apache/lucene/util/packed/DirectMonotonicWriter.java
@@ -62,7 +62,7 @@ public final class DirectMonotonicWriter {
     this.data = dataOut;
     this.numValues = numValues;
     final int blockSize = 1 << blockShift;
-    this.buffer = new long[blockSize];
+    this.buffer = new long[(int) Math.min(numValues, blockSize)];
     this.bufferSize = 0;
     this.baseDataPointer = dataOut.getFilePointer();
   }
diff --git a/lucene/core/src/test/org/apache/lucene/codecs/compressing/AbstractTestCompressionMode.java b/lucene/core/src/test/org/apache/lucene/codecs/compressing/AbstractTestCompressionMode.java
index 4b47274..11f10d3 100644
--- a/lucene/core/src/test/org/apache/lucene/codecs/compressing/AbstractTestCompressionMode.java
+++ b/lucene/core/src/test/org/apache/lucene/codecs/compressing/AbstractTestCompressionMode.java
@@ -19,6 +19,7 @@ package org.apache.lucene.codecs.compressing;
 
 import java.io.IOException;
 import java.util.Arrays;
+import java.util.Random;
 
 import org.apache.lucene.store.ByteArrayDataInput;
 import org.apache.lucene.store.ByteArrayDataOutput;
@@ -33,20 +34,21 @@ public abstract class AbstractTestCompressionMode extends LuceneTestCase {
 
   CompressionMode mode;
 
-  static byte[] randomArray() {
-    final int max = random().nextBoolean()
-        ? random().nextInt(4)
-        : random().nextInt(255);
-    final int length = random().nextBoolean()
-        ? random().nextInt(20)
-        : random().nextInt(192 * 1024);
-    return randomArray(length, max);
+  static byte[] randomArray(Random random) {
+    int bigsize = TEST_NIGHTLY ? 192 * 1024 : 33 * 1024;
+    final int max = random.nextBoolean()
+        ? random.nextInt(4)
+        : random.nextInt(255);
+    final int length = random.nextBoolean()
+        ? random.nextInt(20)
+        : random.nextInt(bigsize);
+    return randomArray(random, length, max);
   }
 
-  static byte[] randomArray(int length, int max) {
+  static byte[] randomArray(Random random, int length, int max) {
     final byte[] arr = new byte[length];
     for (int i = 0; i < arr.length; ++i) {
-      arr[i] = (byte) RandomNumbers.randomIntBetween(random(), 0, max);
+      arr[i] = (byte) RandomNumbers.randomIntBetween(random, 0, max);
     }
     return arr;
   }
@@ -83,11 +85,12 @@ public abstract class AbstractTestCompressionMode extends LuceneTestCase {
   }
 
   public void testDecompress() throws IOException {
-    final int iterations = atLeast(10);
+    Random random = random();
+    final int iterations = atLeast(random, 3);
     for (int i = 0; i < iterations; ++i) {
-      final byte[] decompressed = randomArray();
-      final int off = random().nextBoolean() ? 0 : TestUtil.nextInt(random(), 0, decompressed.length);
-      final int len = random().nextBoolean() ? decompressed.length - off : TestUtil.nextInt(random(), 0, decompressed.length - off);
+      final byte[] decompressed = randomArray(random);
+      final int off = random.nextBoolean() ? 0 : TestUtil.nextInt(random, 0, decompressed.length);
+      final int len = random.nextBoolean() ? decompressed.length - off : TestUtil.nextInt(random, 0, decompressed.length - off);
       final byte[] compressed = compress(decompressed, off, len);
       final byte[] restored = decompress(compressed, len);
       assertArrayEquals(ArrayUtil.copyOfSubArray(decompressed, off, off+len), restored);
@@ -95,16 +98,17 @@ public abstract class AbstractTestCompressionMode extends LuceneTestCase {
   }
 
   public void testPartialDecompress() throws IOException {
-    final int iterations = atLeast(10);
+    Random random = random();
+    final int iterations = atLeast(random, 3);
     for (int i = 0; i < iterations; ++i) {
-      final byte[] decompressed = randomArray();
+      final byte[] decompressed = randomArray(random);
       final byte[] compressed = compress(decompressed, 0, decompressed.length);
       final int offset, length;
       if (decompressed.length == 0) {
         offset = length = 0;
       } else {
-        offset = random().nextInt(decompressed.length);
-        length = random().nextInt(decompressed.length - offset);
+        offset = random.nextInt(decompressed.length);
+        length = random.nextInt(decompressed.length - offset);
       }
       final byte[] restored = decompress(compressed, decompressed.length, offset, length);
       assertArrayEquals(ArrayUtil.copyOfSubArray(decompressed, offset, offset + length), restored);
diff --git a/lucene/core/src/test/org/apache/lucene/codecs/lucene80/TestIndexedDISI.java b/lucene/core/src/test/org/apache/lucene/codecs/lucene80/TestIndexedDISI.java
index 9d118d5..c91bbf1 100644
--- a/lucene/core/src/test/org/apache/lucene/codecs/lucene80/TestIndexedDISI.java
+++ b/lucene/core/src/test/org/apache/lucene/codecs/lucene80/TestIndexedDISI.java
@@ -19,6 +19,7 @@ package org.apache.lucene.codecs.lucene80;
 import java.io.IOException;
 import java.util.ArrayList;
 import java.util.List;
+import java.util.Random;
 
 import org.apache.lucene.search.DocIdSetIterator;
 import org.apache.lucene.store.Directory;
@@ -421,14 +422,15 @@ public class TestIndexedDISI extends LuceneTestCase {
   }
 
   private void doTestRandom(Directory dir) throws IOException {
+    Random random = random();
     List<Integer> docs = new ArrayList<>();
-    final int maxStep = TestUtil.nextInt(random(), 1, 1 << TestUtil.nextInt(random(), 2, 20));
-    final int numDocs = TestUtil.nextInt(random(), 1, Math.min(100000, Integer.MAX_VALUE / maxStep));
+    final int maxStep = TestUtil.nextInt(random, 1, 1 << TestUtil.nextInt(random, 2, 20));
+    final int numDocs = TestUtil.nextInt(random, 1, Math.min(100000, Integer.MAX_VALUE / maxStep));
     for (int doc = -1, i = 0; i < numDocs; ++i) {
-      doc += TestUtil.nextInt(random(), 1, maxStep);
+      doc += TestUtil.nextInt(random, 1, maxStep);
       docs.add(doc);
     }
-    final int maxDoc = docs.get(docs.size() - 1) + TestUtil.nextInt(random(), 1, 100);
+    final int maxDoc = docs.get(docs.size() - 1) + TestUtil.nextInt(random, 1, 100);
 
     FixedBitSet set = new FixedBitSet(maxDoc);
     for (int doc : docs) {
@@ -477,8 +479,9 @@ public class TestIndexedDISI extends LuceneTestCase {
   private void assertAdvanceExactRandomized(IndexedDISI disi, BitSetIterator disi2, int disi2length, int step)
       throws IOException {
     int index = -1;
+    Random random = random();
     for (int target = 0; target < disi2length; ) {
-      target += TestUtil.nextInt(random(), 0, step);
+      target += TestUtil.nextInt(random, 0, step);
       int doc = disi2.docID();
       while (doc < target) {
         doc = disi2.nextDoc();
@@ -489,7 +492,7 @@ public class TestIndexedDISI extends LuceneTestCase {
       assertEquals(doc == target, exists);
       if (exists) {
         assertEquals(index, disi.index());
-      } else if (random().nextBoolean()) {
+      } else if (random.nextBoolean()) {
         assertEquals(doc, disi.nextDoc());
         // This is a bit strange when doc == NO_MORE_DOCS as the index overcounts in the disi2 while-loop
         assertEquals(index, disi.index());
diff --git a/lucene/core/src/test/org/apache/lucene/document/BaseXYShapeTestCase.java b/lucene/core/src/test/org/apache/lucene/document/BaseXYShapeTestCase.java
index 5f9035f..9ec78c0 100644
--- a/lucene/core/src/test/org/apache/lucene/document/BaseXYShapeTestCase.java
+++ b/lucene/core/src/test/org/apache/lucene/document/BaseXYShapeTestCase.java
@@ -17,6 +17,7 @@
 package org.apache.lucene.document;
 
 import java.util.Arrays;
+import java.util.Random;
 
 import com.carrotsearch.randomizedtesting.generators.RandomPicks;
 import org.apache.lucene.document.ShapeField.QueryRelation;
@@ -82,7 +83,7 @@ public abstract class BaseXYShapeTestCase extends BaseShapeTestCase {
 
   @Override
   public XYRectangle randomQueryBox() {
-    return ShapeTestUtil.nextBox();
+    return ShapeTestUtil.nextBox(random());
   }
 
   @Override
@@ -135,11 +136,12 @@ public abstract class BaseXYShapeTestCase extends BaseShapeTestCase {
 
   @Override
   protected Object[] nextPoints() {
-    int numPoints = TestUtil.nextInt(random(), 1, 20);
+    Random random = random();
+    int numPoints = TestUtil.nextInt(random, 1, 20);
     float[][] points = new float[numPoints][2];
     for (int i = 0; i < numPoints; i++) {
-      points[i][0] = (float) ShapeTestUtil.nextDouble();
-      points[i][1] = (float) ShapeTestUtil.nextDouble();
+      points[i][0] = (float) ShapeTestUtil.nextDouble(random);
+      points[i][1] = (float) ShapeTestUtil.nextDouble(random);
     }
     return points;
   }
diff --git a/lucene/core/src/test/org/apache/lucene/document/TestXYLineShapeQueries.java b/lucene/core/src/test/org/apache/lucene/document/TestXYLineShapeQueries.java
index 4bbc76b..0306b0e 100644
--- a/lucene/core/src/test/org/apache/lucene/document/TestXYLineShapeQueries.java
+++ b/lucene/core/src/test/org/apache/lucene/document/TestXYLineShapeQueries.java
@@ -17,6 +17,9 @@
 package org.apache.lucene.document;
 
 import com.carrotsearch.randomizedtesting.generators.RandomNumbers;
+
+import java.util.Random;
+
 import org.apache.lucene.document.ShapeField.QueryRelation;
 import org.apache.lucene.geo.Component2D;
 import org.apache.lucene.geo.ShapeTestUtil;
@@ -35,23 +38,24 @@ public class TestXYLineShapeQueries extends BaseXYShapeTestCase {
 
   @Override
   protected XYLine randomQueryLine(Object... shapes) {
-    if (random().nextInt(100) == 42) {
+    Random random = random();
+    if (random.nextInt(100) == 42) {
       // we want to ensure some cross, so randomly generate lines that share vertices with the indexed point set
       int maxBound = (int)Math.floor(shapes.length * 0.1d);
       if (maxBound < 2) {
         maxBound = shapes.length;
       }
-      float[] x = new float[RandomNumbers.randomIntBetween(random(), 2, maxBound)];
+      float[] x = new float[RandomNumbers.randomIntBetween(random, 2, maxBound)];
       float[] y = new float[x.length];
       for (int i = 0, j = 0; j < x.length && i < shapes.length; ++i, ++j) {
         XYLine l = (XYLine) (shapes[i]);
-        if (random().nextBoolean() && l != null) {
-          int v = random().nextInt(l.numPoints() - 1);
+        if (random.nextBoolean() && l != null) {
+          int v = random.nextInt(l.numPoints() - 1);
           x[j] = (float)l.getX(v);
           y[j] = (float)l.getY(v);
         } else {
-          x[j] = (float)ShapeTestUtil.nextDouble();
-          y[j] = (float)ShapeTestUtil.nextDouble();
+          x[j] = (float)ShapeTestUtil.nextDouble(random);
+          y[j] = (float)ShapeTestUtil.nextDouble(random);
         }
       }
       return new XYLine(x, y);
diff --git a/lucene/core/src/test/org/apache/lucene/document/TestXYMultiPolygonShapeQueries.java b/lucene/core/src/test/org/apache/lucene/document/TestXYMultiPolygonShapeQueries.java
index f1a92b0..62ea204 100644
--- a/lucene/core/src/test/org/apache/lucene/document/TestXYMultiPolygonShapeQueries.java
+++ b/lucene/core/src/test/org/apache/lucene/document/TestXYMultiPolygonShapeQueries.java
@@ -53,7 +53,7 @@ public class TestXYMultiPolygonShapeQueries extends BaseXYShapeTestCase {
             break;
           }
           repetitions++;
-          if (repetitions > 50) {
+          if (repetitions > 2) {
             //try again
             return nextShape();
           }
diff --git a/lucene/core/src/test/org/apache/lucene/document/TestXYPointShapeQueries.java b/lucene/core/src/test/org/apache/lucene/document/TestXYPointShapeQueries.java
index eabb033..cea0ff5 100644
--- a/lucene/core/src/test/org/apache/lucene/document/TestXYPointShapeQueries.java
+++ b/lucene/core/src/test/org/apache/lucene/document/TestXYPointShapeQueries.java
@@ -17,6 +17,9 @@
 package org.apache.lucene.document;
 
 import com.carrotsearch.randomizedtesting.generators.RandomNumbers;
+
+import java.util.Random;
+
 import org.apache.lucene.document.ShapeField.QueryRelation;
 import org.apache.lucene.geo.Component2D;
 import org.apache.lucene.geo.ShapeTestUtil;
@@ -35,22 +38,23 @@ public class TestXYPointShapeQueries extends BaseXYShapeTestCase {
 
   @Override
   protected XYLine randomQueryLine(Object... shapes) {
-    if (random().nextInt(100) == 42) {
+    Random random = random();
+    if (random.nextInt(100) == 42) {
       // we want to ensure some cross, so randomly generate lines that share vertices with the indexed point set
       int maxBound = (int)Math.floor(shapes.length * 0.1d);
       if (maxBound < 2) {
         maxBound = shapes.length;
       }
-      float[] x = new float[RandomNumbers.randomIntBetween(random(), 2, maxBound)];
+      float[] x = new float[RandomNumbers.randomIntBetween(random, 2, maxBound)];
       float[] y = new float[x.length];
       for (int i = 0, j = 0; j < x.length && i < shapes.length; ++i, ++j) {
         Point p = (Point) (shapes[i]);
-        if (random().nextBoolean() && p != null) {
+        if (random.nextBoolean() && p != null) {
           x[j] = p.x;
           y[j] = p.y;
         } else {
-          x[j] = (float)ShapeTestUtil.nextDouble();
-          y[j] = (float)ShapeTestUtil.nextDouble();
+          x[j] = (float)ShapeTestUtil.nextDouble(random);
+          y[j] = (float)ShapeTestUtil.nextDouble(random);
         }
       }
       return new XYLine(x, y);
diff --git a/lucene/core/src/test/org/apache/lucene/document/TestXYShape.java b/lucene/core/src/test/org/apache/lucene/document/TestXYShape.java
index efab57b..838ab4d 100644
--- a/lucene/core/src/test/org/apache/lucene/document/TestXYShape.java
+++ b/lucene/core/src/test/org/apache/lucene/document/TestXYShape.java
@@ -16,6 +16,8 @@
  */
 package org.apache.lucene.document;
 
+import java.util.Random;
+
 import org.apache.lucene.document.ShapeField.QueryRelation;
 import org.apache.lucene.geo.ShapeTestUtil;
 import org.apache.lucene.geo.Tessellator;
@@ -112,8 +114,9 @@ public class TestXYShape extends LuceneTestCase {
   }
 
   public void testBoundingBoxQueries() throws Exception {
-    XYRectangle r1 = ShapeTestUtil.nextBox();
-    XYRectangle r2 = ShapeTestUtil.nextBox();
+    Random random = random();
+    XYRectangle r1 = ShapeTestUtil.nextBox(random);
+    XYRectangle r2 = ShapeTestUtil.nextBox(random);
     XYPolygon p;
     //find two boxes so that r1 contains r2
     while (true) {
@@ -127,12 +130,12 @@ public class TestXYShape extends LuceneTestCase {
           // ignore, try other combination
         }
       }
-      r1 = ShapeTestUtil.nextBox();
-      r2 = ShapeTestUtil.nextBox();
+      r1 = ShapeTestUtil.nextBox(random);
+      r2 = ShapeTestUtil.nextBox(random);
     }
 
     Directory dir = newDirectory();
-    RandomIndexWriter writer = new RandomIndexWriter(random(), dir);
+    RandomIndexWriter writer = new RandomIndexWriter(random, dir);
 
     // add the polygon to the index
     Document document = new Document();
diff --git a/lucene/core/src/test/org/apache/lucene/document/TestXYShapeEncoding.java b/lucene/core/src/test/org/apache/lucene/document/TestXYShapeEncoding.java
index 01d0b66..5aa7a38 100644
--- a/lucene/core/src/test/org/apache/lucene/document/TestXYShapeEncoding.java
+++ b/lucene/core/src/test/org/apache/lucene/document/TestXYShapeEncoding.java
@@ -46,12 +46,12 @@ public class TestXYShapeEncoding extends BaseShapeEncodingTestCase {
 
   @Override
   protected double nextX() {
-    return ShapeTestUtil.nextDouble();
+    return ShapeTestUtil.nextDouble(random());
   }
 
   @Override
   protected double nextY() {
-    return ShapeTestUtil.nextDouble();
+    return ShapeTestUtil.nextDouble(random());
   }
 
   @Override
diff --git a/lucene/core/src/test/org/apache/lucene/geo/ShapeTestUtil.java b/lucene/core/src/test/org/apache/lucene/geo/ShapeTestUtil.java
index f7e304b..f1cc283 100644
--- a/lucene/core/src/test/org/apache/lucene/geo/ShapeTestUtil.java
+++ b/lucene/core/src/test/org/apache/lucene/geo/ShapeTestUtil.java
@@ -22,6 +22,8 @@ import java.util.Random;
 import com.carrotsearch.randomizedtesting.RandomizedContext;
 import com.carrotsearch.randomizedtesting.generators.BiasedNumbers;
 import org.apache.lucene.util.SloppyMath;
+
+import org.apache.lucene.util.LuceneTestCase;
 import org.apache.lucene.util.TestUtil;
 
 /** generates random cartesian geometry; heavy reuse of {@link GeoTestUtil} */
@@ -29,24 +31,25 @@ public class ShapeTestUtil {
 
   /** returns next pseudorandom polygon */
   public static XYPolygon nextPolygon() {
-    if (random().nextBoolean()) {
-      return surpriseMePolygon();
-    } else if (random().nextInt(10) == 1) {
+    Random random = random();
+    if (random.nextBoolean()) {
+      return surpriseMePolygon(random);
+    } else if (LuceneTestCase.TEST_NIGHTLY && random.nextInt(10) == 1) {
       // this poly is slow to create ... only do it 10% of the time:
       while (true) {
-        int gons = TestUtil.nextInt(random(), 4, 500);
+        int gons = TestUtil.nextInt(random, 4, 500);
         // So the poly can cover at most 50% of the earth's surface:
-        double radius = random().nextDouble() * 0.5 * Float.MAX_VALUE + 1.0;
+        double radius = random.nextDouble() * 0.5 * Float.MAX_VALUE + 1.0;
         try {
-          return createRegularPolygon(nextDouble(), nextDouble(), radius, gons);
+          return createRegularPolygon(nextDouble(random), nextDouble(random), radius, gons);
         } catch (IllegalArgumentException iae) {
           // we tried to cross dateline or pole ... try again
         }
       }
     }
 
-    XYRectangle box = nextBoxInternal();
-    if (random().nextBoolean()) {
+    XYRectangle box = nextBox(random);
+    if (random.nextBoolean()) {
       // box
       return boxPolygon(box);
     } else {
@@ -69,22 +72,18 @@ public class ShapeTestUtil {
     return new XYPolygon(polyX, polyY);
   }
 
-  public static XYRectangle nextBox() {
-    return nextBoxInternal();
-  }
-
-  private static XYRectangle nextBoxInternal() {
+  public static XYRectangle nextBox(Random random) {
     // prevent lines instead of boxes
-    double x0 = nextDouble();
-    double x1 = nextDouble();
+    double x0 = nextDouble(random);
+    double x1 = nextDouble(random);
     while (x0 == x1) {
-      x1 = nextDouble();
+      x1 = nextDouble(random);
     }
     // prevent lines instead of boxes
-    double y0 = nextDouble();
-    double y1 = nextDouble();
+    double y0 = nextDouble(random);
+    double y1 = nextDouble(random);
     while (y0 == y1) {
-      y1 = nextDouble();
+      y1 = nextDouble(random);
     }
 
     if (x1 < x0) {
@@ -118,25 +117,25 @@ public class ShapeTestUtil {
     return new XYPolygon(polyX, polyY);
   }
 
-  private static XYPolygon surpriseMePolygon() {
+  private static XYPolygon surpriseMePolygon(Random random) {
     // repeat until we get a poly that doesn't cross dateline:
     while (true) {
       //System.out.println("\nPOLY ITER");
-      double centerX = nextDouble();
-      double centerY = nextDouble();
-      double radius = 0.1 + 20 * random().nextDouble();
-      double radiusDelta = random().nextDouble();
+      double centerX = nextDouble(random);
+      double centerY = nextDouble(random);
+      double radius = 0.1 + 20 * random.nextDouble();
+      double radiusDelta = random.nextDouble();
 
       ArrayList<Float> xList = new ArrayList<>();
       ArrayList<Float> yList = new ArrayList<>();
       double angle = 0.0;
       while (true) {
-        angle += random().nextDouble()*40.0;
+        angle += random.nextDouble()*40.0;
         //System.out.println("  angle " + angle);
         if (angle > 360) {
           break;
         }
-        double len = radius * (1.0 - radiusDelta + radiusDelta * random().nextDouble());
+        double len = radius * (1.0 - radiusDelta + radiusDelta * random.nextDouble());
         double maxX = StrictMath.min(StrictMath.abs(Float.MAX_VALUE - centerX), StrictMath.abs(-Float.MAX_VALUE - centerX));
         double maxY = StrictMath.min(StrictMath.abs(Float.MAX_VALUE - centerY), StrictMath.abs(-Float.MAX_VALUE - centerY));
 
@@ -197,8 +196,8 @@ public class ShapeTestUtil {
     return new XYPolygon(result[0], result[1]);
   }
 
-  public static double nextDouble() {
-    return BiasedNumbers.randomDoubleBetween(random(), -Float.MAX_VALUE, Float.MAX_VALUE);
+  public static double nextDouble(Random random) {
+    return BiasedNumbers.randomDoubleBetween(random, -Float.MAX_VALUE, Float.MAX_VALUE);
   }
 
   /** Keep it simple, we don't need to take arbitrary Random for geo tests */
diff --git a/lucene/core/src/test/org/apache/lucene/geo/TestGeoUtils.java b/lucene/core/src/test/org/apache/lucene/geo/TestGeoUtils.java
index 51afbc1..f875951 100644
--- a/lucene/core/src/test/org/apache/lucene/geo/TestGeoUtils.java
+++ b/lucene/core/src/test/org/apache/lucene/geo/TestGeoUtils.java
@@ -17,6 +17,7 @@
 package org.apache.lucene.geo;
 
 import java.util.Locale;
+import java.util.Random;
 
 import org.apache.lucene.util.LuceneTestCase;
 import org.apache.lucene.util.SloppyMath;
@@ -195,12 +196,13 @@ public class TestGeoUtils extends LuceneTestCase {
   // TODO: does not really belong here, but we test it like this for now
   // we can make a fake IndexReader to send boxes directly to Point visitors instead?
   public void testCircleOpto() throws Exception {
-    int iters = atLeast(3);
+    Random random = random();
+    int iters = atLeast(random, 3);
     for (int i = 0; i < iters; i++) {
       // circle
-      final double centerLat = -90 + 180.0 * random().nextDouble();
-      final double centerLon = -180 + 360.0 * random().nextDouble();
-      final double radius = 50_000_000D * random().nextDouble();
+      final double centerLat = -90 + 180.0 * random.nextDouble();
+      final double centerLon = -180 + 360.0 * random.nextDouble();
+      final double radius = 50_000_000D * random.nextDouble();
       final Rectangle box = Rectangle.fromPointDistance(centerLat, centerLon, radius);
       // TODO: remove this leniency!
       if (box.crossesDateline()) {
@@ -209,22 +211,22 @@ public class TestGeoUtils extends LuceneTestCase {
       }
       final double axisLat = Rectangle.axisLat(centerLat, radius);
 
-      for (int k = 0; k < 1000; ++k) {
-
+      int innerIters = atLeast(100);
+      for (int k = 0; k < innerIters; ++k) {
         double[] latBounds = {-90, box.minLat, axisLat, box.maxLat, 90};
         double[] lonBounds = {-180, box.minLon, centerLon, box.maxLon, 180};
         // first choose an upper left corner
-        int maxLatRow = random().nextInt(4);
-        double latMax = randomInRange(latBounds[maxLatRow], latBounds[maxLatRow + 1]);
-        int minLonCol = random().nextInt(4);
-        double lonMin = randomInRange(lonBounds[minLonCol], lonBounds[minLonCol + 1]);
+        int maxLatRow = random.nextInt(4);
+        double latMax = randomInRange(random, latBounds[maxLatRow], latBounds[maxLatRow + 1]);
+        int minLonCol = random.nextInt(4);
+        double lonMin = randomInRange(random, lonBounds[minLonCol], lonBounds[minLonCol + 1]);
         // now choose a lower right corner
         int minLatMaxRow = maxLatRow == 3 ? 3 : maxLatRow + 1; // make sure it will at least cross into the bbox
-        int minLatRow = random().nextInt(minLatMaxRow);
-        double latMin = randomInRange(latBounds[minLatRow], Math.min(latBounds[minLatRow + 1], latMax));
+        int minLatRow = random.nextInt(minLatMaxRow);
+        double latMin = randomInRange(random, latBounds[minLatRow], Math.min(latBounds[minLatRow + 1], latMax));
         int maxLonMinCol = Math.max(minLonCol, 1); // make sure it will at least cross into the bbox
-        int maxLonCol = maxLonMinCol + random().nextInt(4 - maxLonMinCol);
-        double lonMax = randomInRange(Math.max(lonBounds[maxLonCol], lonMin), lonBounds[maxLonCol + 1]);
+        int maxLonCol = maxLonMinCol + random.nextInt(4 - maxLonMinCol);
+        double lonMax = randomInRange(random, Math.max(lonBounds[maxLonCol], lonMin), lonBounds[maxLonCol + 1]);
 
         assert latMax >= latMin;
         assert lonMax >= lonMin;
@@ -232,12 +234,12 @@ public class TestGeoUtils extends LuceneTestCase {
         if (isDisjoint(centerLat, centerLon, radius, axisLat, latMin, latMax, lonMin, lonMax)) {
           // intersects says false: test a ton of points
           for (int j = 0; j < 200; j++) {
-            double lat = latMin + (latMax - latMin) * random().nextDouble();
-            double lon = lonMin + (lonMax - lonMin) * random().nextDouble();
+            double lat = latMin + (latMax - latMin) * random.nextDouble();
+            double lon = lonMin + (lonMax - lonMin) * random.nextDouble();
 
-            if (random().nextBoolean()) {
+            if (random.nextBoolean()) {
               // explicitly test an edge
-              int edge = random().nextInt(4);
+              int edge = random.nextInt(4);
               if (edge == 0) {
                 lat = latMin;
               } else if (edge == 1) {
@@ -275,8 +277,8 @@ public class TestGeoUtils extends LuceneTestCase {
     }
   }
 
-  static double randomInRange(double min, double max) {
-    return min + (max - min) * random().nextDouble();
+  static double randomInRange(Random random, double min, double max) {
+    return min + (max - min) * random.nextDouble();
   }
 
   static boolean isDisjoint(double centerLat, double centerLon, double radius, double axisLat, double latMin, double latMax, double lonMin, double lonMax) {
diff --git a/lucene/core/src/test/org/apache/lucene/geo/TestPolygon2D.java b/lucene/core/src/test/org/apache/lucene/geo/TestPolygon2D.java
index 0206623..710c6a6 100644
--- a/lucene/core/src/test/org/apache/lucene/geo/TestPolygon2D.java
+++ b/lucene/core/src/test/org/apache/lucene/geo/TestPolygon2D.java
@@ -185,7 +185,8 @@ public class TestPolygon2D extends LuceneTestCase {
       Polygon polygon = nextPolygon();
       Component2D impl = Polygon2D.create(polygon);
       
-      for (int j = 0; j < 100; j++) {
+      int innerIters = atLeast(10);
+      for (int j = 0; j < innerIters; j++) {
         Rectangle rectangle = GeoTestUtil.nextBoxNear(polygon);
         // allowed to conservatively return true.
         if (impl.relate(rectangle.minLon, rectangle.maxLon, rectangle.minLat, rectangle.maxLat) == Relation.CELL_OUTSIDE_QUERY) {
diff --git a/lucene/core/src/test/org/apache/lucene/geo/TestXYRectangle2D.java b/lucene/core/src/test/org/apache/lucene/geo/TestXYRectangle2D.java
index 0ba7ab1..4ced0b8 100644
--- a/lucene/core/src/test/org/apache/lucene/geo/TestXYRectangle2D.java
+++ b/lucene/core/src/test/org/apache/lucene/geo/TestXYRectangle2D.java
@@ -17,6 +17,8 @@
 
 package org.apache.lucene.geo;
 
+import java.util.Random;
+
 import org.apache.lucene.index.PointValues;
 import org.apache.lucene.util.LuceneTestCase;
 
@@ -60,15 +62,16 @@ public class TestXYRectangle2D extends LuceneTestCase {
   }
 
   public void testRandomTriangles() {
-    XYRectangle rectangle = ShapeTestUtil.nextBox();
+    Random random = random();
+    XYRectangle rectangle = ShapeTestUtil.nextBox(random);
     Component2D rectangle2D = XYRectangle2D.create(rectangle);
     for (int i =0; i < 100; i++) {
-      float ax = (float) ShapeTestUtil.nextDouble();
-      float ay = (float) ShapeTestUtil.nextDouble();
-      float bx = (float) ShapeTestUtil.nextDouble();
-      float by = (float) ShapeTestUtil.nextDouble();
-      float cx = (float) ShapeTestUtil.nextDouble();
-      float cy = (float) ShapeTestUtil.nextDouble();
+      float ax = (float) ShapeTestUtil.nextDouble(random);
+      float ay = (float) ShapeTestUtil.nextDouble(random);
+      float bx = (float) ShapeTestUtil.nextDouble(random);
+      float by = (float) ShapeTestUtil.nextDouble(random);
+      float cx = (float) ShapeTestUtil.nextDouble(random);
+      float cy = (float) ShapeTestUtil.nextDouble(random);
 
       float tMinX = StrictMath.min(StrictMath.min(ax, bx), cx);
       float tMaxX = StrictMath.max(StrictMath.max(ax, bx), cx);
diff --git a/lucene/core/src/test/org/apache/lucene/index/TestByteSlices.java b/lucene/core/src/test/org/apache/lucene/index/TestByteSlices.java
index 48f8916..2c76e55 100644
--- a/lucene/core/src/test/org/apache/lucene/index/TestByteSlices.java
+++ b/lucene/core/src/test/org/apache/lucene/index/TestByteSlices.java
@@ -16,6 +16,8 @@
  */
 package org.apache.lucene.index;
 
+import java.util.Random;
+
 import org.apache.lucene.util.ByteBlockPool;
 import org.apache.lucene.util.LuceneTestCase;
 import org.apache.lucene.util.RecyclingByteBlockAllocator;
@@ -23,9 +25,10 @@ import org.apache.lucene.util.RecyclingByteBlockAllocator;
 public class TestByteSlices extends LuceneTestCase {
 
   public void testBasic() throws Throwable {
+    Random random = random();
     ByteBlockPool pool = new ByteBlockPool(new RecyclingByteBlockAllocator(ByteBlockPool.BYTE_BLOCK_SIZE, random().nextInt(100)));
 
-    final int NUM_STREAM = atLeast(100);
+    final int NUM_STREAM = atLeast(random, 100);
 
     ByteSliceWriter writer = new ByteSliceWriter(pool);
 
@@ -42,13 +45,13 @@ public class TestByteSlices extends LuceneTestCase {
         counters[stream] = 0;
       }
       
-      int num = atLeast(3000);
+      int num = atLeast(random, 3000);
       for (int iter = 0; iter < num; iter++) {
         int stream;
-        if (random().nextBoolean()) {
-          stream = random().nextInt(3);
+        if (random.nextBoolean()) {
+          stream = random.nextInt(3);
         } else {
-          stream = random().nextInt(NUM_STREAM);
+          stream = random.nextInt(NUM_STREAM);
         }
 
         if (VERBOSE) {
@@ -65,12 +68,12 @@ public class TestByteSlices extends LuceneTestCase {
 
         writer.init(uptos[stream]);
         int numValue;
-        if (random().nextInt(10) == 3) {
-          numValue = random().nextInt(100);
-        } else if (random().nextInt(5) == 3) {
-          numValue = random().nextInt(3);
+        if (random.nextInt(10) == 3) {
+          numValue = random.nextInt(100);
+        } else if (random.nextInt(5) == 3) {
+          numValue = random.nextInt(3);
         } else {
-          numValue = random().nextInt(20);
+          numValue = random.nextInt(20);
         }
 
         for(int j=0;j<numValue;j++) {
@@ -78,7 +81,7 @@ public class TestByteSlices extends LuceneTestCase {
             System.out.println("    write " + (counters[stream]+j));
           }
           // write some large (incl. negative) ints:
-          writer.writeVInt(random().nextInt());
+          writer.writeVInt(random.nextInt());
           writer.writeVInt(counters[stream]+j);
         }
         counters[stream] += numValue;
diff --git a/lucene/core/src/test/org/apache/lucene/index/TestTermsEnum.java b/lucene/core/src/test/org/apache/lucene/index/TestTermsEnum.java
index c8131a4..a7793bf 100644
--- a/lucene/core/src/test/org/apache/lucene/index/TestTermsEnum.java
+++ b/lucene/core/src/test/org/apache/lucene/index/TestTermsEnum.java
@@ -241,7 +241,8 @@ public class TestTermsEnum extends LuceneTestCase {
       docIDToID[i] = (int) values.longValue();
     }
 
-    for(int iter=0;iter<10*RANDOM_MULTIPLIER;iter++) {
+    int numIterations = atLeast(3);
+    for(int iter=0;iter<numIterations;iter++) {
 
       // TODO: can we also test infinite As here...?
 
diff --git a/lucene/core/src/test/org/apache/lucene/store/TestByteBuffersDataInput.java b/lucene/core/src/test/org/apache/lucene/store/TestByteBuffersDataInput.java
index 20e3bd2..0330389 100644
--- a/lucene/core/src/test/org/apache/lucene/store/TestByteBuffersDataInput.java
+++ b/lucene/core/src/test/org/apache/lucene/store/TestByteBuffersDataInput.java
@@ -83,7 +83,7 @@ public final class TestByteBuffersDataInput extends RandomizedTest {
 
   @Test
   public void testRandomReadsOnSlices() throws Exception {
-    for (int reps = randomIntBetween(1, 200); --reps > 0;) {
+    for (int reps = randomIntBetween(1, 20); --reps > 0;) {
       ByteBuffersDataOutput dst = new ByteBuffersDataOutput();
   
       byte [] prefix = new byte [randomIntBetween(0, 1024 * 8)];
diff --git a/lucene/core/src/test/org/apache/lucene/util/TestPagedBytes.java b/lucene/core/src/test/org/apache/lucene/util/TestPagedBytes.java
index f34ba53..a9971c6 100644
--- a/lucene/core/src/test/org/apache/lucene/util/TestPagedBytes.java
+++ b/lucene/core/src/test/org/apache/lucene/util/TestPagedBytes.java
@@ -45,16 +45,16 @@ public class TestPagedBytes extends LuceneTestCase {
       final int blockSize = 1 << blockBits;
       final PagedBytes p = new PagedBytes(blockBits);
       final IndexOutput out = dir.createOutput("foo", IOContext.DEFAULT);
-      final int numBytes = TestUtil.nextInt(random(), 2, 10000000);
+      final int numBytes = TestUtil.nextInt(random, 2, 10000000);
 
       final byte[] answer = new byte[numBytes];
-      random().nextBytes(answer);
+      random.nextBytes(answer);
       int written = 0;
       while(written < numBytes) {
-        if (random().nextInt(10) == 7) {
+        if (random.nextInt(100) == 7) {
           out.writeByte(answer[written++]);
         } else {
-          int chunk = Math.min(random().nextInt(1000), numBytes - written);
+          int chunk = Math.min(random.nextInt(1000), numBytes - written);
           out.writeBytes(answer, written, chunk);
           written += chunk;
         }
@@ -70,10 +70,10 @@ public class TestPagedBytes extends LuceneTestCase {
       final byte[] verify = new byte[numBytes];
       int read = 0;
       while(read < numBytes) {
-        if (random().nextInt(10) == 7) {
+        if (random.nextInt(100) == 7) {
           verify[read++] = in.readByte();
         } else {
-          int chunk = Math.min(random().nextInt(1000), numBytes - read);
+          int chunk = Math.min(random.nextInt(1000), numBytes - read);
           in.readBytes(verify, read, chunk);
           read += chunk;
         }
diff --git a/lucene/core/src/test/org/apache/lucene/util/bkd/TestBKD.java b/lucene/core/src/test/org/apache/lucene/util/bkd/TestBKD.java
index 9c1bd0f..59e4dd8 100644
--- a/lucene/core/src/test/org/apache/lucene/util/bkd/TestBKD.java
+++ b/lucene/core/src/test/org/apache/lucene/util/bkd/TestBKD.java
@@ -23,6 +23,7 @@ import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.BitSet;
 import java.util.List;
+import java.util.Random;
 
 import org.apache.lucene.codecs.MutablePointValues;
 import org.apache.lucene.index.CorruptIndexException;
@@ -1221,19 +1222,20 @@ public class TestBKD extends LuceneTestCase {
   // Claims 16 bytes per dim, but only use the bottom N 1-3 bytes; this would happen e.g. if a user indexes what are actually just short
   // values as a LongPoint:
   public void testWastedLeadingBytes() throws Exception {
-    int numDims = TestUtil.nextInt(random(), 1, PointValues.MAX_DIMENSIONS);
-    int numIndexDims = TestUtil.nextInt(random(), 1, numDims);
+    Random random = random();
+    int numDims = TestUtil.nextInt(random, 1, PointValues.MAX_DIMENSIONS);
+    int numIndexDims = TestUtil.nextInt(random, 1, numDims);
     int bytesPerDim = PointValues.MAX_NUM_BYTES;
-    int bytesUsed = TestUtil.nextInt(random(), 1, 3);
+    int bytesUsed = TestUtil.nextInt(random, 1, 3);
 
     Directory dir = newFSDirectory(createTempDir());
-    int numDocs = 100000;
+    int numDocs = atLeast(10000);
     BKDWriter w = new BKDWriter(numDocs+1, dir, "tmp", numDims, numIndexDims, bytesPerDim, 32, 1f, numDocs);
     byte[] tmp = new byte[bytesUsed];
     byte[] buffer = new byte[numDims * bytesPerDim];
     for(int i=0;i<numDocs;i++) {
       for(int dim=0;dim<numDims;dim++) {
-        random().nextBytes(tmp);
+        random.nextBytes(tmp);
         System.arraycopy(tmp, 0, buffer, dim*bytesPerDim+(bytesPerDim-bytesUsed), tmp.length);
       }
       w.add(buffer, i);
diff --git a/lucene/core/src/test/org/apache/lucene/util/packed/TestDirectMonotonic.java b/lucene/core/src/test/org/apache/lucene/util/packed/TestDirectMonotonic.java
index 65ac33a..300e1e0 100644
--- a/lucene/core/src/test/org/apache/lucene/util/packed/TestDirectMonotonic.java
+++ b/lucene/core/src/test/org/apache/lucene/util/packed/TestDirectMonotonic.java
@@ -21,6 +21,7 @@ import java.io.IOException;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.List;
+import java.util.Random;
 
 import org.apache.lucene.store.Directory;
 import org.apache.lucene.store.IOContext;
@@ -138,27 +139,28 @@ public class TestDirectMonotonic extends LuceneTestCase {
   }
 
   public void testRandom() throws IOException {
-    final int iters = atLeast(3);
+    Random random = random();
+    final int iters = atLeast(random, 3);
     for (int iter = 0; iter < iters; ++iter) {
       Directory dir = newDirectory();
-      final int blockShift = TestUtil.nextInt(random(), DirectMonotonicWriter.MIN_BLOCK_SHIFT, DirectMonotonicWriter.MAX_BLOCK_SHIFT);
+      final int blockShift = TestUtil.nextInt(random, DirectMonotonicWriter.MIN_BLOCK_SHIFT, DirectMonotonicWriter.MAX_BLOCK_SHIFT);
       final int maxNumValues = 1 << 20;
       final int numValues;
-      if (random().nextBoolean()) {
+      if (random.nextBoolean()) {
         // random number
-        numValues = TestUtil.nextInt(random(), 1, maxNumValues);
+        numValues = TestUtil.nextInt(random, 1, maxNumValues);
       } else {
         // multiple of the block size
-        final int numBlocks = TestUtil.nextInt(random(), 0, maxNumValues >>> blockShift);
-        numValues = TestUtil.nextInt(random(), 0, numBlocks) << blockShift;
+        final int numBlocks = TestUtil.nextInt(random, 0, maxNumValues >>> blockShift);
+        numValues = TestUtil.nextInt(random, 0, numBlocks) << blockShift;
       }
       List<Long> actualValues = new ArrayList<>();
-      long previous = random().nextLong();
+      long previous = random.nextLong();
       if (numValues > 0) {
         actualValues.add(previous);
       }
       for (int i = 1; i < numValues; ++i) {
-        previous += random().nextInt(1 << random().nextInt(20));
+        previous += random.nextInt(1 << random.nextInt(20));
         actualValues.add(previous);
       }
   
diff --git a/lucene/core/src/test/org/apache/lucene/util/packed/TestDirectPacked.java b/lucene/core/src/test/org/apache/lucene/util/packed/TestDirectPacked.java
index 2ab0a6a..8fe4a22 100644
--- a/lucene/core/src/test/org/apache/lucene/util/packed/TestDirectPacked.java
+++ b/lucene/core/src/test/org/apache/lucene/util/packed/TestDirectPacked.java
@@ -99,7 +99,7 @@ public class TestDirectPacked extends LuceneTestCase {
       String name = "bpv" + bpv + "_" + i;
       IndexOutput output = directory.createOutput(name, IOContext.DEFAULT);
       for (long j = 0; j < offset; ++j) {
-        output.writeByte((byte) random().nextInt());
+        output.writeByte((byte) random.nextInt());
       }
       DirectWriter writer = DirectWriter.getInstance(output, original.length, bitsRequired);
       for (int j = 0; j < original.length; j++) {
diff --git a/lucene/core/src/test/org/apache/lucene/util/packed/TestPackedInts.java b/lucene/core/src/test/org/apache/lucene/util/packed/TestPackedInts.java
index fe6875c..7f7cf8b 100644
--- a/lucene/core/src/test/org/apache/lucene/util/packed/TestPackedInts.java
+++ b/lucene/core/src/test/org/apache/lucene/util/packed/TestPackedInts.java
@@ -263,14 +263,15 @@ public class TestPackedInts extends LuceneTestCase {
   }
 
   public void testRandomBulkCopy() {
-    final int numIters = atLeast(3);
+    Random random = random();
+    final int numIters = atLeast(random, 3);
     for(int iter=0;iter<numIters;iter++) {
       if (VERBOSE) {
         System.out.println("\nTEST: iter=" + iter);
       }
-      final int valueCount = atLeast(100000);
-      int bits1 = TestUtil.nextInt(random(), 1, 64);
-      int bits2 = TestUtil.nextInt(random(), 1, 64);
+      final int valueCount = TEST_NIGHTLY ? atLeast(random, 100000) : atLeast(random, 10000);
+      int bits1 = TestUtil.nextInt(random, 1, 64);
+      int bits2 = TestUtil.nextInt(random, 1, 64);
       if (bits1 > bits2) {
         int tmp = bits1;
         bits1 = bits2;
@@ -285,7 +286,7 @@ public class TestPackedInts extends LuceneTestCase {
 
       final long maxValue = PackedInts.maxValue(bits1);
       for(int i=0;i<valueCount;i++) {
-        final long val = TestUtil.nextLong(random(), 0, maxValue);
+        final long val = TestUtil.nextLong(random, 0, maxValue);
         packed1.set(i, val);
         packed2.set(i, val);
       }
@@ -294,8 +295,8 @@ public class TestPackedInts extends LuceneTestCase {
 
       // Copy random slice over, 20 times:
       for(int iter2=0;iter2<20;iter2++) {
-        int start = random().nextInt(valueCount-1);
-        int len = TestUtil.nextInt(random(), 1, valueCount - start);
+        int start = random.nextInt(valueCount-1);
+        int len = TestUtil.nextInt(random, 1, valueCount - start);
         int offset;
         if (VERBOSE) {
           System.out.println("  copy " + len + " values @ " + start);
@@ -303,15 +304,15 @@ public class TestPackedInts extends LuceneTestCase {
         if (len == valueCount) {
           offset = 0;
         } else {
-          offset = random().nextInt(valueCount - len);
+          offset = random.nextInt(valueCount - len);
         }
-        if (random().nextBoolean()) {
+        if (random.nextBoolean()) {
           int got = packed1.get(start, buffer, offset, len);
           assertTrue(got <= len);
           int sot = packed2.set(start, buffer, offset, got);
           assertTrue(sot <= got);
         } else {
-          PackedInts.copy(packed1, offset, packed2, offset, len, random().nextInt(10 * len));
+          PackedInts.copy(packed1, offset, packed2, offset, len, random.nextInt(10 * len));
         }
 
         /*
@@ -694,22 +695,23 @@ public class TestPackedInts extends LuceneTestCase {
   }
 
   public void testPagedGrowableWriter() {
-    int pageSize = 1 << (TestUtil.nextInt(random(), 6, 30));
+    Random random = random();
+    int pageSize = 1 << (TestUtil.nextInt(random, 6, 30));
     // supports 0 values?
-    PagedGrowableWriter writer = new PagedGrowableWriter(0, pageSize, TestUtil.nextInt(random(), 1, 64), random().nextFloat());
+    PagedGrowableWriter writer = new PagedGrowableWriter(0, pageSize, TestUtil.nextInt(random, 1, 64), random.nextFloat());
     assertEquals(0, writer.size());
 
     // compare against AppendingDeltaPackedLongBuffer
-    PackedLongValues.Builder buf = PackedLongValues.deltaPackedBuilder(random().nextFloat());
-    int size = random().nextInt(1000000);
+    PackedLongValues.Builder buf = PackedLongValues.deltaPackedBuilder(random.nextFloat());
+    int size = TEST_NIGHTLY ? random.nextInt(1000000) : random.nextInt(100000);
     long max = 5;
     for (int i = 0; i < size; ++i) {
-      buf.add(TestUtil.nextLong(random(), 0, max));
-      if (rarely()) {
-        max = PackedInts.maxValue(rarely() ? TestUtil.nextInt(random(), 0, 63) : TestUtil.nextInt(random(), 0, 31));
+      buf.add(TestUtil.nextLong(random, 0, max));
+      if (rarely(random)) {
+        max = PackedInts.maxValue(rarely(random) ? TestUtil.nextInt(random, 0, 63) : TestUtil.nextInt(random, 0, 31));
       }
     }
-    writer = new PagedGrowableWriter(size, pageSize, TestUtil.nextInt(random(), 1, 64), random().nextFloat());
+    writer = new PagedGrowableWriter(size, pageSize, TestUtil.nextInt(random, 1, 64), random.nextFloat());
     assertEquals(size, writer.size());
     final LongValues values = buf.build();
     for (int i = size - 1; i >= 0; --i) {
@@ -723,7 +725,7 @@ public class TestPackedInts extends LuceneTestCase {
     assertEquals(RamUsageTester.sizeOf(writer), writer.ramBytesUsed(), 8);
 
     // test copy
-    PagedGrowableWriter copy = writer.resize(TestUtil.nextLong(random(), writer.size() / 2, writer.size() * 3 / 2));
+    PagedGrowableWriter copy = writer.resize(TestUtil.nextLong(random, writer.size() / 2, writer.size() * 3 / 2));
     for (long i = 0; i < copy.size(); ++i) {
       if (i < writer.size()) {
         assertEquals(writer.get(i), copy.get(i));
@@ -733,7 +735,7 @@ public class TestPackedInts extends LuceneTestCase {
     }
 
     // test grow
-    PagedGrowableWriter grow = writer.grow(TestUtil.nextLong(random(), writer.size() / 2, writer.size() * 3 / 2));
+    PagedGrowableWriter grow = writer.grow(TestUtil.nextLong(random, writer.size() / 2, writer.size() * 3 / 2));
     for (long i = 0; i < grow.size(); ++i) {
       if (i < writer.size()) {
         assertEquals(writer.get(i), grow.get(i));
@@ -744,21 +746,22 @@ public class TestPackedInts extends LuceneTestCase {
   }
 
   public void testPagedMutable() {
-    final int bitsPerValue = TestUtil.nextInt(random(), 1, 64);
+    Random random = random();
+    final int bitsPerValue = TestUtil.nextInt(random, 1, 64);
     final long max = PackedInts.maxValue(bitsPerValue);
-    int pageSize = 1 << (TestUtil.nextInt(random(), 6, 30));
+    int pageSize = 1 << (TestUtil.nextInt(random, 6, 30));
     // supports 0 values?
-    PagedMutable writer = new PagedMutable(0, pageSize, bitsPerValue, random().nextFloat() / 2);
+    PagedMutable writer = new PagedMutable(0, pageSize, bitsPerValue, random.nextFloat() / 2);
     assertEquals(0, writer.size());
 
     // compare against AppendingDeltaPackedLongBuffer
-    PackedLongValues.Builder buf = PackedLongValues.deltaPackedBuilder(random().nextFloat());
-    int size = random().nextInt(1000000);
+    PackedLongValues.Builder buf = PackedLongValues.deltaPackedBuilder(random.nextFloat());
+    int size = TEST_NIGHTLY ? random.nextInt(1000000) : random.nextInt(100000);
     
     for (int i = 0; i < size; ++i) {
-      buf.add(bitsPerValue == 64 ? random().nextLong() : TestUtil.nextLong(random(), 0, max));
+      buf.add(bitsPerValue == 64 ? random.nextLong() : TestUtil.nextLong(random, 0, max));
     }
-    writer = new PagedMutable(size, pageSize, bitsPerValue, random().nextFloat());
+    writer = new PagedMutable(size, pageSize, bitsPerValue, random.nextFloat());
     assertEquals(size, writer.size());
     final LongValues values = buf.build();
     for (int i = size - 1; i >= 0; --i) {
@@ -772,7 +775,7 @@ public class TestPackedInts extends LuceneTestCase {
     assertEquals(RamUsageTester.sizeOf(writer) - RamUsageTester.sizeOf(writer.format), writer.ramBytesUsed());
 
     // test copy
-    PagedMutable copy = writer.resize(TestUtil.nextLong(random(), writer.size() / 2, writer.size() * 3 / 2));
+    PagedMutable copy = writer.resize(TestUtil.nextLong(random, writer.size() / 2, writer.size() * 3 / 2));
     for (long i = 0; i < copy.size(); ++i) {
       if (i < writer.size()) {
         assertEquals(writer.get(i), copy.get(i));
@@ -782,7 +785,7 @@ public class TestPackedInts extends LuceneTestCase {
     }
 
     // test grow
-    PagedMutable grow = writer.grow(TestUtil.nextLong(random(), writer.size() / 2, writer.size() * 3 / 2));
+    PagedMutable grow = writer.grow(TestUtil.nextLong(random, writer.size() / 2, writer.size() * 3 / 2));
     for (long i = 0; i < grow.size(); ++i) {
       if (i < writer.size()) {
         assertEquals(writer.get(i), grow.get(i));
@@ -1103,24 +1106,30 @@ public class TestPackedInts extends LuceneTestCase {
   }
 
   public void testBlockPackedReaderWriter() throws IOException {
+    Random random = random();
     final int iters = atLeast(2);
     for (int iter = 0; iter < iters; ++iter) {
-      final int blockSize = 1 << TestUtil.nextInt(random(), 6, 18);
-      final int valueCount = random().nextInt(1 << 18);
+      final int blockSize = 1 << TestUtil.nextInt(random, 6, 18);
+      final int valueCount;
+      if (TEST_NIGHTLY) {
+        valueCount = random.nextInt(1 << 18);
+      } else {
+        valueCount = random.nextInt(1 << 15);
+      }
       final long[] values = new long[valueCount];
       long minValue = 0;
       int bpv = 0;
       for (int i = 0; i < valueCount; ++i) {
         if (i % blockSize == 0) {
-          minValue = rarely() ? random().nextInt(256) : rarely() ? -5 : random().nextLong();
-          bpv = random().nextInt(65);
+          minValue = rarely(random) ? random.nextInt(256) : rarely(random) ? -5 : random.nextLong();
+          bpv = random.nextInt(65);
         }
         if (bpv == 0) {
           values[i] = minValue;
         } else if (bpv == 64) {
-          values[i] = random().nextLong();
+          values[i] = random.nextLong();
         } else {
-          values[i] = minValue + TestUtil.nextLong(random(), 0, (1L << bpv) - 1);
+          values[i] = minValue + TestUtil.nextLong(random, 0, (1L << bpv) - 1);
         }
       }
   
@@ -1142,14 +1151,14 @@ public class TestPackedInts extends LuceneTestCase {
       in1.readBytes(buf, 0, (int) fp);
       in1.seek(0L);
       ByteArrayDataInput in2 = new ByteArrayDataInput(buf);
-      final DataInput in = random().nextBoolean() ? in1 : in2;
+      final DataInput in = random.nextBoolean() ? in1 : in2;
       final BlockPackedReaderIterator it = new BlockPackedReaderIterator(in, PackedInts.VERSION_CURRENT, blockSize, valueCount);
       for (int i = 0; i < valueCount; ) {
-        if (random().nextBoolean()) {
+        if (random.nextBoolean()) {
           assertEquals("" + i, values[i], it.next());
           ++i;
         } else {
-          final LongsRef nextValues = it.next(TestUtil.nextInt(random(), 1, 1024));
+          final LongsRef nextValues = it.next(TestUtil.nextInt(random, 1, 1024));
           for (int j = 0; j < nextValues.length; ++j) {
             assertEquals("" + (i + j), values[i + j], nextValues.longs[nextValues.offset + j]);
           }
@@ -1170,7 +1179,7 @@ public class TestPackedInts extends LuceneTestCase {
       final BlockPackedReaderIterator it2 = new BlockPackedReaderIterator(in, PackedInts.VERSION_CURRENT, blockSize, valueCount);
       int i = 0;
       while (true) {
-        final int skip = TestUtil.nextInt(random(), 0, valueCount - i);
+        final int skip = TestUtil.nextInt(random, 0, valueCount - i);
         it2.skip(skip);
         i += skip;
         assertEquals(i, it2.ord());
diff --git a/lucene/test-framework/src/java/org/apache/lucene/analysis/MockTokenizer.java b/lucene/test-framework/src/java/org/apache/lucene/analysis/MockTokenizer.java
index 76b71c1..2028704 100644
--- a/lucene/test-framework/src/java/org/apache/lucene/analysis/MockTokenizer.java
+++ b/lucene/test-framework/src/java/org/apache/lucene/analysis/MockTokenizer.java
@@ -152,11 +152,13 @@ public class MockTokenizer extends Tokenizer {
       if (cp < 0) {
         break;
       } else if (isTokenChar(cp)) {
+        char chars[] = new char[2];
         int endOffset;
         do {
-          char chars[] = Character.toChars(normalize(cp));
-          for (int i = 0; i < chars.length; i++)
+          int len = Character.toChars(normalize(cp), chars, 0);
+          for (int i = 0; i < len; i++) {
             termAtt.append(chars[i]);
+          }
           endOffset = off;
           if (termAtt.length() >= maxTokenLength) {
             break;
diff --git a/lucene/test-framework/src/java/org/apache/lucene/util/BaseBitSetTestCase.java b/lucene/test-framework/src/java/org/apache/lucene/util/BaseBitSetTestCase.java
index 002ebcf..832009a 100644
--- a/lucene/test-framework/src/java/org/apache/lucene/util/BaseBitSetTestCase.java
+++ b/lucene/test-framework/src/java/org/apache/lucene/util/BaseBitSetTestCase.java
@@ -19,6 +19,7 @@ package org.apache.lucene.util;
 import java.io.IOException;
 import java.util.Collection;
 import java.util.Collections;
+import java.util.Random;
 
 import org.apache.lucene.search.DocIdSet;
 import org.apache.lucene.search.DocIdSetIterator;
@@ -40,9 +41,10 @@ public abstract class BaseBitSetTestCase<T extends BitSet> extends LuceneTestCas
     if (numBitsSet == numBits) {
       set.set(0, numBits);
     } else {
+      Random random = random();
       for (int i = 0; i < numBitsSet; ++i) {
         while (true) {
-          final int o = random().nextInt(numBits);
+          final int o = random.nextInt(numBits);
           if (!set.get(o)) {
             set.set(o);
             break;
@@ -100,12 +102,13 @@ public abstract class BaseBitSetTestCase<T extends BitSet> extends LuceneTestCas
 
   /** Test the {@link BitSet#set} method. */
   public void testSet() throws IOException {
-    final int numBits = 1 + random().nextInt(100000);
+    Random random = random();
+    final int numBits = 1 + random.nextInt(100000);
     BitSet set1 = new JavaUtilBitSet(randomSet(numBits, 0), numBits);
     T set2 = copyOf(set1, numBits);
-    final int iters = 10000 + random().nextInt(10000);
+    final int iters = 10000 + random.nextInt(10000);
     for (int i = 0; i < iters; ++i) {
-      final int index = random().nextInt(numBits);
+      final int index = random.nextInt(numBits);
       set1.set(index);
       set2.set(index);
     }
@@ -114,13 +117,14 @@ public abstract class BaseBitSetTestCase<T extends BitSet> extends LuceneTestCas
 
   /** Test the {@link BitSet#clear(int)} method. */
   public void testClear() throws IOException {
-    final int numBits = 1 + random().nextInt(100000);
+    Random random = random();
+    final int numBits = 1 + random.nextInt(100000);
     for (float percentSet : new float[] {0, 0.01f, 0.1f, 0.5f, 0.9f, 0.99f, 1f}) {
       BitSet set1 = new JavaUtilBitSet(randomSet(numBits, percentSet), numBits);
       T set2 = copyOf(set1, numBits);
-      final int iters = 1 + random().nextInt(numBits * 2);
+      final int iters = 1 + random.nextInt(numBits * 2);
       for (int i = 0; i < iters; ++i) {
-        final int index = random().nextInt(numBits);
+        final int index = random.nextInt(numBits);
         set1.clear(index);
         set2.clear(index);
       }
@@ -130,14 +134,15 @@ public abstract class BaseBitSetTestCase<T extends BitSet> extends LuceneTestCas
 
   /** Test the {@link BitSet#clear(int,int)} method. */
   public void testClearRange() throws IOException {
-    final int numBits = 1 + random().nextInt(100000);
+    Random random = random();
+    final int numBits = 1 + random.nextInt(100000);
     for (float percentSet : new float[] {0, 0.01f, 0.1f, 0.5f, 0.9f, 0.99f, 1f}) {
       BitSet set1 = new JavaUtilBitSet(randomSet(numBits, percentSet), numBits);
       T set2 = copyOf(set1, numBits);
-      final int iters = atLeast(10);
+      final int iters = atLeast(random, 10);
       for (int i = 0; i < iters; ++i) {
-        final int from = random().nextInt(numBits);
-        final int to = random().nextInt(numBits + 1);
+        final int from = random.nextInt(numBits);
+        final int to = random.nextInt(numBits + 1);
         set1.clear(from, to);
         set2.clear(from, to);
         assertEquals(set1, set2, numBits);
diff --git a/lucene/test-framework/src/java/org/apache/lucene/util/BaseDocIdSetTestCase.java b/lucene/test-framework/src/java/org/apache/lucene/util/BaseDocIdSetTestCase.java
index 8a907c0..1798840 100644
--- a/lucene/test-framework/src/java/org/apache/lucene/util/BaseDocIdSetTestCase.java
+++ b/lucene/test-framework/src/java/org/apache/lucene/util/BaseDocIdSetTestCase.java
@@ -20,6 +20,7 @@ import static org.apache.lucene.util.BaseBitSetTestCase.randomSet;
 
 import java.io.IOException;
 import java.util.BitSet;
+import java.util.Random;
 
 import org.apache.lucene.search.DocIdSet;
 import org.apache.lucene.search.DocIdSetIterator;
@@ -62,9 +63,10 @@ public abstract class BaseDocIdSetTestCase<T extends DocIdSet> extends LuceneTes
 
   /** Compare the content of the set against a {@link BitSet}. */
   public void testAgainstBitSet() throws IOException {
-    final int numBits = TestUtil.nextInt(random(), 100, 1 << 20);
+    Random random = random();
+    final int numBits = TestUtil.nextInt(random, 100, 1 << 20);
     // test various random sets with various load factors
-    for (float percentSet : new float[] {0f, 0.0001f, random().nextFloat(), 0.9f, 1f}) {
+    for (float percentSet : new float[] {0f, 0.0001f, random.nextFloat(), 0.9f, 1f}) {
       final BitSet set = randomSet(numBits, percentSet);
       final T copy = copyOf(set, numBits);
       assertEquals(numBits, set, copy);
@@ -75,13 +77,13 @@ public abstract class BaseDocIdSetTestCase<T extends DocIdSet> extends LuceneTes
     T copy = copyOf(set, numBits);
     assertEquals(numBits, set, copy);
     set.clear(0);
-    set.set(random().nextInt(numBits));
+    set.set(random.nextInt(numBits));
     copy = copyOf(set, numBits); // then random index
     assertEquals(numBits, set, copy);
     // test regular increments
     int maxIterations = TEST_NIGHTLY ? Integer.MAX_VALUE : 10;
     int iterations = 0;
-    for (int inc = 2; inc < 1000; inc += TestUtil.nextInt(random(), 1, 100)) {
+    for (int inc = 2; inc < 1000; inc += TestUtil.nextInt(random, 1, 100)) {
       // don't let this test run too many times, even if it gets unlucky with "inc"
       if (iterations >= maxIterations) {
         break;
@@ -89,7 +91,7 @@ public abstract class BaseDocIdSetTestCase<T extends DocIdSet> extends LuceneTes
       iterations++;
 
       set = new BitSet(numBits);
-      for (int d = random().nextInt(10); d < numBits; d += inc) {
+      for (int d = random.nextInt(10); d < numBits; d += inc) {
         set.set(d);
       }
       copy = copyOf(set, numBits);
@@ -99,11 +101,12 @@ public abstract class BaseDocIdSetTestCase<T extends DocIdSet> extends LuceneTes
 
   /** Test ram usage estimation. */
   public void testRamBytesUsed() throws IOException {
+    Random random = random();
     final int iters = 100;
     for (int i = 0; i < iters; ++i) {
-      final int pow = random().nextInt(20);
-      final int maxDoc = TestUtil.nextInt(random(), 1, 1 << pow);
-      final int numDocs = TestUtil.nextInt(random(), 0, Math.min(maxDoc, 1 << TestUtil.nextInt(random(), 0, pow)));
+      final int pow = random.nextInt(20);
+      final int maxDoc = TestUtil.nextInt(random, 1, 1 << pow);
+      final int numDocs = TestUtil.nextInt(random, 0, Math.min(maxDoc, 1 << TestUtil.nextInt(random, 0, pow)));
       final BitSet set = randomSet(maxDoc, numDocs);
       final DocIdSet copy = copyOf(set, maxDoc);
       final long actualBytes = ramBytesUsed(copy, maxDoc);
@@ -114,6 +117,7 @@ public abstract class BaseDocIdSetTestCase<T extends DocIdSet> extends LuceneTes
 
   /** Assert that the content of the {@link DocIdSet} is the same as the content of the {@link BitSet}. */
   public void assertEquals(int numBits, BitSet ds1, T ds2) throws IOException {
+    Random random = random();
     // nextDoc
     DocIdSetIterator it2 = ds2.iterator();
     if (it2 == null) {
@@ -134,7 +138,7 @@ public abstract class BaseDocIdSetTestCase<T extends DocIdSet> extends LuceneTes
       assertEquals(-1, ds1.nextSetBit(0));
     } else {
       for (int doc = -1; doc != DocIdSetIterator.NO_MORE_DOCS;) {
-        if (random().nextBoolean()) {
+        if (random.nextBoolean()) {
           doc = ds1.nextSetBit(doc + 1);
           if (doc == -1) {
             doc = DocIdSetIterator.NO_MORE_DOCS;
@@ -142,7 +146,7 @@ public abstract class BaseDocIdSetTestCase<T extends DocIdSet> extends LuceneTes
           assertEquals(doc, it2.nextDoc());
           assertEquals(doc, it2.docID());
         } else {
-          final int target = doc + 1 + random().nextInt(random().nextBoolean() ? 64 : Math.max(numBits / 8, 1));
+          final int target = doc + 1 + random.nextInt(random.nextBoolean() ? 64 : Math.max(numBits / 8, 1));
           doc = ds1.nextSetBit(target);
           if (doc == -1) {
             doc = DocIdSetIterator.NO_MORE_DOCS;