8242314: use reproducible random in vmTestbase shared code
Reviewed-by: kbarrett, lmesnik
This commit is contained in:
parent
9320f9c60a
commit
6ff66db553
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2017, 2019, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2017, 2020, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -21,16 +21,16 @@
|
||||
* questions.
|
||||
*/
|
||||
|
||||
import jdk.test.lib.Platform;
|
||||
import jdk.test.lib.Utils;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Starts a new process to execute a command.
|
||||
@ -48,6 +48,10 @@ import java.util.Arrays;
|
||||
* {@code --java}, i.e. 0 or 95 means pass.
|
||||
*/
|
||||
public class ExecDriver {
|
||||
// copied from jdk.test.lib.Utils.TEST_CLASS_PATH
|
||||
private static final String TEST_CLASS_PATH = System.getProperty("test.class.path", ".");
|
||||
// copied from jdk.test.lib.Utils.TEST_CLASS_PATH
|
||||
private static final String TEST_JDK = System.getProperty("test.jdk");
|
||||
public static void main(String[] args) throws IOException, InterruptedException {
|
||||
boolean java = false;
|
||||
boolean launcher = false;
|
||||
@ -68,7 +72,7 @@ public class ExecDriver {
|
||||
}
|
||||
args[0] = javaBin();
|
||||
args[1] = "-cp";
|
||||
args[2] = Utils.TEST_CLASS_PATH;
|
||||
args[2] = TEST_CLASS_PATH;
|
||||
System.arraycopy(oldArgs, 1, args, count, oldArgs.length - 1);
|
||||
java = true;
|
||||
break;
|
||||
@ -84,7 +88,7 @@ public class ExecDriver {
|
||||
// adding 'test.vm.opts' and 'test.java.opts'
|
||||
if (java) {
|
||||
String[] oldArgs = args;
|
||||
String[] testJavaOpts = Utils.getTestJavaOpts();
|
||||
String[] testJavaOpts = getTestJavaOpts();
|
||||
if (testJavaOpts.length > 0) {
|
||||
args = new String[args.length + testJavaOpts.length];
|
||||
// bin/java goes before options
|
||||
@ -101,10 +105,11 @@ public class ExecDriver {
|
||||
ProcessBuilder pb = new ProcessBuilder(args);
|
||||
// adding jvm.so to library path
|
||||
if (launcher) {
|
||||
Path dir = Paths.get(Utils.TEST_JDK);
|
||||
Path dir = Paths.get(TEST_JDK);
|
||||
String value;
|
||||
String name = Platform.sharedLibraryPathVariableName();
|
||||
if (Platform.isWindows()) {
|
||||
String name = sharedLibraryPathVariableName();
|
||||
// if (jdk.test.lib.Platform.isWindows()) {
|
||||
if (System.getProperty("os.name").toLowerCase().startsWith("win")) {
|
||||
value = dir.resolve("bin")
|
||||
.resolve(variant())
|
||||
.toAbsolutePath()
|
||||
@ -125,7 +130,7 @@ public class ExecDriver {
|
||||
.merge(name, value, (x, y) -> y + File.pathSeparator + x));
|
||||
System.out.println(" with CLASSPATH = " +
|
||||
pb.environment()
|
||||
.put("CLASSPATH", Utils.TEST_CLASS_PATH));
|
||||
.put("CLASSPATH", TEST_CLASS_PATH));
|
||||
}
|
||||
Process p = pb.start();
|
||||
// inheritIO does not work as expected for @run driver
|
||||
@ -138,19 +143,52 @@ public class ExecDriver {
|
||||
}
|
||||
}
|
||||
|
||||
// copied from jdk.test.lib.Platform::sharedLibraryPathVariableName
|
||||
private static String sharedLibraryPathVariableName() {
|
||||
String osName = System.getProperty("os.name").toLowerCase();
|
||||
if (osName.startsWith("win")) {
|
||||
return "PATH";
|
||||
} else if (osName.startsWith("mac")) {
|
||||
return "DYLD_LIBRARY_PATH";
|
||||
} else if (osName.startsWith("aix")) {
|
||||
return "LIBPATH";
|
||||
} else {
|
||||
return "LD_LIBRARY_PATH";
|
||||
}
|
||||
}
|
||||
|
||||
// copied from jdk.test.lib.Utils::getTestJavaOpts()
|
||||
private static String[] getTestJavaOpts() {
|
||||
List<String> opts = new ArrayList<String>();
|
||||
{
|
||||
String v = System.getProperty("test.vm.opts", "").trim();
|
||||
if (!v.isEmpty()) {
|
||||
Collections.addAll(opts, v.split("\\s+"));
|
||||
}
|
||||
}
|
||||
{
|
||||
String v = System.getProperty("test.java.opts", "").trim();
|
||||
if (!v.isEmpty()) {
|
||||
Collections.addAll(opts, v.split("\\s+"));
|
||||
}
|
||||
}
|
||||
return opts.toArray(new String[0]);
|
||||
}
|
||||
|
||||
// copied jdk.test.lib.Platform::variant
|
||||
private static String variant() {
|
||||
if (Platform.isServer()) {
|
||||
String vmName = System.getProperty("java.vm.name");
|
||||
if (vmName.endsWith(" Server VM")) {
|
||||
return "server";
|
||||
} else if (Platform.isClient()) {
|
||||
} else if (vmName.endsWith(" Client VM")) {
|
||||
return "client";
|
||||
} else if (Platform.isMinimal()) {
|
||||
} else if (vmName.endsWith(" Minimal VM")) {
|
||||
return "minimal";
|
||||
} else {
|
||||
throw new Error("TESTBUG: unsuppported vm variant");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private static void copy(InputStream is, OutputStream os) {
|
||||
byte[] buffer = new byte[1024];
|
||||
int n;
|
||||
@ -165,7 +203,7 @@ public class ExecDriver {
|
||||
}
|
||||
|
||||
private static String javaBin() {
|
||||
return Paths.get(Utils.TEST_JDK)
|
||||
return Paths.get(TEST_JDK)
|
||||
.resolve("bin")
|
||||
.resolve("java")
|
||||
.toAbsolutePath()
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2003, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2003, 2020, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -27,6 +27,7 @@ import java.io.*;
|
||||
import java.util.*;
|
||||
|
||||
import nsk.share.test.ExecutionController;
|
||||
import nsk.share.test.LocalRandom;
|
||||
|
||||
/**
|
||||
* <tt>NonbranchyTree</tt> defines a tree structure. Each node of the tree
|
||||
@ -38,7 +39,6 @@ public class NonbranchyTree {
|
||||
/** Minimal size of each node (in bytes) */
|
||||
public final static int MIN_NODE_SIZE = 20;
|
||||
private Node root;
|
||||
private Random random;
|
||||
private int numberOfNodes;
|
||||
private float branchiness;
|
||||
private int size;
|
||||
@ -61,21 +61,16 @@ public class NonbranchyTree {
|
||||
*
|
||||
*/
|
||||
public NonbranchyTree(int numberOfNodes, float branchiness, int size) {
|
||||
this(numberOfNodes, branchiness, size, new Random(System.currentTimeMillis()), null);
|
||||
this(numberOfNodes, branchiness, size, null);
|
||||
initTree();
|
||||
}
|
||||
|
||||
public NonbranchyTree(int numberOfNodes, float branchiness, int size, ExecutionController controller) {
|
||||
this(numberOfNodes, branchiness, size, new Random(System.currentTimeMillis()), controller);
|
||||
initTree();
|
||||
}
|
||||
|
||||
private NonbranchyTree(int numberOfNodes, float branchiness, int size, Random random, ExecutionController controller) {
|
||||
this.numberOfNodes = numberOfNodes;
|
||||
this.branchiness = branchiness;
|
||||
this.size = size;
|
||||
this.random = random;
|
||||
this.controller = controller;
|
||||
initTree();
|
||||
}
|
||||
|
||||
private void initTree() {
|
||||
@ -94,6 +89,8 @@ public class NonbranchyTree {
|
||||
throw new IllegalArgumentException("Illegal size of nodes: "
|
||||
+ size + ", must be at least 1.");
|
||||
}
|
||||
// ensure that LocalRandom is loaded and has enough memory
|
||||
LocalRandom.nextBoolean();
|
||||
root = createTree(numberOfNodes, size);
|
||||
}
|
||||
|
||||
@ -119,7 +116,7 @@ public class NonbranchyTree {
|
||||
// Create a few nodes
|
||||
if (makeRightNode()) {
|
||||
// The node will have two sons
|
||||
int leftNodes = 1 + random.nextInt(numberOfNodes - 2);
|
||||
int leftNodes = 1 + LocalRandom.nextInt(numberOfNodes - 2);
|
||||
int rightNodes = numberOfNodes - 1 - leftNodes;
|
||||
|
||||
node.left = createTree(leftNodes, size);
|
||||
@ -142,7 +139,7 @@ public class NonbranchyTree {
|
||||
|
||||
// Define the "branchiness" of the tree
|
||||
private boolean makeRightNode() {
|
||||
return (random.nextFloat() < branchiness);
|
||||
return (LocalRandom.nextFloat() < branchiness);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2006, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2006, 2020, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -27,6 +27,7 @@ import nsk.share.TestBug;
|
||||
import nsk.share.jpda.AbstractDebuggeeTest;
|
||||
import java.io.*;
|
||||
import java.util.*;
|
||||
import jdk.test.lib.Utils;
|
||||
|
||||
/*
|
||||
* This class serial executes several JDI tests based on nsk.share.jdi.TestDebuggerType2 in single VM
|
||||
@ -192,7 +193,7 @@ public class SerialExecutionDebugger extends TestDebuggerType2 {
|
||||
if (testWorkDir == null)
|
||||
throw new TestBug("Debugger requires -testWorkDir parameter");
|
||||
|
||||
Collections.shuffle(result);
|
||||
Collections.shuffle(result, Utils.getRandomInstance());
|
||||
|
||||
// save resulted tests sequence in file (to simplify reproducing)
|
||||
try {
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2007, 2020, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -26,13 +26,13 @@ package nsk.share.runner;
|
||||
import nsk.share.log.Log;
|
||||
import nsk.share.test.StressOptions;
|
||||
import java.io.PrintStream;
|
||||
import jdk.test.lib.Utils;
|
||||
|
||||
public class RunParams {
|
||||
private StressOptions stressOptions;
|
||||
private long sleepTime = 500;
|
||||
private long iterations = 0;
|
||||
private int numberOfThreads;
|
||||
private long seed = System.currentTimeMillis();
|
||||
private boolean runGCThread = false;
|
||||
private boolean runFinThread = false;
|
||||
private boolean runMemDiagThread = false;
|
||||
@ -126,11 +126,9 @@ public class RunParams {
|
||||
}
|
||||
|
||||
public final long getSeed() {
|
||||
return seed;
|
||||
}
|
||||
|
||||
public final void setSeed(long seed) {
|
||||
this.seed = seed;
|
||||
// ensure that seed got printed out
|
||||
Utils.getRandomInstance();
|
||||
return Utils.SEED;
|
||||
}
|
||||
|
||||
public final boolean isRunGCThread() {
|
||||
@ -212,8 +210,6 @@ public class RunParams {
|
||||
runFinDiagThread = true;
|
||||
else if (args[i].equals("-Df"))
|
||||
runFinDiagThread = true;
|
||||
else if (args[i].equals("-s"))
|
||||
seed = Long.parseLong(args[++i]);
|
||||
else if (args[i].equals("-t"))
|
||||
numberOfThreads = Integer.parseInt(args[++i]);
|
||||
else if (args[i].equals("-it"))
|
||||
@ -233,7 +229,6 @@ public class RunParams {
|
||||
out.println("Sleep time: " + sleepTime);
|
||||
out.println("Iterations: " + iterations);
|
||||
out.println("Number of threads: " + numberOfThreads);
|
||||
out.println("Seed: " + seed);
|
||||
out.println("Run GC thread: " + runGCThread);
|
||||
out.println("Run mem diag thread: " + runMemDiagThread);
|
||||
out.println("Run forever: " + runForever);
|
||||
@ -244,7 +239,6 @@ public class RunParams {
|
||||
log.debug("Sleep time: " + sleepTime);
|
||||
log.debug("Iterations: " + iterations);
|
||||
log.debug("Number of threads: " + numberOfThreads);
|
||||
log.debug("Seed: " + seed);
|
||||
log.debug("Run GC thread: " + runGCThread);
|
||||
log.debug("Run mem diag thread: " + runMemDiagThread);
|
||||
log.debug("Run forever: " + runForever);
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2007, 2020, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -23,28 +23,50 @@
|
||||
|
||||
package nsk.share.test;
|
||||
|
||||
import java.util.concurrent.ThreadLocalRandom;
|
||||
import java.util.Random;
|
||||
import jdk.test.lib.Utils;
|
||||
import nsk.share.TestFailure;
|
||||
|
||||
/**
|
||||
* Utility class which encapsulates all useful static methods.
|
||||
*/
|
||||
public class LocalRandom {
|
||||
static {
|
||||
// ensure seed got printed out
|
||||
Utils.getRandomInstance();
|
||||
}
|
||||
private final static ThreadLocal<Random> random = new ThreadLocal<>() {
|
||||
protected Random initialValue() {
|
||||
// each thread gets its own seed independendly on the order they
|
||||
// use LocalRandom, yet it depends on the order threads are created.
|
||||
// main thread uses original seed
|
||||
return new Random(Utils.SEED ^ (Thread.currentThread().getId() - 1));
|
||||
}
|
||||
};
|
||||
private static int minPauseTime = 3000;
|
||||
private static int maxPauseTime = 5000;
|
||||
private static int maxRandomCount = 65536;
|
||||
|
||||
|
||||
/*
|
||||
* Initializes a thread-local instance to ensure that there is enough memory.
|
||||
* Useful for tests that exhaust memory.
|
||||
*/
|
||||
public static void init() {
|
||||
random.get();
|
||||
}
|
||||
|
||||
/*
|
||||
* Return next random double number.
|
||||
*
|
||||
* @return random double
|
||||
*/
|
||||
public static double random() {
|
||||
return ThreadLocalRandom.current().nextDouble();
|
||||
return random.get().nextDouble();
|
||||
}
|
||||
|
||||
public static double nextDouble() {
|
||||
return ThreadLocalRandom.current().nextDouble();
|
||||
return random.get().nextDouble();
|
||||
}
|
||||
|
||||
public static byte nextByte() {
|
||||
@ -60,7 +82,7 @@ public class LocalRandom {
|
||||
}
|
||||
|
||||
public static boolean nextBoolean() {
|
||||
return ThreadLocalRandom.current().nextBoolean();
|
||||
return random.get().nextBoolean();
|
||||
}
|
||||
|
||||
public static void nextBytes(byte[] arr) {
|
||||
@ -252,7 +274,7 @@ public class LocalRandom {
|
||||
}
|
||||
|
||||
public static int nextInt() {
|
||||
return ThreadLocalRandom.current().nextInt();
|
||||
return random.get().nextInt();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -262,11 +284,11 @@ public class LocalRandom {
|
||||
* @return random integer
|
||||
*/
|
||||
public static int nextInt(int n) {
|
||||
return ThreadLocalRandom.current().nextInt(n);
|
||||
return random.get().nextInt(n);
|
||||
}
|
||||
|
||||
public static long nextLong() {
|
||||
return ThreadLocalRandom.current().nextLong();
|
||||
return random.get().nextLong();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -286,7 +308,7 @@ public class LocalRandom {
|
||||
* @return random double
|
||||
*/
|
||||
public static float nextFloat() {
|
||||
return ThreadLocalRandom.current().nextFloat();
|
||||
return random.get().nextFloat();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2010, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2010, 2020, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -30,12 +30,12 @@ import java.net.URLClassLoader;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Random;
|
||||
import nsk.share.ClassUnloader;
|
||||
import nsk.share.TestFailure;
|
||||
import nsk.share.gc.ThreadedGCTest;
|
||||
import nsk.share.gc.gp.GarbageUtils;
|
||||
import nsk.share.test.ExecutionController;
|
||||
import nsk.share.test.LocalRandom;
|
||||
|
||||
/**
|
||||
* This is the base class for btree & chain tests. It is a standard GCThreaded Test.
|
||||
@ -114,7 +114,7 @@ public abstract class SysDictTest extends ThreadedGCTest {
|
||||
List<String> listNames = new ArrayList<String>(classnames.length);
|
||||
listNames.addAll(Arrays.asList(classnames));
|
||||
for (int i = 0; i < classnames.length; i++) {
|
||||
int idx1 = new Random().nextInt(listNames.size());
|
||||
int idx1 = LocalRandom.nextInt(listNames.size());
|
||||
this.names[i] = listNames.remove(idx1);
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2013, 2020, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -28,6 +28,8 @@ import java.util.Random;
|
||||
import java.util.function.Predicate;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
import jdk.test.lib.Utils;
|
||||
|
||||
public class RandomEx extends Random {
|
||||
private final Map<Class<?>, Supplier<?>> map = new HashMap<>();
|
||||
|
||||
@ -51,6 +53,7 @@ public class RandomEx extends Random {
|
||||
}
|
||||
|
||||
public RandomEx() {
|
||||
super(Utils.getRandomInstance().nextLong());
|
||||
}
|
||||
|
||||
public RandomEx(long seed) {
|
||||
|
Loading…
Reference in New Issue
Block a user