Path: blob/aarch64-shenandoah-jdk8u272-b10/jdk/test/java/util/SplittableRandom/SplittableRandomTest.java
38811 views
/*1* Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation.7*8* This code is distributed in the hope that it will be useful, but WITHOUT9* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or10* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License11* version 2 for more details (a copy is included in the LICENSE file that12* accompanied this code).13*14* You should have received a copy of the GNU General Public License version15* 2 along with this work; if not, write to the Free Software Foundation,16* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.17*18* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA19* or visit www.oracle.com if you need additional information or have any20* questions.21*/2223import org.testng.Assert;24import org.testng.annotations.Test;2526import java.util.SplittableRandom;27import java.util.concurrent.ThreadLocalRandom;28import java.util.concurrent.atomic.AtomicInteger;29import java.util.concurrent.atomic.LongAdder;30import java.util.function.BiConsumer;3132import static org.testng.Assert.assertEquals;33import static org.testng.Assert.assertNotNull;34import static org.testng.AssertJUnit.assertTrue;3536/**37* @test38* @run testng SplittableRandomTest39* @run testng/othervm -Djava.util.secureRandomSeed=true SplittableRandomTest40* @summary test methods on SplittableRandom41* @key randomness42*/43@Test44public class SplittableRandomTest {4546// Note: this test was copied from the 166 TCK SplittableRandomTest test47// and modified to be a TestNG test4849/*50* Testing coverage notes:51*52* 1. Many of the test methods are adapted from ThreadLocalRandomTest.53*54* 2. These tests do not check for random number generator quality.55* But we check for minimal API compliance by requiring that56* repeated calls to nextX methods, up to NCALLS tries, produce at57* least two distinct results. (In some possible universe, a58* "correct" implementation might fail, but the odds are vastly59* less than that of encountering a hardware failure while running60* the test.) For bounded nextX methods, we sample various61* intervals across multiples of primes. In other tests, we repeat62* under REPS different values.63*/6465// max numbers of calls to detect getting stuck on one value66static final int NCALLS = 10000;6768// max sampled int bound69static final int MAX_INT_BOUND = (1 << 28);7071// max sampled long bound72static final long MAX_LONG_BOUND = (1L << 42);7374// Number of replications for other checks75static final int REPS = 20;7677/**78* Repeated calls to nextInt produce at least two distinct results79*/80public void testNextInt() {81SplittableRandom sr = new SplittableRandom();82int f = sr.nextInt();83int i = 0;84while (i < NCALLS && sr.nextInt() == f)85++i;86assertTrue(i < NCALLS);87}8889/**90* Repeated calls to nextLong produce at least two distinct results91*/92public void testNextLong() {93SplittableRandom sr = new SplittableRandom();94long f = sr.nextLong();95int i = 0;96while (i < NCALLS && sr.nextLong() == f)97++i;98assertTrue(i < NCALLS);99}100101/**102* Repeated calls to nextDouble produce at least two distinct results103*/104public void testNextDouble() {105SplittableRandom sr = new SplittableRandom();106double f = sr.nextDouble();107int i = 0;108while (i < NCALLS && sr.nextDouble() == f)109++i;110assertTrue(i < NCALLS);111}112113/**114* Two SplittableRandoms created with the same seed produce the115* same values for nextLong.116*/117public void testSeedConstructor() {118for (long seed = 2; seed < MAX_LONG_BOUND; seed += 15485863) {119SplittableRandom sr1 = new SplittableRandom(seed);120SplittableRandom sr2 = new SplittableRandom(seed);121for (int i = 0; i < REPS; ++i)122assertEquals(sr1.nextLong(), sr2.nextLong());123}124}125126/**127* A SplittableRandom produced by split() of a default-constructed128* SplittableRandom generates a different sequence129*/130public void testSplit1() {131SplittableRandom sr = new SplittableRandom();132for (int reps = 0; reps < REPS; ++reps) {133SplittableRandom sc = sr.split();134int i = 0;135while (i < NCALLS && sr.nextLong() == sc.nextLong())136++i;137assertTrue(i < NCALLS);138}139}140141/**142* A SplittableRandom produced by split() of a seeded-constructed143* SplittableRandom generates a different sequence144*/145public void testSplit2() {146SplittableRandom sr = new SplittableRandom(12345);147for (int reps = 0; reps < REPS; ++reps) {148SplittableRandom sc = sr.split();149int i = 0;150while (i < NCALLS && sr.nextLong() == sc.nextLong())151++i;152assertTrue(i < NCALLS);153}154}155156/**157* nextInt(negative) throws IllegalArgumentException158*/159@Test(expectedExceptions = IllegalArgumentException.class)160public void testNextIntBoundedNeg() {161SplittableRandom sr = new SplittableRandom();162int f = sr.nextInt(-17);163}164165/**166* nextInt(least >= bound) throws IllegalArgumentException167*/168@Test(expectedExceptions = IllegalArgumentException.class)169public void testNextIntBadBounds() {170SplittableRandom sr = new SplittableRandom();171int f = sr.nextInt(17, 2);172}173174/**175* nextInt(bound) returns 0 <= value < bound;176* repeated calls produce at least two distinct results177*/178public void testNextIntBounded() {179SplittableRandom sr = new SplittableRandom();180// sample bound space across prime number increments181for (int bound = 2; bound < MAX_INT_BOUND; bound += 524959) {182int f = sr.nextInt(bound);183assertTrue(0 <= f && f < bound);184int i = 0;185int j;186while (i < NCALLS &&187(j = sr.nextInt(bound)) == f) {188assertTrue(0 <= j && j < bound);189++i;190}191assertTrue(i < NCALLS);192}193}194195/**196* nextInt(least, bound) returns least <= value < bound;197* repeated calls produce at least two distinct results198*/199public void testNextIntBounded2() {200SplittableRandom sr = new SplittableRandom();201for (int least = -15485863; least < MAX_INT_BOUND; least += 524959) {202for (int bound = least + 2; bound > least && bound < MAX_INT_BOUND; bound += 49979687) {203int f = sr.nextInt(least, bound);204assertTrue(least <= f && f < bound);205int i = 0;206int j;207while (i < NCALLS &&208(j = sr.nextInt(least, bound)) == f) {209assertTrue(least <= j && j < bound);210++i;211}212assertTrue(i < NCALLS);213}214}215}216217/**218* nextLong(negative) throws IllegalArgumentException219*/220@Test(expectedExceptions = IllegalArgumentException.class)221public void testNextLongBoundedNeg() {222SplittableRandom sr = new SplittableRandom();223long f = sr.nextLong(-17);224}225226/**227* nextLong(least >= bound) throws IllegalArgumentException228*/229@Test(expectedExceptions = IllegalArgumentException.class)230public void testNextLongBadBounds() {231SplittableRandom sr = new SplittableRandom();232long f = sr.nextLong(17, 2);233}234235/**236* nextLong(bound) returns 0 <= value < bound;237* repeated calls produce at least two distinct results238*/239public void testNextLongBounded() {240SplittableRandom sr = new SplittableRandom();241for (long bound = 2; bound < MAX_LONG_BOUND; bound += 15485863) {242long f = sr.nextLong(bound);243assertTrue(0 <= f && f < bound);244int i = 0;245long j;246while (i < NCALLS &&247(j = sr.nextLong(bound)) == f) {248assertTrue(0 <= j && j < bound);249++i;250}251assertTrue(i < NCALLS);252}253}254255/**256* nextLong(least, bound) returns least <= value < bound;257* repeated calls produce at least two distinct results258*/259public void testNextLongBounded2() {260SplittableRandom sr = new SplittableRandom();261for (long least = -86028121; least < MAX_LONG_BOUND; least += 982451653L) {262for (long bound = least + 2; bound > least && bound < MAX_LONG_BOUND; bound += Math.abs(bound * 7919)) {263long f = sr.nextLong(least, bound);264assertTrue(least <= f && f < bound);265int i = 0;266long j;267while (i < NCALLS &&268(j = sr.nextLong(least, bound)) == f) {269assertTrue(least <= j && j < bound);270++i;271}272assertTrue(i < NCALLS);273}274}275}276277/**278* nextDouble(bound) throws IllegalArgumentException279*/280public void testNextDoubleBadBound() {281SplittableRandom sr = new SplittableRandom();282executeAndCatchIAE(() -> sr.nextDouble(0.0));283executeAndCatchIAE(() -> sr.nextDouble(-0.0));284executeAndCatchIAE(() -> sr.nextDouble(+0.0));285executeAndCatchIAE(() -> sr.nextDouble(-1.0));286executeAndCatchIAE(() -> sr.nextDouble(Double.NaN));287executeAndCatchIAE(() -> sr.nextDouble(Double.NEGATIVE_INFINITY));288289// Returns Double.MAX_VALUE290// executeAndCatchIAE(() -> r.nextDouble(Double.POSITIVE_INFINITY));291}292293/**294* nextDouble(origin, bound) throws IllegalArgumentException295*/296public void testNextDoubleBadOriginBound() {297testDoubleBadOriginBound(new SplittableRandom()::nextDouble);298}299300// An arbitrary finite double value301static final double FINITE = Math.PI;302303void testDoubleBadOriginBound(BiConsumer<Double, Double> bi) {304executeAndCatchIAE(() -> bi.accept(17.0, 2.0));305executeAndCatchIAE(() -> bi.accept(0.0, 0.0));306executeAndCatchIAE(() -> bi.accept(Double.NaN, FINITE));307executeAndCatchIAE(() -> bi.accept(FINITE, Double.NaN));308executeAndCatchIAE(() -> bi.accept(Double.NEGATIVE_INFINITY, Double.NEGATIVE_INFINITY));309310// Returns NaN311// executeAndCatchIAE(() -> bi.accept(Double.NEGATIVE_INFINITY, FINITE));312// executeAndCatchIAE(() -> bi.accept(Double.NEGATIVE_INFINITY, Double.POSITIVE_INFINITY));313314executeAndCatchIAE(() -> bi.accept(FINITE, Double.NEGATIVE_INFINITY));315316// Returns Double.MAX_VALUE317// executeAndCatchIAE(() -> bi.accept(FINITE, Double.POSITIVE_INFINITY));318319executeAndCatchIAE(() -> bi.accept(Double.POSITIVE_INFINITY, Double.NEGATIVE_INFINITY));320executeAndCatchIAE(() -> bi.accept(Double.POSITIVE_INFINITY, FINITE));321executeAndCatchIAE(() -> bi.accept(Double.POSITIVE_INFINITY, Double.POSITIVE_INFINITY));322}323324/**325* nextDouble(least, bound) returns least <= value < bound;326* repeated calls produce at least two distinct results327*/328public void testNextDoubleBounded2() {329SplittableRandom sr = new SplittableRandom();330for (double least = 0.0001; least < 1.0e20; least *= 8) {331for (double bound = least * 1.001; bound < 1.0e20; bound *= 16) {332double f = sr.nextDouble(least, bound);333assertTrue(least <= f && f < bound);334int i = 0;335double j;336while (i < NCALLS &&337(j = sr.nextDouble(least, bound)) == f) {338assertTrue(least <= j && j < bound);339++i;340}341assertTrue(i < NCALLS);342}343}344}345346/**347* Invoking sized ints, long, doubles, with negative sizes throws348* IllegalArgumentException349*/350public void testBadStreamSize() {351SplittableRandom r = new SplittableRandom();352executeAndCatchIAE(() -> r.ints(-1L));353executeAndCatchIAE(() -> r.ints(-1L, 2, 3));354executeAndCatchIAE(() -> r.longs(-1L));355executeAndCatchIAE(() -> r.longs(-1L, -1L, 1L));356executeAndCatchIAE(() -> r.doubles(-1L));357executeAndCatchIAE(() -> r.doubles(-1L, .5, .6));358}359360/**361* Invoking bounded ints, long, doubles, with illegal bounds throws362* IllegalArgumentException363*/364public void testBadStreamBounds() {365SplittableRandom r = new SplittableRandom();366executeAndCatchIAE(() -> r.ints(2, 1));367executeAndCatchIAE(() -> r.ints(10, 42, 42));368executeAndCatchIAE(() -> r.longs(-1L, -1L));369executeAndCatchIAE(() -> r.longs(10, 1L, -2L));370371testDoubleBadOriginBound((o, b) -> r.doubles(10, o, b));372}373374private void executeAndCatchIAE(Runnable r) {375executeAndCatch(IllegalArgumentException.class, r);376}377378private void executeAndCatch(Class<? extends Exception> expected, Runnable r) {379Exception caught = null;380try {381r.run();382}383catch (Exception e) {384caught = e;385}386387assertNotNull(caught,388String.format("No Exception was thrown, expected an Exception of %s to be thrown",389expected.getName()));390Assert.assertTrue(expected.isInstance(caught),391String.format("Exception thrown %s not an instance of %s",392caught.getClass().getName(), expected.getName()));393}394395/**396* A parallel sized stream of ints generates the given number of values397*/398public void testIntsCount() {399LongAdder counter = new LongAdder();400SplittableRandom r = new SplittableRandom();401long size = 0;402for (int reps = 0; reps < REPS; ++reps) {403counter.reset();404r.ints(size).parallel().forEach(x -> {counter.increment();});405assertEquals(counter.sum(), size);406size += 524959;407}408}409410/**411* A parallel sized stream of longs generates the given number of values412*/413public void testLongsCount() {414LongAdder counter = new LongAdder();415SplittableRandom r = new SplittableRandom();416long size = 0;417for (int reps = 0; reps < REPS; ++reps) {418counter.reset();419r.longs(size).parallel().forEach(x -> {counter.increment();});420assertEquals(counter.sum(), size);421size += 524959;422}423}424425/**426* A parallel sized stream of doubles generates the given number of values427*/428public void testDoublesCount() {429LongAdder counter = new LongAdder();430SplittableRandom r = new SplittableRandom();431long size = 0;432for (int reps = 0; reps < REPS; ++reps) {433counter.reset();434r.doubles(size).parallel().forEach(x -> {counter.increment();});435assertEquals(counter.sum(), size);436size += 524959;437}438}439440/**441* Each of a parallel sized stream of bounded ints is within bounds442*/443public void testBoundedInts() {444AtomicInteger fails = new AtomicInteger(0);445SplittableRandom r = new SplittableRandom();446long size = 12345L;447for (int least = -15485867; least < MAX_INT_BOUND; least += 524959) {448for (int bound = least + 2; bound > least && bound < MAX_INT_BOUND; bound += 67867967) {449final int lo = least, hi = bound;450r.ints(size, lo, hi).parallel().451forEach(x -> {if (x < lo || x >= hi)452fails.getAndIncrement(); });453}454}455assertEquals(fails.get(), 0);456}457458/**459* Each of a parallel sized stream of bounded longs is within bounds460*/461public void testBoundedLongs() {462AtomicInteger fails = new AtomicInteger(0);463SplittableRandom r = new SplittableRandom();464long size = 123L;465for (long least = -86028121; least < MAX_LONG_BOUND; least += 1982451653L) {466for (long bound = least + 2; bound > least && bound < MAX_LONG_BOUND; bound += Math.abs(bound * 7919)) {467final long lo = least, hi = bound;468r.longs(size, lo, hi).parallel().469forEach(x -> {if (x < lo || x >= hi)470fails.getAndIncrement(); });471}472}473assertEquals(fails.get(), 0);474}475476/**477* Each of a parallel sized stream of bounded doubles is within bounds478*/479public void testBoundedDoubles() {480AtomicInteger fails = new AtomicInteger(0);481SplittableRandom r = new SplittableRandom();482long size = 456;483for (double least = 0.00011; least < 1.0e20; least *= 9) {484for (double bound = least * 1.0011; bound < 1.0e20; bound *= 17) {485final double lo = least, hi = bound;486r.doubles(size, lo, hi).parallel().487forEach(x -> {if (x < lo || x >= hi)488fails.getAndIncrement(); });489}490}491assertEquals(fails.get(), 0);492}493494/**495* A parallel unsized stream of ints generates at least 100 values496*/497public void testUnsizedIntsCount() {498LongAdder counter = new LongAdder();499SplittableRandom r = new SplittableRandom();500long size = 100;501r.ints().limit(size).parallel().forEach(x -> {counter.increment();});502assertEquals(counter.sum(), size);503}504505/**506* A parallel unsized stream of longs generates at least 100 values507*/508public void testUnsizedLongsCount() {509LongAdder counter = new LongAdder();510SplittableRandom r = new SplittableRandom();511long size = 100;512r.longs().limit(size).parallel().forEach(x -> {counter.increment();});513assertEquals(counter.sum(), size);514}515516/**517* A parallel unsized stream of doubles generates at least 100 values518*/519public void testUnsizedDoublesCount() {520LongAdder counter = new LongAdder();521SplittableRandom r = new SplittableRandom();522long size = 100;523r.doubles().limit(size).parallel().forEach(x -> {counter.increment();});524assertEquals(counter.sum(), size);525}526527/**528* A sequential unsized stream of ints generates at least 100 values529*/530public void testUnsizedIntsCountSeq() {531LongAdder counter = new LongAdder();532SplittableRandom r = new SplittableRandom();533long size = 100;534r.ints().limit(size).forEach(x -> {counter.increment();});535assertEquals(counter.sum(), size);536}537538/**539* A sequential unsized stream of longs generates at least 100 values540*/541public void testUnsizedLongsCountSeq() {542LongAdder counter = new LongAdder();543SplittableRandom r = new SplittableRandom();544long size = 100;545r.longs().limit(size).forEach(x -> {counter.increment();});546assertEquals(counter.sum(), size);547}548549/**550* A sequential unsized stream of doubles generates at least 100 values551*/552public void testUnsizedDoublesCountSeq() {553LongAdder counter = new LongAdder();554SplittableRandom r = new SplittableRandom();555long size = 100;556r.doubles().limit(size).forEach(x -> {counter.increment();});557assertEquals(counter.sum(), size);558}559560}561562563