ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/test/tck/ThreadLocalRandomTest.java
(Generate patch)

Comparing jsr166/src/test/tck/ThreadLocalRandomTest.java (file contents):
Revision 1.9 by jsr166, Fri May 27 19:44:03 2011 UTC vs.
Revision 1.19 by jsr166, Fri Sep 27 20:22:26 2013 UTC

# Line 4 | Line 4
4   * http://creativecommons.org/publicdomain/zero/1.0/
5   */
6   import junit.framework.*;
7 import java.util.concurrent.*;
7   import java.util.*;
8 + import java.util.concurrent.ThreadLocalRandom;
9 + import java.util.concurrent.atomic.AtomicLong;
10 + import java.util.concurrent.atomic.AtomicReference;
11  
12   public class ThreadLocalRandomTest extends JSR166TestCase {
13  
# Line 16 | Line 18 | public class ThreadLocalRandomTest exten
18          return new TestSuite(ThreadLocalRandomTest.class);
19      }
20  
21 <    /**
21 >    /*
22       * Testing coverage notes:
23       *
24       * We don't test randomness properties, but only that repeated
# Line 25 | Line 27 | public class ThreadLocalRandomTest exten
27       * across multiples of primes.
28       */
29  
30 <    //
30 >    // max numbers of calls to detect getting stuck on one value
31      static final int NCALLS = 10000;
32  
33      // max sampled int bound
34      static final int MAX_INT_BOUND = (1 << 28);
35  
36 <    // Max sampled long bound
36 >    // max sampled long bound
37      static final long MAX_LONG_BOUND = (1L << 42);
38  
39 +    // Number of replications for other checks
40 +    static final int REPS = 20;
41 +
42      /**
43       * setSeed throws UnsupportedOperationException
44       */
# Line 45 | Line 50 | public class ThreadLocalRandomTest exten
50      }
51  
52      /**
53 <     * Repeated calls to nextInt produce at least one different result
53 >     * Repeated calls to nextInt produce at least two distinct results
54       */
55      public void testNextInt() {
56          int f = ThreadLocalRandom.current().nextInt();
# Line 56 | Line 61 | public class ThreadLocalRandomTest exten
61      }
62  
63      /**
64 <     * Repeated calls to nextLong produce at least one different result
64 >     * Repeated calls to nextLong produce at least two distinct results
65       */
66      public void testNextLong() {
67          long f = ThreadLocalRandom.current().nextLong();
# Line 67 | Line 72 | public class ThreadLocalRandomTest exten
72      }
73  
74      /**
75 <     * Repeated calls to nextBoolean produce at least one different result
75 >     * Repeated calls to nextBoolean produce at least two distinct results
76       */
77      public void testNextBoolean() {
78          boolean f = ThreadLocalRandom.current().nextBoolean();
# Line 78 | Line 83 | public class ThreadLocalRandomTest exten
83      }
84  
85      /**
86 <     * Repeated calls to nextFloat produce at least one different result
86 >     * Repeated calls to nextFloat produce at least two distinct results
87       */
88      public void testNextFloat() {
89          float f = ThreadLocalRandom.current().nextFloat();
# Line 89 | Line 94 | public class ThreadLocalRandomTest exten
94      }
95  
96      /**
97 <     * Repeated calls to nextDouble produce at least one different result
97 >     * Repeated calls to nextDouble produce at least two distinct results
98       */
99      public void testNextDouble() {
100          double f = ThreadLocalRandom.current().nextDouble();
101 <        double i = 0;
101 >        int i = 0;
102          while (i < NCALLS && ThreadLocalRandom.current().nextDouble() == f)
103              ++i;
104          assertTrue(i < NCALLS);
105      }
106  
107      /**
108 <     * Repeated calls to nextGaussian produce at least one different result
108 >     * Repeated calls to nextGaussian produce at least two distinct results
109       */
110      public void testNextGaussian() {
111          double f = ThreadLocalRandom.current().nextGaussian();
# Line 111 | Line 116 | public class ThreadLocalRandomTest exten
116      }
117  
118      /**
119 <     * nextInt(negative) throws IllegalArgumentException;
119 >     * nextInt(non-positive) throws IllegalArgumentException
120       */
121 <    public void testNextIntBoundedNeg() {
122 <        try {
123 <            int f = ThreadLocalRandom.current().nextInt(-17);
124 <            shouldThrow();
125 <        } catch (IllegalArgumentException success) {}
121 >    public void testNextIntBoundNonPositive() {
122 >        ThreadLocalRandom rnd = ThreadLocalRandom.current();
123 >        for (int bound : new int[] { 0, -17, Integer.MIN_VALUE }) {
124 >            try {
125 >                rnd.nextInt(bound);
126 >                shouldThrow();
127 >            } catch (IllegalArgumentException success) {}
128 >        }
129      }
130  
131      /**
132 <     * nextInt(least >= bound) throws IllegalArgumentException;
132 >     * nextInt(least >= bound) throws IllegalArgumentException
133       */
134      public void testNextIntBadBounds() {
135 <        try {
136 <            int f = ThreadLocalRandom.current().nextInt(17, 2);
137 <            shouldThrow();
138 <        } catch (IllegalArgumentException success) {}
135 >        int[][] badBoundss = {
136 >            { 17, 2 },
137 >            { -42, -42 },
138 >            { Integer.MAX_VALUE, Integer.MIN_VALUE },
139 >        };
140 >        ThreadLocalRandom rnd = ThreadLocalRandom.current();
141 >        for (int[] badBounds : badBoundss) {
142 >            try {
143 >                rnd.nextInt(badBounds[0], badBounds[1]);
144 >                shouldThrow();
145 >            } catch (IllegalArgumentException success) {}
146 >        }
147      }
148  
149      /**
150       * nextInt(bound) returns 0 <= value < bound;
151 <     * repeated calls produce at least one different result
151 >     * repeated calls produce at least two distinct results
152       */
153      public void testNextIntBounded() {
154          // sample bound space across prime number increments
# Line 152 | Line 168 | public class ThreadLocalRandomTest exten
168  
169      /**
170       * nextInt(least, bound) returns least <= value < bound;
171 <     * repeated calls produce at least one different result
171 >     * repeated calls produce at least two distinct results
172       */
173      public void testNextIntBounded2() {
174          for (int least = -15485863; least < MAX_INT_BOUND; least += 524959) {
# Line 172 | Line 188 | public class ThreadLocalRandomTest exten
188      }
189  
190      /**
191 <     * nextLong(negative) throws IllegalArgumentException;
191 >     * nextLong(non-positive) throws IllegalArgumentException
192       */
193 <    public void testNextLongBoundedNeg() {
194 <        try {
195 <            long f = ThreadLocalRandom.current().nextLong(-17);
196 <            shouldThrow();
197 <        } catch (IllegalArgumentException success) {}
193 >    public void testNextLongBoundNonPositive() {
194 >        ThreadLocalRandom rnd = ThreadLocalRandom.current();
195 >        for (long bound : new long[] { 0L, -17L, Long.MIN_VALUE }) {
196 >            try {
197 >                rnd.nextLong(bound);
198 >                shouldThrow();
199 >            } catch (IllegalArgumentException success) {}
200 >        }
201      }
202  
203      /**
204 <     * nextLong(least >= bound) throws IllegalArgumentException;
204 >     * nextLong(least >= bound) throws IllegalArgumentException
205       */
206      public void testNextLongBadBounds() {
207 <        try {
208 <            long f = ThreadLocalRandom.current().nextLong(17, 2);
209 <            shouldThrow();
210 <        } catch (IllegalArgumentException success) {}
207 >        long[][] badBoundss = {
208 >            { 17L, 2L },
209 >            { -42L, -42L },
210 >            { Long.MAX_VALUE, Long.MIN_VALUE },
211 >        };
212 >        ThreadLocalRandom rnd = ThreadLocalRandom.current();
213 >        for (long[] badBounds : badBoundss) {
214 >            try {
215 >                rnd.nextLong(badBounds[0], badBounds[1]);
216 >                shouldThrow();
217 >            } catch (IllegalArgumentException success) {}
218 >        }
219      }
220  
221      /**
222       * nextLong(bound) returns 0 <= value < bound;
223 <     * repeated calls produce at least one different result
223 >     * repeated calls produce at least two distinct results
224       */
225      public void testNextLongBounded() {
226          for (long bound = 2; bound < MAX_LONG_BOUND; bound += 15485863) {
# Line 212 | Line 239 | public class ThreadLocalRandomTest exten
239  
240      /**
241       * nextLong(least, bound) returns least <= value < bound;
242 <     * repeated calls produce at least one different result
242 >     * repeated calls produce at least two distinct results
243       */
244      public void testNextLongBounded2() {
245          for (long least = -86028121; least < MAX_LONG_BOUND; least += 982451653L) {
# Line 232 | Line 259 | public class ThreadLocalRandomTest exten
259      }
260  
261      /**
262 +     * nextDouble(non-positive) throws IllegalArgumentException
263 +     */
264 +    public void testNextDoubleBoundNonPositive() {
265 +        ThreadLocalRandom rnd = ThreadLocalRandom.current();
266 +        double[] badBounds = {
267 +            0.0d,
268 +            -17.0d,
269 +            -Double.MIN_VALUE,
270 +            Double.NEGATIVE_INFINITY,
271 +            Double.NaN,
272 +        };
273 +        for (double bound : badBounds) {
274 +            try {
275 +                rnd.nextDouble(bound);
276 +                shouldThrow();
277 +            } catch (IllegalArgumentException success) {}
278 +        }
279 +    }
280 +
281 +    /**
282       * nextDouble(least, bound) returns least <= value < bound;
283 <     * repeated calls produce at least one different result
283 >     * repeated calls produce at least two distinct results
284       */
285      public void testNextDoubleBounded2() {
286          for (double least = 0.0001; least < 1.0e20; least *= 8) {
# Line 252 | Line 299 | public class ThreadLocalRandomTest exten
299          }
300      }
301  
302 +    /**
303 +     * Different threads produce different pseudo-random sequences
304 +     */
305 +    public void testDifferentSequences() {
306 +        // Don't use main thread's ThreadLocalRandom - it is likely to
307 +        // be polluted by previous tests.
308 +        final AtomicReference<ThreadLocalRandom> threadLocalRandom =
309 +            new AtomicReference<ThreadLocalRandom>();
310 +        final AtomicLong rand = new AtomicLong();
311 +
312 +        long firstRand = 0;
313 +        ThreadLocalRandom firstThreadLocalRandom = null;
314 +
315 +        Runnable getRandomState = new CheckedRunnable() {
316 +            public void realRun() {
317 +                ThreadLocalRandom current = ThreadLocalRandom.current();
318 +                assertSame(current, ThreadLocalRandom.current());
319 +                // test bug: the following is not guaranteed and not true in JDK8
320 +                //                assertNotSame(current, threadLocalRandom.get());
321 +                rand.set(current.nextLong());
322 +                threadLocalRandom.set(current);
323 +            }};
324 +
325 +        Thread first = newStartedThread(getRandomState);
326 +        awaitTermination(first);
327 +        firstRand = rand.get();
328 +        firstThreadLocalRandom = threadLocalRandom.get();
329 +
330 +        for (int i = 0; i < NCALLS; i++) {
331 +            Thread t = newStartedThread(getRandomState);
332 +            awaitTermination(t);
333 +            if (firstRand != rand.get())
334 +                return;
335 +        }
336 +        fail("all threads generate the same pseudo-random sequence");
337 +    }
338 +
339   }

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines