1 /*
2  * Copyright (c) 2012, 2017, Oracle and/or its affiliates. All rights reserved.
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * This code is free software; you can redistribute it and/or modify it
6  * under the terms of the GNU General Public License version 2 only, as
7  * published by the Free Software Foundation.
8  *
9  * This code is distributed in the hope that it will be useful, but WITHOUT
10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
12  * version 2 for more details (a copy is included in the LICENSE file that
13  * accompanied this code).
14  *
15  * You should have received a copy of the GNU General Public License version
16  * 2 along with this work; if not, write to the Free Software Foundation,
17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18  *
19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20  * or visit www.oracle.com if you need additional information or have any
21  * questions.
22  */
23 
24 package test.java.util.Random;
25 
26 import java.util.Random;
27 import java.util.concurrent.atomic.AtomicInteger;
28 import java.util.concurrent.atomic.LongAdder;
29 import java.util.function.BiConsumer;
30 
31 import org.testng.annotations.Test;
32 
33 import static org.testng.Assert.*;
34 
35 /**
36  * @test
37  * @run testng RandomTest
38  * @summary test methods on Random
39  * @key randomness
40  */
41 @Test
42 public class RandomTest {
43 
44     // Note: this test was adapted from the 166 TCK ThreadLocalRandomTest test
45     // and modified to be a TestNG test
46 
47     /*
48      * Testing coverage notes:
49      *
50      * We don't test randomness properties, but only that repeated
51      * calls, up to NCALLS tries, produce at least one different
52      * result.  For bounded versions, we sample various intervals
53      * across multiples of primes.
54      */
55 
56     // max numbers of calls to detect getting stuck on one value
57     static final int NCALLS = 10000;
58 
59     // max sampled int bound
60     static final int MAX_INT_BOUND = (1 << 28);
61 
62     // max sampled long bound
63     static final long MAX_LONG_BOUND = (1L << 42);
64 
65     // Number of replications for other checks
66     // Android-changed: takes too much time to run on certain targets.
67     // static final int REPS = 20;
68     static final int REPS = 5;
69 
70     /**
71      * Repeated calls to nextInt produce at least two distinct results
72      */
testNextInt()73     public void testNextInt() {
74         Random r = new Random();
75         int f = r.nextInt();
76         int i = 0;
77         while (i < NCALLS && r.nextInt() == f)
78             ++i;
79         assertTrue(i < NCALLS);
80     }
81 
82     /**
83      * Repeated calls to nextLong produce at least two distinct results
84      */
85     public void testNextLong() {
86         Random r = new Random();
87         long f = r.nextLong();
88         int i = 0;
89         while (i < NCALLS && r.nextLong() == f)
90             ++i;
91         assertTrue(i < NCALLS);
92     }
93 
94     /**
95      * Repeated calls to nextBoolean produce at least two distinct results
96      */
97     public void testNextBoolean() {
98         Random r = new Random();
99         boolean f = r.nextBoolean();
100         int i = 0;
101         while (i < NCALLS && r.nextBoolean() == f)
102             ++i;
103         assertTrue(i < NCALLS);
104     }
105 
106     /**
107      * Repeated calls to nextFloat produce at least two distinct results
108      */
109     public void testNextFloat() {
110         Random r = new Random();
111         float f = r.nextFloat();
112         int i = 0;
113         while (i < NCALLS && r.nextFloat() == f)
114             ++i;
115         assertTrue(i < NCALLS);
116     }
117 
118     /**
119      * Repeated calls to nextDouble produce at least two distinct results
120      */
121     public void testNextDouble() {
122         Random r = new Random();
123         double f = r.nextDouble();
124         int i = 0;
125         while (i < NCALLS && r.nextDouble() == f)
126             ++i;
127         assertTrue(i < NCALLS);
128     }
129 
130     /**
131      * Repeated calls to nextGaussian produce at least two distinct results
132      */
133     public void testNextGaussian() {
134         Random r = new Random();
135         double f = r.nextGaussian();
136         int i = 0;
137         while (i < NCALLS && r.nextGaussian() == f)
138             ++i;
139         assertTrue(i < NCALLS);
140     }
141 
142     /**
143      * nextInt(negative) throws IllegalArgumentException
144      */
145     @Test(expectedExceptions = IllegalArgumentException.class)
146     public void testNextIntBoundedNeg() {
147         Random r = new Random();
148         int f = r.nextInt(-17);
149     }
150 
151     /**
152      * nextInt(bound) returns 0 <= value < bound; repeated calls produce at
153      * least two distinct results
154      */
155     public void testNextIntBounded() {
156         Random r = new Random();
157         // sample bound space across prime number increments
158         for (int bound = 2; bound < MAX_INT_BOUND; bound += 524959) {
159             int f = r.nextInt(bound);
160             assertTrue(0 <= f && f < bound);
161             int i = 0;
162             int j;
163             while (i < NCALLS &&
164                    (j = r.nextInt(bound)) == f) {
165                 assertTrue(0 <= j && j < bound);
166                 ++i;
167             }
168             assertTrue(i < NCALLS);
169         }
170     }
171 
172     /**
173      * Invoking sized ints, long, doubles, with negative sizes throws
174      * IllegalArgumentException
175      */
176     public void testBadStreamSize() {
177         Random r = new Random();
178         assertThrowsIAE(() -> r.ints(-1L));
179         assertThrowsIAE(() -> r.ints(-1L, 2, 3));
180         assertThrowsIAE(() -> r.longs(-1L));
181         assertThrowsIAE(() -> r.longs(-1L, -1L, 1L));
182         assertThrowsIAE(() -> r.doubles(-1L));
183         assertThrowsIAE(() -> r.doubles(-1L, .5, .6));
184     }
185 
186     /**
187      * Invoking bounded ints, long, doubles, with illegal bounds throws
188      * IllegalArgumentException
189      */
190     public void testBadStreamBounds() {
191         Random r = new Random();
192         assertThrowsIAE(() -> r.ints(2, 1));
193         assertThrowsIAE(() -> r.ints(10, 42, 42));
194         assertThrowsIAE(() -> r.longs(-1L, -1L));
195         assertThrowsIAE(() -> r.longs(10, 1L, -2L));
196 
197         testDoubleBadOriginBound((o, b) -> r.doubles(10, o, b));
198     }
199 
200     // An arbitrary finite double value
201     static final double FINITE = Math.PI;
202 
203     void testDoubleBadOriginBound(BiConsumer<Double, Double> bi) {
204         assertThrowsIAE(() -> bi.accept(17.0, 2.0));
205         assertThrowsIAE(() -> bi.accept(0.0, 0.0));
206         assertThrowsIAE(() -> bi.accept(Double.NaN, FINITE));
207         assertThrowsIAE(() -> bi.accept(FINITE, Double.NaN));
208         assertThrowsIAE(() -> bi.accept(Double.NEGATIVE_INFINITY, Double.NEGATIVE_INFINITY));
209 
210         // Returns NaN
211 //        assertThrowsIAE(() -> bi.accept(Double.NEGATIVE_INFINITY, FINITE));
212 //        assertThrowsIAE(() -> bi.accept(Double.NEGATIVE_INFINITY, Double.POSITIVE_INFINITY));
213 
214         assertThrowsIAE(() -> bi.accept(FINITE, Double.NEGATIVE_INFINITY));
215 
216         // Returns Double.MAX_VALUE
217 //        assertThrowsIAE(() -> bi.accept(FINITE, Double.POSITIVE_INFINITY));
218 
219         assertThrowsIAE(() -> bi.accept(Double.POSITIVE_INFINITY, Double.NEGATIVE_INFINITY));
220         assertThrowsIAE(() -> bi.accept(Double.POSITIVE_INFINITY, FINITE));
221         assertThrowsIAE(() -> bi.accept(Double.POSITIVE_INFINITY, Double.POSITIVE_INFINITY));
222     }
223 
assertThrowsIAE(ThrowingRunnable r)224     private void assertThrowsIAE(ThrowingRunnable r) {
225         assertThrows(IllegalArgumentException.class, r);
226     }
227 
228     /**
229      * A sequential sized stream of ints generates the given number of values
230      */
testIntsCount()231     public void testIntsCount() {
232         LongAdder counter = new LongAdder();
233         Random r = new Random();
234         long size = 0;
235         for (int reps = 0; reps < REPS; ++reps) {
236             counter.reset();
237             r.ints(size).forEach(x -> {
238                 counter.increment();
239             });
240             assertEquals(counter.sum(), size);
241             size += 524959;
242         }
243     }
244 
245     /**
246      * A sequential sized stream of longs generates the given number of values
247      */
testLongsCount()248     public void testLongsCount() {
249         LongAdder counter = new LongAdder();
250         Random r = new Random();
251         long size = 0;
252         for (int reps = 0; reps < REPS; ++reps) {
253             counter.reset();
254             r.longs(size).forEach(x -> {
255                 counter.increment();
256             });
257             assertEquals(counter.sum(), size);
258             size += 524959;
259         }
260     }
261 
262     /**
263      * A sequential sized stream of doubles generates the given number of values
264      */
testDoublesCount()265     public void testDoublesCount() {
266         LongAdder counter = new LongAdder();
267         Random r = new Random();
268         long size = 0;
269         for (int reps = 0; reps < REPS; ++reps) {
270             counter.reset();
271             r.doubles(size).forEach(x -> {
272                 counter.increment();
273             });
274             assertEquals(counter.sum(), size);
275             size += 524959;
276         }
277     }
278 
279     /**
280      * Each of a sequential sized stream of bounded ints is within bounds
281      */
testBoundedInts()282     public void testBoundedInts() {
283         AtomicInteger fails = new AtomicInteger(0);
284         Random r = new Random();
285         long size = 12345L;
286         for (int least = -15485867; least < MAX_INT_BOUND; least += 524959) {
287             for (int bound = least + 2; bound > least && bound < MAX_INT_BOUND; bound += 67867967) {
288                 final int lo = least, hi = bound;
289                 r.ints(size, lo, hi).
290                         forEach(x -> {
291                             if (x < lo || x >= hi)
292                                 fails.getAndIncrement();
293                         });
294             }
295         }
296         assertEquals(fails.get(), 0);
297     }
298 
299     /**
300      * Each of a sequential sized stream of bounded longs is within bounds
301      */
testBoundedLongs()302     public void testBoundedLongs() {
303         AtomicInteger fails = new AtomicInteger(0);
304         Random r = new Random();
305         long size = 123L;
306         for (long least = -86028121; least < MAX_LONG_BOUND; least += 1982451653L) {
307             for (long bound = least + 2; bound > least && bound < MAX_LONG_BOUND; bound += Math.abs(bound * 7919)) {
308                 final long lo = least, hi = bound;
309                 r.longs(size, lo, hi).
310                         forEach(x -> {
311                             if (x < lo || x >= hi)
312                                 fails.getAndIncrement();
313                         });
314             }
315         }
316         assertEquals(fails.get(), 0);
317     }
318 
319     /**
320      * Each of a sequential sized stream of bounded doubles is within bounds
321      */
testBoundedDoubles()322     public void testBoundedDoubles() {
323         AtomicInteger fails = new AtomicInteger(0);
324         Random r = new Random();
325         long size = 456;
326         for (double least = 0.00011; least < 1.0e20; least *= 9) {
327             for (double bound = least * 1.0011; bound < 1.0e20; bound *= 17) {
328                 final double lo = least, hi = bound;
329                 r.doubles(size, lo, hi).
330                         forEach(x -> {
331                             if (x < lo || x >= hi)
332                                 fails.getAndIncrement();
333                         });
334             }
335         }
336         assertEquals(fails.get(), 0);
337     }
338 
339     /**
340      * A parallel unsized stream of ints generates at least 100 values
341      */
testUnsizedIntsCount()342     public void testUnsizedIntsCount() {
343         LongAdder counter = new LongAdder();
344         Random r = new Random();
345         long size = 100;
346         r.ints().limit(size).parallel().forEach(x -> {
347             counter.increment();
348         });
349         assertEquals(counter.sum(), size);
350     }
351 
352     /**
353      * A parallel unsized stream of longs generates at least 100 values
354      */
testUnsizedLongsCount()355     public void testUnsizedLongsCount() {
356         LongAdder counter = new LongAdder();
357         Random r = new Random();
358         long size = 100;
359         r.longs().limit(size).parallel().forEach(x -> {
360             counter.increment();
361         });
362         assertEquals(counter.sum(), size);
363     }
364 
365     /**
366      * A parallel unsized stream of doubles generates at least 100 values
367      */
testUnsizedDoublesCount()368     public void testUnsizedDoublesCount() {
369         LongAdder counter = new LongAdder();
370         Random r = new Random();
371         long size = 100;
372         r.doubles().limit(size).parallel().forEach(x -> {
373             counter.increment();
374         });
375         assertEquals(counter.sum(), size);
376     }
377 
378     /**
379      * A sequential unsized stream of ints generates at least 100 values
380      */
testUnsizedIntsCountSeq()381     public void testUnsizedIntsCountSeq() {
382         LongAdder counter = new LongAdder();
383         Random r = new Random();
384         long size = 100;
385         r.ints().limit(size).forEach(x -> {
386             counter.increment();
387         });
388         assertEquals(counter.sum(), size);
389     }
390 
391     /**
392      * A sequential unsized stream of longs generates at least 100 values
393      */
testUnsizedLongsCountSeq()394     public void testUnsizedLongsCountSeq() {
395         LongAdder counter = new LongAdder();
396         Random r = new Random();
397         long size = 100;
398         r.longs().limit(size).forEach(x -> {
399             counter.increment();
400         });
401         assertEquals(counter.sum(), size);
402     }
403 
404     /**
405      * A sequential unsized stream of doubles generates at least 100 values
406      */
testUnsizedDoublesCountSeq()407     public void testUnsizedDoublesCountSeq() {
408         LongAdder counter = new LongAdder();
409         Random r = new Random();
410         long size = 100;
411         r.doubles().limit(size).forEach(x -> {
412             counter.increment();
413         });
414         assertEquals(counter.sum(), size);
415     }
416 
417 }
418