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