ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/test/tck/SplittableRandomTest.java
Revision: 1.17
Committed: Wed Dec 31 21:28:49 2014 UTC (9 years, 4 months ago) by jsr166
Branch: MAIN
Changes since 1.16: +12 -9 lines
Log Message:
whitespace

File Contents

# User Rev Content
1 dl 1.1 /*
2     * Written by Doug Lea with assistance from members of JCP JSR-166
3     * Expert Group and released to the public domain, as explained at
4     * http://creativecommons.org/publicdomain/zero/1.0/
5     */
6 jsr166 1.16
7 dl 1.1 import java.util.SplittableRandom;
8     import java.util.concurrent.atomic.AtomicInteger;
9     import java.util.concurrent.atomic.LongAdder;
10    
11 jsr166 1.16 import junit.framework.Test;
12     import junit.framework.TestSuite;
13    
14 dl 1.1 public class SplittableRandomTest extends JSR166TestCase {
15    
16     public static void main(String[] args) {
17     junit.textui.TestRunner.run(suite());
18     }
19     public static Test suite() {
20     return new TestSuite(SplittableRandomTest.class);
21     }
22    
23     /*
24     * Testing coverage notes:
25     *
26 jsr166 1.4 * 1. Many of the test methods are adapted from ThreadLocalRandomTest.
27 dl 1.1 *
28 jsr166 1.4 * 2. These tests do not check for random number generator quality.
29     * But we check for minimal API compliance by requiring that
30     * repeated calls to nextX methods, up to NCALLS tries, produce at
31     * least two distinct results. (In some possible universe, a
32     * "correct" implementation might fail, but the odds are vastly
33     * less than that of encountering a hardware failure while running
34     * the test.) For bounded nextX methods, we sample various
35     * intervals across multiples of primes. In other tests, we repeat
36     * under REPS different values.
37 dl 1.1 */
38    
39     // max numbers of calls to detect getting stuck on one value
40     static final int NCALLS = 10000;
41    
42     // max sampled int bound
43 jsr166 1.11 static final int MAX_INT_BOUND = (1 << 26);
44 dl 1.1
45 jsr166 1.4 // max sampled long bound
46 jsr166 1.12 static final long MAX_LONG_BOUND = (1L << 40);
47 dl 1.1
48     // Number of replications for other checks
49 jsr166 1.7 static final int REPS =
50     Integer.getInteger("SplittableRandomTest.reps", 4);
51 dl 1.1
52     /**
53 jsr166 1.4 * Repeated calls to nextInt produce at least two distinct results
54 dl 1.1 */
55     public void testNextInt() {
56     SplittableRandom sr = new SplittableRandom();
57     int f = sr.nextInt();
58     int i = 0;
59     while (i < NCALLS && sr.nextInt() == f)
60     ++i;
61     assertTrue(i < NCALLS);
62     }
63    
64     /**
65 jsr166 1.4 * Repeated calls to nextLong produce at least two distinct results
66 dl 1.1 */
67     public void testNextLong() {
68     SplittableRandom sr = new SplittableRandom();
69     long f = sr.nextLong();
70     int i = 0;
71     while (i < NCALLS && sr.nextLong() == f)
72     ++i;
73     assertTrue(i < NCALLS);
74     }
75    
76     /**
77 jsr166 1.4 * Repeated calls to nextDouble produce at least two distinct results
78 dl 1.1 */
79     public void testNextDouble() {
80     SplittableRandom sr = new SplittableRandom();
81     double f = sr.nextDouble();
82 jsr166 1.4 int i = 0;
83 dl 1.1 while (i < NCALLS && sr.nextDouble() == f)
84     ++i;
85     assertTrue(i < NCALLS);
86     }
87    
88     /**
89     * Two SplittableRandoms created with the same seed produce the
90     * same values for nextLong.
91     */
92     public void testSeedConstructor() {
93 jsr166 1.14 for (long seed = 2; seed < MAX_LONG_BOUND; seed += 15485863) {
94 dl 1.1 SplittableRandom sr1 = new SplittableRandom(seed);
95     SplittableRandom sr2 = new SplittableRandom(seed);
96 jsr166 1.3 for (int i = 0; i < REPS; ++i)
97 dl 1.1 assertEquals(sr1.nextLong(), sr2.nextLong());
98     }
99     }
100    
101     /**
102     * A SplittableRandom produced by split() of a default-constructed
103     * SplittableRandom generates a different sequence
104     */
105     public void testSplit1() {
106     SplittableRandom sr = new SplittableRandom();
107     for (int reps = 0; reps < REPS; ++reps) {
108     SplittableRandom sc = sr.split();
109     int i = 0;
110     while (i < NCALLS && sr.nextLong() == sc.nextLong())
111     ++i;
112     assertTrue(i < NCALLS);
113     }
114     }
115    
116     /**
117     * A SplittableRandom produced by split() of a seeded-constructed
118     * SplittableRandom generates a different sequence
119     */
120     public void testSplit2() {
121     SplittableRandom sr = new SplittableRandom(12345);
122     for (int reps = 0; reps < REPS; ++reps) {
123     SplittableRandom sc = sr.split();
124     int i = 0;
125     while (i < NCALLS && sr.nextLong() == sc.nextLong())
126     ++i;
127     assertTrue(i < NCALLS);
128     }
129     }
130    
131     /**
132 jsr166 1.9 * nextInt(non-positive) throws IllegalArgumentException
133 dl 1.1 */
134 jsr166 1.13 public void testNextIntBoundNonPositive() {
135 dl 1.1 SplittableRandom sr = new SplittableRandom();
136 jsr166 1.9 Runnable[] throwingActions = {
137     () -> sr.nextInt(-17),
138     () -> sr.nextInt(0),
139     () -> sr.nextInt(Integer.MIN_VALUE),
140     };
141     assertThrows(IllegalArgumentException.class, throwingActions);
142 dl 1.1 }
143    
144     /**
145 jsr166 1.4 * nextInt(least >= bound) throws IllegalArgumentException
146 dl 1.1 */
147     public void testNextIntBadBounds() {
148     SplittableRandom sr = new SplittableRandom();
149 jsr166 1.10 Runnable[] throwingActions = {
150     () -> sr.nextInt(17, 2),
151     () -> sr.nextInt(-42, -42),
152     () -> sr.nextInt(Integer.MAX_VALUE, Integer.MIN_VALUE),
153     };
154     assertThrows(IllegalArgumentException.class, throwingActions);
155 dl 1.1 }
156    
157     /**
158     * nextInt(bound) returns 0 <= value < bound;
159 jsr166 1.4 * repeated calls produce at least two distinct results
160 dl 1.1 */
161     public void testNextIntBounded() {
162     SplittableRandom sr = new SplittableRandom();
163     // sample bound space across prime number increments
164     for (int bound = 2; bound < MAX_INT_BOUND; bound += 524959) {
165     int f = sr.nextInt(bound);
166     assertTrue(0 <= f && f < bound);
167     int i = 0;
168     int j;
169     while (i < NCALLS &&
170     (j = sr.nextInt(bound)) == f) {
171     assertTrue(0 <= j && j < bound);
172     ++i;
173     }
174     assertTrue(i < NCALLS);
175     }
176     }
177    
178     /**
179     * nextInt(least, bound) returns least <= value < bound;
180 jsr166 1.4 * repeated calls produce at least two distinct results
181 dl 1.1 */
182     public void testNextIntBounded2() {
183     SplittableRandom sr = new SplittableRandom();
184     for (int least = -15485863; least < MAX_INT_BOUND; least += 524959) {
185     for (int bound = least + 2; bound > least && bound < MAX_INT_BOUND; bound += 49979687) {
186     int f = sr.nextInt(least, bound);
187     assertTrue(least <= f && f < bound);
188     int i = 0;
189     int j;
190     while (i < NCALLS &&
191     (j = sr.nextInt(least, bound)) == f) {
192     assertTrue(least <= j && j < bound);
193     ++i;
194     }
195     assertTrue(i < NCALLS);
196     }
197     }
198     }
199    
200     /**
201 jsr166 1.9 * nextLong(non-positive) throws IllegalArgumentException
202 dl 1.1 */
203 jsr166 1.13 public void testNextLongBoundNonPositive() {
204 dl 1.1 SplittableRandom sr = new SplittableRandom();
205 jsr166 1.9 Runnable[] throwingActions = {
206     () -> sr.nextLong(-17L),
207     () -> sr.nextLong(0L),
208     () -> sr.nextLong(Long.MIN_VALUE),
209     };
210     assertThrows(IllegalArgumentException.class, throwingActions);
211 dl 1.1 }
212    
213     /**
214 jsr166 1.4 * nextLong(least >= bound) throws IllegalArgumentException
215 dl 1.1 */
216     public void testNextLongBadBounds() {
217     SplittableRandom sr = new SplittableRandom();
218 jsr166 1.10 Runnable[] throwingActions = {
219     () -> sr.nextLong(17L, 2L),
220     () -> sr.nextLong(-42L, -42L),
221     () -> sr.nextLong(Long.MAX_VALUE, Long.MIN_VALUE),
222     };
223     assertThrows(IllegalArgumentException.class, throwingActions);
224 dl 1.1 }
225    
226     /**
227     * nextLong(bound) returns 0 <= value < bound;
228 jsr166 1.4 * repeated calls produce at least two distinct results
229 dl 1.1 */
230     public void testNextLongBounded() {
231     SplittableRandom sr = new SplittableRandom();
232     for (long bound = 2; bound < MAX_LONG_BOUND; bound += 15485863) {
233     long f = sr.nextLong(bound);
234     assertTrue(0 <= f && f < bound);
235     int i = 0;
236     long j;
237     while (i < NCALLS &&
238     (j = sr.nextLong(bound)) == f) {
239     assertTrue(0 <= j && j < bound);
240     ++i;
241     }
242     assertTrue(i < NCALLS);
243     }
244     }
245    
246     /**
247     * nextLong(least, bound) returns least <= value < bound;
248 jsr166 1.4 * repeated calls produce at least two distinct results
249 dl 1.1 */
250     public void testNextLongBounded2() {
251     SplittableRandom sr = new SplittableRandom();
252     for (long least = -86028121; least < MAX_LONG_BOUND; least += 982451653L) {
253     for (long bound = least + 2; bound > least && bound < MAX_LONG_BOUND; bound += Math.abs(bound * 7919)) {
254     long f = sr.nextLong(least, bound);
255     assertTrue(least <= f && f < bound);
256     int i = 0;
257     long j;
258     while (i < NCALLS &&
259     (j = sr.nextLong(least, bound)) == f) {
260     assertTrue(least <= j && j < bound);
261     ++i;
262     }
263     assertTrue(i < NCALLS);
264     }
265     }
266     }
267    
268     /**
269 jsr166 1.9 * nextDouble(non-positive) throws IllegalArgumentException
270     */
271 jsr166 1.13 public void testNextDoubleBoundNonPositive() {
272 jsr166 1.9 SplittableRandom sr = new SplittableRandom();
273     Runnable[] throwingActions = {
274     () -> sr.nextDouble(-17.0d),
275     () -> sr.nextDouble(0.0d),
276     () -> sr.nextDouble(-Double.MIN_VALUE),
277     () -> sr.nextDouble(Double.NEGATIVE_INFINITY),
278     () -> sr.nextDouble(Double.NaN),
279     };
280     assertThrows(IllegalArgumentException.class, throwingActions);
281     }
282    
283     /**
284 jsr166 1.10 * nextDouble(! (least < bound)) throws IllegalArgumentException
285     */
286     public void testNextDoubleBadBounds() {
287     SplittableRandom sr = new SplittableRandom();
288     Runnable[] throwingActions = {
289     () -> sr.nextDouble(17.0d, 2.0d),
290     () -> sr.nextDouble(-42.0d, -42.0d),
291     () -> sr.nextDouble(Double.MAX_VALUE, Double.MIN_VALUE),
292     () -> sr.nextDouble(Double.NaN, 0.0d),
293     () -> sr.nextDouble(0.0d, Double.NaN),
294     };
295     assertThrows(IllegalArgumentException.class, throwingActions);
296     }
297    
298     // TODO: Test infinite bounds!
299     //() -> sr.nextDouble(Double.NEGATIVE_INFINITY, 0.0d),
300     //() -> sr.nextDouble(0.0d, Double.POSITIVE_INFINITY),
301    
302     /**
303 dl 1.1 * nextDouble(least, bound) returns least <= value < bound;
304 jsr166 1.4 * repeated calls produce at least two distinct results
305 dl 1.1 */
306     public void testNextDoubleBounded2() {
307     SplittableRandom sr = new SplittableRandom();
308     for (double least = 0.0001; least < 1.0e20; least *= 8) {
309     for (double bound = least * 1.001; bound < 1.0e20; bound *= 16) {
310     double f = sr.nextDouble(least, bound);
311     assertTrue(least <= f && f < bound);
312     int i = 0;
313     double j;
314     while (i < NCALLS &&
315     (j = sr.nextDouble(least, bound)) == f) {
316     assertTrue(least <= j && j < bound);
317     ++i;
318     }
319     assertTrue(i < NCALLS);
320     }
321     }
322     }
323    
324     /**
325     * Invoking sized ints, long, doubles, with negative sizes throws
326     * IllegalArgumentException
327     */
328     public void testBadStreamSize() {
329     SplittableRandom r = new SplittableRandom();
330 jsr166 1.8 Runnable[] throwingActions = {
331     () -> { java.util.stream.IntStream x = r.ints(-1L); },
332     () -> { java.util.stream.IntStream x = r.ints(-1L, 2, 3); },
333     () -> { java.util.stream.LongStream x = r.longs(-1L); },
334     () -> { java.util.stream.LongStream x = r.longs(-1L, -1L, 1L); },
335     () -> { java.util.stream.DoubleStream x = r.doubles(-1L); },
336     () -> { java.util.stream.DoubleStream x = r.doubles(-1L, .5, .6); },
337     };
338     assertThrows(IllegalArgumentException.class, throwingActions);
339 dl 1.1 }
340    
341     /**
342     * Invoking bounded ints, long, doubles, with illegal bounds throws
343     * IllegalArgumentException
344     */
345     public void testBadStreamBounds() {
346     SplittableRandom r = new SplittableRandom();
347 jsr166 1.8 Runnable[] throwingActions = {
348     () -> { java.util.stream.IntStream x = r.ints(2, 1); },
349     () -> { java.util.stream.IntStream x = r.ints(10, 42, 42); },
350     () -> { java.util.stream.LongStream x = r.longs(-1L, -1L); },
351     () -> { java.util.stream.LongStream x = r.longs(10, 1L, -2L); },
352     () -> { java.util.stream.DoubleStream x = r.doubles(0.0, 0.0); },
353     () -> { java.util.stream.DoubleStream x = r.doubles(10, .5, .4); },
354     };
355     assertThrows(IllegalArgumentException.class, throwingActions);
356 dl 1.1 }
357    
358     /**
359     * A parallel sized stream of ints generates the given number of values
360     */
361     public void testIntsCount() {
362     LongAdder counter = new LongAdder();
363     SplittableRandom r = new SplittableRandom();
364     long size = 0;
365     for (int reps = 0; reps < REPS; ++reps) {
366     counter.reset();
367 jsr166 1.6 r.ints(size).parallel().forEach(x -> counter.increment());
368 jsr166 1.4 assertEquals(size, counter.sum());
369 dl 1.1 size += 524959;
370     }
371     }
372    
373     /**
374     * A parallel sized stream of longs generates the given number of values
375     */
376     public void testLongsCount() {
377     LongAdder counter = new LongAdder();
378     SplittableRandom r = new SplittableRandom();
379     long size = 0;
380     for (int reps = 0; reps < REPS; ++reps) {
381     counter.reset();
382 jsr166 1.6 r.longs(size).parallel().forEach(x -> counter.increment());
383 jsr166 1.4 assertEquals(size, counter.sum());
384 dl 1.1 size += 524959;
385     }
386     }
387    
388     /**
389     * A parallel sized stream of doubles generates the given number of values
390     */
391     public void testDoublesCount() {
392     LongAdder counter = new LongAdder();
393     SplittableRandom r = new SplittableRandom();
394     long size = 0;
395     for (int reps = 0; reps < REPS; ++reps) {
396     counter.reset();
397 jsr166 1.6 r.doubles(size).parallel().forEach(x -> counter.increment());
398 jsr166 1.4 assertEquals(size, counter.sum());
399 dl 1.1 size += 524959;
400     }
401     }
402    
403     /**
404     * Each of a parallel sized stream of bounded ints is within bounds
405     */
406     public void testBoundedInts() {
407     AtomicInteger fails = new AtomicInteger(0);
408     SplittableRandom r = new SplittableRandom();
409     long size = 12345L;
410     for (int least = -15485867; least < MAX_INT_BOUND; least += 524959) {
411     for (int bound = least + 2; bound > least && bound < MAX_INT_BOUND; bound += 67867967) {
412     final int lo = least, hi = bound;
413 jsr166 1.17 r.ints(size, lo, hi).parallel().forEach(
414     x -> {
415     if (x < lo || x >= hi)
416     fails.getAndIncrement(); });
417 dl 1.1 }
418     }
419 jsr166 1.4 assertEquals(0, fails.get());
420 dl 1.1 }
421    
422     /**
423     * Each of a parallel sized stream of bounded longs is within bounds
424     */
425     public void testBoundedLongs() {
426     AtomicInteger fails = new AtomicInteger(0);
427     SplittableRandom r = new SplittableRandom();
428     long size = 123L;
429     for (long least = -86028121; least < MAX_LONG_BOUND; least += 1982451653L) {
430     for (long bound = least + 2; bound > least && bound < MAX_LONG_BOUND; bound += Math.abs(bound * 7919)) {
431     final long lo = least, hi = bound;
432 jsr166 1.17 r.longs(size, lo, hi).parallel().forEach(
433     x -> {
434     if (x < lo || x >= hi)
435     fails.getAndIncrement(); });
436 dl 1.1 }
437     }
438 jsr166 1.4 assertEquals(0, fails.get());
439 dl 1.1 }
440    
441     /**
442     * Each of a parallel sized stream of bounded doubles is within bounds
443     */
444     public void testBoundedDoubles() {
445     AtomicInteger fails = new AtomicInteger(0);
446     SplittableRandom r = new SplittableRandom();
447     long size = 456;
448     for (double least = 0.00011; least < 1.0e20; least *= 9) {
449     for (double bound = least * 1.0011; bound < 1.0e20; bound *= 17) {
450     final double lo = least, hi = bound;
451 jsr166 1.17 r.doubles(size, lo, hi).parallel().forEach(
452     x -> {
453     if (x < lo || x >= hi)
454     fails.getAndIncrement(); });
455 dl 1.1 }
456     }
457 jsr166 1.4 assertEquals(0, fails.get());
458 dl 1.1 }
459    
460 dl 1.2 /**
461     * A parallel unsized stream of ints generates at least 100 values
462     */
463     public void testUnsizedIntsCount() {
464     LongAdder counter = new LongAdder();
465     SplittableRandom r = new SplittableRandom();
466     long size = 100;
467 jsr166 1.6 r.ints().limit(size).parallel().forEach(x -> counter.increment());
468 jsr166 1.4 assertEquals(size, counter.sum());
469 dl 1.2 }
470    
471     /**
472     * A parallel unsized stream of longs generates at least 100 values
473     */
474     public void testUnsizedLongsCount() {
475     LongAdder counter = new LongAdder();
476     SplittableRandom r = new SplittableRandom();
477     long size = 100;
478 jsr166 1.6 r.longs().limit(size).parallel().forEach(x -> counter.increment());
479 jsr166 1.4 assertEquals(size, counter.sum());
480 dl 1.2 }
481    
482     /**
483     * A parallel unsized stream of doubles generates at least 100 values
484     */
485     public void testUnsizedDoublesCount() {
486     LongAdder counter = new LongAdder();
487     SplittableRandom r = new SplittableRandom();
488     long size = 100;
489 jsr166 1.6 r.doubles().limit(size).parallel().forEach(x -> counter.increment());
490 jsr166 1.4 assertEquals(size, counter.sum());
491 dl 1.2 }
492    
493     /**
494     * A sequential unsized stream of ints generates at least 100 values
495     */
496     public void testUnsizedIntsCountSeq() {
497     LongAdder counter = new LongAdder();
498     SplittableRandom r = new SplittableRandom();
499     long size = 100;
500 jsr166 1.6 r.ints().limit(size).forEach(x -> counter.increment());
501 jsr166 1.4 assertEquals(size, counter.sum());
502 dl 1.2 }
503    
504     /**
505     * A sequential unsized stream of longs generates at least 100 values
506     */
507     public void testUnsizedLongsCountSeq() {
508     LongAdder counter = new LongAdder();
509     SplittableRandom r = new SplittableRandom();
510     long size = 100;
511 jsr166 1.6 r.longs().limit(size).forEach(x -> counter.increment());
512 jsr166 1.4 assertEquals(size, counter.sum());
513 dl 1.2 }
514    
515     /**
516     * A sequential unsized stream of doubles generates at least 100 values
517     */
518     public void testUnsizedDoublesCountSeq() {
519     LongAdder counter = new LongAdder();
520     SplittableRandom r = new SplittableRandom();
521     long size = 100;
522 jsr166 1.6 r.doubles().limit(size).forEach(x -> counter.increment());
523 jsr166 1.4 assertEquals(size, counter.sum());
524 dl 1.2 }
525    
526 dl 1.1 }