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