--- jsr166/src/test/tck/SplittableRandomTest.java 2016/11/13 03:36:50 1.20 +++ jsr166/src/test/tck/SplittableRandomTest.java 2017/10/03 22:27:04 1.22 @@ -4,9 +4,15 @@ * http://creativecommons.org/publicdomain/zero/1.0/ */ +import java.util.Arrays; +import java.util.ArrayList; +import java.util.List; import java.util.SplittableRandom; import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.atomic.LongAdder; +import java.lang.reflect.Method; +import java.util.function.Predicate; +import java.util.stream.Collectors; import junit.framework.Test; import junit.framework.TestSuite; @@ -50,41 +56,6 @@ public class SplittableRandomTest extend Integer.getInteger("SplittableRandomTest.reps", 4); /** - * Repeated calls to next (only accessible via reflection) produce - * at least two distinct results, and repeated calls produce all - * possible values. - */ - public void testNext() throws ReflectiveOperationException { - SplittableRandom rnd = new SplittableRandom(); - try { - java.lang.reflect.Method m - = SplittableRandom.class.getDeclaredMethod( - "next", new Class[] { int.class }); - m.setAccessible(true); - - int i; - { - int val = new java.util.Random().nextInt(4); - for (i = 0; i < NCALLS; i++) { - int q = (int) m.invoke(rnd, new Object[] { 2 }); - if (val == q) break; - } - assertTrue(i < NCALLS); - } - - { - int r = (int) m.invoke(rnd, new Object[] { 3 }); - for (i = 0; i < NCALLS; i++) { - int q = (int) m.invoke(rnd, new Object[] { 3 }); - assertTrue(q < (1<<3)); - if (r != q) break; - } - assertTrue(i < NCALLS); - } - } catch (SecurityException acceptable) {} - } - - /** * Repeated calls to nextInt produce at least two distinct results */ public void testNextInt() { @@ -560,4 +531,50 @@ public class SplittableRandomTest extend assertEquals(size, counter.sum()); } + /** + * SplittableRandom should implement most of Random's public methods + */ + public void testShouldImplementMostRandomMethods() throws Throwable { + Predicate wasForgotten = method -> { + String name = method.getName(); + // some methods deliberately not implemented + if (name.equals("setSeed")) return false; + if (name.equals("nextFloat")) return false; + if (name.equals("nextGaussian")) return false; + try { + SplittableRandom.class.getMethod( + method.getName(), method.getParameterTypes()); + } catch (ReflectiveOperationException ex) { + return true; + } + return false; + }; + List forgotten = + Arrays.stream(java.util.Random.class.getMethods()) + .filter(wasForgotten) + .collect(Collectors.toList()); + if (!forgotten.isEmpty()) + throw new AssertionError("Please implement: " + forgotten); + } + + /** + * Repeated calls to nextBytes produce at least values of different signs for every byte + */ + public void testNextBytes() { + SplittableRandom sr = new SplittableRandom(); + int n = sr.nextInt(20); + byte[] bytes = new byte[n]; + outer: + for (int i = 0; i < n; i++) { + for (int tries = NCALLS; tries-->0; ) { + byte before = bytes[i]; + sr.nextBytes(bytes); + byte after = bytes[i]; + if (after * before < 0) + continue outer; + } + fail("not enough variation in random bytes"); + } + } + }